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之认证,授权及准入控制的主要内容,如果未能解决你的问题,请参考以下文章

kubernetes集群的认证授权准入控制

k8s APIserver 安全机制之 rbac 授权

k8s认证授权

k8s的安全认证

15.kubernetes认证及serviceaccount

kubernetes API 访问控制之:准入控制