使用 CertificateSigningRequest 为 Kubernetes API 客户端颁发证书
Kubernetes 允许你使用公钥基础设施 (PKI) 作为客户端来对集群进行身份验证。
为了使普通用户能够进行身份验证并调用 API,需要几个步骤。首先,该用户必须拥有由你的 Kubernetes 集群信任的机构颁发的 X.509 证书。然后,客户端必须将该证书呈现给 Kubernetes API。
你将使用 CertificateSigningRequest 作为此过程的一部分,并且你或一些其他主体必须批准该请求。
你将创建一个私钥,然后获得颁发的证书,最后为客户端配置该私钥。
准备工作
你需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与你的集群通信。建议在至少有两个不是控制平面主机的节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者你可以使用这些 Kubernetes 演练场中的一个。
你需要
kubectl
、openssl
和base64
实用程序。
本页面假设你正在使用 Kubernetes 基于角色的访问控制 (RBAC)。如果你有替代或额外的授权安全机制,也需要考虑到这些。
创建私钥
在此步骤中,你将创建一个私钥。你需要将此文档保密;任何拥有它的人都可以冒充该用户。
# Create a private key
openssl genrsa -out myuser.key 3072
创建 X.509 证书签名请求
注意
这与同名的 CertificateSigningRequest API 不同;你在此处生成的文件将放入 CertificateSigningRequest 中。重要的是要设置 CSR 的 CN 和 O 属性。CN 是用户的名称,O 是该用户所属的组。你可以参考 RBAC 以了解标准组。
# Change the common name "myuser" to the actual username that you want to use
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 # example
spec:
# This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
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
证书值在 .status.certificate
下是 Base64 编码格式。
从 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