3-13-4-k8s访问控制--用户认证

熊 0 阅读 容器

1. 用户认证基础

我们知道在k8s上APIserver是整个集群的访问入口 , etcd是保存整个集群所有资源状态配置信息的kv键值存储数据库 , 一旦etcd宕机 , k8s整个集群将无法正常工作 , 为此我们需要对etcd做高可用 ; 除此之外为了保证etcd中的数据安全 , k8s只允许APIserver去访问/操作etcd;这也是APIserver为什么是整个集群的访问入口的原因 ; 简单讲etcd的客户端只有APIserver , 我们用客户端想要查看对应资源的状态或者修改对应资源属性等等操作 , 都需要把请求发送给APIserver , 由APIserver再把客户端的请求代理到etcd上 , 从而实现客户端访问/操作etcd中对应资源的状态或属性信息 ; 这样一来APIserver就承担了整个etcd的数据访问安全 ; 一旦APIserver出现问题 , 把恶意请求放进来 , 对应etcd的中的数据安全将无从保证 ; 为此APIserver就必须拥有一套对客户端请求进行验证管控的机制 ; 如下图

kubernetes-access-control-user-identify-1
  1. 用户认证

    首先APIserver要验证客户端是否是合法客户端 , 在k8s上我们用kubectl工具去管理k8s集群 , APIserver首先要验证kubectl客户端的证书 , 同时kubectl也要验证对应APIserver的证书 ; 这个过程我们叫k8s用户认证的过程 ; 在k8s上除了有通过证书方式认证客户端 , 还有其他机制 , 比如用户名和密码 , 利用token机制去验证对应客户端 ; 其中利用token机制中有明文token ( plain token ) 和引导token ( bootstrap token ) ; 不管是用户名密码还是token方式认证用户 , 在发送给APIserver时都是通过把对应的信息转化成http协议头部信息传递给APIserver ; 对应APIserver收到对应客户端请求 , 就会把对应头部信息检索下来 , 进行验证 ; 不同的是plain token主要用于验证对应客户端是否合法 , 是否能够登陆APIserver ; 而对应bootstrap token是用来验证对应节点是否能够加入到k8s集群 , 如果bootstrap认证通过后 , 对应APIserver会调用ca给对应节点上的kubelet和kubeproxy颁发证书 ; 此后kubelet和kubeproxy就可以通过APIserver认可的ca颁发的证书到APIserver认证 , 访问对应资源的信息了 ;

    用户认证只是验证对应客户端是否是合法客户端 , 这里的验证的机制是一票通过的机制 ; 所谓一票通过是指在APIserver上有多种验证机制 ( 方法 ) , 它会从上至下依次进行验证 , 如果对应验证方法没有明确拒绝 , 接着它会用下一个验证方法 , 直到有一个机制通过以后 , 余下的就不验证了 ; 比如 , 在k8s上有证书验证 , 用户名密码验证 , token验证 , 如果此时有一个客户端拿着一个token来登陆APIserver , 此时APIserver就会先用证书验证的方法验证客户端 , 如果对应验证方法没有明确拒绝 , 说明此方法不识别对应的客户端信息 , 接着它会用用户名密码的方法进行验证 , 如果对应方法也没有明确拒绝 , 接着它会用token方法进行验证 , 如果对应方法通过了 , 那么接下来的其他方法验证就不会再进行下去 ; 如果所有验证方法都没有拒绝 , 说明该客户端提供的认证信息在k8s上不适配 , 此时apiserver 就会把对应客户端归纳为匿名用户 ; 当然此类用户虽然登陆到APIserver上 , 但它没有权限操作资源 ;

  2. 验证授权

    只有验证通过的客户端 , 才会有机会进行权限验证 , 所谓权限验证是指验证对应客户端是否拥有对应k8s上的资源访问/操作权限 ; 验证权限也是一票通过的机制 ; 只要对应客户端有对应资源的操作/访问权限 , 则其他资源的权限验证就不会再进行下去 ; 如果没有对应资源访问/操作权限 , 此时APIserver就直接响应对应的客户端请求没有权限访问 ; 如果对应客户端有对资源的访问/操作操作权限 , 此时客户端请求会进入到下一个步骤 , 准入控制 ;

  3. 准入控制

    所谓准入控制是指检查对应客户端的请求是否符合对应请求/操作API规范 ; 传递参数是否是正确的 ; 比如我们要想k8s上创建一个pod , 此时准入控制会检查我们提交的信息是否符合创建对应资源的规范 , 如果符合规范就创建 , 不符合规范就拒绝 ; 准入控制这个环节是使用的一票否决的机制 , 所谓一票否决是指只要有一项不通过 , 则整个请求都将是拒绝的 , 即便余下的检查都是通过的 ; 当然只要有一项没有通过 , 余下的验证就不会再进行 ; 除了检查对应客户端提交的信息是否符合对应API资源的规范 , 准入控制还会帮助我们把我们没有明确指定的字段信息 , 通过默认值的方式把对应的字段填充到客户端请求中 ; 然后把填充好的信息一并由APIserver把客户端请求更新到对应资源在etcd中的对应信息上 ;

  

2. k8s上的用户

在k8s上用户有两类 , 一类是常规用户 ( normal users ) , 一类是服务帐号 ( Service Account ) ; 所谓常规用户就是指对应客户端现实生活中的操作者 , 这个有点类似Linux上的登录用户 ; 它把对应操作该客户端的人 , 映射到对应客户端的名称上 ; 比如我们用kubectl去操作k8s集群 , 在k8s上我们自己就是对应kubeclt持有的证书信息中的/CN对应的字符串 ; 服务帐号是指非人类操作的客户端所用到的用户名 , 有点类似Linux系统上的系统账号 ; 它的存在只是为了在k8s上方便权限的划分 ; 简单讲服务帐号就是用来针对那些程序自身向apiserver发起连接时 , 附加的用户信息 , 主要作用是apiserver可以根据对应的用户信息 , 来判断对应客户端在apiserver上的权限 ; 如下所示

kubernetes-access-control-user-identify-2

上图是一个pod的详细信息 , 其中我们并没有定义存储卷 , 创建pod后 , 它默认会生成这个存储卷 ; 这个存储卷被挂载到对应pod容器内部的/var/run/secrets/kubernetes.io/serviceaccount这个路径 ; 其实这个就是对应pod检索/更新自己的状态信息 , 要在apiserver上进行认证的serviceaccount信息 , 保存在secret存储卷中 ; 如下图所示

kubernetes-access-control-user-identify-3

对应pod挂载secret存储卷 , 主要作用是在检索/更新自己的状态信息时 , 它会把这个token发送给apiserver进行验证 ; apiserver认证通过后就把对应状态信息更新到etcd中进行保存 ; 正是因为pod提供了sa( serviceaccount的简写) 账号token信息 , 使得apiserver 才能正常判断出对应token对应用户的权限 ; 这个token是在创建pod时 , 对应准入控制器自动生成sa账号 , 并把对应的sa账号的token信息以secret存储卷的方式挂载至对应pod的对应位置 , pod更新或检索自己的信息时 , 它会把/var/run/secrets/kubernetes.io/serviceaccount这个文件中的信息发送给apiserver进行验证 ; 此时apiserver一验证对应token信息 , 就能知道这个token是对应sa账号的token信息 , 从而识别到对应sa账号的权限 ; 所以pod才能够正常的通过apiserver更新/检索自己的状态信息 ;

3. 客户端配置文件kubeconfig

在k8s上各个客户端都是优先使用证书来做认证 , apiserver通过验证各客户端的证书来确认对应的客户端是否能够正常访问apiserver ; 在k8s上证书验证是双向的 , apiserver会验证客户端的证书中的subj中的CN ( common name ) 的信息 , 是否符合对应客户端持有的身份信息 , 即用户名称 ; 把证书中的subj中的O ( organization ) 信息视为对应用户组 ; 除此之外apiserver还会验证对应客户端证书是否是自己信任的CA所颁发的证书 ; 对于客户端来说 , 也是同样的逻辑 , 它也需要验证apiserver的证书是否吻合对应apiserver的名称 , 是否是同一CA颁发的证书 ; 那么问题来了 , 每次客户端是怎么向apiserver发送自己的的证书信息的呢?在k8s上每一个客户端都有一个配置文件 , 这个配置文件主要用来记录客户端证书验证相关信息 ; 这个配置文件有一个统一的称呼叫kubeconfig ; 保存在/etc/kubernetes/目录下 ;

[root@master01 ~]# ll /etc/kubernetes/
total 32
-rw------- 1 root root 5567 Dec 22 20:00 admin.conf
-rw------- 1 root root 5599 Dec 22 20:00 controller-manager.conf
-rw------- 1 root root 1955 Dec 22 20:01 kubelet.conf
drwxr-xr-x 2 root root  113 Dec 22 20:00 manifests
drwxr-xr-x 3 root root 4096 Dec 22 20:00 pki
-rw------- 1 root root 5547 Dec 22 20:00 scheduler.conf
[root@master01 ~]#

我们使用kubectl客户端工具去访问对应apiserver时 , 默认没有指定其配置文件 , 主要原因是在对应Linux用户的家目录下有一个.kube的目录里有一个config文件 ; 这个文件是我们在初始化集群后 , 从/etc/kubernetes/admin.conf文件复制过来的 , 两者内容一样 ; 默认不指定其配置文件kubectl会到当前Linux用户所在家目录下的.kube/config文件作为对应访问apiserver的认证文件 ;

查看kubctl的配置文件内容

[root@master01 manifests]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.0.41: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
[root@master01 manifests]#

k8s上的客户端配置文件主要有4部分组成 , 分别是 , users、clusters、contexts、current-context ;

  • users是指定用户帐号以及相关认证列表 ;

  • clusters用来指定目标集群列表 ;

  • contexts用来指定以哪个user接入那个cluster的对应连接组合 ;

  • curren-context是用来指定当前使用的context ;

从上面的信息可以看到当前使用的是kubernetes-admin@kubernetes context连接k8s集群 , 对应context中 , 集群名叫kubernetes,使用的用户是kubernetes-admin ; 而对应集群的地址是https://192.168.0.41:6443,对应用户的的证书和私钥这里被隐藏了 ;

查看集群列表

[root@master01 manifests]# kubectl config get-clusters
NAME
kubernetes
[root@master01 manifests]#

查看用户列表

[root@master01 manifests]# kubectl config get-users
NAME
kubernetes-admin
[root@master01 manifests]#

查看context列表

[root@master01 manifests]# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin  
[root@master01 manifests]#

查看当前使用的context

[root@master01 manifests]# kubectl config current-context
kubernetes-admin@kubernetes
[root@master01 manifests]#

4. 具体示例 

4.1 示例一

示例: 创建一个集群、常规用户、context , 把对应信息保存到一个配置文件中 , 用对应配置文件去apiserver上请求资源 , 看看是否能够请求到对应资源信息

  • 创建私钥

    [root@master01 manifests]# cd /etc/kubernetes/pki/
    [root@master01 pki]# ls
    apiserver.crt              apiserver-kubelet-client.crt  etcd                    front-proxy-client.key
    apiserver-etcd-client.crt  apiserver-kubelet-client.key  front-proxy-ca.crt      sa.key
    apiserver-etcd-client.key  ca.crt                        front-proxy-ca.key      sa.pub
    apiserver.key              ca.key                        front-proxy-client.crt
    [root@master01 pki]# openssl genrsa -out tom.key 2048
    Generating RSA private key, 2048 bit long modulus
    ..............+++
    ..........................................................................................................................................................................................................................................+++
    e is 65537 (0x10001)
    [root@master01 pki]# ls
    apiserver.crt              apiserver-kubelet-client.crt  etcd                    front-proxy-client.key
    apiserver-etcd-client.crt  apiserver-kubelet-client.key  front-proxy-ca.crt      sa.key
    apiserver-etcd-client.key  ca.crt                        front-proxy-ca.key      sa.pub
    apiserver.key              ca.key                        front-proxy-client.crt  tom.key
    [root@master01 pki]#
  • 使用tom.key为tom用户生成签署请求文件tom.csr

    [root@master01 pki]# openssl req -new -key ./tom.key -out tom.csr -subj "/CN=tom/O=myuser"
    [root@master01 pki]# ls
    apiserver.crt                 apiserver-kubelet-client.key  front-proxy-ca.key      tom.csr
    apiserver-etcd-client.crt     ca.crt                        front-proxy-client.crt  tom.key
    apiserver-etcd-client.key     ca.key                        front-proxy-client.key
    apiserver.key                 etcd                          sa.key
    apiserver-kubelet-client.crt  front-proxy-ca.crt            sa.pub
    [root@master01 pki]#
  • 使用apiserver信任的ca给tom用户签发证书

    [root@master01 pki]# openssl x509 -req -in tom.csr -CA ./ca.crt -CAkey ./ca.key  -CAcreateserial -out tom.crt -days 365
    Signature ok
    subject=/CN=tom/O=myuser
    Getting CA Private Key
    [root@master01 pki]# ls
    apiserver.crt                 apiserver-kubelet-client.key  front-proxy-ca.key      tom.crt
    apiserver-etcd-client.crt     ca.crt                        front-proxy-client.crt  tom.csr
    apiserver-etcd-client.key     ca.key                        front-proxy-client.key  tom.key
    apiserver.key                 etcd                          sa.key
    apiserver-kubelet-client.crt  front-proxy-ca.crt            sa.pub
    [root@master01 pki]#

    提示: 这里使用的CA必须要用apiserver信任的ca来签发证书 , 否则apiserver它不认 ;

  • 创建集群 , 指定对应ca的证书信息 , 集群名字以及集群的地址

    [root@master01 ~]# kubectl config set-cluster myk8s --server="https://192.168.0.41:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
    Cluster "myk8s" set.
    [root@master01 ~]# kubectl config get-clusters
    NAME
    myk8s
    kubernetes
    [root@master01 ~]#

    提示: --embed-certs=ture表示隐藏证书信息 ; 这里默认没有指定将配置信息保存在那个配置文件 , 默认就保存在当前配置文件 ( 用户家目录的./kube/config文件中 ) ; 如果要想指定保存在某个配置文件中 , 可以在后面加上--kubeconfig选项来指定对应的配置文件即可 ;

    把创建集群的配置保存在/tmp/myk8s.config文件中

    [root@master01 ~]# kubectl config set-cluster myk8s --server="https://192.168.0.41:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/tmp/myk8s.config
    Cluster "myk8s" set.
    [root@master01 ~]# kubectl config get-clusters --kubeconfig=/tmp/myk8s.config
    NAME
    myk8s
    [root@master01 ~]# cat /tmp/myk8s.config            
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01USXdPREEyTXpnMU5Gb1hEVE13TVRJd05qQTJNemcxTkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSzZXCjl5Mkc5YUxFc3h1Q3dNQllBbEdtRys5TG5nMU9OWm9aRDZDd2ZLUUY3Y3lHSStuN1BwSDJFT2o1K292WlBNWG0KckpNaVFHOXB2bVNDZC9FRkxod05YRWNOREZDbGF6Y0cvQ1B0QjlCRlQ1ZGdVMXJnMGxvRUxEVXduUk16eU43QwozRkdacW9maW9kMXJZaGhRaHpDc2N6a0w3dWJjcTBOS2NFQjY0OTB1N0hyeVZ5Y0pGSmwzR0ZKVnN0d0pYZkV1CmtVQ2s2bVlYNFFWb2NObHlKVWZLaWZUMFBZSVQwVVBqZWwvc2NrTnJIUjFFTU5sVXJOWXlHMkJ1cTFhSENhZ2oKRGNrUWh5dU44cTZqNERiSGwrS0pJUTNtN0dxL29vTzBSMm5LNFlKUVMyZjI4bkFhWkRlRWZZcDEwdmg0ditUQwpjaXI5RStmYm1EYWFUQXNsVGdrQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMNVRSSG9QUGJDWk4vUFRVcjdCZGVidmdkMFRNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBQTRxa3prejNsTGFRYlQ3a0x3SnBoTXZnczJUdzU1b01VYWlzdlBJczVwSk1aZmNwNQpDcFdiRnc1VzR6R0RqWFBpRUExb3BvOEFEQzlXTERZem01eHV3V1ZQeWlWZzRmWjYxK3hISU9KMnlnQW4rWEo1CjRVUHMzYUl3RUJ3OHNPdTM4c1N0a29HNDJTY1gzTXR5cDRjRHJDakFGYnVrMUR5U3E5RytOWG9iL3FVdWxDWC8KSkdzSUJZd3pHVmVDSzVweVJDdHUwY0VRWkp4N1pQc2RhOXcwWXVBdGt5dFN3YkxVakU5MWpMNDV4blRHdllpMwo4eC9ocmJOYVBKUjVlNStpZlZqQVR1TDNHM3liNkduaVNsMGNBSDlNeEUzNE50MStwUFlOTmduVk9HdC9SZTdwClVubzVocXd4RTB2cmQxanU2YlVmVDZ6U0ozb1hpejI5Ri93RwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        server: https://192.168.0.41:6443
      name: myk8s
    contexts: null
    current-context: ""
    kind: Config
    preferences: {}
    users: null
    [root@master01 ~]#

    提示: 这里的证书信息是--base64编码处理以后的信息 ;

  • 创建用户 , 指定对应用户名称 , 用户证书和私钥信息

    [root@master01 ~]# kubectl config set-credentials tom --client-certificate=/etc/kubernetes/pki/tom.crt --client-key=/etc/kubernetes/pki/tom.key --username=tom --embed-certs=true
    User "tom" set.
    [root@master01 ~]# kubectl config set-credentials tom --client-certificate=/etc/kubernetes/pki/tom.crt --client-key=/etc/kubernetes/pki/tom.key --username=tom --embed-certs=true --kubeconfig=/tmp/myk8s.config
    User "tom" set.
    [root@master01 ~]# kubectl config view --kubeconfig=/tmp/myk8s.config
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: DATA+OMITTED
        server: https://192.168.0.41:6443
      name: myk8s
    contexts: null
    current-context: ""
    kind: Config
    preferences: {}
    users:
    - name: tom
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
        username: tom
    [root@master01 ~]#

    提示: --username指定的名字尽量同证书中的CN名称相同 , 因为apiserver会把CN的信息识别为对应用户信息 ; 这里补充一点 , 在k8s上没有真正的人类用户 , 它是把对应客户端的证书中的CN信息识别成对应操作该客户端的用户 ; 只要对应的证书能够通过认证 , 不管对应操作者是谁 , k8s并不关心 ; 就像我们在使用Linux时 , 拿着root用户登录了系统 , 只要密码正确 , Linux内核就认为是root在操作 ; 这里的证书就好比Linuxroot的密码 ;

  • 创建context , 把tom用户和myk8s集群做关联 , 并指定对应context的名称

    [root@master01 ~]# kubectl config set-context tom@myk8s --cluster=myk8s --user=tom
    Context "tom@myk8s" created.
    [root@master01 ~]# kubectl config set-context tom@myk8s --cluster=myk8s --user=tom --kubeconfig=/tmp/myk8s.config            
    Context "tom@myk8s" created.
    [root@master01 ~]# kubectl config view --kubeconfig=/tmp/myk8s.config                                        apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: DATA+OMITTED
        server: https://192.168.0.41:6443
      name: myk8s
    contexts:
    - context:
        cluster: myk8s
        user: tom
      name: tom@myk8s
    current-context: ""
    kind: Config
    preferences: {}
    users:
    - name: tom
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
        username: tom
    [root@master01 ~]#

    提示: 创建context尽量做到见名知意 ; 一般都是使用用户名@集群名的格式为context命名 ;

到此 , 对应tom用户的配置文件就做好了 , 我们在/tmp/myk8s.config文件中保存了对应新建的用户、集群、context信息 , 在当前配置文件中也保存了相应的配置信息 ;

4.2 示例二

测试: 在没有切换配置之前 , 查看集群运行在default名称空间运行的pod

[root@master01 ~]# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin  
          tom@myk8s                     myk8s        tom               
[root@master01 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
nginx-pod-demo   1/1     Running   0          117m
web-0            1/1     Running   1          27h
web-1            1/1     Running   1          27h
web-2            1/1     Running   1          27h
web-3            1/1     Running   2          27h
[root@master01 ~]#

提示: 当前配置还是用的kubernetes-admin@kubernetes这个context , 查看default名称空间下的pod能够正常查询到 ;

  • 切换context到tom@myk8s context上 , 看看是否还能看到default名称空间下的pod 呢?

    [root@master01 ~]# kubectl config use-context tom@myk8s  
    Switched to context "tom@myk8s".
    [root@master01 ~]# kubectl config get-contexts        
    CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
              kubernetes-admin@kubernetes   kubernetes   kubernetes-admin  
    *         tom@myk8s                     myk8s        tom               
    [root@master01 ~]# kubectl get pods
    Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "default"
    [root@master01 ~]#

    可以看到切换到tom@myk8s这个context后 , 再次查看default名称空间下pod列表就看不到 ; 这里提示我们权限拒绝 ; 其实看不到才是正常的 , 因为我们只是把tom用户接入到apiserver上进行认证 , 并没有给他授权 , 所以tom用户目前只是通过了验证 , 并没有对资源的操作权限 , 在权限验证时给拒绝了 ;

  • 使用/tmp/myk8s.config配置文件查看default名称空间下的pod列表

    [root@master01 ~]# kubectl config get-contexts --kubeconfig=/tmp/myk8s.config
    CURRENT   NAME        CLUSTER   AUTHINFO   NAMESPACE
              tom@myk8s   myk8s     tom       
    [root@master01 ~]# kubectl config use-context tom@myk8s --kubeconfig=/tmp/myk8s.config
    Switched to context "tom@myk8s".
    [root@master01 ~]# kubectl config get-contexts --kubeconfig=/tmp/myk8s.config        
    CURRENT   NAME        CLUSTER   AUTHINFO   NAMESPACE
    *         tom@myk8s   myk8s     tom       
    [root@master01 ~]# kubectl get pods --kubeconfig=/tmp/myk8s.config
    Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "default"
    [root@master01 ~]#

    使用/tmp/myk8s.config配置文件去apiserver上验证 , 也是一样的情况看不到pod , 响应我们对应资源禁止访问 ;

  • 切回kubernetes-admin@kubernetes context再次查看default名称空间下的pod列表

    [root@master01 ~]# kubectl config use-context kubernetes-admin@kubernetes
    Switched to context "kubernetes-admin@kubernetes".
    [root@master01 ~]# kubectl config get-contexts
    CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
    *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin  
              tom@myk8s                     myk8s        tom               
    [root@master01 ~]# kubectl get pods
    NAME             READY   STATUS    RESTARTS   AGE
    nginx-pod-demo   1/1     Running   0          132m
    web-0            1/1     Running   1          27h
    web-1            1/1     Running   1          27h
    web-2            1/1     Running   1          27h
    web-3            1/1     Running   2          27h
    [root@master01 ~]#

    切回kubernetes-admin@kubernetes context后 , 查看default名称空间下的pod列表 , 能够正常查看到 , 这是因为切换context以后 , 对应的用户认证在apiserver有查看对应资源的权限 ;

  • 创建一个sa账号

    [root@master01 ~]# cat sa-demo.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sa-demo
      namespace: default
    [root@master01 ~]#

    sa是k8s上的一个标准资源 , 其群组为v1 , 类型为ServiceAccount ; 其中metadata.name是用来指定sa账号的名称 , namespace用来指定其名称空间信息 ; 创建一个sa资源用户只需要定义对应的名称和名称空间就可以了 ; 对应secret资源会自动创建并生成的对应的token信息 ; 这样一来就意味着只要我们创建一个sa账号 , 在k8s上就能够被认证通过 ; 因为创建sa它自动创建secret并将对应的token生成好 ; 我们可以理解为创建secret并生成token的过程就是在把对应sa账号和对应token进行关联 ;

  • 应用资源清单

    [root@master01 ~]# kubectl apply -f sa-demo.yaml
    serviceaccount/sa-demo created
    [root@master01 ~]# kubectl get sa
    NAME      SECRETS   AGE
    default   1         21d
    sa-demo   1         5s
    [root@master01 ~]# kubectl describe sa sa-demo
    Name:                sa-demo
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   sa-demo-token-8kjhc
    Tokens:              sa-demo-token-8kjhc
    Events:              <none>
    [root@master01 ~]# kubectl get secret
    NAME                           TYPE                                  DATA   AGE
    default-token-xvd4c            kubernetes.io/service-account-token   3      21d
    docker-registry.io             kubernetes.io/dockerconfigjson        1      3d1h
    mysql-auth                     Opaque                                2      3d
    sa-demo-token-8kjhc            kubernetes.io/service-account-token   3      26s
    test-secret-demo               Opaque                                2      2d23h
    test-secret-demo1              Opaque                                2      2d23h
    test-tls                       kubernetes.io/tls                     2      3d
    www-myapp-com-ingress-secret   kubernetes.io/tls                     2      7d23h
    [root@master01 ~]# kubectl describe secret sa-demo-token-8kjhc
    Name:         sa-demo-token-8kjhc
    Namespace:    default
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: sa-demo
                  kubernetes.io/service-account.uid: 34cb62e8-23bd-4f2b-be82-4a8c9afc4037
     
    Type:  kubernetes.io/service-account-token
     
    Data
    ====
    ca.crt:     1066 bytes
    namespace:  7 bytes
    token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4WnU0Z1Q1c0hBNmR5Q1V0ejRaMFk4d2J2WncwWjNiUTAxZk02SGN4OTgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLWRlbW8tdG9rZW4tOGtqaGMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoic2EtZGVtbyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjM0Y2I2MmU4LTIzYmQtNGYyYi1iZTgyLTRhOGM5YWZjNDAzNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnNhLWRlbW8ifQ.XyYaqpeZXexal1wr1aiBaZOelRJtlQ2drElDcvWIep1yj4TNYKhqsEUA11fzazStUahpLzuTMXGHMDG7AKA8MqBgBUxRW7UPNBxF7_radK4dfUxig_049Dp7nBYpPKl3sRyPfZcm_R0bXrnXfiMj7KEsfenx3_Skr7R0Wtc4asuVcLgYR1PGFMKbAqi_FDLlZYsledP74fGs3pGNnQ46LNaZ7-ZrsDuIOCxsaJ-QKR_zUQni8wmmKYzGmuVTRvSmlk79DCjMhmVJ6B-AOtXLc8N8yoZ35_ZtXc5VyBTdGTYtIE6x7O6kUlNMFZQLwYgRnUQJdwbfSEUAJXD4b7KMQw
    [root@master01 ~]#

    可以看到应用资源清单以后 , 对应sa就成功被创建 , 同时查看sa的详细信息 , 它关联了一个secret资源 , 对应secret资源的详细信息中明确标注了对应sa用户名称为sa-demo ; 从上面反馈的信息我们不难理解 , 创建sa账号 , 它会自动创建一个secret , 并且把对应的secret中的token与sa账号做绑定 ; 这就意味着 , 我们只要拿着对应的token去apiserver认证 , 对应apiserver一定能够在etcd中查到对应的token绑定的sa账号 ; 从而对应sa账号就能顺利的通过apiserver中的认证机制 ;


参考链接

容器编排系统K8s之访问控制--用户认证 - Linux-1874 - 博客园 (cnblogs.com)