通过负载均衡器使用kubectl访问K8s API Server遇认证及证书问题求助
看起来你在通过Nginx反向代理Kubernetes API Server时遇到了两个典型的认证和证书问题,我来帮你拆解问题并给出修复方案:
首先先明确你之前操作里的两个核心错误:
- 一开始用HTTP代理API Server:K8s API Server默认只接受HTTPS请求,而且即使kubectl带着认证信息,HTTP传输要么会丢失认证数据,要么直接被API Server拒绝(因为它不允许未加密的连接)。
- 后来改用HTTPS但复用了API Server的证书:这个证书是为API Server的IP(192.168.0.10)签发的,当kubectl连接负载均衡器IP(10.10.0.2)时,证书的主题备选名称(SAN)不匹配,自然触发x509验证错误。
接下来是具体的修复步骤:
1. 调整Nginx配置,正确做HTTPS反向代理并传递认证信息
Nginx需要作为HTTPS端点,同时确保kubectl的认证信息(不管是客户端证书还是Bearer Token)能完整传递给后端的API Server。修改你的Nginx配置如下:
server { listen 8080 ssl; listen [::]:8080 ssl; server_name _; # 这里要用包含负载均衡器IP(10.10.0.2)的SSL证书,后面会说怎么生成 ssl_certificate /path/to/your/lb-cert.pem; ssl_certificate_key /path/to/your/lb-key.pem; # 允许客户端提供证书(kubectl会自动用kubeconfig里的客户端证书) ssl_verify_client optional; location / { proxy_pass https://192.168.0.10:6443; # 把客户端证书传递给API Server,用于认证 proxy_set_header X-SSL-CERT $ssl_client_cert; # 传递真实客户端IP给API Server proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 确保API Server能正确识别请求的SSL名称 proxy_ssl_server_name on; # 如果API Server用的是自签证书,需要把它的CA证书加到这里,让Nginx信任 proxy_ssl_trusted_certificate /path/to/api-server-ca.pem; } }
2. 解决证书不匹配问题
这里有两种方案,根据你的环境选择:
方案A:生成适配负载均衡器的SSL证书(生产环境推荐)
你需要生成一个包含10.10.0.2作为SAN的证书,用于Nginx。如果是自签证书,可以用openssl一步步生成:
# 先生成CA证书(如果没有现成的CA) openssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca-cert.pem -days 365 -nodes -subj "/CN=K8s-LB-CA" # 生成负载均衡器的证书请求 openssl req -newkey rsa:4096 -keyout lb-key.pem -out lb-csr.pem -nodes -subj "/CN=10.10.0.2" # 创建SAN配置文件,指定负载均衡器的IP echo "subjectAltName = IP:10.10.0.2" > lb-san.cnf # 用刚才生成的CA签署负载均衡器的证书 openssl x509 -req -in lb-csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out lb-cert.pem -days 365 -extfile lb-san.cnf
生成后,把lb-cert.pem和lb-key.pem配置到Nginx中,然后修改你的kubeconfig,让kubectl信任这个CA证书:
apiVersion: v1 clusters: - cluster: certificate-authority: /path/to/ca-cert.pem # 就是刚才生成的CA证书路径 server: https://10.10.0.2:8080 name: your-cluster-name # 替换成你的集群名称 # 其他用户、上下文配置保持不变
方案B:临时跳过证书验证(仅测试环境用)
如果只是测试环境不想折腾证书,可以直接修改kubeconfig,让kubectl跳过证书验证:
apiVersion: v1 clusters: - cluster: insecure-skip-tls-verify: true server: https://10.10.0.2:8080 name: your-cluster-name # 其他配置不变
3. 验证配置
重启Nginx让配置生效:
systemctl restart nginx
然后执行kubectl get nodes,应该就能正常返回节点列表了。
最后再复盘下你之前的操作失误:
- 用HTTP代理API Server:K8s API Server默认强制HTTPS,HTTP连接会被直接拒绝,而且kubectl的认证信息在HTTP传输中也可能无法正确传递。
- 复用API Server的证书:证书的SAN字段必须包含客户端连接的IP/域名,否则kubectl的证书验证会失败,这是TLS的基本要求。
内容的提问来源于stack exchange,提问作者s_z_p
相关产品推荐
相关产品推荐

