- 由 虚拟的现实创建于9月 06, 2024 需要 3 分钟阅读时间
K8S 高可用相关
etcd 就不说了,奇数个副本,可以坏 (n-1)/2 个,有条件的可以单独 SSD 机器部署 etcd 。K8S 所有组件和客户端,都会使用 kubeconfig 或者集群内 rbac 的 serviceaccount 后通过 kubernetes 这个 service 最终连到实体的 kube-apiserver 进程。
etcd 集群下,一般都是 kube-apiserver/kube-controller-manager/kube-scheduler 部署多份,但是所有的都是连接 kube-apiserver,所以需要一个负载均衡负载到 kube-apiserver 副本上。
K8S 集群内部相关
集群内部自带了第一个 Service CIDR 第一个 IP 的 kubernetes service:
$ kubectl -n default describe svc kubernetes Name: kubernetes Namespace: default Labels: component=apiserver provider=kubernetes Annotations: <none> Selector: <none> Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.0.1 IPs: 10.96.0.1 Port: https 443/TCP TargetPort: 6443/TCP Endpoints: 192.168.2.111:6443,192.168.2.112:6443,192.168.2.113:6443 Session Affinity: None Events: <none>
集群内部访问 https://kubernetes.default 最终解析成 10.96.0.1,然后 DNAT 到 endpoint 里任意一个 kube-apiserver。可能有些聪明的人会问,这看起来是 kube-apiserver 上报的自己网卡 IP,如果是 nat 后的怎么处理,kube-apiserver 提供了 --advertise-address 选项,用于告诉访问自己使用哪个 IP。
使用负载均衡
kube-apiserver 本质上是个 web 七层服务,所以我们要整高可用不要把 k8s 想的太复杂了,保证了 apiserver 的高可用就行了。tcp 和 web 层面,是否软硬件,还是组合使用都行,例如:
- 硬件 F5 配置转发
- nginx、caddy、envoy、haproxy
- 云上 SLB 代理
- keepalived VRRP
- keepalived VRRP + haproxy
- 网络设备 ospf + lvs
...
如果是 7层负载均衡,健康检查可以用应用层面 url /healthz:
$ kubectl get --raw / | grep /healthz "/healthz", "/healthz/autoregister-completion", "/healthz/etcd", "/healthz/log", "/healthz/ping", "/healthz/post ...
可以 kube-apiserver 不配置 --anonymous-auth=false 后 /healthz 路由就返回 200 状态码了,或者把证书上传到 SLB 上之类的配置里,7层检查,例如下面是 haproxy 的 7 层检查 tcp 代理:
frontend k8s-api bind 0.0.0.0:8443 bind 127.0.0.1:8443 mode tcp option tcplog tcp-request inspect-delay 5s default_backend k8s-api backend k8s-api mode tcp option tcplog option httpchk GET /healthz http-check expect string ok balance roundrobin default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100 server api1 192.168.2.111:6443 check check-ssl verify none server api2 192.168.2.112:6443 check check-ssl verify none server api3 192.168.2.113:6443 check check-ssl verify none
kubeconfig 文件里包含有 kubernetes 的 URL 地址,想在使用 kubectl 的时候绕过负载均衡,可以使用 -s, --server= 来指定 kube-apiserver url ,另外可能你会遇到 kubectl 报错无法连接:
这是因为没有 ~/.kube/config 文件和 KUBECONFIG 变量文件不存在或者权限问题下,kubectl 默认认为连接 kube-apiserver 地址是 http://localhost:8080 的不需要授权的匿名地址,而现在 kube-apiserver 都会把 insecure-port 关闭了造成的报错。
local proxy
在一些私有化环境内,客户会无法提供 SLB 和硬件负载均衡,环境也可能是 openstack 环境上的虚拟机而无法使用 VRRP VIP(会因为 IP 和 MAC 不匹配被 drop),所以可以使用 local proxy 方式代理,也就是每个节点上部署一个软件做负载均衡,例如每个节点部署一个 nginx,监听 0.0.0.0:8443 反向代理
upstream kube_apiserver { least_conn; server 192.168.2.111:6443 max_fails=3 fail_timeout=10s; server 192.168.2.112:6443 max_fails=3 fail_timeout=10s; server 192.168.2.113:6443 max_fails=3 fail_timeout=10s; } server { listen 0.0.0.0:8443; proxy_pass kube_apiserver; proxy_connect_timeout 1s; }
例如下面是市面上的 sealos 就是使用 kubeadm 部署,staticPod 的目录加了个 yaml,使用的内核 lvs 能力做四层负载。每个 node 跑一个 lvs 的 watch 进程的 pod 去维护 lvs 的规则保持高可用:
再次重申下,不要局限在自己会的软件和实现手段的顽固思想上,而是看场景和后续升级维护和规模多方面考虑,例如如果客户经常注重漏洞扫描 CVE,那选择 caddy 这种单二进制 web server 做代理更新方便。
- 无标签
添加评论