Kubernetes准入Webhook是否必须启用TLS?证书报错及文档疑问
问题背景
尝试搭建自定义Kubernetes准入Webhook,希望不使用TLS协议,但了解kube-apiserver会向Webhook服务器发起HTTPS请求,因此配置了带有虚拟证书的TLS服务器。
Webhook服务器代码
package main import ( "crypto/tls" "fmt" "html" "log" "net/http" ) func handleRoot(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello test.. %q", html.EscapeString(r.URL.Path)) } type Config struct { CertFile string KeyFile string } func main() { log.Print("Starting server ...2.2") http.HandleFunc("/test", handleRoot) config := Config{ CertFile: cert, KeyFile: key, } server := &http.Server{ Addr: ":9543", TLSConfig: configTLS(config), } err := server.ListenAndServeTLS("", "") if err != nil { panic(err) } } func configTLS(config Config) *tls.Config { sCert, err := tls.X509KeyPair([]byte(config.CertFile), []byte(config.KeyFile)) if err != nil { log.Fatal(err) } return &tls.Config{ Certificates: []tls.Certificate{sCert}, ClientAuth: tls.NoClientCert, InsecureSkipVerify: true, } }
MutatingWebhookConfiguration配置
apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: creationTimestamp: null labels: test-webhook-service.io/system: "true" name: test-webhook-service-mutating-webhook-configuration webhooks: - admissionReviewVersions: - v1 - v1beta1 clientConfig: service: name: test-webhook-service-service namespace: test-webhook-service-system path: /test failurePolicy: Ignore matchPolicy: Equivalent name: mutation.test-webhook-service.io rules: - apiGroups: - "" apiVersions: - v1 operations: - CREATE - UPDATE resources: - pods sideEffects: None
报错信息
2022/09/30 05:42:56 Starting server ...2.2 2022/09/30 05:43:23 http: TLS handshake error from 10.100.0.1:37976: remote error: tls: bad certificate
问题解答
1. 错误含义
remote error: tls: bad certificate 表示kube-apiserver作为客户端,在与Webhook服务器建立TLS连接时,无法信任服务器提供的证书。因为你使用的是"虚拟证书",该证书不在kube-apiserver的信任链范围内,所以被判定为无效证书,导致TLS握手终止。
2. TLS是否是必选项?是否必须配置有效的caBundle?
是的,TLS是Kubernetes准入Webhook的强制要求,kube-apiserver仅支持通过HTTPS与Webhook服务器通信,不允许HTTP请求。
caBundle字段必须配置为签发Webhook服务器证书的CA证书的Base64编码内容。kube-apiserver会通过这个CA证书验证Webhook服务器证书的有效性。如果未配置有效的caBundle,或者证书不在kube-apiserver的信任范围内,就会触发你遇到的证书错误。
你使用虚拟证书的方式无法通过验证,必须使用由可信CA(集群自签CA或自建CA均可)签发的证书,并在MutatingWebhookConfiguration的clientConfig中正确配置caBundle。
3. 官方文档描述的翻译与解释
原文引用:
The example admission webhook server leaves the ClientAuth field
empty, which defaults to NoClientCert. This means that the webhook
server does not authenticate the identity of the clients, supposedly
API servers.
翻译:
示例准入Webhook服务器将ClientAuth字段留空,其默认值为NoClientCert。这意味着该Webhook服务器不会对客户端(即API服务器)的身份进行验证。
这段描述聚焦的是Webhook服务器对客户端(kube-apiserver)的身份验证逻辑,和你当前遇到的问题分属两个验证方向:
- 你碰到的是kube-apiserver作为客户端,验证Webhook服务器的证书是否可信
- 这段文档讲的是Webhook服务器是否要求kube-apiserver提供客户端证书,来确认对方的身份
你的代码里已经明确设置了ClientAuth: tls.NoClientCert,和文档示例逻辑一致,所以Webhook不会校验apiserver的身份,但apiserver仍然会强制校验Webhook的证书有效性,这正是你出现报错的核心原因。
内容的提问来源于stack exchange,提问作者Ishani Gupta

