在编写一个准入 Webhook 服务时,需要配置相关证书,k8s 提供了 api 用于对用户自主创建的证书进行认证签发。以下部分演示为 Webhook 服务创建 TLS 证书。
通过运行以下命令生成私钥:
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
"hosts": [
"my-svc.my-namespace.svc.cluster.local",
"my-pod.my-namespace.pod.cluster.local",
"192.0.2.24",
"10.0.34.2"
],
"CN": "my-pod.my-namespace.pod.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
}
}
EOF
此命令生成两个文件;它生成包含 PEM 编码 PKCS#10 证书请求的 server.csr
, 以及 PEM 编码密钥的 server-key.pem
,用于待生成的证书。
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: example
spec:
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
你能看到的输出类似于:
certificatesigningrequest.certificates.k8s.io/example created
Warning: certificates.k8s.io/v1beta1 CertificateSigningRequest is deprecated in v1.19+, unavailable in v1.22+; use certificates.k8s.io/v1 CertificateSigningRequest
CSR 处于 Pending 状态。执行下面的命令你将可以看到:
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
example 17s kubernetes.io/legacy-unknown 100015926370-1650441195 Pending
kubectl certificate approve example
certificatesigningrequest.certificates.k8s.io/example approved
你现在应该能看到如下输出:
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
example 5m4s kubernetes.io/legacy-unknown 100015926370-1650441195 Approved,Issued
kubectl get csr example -o jsonpath='{.status.certificate}' | base64 --decode > server.crt
现在你可以将 server.crt
和 server-key.pem
作为你的服务的 https 认证了。
例如 kubebuilder
中使用 TLS 证书,将 server.crt
和 server-key.pem
放在 cert
目录中并修改名称为 tls.crt
和 tls.key
,然后指定证书目录:
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "27e1b0af.blazehu.com",
CertDir: "./cert/",
})
上述例子使用 certificates.k8s.io/v1beta1
API 版本的 CertificateSigningRequest
不在 v1.22 版本中继续提供。官方迁移指南点这里。 我们可以使用 certificates.k8s.io/v1
API 版本,此 API 从 v1.19 版本开始可用。
certificates.k8s.io/v1
中需要额外注意的变更:spec.signerName
现在变成必需字段(参阅 已知的 Kubernetes 签署者), 并且通过 certificates.k8s.io/v1
API 不可以创建签署者为 kubernetes.io/legacy-unknown
的请求spec.usages
现在变成必需字段,其中不可以包含重复的字符串值, 并且只能包含已知的用法字符串通过运行以下命令生成私钥:
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
"hosts": [
"my-svc.my-namespace.svc.cluster.local",
"my-pod.my-namespace.pod.cluster.local",
"192.0.2.24",
"10.0.34.2"
],
"CN": "my-pod.my-namespace.pod.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
}
}
EOF
这里 csr signerName 不能是 kubernetes.io/legacy-unknown
,演示我们随便指定一个为 example.com/serving
,v1beta1 版本默认是 kubernetes.io/legacy-unknown
。
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: example
spec:
request: $(cat server.csr | base64 | tr -d '\n')
signerName: example.com/serving
usages:
- digital signature
- key encipherment
- server auth
EOF
kubectl certificate approve example
certificatesigningrequest.certificates.k8s.io/example approved
你现在应该能看到如下输出:
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
example 11s example.com/serving 100015926370-1650441195 Approved
这里可以看到证书请求已被批准,但是没有自动签名,正在等待请求的签名者对其签名。
我们扮演证书签署者的角色,颁发证书并将其上传到 API 服务器。
通过运行以下命令创建签名证书:
cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
{
"CN": "example.com/serving",
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
这会产生一个证书颁发机构密钥文件(ca-key.pem
)和证书(ca.pem
)。
创建文件 server-signing-config.json
内容如下:
{
"signing": {
"default": {
"usages": [
"digital signature",
"key encipherment",
"server auth"
],
"expiry": "876000h",
"ca_constraint": {
"is_ca": false
}
}
}
}
使用 server-signing-config.json
签名配置、证书颁发机构密钥文件和证书来签署证书请求:
kubectl get csr example -o jsonpath='{.spec.request}' | \
base64 --decode | \
cfssl sign -ca ca.pem -ca-key ca-key.pem -config server-signing-config.json - | \
cfssljson -bare ca-signed-server
这会生成一个签名的服务证书文件,ca-signed-server.pem
。
kubectl get csr example -o json | \
jq '.status.certificate = "'$(base64 ca-signed-server.pem | tr -d '\n')'"' | \
kubectl replace --raw /apis/certificates.k8s.io/v1/certificatesigningrequests/example/status -f -
批准 CSR 并上传签名证书后,你现在应该能看到如下输出:
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
example 10m example.com/serving 100015926370-1650441195 Approved,Issued
这是你可以正常下载证书并使用它了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。