K8S高可用集群-二进制部署 + nginx-proxy静态Pod版本
Kubernetes高可用集群部署完整指南
原来部署都用用集群外的haproxy来代理(OCP)养成的习惯,最近看了一个文档见的是 集群内 静态 nginx-proxy pod版本 挺有意思 记录一下
简单对比一下先 目前主流的方案:
kubeadm(kubesphere ) 开箱急用初学者
轻量k3s 定位好像是边缘设备
ranche研发用的多 适合研发二开自己玩
ocp 最笨插件也多 其实红帽做了很多工作 不多评价
比较适合研究学习的也就二进制和晕厂商了 一个细 一个实用
静态Pod nginx-proxy方案在成本、简单性和自包含方面具有明显优势,特别适合中小型自建环境。虽然功能相对基础,但对于大多数Kubernetes集群来说已经足够,是性价比高。
对于追求企业级和有专业运维团队的,外部HAProxy方案仍然是黄金标准。
云厂商方案我局的最合适,则适合专注于业务开发的团队,维护简单。
一 架构和部署
本方案采用二进制部署 + nginx-proxy静态Pod的高可用架构,无需外部负载均衡器。
集群节点规划
控制平面节点 (3节点高可用):
- Master1: 10.10.10.1
- Master2: 10.10.10.2
- Master3: 10.10.10.3
工作节点 (3节点):
- Node1: 10.10.100.1
- Node2: 10.10.100.2
- Node3: 10.10.100.3
网络架构
工作节点(kubelet) → 本地nginx-proxy(127.0.0.1:6443) → 负载均衡 → 后端API Server集群(10.10.10.1:6443, 10.10.10.2:6443, 10.10.10.3:6443)
1. 证书生成与配置
1.1 创建证书目录
在所有节点创建证书目录:
mkdir -p /etc/kubernetes/ssl
1.2 生成CA证书(在Master1执行)
# 生成CA私钥
openssl genrsa -out /etc/kubernetes/ssl/ca-key.pem 2048
# 生成CA证书(有效期5年)
openssl req -x509 -new -nodes -key /etc/kubernetes/ssl/ca-key.pem \
-days 1825 -out /etc/kubernetes/ssl/ca.pem \
-subj "/CN=kubernetes-ca"
1.3 生成API Server证书(包含所有SAN)
# 生成API Server私钥
openssl genrsa -out /etc/kubernetes/ssl/kubernetes-key.pem 2048
# 创建证书签名请求(内联配置SAN)
openssl req -new -key /etc/kubernetes/ssl/kubernetes-key.pem \
-out /etc/kubernetes/ssl/kubernetes.csr \
-subj "/CN=kube-apiserver" \
-config <(
cat <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.svc.cluster.local
IP.1 = 10.233.0.1
IP.2 = 10.10.10.1
IP.3 = 10.10.10.2
IP.4 = 10.10.10.3
IP.5 = 127.0.0.1
EOF
)
# 使用CA签名生成证书
openssl x509 -req -in /etc/kubernetes/ssl/kubernetes.csr \
-CA /etc/kubernetes/ssl/ca.pem -CAkey /etc/kubernetes/ssl/ca-key.pem \
-CAcreateserial -out /etc/kubernetes/ssl/kubernetes.pem \
-days 365 -extensions v3_req -extfile <(
cat <<EOF
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.svc.cluster.local
IP.1 = 10.233.0.1
IP.2 = 10.10.10.1
IP.3 = 10.10.10.2
IP.4 = 10.10.10.3
IP.5 = 127.0.0.1
EOF
)
1.4 生成Service Account证书
openssl genrsa -out /etc/kubernetes/ssl/service-account-key.pem 2048
openssl req -new -key /etc/kubernetes/ssl/service-account-key.pem \
-out /etc/kubernetes/ssl/service-account.csr -subj "/CN=service-account"
openssl x509 -req -in /etc/kubernetes/ssl/service-account.csr \
-CA /etc/kubernetes/ssl/ca.pem -CAkey /etc/kubernetes/ssl/ca-key.pem \
-CAcreateserial -out /etc/kubernetes/ssl/service-account.pem -days 365
1.5 生成代理客户端证书
openssl genrsa -out /etc/kubernetes/ssl/proxy-client-key.pem 2048
openssl req -new -key /etc/kubernetes/ssl/proxy-client-key.pem \
-out /etc/kubernetes/ssl/proxy-client.csr -subj "/CN=aggregator"
openssl x509 -req -in /etc/kubernetes/ssl/proxy-client.csr \
-CA /etc/kubernetes/ssl/ca.pem -CAkey /etc/kubernetes/ssl/ca-key.pem \
-CAcreateserial -out /etc/kubernetes/ssl/proxy-client.pem -days 365
1.6 分发证书到其他Master节点
scp -r /etc/kubernetes/ssl/ root@10.10.10.2:/etc/kubernetes/
scp -r /etc/kubernetes/ssl/ root@10.10.10.3:/etc/kubernetes/
1.7 为工作节点生成专用证书
为每个工作节点生成节点证书(以Node1为例):
openssl genrsa -out /etc/kubernetes/ssl/node1-key.pem 2048
openssl req -new -key /etc/kubernetes/ssl/node1-key.pem \
-out /etc/kubernetes/ssl/node1.csr \
-subj "/CN=system:node:node1/O=system:nodes"
openssl x509 -req -in /etc/kubernetes/ssl/node1.csr \
-CA /etc/kubernetes/ssl/ca.pem -CAkey /etc/kubernetes/ssl/ca-key.pem \
-CAcreateserial -out /etc/kubernetes/ssl/node1.pem -days 365
2. 控制平面部署
2.1 安装二进制文件
在所有控制平面节点安装以下二进制文件到 /usr/local/bin/:
- kube-apiserver
- kube-controller-manager
- kube-scheduler
- etcd
- kubelet
- kubectl
2.2 配置etcd服务
创建 /etc/systemd/system/etcd.service:
[Unit]
Description=Etcd Server
After=network.target
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \
--name=master1 \
--data-dir=/var/lib/etcd \
--listen-client-urls=https://10.10.10.1:2379,https://127.0.0.1:2379 \
--advertise-client-urls=https://10.10.10.1:2379 \
--listen-peer-urls=https://10.10.10.1:2380 \
--initial-advertise-peer-urls=https://10.10.10.1:2380 \
--initial-cluster=master1=https://10.10.10.1:2380,master2=https://10.10.10.2:2380,master3=https://10.10.10.3:2380 \
--client-cert-auth=true \
--trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
--peer-client-cert-auth=true \
--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--peer-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--peer-key-file=/etc/kubernetes/ssl/kubernetes-key.pem
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
2.3 配置kube-apiserver服务
创建 /etc/systemd/system/kube-apiserver.service:
[Unit]
Description=Kubernetes API Server
After=etcd.service
[Service]
ExecStart=/usr/local/bin/kube-apiserver \
--advertise-address=10.10.10.1 \
--allow-privileged=true \
--apiserver-count=3 \
--authorization-mode=Node,RBAC \
--bind-address=0.0.0.0 \
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--etcd-cafile=/etc/kubernetes/ssl/ca.pem \
--etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem \
--etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem \
--etcd-servers=https://10.10.10.1:2379,https://10.10.10.2:2379,https://10.10.10.3:2379 \
--kubelet-client-certificate=/etc/kubernetes/ssl/kubernetes.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kubernetes-key.pem \
--secure-port=6443 \
--service-account-key-file=/etc/kubernetes/ssl/service-account.pem \
--service-cluster-ip-range=10.233.0.0/18 \
--tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
2.4 启动控制平面服务
systemctl daemon-reload
systemctl enable etcd kube-apiserver kube-controller-manager kube-scheduler
systemctl start etcd kube-apiserver kube-controller-manager kube-scheduler
3. 工作节点部署
3.1 配置nginx代理
在所有工作节点创建 /etc/nginx/nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
stream {
upstream kubernetes {
server 10.10.10.1:6443 max_fails=3 fail_timeout=30s;
server 10.10.10.2:6443 max_fails=3 fail_timeout=30s;
server 10.10.10.3:6443 max_fails=3 fail_timeout=30s;
}
server {
listen 127.0.0.1:6443;
proxy_pass kubernetes;
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
server {
listen 127.0.0.1:8081;
return 200 "healthy\n";
}
}
3.2 配置nginx-proxy静态Pod
创建 /etc/kubernetes/manifests/nginx-proxy.yaml:
apiVersion: v1
kind: Pod
metadata:
name: nginx-proxy
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: Reconcile
k8s-app: kube-nginx
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-node-critical
containers:
- name: nginx-proxy
image: docker.io/library/nginx:1.19
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 25m
memory: 32M
securityContext:
privileged: true
livenessProbe:
httpGet:
path: /healthz
port: 8081
readinessProbe:
httpGet:
path: /healthz
port: 8081
volumeMounts:
- mountPath: /etc/nginx
name: etc-nginx
readOnly: true
volumes:
- name: etc-nginx
hostPath:
path: /etc/nginx
3.3 配置kubelet
创建 /etc/kubernetes/kubelet-config.yaml:
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
staticPodPath: /etc/kubernetes/manifests
authentication:
x509:
clientCAFile: "/etc/kubernetes/ssl/ca.pem"
authorization:
mode: Webhook
clusterDNS:
- "169.254.25.10"
address: 10.10.100.1
tlsCertFile: "/etc/kubernetes/ssl/node1.pem"
tlsPrivateKeyFile: "/etc/kubernetes/ssl/node1-key.pem"
3.4 启动工作节点
systemctl enable kubelet && systemctl start kubelet
4. 验证集群状态
4.1 检查节点状态
kubectl get nodes -o wide
4.2 检查组件状态
kubectl get componentstatuses
4.3 验证网络连通性
curl -k https://127.0.0.1:6443/version
5. 所需软件版本
容器运行时
- containerd: 1.4.3+
- crictl: 1.18.0+
Kubernetes组件
- Kubernetes: v1.20.2
- etcd: 3.4.13+
核心镜像 简介
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
docker.io/library/nginx:1.19
registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/pause:3.2
docker.io/calico/cni:v3.20.6
docker.io/calico/node:v3.20.6
6. 运维常用命令
6.1 证书管理
# 查看证书有效期
openssl x509 -in /etc/kubernetes/ssl/ca.pem -noout -dates
# 检查证书SAN信息
openssl x509 -in /etc/kubernetes/ssl/kubernetes.pem -text -noout | grep -A10 "Subject Alternative Name"
# 批量检查证书
for cert in /etc/kubernetes/ssl/*.pem; do
echo "=== $(basename $cert) ==="
openssl x509 -in $cert -noout -subject -dates 2>/dev/null || echo "私钥文件"
done
6.2 集群状态检查
# 节点和Pod状态
kubectl get nodes -o wide
kubectl get pods -A -o wide
# 服务状态
kubectl get svc -A
kubectl get componentstatuses
6.3 服务管理
# 控制平面服务
systemctl status kube-apiserver
systemctl status kube-controller-manager
systemctl status kube-scheduler
systemctl status etcd
# 工作节点服务
systemctl status kubelet
systemctl status containerd
6.4 网络诊断
# 检查nginx代理
kubectl get pods -n kube-system | grep nginx-proxy
kubectl logs -n kube-system nginx-proxy-xxx
# 端口监听检查
netstat -lntp | grep 6443
6.5 集群备份
# 备份证书和配置
cp -r /etc/kubernetes/ssl /backup/kubernetes-ssl-$(date +%Y%m%d)
cp -r /etc/kubernetes/manifests /backup/manifests-$(date +%Y%m%d)
# 备份资源定义
kubectl get all --all-namespaces -o yaml > /backup/k8s-resources-$(date +%Y%m%d).yaml
总结
本方案通过静态Pod nginx-proxy实现了高可用负载均衡,具有以下优势:
- 无外部依赖:无需额外的负载均衡器硬件/软件
- 配置一致:所有工作节点使用相同的连接地址
- 高可用:内置故障检测和自动故障转移
- 易于维护:静态Pod由kubelet自动管理
这种架构特别适合自建环境,在保证高可用的同时简化了网络配置和外部依赖。
二 镜像架构概述
有些同学可能第一次接触部署,加上这部分吧
在Kubernetes高可用集群中,镜像分为多个层次,每个层次承担不同的功能。以下是完整的镜像分类和使用说明。
1. 核心基础设施镜像
1.1 基础运行时镜像
# Pause容器 - 所有Pod的基础基础设施容器
registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/pause:3.2
# 或
k8s.gcr.io/pause:3.2
# 功能:为Pod提供共享的Linux命名空间,作为Pod内所有容器的"父容器"
# 用途:每个Pod都会自动创建pause容器
1.2 nginx代理镜像
# nginx代理 - 用于API Server负载均衡
docker.io/library/nginx:1.19
# 功能:作为静态Pod运行,代理所有到API Server的请求
# 配置:通过HostPath挂载nginx配置文件
# 网络模式:使用主机网络,监听127.0.0.1:6443
2. 网络插件镜像 (Calico)
2.1 Calico核心组件
# Calico CNI插件 - 负责Pod网络配置
docker.io/calico/cni:v3.20.6
# 功能:安装CNI二进制文件,配置Pod网络接口
# 运行方式:DaemonSet,每个节点运行
# Calico节点组件 - 核心网络服务
docker.io/calico/node:v3.20.6
# 功能:BGP路由发布、Felix策略执行、网络状态报告
# 包含:bird, felix, confd等组件
# 运行方式:DaemonSet,每个节点运行
# FlexVolume驱动 - 用于网络策略
docker.io/calico/pod2daemon-flexvol:v3.20.6
# 功能:为Calico提供FlexVolume支持
# 运行方式:DaemonSet,每个节点运行
2.2 Calico控制器
# Calico Kube控制器 - 集群级别网络策略
docker.io/calico/kube-controllers:v3.20.6
# 功能:执行网络策略、服务IP广告、节点监控
# 运行方式:Deployment,通常单副本运行
3. DNS服务镜像
3.1 CoreDNS
# CoreDNS - Kubernetes集群DNS服务
k8s.gcr.io/coredns:1.7.0
# 或
registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/coredns:1.7.0
# 功能:提供集群内服务发现和DNS解析
# 配置:通过ConfigMap管理
# 运行方式:Deployment,通常2副本运行
3.2 NodeLocal DNS Cache
# 节点本地DNS缓存 - 提升DNS解析性能
registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/dns_k8s-dns-node-cache:1.16.0
# 功能:在每个节点运行DNS缓存,减少CoreDNS负载
# 运行方式:DaemonSet,每个节点运行
# 监听:节点上的169.254.25.10:53
4. Ingress控制器镜像
4.1 NGINX Ingress Controller
# NGINX Ingress控制器
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0
# 功能:提供HTTP/HTTPS入口流量管理
# 特性:支持负载均衡、SSL终止、基于路径路由
# 运行方式:Deployment,可配置多副本
# 默认后端服务
k8s.gcr.io/defaultbackend-amd64:1.5
# 功能:处理所有未配置路由的请求
# 用途:Ingress控制器的默认回退服务
5. 监控与日志镜像
5.1 指标收集
# metrics-server - 资源指标收集
k8s.gcr.io/metrics-server/metrics-server:v0.5.0
# 功能:收集Node和Pod的CPU、内存使用指标
# 用途:支持kubectl top命令和HPA
6. 镜像拉取与准备
6.1 镜像预加载脚本
#!/bin/bash
# 定义镜像列表
IMAGES=(
"registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/pause:3.2"
"docker.io/library/nginx:1.19"
"docker.io/calico/cni:v3.20.6"
"docker.io/calico/node:v3.20.6"
"docker.io/calico/kube-controllers:v3.20.6"
"docker.io/calico/pod2daemon-flexvol:v3.20.6"
"registry.cn-hangzhou.aliyuncs.com/kubernetes-kubespray/dns_k8s-dns-node-cache:1.16.0"
"quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.19.0"
)
# 拉取所有镜像
for image in "${IMAGES[@]}"; do
echo "Pulling $image"
crictl pull $image
done
# 验证镜像拉取
crictl images
6.2 镜像导出与导入(离线环境)
# 导出镜像
crictl images --digests > images-list.txt
for image in $(crictl images -q); do
crictl save $image > $(echo $image | tr '/' '_' | tr ':' '_').tar
done
# 导入镜像(在目标机器)
for tar_file in *.tar; do
crictl load < $tar_file
done
7. 镜像配置说明
7.1 镜像仓库配置
如果使用私有仓库,需要配置containerd:
# 编辑containerd配置
vim /etc/containerd/config.toml
# 添加镜像仓库mirror
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
endpoint = ["https://registry.cn-hangzhou.aliyuncs.com"]
7.2 镜像拉取策略
在Kubernetes资源配置中指定拉取策略:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: calico-node
spec:
template:
spec:
containers:
- name: calico-node
image: docker.io/calico/node:v3.20.6
imagePullPolicy: IfNotPresent # 可选:Always, IfNotPresent, Never
8. 镜像版本对应关系
8.1 Kubernetes版本与镜像版本
| Kubernetes版本 | Calico版本 | CoreDNS版本 | nginx-ingress版本 |
|---|---|---|---|
| v1.20.2 | v3.20.6 | 1.7.0 | 0.19.0 |
| v1.21.x | v3.21.x | 1.8.3 | 1.0.x |
| v1.22.x | v3.22.x | 1.8.6 | 1.1.x |
8.2 镜像大小参考
# 常见镜像大小
pause:3.2 # 300KB
nginx:1.19 # 50MB
calico/cni:v3.20.6 # 45MB
calico/node:v3.20.6 # 60MB
coredns:1.7.0 # 40MB
nginx-ingress-controller:0.19.0 # 160MB
9. 镜像健康检查
9.1 镜像状态验证
# 检查所有运行的Pod使用的镜像
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
# 检查镜像拉取错误
kubectl get pods -A -o wide | grep -E "ImagePullBackOff|ErrImagePull"
# 检查节点上的镜像
crictl images
9.2 镜像更新策略
# 安全更新镜像步骤
# 1. 拉取新版本镜像
crictl pull docker.io/calico/node:v3.20.7
# 2. 更新DaemonSet/Deployment的镜像版本
kubectl set image daemonset/calico-node calico-node=docker.io/calico/node:v3.20.7 -n kube-system
# 3. 滚动更新验证
kubectl rollout status daemonset/calico-node -n kube-system
10. 镜像安全最佳实践
10.1 安全扫描
# 使用trivy扫描镜像漏洞
trivy image docker.io/calico/node:v3.20.6
# 检查镜像签名
cosign verify docker.io/calico/node:v3.20.6
10.2 镜像源管理
# 只信任官方镜像源
# Calico: docker.io/calico/*
# NGINX: docker.io/library/nginx
# Kubernetes: k8s.gcr.io/*
# 避免使用不明来源的镜像
这个完整的镜像说明涵盖了集群所有核心组件的镜像使用,包括功能说明、配置方法和运维实践。
更多推荐


所有评论(0)