回顾

​ 有状态有存储的就需要使用到sts控制器,比如一些常见的扩缩容问题,在K8s之上如果想要定义StatefulSet不建议直接使用StatefulSet,需要使用CordOS提供的第三方解决方案进行配置,配置方式:

底层存储-->pv --> 无头service ,只有基于这个无头服务才能给每个pod分配一个唯一的持久的固定标识符
                sts -- pod   
                    volumeClaimTemplates 让sts自动创建PVC关连pv,然后pod在挂载pvc, volumeMounts

理论来源: Kubernetes证书

系统安全说明

        对于Kubernetes来讲,etcd存储了当前整个集群当中,每一个资源相关用户定义的期望的状态,以及当前在集群之上的资源状态,他们分别保存于资源的spec和status当中,当然也有个别资源没有spec字段,比如像ConfigMap、Secret当中只有data,但是事实上也代表了spec,只不过其过于简单,没有使用spec来进行嵌套而已,如果说etcd宕机那么整个集群的所有状态就丢失了,因此,我们必须要对etcd做高可用,而etcd本身是一个有状态应用,如果它运行于Kubernetes上,那我们应该使用StatefulSet或者etcd的Operator来管理;
        整个集群当中的所有状态数据都必须保存在etcd中,k8s的kube-apiserver是整个etcd存储集群的唯一访问入口,任何客户端都不能直接写etcd,用户要想创建一个Pod资源也必须使用kubeadm这样的工具与apiserver进行通信,将数据先提交给apiserver,然后再由api提交给etcd;
        对于Kubernetes来说,如果有用户提交了所有关于Service的定义,都会被kube-proxy所捕获,并读取到本地转换为Iptables或者Ipvs规则,而Service的定义也需要通过APIServer进行获取,它读取完成并且创建相关规则以后这个创建的结果就结束了,这个结果就是当前状态,也需要保存于etcd,它也需要经过APIServer保存于etcd当中,所以etcd就是一个通用键值存储系统,但是在Kubernetes之上,它不允许随意存取数据,所有能够操作或使用数据的行为,一定是在APIServer内部定义好了的;
        详细创建过程: 当用户创建一个pod资源, 该pod先被调度到集群的任意一个 工作节点 之上, 然后通过 service内核中的 kubelet 调用docker将其运行, 调度器kube-sceduler守护进程也是APIServer的客户端之一, 当有kubectl提交了一个新的Pod定义给APIServer, APIServer自己把etcd的watch机制通知给注册监视相关资源的程序, 而kube-sceduler就像APIServer注册监视了每一个没有没调度结果的相关信息,而kube-sceduler其实也是APIServer的客户端,它需要通过APIServer完成Pod信息的查询,甚至修改,比如把调度的结果保存给etcd当中,它不能够直接操作etcd,而必须要经过APIServer;

字段说明
kube-sceduler负责只是调度它也只应该修改Pod上关于调度结果的字段
controller manager负责更新当前状态,并确保当前状态一定要吻合于用户期望的状态的,
它负责修改status相关的信息
kubelet负责创建Pod并负责更新Pod当前状态信息
kube-proxy负责创建\修改\更新Service相关的信息

        从这个角度来说,我们就没有必要,kube-sceduler拥有controller manager、kube-proxy等相关的权限,还有如果kube-sceduler随便连接到APIService上能随便完成各种调度,那么任何一个人使用kube-sceduler都可以完成集群上的所有操作了,这就乱套了,安全性不言而喻,因此Kubernetes必须对运行其上的所有资源在访问上构建出一个安全的访问机制,或者说访问控制模型来;

连接api时的操作

        在k8s之上的API Server是整个集群的网关,因此它的访问控制功能都是在API Server上实现的, 当客户端发起API Server调用时,API Server 内部要先进行用户认证,然后执行用户授权流程,即通过 “授权策略” 来决定一个API 调用是否合法,对合法用户进行授权,并且随后在用户访问时进行鉴权;
​        k8s是一个高度模块化设计的工具,因此它的认证,授权,准入控制各自都通过插件的方式可以由用户自定义选择经由什么样的插件来完成何种控制逻辑, 由于k8s提供的是restFul风格的接口,它所有服务都通过http协议提供,由此认证信息只能经由http协议的认证首部进行传递(token),

  1. 认证:确认这个客户端是否有权限允许操作API Server中的相关功能;
  2. 授权检查: 检查权限是否有这个权限,进行API Server之后资源调度(资源管理逻辑实现合理的权限指派)
  3. 准入控制: 有两种操作
    1. 检查其定义的资源是否合理;
    2. 检查请求资源时的语法是否合乎规范,
      • 如果不合乎规范,如缺失就给它补齐,这种称为: 便易型准入控制
      • 不符合就拒绝,这种属于合法性的一种准入控制器, 比如请求资源超过用户最大的使用量 如CPU

在这里插入图片描述

认证说明

        对于kube-Apiserver来讲,认证是一种功能,认证有多种认证机制,每一种机制都要一个认证插件, 可以选择在kube-Apiserver启动时,激活哪一个插件,来做认证插件, 甚至于还可以同时激活多个插件,都可以生效,授权、准入控制也一样。但是只有激活的才生效,未激活的不会生效,它的认证逻辑很特别,叫一票通过, 从1到N只 不管顺序只要其中一个通过便算通过, 插件对于不认证的用户不允许也不会拒绝;
        Kubernetes的授权的逻辑有点独特,叫做许可授权, 如:当用户进来只要API Server允许就允许, 没有允许就继续下一个插件检查, 直到通过, 拒绝是默认值, 没有显示告知允许
        准入控制的插件也可以有多个,准入控制插件的逻辑有点独特, 实现一票否决权, 只要其中有一个拒绝,那么整个都算失败, 要不就全部允许

认证插件

Kubernetes支持很多种认证插件,如

  1. Client Certificates(客户端证书认证: 类似就是公私密钥认证的
  2. Passwd:用户名和密码认证,通过base64编码之后通过header传输
  3. Plain Tokens(令牌): 随机字符,称之为令牌,没有用户名;
  4. Bootstrap Tokens(引导令牌,引导集群启动,或者加入集群使用的令牌)
  5. JWT Tokens(JSON的web Token,基于HTTP协议携带json格式的令牌)

kubectl proxy

  1. 获取 api 资源类型

    1. 通过kubectl proxy命令,在本地监听某个端口
    2. 然后就能在通过本地的curl 命令地址:端口 反向代理至apiserver
    # 监听 proxy    
    ~]# kubectl proxy --port=1999
    	Starting to serve on 127.0.0.1:1999
    
    # 列出当前系统上所有namespace所有资源
    ~]# curl http://127.0.0.1:1999/api/v1/namespaces
      # 对象类: pod, Service...  同一类型对象下所有叫集合
        {
            "kind": "NamespaceList",  # 资源类型
            "apiVersion": "v1",
            "metadata": {
                "selfLink": "/api/v1/namespaces",
            },
            "items": [
                {
                    "metadata": {
                        "name": "default",
                        "selfLink": "/api/v1/namespaces/default",
                        "uid": "93b7a2c6-a62f-40dd-830d-caca91104047"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-node-lease",
                        "selfLink": "/api/v1/namespaces/kube-node-lease",
                        "uid": "99cf5fac-605d-4095-97f9-e7f48fe50d7f"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-public",
                        "selfLink": "/api/v1/namespaces/kube-public",
                        "uid": "93e98efe-b0e6-4e56-ae50-5cb41e898c89"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-system",
                        "selfLink": "/api/v1/namespaces/kube-system",
                        "uid": "9832f8fa-b476-496b-b465-6d97a0e97537"
                    }
                }
            ]
        }
    
  2. 获取某个特定的API信息

    • /api/v1: 一种特殊的路径, 只有核心群组才有这样访问逻辑
    • /apis: 只要不是核心群组,都必须要起始与/apis
    # 获取全部的 deployments 所有的对象
    ~]#  curl http://127.0.0.1:1999/apis/apps/v1/namespaces/kube-system/deployments
      "kind": "DeploymentList",
      "apiVersion": "apps/v1",
      "metadata": {
        "selfLink": "/apis/apps/v1/namespaces/kube-system/deployments",
        "resourceVersion": "454268"
      },
    
  3. 只访问某单个资源

    ~]#  curl http://127.0.0.1:1999/apis/apps/v1/namespaces/kube-system/deployments/coredns
      "kind": "Deployment",
      "apiVersion": "apps/v1",
      "metadata": {
        "name": "coredns", ....
       }
    
  4. 访问请求方式

    1. http request: get, port, put, delete
    2. API request: get, list, create, update, patch, edit, watch, redirect, delete, deletecollection(删除一组)
    3. Resource
    4. Subresource
    5. Namespace
    6. API Group
  5. 访问请求总结

    ​ API Server是整个访问请求进入的网关接口,请求过程当中认证用于实现身份识别,而授权实现权限检查,而准入控制机制进一步补充了授权机制,它也一样有多个插件来实现,一般而言只在 创建删除修改或做代理 操作时做补充

k8s认证

在Kubernetes之上认证是双向的,也就是说kubectl接入APIServer时,双方要互相认证

  1. kubectl会把自己的证书提交给APIServer并请求APIServer的证书;
  2. 此时kubectl是客户端证书APIServer是服务端证书,他们互相做双向认证;
  3. kubectl还需要检查证书是否由自己认可信任的机制颁发,该证书持有者所声明的身份要与证书中的身份保持一致,证书还需要在有效期内,一旦条件不满足,认证就失败;
  4. 集群需要很多证书,但是一般Kubernetes集群所有的证书都不会使用一样的,认证通过之后还需要知道这个认证是谁来认证的,如果这个证书颁发给某一个用户了,那么这个证书里面的subject里面的CN就是哪个用户,很显然,每个用户都需要不同的证书,来进行用户身份判断,这样才能做到分用户或分客户端进行不同的授权;

​        Kubernetes对于权限的检查,还需要知道哪个用户的哪个权限,按上面的例子来说用户就是subject里面的CN,所以我们创建的每一个证书的CN的名字还要和Kubernetes内建的用户名一致,subject里面还有一个字段叫做owner,O是用户所属的部门,O就相当于用户的组,CN是用户名,所以我们就可以在Kubernetes上利用Auth Policies对一个组授权,加入到这个组中的所有用户都有同一个权限,所以必要的时候多个用户要拥有通一个权限就可以在同一个组的方式来实现权限控制;

用户类型

  1. Useraccount: 用户客户端操作的用户;
    • 对于客户端用户来说,只需要拥有该 API Server的证书并且认证通过,那么该客户端就能拥有该证书用户的权限。
  2. 服务帐号: 让pod连接server时使用的帐号, 程序作为一个守护进程需要连入APIServer认证并获得相关授权时,它就需要附带着用户身份;
    • 服务帐号是在 k8s 系统上存在的帐号,它是k8s之上的一个标准资源,它通过secrets保存着这个用户帐号要接入APIServer时的密码,作为一个secrets资源存在。

启用证书

APIServer内建了很多认证授权与准入控制插件,最终APIServer启用与否取决在传递的参数选项

  1. Client Certificates:--client-ca-file=SOMEFILE启用证书认证;
  2. Static Token File:静态令牌认证,简单的明文令牌认证
    • --token-auth-file=SOMEFILE启用静态令牌认证;
  3. Bootstrap Tokens:Bootstrap的令牌文件也需要指定,定义方式
    • kube-apiserver使用: --experimental-bootstrap-token-auth选项;
    • kube-controller-manager使用: "--controllers=*,tokencleaner"选项;
  4. ServiceAccount Tokens:
    1. 承载令牌进行数字前面的PEM格式的密钥: --service-account-key-file;
    2. 缺省使用APIServer的TLS私钥,--service-account-lookup是否吊销删除的令牌;

通信方式

kubectl有哪些客户些需要与API Server通信

  1. 集群内部的POD

        pod与api server 通信使用的是集群内的工作地址,通过一个专用于集群内的地址: kubectl get svc查看 指向的是节点地址 Endpoints: 192.168.2.220:6443 而 server 引用到集群内部从而使的pod就能直接请求API Server上的服务了 IP: 10.96.0.1

master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4d

master ~]# kubectl describe svc kubernetes 
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.2.220:6443
Session Affinity:  None
Events:            <none>

# api Server必须要认证后才能进行通信
  1. 集群外部的客户端: 每次访问api server时都使用自己api server所监听的节点地址
            任意版本kubectl客户端只需要配置好连接方式,就连接至master上的api server的监听地址

kubeconfig简介

选项说明
users用户帐号及其认证信息列表
clusters目标集群列表
contexts以哪个user接入哪个clustere的连接组合
curren-context当前使用的context,当前上下文,它可以进行切换
用户@上下文
]# kubectl config view
# 或 ~]# cat .kube/config ,  与kubectl config view结果是一样的
apiVersion: v1
clusters:    # 集群列表,当有多个集群时,可以同时定义多个集群名称
- cluster:   # 集群配置的标识,因为可以有多个所有得有所区分
    certificate-authority-data: DATA+OMITTED  # 集群的CA证书,APIServer所信任的CA的证书
    server: https://192.168.2.220:6443        # 集群Server地址
  name: kubernetes           #  集群名称
contexts:
- context:     # 上下文列表
    cluster: kubernetes      # 这个上下文接入的cluster
    user: kubernetes-admin   # 这个上下文使用的user
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes   # 当前上下文
kind: Config
preferences: {}
users:                          # 用户列表,  当有多个集群,可以定义多个用户
- name: kubernetes-admin        # 定义一个users,名为kubernetes-admin
  user:    # 该user的信息
    client-certificate-data: REDACTED   # 公钥
    client-key-data: REDACTED			# 私钥

# 客户端只需要拿着证书,那么就能够认证成功,而Kubernetes所信任的CA就在我们的/etc/kubernetes/pki里面他们分别是ca.crt和ca.key,那么我们就自己生成一个私钥,手动用这个ca去签署得到一个证书,那拿着这个客户端签署的证书就可以直接接入kube-apiserver,CN代表用户名,能够认证通过,对应的这个获得了哪些权限它就能拥有哪些权限,而且这个用户名不需要在Kubernetes之上存在,系统上有一个组叫做masters,这是一个管理员组,如果创建一个用户加入这个组,那么该用户就是管理员;

Kubernetes证书

整个Kubernetes之上要使用的证书有以下组件:
        etcd:etcd保存着整个Kubernetes集群之上的资源,所以etcd也一定不能非授权访问,它的认证方式和APIServer的方式一样,默认使用证书认证,etcd是服务端,APIServer是etcd的客户端,为了保证etcd不被非授权访问,要做一个专门的CA,让etcd各节点之间通信要使用一个证书,自己做个CA证书,只用于节点之间通信,这叫做节点证书,还需要为每一个节点发送一个Server端证书,而后再给APIServer发生一个Client证书,APIServer与etcd通信也需要拿着Client证书才可以;

对于集群组件连接到APIServer也需要证书:
        这个时候还需要一套CA,然后给各组件通信到APIServer各一套证书,因为上面说过不同组件实现不同功能,组件也不能非授权访问,Kubernetes是没有用户这么一说的,用户的区别主要是以证书里面的信息来区分的,比如说CN就是用户名,所以每个组件的证书我们应该使用不一样的,而不能使用同一个证书,因为Kubernetes组件到APIServer是双向认证的,也就是说APIServer到组件也需要证书,也就是说APIServer->组件,组件->APIServer一套,每个组件两套证书,好在这个APIServer->组件的证书会自己生成;

证书说明:

  • 各节点证书:server端证书,
  • apiserver: client证书
  • apiserver与etcd通信: client证书

授权配置管理

​        至于切换上下文,设置users设置contexts等都可以使用命令行的方式来定义,其主要配置是/etc/kubernetes/admin.conf,

语法kubectl config command [option]

参数说明
set-cluster添加集群
set-context添加一个上下文
set-credentials添加用户信息
set添加集群、添加用户、添加上下文
use-context指定当前使用的上下文
view查看当前配置

ApiServer

​        ApiServer定义了当前资源可以使用哪些资源类型,如Pod、StatefulSet等,如果认为K8s自建的存储方案不够用,需自定义有如下方案

  1. 通过ApiServer直接修改go源代码;

  2. 自建ApiServer,自已写一个程序,将这个程序引入新的资源类型,以Pod方式运行在k8s之上,这种叫自定义资源类型,类型Operator控制器,此处我们只写定ApiServer,而k8s为了开发者更方便开发ApiServer扩展接口,包含了如下组件:

  3. kube-aggregator:用于反代,

  4. kube-apiserver: 默认资源,

  5. extension–apiserver:自定义资源反代

  所以当我们需要自定义Apiserver时只需要配置kube-aggregator,然后将默认资源反代给kube-apiserver,自定义资源反代给extension--apiserver,所以kube-aggregator到extension--apiserver还需要一套证书;

APIServer证书: ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml

k8s证书示例

自建证书

--kubeconfig:指定要配置的配置文件;
--embed-certs:证书和私钥打包存放;
--username:指定用户名,在此处无实际意义,因为用户主要是靠证书的CN来区分的,但是这里最好和证书里面的CN一致;

# 创建一个私钥
]# openssl genrsa -out lzx.key 4096

# 为证书生成一个证书签署请求,并且使用kubernetes的CA来签署, CN代表用户名, 0组织表示组
]# openssl req -new -key lzx.key -out lzx.csr -subj "/CN=xiong/O=kubernetes"

# 使用CA签署证书
]# openssl x509 -req -in lzx.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key  -CAcreateserial -out lzx.crt -days 3650

]# mkdir /etc/kubernetes/lzx
]# mv lzx.* /etc/kubernetes/lzx/

]# openssl x509 -in lzx.crt -text -noout
    Certificate:
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN=kubernetes
            Subject: CN=xiong

使用证书

  1. 配置用户信息, 直接这么配置就是保存在 /etc/k8s/admin.conf中

    ]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt  --client-key=/etc/kubernetes/lzx/lzx.key  --embed-certs=true
    
    ]# kubectl config view
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    - name: xiong     # 自定义的用户
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    
  2. 将user和cluster组合起来形成一个context, 组成一个上下文

# server 集群不动 还是使用 kubernetes的
]# kubectl config set-context xiong-k8s --cluster=kubernetes --user=xiong
Context "xiong-k8s" created.

]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.2.220:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: xiong
  name: xiong-k8s
  1. 切换用户
]# kubectl config use-context xiong-k8s

]# kubectl config view
current-context: xiong-k8s
  1. 测试
]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "xiong" cannot list resource "services" in API group "" in the namespace "default"

# 删除用户 
kubectl config unset users.username   # 相当于 delete user username

# 删除下上文  kubectl config set-context xiong-k8s
kubectl config unset contexts.name    # 如  unset contexts.xiong-k8s

配置文件

# 创建一个新的kubeconfig文件, 配置 集群
]# kubectl config set-cluster xiong-cluster --server=https://192.168.2.220:6443 --certificate-authority=/etc/kubernetes/lzx/lzx.crt --embed-certs=true --kubeconfig=/etc/kubernetes/lzx.conf

# 设定用户配置信息, 配置 用户
]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt --client-key=/etc/kubernetes/lzx/lzx.key --username=xiong --kubeconfig=/etc/kubernetes/lzx.conf --embed-certs=true

# 将user和cluster组合起来形成一个context, 组成一个上下文
]# kubectl config set-context context-xiong --cluster=kubernetes --user=xiong --kubeconfig=/etc/kubernetes/lzx.conf 

# 指定默认使用的context  
]# kubectl config use-context --kubeconfig=/etc/kubernetes/lzx.conf  context-xiong 
Switched to context "context-xiong".

# 测试使用该配置连接Kubernetes集群
]# kubectl get pods --kubeconfig=/etc/kubernetes/lzx.conf  # 权限被拒绝
error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable

# 系统k8s上下文: 

最终还是切换回原先版本:

]# kubectl config use-context kubernetes-admin@kubernetes
# 在次访问,就没有环境变量问题了

serviceaccount

牢记:认证不代表权限, 权限需要有授权

Kubernetes之上的认证用户有两种

  1. 常规用户: UserAccount,
  2. ServiceAccount

​        在创建SA资源时,指定用户的认证信息需要靠secrets来提供,这个secrets可以不非得是tls帐号密码,因为我们证书和私钥都在secrets当中,如果需要定义为tls类型,可以用于ssl通信而不是用于认证,因此这里的SA不能使用secret创建时的tls类型,而是应该使用generic类型的证书,我们在创建SA时可以不用自行定义secrets,在创建时k8s会自动生成一个secerts,其保存了相关用户的认证信息,
​        每一个ServiceAccount的定义方式很简单,简称为SA,在创建SA资源的时候我们可以指定metadata.name来指定该SA的名称,metadata.namespace来指定该ServiceAccount所属的namespace,当前用户的认证信息是什么则需要靠secrets来提供,这个secrets可以不用非得是tls帐号密码,因为我们的证书和私钥在secrets当中,如果要定义为tls类型的,那是用于ssl通信的,而不是用于认证的,而认证不代表权限,权限需要有授权

认证信息说明

]# 查看某一个pod的详细信息, kubectl describe pods PODNAME
Volumes:
  default-token-cbkjx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-cbkjx
    Optional:    false
    
# 通过secret定义,并以存储卷的方式关连到pod,从而让pod内的应用通过对应的secret保存的认证信息来连接API Server并完成认证

]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-cbkjx   kubernetes.io/service-account-token   3      4d3h

]# kubectl describe secrets default-token-cbkjx 
Name:         default-token-cbkjx
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 4b1cf2dc-b8c6-45fa-8b6d-46b9d746e037

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      xxxxx

其它pod认证

]# kubectl get pods -n ingress-nginx 
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-67754f4878-fr8cz   1/1     Running   0          35m

]# kubectl describe pods -n ingress-nginx nginx-ingress-controller-67754f4878-fr8cz 
Volumes:
  nginx-ingress-serviceaccount-token-lh6vj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  nginx-ingress-serviceaccount-token-lh6vj
    Optional:    false
    
]#  kubectl get secrets -n ingress-nginx 
NAME                            TYPE                                  DATA   AGE
nginx-ingress-serviceaccount-token-lh6vj   kubernetes.io/service-account-token   3      37m

]# kubectl describe secrets -n ingress-nginx nginx-ingress-serviceaccount-token-lh6vj 
Name:         nginx-ingress-serviceaccount-token-lh6vj
Namespace:    ingress-nginx
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: nginx-ingress-serviceaccount
              kubernetes.io/service-account.uid: 3fba317a-efc3-499d-8dc9-b692f50df714

Type:  kubernetes.io/service-account-token

Data
====
token:      xxxxxxx
ca.crt:     1025 bytes
namespace:  13 bytes

sa-示例

牢记, 认证不代表权限, 权限需要有授权

  1. 创建serviceaccount

    # serviceAccount不带权限, 通过RBAC可以增加权限
    
    ]# kubectl create serviceaccount mysa
    
  2. 查看详细页

    ]# kubectl describe serviceaccounts mysa
    Name:                mysa
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   mysa-token-tddm9
    Tokens:              mysa-token-tddm9
    Events:              <none>
    
    # 通过 -o yaml可以查看创建yaml内容
    ]# kubectl get serviceaccounts mysa -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: "2020-05-11T07:16:16Z"
      name: mysa
      namespace: default
      resourceVersion: "859176"
      selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
      uid: 5d361efd-18aa-4c42-9dc6-cc71b08bcee7
    secrets:
    - name: mysa-token-tddm9
    
  3. 查看secrets

    ]# kubectl get secrets 
    	# k8s自动生成token,用于让sa连接至当前系统api 认证信息,认证不表达权限, 权限需要有授权
    	
    NAME                  TYPE                                  DATA   AGE
    mysa-token-tddm9      kubernetes.io/service-account-token   3      3m4s
    
  4. 认证详情

    ]# kubectl describe secrets mysa-token-tddm9 
    Name:         mysa-token-tddm9
    Namespace:    default
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: mysa
                  kubernetes.io/service-account.uid: 5d361efd-18aa-4c42-9dc6-cc71b08bcee7
    
    Type:  kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt:     1025 bytes
    namespace:  7 bytes
    token:      token内容
    
  5. pod使用自定义sa

    # 1、创建一个sa,
    ~]# kubectl describe sa podsa
    
    ~]# kubectl describe sa podsa 
    Name:                podsa
    Namespace:           default
    Tokens:              podsa-token-nfbns
    
    # 2、定义pod
    ]#   cat pod_sa.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-sa
      labels:
        name: pod-sa
    spec:
      containers:
      - name: pod-sa
        image: ikubernetes/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        readinessProbe:
          failureThreshold: 5
          initialDelaySeconds: 3
          tcpSocket:
            port: http
      serviceAccountName: podsa   # 只需要指定sa,认证不代表权限, 权限需要有授权
      
    ]#  kubectl describe pod pod-sa
    Name:         pod-sa
    Namespace:    default
    Containers:
      pod-sa:
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from podsa-token-nfbns (ro)
    Volumes:
      podsa-token-nfbns:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  podsa-token-nfbns
        Optional:    false
    

资源清单提供给api server时,api server告诉 kubenet, 创建并运行Pod, pod中的容器依赖于私有register,部分私有register就需要提供用户帐号密码了

为pod获取私有register的两种方式:

  1. 在pod上直接使用imagesecrtePull字段指定能认证完成的sercret对象
  2. 在pod上自定义一个sa, 附加一个Image pull secrets对象

授权

   ]#  kubectl describe pod pod-sa
   Name:         pod-sa
   Namespace:    default
   Containers:
     pod-sa:
       Mounts:
         /var/run/secrets/kubernetes.io/serviceaccount from podsa-token-nfbns (ro)
   Volumes:
     podsa-token-nfbns:
       Type:        Secret (a volume populated by a Secret)
       SecretName:  podsa-token-nfbns
       Optional:    false

        资源清单提供给api server时,api server告诉 kubenet, 创建并运行Pod, pod中的容器依赖于私有register,部分私有register就需要提供用户帐号密码了

为pod获取私有register的两种方式:

  1. 在pod上直接使用imagesecrtePull字段指定能认证完成的sercret对象
  2. 在pod上自定义一个sa, 附加一个Image pull secrets对象
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐