K8s之认证,授权及准入控制
Posted yufenchi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8s之认证,授权及准入控制相关的知识,希望对你有一定的参考价值。
第1章 访问认证的概述
1.1 概念的引入
API Server作为Kubernetes集群系统的网关,是访问及管理资源对象的唯一人口,
余下所有需要访问集群资源的组件,包括kube-controller-manager、kube- scheduler 、
kubelet和kube-proxy等集群基础组件、CoreDNS等集群的附加组件以及此前使用的kubectl
命令等都要经由此网关进行集群访问和管理。这些客户端均要经由API Server访问或改变集群状态并
完成数据存储,并由它对每一次的访问请求进行合法性检验,包括用户身份鉴别、操作权限
验证以及操作是否符合全局规范的约束等。所有检查均正常完成且对象配置信息合法性检验
无误之后才能访问或存人数据于后端存储系统etcd中
第2章 ServiceAccount
2.1 概述
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同
1)User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
2)User account是跨namespace的,而service account则是仅局限它所在的namespace;
3)每个namespace都会自动创建一个default service account
4)Token controller检测service account的创建,并为它们创建secret
开启ServiceAccount Admission Controller后
1.每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
2.验证Pod引用的service account已经存在,否则拒绝创建
3.如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
4.每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/
2.2 查看相关信息
当创建pod的时候,如果没有指定一个service account,系统会自动在与该pod相同的namespace下为其指派一个default service account。
而pod和apiserver之间进行通信的账号,称为serviceAccountName。如下:
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
filebeat-ds-hxgdx 1/1 Running 1 34d
filebeat-ds-s466l 1/1 Running 2 34d
myapp-0 1/1 Running 0 3h
myapp-1 1/1 Running 0 3h
myapp-2 1/1 Running 0 4h
myapp-3 1/1 Running 0 4h
pod-vol-demo 2/2 Running 0 2d
redis-5b5d6fbbbd-q8ppz 1/1 Running 1 2d
[root@master ~]# kubectl get pods/myapp-0 -o yaml |grep "serviceAccountName"
serviceAccountName: default
[root@k8s-master ~]# kubectl describe pods myapp-0
Name: myapp-0
Namespace: default
......
Volumes:
......
default-token-j5pf5:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j5pf5
Optional: false
从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-*** token令牌,
这就是pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,
并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。
每个namespace中都有一个默认的叫做default的service account资源。进行查看名称空间内的secret也可以看到对应的default-token。
让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。
2.3 service account定义的方式
[root@master ~]# kubectl explain sa
KIND: ServiceAccount
VERSION: v1
FIELDS:
apiVersion <string>
automountServiceAccountToken <boolean>
imagePullSecrets <[]Object>
kind <string>
metadata <Object>
secrets <[]Object>
2.4 service account的创建
[root@master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run #不执行查看定义方式
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: mysa
[root@master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml #直接导出为yaml定义文件,可以节省敲键盘的时间
[root@master mainfests]# kubectl apply -f serviceaccount.yaml
serviceaccount/mysa created
[root@master mainfests]# kubectl get serviceaccount/mysa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"mysa","namespace":"default"}}
creationTimestamp: 2018-10-11T08:12:25Z
name: mysa
namespace: default
resourceVersion: "432865"
selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
uid: 62fc7782-cd2d-11e8-801a-000c2972dc1f
secrets:
- name: mysa-token-h2mgk
看到有一个token已经被自动创建,并被service account引用。设置非默认的service account
只需要在pod的spec.serviceAccountName字段中将name设置为您想要用的service account名字即可。
在pod创建之初service account就必须已经存在,否则创建将被拒绝。需要注意的是不能更新已创建的pod的service account
2.5 serviceaccount的自定义使用
这里在default名称空间创建了一个sa为admin,可以看到已经自动生成了一个Tokens:admin-token-7k5nr
[root@master mainfests]# kubectl create serviceaccount admin
serviceaccount/admin created
[root@master mainfests]# kubectl get sa
NAME SECRETS AGE
admin 1 3s
default 1 50d
[root@master mainfests]# kubectl describe sa/admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: admin-token-7k5nr
Tokens: admin-token-7k5nr
Events: <none>
[root@master mainfests]# kubectl get secret
NAME TYPE DATA AGE
admin-token-7k5nr kubernetes.io/service-account-token 3 31s
default-token-j5pf5 kubernetes.io/service-account-token 3 50d
mysecret Opaque 2 1d
tomcat-ingress-secret kubernetes.io/tls 2 10d
[root@master mainfests]# vim pod-sa-demo.yaml #Pod中引用新建的serviceaccount
apiVersion: v1
kind: Pod
metadata:
name: pod-sa-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
serviceAccountName: admin
[root@master mainfests]# kubectl apply -f pod-sa-demo.yaml
pod/pod-sa-demo created
[root@master mainfests]# kubectl describe pods pod-sa-demo
......
Volumes:
admin-token-7k5nr:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-7k5nr
Optional: false
在K8S集群当中,每一个用户对资源的访问都是需要通过apiserver进行通信认证才能进行访问的,那么在此机制当中,对资源的访问可以是token,也可以是通过配置文件的方式进行保存和使用认证信息,可以通过kubectl config进行查看配置,如下:
[root@master mainfests]# kubectl config view
apiVersion: v1
clusters: #集群列表
- cluster:
certificate-authority-data: REDACTED
server: https://192.168.56.11:6443
name: kubernetes
contexts: #上下文列表
- context: #定义哪个集群被哪个用户访问
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes #当前上下文
kind: Config
preferences: {}
users: #用户列表
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
在上面的配置文件当中,定义了集群、上下文以及用户。其中Config也是K8S的标准资源之一,在该配置文件当中定义了一个集群列表,指定的集群可以有多个;
用户列表也可以有多个,指明集群中的用户;而在上下文列表当中,是进行定义可以使用哪个用户对哪个集群进行访问,以及当前使用的上下文是什么。
如图:定义了用户kubernetes-admin可以对kubernetes该集群的访问,用户kubernetes-user1对Clluster1集群的访问
上图解析:
1. kubectl config中定义了有哪些集群和哪些用户(都是以列表的形式)
2. contexts就是定义哪个用户去访问哪个集群(从kubectl config中选出来)
3. contexts可以是多个的(一个contexts用来包含一个账号和一个集群),所以用的列表的形式
4. current-context: kubernetes-admin@kubernetes 就是表示从众多的contexts选出一个当前使用的contexts
以上是关于K8s之认证,授权及准入控制的主要内容,如果未能解决你的问题,请参考以下文章