K8s sidecar 注入器实战部署:从 CA 签名、镜像构建到 MutatingWebhook 上线全流程

前言:那个让我怀疑人生的下午

代码写完了,单测过了,本地起 webhook server 也没问题。本以为部署就是体力活——

把代码打成镜像 → 推到节点 → kubectl apply 一把梭 → 收工下班。

理想很美好。现实是:

  • 第一次部署,证书签错了,APIServer 调 webhook 直接 x509: certificate signed by unknown authority
  • 第二次重新签,CABundle 填的是 base64 解码后的内容,APIServer 还是不认
  • 第三次终于过了认证,但 Pod 创建出来 没有 sidecar——日志里没有任何报错
  • 第四次发现 namespaceSelector 的 label 写反了
  • 第五次……

折腾完一个下午,回头看其实就 6 步。但每一步都有一个坑能让你卡半小时。今天把这条路完整走一遍,让你少踩点坑。


本节重点

  • 创建 CA 证书,通过 CSR 让 APIServer 签名
  • 获取审批后的证书,用它创建 MutatingWebhookConfiguration
  • 部署 sidecar-injector 并验证注入效果

一、编译打镜像

1.1 Makefile

把 Go 代码编译成 Linux 平台二进制(重点:必须用 GOOS=linux,否则镜像里跑不起来),再用 Docker 打包。

IMAGE_NAME ?= sidecar-injector

PWD := $(shell pwd)
BASE_DIR := $(shell basename $(PWD))

export GOPATH ?= $(GOPATH_DEFAULT)

IMAGE_TAG ?= $(shell date +v%Y%m%d)-$(shell git describe --match=$(git rev-parse --short=8 HEAD) --tags --always --dirty)

build:
	@echo "Building the $(IMAGE_NAME) binary..."
	@CGO_ENABLED=0 go build -o $(IMAGE_NAME) ./pkg/

build-linux:
	@echo "Building the $(IMAGE_NAME) binary for Docker (linux)..."
	@GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o $(IMAGE_NAME) ./pkg/

############################################################
# image section
############################################################

image: build-image

build-image: build-linux
	@echo "Building the docker image: $(IMAGE_NAME)..."
	@docker build -t $(IMAGE_NAME) -f Dockerfile .

.PHONY: all  build image

💡 CGO_ENABLED=0 是关键:用 alpine 作为基础镜像时,glibc 是缺失的。如果你的 Go 程序启用了 CGO(默认开启),编译出来的二进制依赖 glibc,进 alpine 容器后会报 not found —— 这个错超级让人迷惑,二进制明明存在,但执行就报 not found。CGO_ENABLED=0 强制静态编译,alpine 也能直接跑。

1.2 Dockerfile

FROM alpine:latest

# set environment variables
ENV SIDECAR_INJECTOR=/usr/local/bin/sidecar-injector \
  USER_UID=1001 \
  USER_NAME=sidecar-injector

COPY sidecar-injector /usr/local/bin/sidecar-injector

# set entrypoint
ENTRYPOINT ["/usr/local/bin/sidecar-injector"]

# switch to non-root user
USER ${USER_UID}

⚠️ 安全提示USER 1001 这一行别省。webhook 不需要 root 权限,跑成非 root 是 K8s 安全基线(Pod Security Standards)的硬要求。生产集群如果开了 restricted profile,root 容器直接被 admission 拒绝。

1.3 打镜像 + 分发到节点

# 在 master 节点构建
make build-image

# 导出镜像
docker save sidecar-injector > a.tar

# 拷贝到 worker 节点
scp a.tar k8s-node01:~

# 在 worker 节点导入(containerd 运行时)
ctr --namespace k8s.io images import a.tar

💡 关于 ctr --namespace k8s.io:containerd 默认 namespace 是 default,但 kubelet 用的是 k8s.io导入到错的 namespace,kubelet 找不到镜像,Pod 永远 ImagePullBackOff。这个坑我踩过两次。

如果你用的是 Docker 运行时(K8s 1.24 之前),用 docker load < a.tar 就行。

更省事的做法是搭一个内部 Registry(Harbor / Nexus),make build-imagedocker push,节点直接拉。这里为了演示简化用 save/load。


二、创建 namespace

# 业务 Pod 部署的 ns(这里的 Pod 会被注入 sidecar)
kubectl create ns nginx-injection

# sidecar-injector 自己部署的 ns
kubectl create ns sidecar-injector

两个 namespace 分开管理:

  • sidecar-injector:基础设施 ns,只跑 webhook 自己
  • nginx-injection:业务 ns,被 webhook 监听并注入

三、CA 证书:让 APIServer 信任你的 webhook

这是整个部署最容易翻车的一步。MutatingWebhook 必须通过 HTTPS 暴露,APIServer 调用 webhook 时会校验证书。如果证书不被 APIServer 信任,APIServer 调不通 webhook,Pod 创建会卡住或失败。

完整流程:生成密钥 → 创建 CSR → 让 K8s APIServer 签名 → 取签名后的证书 → 创建 Secret → 把 CA 填到 MutatingWebhookConfiguration

3.1 生成 CSR 配置文件

cat <<EOF > 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 = sidecar-injector-webhook-svc
DNS.2 = sidecar-injector-webhook-svc.sidecar-injector
DNS.3 = sidecar-injector-webhook-svc.sidecar-injector.svc
EOF

🚨 最常见的坑:SAN 必须包含 Service 的完整 DNS

APIServer 调 webhook 用的是 Service DNS(sidecar-injector-webhook-svc.sidecar-injector.svc),TLS 校验时会比对证书 SAN 字段和这个 DNS。漏写或写错 SAN,会直接报:

x509: certificate is valid for xxx, not sidecar-injector-webhook-svc.sidecar-injector.svc

上面三个 DNS 名都要写全(短名 / namespace 短名 / 完整 FQDN),缺一不可。

3.2 生成私钥

openssl genrsa -out server-key.pem 2048

3.3 用私钥生成 CSR 请求文件

openssl req -new \
    -key server-key.pem \
    -subj "/CN=sidecar-injector-webhook-svc.sidecar-injector.svc" \
    -out server.csr \
    -config csr.conf

CN(Common Name)也写成 Service 的完整 DNS,便于一些老版本客户端做兼容性校验。

3.4 删除可能存在的旧 CSR

kubectl delete csr sidecar-injector-webhook-svc.sidecar-injector

💡 为什么先删? CSR 资源的 name 在集群内全局唯一。如果你之前签过一次(哪怕 Pending 状态),再创建同名的会报 AlreadyExists。重新部署时养成习惯先删旧的。

3.5 向 APIServer 申请 CSR 签名

cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: sidecar-injector-webhook-svc.sidecar-injector
spec:
  groups:
  - system:authenticated
  request: $(< server.csr base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF

⚠️ 版本坑certificates.k8s.io/v1beta1K8s 1.22+ 被移除,必须改成 certificates.k8s.io/v1。v1 版本多了一个必填字段 signerName

spec:
  signerName: kubernetes.io/kubelet-serving   # 或 kubernetes.io/legacy-unknown
  request: ...

不同 signerName 对应不同的签名器,能否被自动审批也不一样。kubernetes.io/legacy-unknown 不会被自动审批,必须手动 approve(适合 webhook 这种一次性场景)。

3.6 查看 CSR 状态

[root@k8s-master01 ssl]# kubectl get csr
NAME                                            AGE   SIGNERNAME                     REQUESTOR          CONDITION
sidecar-injector-webhook-svc.sidecar-injector   54s   kubernetes.io/legacy-unknown   kubernetes-admin   Pending

Pending 状态——等待管理员审批。

3.7 审批 CSR

kubectl certificate approve sidecar-injector-webhook-svc.sidecar-injector
# 输出:
# certificatesigningrequest.certificates.k8s.io/sidecar-injector-webhook-svc.sidecar-injector approved

3.8 提取签名后的证书

serverCert=$(kubectl get csr sidecar-injector-webhook-svc.sidecar-injector -o jsonpath='{.status.certificate}')
echo "${serverCert}" | openssl base64 -d -A -out server-cert.pem

这一步把 APIServer 签好的证书从 CSR 资源里取出来,base64 解码后存到本地 server-cert.pem

3.9 把证书放进 Secret

kubectl create secret generic sidecar-injector-webhook-certs \
        --from-file=key.pem=server-key.pem \
        --from-file=cert.pem=server-cert.pem \
        --dry-run=client -o yaml |
    kubectl -n sidecar-injector apply -f -

💡 这里用 --dry-run=client -o yaml | apply 的小技巧:先在客户端生成 YAML,再 apply。好处是幂等——如果 Secret 已存在,会更新而不是报错。kubectl create secret 直接执行的话,重复运行会 AlreadyExists

检查 Secret:

kubectl get secret -n sidecar-injector
# 输出:
# NAME                             TYPE                                  DATA   AGE
# default-token-hvgnl              kubernetes.io/service-account-token   3      25m
# sidecar-injector-webhook-certs   Opaque                                2      25m

DATA=2 说明 key.pemcert.pem 都进去了。


四、CABundle:让 MutatingWebhookConfiguration 认证书

MutatingWebhookConfiguration 里有个 caBundle 字段,告诉 APIServer:“调你这个 webhook 时,用这个 CA 来验证它的证书”。我们的证书是 APIServer 自己签的,所以 caBundle 就是 集群 CA 的 base64 编码

4.1 获取集群 CA

CA_BUNDLE=$(kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}')

# 备用方案:从 default sa 的 token secret 里取
if [ -z "${CA_BUNDLE}" ]; then
    CA_BUNDLE=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.ca\.crt}")
fi

🚨 超级容易踩的坑certificate-authority-data 拿到的已经是 base64 编码的字符串,直接填到 caBundle 里就行,不要 base64 -d 解码!

我第一次部署就栽在这——看到字符串以为是原始数据,手贱解了一次码再填进去,结果 APIServer 把它当 PEM 解析失败,报 tls: failed to verify certificate: x509: certificate signed by unknown authoritycaBundle 期望的就是 base64 后的字符串

4.2 把 CABundle 替换到 webhook 配置里

mutating_webhook.yaml 模板里写了占位符 ${CA_BUNDLE}

# mutating_webhook.yaml(节选)
clientConfig:
  service:
    name: sidecar-injector-webhook-svc
    namespace: sidecar-injector
    path: "/mutate"
  caBundle: ${CA_BUNDLE}

sed 把占位符替换成真实值:

cat deploy/mutating_webhook.yaml | sed -e "s|\${CA_BUNDLE}|${CA_BUNDLE}|g" > deploy/mutatingwebhook-ca-bundle.yaml

检查替换结果:

cat deploy/mutatingwebhook-ca-bundle.yaml

caBundle 字段应该是一串很长的 base64 字符串(通常 1000+ 字符),不是 ${CA_BUNDLE} 字面量。

4.3 用脚本一键完成

上面的步骤可以全部封装成脚本(这里复用了 Istio 项目的 webhook-create-signed-cert.sh):

chmod +x ./deploy/*.sh

# 一键完成:生成证书 → 申请签名 → 审批 → 创建 Secret
./deploy/webhook-create-signed-cert.sh \
    --service sidecar-injector-webhook-svc \
    --secret sidecar-injector-webhook-certs \
    --namespace sidecar-injector

# 一键完成:CABundle 替换
cat deploy/mutating_webhook.yaml | \
    deploy/webhook-patch-ca-bundle.sh > \
    deploy/mutatingwebhook-ca-bundle.yaml

生产环境强烈建议用 cert-manager 自动管理证书生命周期,省心很多。


五、部署 sidecar-injector

5.1 先部署 webhook 本体

按顺序部署三个资源:

# 1. 配置文件(sidecar 模板:要注入哪些容器、哪些 volume)
kubectl create -f deploy/inject_configmap.yaml

# 2. Deployment(webhook server)
kubectl create -f deploy/inject_deployment.yaml

# 3. Service(暴露 webhook HTTPS 端口)
kubectl create -f deploy/inject_service.yaml

检查 Pod 和 Service:

[root@k8s-master01]# kubectl get pod -n sidecar-injector
NAME                                                   READY   STATUS    RESTARTS   AGE
sidecar-injector-webhook-deployment-5cd7466c9f-xqpq4   1/1     Running   0          98s

[root@k8s-master01]# kubectl get svc -n sidecar-injector
NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
sidecar-injector-webhook-svc   ClusterIP   10.96.171.114   <none>        443/TCP   111s

⚠️ Pod 起不来怎么办? 最常见 3 个原因:

  1. 镜像不在节点上 → ImagePullBackOff,检查 ctr -n k8s.io images ls | grep sidecar-injector
  2. Secret 没挂上 → Pod 报 MountVolume.SetUp failed,检查 Deployment 里 volumes.secret.secretName 和实际 Secret 名一致
  3. 二进制和镜像架构不匹配 → CrashLoopBackOff,日志报 exec format error,确认 GOARCH 和节点架构一致

5.2 部署 MutatingWebhookConfiguration

这一步把 webhook 注册到 APIServer。注册成功后,所有匹配的 Pod 创建请求都会先经过你的 webhook

kubectl create -f deploy/mutatingwebhook-ca-bundle.yaml

检查:

[root@k8s-master01]# kubectl get MutatingWebhookConfiguration -A
NAME                           WEBHOOKS   AGE
sidecar-injector-webhook-cfg   1          57s

🚨 这一步部署完之后,整个集群的 Pod 创建都会过这个 webhook。如果 webhook 配置有问题(比如证书错、Service 不通),可能会让 所有 Pod 都无法创建。务必确认 failurePolicy: Ignore 已配置,或者你只是在测试集群操作。

5.3 部署 sidecar 容器需要的 ConfigMap

我们要注入的 sidecar 是个 nginx 容器,它需要 nginx 配置文件——这个配置以 ConfigMap 形式挂进 sidecar:

kubectl create -f deploy/nginx_configmap.yaml

5.4 给业务 ns 打标签,启用注入

MutatingWebhookConfiguration 里通常配置了 namespaceSelector,只对指定 label 的 namespace 生效。这样可以按 namespace 粒度控制注入范围,避免影响其他业务。

kubectl create ns nginx-injection
kubectl label namespace nginx-injection sidecar-injection=enabled

sidecar-injection=enabled 这个 label 必须和 webhook 配置里的 namespaceSelector 完全一致:

namespaceSelector:
  matchLabels:
    nginx-sidecar-injection: enabled

🚨 超容易翻车点:上面这个 YAML 写的是 nginx-sidecar-injection,但我们打的 label 是 sidecar-injection——两个 key 不一样!这是原文档的一个不一致,实际部署时必须保证 label key 和 namespaceSelector 完全相同,否则 webhook 永远不会被触发,且没有任何报错

排查这个问题的最快方法:kubectl get ns nginx-injection --show-labels 对照 webhook 配置里的 namespaceSelector.matchLabels,字符一个一个比。

确认 label 已打上:

kubectl get ns -L nginx-sidecar-injection
NAME               STATUS   AGE     NGINX-SIDECAR-INJECTION
default            Active   156d
kube-system        Active   156d
nginx-injection    Active   3h57m   enabled
sidecar-injector   Active   4h38m

最后一列显示 enabled 才算生效。


六、验证:注入一个 Pod 试试

6.1 部署一个需要注入的 Pod

关键是 annotations 里写 need_inject: "true"

apiVersion: v1
kind: Pod
metadata:
  namespace: nginx-injection
  name: test-alpine-inject-01
  labels:
    role: myrole
  annotations:
    sidecar-injector-webhook.nginx.sidecar/need_inject: "true"
spec:
  containers:
    - image: alpine
      command:
        - /bin/sh
        - "-c"
        - "sleep 60m"
      imagePullPolicy: IfNotPresent
      name: alpine
  restartPolicy: Always

部署:

[root@k8s-master01 deploy]# kubectl create -f test_sleep_deployment.yaml
pod/test-alpine-inject-01 created

6.2 验证 sidecar 已注入

注意 READY 列——原本 Pod 只有 1 个容器(alpine),现在变成 2/2

[root@k8s-master01 deploy]# kubectl get pod -n nginx-injection -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE
test-alpine-inject-01   2/2     Running   0          78s   10.100.85.216   k8s-node01   <none>

curl 一下 Pod IP 的 80 端口,应该能拿到 nginx 的响应(404 是正常的,因为我们没配 root 目录):

[root@k8s-master01 deploy]# curl 10.100.85.216
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>

看到 nginx/1.12.2 说明 sidecar 已经成功注入并对外提供服务

6.3 看 sidecar-injector 日志确认整条链路

kubectl logs -n sidecar-injector deployment/sidecar-injector-webhook-deployment

应该能看到类似这样的日志(节选关键部分):

I0910 08:35:14.788857  webhook.go:179] serveMutate.receive.request: Body={"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1beta1","request":{"uid":"17d2ced2-...","kind":{"group":"","version":"v1","kind":"Pod"},"name":"test-alpine-inject-01","namespace":"nginx-injection",...}}

I0910 08:35:14.789561  webhook.go:128] AdmissionReview for Kind=/v1, Kind=Pod, Namespace=nginx-injection Name=test-alpine-inject-01 UID=17d2ced2-... patchOperation=CREATE

I0910 08:35:14.789945  webhook.go:154] AdmissionResponse: patch=[
  {"op":"add","path":"/spec/containers/-","value":{"name":"sidecar-nginx","image":"nginx:1.12.2","ports":[{"containerPort":80}],...}},
  {"op":"add","path":"/spec/volumes/-","value":{"name":"nginx-conf","configMap":{"name":"nginx-configmap"}}},
  {"op":"add","path":"/metadata/annotations","value":{"sidecar-injector-webhook.nginx.sidecar/status":"injected"}}
]

I0910 08:35:14.789987  webhook.go:221] Ready to write reponse ...

三段 patch 一目了然:加 sidecar 容器 → 加 nginx-conf volume → 加 status: injected 标记

6.4 部署一个不需要注入的 Pod 做对照

把 annotation 改成 need_inject: "false",验证 webhook 能正确跳过:

apiVersion: v1
kind: Pod
metadata:
  namespace: nginx-injection
  name: test-alpine-inject-02
  labels:
    role: myrole
  annotations:
    sidecar-injector-webhook.nginx.sidecar/need_inject: "false"
spec:
  containers:
    - image: alpine
      command:
        - /bin/sh
        - "-c"
        - "sleep 60m"
      imagePullPolicy: IfNotPresent
      name: alpine
  restartPolicy: Always

部署后查看:

kubectl get pod -n nginx-injection -o wide
NAME                    READY   STATUS    RESTARTS   AGE    IP              NODE
test-alpine-inject-01   2/2     Running   0          6m8s   10.100.85.216   k8s-node01
test-alpine-inject-02   1/1     Running   0          77s    10.100.85.215   k8s-node01

test-alpine-inject-02 只有 1/1——没被注入,符合预期。

日志里也能看到对应的跳过逻辑:

I0910 08:40:05.466733  webhook.go:106] [skip_mutation][reason=pod_not_need][name:test-alpine-inject-02][ns:nginx-injection]
I0910 08:40:05.466765  webhook.go:133] Skipping mutation for nginx-injection/test-alpine-inject-02 due to policy check
I0910 08:40:05.466815  webhook.go:221] Ready to write reponse ...

reason=pod_not_need 清晰地说明了原因。这种带原因码的日志在生产环境排查问题时巨好用,强烈建议你的 webhook 也这么打。


七、完整流程图

                ┌──────────────────────────────────────┐
                │   Step 1: 编译打镜像                  │
                │   make build-image → docker save      │
                │   → scp → ctr import                  │
                └──────────────┬───────────────────────┘
                               ▼
                ┌──────────────────────────────────────┐
                │   Step 2: 创建 namespace             │
                │   nginx-injection / sidecar-injector  │
                └──────────────┬───────────────────────┘
                               ▼
                ┌──────────────────────────────────────┐
                │   Step 3: CA 证书                    │
                │   openssl → CSR → approve            │
                │   → Secret(key.pem, cert.pem)        │
                └──────────────┬───────────────────────┘
                               ▼
                ┌──────────────────────────────────────┐
                │   Step 4: CABundle 替换              │
                │   kubectl config → caBundle 字段     │
                └──────────────┬───────────────────────┘
                               ▼
                ┌──────────────────────────────────────┐
                │   Step 5: 部署                       │
                │   ConfigMap + Deployment + Service   │
                │   + MutatingWebhookConfiguration     │
                │   + ns label                          │
                └──────────────┬───────────────────────┘
                               ▼
                ┌──────────────────────────────────────┐
                │   Step 6: 验证                       │
                │   apply test pod → 看 2/2 + curl     │
                └──────────────────────────────────────┘

八、部署排查 Checklist(生产环境保命)

下面这份清单是我踩坑后整理的,强烈建议照着一条条对:

#检查项命令 / 方法出问题的现象
1镜像在节点上ctr -n k8s.io images ls | grep sidecarPod ImagePullBackOff
2镜像架构匹配file sidecar-injector(看 ELF 架构)Pod CrashLoopBackOff, exec format error
3webhook Pod Runningkubectl get pod -n sidecar-injector注入完全不生效
4Service 可达kubectl get svc -n sidecar-injectorAPIServer 调不通 webhook
5Secret 已挂载kubectl describe pod 看 Volumes 段webhook 启动失败
6证书 SAN 含 Service DNSopenssl x509 -in cert.pem -text -noout | grep DNSx509: certificate is valid for...
7CABundle 不要再 base64 解码看 caBundle 字段长度(>1000 字符)x509: signed by unknown authority
8CSR API 版本对K8s ≥1.22 用 v1,并写 signerNameCSR 创建失败
9namespaceSelector label 完全匹配kubectl get ns --show-labels 对照 webhook 配置webhook 永远不被触发,无报错
10failurePolicy: Ignore看 MutatingWebhookConfiguration 字段webhook 挂了导致整集群 Pod 创建失败
11annotation key 拼写一致kubectl get pod -o yaml 比对代码常量mutationRequired 永远 return false
12webhook 自身不被自己注入objectSelector 排除 webhook 自己webhook 注入死锁,Pod 起不来

九、本节小结

把 sidecar 注入器跑起来,本质就是 6 个 step

  1. 打镜像:注意静态编译 + 推到正确的 containerd namespace
  2. 建 ns:业务 ns 和 webhook ns 分离
  3. 签证书:注意 SAN、CSR API 版本、签好的证书放进 Secret
  4. 填 CABundle:直接用 base64 字符串,不要解码
  5. 部署 webhook + 注册 MutatingWebhookConfiguration:注意 failurePolicy
  6. 打 ns label + 验证:label key 必须和 namespaceSelector 一致

整条链路里最隐蔽的坑是第 9 条——namespaceSelector label 拼错。它不会有任何报错,webhook server 一切正常,Pod 创建也正常,就是 sidecar 注不进去。我第一次部署有一半时间都是在找这个问题。

下一节会进入更进阶的话题:生产环境如何用 cert-manager 自动续期证书、如何用 objectSelector 排除 webhook 自身、以及 webhook 升级时的零停机方案


十、你踩过这些坑吗?

  1. 你们生产环境的 webhook 证书是手动签的还是用 cert-manager 自动管理的?过期处理方案是什么?
  2. failurePolicyIgnore 还是 Fail?你们是基于什么场景做的决策?是否遇到过 webhook 挂了导致整集群 Pod 创建失败的情况?
  3. webhook 升级时怎么做到对业务无感?滚动更新有没有坑过你?

欢迎在评论区分享你的踩坑实录,我会整理补充到这份 Checklist 里。

十一、延伸思考

  • 如果一个 Pod 要被 多个 MutatingWebhook 处理(比如 Istio + 你自己的),patch 的合并顺序是什么?谁的修改会被覆盖?
  • MutatingWebhookConfiguration 里的 reinvocationPolicy: IfNeeded 是干什么的?什么时候必须开?
  • 怎么给 webhook 做 健康检查?仅仅 /healthz 还不够,怎么保证 TLS 配置也是健康的?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加倍巴巴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值