Dok Docs
Github Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

kube-apiserver-ha

概述

一般环境下由于没有 vip 等工具的提供,所以通过在 worker 节点上部署 Nginx,反向代理 worker 到 kube-apiserver 的请求来实现可高用。

原理介绍

所有的节点上,不管是 controlplane 普通 worker 节点上的组件,如 kube-proxy, kube-controller-manager 等,都不会直接访问 kube-apiserver,默认情况下这个地址应该是 ip:6443,然而 DOK 改造的地方,是会在每个节点上都部署一个 Nginx 组件作为反向代理,组件通过访问本地的 127.0.0.1:8443,就会被代理到任意的 kube-apiserver 上,从而实现 kube-apiserver 的 HA,目前 DOK 的实现是会在每个节点上部署一个 nginx 将请求代理到 kube-apiserver。

反向代理的部署也可以通过静态 Pod 实现的,所以 kubelet 进程是会帮助管理这个静态 Pod,会检测起状态,辅助重新拉起等,关于静态 Pod 的原理,可以参考官方文档

反向代理后的影响

需要关心的 kubelet/kube-proxy 如果通过反向代理访问 kube-apiserver 的话,对其他组件会有影响吗?真实的情况是不会的,因为原来的6443端口仍然可用,比如一些健康检查,指标获取仍然可以通过6443端口来获取。

简单测试

nerdctl pull docker.io/tekn0ir/nginx-stream
nerdctl run -d -p 8443:8443 -v /root/stream.conf.d:/opt/nginx/stream.conf.d -v /root/http.conf.d:/opt/nginx/http.conf.d --name nginx tekn0ir/nginx-stream
nerdctl run -d -p 8443:8443 -v /root/stream.conf.d:/opt/nginx/stream.conf.d -v /root/http.conf.d:/opt/nginx/http.conf.d --name nginx nginx-stream
docker run -d --net host -p 8443:8443 --name nginx nginx-stream

未来是计划通过Static Pod来实现反向代理的部署,不过需要解决一下循环依赖的问题

第一期方案

离线安装Nginx

目前只会在 worker 节点安装 Nginx 作为 kube-apiserver 的反向代理,用户也可以在安装包中找到 Nginx 相关的 rpm 包自行安装。

rpm -ivh /root/dok-release/bin/kernel/rh-nginx120* /root/dok-release/bin/kernel/scl-utils*

日志收集

默认的日志收集在 /var/log/nginx/tcp-access.log

img.png

第二期方案

考虑到安装 Nginx 对不同版本的内核和源会有一些要求,所以第二期方案考虑了直接使用容器来部署这个代理的容器,这个容器的部署会在 kubeadm init 之前,也就是 Kubelet 启动后直接就会通过这个代理去等待 kube-apiserver 的启动。

nerdctl -n k8s.io run --network host --name reverse-nginx-proxy -v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx:1.20.1-alpine

第三期方案(Pending)

上文有提到,未来计划是通过 Static Pod 来部署反向代理,其实网络上代理关系跟直接部署 Nginx 是没有区别的,主要的区别在于通过 Static Pod 来部署反向代理,不需要管不同操作系统、源以及 Nginx 版本和依赖的影响,并且 Kubelet 可以协助管理反向代理的 Pod,日志采集上跟普通 Pod 采集可以一起做完,具体的实现可以查看 kube-ha-proxy.yaml, 计划是通过 --experimental-patches /root/dok-release/bin/k8s/ 这样的参数,控制 kubeadm 读取 patch.yaml patch 到 kube-apiserver 中。

目前遇到的问题是kubeadm创建的/etc/kubernetes/manifest无法放自定义的静态Pod的Yaml,放了也不会启动,在不改造kubeadm的条件下,不好实现

问题排查

参考资料

  1. 基于nginx代理的kube-apiserver高可用方案