06-0 kube-apiserver 高可用之 nginx 代理

    注意:如果没有特殊指明,本文档的所有操作均在 zhangjun-k8s01 节点上执行,然后远程分发文件和执行命令。

    • 控制节点的 kube-controller-manager、kube-scheduler 是多实例部署,所以只要有一个实例正常,就可以保证高可用;
    • 集群内的 Pod 使用 K8S 服务域名 kubernetes 访问 kube-apiserver, kube-dns 会自动解析出多个 kube-apiserver 节点的 IP,所以也是高可用的;
    • 在每个节点起一个 nginx 进程,后端对接多个 apiserver 实例,nginx 对它们做健康检查和负载均衡;
    • kubelet、kube-proxy、controller-manager、scheduler 通过本地的 nginx(监听 127.0.0.1)访问 kube-apiserver,从而实现 kube-apiserver 的高可用;

    下载和编译 nginx

    下载源码:

    配置编译参数:

    1. mkdir nginx-prefix
    2. ./configure --with-stream --without-http --prefix=$(pwd)/nginx-prefix --without-http_uwsgi_module --without-http_scgi_module --without-http_fastcgi_module
    • --with-stream:开启 4 层透明转发(TCP Proxy)功能;
    • --without-xxx:关闭所有其他功能,这样生成的动态链接二进制程序依赖最小;

    输出:

    1. Configuration summary
    2. + PCRE library is not used
    3. + OpenSSL library is not used
    4. + zlib library is not used
    5. nginx path prefix: "/root/tmp/nginx-1.15.3/nginx-prefix"
    6. nginx binary file: "/root/tmp/nginx-1.15.3/nginx-prefix/sbin/nginx"
    7. nginx modules path: "/root/tmp/nginx-1.15.3/nginx-prefix/modules"
    8. nginx configuration prefix: "/root/tmp/nginx-1.15.3/nginx-prefix/conf"
    9. nginx configuration file: "/root/tmp/nginx-1.15.3/nginx-prefix/conf/nginx.conf"
    10. nginx pid file: "/root/tmp/nginx-1.15.3/nginx-prefix/logs/nginx.pid"
    11. nginx error log file: "/root/tmp/nginx-1.15.3/nginx-prefix/logs/error.log"
    12. nginx http access log file: "/root/tmp/nginx-1.15.3/nginx-prefix/logs/access.log"
    13. nginx http client request body temporary files: "client_body_temp"
    14. nginx http proxy temporary files: "proxy_temp"
    1. cd /opt/k8s/work/nginx-1.15.3
    2. make && make install
    1. cd /opt/k8s/work/nginx-1.15.3

    输出:

    查看 nginx 动态链接的库:

    1. $ ldd ./nginx-prefix/sbin/nginx

    输出:

    1. linux-vdso.so.1 => (0x00007ffc945e7000)
    2. libdl.so.2 => /lib64/libdl.so.2 (0x00007f4385072000)
    3. libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4384e56000)
    4. libc.so.6 => /lib64/libc.so.6 (0x00007f4384a89000)
    5. /lib64/ld-linux-x86-64.so.2 (0x00007f4385276000)
    • 由于只开启了 4 层透明转发功能,所以除了依赖 libc 等操作系统核心 lib 库外,没有对其它 lib 的依赖(如 libz、libssl 等),这样可以方便部署到各版本操作系统中;

    安装和部署 nginx

    创建目录结构:

    1. source /opt/k8s/bin/environment.sh
    2. for node_ip in ${NODE_IPS[@]}
    3. do
    4. echo ">>> ${node_ip}"
    5. ssh root@${node_ip} "mkdir -p /opt/k8s/kube-nginx/{conf,logs,sbin}"
    6. done
    1. cd /opt/k8s/work
    2. source /opt/k8s/bin/environment.sh
    3. for node_ip in ${NODE_IPS[@]}
    4. do
    5. echo ">>> ${node_ip}"
    6. ssh root@${node_ip} "mkdir -p /opt/k8s/kube-nginx/{conf,logs,sbin}"
    7. scp /opt/k8s/work/nginx-1.15.3/nginx-prefix/sbin/nginx root@${node_ip}:/opt/k8s/kube-nginx/sbin/kube-nginx
    8. ssh root@${node_ip} "chmod a+x /opt/k8s/kube-nginx/sbin/*"
    9. done
    • 重命名二进制文件为 kube-nginx;

    配置 nginx,开启 4 层透明转发功能:

    • 需要根据集群 kube-apiserver 的实际情况,替换 backend 中 server 列表;

    分发配置文件:

    1. cd /opt/k8s/work
    2. source /opt/k8s/bin/environment.sh
    3. for node_ip in ${NODE_IPS[@]}
    4. do
    5. echo ">>> ${node_ip}"
    6. scp kube-nginx.conf root@${node_ip}:/opt/k8s/kube-nginx/conf/kube-nginx.conf
    7. done

    配置 kube-nginx systemd unit 文件:

    1. cd /opt/k8s/work
    2. [Unit]
    3. Description=kube-apiserver nginx proxy
    4. After=network.target
    5. After=network-online.target
    6. Wants=network-online.target
    7. [Service]
    8. Type=forking
    9. ExecStartPre=/opt/k8s/kube-nginx/sbin/kube-nginx -c /opt/k8s/kube-nginx/conf/kube-nginx.conf -p /opt/k8s/kube-nginx -t
    10. ExecStart=/opt/k8s/kube-nginx/sbin/kube-nginx -c /opt/k8s/kube-nginx/conf/kube-nginx.conf -p /opt/k8s/kube-nginx
    11. ExecReload=/opt/k8s/kube-nginx/sbin/kube-nginx -c /opt/k8s/kube-nginx/conf/kube-nginx.conf -p /opt/k8s/kube-nginx -s reload
    12. PrivateTmp=true
    13. Restart=always
    14. RestartSec=5
    15. StartLimitInterval=0
    16. LimitNOFILE=65536
    17. [Install]
    18. WantedBy=multi-user.target
    19. EOF

    分发 systemd unit 文件:

    1. cd /opt/k8s/work
    2. source /opt/k8s/bin/environment.sh
    3. for node_ip in ${NODE_IPS[@]}
    4. do
    5. echo ">>> ${node_ip}"
    6. scp kube-nginx.service root@${node_ip}:/etc/systemd/system/
    7. done
    1. cd /opt/k8s/work
    2. source /opt/k8s/bin/environment.sh
    3. for node_ip in ${NODE_IPS[@]}
    4. do
    5. echo ">>> ${node_ip}"
    6. ssh root@${node_ip} "systemctl daemon-reload && systemctl enable kube-nginx && systemctl restart kube-nginx"

    检查 kube-nginx 服务运行状态

    确保状态为 active (running),否则查看日志,确认原因: