K8S认证体系与ServiceAccount
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Kubernetes认证体系概述
1.API Server内置的访问控制机制
API Server的访问方式:
- 集群外部: https://IP:Port
- 集群内部: https://kubernetes.default.svc
API Server内置了插件化的访问控制机制(每种访问控制机制均有一组专用的插件栈)
认证(Authentication):
核验请求者身份的合法性,进行身份识别,验证客户端身份。
身份核验过程遵循“或”逻辑,且任何一个插件核验成功后都将不再进行后续的插件验证。
均不成功,则失败,或以“匿名者”身份访问,建议禁用“匿名者”。
授权(Authorization):
核验请求的操作是否获得许可,验证客户端是否有权限操作资源对象。
鉴权过程遵循“或”逻辑,且任何一个插件对操作的许可授权后都将不再进行后续的插件验证。
均未许可,则拒绝请求的操作
准入控制(Admission Control):
检查操作内容是否合规,仅同"写"请求相关,负责实现"检验"字段类型是否合法及和补全默认字段。
内容合规性检查过程遵循“与”逻辑,且无论成败,每次的操作请求都要经由所有插件的检验。
将数据写入etcd前,负责检查内容的有效性,因此仅对“写”操作有效。
分两类:validating(校验)和 mutating(补全或订正)。
2.Kubernetes上的用户
“用户”即服务请求者的身份指代,一般使用身份标识符进行识别,比如用户名,用户组,服务账号,匿名用户等。
Kubernetes系统的用户大体可分Service Account,User Account和Anonymous Account。
Service Account:
Kubernetes内置的资源类型,用于Pod内的进程访问API Server时使用的身份信息。
引用格式: "system:serviceaccount:NAMESPACE:SA_NAME"
User Account:
用户账户,指非Pod类的客户端访问API Server时使用的身份标识,一般是现实中的“人”。
API Server没有为这类账户提供保存其信息的资源类型,相关的信息通常保存于外部的文件或认证系统中。
身份核验操作可由API Server进行,也可能是由外部身份认证服务完成。
Anonymous Account:
不能被识别为Service Account,也不能被识别为User Account的用户。
这类账户K8S系统称之为"system:anonymous",即“匿名用户”。
3.身份认证策略
- X.509客户端证书认证:
在双向TLS通信中,客户端持有数字证书信任的CA,需要在kube-apiserver程序启动时,通过--client-ca-file选项传递。
认证通过后,客户端数字证书中的CN(Common Name)即被识别为用户名,而O(Organization)被识别为组名。
kubeadm部署的K8s集群,默认使用"/etc/kubernetes/pki/ca.crt"(各组件间颁发数字证书的CA)进行客户端认证。
- 持有者令牌:
- 1.静态令牌文件(Static Token File):
令牌信息保存于文本文件中,由kube-apiserver在启动时通过--token-auth-file选项加载。
加载完成后的文件变动,仅能通过重启程序进行重载,因此,相关的令牌会长期有效。
客户端在HTTP请求中,通过“Authorization: Bearer TOKEN”标头附带令牌令牌以完成认证。
- 2.Bootstrap令牌:
一般用于加入集群时使用,尤其是在集群的扩容场景时会用到。
- 3.Service Account令牌:
该认证方式将由kube-apiserver程序内置直接启用,它借助于经过签名的Bearer Token来验证请求。
签名时使用的密钥可以由--service-account-key-file选项指定,也可以默认使用API Server的tls私钥
用于将Pod认证到API Server之上,以支持集群内的进程与API Server通信。
K8s可使用ServiceAccount准入控制器自动为Pod关联ServiceAccount。
- 4.OIDC(OpenID Connect)令牌:
有点类似于"微信","支付宝"认证的逻辑,自建的话需要配置认证中心。
OAuth2认证机制,通常由底层的IaaS服务所提供。
- 5.Webhook令牌:
基于web的形式进行认证,比如之前配置的"钉钉机器人","微信机器人"等;
是一种用于验证Bearer Token的回调机制,能够扩展支持外部的认证服务,例如LDAP等。
- 身份认证代理(Authenticating Proxy):
由kube-apiserver从请求报文的特定HTTP标头中识别用户身份,相应的标头名称可由特定的选项配置指定。
kube-apiserver应该基于专用的CA来验证代理服务器身份。
- 匿名请求:
生产环境中建议禁用匿名认证。
4.API Server启用的身份认证机制
基于认证插件支持多种认证方式,而相应认证插件的启用需要经由kube-apiserver上的专用选项完成。
kubeadm v1.23.17部署的集群默认启用的认证机制如上图红框中的选项,它们依次是
- 1.X509客户端证书认证
- 2.Bootstrap令牌认证
- 3.身份认证代理
- 4.Service Account认证
值得注意的是,API Server并不保证各认证插件的生效次序与定义的次序相同。
5.kubelet启用的身份认证机制
如上图所示,kubelet默认开启了客户端身份进行认证。
API Server是该API端点的客户端,因此,kubelet需要在验证客户端身份时信任给API Server颁发数字证书的CA
kubelet的REST API端点默认通过TCP协议的10250端口提供,支持管理操作如下表所示。
Kubernetes API | 功能描述 |
---|---|
/pods | 列出当前kubelet节点的Pod列表。 |
/run | 在一个容器内运行指定的命令。 |
/exec | 在一个容器内运行指定的命令。 |
/configz | 设置kubelet的配置文件参数。 |
/debug | 调试信息。 |
二.静态令牌文件认证测试案例
1.模拟生成token
[root@master231 ~]# echo "$(openssl rand -hex 3).$(openssl rand -hex 8)"
309837.3a7a5c1fe08fb422
[root@master231 ~]#
[root@master231 ~]# echo "$(openssl rand -hex 3).$(openssl rand -hex 8)"
f2285b.39b1c2eeb4d22e51
[root@master231 ~]#
[root@master231 ~]# echo "$(openssl rand -hex 3).$(openssl rand -hex 8)"
f13928.3c1423beb3eb5d98
[root@master231 ~]#
2.创建csv文件
[root@master231 yinzhengjie-authCase]# cat token.csv
309837.3a7a5c1fe08fb422,yinzhengjie,10001,k8s
f2285b.39b1c2eeb4d22e51,jasonyin,10002,k8s
f13928.3c1423beb3eb5d98,jiege,10003,k3s
[root@master231 yinzhengjie-authCase]#
温馨提示:
文件格式为CSV,每行定义一个用户,由“令牌、用户名、用户ID和所属的用户组”四个字段组成,用户组为可选字段
具体格式: token,user,uid,"group1,group2,group3"
3.修改api-server参数加载token文件
[root@master231 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
...
spec:
containers:
- command:
- kube-apiserver
- --token-auth-file=/etc/kubernetes/yinzhengjie-authCase/token.csv
...
volumeMounts:
...
- mountPath: /etc/kubernetes/yinzhengjie-authCase/token.csv
name: yinzhengjie-static-token-file
readOnly: true
...
volumes:
...
- hostPath:
path: /etc/kubernetes/yinzhengjie-authCase/token.csv
type: File
name: yinzhengjie-static-token-file
status: {}
[root@master231 ~]#
4.kubectl使用token认证并指定api-server的证书
[root@worker232 ~]# kubectl --server=https://10.0.0.231:6443 --token=309837.3a7a5c1fe08fb422 --certificate-authority=/etc/kubernetes/pki/ca.crt get nodes
Error from server (Forbidden): nodes is forbidden: User "yinzhengjie" cannot list resource "nodes" in API group "" at the cluster scope
[root@worker232 ~]#
5.kubectl使用token认证并跳过证书校验
[root@worker232 ~]# kubectl --server=https://10.0.0.231:6443 --token=f2285b.39b1c2eeb4d22e51 --insecure-skip-tls-verify get nodes
Error from server (Forbidden): nodes is forbidden: User "jasonyin" cannot list resource "nodes" in API group "" at the cluster scope
[root@worker232 ~]#
6.curl基于token认证案例
[root@worker232 ~]# curl -k https://10.0.0.231:6443 # 如果不指定认证信息,将被识别为匿名"system:anonymous"用户。
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
[root@worker232 ~]# curl -k -H "Authorization: Bearer f13928.3c1423beb3eb5d98" https://10.0.0.231:6443/api/v1/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"jiege\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
}
三.X509 数字证书认证测试案例
1.基于API-Server签发
1.1 创建证书签署请求
1.创建证书签署请求的密钥
[root@master231 ~]# openssl genrsa -out jasonyin.key 2048
[root@master231 ~]#
[root@master231 ~]# ll jasonyin.key
-rw------- 1 root root 1704 Feb 20 21:36 jasonyin.key
[root@master231 ~]#
2.创建证书签署请求
[root@master231 ~]# openssl req -new -key jasonyin.key -out jasonyin.csr -subj "/CN=jasonyin/O=jiege"
[root@master231 ~]#
[root@master231 ~]# ll jasonyin.*
-rw-r--r-- 1 root root 911 Feb 20 21:37 jasonyin.csr
-rw------- 1 root root 1704 Feb 20 21:36 jasonyin.key
[root@master231 ~]#
3.将证书签署请求证书使用base64编码
[root@master231 ~]# cat jasonyin.csr | base64 | tr -d '\n'
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2FEQ0NBVkFDQVFBd0l6RVJNQThHQTFVRUF3d0lhbUZ6YjI1NWFXNHhEakFNQmdOVkJBb01CV3BwWldkbApNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQW5rdGFVMmw0NmpqK2VVY3VML1JpCnYzU044RTlxM1ZOczRTUkJqRy9RcDh1UXpOUGd2Mm00MldpZFBERFZpOUFwVWdxajJSc0d4WjFJQ2w1MFBlcWUKOG51TFh0T21ZWTNlVC9iVmtsVVlyMThKbUpGMFFPNTVYanpXckN3MXdJcWhLL0RJOTE3Z1poR0hBNlFsd1ZrSwplSm50OGJkT2tNRVdjVndncENWcHlOUnNFQS9VNDZTWDlEL0ljRzUydWlQVW1zTGI5eUk4WmUzK2FubzlnQkVmCndOV1Rnbkk5dEtUN3pvUTNlVlBYYjByclJtcFVTOTNqT1ZRSStGcEw4ZWxIa2VLOWJ5WW90NUlYUFFFYWlVa0QKeGc5SjN5eTdtb2VGSmZjNDJPR1lmcjZ6T256a295YUt6VjdJQi9xMmlmN1oyUXlPMFZvcW83TXdOK0t6YjNqSwp0UUlEQVFBQm9BQXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRWgxV0ZJRkpVOGJiUVJXeUZFT0RBMnloeThUCmJHS0g1ODZSRFFZdjlIS1BpOGUwMVRxRDBFbFFDQjNQYWsrRU1uZGRLc2xVS1JYTXZ1eFdVckRnc3lsbEFVVTkKL09YZ2E3dENGV2dNYkVHdFg5ZDlDcThTdUxqWHErZ04wSnJFNVFyamN1NEQ0RC85T0NOekZ3c1plZkRiZ0xRSQo2RnZmT3haRm9DOEI4SHVOTmFoZUVSVkI3MDZVTGVMQlZQSXMyZC85WjZlYnM4dWd5OW1tUVJOY0RTb2lXOXFsCjNieTZlMnV1TWRxRUw3N1Y2SkV0UkRQaUJNanNtNmhSU3VVc25sZjdwUndmNGxUcEw3bjhONUlRQzlLY2R6aFUKc0ozcFprR3phM1FRbkt3L1dHdWFOUFl2VEpJeFJtN2tFUlE0VTJmK1dMSlA4VkRldWFGTDdGRWR4V1E9Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
1.2 手动创建csr资源
1.编写资源清单,将证书签署请求编码后的数据使用csr资源封装
[root@master231 ~]# cat certificateSigningRequests-jason.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: jasonyin-csr
spec:
# 将证书签发请求使用base64编码
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2FEQ0NBVkFDQVFBd0l6RVJNQThHQTFVRUF3d0lhbUZ6YjI1NWFXNHhEakFNQmdOVkJBb01CV3BwWldkbApNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQW5rdGFVMmw0NmpqK2VVY3VML1JpCnYzU044RTlxM1ZOczRTUkJqRy9RcDh1UXpOUGd2Mm00MldpZFBERFZpOUFwVWdxajJSc0d4WjFJQ2w1MFBlcWUKOG51TFh0T21ZWTNlVC9iVmtsVVlyMThKbUpGMFFPNTVYanpXckN3MXdJcWhLL0RJOTE3Z1poR0hBNlFsd1ZrSwplSm50OGJkT2tNRVdjVndncENWcHlOUnNFQS9VNDZTWDlEL0ljRzUydWlQVW1zTGI5eUk4WmUzK2FubzlnQkVmCndOV1Rnbkk5dEtUN3pvUTNlVlBYYjByclJtcFVTOTNqT1ZRSStGcEw4ZWxIa2VLOWJ5WW90NUlYUFFFYWlVa0QKeGc5SjN5eTdtb2VGSmZjNDJPR1lmcjZ6T256a295YUt6VjdJQi9xMmlmN1oyUXlPMFZvcW83TXdOK0t6YjNqSwp0UUlEQVFBQm9BQXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRWgxV0ZJRkpVOGJiUVJXeUZFT0RBMnloeThUCmJHS0g1ODZSRFFZdjlIS1BpOGUwMVRxRDBFbFFDQjNQYWsrRU1uZGRLc2xVS1JYTXZ1eFdVckRnc3lsbEFVVTkKL09YZ2E3dENGV2dNYkVHdFg5ZDlDcThTdUxqWHErZ04wSnJFNVFyamN1NEQ0RC85T0NOekZ3c1plZkRiZ0xRSQo2RnZmT3haRm9DOEI4SHVOTmFoZUVSVkI3MDZVTGVMQlZQSXMyZC85WjZlYnM4dWd5OW1tUVJOY0RTb2lXOXFsCjNieTZlMnV1TWRxRUw3N1Y2SkV0UkRQaUJNanNtNmhSU3VVc25sZjdwUndmNGxUcEw3bjhONUlRQzlLY2R6aFUKc0ozcFprR3phM1FRbkt3L1dHdWFOUFl2VEpJeFJtN2tFUlE0VTJmK1dMSlA4VkRldWFGTDdGRWR4V1E9Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
# 指定颁发证书的请求类型,仅支持如下三种,切均可以由kube-controllmanager中的“csrsigning”控制器发出。
# "kubernetes.io/kube-apiserver-client":
# 颁发用于向kube-apiserver进行身份验证的客户端证书。
# 对该签名者的请求是Kubernetes控制器管理器从不自动批准。
#
# "kubernetes.io/kube-apiserver-client-kubelet":
# 颁发kubelets用于向kube-apiserver进行身份验证的客户端证书。
# 对该签名者的请求可以由kube-controllermanager中的“csrapproving”控制器自动批准。
#
# "kubernetes.io/kubelet-serving":
# 颁发kubelets用于服务TLS端点的证书,kube-apiserver可以连接到这些端点安全。
# 对该签名者的请求永远不会被kube-controllmanager自动批准。
signerName: kubernetes.io/kube-apiserver-client
# 指定证书的过期时间,此处我设置的是24h(3600*24=86400)
expirationSeconds: 86400
# 指定在颁发的证书中请求的一组密钥用法。
# 对TLS客户端证书的请求通常请求:
# “数字签名(digital signature)”、“密钥加密(key encipherment)”、“客户端身份验证(client auth)”。
# 对TLS服务证书的请求通常请求:
# “密钥加密(key encipherment)”、“数字签名(digital signature)”、“服务器身份验证(server auth)”。
#
# 有效值的值为: "signing", "digital signature", "content commitment", "key encipherment","key agreement",
# "data encipherment", "cert sign", "crl sign", "encipher only", "decipher only", "any", "server auth",
# "client auth", "code signing", "email protection", "s/mime", "ipsec end system", "ipsec tunnel","ipsec user",
# "timestamping", "ocsp signing", "microsoft sgc", "netscape sgc"。
usages:
- client auth
[root@master231 ~]#
2.创建csr资源
[root@master231 ~]# kubectl apply -f certificateSigningRequests-jason.yaml
certificatesigningrequest.certificates.k8s.io/jasonyin-csr created
[root@master231 ~]#
[root@master231 ~]# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
jasonyin-csr 5s kubernetes.io/kube-apiserver-client kubernetes-admin 24h Pending
[root@master231 ~]#
1.3 管理员手动签署(approve)证书请求csr
1.为签署证书的状态为Pending
[root@master231 ~]# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
jasonyin-csr 67s kubernetes.io/kube-apiserver-client kubernetes-admin 24h Pending
[root@master231 ~]#
2.手动批准证书
[root@master231 ~]# kubectl certificate approve jasonyin-csr
certificatesigningrequest.certificates.k8s.io/jasonyin-csr approved
[root@master231 ~]#
3.再次查看证书状态
[root@master231 ~]# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
jasonyin-csr 80s kubernetes.io/kube-apiserver-client kubernetes-admin 24h Approved,Issued
[root@master231 ~]#
1.4 获取签发后的证书
1.获取签发后的证书
[root@master231 ~]# kubectl get csr jasonyin-csr -o jsonpath='{.status.certificate}' | base64 -d > jasonyin.crt
[root@master231 ~]#
[root@master231 ~]# ll jasonyin.crt
-rw-r--r-- 1 root root 1111 Feb 20 22:23 jasonyin.crt
[root@master231 ~]#
2.将证书拷贝到客户端节点,便于后续使用
[root@master231 ~]# scp jasonyin.key jasonyin.crt 10.0.0.232:/opt
1.5 使用签发后的证书进行认证
[root@worker232 ~]# kubectl -s https://10.0.0.231:6443 --client-key /opt/jasonyin.key --client-certificate /opt/jasonyin.crt --insecure-skip-tls-verify get nodes
Error from server (Forbidden): nodes is forbidden: User "jasonyin" cannot list resource "nodes" in API group "" at the cluster scope
[root@worker232 ~]#
2.手动签发证书【扩展】
2.1 创建证书签发请求
1.进入到K8S集群证书目录
[root@master231 ~]# cd /etc/kubernetes/pki/
[root@master231 pki]#
[root@master231 pki]# ls
apiserver.crt apiserver.key ca.crt front-proxy-ca.crt front-proxy-client.key
apiserver-etcd-client.crt apiserver-kubelet-client.crt ca.key front-proxy-ca.key sa.key
apiserver-etcd-client.key apiserver-kubelet-client.key etcd front-proxy-client.crt sa.pub
[root@master231 pki]#
2.创建证书签发请求
[root@master231 pki]# openssl genrsa -out jiege.key 4096
[root@master231 pki]#
[root@master231 pki]# openssl req -new -key jiege.key -out jiege.csr -subj "/CN=jiege/O=k8s"
[root@master231 pki]#
[root@master231 pki]# ll jiege.*
-rw-r--r-- 1 root root 1598 Feb 20 22:37 jiege.csr
-rw------- 1 root root 3268 Feb 20 22:37 jiege.key
[root@master231 pki]#
温馨提示:
如果我们是管理员,且可以访问到API-SERVER的CA证书文件,完全可以基于CA证书手动签发,步骤更加简单。
2.2 手动签发证书
1.手动签发证书
[root@master231 pki]# openssl x509 -req -days 1 -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -in jiege.csr -out jiege.crt
Certificate request self-signature ok
subject=CN = jiege, O = k8s
[root@master231 pki]#
[root@master231 pki]# ll jiege.*
-rw-r--r-- 1 root root 1354 Feb 20 22:39 jiege.crt
-rw-r--r-- 1 root root 1598 Feb 20 22:37 jiege.csr
-rw------- 1 root root 3268 Feb 20 22:37 jiege.key
[root@master231 pki]#
2.将证书拷贝到客户端节点,便于后续使用
[root@master231 ~]# scp jiege.key jiege.crt 10.0.0.233:/opt
2.3 使用签发后的证书认证
[root@worker233 ~]# kubectl -s https://10.0.0.231:6443 --client-key /opt/jiege.key --client-certificate /opt/jiege.crt --insecure-skip-tls-verify get cs
Error from server (Forbidden): componentstatuses is forbidden: User "jiege" cannot list resource "componentstatuses" in API group "" at the cluster scope
[root@worker233 ~]#
四.kubeconfig文件管理认证信息
1.kubeconfig的组成部分
kubeconfig是YAML格式的文件,用于存储身份认证信息,以便于客户端加载并认证到API Server。
kubeconfig保存有认证到一至多个Kubernetes集群的相关配置信息,并允许管理员按需在各配置间灵活切换
clusters:
Kubernetes集群访问端点(API Server)列表。
users:
认证到API Server的身份凭据列表。
contexts:
将每一个user同可认证到的cluster建立关联的上下文列表。
current-context:
当前默认使用的context。
2.客户端程序加载的kubeconfig文件顺序
客户端程序加载的kubeconfig文件的途径及次序如下所示:
- 1.--kubeconfig;
- 2.KUBECONFIG环境变量:其值是包含有kubeconfig文件的列表
- 3.默认路径:$HOME/.kube/config
当然,我们也可以使用别名来使用上面任意一种方式来管理kubeconfig文件。
3.为静态令牌认证的用户生成kubeconfig实战
3.1 定义集群
1.创建一个集群
[root@master231 ~]# kubectl config set-cluster myk8s --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://10.0.0.231:6443" --kubeconfig=./yinzhengjie-k8s.conf
Cluster "myk8s" set.
[root@master231 ~]#
[root@master231 ~]# ll yinzhengjie-k8s.conf
-rw------- 1 root root 1663 Feb 20 23:15 yinzhengjie-k8s.conf
[root@master231 ~]#
2.查看集群信息
[root@master231 ~]# kubectl config get-clusters --kubeconfig=./yinzhengjie-k8s.conf
NAME
myk8s
[root@master231 ~]#
3.2 定义用户
1.查看令牌认证文件
[root@master231 ~]# cat /etc/kubernetes/yinzhengjie-authCase/token.csv
309837.3a7a5c1fe08fb422,yinzhengjie,10001,k8s
f2285b.39b1c2eeb4d22e51,jasonyin,10002,k8s
f13928.3c1423beb3eb5d98,jiege,10003,k3s
[root@master231 ~]#
2.创建用户信息
[root@master231 ~]# kubectl config set-credentials yinzhengjie --token="309837.3a7a5c1fe08fb422" --kubeconfig=./yinzhengjie-k8s.conf
User "yinzhengjie" set.
[root@master231 ~]#
[root@master231 ~]# kubectl config set-credentials jasonyin --token="f2285b.39b1c2eeb4d22e51" --kubeconfig=./yinzhengjie-k8s.conf
User "jasonyin" set.
[root@master231 ~]#
3.查看用户信息
[root@master231 ~]# kubectl config get-users --kubeconfig=./yinzhengjie-k8s.conf
NAME
jasonyin
yinzhengjie
[root@master231 ~]#
3.3 定义上下文
1.定义上下文
[root@master231 ~]# kubectl config set-context yinzhengjie@myk8s --user=yinzhengjie --cluster=myk8s --kubeconfig=./yinzhengjie-k8s.conf
Context "yinzhengjie@myk8s" created.
[root@master231 ~]#
[root@master231 ~]# kubectl config set-context jasonyin@myk8s --user=jasonyin --cluster=myk8s --kubeconfig=./yinzhengjie-k8s.conf
Context "jasonyin@myk8s" created.
[root@master231 ~]#
2.查看上下文列表
[root@master231 ~]# kubectl config get-contexts --kubeconfig=./yinzhengjie-k8s.conf
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
jasonyin@myk8s myk8s jasonyin
yinzhengjie@myk8s myk8s yinzhengjie
[root@master231 ~]#
3.4 定义当前使用的上下文
1.定义当前使用的上下文
[root@master231 ~]# kubectl config use-context yinzhengjie@myk8s --kubeconfig=./yinzhengjie-k8s.conf
Switched to context "yinzhengjie@myk8s".
[root@master231 ~]#
2.查看当前使用的上下文
[root@master231 ~]# kubectl config current-context --kubeconfig=./yinzhengjie-k8s.conf
yinzhengjie@myk8s
[root@master231 ~]#
[root@master231 ~]# kubectl config get-contexts --kubeconfig=./yinzhengjie-k8s.conf
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
jasonyin@myk8s myk8s jasonyin
* yinzhengjie@myk8s myk8s yinzhengjie
[root@master231 ~]#
3.5 查看kubeconfig信息
1.打印kubeconfig信息,默认会使用“REDACTED”或者“DATA+OMITTED”关键字隐藏证书信息。
[root@master231 ~]# kubectl config view --kubeconfig=./yinzhengjie-k8s.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.231:6443
name: myk8s
contexts:
- context:
cluster: myk8s
user: jasonyin
name: jasonyin@myk8s
- context:
cluster: myk8s
user: yinzhengjie
name: yinzhengjie@myk8s
current-context: yinzhengjie@myk8s
kind: Config
preferences: {}
users:
- name: jasonyin
user:
token: REDACTED
- name: yinzhengjie
user:
token: REDACTED
[root@master231 ~]#
2.查看源文件格式【危险,证书会被泄露】
[root@master231 ~]# kubectl config view --kubeconfig=./yinzhengjie-k8s.conf --raw
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJME1USXhOVEEzTkRZek1Gb1hEVE0wTVRJeE16QTNORFl6TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUk3CjQrNTBsR09mVm1TenRlL3R1SStqMlgvY2R3cWZWR0lydkN5TWROM3dFd3hnQjFhb3k0SDU1c2tIcUI0MGdRS3cKbXR4ZjVyRFlFRS9iMXdPWmdXL1h6RTU2dUx2enRvQjBtNEpmdVhGT3pMOExqVUx2OXMvbDVEUWFJOFVidVVSWApnZ1NEYnlhQnFqZDljcU0yY3hubjR3VC9SZktReURtaUJ2Nnp4MFd3USszMUlac3hDMzJGZU5Zb05GbWpxTjFpCnB4R09aRTN0QmtWYUl4cHVlRjdLVnpNQU1mMjR4NlcwZUZhd015LzZ6Wmt4emw2bDZ0cWh5cWVTUEltZm9lcW0KVVUwMzRYODNoUWdCalBEYU9nQ2gvMFUzbkZCWW5yN25DcTBUK1lPbmhaQ1NldUVxaU5Vd2JRTXFEUE04QzhlTQpPb29ZdkY4RGVXU3ZmNHo2aS9zQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZLbG9PNlZuelI3R0g3QW14ZUlrazRPMDZCTy9NQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmk5VkZnU2k4d2JrR1piYVVHTgpFYithMDRXenRXU1crTUVrTGNBYmNyYjhwaGlsa2NBY3puNitrRmhwUy92eWJ2N1ViSUlMUGZXRmp0SEdNSVNvCklRV3o5K0FsdDhieVZmMGR5cHdTVTlBZ1BnSXhySy90ZXNQc0ZmcmprK0w1elVHaUhpOEg1M09pZ3F1ZU1vYVAKL0pVQXZ5TitjeGEyYWF6ZDJiVUd5eVNjZEo5bU5Zd3RtenZxdFQyU3hzTU9MeUNQczBHS2YvNmV6UGpDUFhRYgpKWDhwTHpmclZwSzhRN1NxNGltS01EeldadFVQeURJQXo0RTE4WEZ4aTdUd1UxVDlNckd5dUREenRpOXQ2OUdiCnFid1VyQlk3ekg4cStCOGNCM0lwY014NzJBcllyQmxIVHdQYjZONU84aXZrb3hQOExNSVNmL0lpSXhGVXVWbUMKRDljPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://10.0.0.231:6443
name: myk8s
contexts:
- context:
cluster: myk8s
user: jasonyin
name: jasonyin@myk8s
- context:
cluster: myk8s
user: yinzhengjie
name: yinzhengjie@myk8s
current-context: yinzhengjie@myk8s
kind: Config
preferences: {}
users:
- name: jasonyin
user:
token: f2285b.39b1c2eeb4d22e51
- name: yinzhengjie
user:
token: 309837.3a7a5c1fe08fb422
[root@master231 ~]#
3.6 使用kubeconfig文件验证
1.不难发现,默认使用的是"yinzhengjie@myk8s"上下文验证的
[root@master231 ~]# kubectl --kubeconfig=./yinzhengjie-k8s.conf get nodes
Error from server (Forbidden): nodes is forbidden: User "yinzhengjie" cannot list resource "nodes" in API group "" at the cluster scope
[root@master231 ~]#
2.使用指定的"jasonyin@myk8s"上下文验证
[root@master231 ~]# kubectl --kubeconfig=./yinzhengjie-k8s.conf get nodes --context="jasonyin@myk8s"
Error from server (Forbidden): nodes is forbidden: User "jasonyin" cannot list resource "nodes" in API group "" at the cluster scope
[root@master231 ~]#
4.为X509 数字证书的用户生成kubeconfig实战
4.1 添加证书用户
1.添加证书用户
[root@master231 ~]# kubectl config set-credentials jiege --client-certificate=/etc/kubernetes/pki/jiege.crt --client-key=/etc/kubernetes/pki/jiege.key --embed-certs=true --kubeconfig=./yinzhengjie-k8s.conf
User "jiege" set.
[root@master231 ~]#
2.查看用户列表
[root@master231 ~]# kubectl config get-users --kubeconfig=./yinzhengjie-k8s.conf
NAME
jasonyin
jiege
yinzhengjie
[root@master231 ~]#
4.2 创建上下文
1.配置上下文
[root@master231 ~]# kubectl config set-context jiege@myk8s --user=jiege --cluster=myk8s --kubeconfig=./yinzhengjie-k8s.conf
Context "jiege@myk8s" created.
[root@master231 ~]#
2.查看上下文列表
[root@master231 ~]# kubectl config get-contexts --kubeconfig=./yinzhengjie-k8s.conf
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
jasonyin@myk8s myk8s jasonyin
jiege@myk8s myk8s jiege
* yinzhengjie@myk8s myk8s yinzhengjie
[root@master231 ~]#
3.查看kubeconfig信息
[root@master231 ~]# kubectl --kubeconfig=./yinzhengjie-k8s.conf config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.231:6443
name: myk8s
contexts:
- context:
cluster: myk8s
user: jasonyin
name: jasonyin@myk8s
- context:
cluster: myk8s
user: jiege
name: jiege@myk8s
- context:
cluster: myk8s
user: yinzhengjie
name: yinzhengjie@myk8s
current-context: yinzhengjie@myk8s
kind: Config
preferences: {}
users:
- name: jasonyin
user:
token: REDACTED
- name: jiege
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: yinzhengjie
user:
token: REDACTED
[root@master231 ~]#
4.3 使用指定上下文访问验证
[root@master231 ~]# kubectl --kubeconfig=./yinzhengjie-k8s.conf get nodes --context="jiege@myk8s"
Error from server (Forbidden): nodes is forbidden: User "jiege" cannot list resource "nodes" in API group "" at the cluster scope
[root@master231 ~]#
5.合并kubeconfig文件案例
客户端能够通过多种途径获取到kubeconfig文件时,将遵循如下逻辑进行文件合并:
1.设置了"--kubeconfig"参数时,则仅使用指定的文件,且不进行合并;该参数只能使用一次;
2.否则,若设置了KUBECONFIG环境变量,则将其值用作应合并的文件列表;
3.否则,将使用默认的“${HOME}/.kube/config”,且不进行合并
context的判定机制
1.若使用了"--context"选项,则加载该选项指定要使用的上下文;
2.否则,将使用合并后的kubeconfig文件中的current-context的设定;
合并kubeconfig文件案例:
1.未合并前
[root@master231 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.231: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@master231 ~]#
2.定义变量,配置多个kubeconfig文件路径
[root@master231 ~]# export KUBECONFIG='/root/yinzhengjie-k8s.conf:/etc/kubernetes/admin.conf'
[root@master231 ~]#
3.再次查看配置文件信息
[root@master231 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.231:6443
name: kubernetes
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.231:6443
name: myk8s
contexts:
- context:
cluster: myk8s
user: jasonyin
name: jasonyin@myk8s
- context:
cluster: myk8s
user: jiege
name: jiege@myk8s
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: myk8s
user: yinzhengjie
name: yinzhengjie@myk8s
current-context: yinzhengjie@myk8s
kind: Config
preferences: {}
users:
- name: jasonyin
user:
token: REDACTED
- name: jiege
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: yinzhengjie
user:
token: REDACTED
[root@master231 ~]#
五.Service Account实战
1.为何需要Service Account
Kubernetes原生(kubernetes-native)托管运行于Kubernetes之上,通常需要直接与API Server进行交互以获取必要的信息。
API Server同样需要对这类来自于Pod资源中客户端程序进行身份验证,Service Account也就是设计专用于这类场景的账号。
ServiceAccount是API Server支持的标准资源类型之一。
- 1.基于资源对象保存ServiceAccount的数据;
- 2.认证信息保存于ServiceAccount对象专用的Secret中(v1.23-版本)
- 3.隶属名称空间级别,专供集群上的Pod中的进程访问API Server时使用;
2.Pod使用ServiceAccount方式
在Pod上使用Service Account通常有两种方式:
自动设定:
Service Account通常由API Server自动创建并通过ServiceAccount准入控制器自动关联到集群中创建的每个Pod上。
自定义:
在Pod规范上,使用serviceAccountName指定要使用的特定ServiceAccount。
Kubernetes基于三个组件完成Pod上serviceaccount的自动化,分别对应: ServiceAccount Admission Controller,Token Controller,ServiceAccount Controller。
- ServiceAccount Admission Controller:
API Server准入控制器插件,主要负责完成Pod上的ServiceAccount的自动化。
为每个名称空间自动生成一个"default"的sa,若用户未指定sa,则默认使用"default"。
- Token Controller:
为每一个sa分配一个token的组件,已经集成到Controller manager的组件中。
- ServiceAccount Controller:
为sa生成对应的数据信息,已经集成到Controller manager的组件中。
温馨提示:
需要用到特殊权限时,可为Pod指定要使用的自定义ServiceAccount资源对象
3.ServiceAccount Token的不同实现方式
ServiceAccount使用专用的Secret对象(Kubernetes v1.23-)存储相关的敏感信息
- 1.Secret对象的类型标识为“kubernetes.io/serviceaccount”
- 2.该Secret对象会自动附带认证到API Server用到的Token,也称为ServiceAccount Token
ServiceAccount Token的不同实现方式
- 1.Kubernetes v1.20-
系统自动生成专用的Secret对象,并基于secret卷插件关联至相关的Pod;
Secret中会自动附带Token且永久有效(安全性低,如果将来获取该token可以长期登录)。
- 2.Kubernetes v1.21-v1.23:
系统自动生成专用的Secret对象,并通过projected卷插件关联至相关的Pod;
Pod不会使用Secret上的Token,被弃用后,在未来版本就不在创建该token。
而是由Kubelet向TokenRequest API请求生成,默认有效期为一年,且每小时更新一次;
- 3.Kubernetes v1.24+:
系统不再自动生成专用的Secret对象。
而是由Kubelet负责向TokenRequest API请求生成Token,默认有效期为一年,且每小时更新一次;
4.ServiceAccount中的数据
如上图所示,ServiceAccount专用的Secret对象有三个固定的数据项,它们的键名称分别为:
ca.crt:
Kubernetes CA的数字证书。
namespace:
该ServiceAccount可适用的名称空间。
token:
认证到API Server的令牌,其生成方式曾多次变动。
温馨提示:
若需要一个永不过期的Token,可手动创建ServiceAccount专用类型的Secret,并将其关联到ServiceAccount之上。
5.Pod基于projected存储卷引用ServiceAccount案例
如下图所示,Kubernetes v1.21+版本中,Pod加载上面三种数据的方式,改变为基于projected卷插件,通过三个数据源(source)分别进行
serviceAccountToken:
提供由Kubelet负责向TokenRequest API请求生成的Token。
configMap:
经由kube-root-ca.crt这个ConfigMap对象的ca.crt键,引用Kubernetes CA的证书
downwardAPI:
基于fieldRef,获取当前Pod所处的名称空间。
实战案例:
[root@master231 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
xiuxian-v1 1/1 Running 0 39m 10.100.203.145 worker232 <none> <none>
xiuxian-v2 1/1 Running 0 39m 10.100.140.83 worker233 <none> <none>
[root@master231 ~]#
[root@master231 ~]# kubectl get pods xiuxian-v1 -o yaml
apiVersion: v1
kind: Pod
metadata:
...
name: xiuxian-v1
namespace: default
...
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
...
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-v929g
readOnly: true
...
serviceAccount: default
serviceAccountName: default
...
volumes:
- name: kube-api-access-v929g
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
...
[root@master231 ~]#
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18728122,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。