问题描述
我的集群中运行了一个 wehook。
我创建了一个证书并成功签署了它。
证书配置:
cat > csr.conf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = s-controller.ns-controller
DNS.2 = s-controller.ns-controller.svc
EOF
我他们创建的证书如下:
openssl genrsa -out server-key.pem 2048
openssl req -new -key server-key.pem -subj "/CN=s-controller.ns-controller.svc" -out server.csr -config csr.conf
证书签名请求 (v1beta1
)
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
Metadata:
name: csr-controller
spec:
groups:
- system:authenticated
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
效果很好!
自从我更新了 kubernetes 版本后,我收到以下警告:Warning: certificates.k8s.io/v1beta1 CertificateSigningRequest is deprecated in v1.19+,unavailable in v1.22+; use certificates.k8s.io/v1
,我更新了 CertificateSigningRequest
所以现在如下:
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
Metadata:
name: csr-controller
spec:
groups:
- system:authenticated
request: $(cat server.csr | base64 | tr -d '\n')
signerName: kubernetes.io/kube-apiserver-client
usages:
- digital signature
- key encipherment
- client auth
EOF
现在 api 服务器无法连接到我的 webhook:Post "https://s-controller.ns-controller.svc:443/mutate?timeout=30s": x509: certificate specifies an incompatible key usage
我尝试将证书配置更新为 extendedKeyUsage = clientAuth
,但没有帮助。
知道什么是正确的 signerName
以及 certificates.k8s.io/v1
apiVersion 的配置
解决方法
我没有按照自己的意愿创建 CertificateSigningRequest
,但是我通过创建自己的 CA 绕过了这个问题,如下所示:
首先,我编辑了我的证书配置文件,使其包含 commonName
和当前的 extendedKeyUsage
:
cat > csr.conf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
CN = s-controller.ns-controller.svc
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitalSignature,keyEncipherment
extendedKeyUsage = clientAuth,serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = s-controller.ns-controller
DNS.2 = s-controller.ns-controller.svc
EOF
生成 CA 证书(注意 -days 365
)
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 365 -out ca.crt -subj "/CN=admission_ca"
生成 tls 密钥和证书
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -config csr.conf
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extensions v3_req -extfile csr.conf
为 webhook 创建 kubernetes tls secret
kubectl create secret tls webhook-tls --cert=server.crt --key=server.key
设置 CA_BUNDLE
export CA_BUNDLE=$(cat ca.crt | base64 | tr -d '\n')
删除所有生成的文件
rm ca.crt
rm ca.key
rm server.key
rm server.csr
rm server.crt
在我的 webhhok 中,我有一个 volume
volumeMount
:
音量:
volumes:
- name: tls-vol
secret:
secretName: webhook-tls
音量安装:
volumeMounts:
- name: tls-vol
mountPath: /etc/webhook/certs
readOnly: true
还有船长args
args:
- -tlsCertFile=/etc/webhook/certs/tls.crt
- -tlsKeyFile=/etc/webhook/certs/tls.key
,
如何使用 apiVersion 创建 D:\DATA
+---post
| +---subject_01
| | +---0024_63_Touch
| | | File1.txt
| | | File2.txt
| | |
| | \---654_mpr_8364
| | File1.txt
| | File2.txt
| |
| \---subject_02
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| \---654_mpr_8364
| File1.txt
| File2.txt
|
\---pre
+---subject_01
| +---0024_63_Touch
| | File1.txt
| | File2.txt
| |
| \---654_mpr_8364
| File1.txt
| File2.txt
|
\---subject_02
+---0024_63_Touch
| File1.txt
| File2.txt
|
\---654_mpr_8364
File1.txt
File2.txt
CertificateSigningRequest
用于网络钩子?
我已使用以下发行者和 openssl csr 配置成功创建了 certificates.k8s.io/v1
。它已使用 this webhook example 进行测试。
请查看以下配置:
certificates.k8s.io/v1
和:
#csr.conf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${service}
DNS.2 = ${service}.${namespace}
DNS.3 = ${service}.${namespace}.svc
,
在旧的 CertificateSigningRequest yaml 中,您使用 server auth 作为关键用法之一,但在最新的一个中,您将其更改为 client auth 。 webhook 所需的证书需要使用服务器身份验证密钥进行签名,并且 signerName 应该是 kubernetes.io/kubelet-serving 。因此,请按如下方式更新您的文件以避免出现此问题:
csr.conf
cat > csr.conf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
CN = s-controller.ns-controller.svc
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,keyEncipherment
extendedKeyUsage = clientAuth,serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = s-controller.ns-controller
DNS.2 = s-controller.ns-controller.svc
EOF
以subject.organization为“system:nodes”生成csr
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=system:node:s-contoller.ns-controller.svc /OU="system:nodes" /O=system:nodes" -out $server.csr -config csr.conf
csr-for-webhook.yaml
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: csr-controller
spec:
groups:
- system:authenticated
request: $(cat server.csr | base64 | tr -d '\n')
signerName: kubernetes.io/kubelet-serving
usages:
- digital signature
- key encipherment
- server auth
EOF
来源:https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/
PS:我已经用 Kubernetes 1.21.3 版测试过