如何为 webhook 创建带有 apiVersion“certificates.k8s.io/v1”的“CertificateSigningRequest”

Dav*_*Wer 5 kubernetes kubernetes-apiserver

我的集群中有一个 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
Run Code Online (Sandbox Code Playgroud)

我按如下方式创建证书:

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

Run Code Online (Sandbox Code Playgroud)

证书签名请求 ( 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
Run Code Online (Sandbox Code Playgroud)

这效果很好!

由于我更新了我的 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
Run Code Online (Sandbox Code Playgroud)

现在 api 服务器无法连接到我的 webhook:Post "https://s-controller.ns-controller.svc:443/mutate?timeout=30s": x509: certificate specifies an incompatible key usage

我尝试更新证书配置,extendedKeyUsage = clientAuth但没有帮助。

知道apiVersionsignerName的正确配置是什么certificates.k8s.io/v1

Dav*_*Wer 1

我没有按照CertificateSigningRequest我的意愿创建一个 CA,但是我通过创建自己的 CA 绕过了这个问题,如下所示:

首先,我编辑了我的证书配置文件,因此它将包含 acommonName和 current 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
Run Code Online (Sandbox Code Playgroud)

生成 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"
Run Code Online (Sandbox Code Playgroud)

生成 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
Run Code Online (Sandbox Code Playgroud)

为 webhook 创建 kubernetes tls 密钥

kubectl create secret tls webhook-tls --cert=server.crt --key=server.key
Run Code Online (Sandbox Code Playgroud)

设置CA_BUNDLE

export CA_BUNDLE=$(cat ca.crt | base64 | tr -d '\n')
Run Code Online (Sandbox Code Playgroud)

删除所有生成的文件

rm ca.crt 
rm ca.key 
rm server.key
rm server.csr
rm server.crt

Run Code Online (Sandbox Code Playgroud)

在我的 webhhok 中,我有一个volume volumeMount

体积:

volumes:
- name: tls-vol
    secret:
      secretName: webhook-tls
Run Code Online (Sandbox Code Playgroud)

卷挂载:

volumeMounts:
- name: tls-vol
  mountPath: /etc/webhook/certs
  readOnly: true
Run Code Online (Sandbox Code Playgroud)

还有副驾驶args

args:
- -tlsCertFile=/etc/webhook/certs/tls.crt
- -tlsKeyFile=/etc/webhook/certs/tls.key
Run Code Online (Sandbox Code Playgroud)