1. K8S中的账户简介
k8s中的账户分为useraccount和serviceaccount,主要差异有四点:
- useraccount是给人使用的,serviceaccount是给pod中进程调用APIServer使用的
- useraccount是跨namespace的,serviceaccount是局限在它所在的namespace的
- useraccount不能通过k8s api添加,但是能够通过证书签名方式进行认证;serviceaccount可以通过k8s api添加
- 每个namespace都有一个默认的serviceaccount,叫做default
本文中,我们主要研究怎样为K8S创建用户账户和怎样创建服务账户。
参考文档:用户认证
2. 创建用户账户
需求:创建一个名为jane的用户账户。
2.1. 创建用户密钥对
1 | openssl genrsa -out jane.key 2048 |
其中,key文件是私钥;csr文件是证书签名申请(Certificate Signing Request),里面包含证书的公钥和其他信息。
2.2. 使用CA签名
假设可以登录运行kube-controller-manager的master节点,那么可以直接在该节点进行CA签名。
1、查看签名用的CA路径
1 | cat /etc/kubernetes/manifests/kube-controller-manager.yaml | grep ca.crt |
查到的路径为/etc/kubernetes/pki/ca.crt
和 /etc/kubernetes/pki/ca.key
2、使用CA签名
1 | openssl x509 -req -in /root/jane.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out /root/jane.crt |
其中,crt文件是签名后的证书。
以上,有了crt和key,这俩加起来就是jane用户账户。一般的用户账户是用户名和密码,K8S的用户账户就是签名证书和私钥。
2.3. 使用API签名
如果无法直接使用CA证书进行签名,那么可以通过APIServer的方式进行签名。
1、查看证书签名申请,base64加密
1 | cat jane.csr | base64 | tr -d '\n' |
2、创建jane-csr.yaml文件,把证书签名申请的内容粘贴到spec.request部分
1 | apiVersion: certificates.k8s.io/v1beta1 |
3、签名请求并通过
1 | kubectl apply -f jane-csr.yaml |
4、导出签名证书
1 | kubectl get csr jane -o yaml |
以上,有了crt和key,这俩加起来就是jane用户账户。
更多内容参考Manage TLS Certificates in a Cluster。
3. 证书格式转换
X.509是一种证书标准,定义了证书中应该包含哪些内容,详情参考RFC5280,SSL使用的就是这种证书标准。
同样的X.509证书,可能有不同的编码格式,目前有以下两种编码格式。
PEM:Privacy Enhanced Mail,BASE64编码,以”—–BEGIN—–”开头,”—–END—–”结尾。
查看PEM格式证书的信息:
1 | openssl x509 -in cert.pem -text -noout |
DER:Distinguished Encoding Rules,二进制格式,不可读。
查看DER格式证书的信息:
1 | openssl x509 -in cert.der -inform der -text -noout |
问题来了,k8s中的证书,除了使用pem格式,还有就是crt格式,并没有der格式啊?这是因为,crt只是一个文件后缀,编码格式可能是pem也可能是der。
那么,pem和der怎样互相转换呢?
1 | # pem to der |
4. K8S中的数字证书
我们自己创建的用户账户拥有自己的数字证书,除此之外,K8S的各个组件也拥有自己的数字证书,用于组件之间的安全访问。
HTTPS(SSL/TLS)加密原理,参考文档《浅谈数据加密》。
4.1. 查看证书
1、查看证书位置
1 | ps aux | grep kubelet |
2、查看证书详情
1 | openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text |
4.2. 签名
签名,或者签名过期后重新签名
1 | openssl x509 -req -in /etc/kubernetes/pki/apiserver-etcd-client.csr -CA /etc/kubernetes/pki/etcd/ca.crt -CAkey /etc/kubernetes/pki/etcd/ca.key -CAcreateserial -out /etc/kubernetes/pki/apiserver-etcd-client.crt |
5. 创建服务账户
5.1. v1.22之前的版本
1、创建ServiceAccount和Secret
1 | kubectl create serviceaccount harkin |
v1.22 之前的 Kubernetes 版本,当创建ServiceAccount时,会自动创建Secret,Secret中包含Token和CA,用于访问 Kubernetes API。
当Pod中指定使用这个ServiceAccount时,TOKEN和CA会挂载到Pod中,以便程序使用。
- Token的路径:
/var/run/secrets/kubernetes.io/serviceaccount/token
- CA证书的路径:
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
2、查看ServiceAccount和Secret
1 | kubectl get sa |
5.2. v1.22之后的版本
在包括 Kubernetes v1.27 在内最近的几个版本中,使用 TokenRequest API 直接获得 API 凭据,并使用投射卷挂载到 Pod 中。
使用这种方法获得的令牌具有绑定的生命周期,当挂载的 Pod 被删除时这些令牌将自动失效。
简单来说,新版本的K8S创建sa时,已经不会自动生成admin-user-token-xxx
这种secret,也就无法从这种secret中获取token。
详情参考文档手动管理 ServiceAccount 的 Secret
1、创建ServiceAccount
1 | kubectl create serviceaccount harkin |
2、创建ServiceAccount的Secret
(1)创建有期限Token(令牌)
1 | kubectl create token harkin --duration=8760h |
该令牌只会显示一次,请保存好它。至于ca.crt,从/etc/kubernetes/pki/ca.crt
获取即可。
(2)创建长期有效Token(令牌)
我们仍然可以手动创建 Secret 来保存服务账号令牌,例如在我们需要一个永不过期的令牌的时候。
一旦我们手动创建一个 Secret 并将其关联到 ServiceAccount, Kubernetes 控制平面就会自动将令牌填充到该 Secret 中。
1 | kubectl apply -f - <<EOF |
3、查看ServiceAccount和Secret
1 | kubectl get sa |
6. 授权
创建完用户账户和服务账户,只是有了账户,并没有K8S集群的权限。
账户授权方法参考文档《好好学K8S:K8S中用户账户的RBAC鉴权》和《好好学K8S:K8S中服务账户的RBAC鉴权》。