使用 CertificateSigningRequest 为 Kubernetes API 客户端颁发证书
Kubernetes 允许你使用公钥基础设施 (PKI) 对你的集群进行身份认证,这类似于对客户端进行身份认证。
为了能够对普通用户进行身份认证并调用 API,需要执行几个步骤。首先,此用户必须拥有由你的 Kubernetes 集群所信任的权威机构颁发的 X.509 证书。之后客户端必须向 Kubernetes API 提交该证书。
在这个过程中,你需要使用 CertificateSigningRequest,并且你或其他主体必须批准此请求。
你将创建私钥,然后获取颁发的证书,最后为客户端配置该私钥。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
- 你需要
kubectl
、openssl
和base64
等工具。
此页面假设你使用的是 Kubernetes 基于角色的访问控制 (RBAC)。 如果你在鉴权方面有替代的或额外的安全机制,也需要将其考虑在内。
创建私钥
在这一步中,你将创建一个私钥。你将此文件作为秘密保管起来,因为任何拥有该私钥的人都可以伪装成对应的用户。
# 创建一个私钥
openssl genrsa -out myuser.key 3072
创建 X.509 证书签名请求
说明:
这与类似名称的 CertificateSigningRequest API 不同; 你在此处生成的文件将被放入 CertificateSigningRequest 对象中。
设置 CSR 的 CN 和 O 属性非常重要。CN 是用户的名称,O 是此用户所属的群组。 你可以参阅 RBAC 了解标准的群组。
# 将通用名称 "myuser" 更改为你要使用的实际用户名
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
创建 Kubernetes CertificateSigningRequest
使用以下命令对 CSR 文档进行编码:
cat myuser.csr | base64 | tr -d "\n"
创建 CertificateSigningRequest 并通过 kubectl 将其提交到 Kubernetes 集群。以下是你可以用于生成 CertificateSigningRequest 的 Shell 片段。
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser # 示例
spec:
# 这是已编码的 CSR。将此更改为 myuser.csr 的经 base64 编码的内容
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # 一天
usages:
- client auth
EOF
一些注意点:
usages
必须是client auth
expirationSeconds
可以设置得更长(例如864000
表示十天)或更短(例如3600
表示一小时)。 你所请求的时长不能短于 10 分钟。request
值是 CSR 文件内容的 base64 编码值。
批准 CertificateSigningRequest
使用 kubectl 找到你创建的 CSR,并手动批准它。
获取 CSR 列表:
kubectl get csr
批准 CSR:
kubectl certificate approve myuser
获取证书
从 CSR 中检索证书,以检查其是否正常。
kubectl get csr/myuser -o yaml
证书值以 Base64 编码格式显示在 .status.certificate
下。
从 CertificateSigningRequest 导出已颁发的证书。
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
将证书配置到 kubeconfig 中
下一步是将此用户添加到 kubeconfig 文件中。
首先,你需要添加新的凭证:
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
然后,你需要添加上下文:
kubectl config set-context myuser --cluster=kubernetes --user=myuser
对其执行测试:
kubectl --context myuser auth whoami
你应该看到确认你是 “myuser” 的输出。
创建 Role 和 RoleBinding
说明:
如果你不使用 Kubernetes RBAC,请跳过这一步,并对集群实际使用的鉴权机制进行适当更改。
创建证书之后,就可以为此用户定义 Role 和 RoleBinding,以访问 Kubernetes 集群资源。
这是为新用户创建 Role 的示例命令:
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
这是为新用户创建 RoleBinding 的示例命令:
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
接下来
- 阅读管理集群中的 TLS 证书
- 有关 X.509 本身的细节,参阅 RFC 5280 第 3.1 节
- 有关 PKCS#10 证书签名请求的语法信息,请参阅 RFC 2986
- 参阅 ClusterTrustBundles