使用Nginx作为外部负载均衡器时Kubernetes API Server负载均衡失败求助
我之前搭建多master节点的Kubernetes高可用集群时,也碰到过和你几乎一模一样的问题——用Nginx做APIServer的负载均衡,结果kubelet、kube-proxy这些组件死活连不上,折腾了好几天才把坑都踩完。给你梳理几个最关键的排查方向,应该能帮你解决问题:
先排查Nginx的负载均衡配置(最常见的坑)
APIServer是基于HTTPS的服务,Nginx的配置方式直接决定了转发是否正常,这里分两种情况说:
- 推荐用四层TCP转发:这种方式不需要Nginx处理HTTPS证书,直接转发TCP流量到后端APIServer,出错概率最低。给你一个参考配置:
stream { upstream k8s-apiservers { # 用最少连接策略分配请求 least_conn; # 配置三个APIServer节点的地址和端口,添加失败重试机制 server 192.168.1.10:6443 max_fails=3 fail_timeout=30s; server 192.168.1.11:6443 max_fails=3 fail_timeout=30s; server 192.168.1.12:6443 max_fails=3 fail_timeout=30s; # 开启健康检查,只转发到正常的节点 health_check interval=5s; } server { listen 6443; proxy_pass k8s-apiservers; # 适配APIServer的长连接需求 proxy_timeout 10m; proxy_connect_timeout 1s; } } - 如果用七层HTTPS代理:必须确保Nginx的
server_name和APIServer证书的SAN字段完全匹配,同时要添加以下配置来避免请求头丢失和长连接问题:
这种方式需要在Nginx上配置APIServer的CA证书和服务端证书,复杂度更高,不推荐除非有特殊需求。proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Connection "";
检查集群组件的kubeconfig配置
所有和APIServer通信的组件(kubelet、kube-proxy、controller-manager、scheduler)的kubeconfig文件里,server字段必须指向Nginx负载均衡的VIP/地址,而不是单个APIServer的节点地址:
- 比如kubelet的kubeconfig通常在
/var/lib/kubelet/kubeconfig,打开后确认server字段是https://<nginx-vip>:6443 - 同时要确保kubeconfig里的CA证书和APIServer使用的CA证书完全一致,否则会出现SSL验证失败。可以用这条命令测试连通性:
如果返回curl -v --cacert /path/to/ca.crt https://<nginx-vip>:6443/healthzok,说明基础连通性没问题;如果出现SSL错误,那就是证书不匹配或者Nginx配置的问题。
验证后端APIServer的可达性和绑定地址
- 先在Nginx所在节点,用
telnet <apiserver-node-ip> 6443测试每个APIServer的6443端口是否能连通,排除节点之间的防火墙/安全组拦截问题 - 检查每个APIServer的启动参数,确认
--bind-address设置的是0.0.0.0或者节点的内网IP,而不是127.0.0.1——如果绑定到本地回环地址,Nginx根本无法访问到APIServer
重启组件并查看日志
如果你修改了Nginx配置或者组件的kubeconfig,一定要重启对应的服务:
- 重启Nginx:
systemctl restart nginx,并查看日志tail -f /var/log/nginx/error.log,看有没有转发失败的报错 - 重启集群组件:比如
systemctl restart kubelet kube-proxy kube-controller-manager kube-scheduler,然后查看组件日志(比如journalctl -u kubelet -f),看有没有连接APIServer失败的具体错误信息
内容的提问来源于stack exchange,提问作者e-pirate
相关产品推荐
相关产品推荐

