k8s-api-request-lifecycle.png

在之前的文章中,我们讲过webhook admission是什么以及如何在代码中实现一个webhook admission。今天我们主要讲下,如何在kubernetes中部署自己的webhook admission。

生成TLS验证的证书

为什么需要TLS验证:

  • 首先API服务器与其他程序通信需要保证安全性,所以他们之间要https加密通信。
  • webhook程序跟API服务器通信的时候可以理解为webhook程序是服务端,所以它要产生公私匙,将公匙交给客户端,让其加密后再发送数据。但是,客户端不知道服务端发公匙是不是伪造的,所以需要一个第三方机构CA进行证书签名。证书签名是使用CA的私匙加密,然后客户端用CA的公匙解密验证证书的真伪。

关于证书这块,可以两种方式实现,分为:

  • 由k8s自带的CA进行签名,因为这样api服务器就可以用自带CA的公匙进行验证。
  • 自己通过cfssl签发。

关于k8s自带的CA签名的,大家可以参照下面的脚本 webhook-create-signed-cert.sh

#!/bin/bash

set -e

usage() {
    cat <<EOF
Generate certificate suitable for use with an aksk-injector webhook service.
This script uses k8s' CertificateSigningRequest API to a generate a
certificate signed by k8s CA suitable for use with aksk-injector webhook
services. This requires permissions to create and approve CSR. See
https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster for
detailed explantion and additional instructions.
The server key/cert k8s CA cert are stored in a k8s secret.
usage: ${0} [OPTIONS]
The following flags are required.
       --service          Service name of webhook.
       --namespace        Namespace where webhook service and secret reside.
       --secret           Secret name for CA certificate and server certificate/key pair.
EOF
    exit 1
}

while [[ $# -gt 0 ]]; do
    case ${1} in
        --service)
            service="$2"
            shift
            ;;
        --secret)
            secret="$2"
            shift
            ;;
        --namespace)
            namespace="$2"
            shift
            ;;
        *)
            usage
            ;;
    esac
    shift
done

[ -z ${service} ] && service=aksk-injector-webhook-svc
[ -z ${secret} ] && secret=aksk-injector-webhook-certs
[ -z ${namespace} ] && namespace=kube-admin

if [ ! -x "$(command -v openssl)" ]; then
    echo "openssl not found"
    exit 1
fi

csrName=${service}.${namespace}
tmpdir=$(mktemp -d)
echo "creating certs in tmpdir ${tmpdir} "

cat <<EOF >> ${tmpdir}/csr.conf
[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 = ${service}
DNS.2 = ${service}.${namespace}
DNS.3 = ${service}.${namespace}.svc
EOF

openssl genrsa -out ${tmpdir}/server-key.pem 2048
openssl req -new -key ${tmpdir}/server-key.pem -subj "/CN=${service}.${namespace}.svc" -out ${tmpdir}/server.csr -config ${tmpdir}/csr.conf

# clean-up any previously created CSR for our service. Ignore errors if not present.
kubectl delete csr ${csrName} 2>/dev/null || true

# create  server cert/key CSR and  send to k8s API
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: ${csrName}
spec:
  groups:
  - system:authenticated
  request: $(cat ${tmpdir}/server.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF

# verify CSR has been created
while true; do
    kubectl get csr ${csrName}
    if [ "$?" -eq 0 ]; then
        break
    fi
done

# approve and fetch the signed certificate
kubectl certificate approve ${csrName}
# verify certificate has been signed
for x in $(seq 10); do
    serverCert=$(kubectl get csr ${csrName} -o jsonpath='{.status.certificate}')
    if [[ ${serverCert} != '' ]]; then
        break
    fi
    sleep 1
done
if [[ ${serverCert} == '' ]]; then
    echo "ERROR: After approving csr ${csrName}, the signed certificate did not appear on the resource. Giving up after 10 attempts." >&2
    exit 1
fi
echo ${serverCert} | openssl base64 -d -A -out ${tmpdir}/server-cert.pem


# create the secret with CA cert and server cert/key
kubectl create secret generic ${secret} \
        --from-file=key.pem=${tmpdir}/server-key.pem \
        --from-file=cert.pem=${tmpdir}/server-cert.pem \
        --dry-run -o yaml |
    kubectl -n ${namespace} apply -f -

但是有些特殊的托管集群,为了安全的内容,这种签发是行不通的。所以我们可以使用cfssl 自己签发。

安装cfssl

OS X
brew install cfssl
Linux
wget -q --show-progress --https-only --timestamping \\
  https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 \\
  https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64
sudo mv cfssl_linux-amd64 /usr/local/bin/cfssl
sudo mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

创建CA cert

{

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "server": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

}

Results:

ca-key.pem
ca.pem

创建 Server Cert

cat > server-csr.json <<EOF
{
  "CN": "admission",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \\
  -ca=ca.pem \\
  -ca-key=ca-key.pem \\
  -config=ca-config.json \\
  -hostname=kms.kube-admin.svc \\
  -profile=server \\
  server-csr.json | cfssljson -bare server

}

PS: 最重要的是 -hostname 的值, {service-name}.{service-namespace}.svc, service-name代表你webhook 的service名字,service-namespace代表你webhook的命名空间。

Results:

server-key.pem
server.pem

创建WebhookConfiguration

Encode and trim the ca cert.

cat ca.pem | base64

Results:

LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURvRENDQW9pZ0F3SUJBZ0lVVkZ0d2UwR09DMzRvbWppWUV6WGZKaGd4L244d0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRJd01EUXlPREEzTWprd01Gb1hEVEkxTURReU56QTNNamt3TUZvd2FERUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14Q3pBSkJnTlZCQXNUQWtOQk1STXdFUVlEVlFRREV3cExkV0psCmNtNWxkR1Z6TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFydkF5Vzd0Umk0Zk8Ka21lQjFQRFhjN1VjeFRrVW1jSDBETkZ6NzJyVXN0cFdsbVV4SDZBRjNEYTRDU3ZpSHgrOUQ4Z2ZBaEdMcFVxSApzVklaT3NqTDVocVNuZzJEVzZRc2VUc3pHcWV1Z3NueFNlZXhLSzlYUi9RUnFmT3VrM3dqZWR3SGM2MU1BdWNBCndkT2h2SGlKQk5KR0NNSlF4ZGpkMTRaVk5KT2o1djJFHpkcWhzbjlXU3Ivc0ptOVFLRitPeTAyenN0MVUKd2NDSVN5dnpyMmJvRm5tbEgvWWVCRVRsTzJXQm95ZDZ0bHk0YmllRVV5Y0hBMzRnc3liUWVZcUFuSzF2S3UragpYVUxZQ3dXMzFwc1lxQTAxNURDbGlIcjgxNG50Q251NVVGYUJwUmtDTkMrM3A5aEU2WjdKRGVKQS9zVnBST3B5CmxWZ0RjTjEyT1FJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBZEJnTlZIUTRFRmdRVUpmQVk2aW5uRXEveFdXSE9kOEJBWE9YdktCOHdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0VCQUFyQjBSZ1hzN1JhSU96Tk40QTFuVFg2d21keTdDaytSVEE4RXo4MkFPQnBJV2w3c2tCMUY1aFhJYWI5CjhvWi9UUzdhZTJuakJuK2lWVWpTbU5qdlM5M3BmRUxMR1lFZ2ZYYnJkdkNibnRDODRnQnlDM2YxSzJwR01zY1oKQ2N4OUUrSTFZekxDdFFQV2dPS0NEb3VJdGJCcmVTOVpodklNUkI2WjE3QW5CYWI1UGJodkNENjVIM0JYNlpsZgprVEJOUldFZFpDS0tBa2ZyUW1QaWVBRVpTbTd6eFFVZi85Rkx0RytkK3JHejAxeHZSUVFkSHZnbUNhSmx5TEE1CkZZbTRNSGtIb3dIa0I3aWxLVUhQc2ZzZ3ZFNlpweFpsdi9BbTVPcFhINllCZ0NuZVBha1c3RjdzanhxWVBUakMKei85RGNSSm5haDcvWXpROWZweFBha1o5c1dzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==

创建webhook config:

cat mutaing.yaml <<EOF
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  labels:
    app: kms
  name: kms
webhooks:
- clientConfig:
    caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURvRENDQW9pZ0F3SUJBZ0lVVkZ0d2UwR09DMzRvbWppWUV6WGZKaGd4L244d0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRJd01EUXlPREEzTWprd01Gb1hEVEkxTURReU56QTNNamt3TUZvd2FERUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14Q3pBSkJnTlZCQXNUQWtOQk1STXdFUVlEVlFRREV3cExkV0psCmNtNWxkR1Z6TUlJQklqQU5CZ2Ka21lQjFQRFhjN1VjeFRrVW1jSDBETkZ6NzJyVXN0cFdsbVV4SDZBRjNEYTRDU3ZpSHgrOUQ4Z2ZBaEdMcFVxSApzVklaT3NqTDVocVNuZzJEVzZRc2VUc3pHcWV1Z3NueFNlZXhLSzlYUi9RUnFmT3VrM3dqZWR3SGM2MU1BdWNBCndkT2h2SGlKQk5KR0NNSlF4ZGpkMTRaVk5KT2o1djJFR2oxeHpkcWhzbjlXU3Ivc0ptOVFLRitPeTAyenN0MVUKd2NDSVN5dnpyMmJvRm5tbEgvWWVCRVRsTzJXQm95ZDZ0bHk0YmllRVV5Y0hBMzRnc3liUWVZcUFuSzF2S3UragpYVUxZQ3dXMzFwc1lxQTAxNURDbGlIcjgxNG50Q251NVVGYUJwUmtDTkMrM3A5aEU2WjdKRGVKQS9zVnBST3B5CmxWZ0RjTjEyT1FJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBZEJnTlZIUTRFRmdRVUpmQVk2aW5uRXEveFdXSE9kOEJBWE9YdktCOHdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0VCQUFyQjBSZ1hzN1JhSU96Tk40QTFuVFg2d21keTdDaytSVEE4RXo4MkFPQnBJV2w3c2tCMUY1aFhJYWI5CjhvWi9UUzdhZTJuakJuK2lWVWpTbU5qdlM5M3BmRUxMR1lFZ2ZYYnJkdkNibnRDODRnQnlDM2YxSzJwR01zY1oKQ2N4OUUrSTFZekxDdFFQV2dPS0NEb3VJdGJCcmVTOVpodklNUkI2WjE3QW5CYWI1UGJodkNENjVIM0JYNlpsZgprVEJOUldFZFpDS0tBa2ZyUW1QaWVBRVpTbTd6eFFVZi85Rkx0RytkK3JHejAxeHZSUVFkSHZnbUNhSmx5TEE1CkZZbTRNSGtIb3dIa0I3aWxLVUhQc2ZzZ3ZFNlpweFpsdi9BbTVPcFhINllCZ0NuZVBha1c3RjdzanhxWVBUakMKei85RGNSSm5haDcvWXpROWZweFBha1o5c1dzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    service:
      name: kms
      namespace: kube-admin
      path: /mutate
  failurePolicy: Fail
  name: kms.xxx.me
  namespaceSelector: {}
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:
    - CREATE
    resources:
    - pods
kubectl create -f mutating.yaml

此处需要注意:failurePolicy: Fail定义了如何处理 admission webhook 中无法识别的错误和超时错误。允许的值为IgnoreFail

  • Ignore表示调用 webhook 的错误将被忽略并且允许 API 请求继续。
  • Fail表示调用 webhook 的错误导致准入失败并且 API 请求被拒绝。

创建 TLS secret for server

cat server.pem | base64

Result:

LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVCVENDQXUyZ0F3SUJBZ0lVRUlOL1VvVGpnbWgwN3c2QnBmaDhQeVlCKzdzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRJd01EUXlPREE1TVRjd01Gb1hEVEl4TURReU9EQTVNVGN3TUZvd2J6RUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14RXpBUkJnTlZCQXNUQ2t0MVltVnlibVYwWlhNeEVqQVFCZ05WCkJBTVRDV0ZrYldsemMybHZiakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLQkMKTnF5V3BSc1dmYi8yd3FGeU0vbmo1SGc0ZmJsY2YvQUNPNjFNejV5amIwVDB1NWFHd3pCeWNVMm1sN2ZqaGdscQo3N3BEWGlvaU9OYlY3N2NDNDIzZWV1MXdtajhVeENITDlNTGk5MjlNODBNWDN0NmZHWHVMUDUxTkVpaVY2YUt6Cncya2R4RFYwWklqUTd6YUNwOFExdFpDQXVpbzFzWkdlR205cUJOOHNhZjgvNkQraXRmN1dTUUZKVEt0K2k1ckMKRnVSQXo2ZEdqVmFmd2ZrS1YzeWNoT0IrRitxVm1oV3UyWFJCUjZmMDJESVNNVWFXei9DdUZ1MGpYN3pqcE1yVQpoZCtiU2lsaStodko2RHZYWkd5UUxIMlNuNG95enFSckozQktFcnhuRDBlbDYwRDVjaHUydFR1Q3pHVXhrS1NZCmRzVHNyOVpBRno5QVpFL0JvaHNDQXdFQUFhT0JuekNCbkRBT0JnTlZIUThCQWY4RUJBTUNCYUF3SFFZRFZSMGwKQkJZd0ZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRQpGUFlTRTBiOEtKNVphaWpYbnJabjJjalB1dklMTUI4R0ExVWRJd1FZTUJhQUZDWHdHT29wNXhLdjhWbGh6bmZBClFGemw3eWdmTUIwR0ExVWRFUVFXTUJTQ0VtdHRjeTVyZFdKbExXRmtiV2x1TG5OMll6QU5CZ2txaGtpRW9EV2lvd3FWUTJzOUJRSnh2OVZEMEZpdi9Od1JjU2FSZHgrT0tQMHgvCnVyUmlkNHhIVnFBYjFlQ0wwQVF6Skh5MEV6YkU3bjV4NE1aSFhWYnhvdFA1b1RyR1R6T1VuZ0xqeWl0NFZ6UmgKUU9KSlRuVkIwY3MwZFpEVWduWTZ0VGFrSzFJY2d2ZndtVlMzN0FWZmZZcFlSNUdLTG50OGVlWEVwZFlTS1VQOApzdlNCRDRIenBqNGlVd2lLTU9LaGZja05INDM2N1k2S2pOUlhEaHp4OGVnVnp5Q3F6UGhoQWx5NlB0L1FER0ZwCk1RQmo2aFYzaUZ5NlY3UWowc0FZdDVBYzB5bERBT0RqaXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
cat server-key.pem | base64

Result:

LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb0VJMnJKYWxHeFo5di9iQ29YSXorZVBrZURoOXVWeC84QUk3clV6UG5LTnZSUFM3CmxvYkRNSEp4VGFhWHQrT0dDV3J2dWtOZUtpSTQxdFh2dHdMamJkNTY3WENhUHhURUljdjB3dUwzYjB6elF4ZmUKM3A4WmU0cy9uVTBTS0pYcG9yUERhUjNFTlhSa2lORHZOb0tueERXMWtJQzZLald4a1o0YWIyb0UzeXhwL3ovbwpQNksxL3RaSkFVbE1xMzZMbXNJVzVFRFBwMGFOVnAvQitRcFhmSnlFNEg0WDZwV2FGYTdaZEVGSHAvVFlNaEl4ClJwYlA4SzRXN1NOZnZPT2t5dFNGMzV0S0tXTDZHOG5vTzlka2JKQXNmWktmaWpMT3BHc25jRW9TdkdjUFI2WHIKUVBseUc3YTFPNExNWlRHUXBKaDJ4T3l2MWtBWFAwQmtUOEdpR3dJREFRQUJBb0lCQUF3dGUrSVpnR3BTaHpPegpHSThVRW9jR25qSFVlUmxBd2lnR3cyb2owQkxqQ0cyQSsxQXc1VndsRmg4RWJicjNleFAwSUV0VEd6Q3djUWxDCk1Ia0RxeXlLSDJVempVVUYydkdHZ2c3ZEdGaEl6S05vaVBMNXZBSDdUdFl4S1JRVWNEQ0E0SFI0WXBSOVI3WnQKeWYrbVpnRXU0NkViWndvV0Vtd3lTMmZ6OG5MUzJsek9qN1kvbFRPcDJPZnRYZ3Q5WGV4TXR2WXc4alNpVTBmSApJMk9UcG9oYlhvL2hkOThsdDNOei9DZzIrYU4waXRvZzAxZVV3TjY2UHh2MndtQ0VsVUd5cmh4enRyY2FaQVFiCjhqQWVWUUJyUnlpUmZpU1FSTXhTOWRPMGpseXhkdzVvNUs5YzFDMEhvRkxNSEJhVmxHNWpEWWNvVGJ2S0FDSzMKVmUydUdZRUNnWUVBd3QrbnVxYVd1WkFDb3k3Vi9remFRY3EyMWxiOUZxSUlEVTVSQ3Npa3l4WktWVmZRRXBQMQpJREV6TThOL1doSFE2bm5namUwdFBXWnhpQkFzcHM2VTB3V3ViQ0VZdmdnN2wvR3AyS2czODVEeTNDWnAwY3JBCkg3cXIrTlhBR2RRS0FrdDN3UDBuNE1rYk1Jd2k2ckZ1b2lKdW5hMWJ1YmEyNUd5U0hhcXJOREVDZ1lFQTBvYjUKbmRONjJFZzM5bFc1OEZzdEtRaDBYUHZrNlE0UEFYZHN4My9RK3dZeWsweWk3aEpIVHR0MjhCMlRrVmU1Z003VQpOYnRJcGs1eUlaQmdTc0VmMktUZWpjS0hVY3NsbEFDWGFOQkJOVXFpNHltdTc1SGhwajhYc2R3Q2tRRU1ERi9vCjZyYmpyNmpHQXpsVE1McDJGRmcrTllJd3J5MjgwRXIvUWhHbnBBc0NnWUJ5dFZZMC8zUi9mQzZoUWFPRFVsZXoKSEpFdGIvMEFRcFo4eHBuYndDbUl4ZkV4ZFVRc2UxMXgrcVFLRjB5eWh3UXowVlFHRnhObkxoTXNKV0V6T3l6TgpYbTNDaG1UYkQxdU00QnE3UnFIUXhJVEFZL2dzSHEyaXY2NFZCalZTdnNhNWZSVGJ5K2lhWDZhYW1CTEJsWG5yCkJGdWFndjRZUGw0LzdVekJHOEkxTVFLQmdHVU1KQU44M2hteGtDck1PdE1DOEVva4RjdNd09mNDJmNHhEOGRNd3ZwRm1rMFZYOE00cHlITENWQwowQW1rS1VxZlZ6Zmw3VWkrUDhFK3VIeWc1QWVNZ1Y4bktXSEd3RVFMMzhJanZVbEdrWlZkUjhETlV6TW16QjRLCkcwekJBb0dCQUxhQTdOb0ltblg4SFZoL1RRZlcxQ3Y0VytaSjdaNFRnb2FjYnZnd05nelFlNU1aMCt5Z3hsaVMKQ1BVdVBwVVV0ejU3MWhOTjI4Q1J2c2JVZFNxS2xyZ2RubGhONFJpZDAyK243R0h1RWYvZUE1NFZab2dQcURkMApnVVdVdnZiTXljTGFiS0c5dG1lQjQ4Q0xPektDSVlyVzJ6Y2RCK1YyeXdvQ29ZQUlSSnduCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
cat > secret.yaml <<EOF
apiVersion: v1
data:
  cert.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVCVENDQXUyZ0F3SUJBZ0lVRUlOL1VvVGpnbWgwN3c2QnBmaDhQeVlCKzdzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRJd01EUXlPREE1TVRjd01Gb1hEVEl4TURReU9EQTVNVGN3TUZvd2J6RUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14RXpBUkJnTlZCQXNUQ2t0MVltVnlibVYwWlhNeEVqQVFCZ05WCkJBTVRDV0ZrYldsemMybHZiakNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLQkMKTnF5V3BSc1dmYi8yd3FGeU0vbmo1SGc0ZmJsY2YvQUNPNjFNejV5amIwVDB1NWFHd3pCeWNVMm1sN2ZqaGdscQo3N3BEWGlvaU9OYlY3N2NDNDIzZWV1MXdtajhVeENITDlNTGk5MjlNODBNWDN0NmZHWHVMUDUxTkVpaVY2YUt6Cncya2R4RFYwWklqUTd6YUNwOFExdFpDQXVpbzFzWkdlR205cUJOOHNhZjgvNkQraXRmN1dTUUZKVEt0K2k1ckMKRnVSQXo2ZEdqVmFmd2ZrS1YzeWNoT0IrRitxVm1oV3UyWFJCUjZmMDJESVNNVWFXei9DdUZ1MGpYN3pqcE1yVQpoZCtiU2lsaStodko2RHZYWkd5UUxIMlNuNG95enFSckozQktFcnhuRDBlbDYwRDVjaHUydFR1Q3pHVXhrS1NZCmRzVHNyOVpBRno5QVpFL0JvaHNDQXdFQUFhT0JuekNCbkRBT0JnTlZIUThCQWY4RUJBTUNCYUF3SFFZRFZSMGwKQkJZd0ZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRQpGUFlTRTjeTVyZFdKbExXRmtiV2x1TG5OMll6QU5CZ2txaGtpRzl3MEIKQVFzRkFBT0NBUUVBRWJnQ1ROQ2dOcys4U3ZzTTlMQ3ZKcDZGOFFqbEdxRUNBNVY3WXIxbDZFMnQ4ZW9uNFZFdgoyU0g3MTJPamJ4T29PNk1FOVExSUxWRW9EV2lvd3FWUTJzOUJRSnh2OVZEMEZpdi9Od1JjU2FSZHgrT0tQMHgvCnVyUmlkNHhIVnFBYjFlQ0wwQVF6Skh5MEV6YkU3bjV4NE1aSFhWYnhvdFA1b1RyR1R6T1VuZ0xqeWl0NFZ6UmgKUU9KSlRuVkIwY3MwZFpEVWduWTZ0VGFrSzFJY2d2ZndtVlMzN0FWZmZZcFlSNUdLTG50OGVlWEVwZFlTS1VQOApzdlNCRDRIenBqNGlVd2lLTU9LaGZja05INDM2N1k2S2pOUlhEaHp4OGVnVnp5Q3F6UGhoQWx5NlB0L1FER0ZwCk1RQmo2aFYzaUZ5NlY3UWowc0FZdDVBYzB5bERBT0RqaXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCgo=
  key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb0VJMnJKYWxHeFo5di9iQ29YSXorZVBrZURoOXVWeC84QUk3clV6UG5LTnZSUFM3CmxvYkRNSEp4VGFhWHQrT0dDV3J2dWtOZUtpSTQxdFh2dHdMamJkNTY3WENhUHhURUljdjB3dUwzYjB6elF4ZmUKM3A4WmU0cy9uVTBTS0pYcG9yUERhUjNFTlhSa2lORHZOb0tueERXMWtJQzZLald4a1o0YWIyb0UzeXhwL3ovbwpQNksxL3RaSkFVbE1xMzZMbXNJVzVFRFBwMGFOVnAvQitRcFhmSnlFNEg0WDZwV2FGYTdaZEVGSHAvVFlNaEl4ClJwYlA4SzRXN1NOZnZPT2t5dFNGMzV0S0tXTDZHOG5vTzlka2JKQXNmWktmaWpMT3BHc25jRW9TdkdjUFI2WHIKUVBseUc3YTFPNExNWlRHUXBKaDJ4T3l2MWtBWFAwQmtUOEdpR3dJREFRQUJBb0lCQUF3dGUrSVpnR3BTaHpPegpHSThVRW9jR25qSFVlUmxBd2lnR3cyb2owQkxqQ0cyQSsxQXc1VndsRmg4RWJicjNleFAwSUV0VEd6Q3djUWxDCk1Ia0RxeXlLSDJVempVVUYydkdHZ2c3ZEdGaEl6S05vaVBMNXZBSDdUdFl4S1JRVWNEQ0E0SFI0WXBSOVI3WnQKeWYrbVpnRXU0NkViWndvV0Vtd3lTMmZ6OG5MUzJsek9qN1kvbFRPcDJPZnRYZ3Q5WGV4TXR2WXc4alNpVTBmSApJMk9UcG9oYlhvL2hkOThsdDNOei9DZzIrYU4waXRvZzAxZVV3TjY2UHh2MndtQ0VsVUd5cmh4enRyY2FaQVFiCjhqQWVWUUJyUnlpUmZpU1FSTXhTOWRPMGpseXhkdzVvNUs5YzFDMEhvRkxNSEJhVmxHNWpEWWNvVGJ2S0FDSzMKVmUydUdZRUNnWUVBd3QrbnVxYVd1WkFDb3k3Vi9remFRY3EyMWxiOUZxSUlEVTVSQ3Npa3l4WktWVmZRRXBQMQpJREV6TThOL1doSFE2bm5namUwdFBXWnhpQkFzcHM2VTB3V3ViQ0VZdmdnN2wvR3AyS2czODVEeTNDWnAwY3JBCkg3cXIrTlhBR2RRS0FrdDN3UDBuNE1rYk1Jd2k2ckZ1b2lKdW5hMWJ1YmEyNUd5U0hhcXJOREVDZ1lFQTBvYjUKbmRONjJFZzM5bFc1OEZzdEtRaDBYUHZrNlE0UEFYZHN4My9RK3dZeWsweWk3aEpIVHR0MjhCMlRrVmU1Z003VQpOYnRJcGs1eUlaQmdTc0VmMktUZWpjS0hVY3NsbEFDWGFOQkJOVXFpNHltdTc1SGhwajhYc2R3Q2tRRU1ERi9vCjZyYmpyNmpHQXpsVE1McDJGRmcrTllJd3J5MjgwRXIvUWhHbnBBc0NnWUJ5dFZZMC8zUi9mQzZoUWFPRFVsZXoKSEpFdGIvMEFRcFo4eHBuYndDbUl4ZkV4ZFVRc2UxMXgrcVFLRjB5eWh3UXowVlFHRnhObkxoTXNKV0V6T3l6TgpYbTNDaG1UYkQxdU00QnE3UnFIUXhJVEFZL2dzSHEyaXY2NFZCalZTdnNhNWZSVGJ5K2lhWDZhYW1CTEJsWG5yCkJGdWFndjRZUGw0LzdVekJHOEkxTVFLQmdHVU1KQU44M2hteGtDck1PdE1DOEVvaHBMaDhyd0t0bk1ZM2JCN1YKV3BraUFHUnpCRUVBeFBrMG5ZSGlzRkd5cVhjdNd09mNDJmNHhEOGRNd3ZwRm1rMFZYOE00cHlITENWQwowQW1rS1VxZlZ6Zmw3VWkrUDhFK3VIeWc1QWVNZ1Y4bktXSEd3RVFMMzhJanZVbEdrWlZkUjhETlV6TW16QjRLCkcwekJBb0dCQUxhQTdOb0ltblg4SFZoL1RRZlcxQ3Y0VytaSjdaNFRnb2FjYnZnd05nelFlNU1aMCt5Z3hsaVMKQ1BVdVBwVVV0ejU3MWhOTjI4Q1J2c2JVZFNxS2xyZ2RubGhONFJpZDAyK243R0h1RWYvZUE1NFZab2dQcURkMApnVVdVdnZiTXljTGFiS0c5dG1lQjQ4Q0xPektDSVlyVzJ6Y2RCK1YyeXdvQ29ZQUlSSnduCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCgo=
kind: Secret
metadata:
  name: kms
  namespace: kube-admin
EOF
kubectl create -f mutating.yaml

创建webhook deployment

将TLS密钥作为卷挂载,以便可以在Web服务中使用它来启动HTTPS服务器。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kms
  namespace: kube-admin
  labels:
    app: kms
spec:
  replicas: 2
  selector:
    matchLabels:
      app: kms
  template:
    metadata:
      labels:
        app: kms
    spec:
      containers:
      - name: kms
        image: xxx/mutation:v0.3.0
        imagePullPolicy: Always
        args:
        - -tlsCertFile=/etc/webhook/certs/cert.pem
        - -tlsKeyFile=/etc/webhook/certs/key.pem
        - -alsologtostderr
        - -v=4
        - 2>&1
        volumeMounts:
        - name: webhook-certs
          mountPath: /etc/webhook/certs
          readOnly: true
      volumes:
      - name: webhook-certs
        secret:
          secretName: kms

创建webhook service

apiVersion: v1
kind: Service
metadata:
  name: kms
  namespace: kube-admin
spec:
  selector:
    app: kms
  ports:
  - protocol: TCP
    port: 443
    targetPort: 443

iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。