在国产化信息技术应用创新(信创)背景下,构建高可用的Kubernetes集群已成为企业级云原生基础设施的核心需求。作为一名在金融行业实施过多个信创云原生项目的架构师,我将分享基于国产化环境的Kubernetes多主高可用架构实战经验。
信创环境与传统x86架构的主要差异体现在:
实际踩坑经验:在鲲鹏920芯片上首次部署时,因未使用ARM架构的Docker镜像导致Pod启动失败。后改用华为容器引擎(基于ARM优化)才解决问题。
传统单Master架构在信创生产环境中存在明显短板:
通过3节点多主架构可实现:
我们在政务云项目中对比测试了两种架构:
| 指标 | 堆叠式etcd (Stacked) | 外部etcd (External) |
|---|---|---|
| 部署复杂度 | ★★☆ | ★★★★ |
| 资源占用 | 较低(共用服务器) | 较高(独立服务器) |
| 故障隔离性 | 差(耦合存储与控制) | 优(完全隔离) |
| 性能(100节点集群) | API延迟15-20ms | API延迟8-12ms |
| 信创适配性 | 银河麒麟V10已验证 | 统信UOS/欧拉已验证 |
结论:生产环境强烈推荐外部etcd拓扑,虽然部署复杂但稳定性更好。我们在某银行项目中,外部etcd架构在单AZ故障时仍保持服务可用。
配置要点:controller-manager和scheduler的
--leader-elect=true参数必须开启(默认值)
etcd集群:
负载均衡方案:
mermaid复制graph TD
A[客户端] --> B{HAProxy+Keepalived}
B --> C[Master1:6443]
B --> D[Master2:6443]
B --> E[Master3:6443]
实测发现,采用独立LB节点比部署在Master上性能提升30%
某政务云项目实际配置参考:
| 节点类型 | 数量 | CPU | 内存 | 存储 | 网络 |
|---|---|---|---|---|---|
| Master | 3 | 8核 | 32G | 100G ESSD | 10Gbps |
| etcd | 3 | 4核 | 16G | 200G NVMe | 10Gbps |
| Worker | 2+ | 16核 | 64G | 500G ESSD | 10Gbps |
注:etcd节点务必使用低延迟存储(NVMe),我们曾因使用SATA SSD导致集群频繁超时
bash复制# 关闭防火墙(银河麒麟)
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 关闭SELinux
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 关闭Swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
证书生成关键步骤(使用cfssl):
bash复制# 生成CA证书
cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
{
"CN": "etcd-ca",
"key": { "algo": "rsa", "size": 2048 },
"names": [
{"C": "CN", "L": "Beijing", "O": "etcd", "OU": "xinchuang"}
]
}
EOF
# 生成服务器证书
cat <<EOF | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server - | cfssljson -bare server
{
"CN": "etcd-server",
"hosts": [
"etcd1", "etcd2", "etcd3",
"192.168.1.30", "192.168.1.31", "192.168.1.32"
],
"key": { "algo": "rsa", "size": 2048 }
}
EOF
etcd服务配置示例(etcd1节点):
ini复制[Unit]
Description=Etcd Server
After=network.target
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \
--name=etcd1 \
--data-dir=/var/lib/etcd \
--listen-peer-urls=https://192.168.1.30:2380 \
--listen-client-urls=https://192.168.1.30:2379,https://127.0.0.1:2379 \
--advertise-client-urls=https://192.168.1.30:2379 \
--initial-advertise-peer-urls=https://192.168.1.30:2380 \
--initial-cluster=etcd1=https://192.168.1.30:2380,etcd2=https://192.168.1.31:2380,etcd3=https://192.168.1.32:2380 \
--initial-cluster-token=etcd-cluster \
--initial-cluster-state=new \
--client-cert-auth=true \
--trusted-ca-file=/etc/etcd/ca.pem \
--cert-file=/etc/etcd/server.pem \
--key-file=/etc/etcd/server.key \
--peer-client-cert-auth=true \
--peer-trusted-ca-file=/etc/etcd/ca.pem \
--peer-cert-file=/etc/etcd/peer.pem \
--peer-key-file=/etc/etcd/peer.key
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
关键初始化命令:
bash复制sudo kubeadm init \
--control-plane-endpoint "192.168.1.100:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version v1.26.10 \
--apiserver-cert-extra-sans=k8s-vip.example.com \
--etcd-servers=https://192.168.1.30:2379,https://192.168.1.31:2379,https://192.168.1.32:2379 \
--etcd-cafile=/etc/etcd/ca.pem \
--etcd-certfile=/etc/etcd/server.pem \
--etcd-keyfile=/etc/etcd/server.key
特别注意:
--image-repository必须指定国内镜像源,否则ARM架构镜像拉取会失败
推荐监控指标:
Granfa看板配置示例:
bash复制# 创建数据源
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasources
namespace: monitoring
data:
prometheus.yaml: |
{
"apiVersion": 1,
"datasources": [
{
"access": "proxy",
"editable": true,
"name": "Prometheus",
"orgId": 1,
"type": "prometheus",
"url": "http://prometheus-server.monitoring.svc.cluster.local",
"version": 1
}
]
}
EOF
bash复制#!/bin/bash
DATE=$(date +%Y%m%d-%H%M%S)
ETCD_ENDPOINTS="https://192.168.1.30:2379,https://192.168.1.31:2379,https://192.168.1.32:2379"
BACKUP_DIR="/data/etcd-backup"
ETCDCTL_API=3 etcdctl \
--endpoints=$ETCD_ENDPOINTS \
--cacert=/etc/etcd/ca.pem \
--cert=/etc/etcd/server.pem \
--key=/etc/etcd/server.key \
snapshot save $BACKUP_DIR/etcd-snapshot-$DATE.db
# 上传到OSS(华为云OBS)
ossutil cp $BACKUP_DIR/etcd-snapshot-$DATE.db oss://mybucket/etcd-backup/ --config-file=/etc/ossutil.conf
# 保留最近7天备份
find $BACKUP_DIR -name "*.db" -mtime +7 -delete
bash复制ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--name etcd-new1 \
--initial-cluster etcd-new1=https://192.168.1.40:2380,etcd-new2=https://192.168.1.41:2380 \
--initial-cluster-token etcd-recovery \
--initial-advertise-peer-urls https://192.168.1.40:2380
yaml复制# /etc/etcd/etcd.conf
# 提高存储性能
auto-compaction-retention: "1h"
max-request-bytes: 33554432 # 32MB
quota-backend-bytes: 8589934592 # 8GB
# 网络优化
heartbeat-interval: 500
election-timeout: 5000
yaml复制# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --max-requests-inflight=3000
- --max-mutating-requests-inflight=1000
- --watch-cache-sizes=1000
- --event-ttl=168h
| 故障现象 | 可能原因 | 解决方案 |
|---|---|---|
| etcd集群失去仲裁 | 节点间网络中断 | 检查防火墙规则,确保2379/2380端口互通 |
| API Server间歇性不可用 | 负载均衡器健康检查配置错误 | 验证HAProxy的check间隔(应≤2s) |
| Worker节点无法加入集群 | 证书过期或token失效 | 生成新token:kubeadm token create --print-join-command |
| Pod网络不通 | Calico配置与pod-cidr不匹配 | 确认calico.yaml中的CALICO_IPV4POOL_CIDR与kubeadm初始化参数一致 |
| 控制平面组件频繁重启 | 资源不足(OOM) | 增加Master节点资源或设置资源限制 |
bash复制# 检查etcd集群健康
ETCDCTL_API=3 etcdctl --endpoints=$ENDPOINTS --cacert=$CA --cert=$CERT --key=$KEY endpoint health
# 查看API Server请求指标
kubectl get --raw /metrics | grep apiserver_request_total
# 诊断网络问题
kubectl run net-test --image=nicolaka/netshoot -it --rm -- /bin/bash
# 在容器内执行:
ping <target_ip>
curl -v http://<service>:<port>
traceroute <target_ip>
bash复制kubectl create role developer --verb=get,list --resource=pods,svc
kubectl create rolebinding dev-binding --role=developer --user=dev-user
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
yaml复制# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
在三个大型信创项目中实施多主Kubernetes集群后,我们得出以下关键经验:
最后建议:生产环境部署前,务必在测试环境进行完整的破坏性测试(随机杀死节点、网络分区等),验证高可用机制的有效性。我们在某次演练中发现Keepalived配置缺陷,及时修复避免了生产事故。