1. 为什么选择Ubuntu部署Kubernetes 1.23
在容器编排领域,Kubernetes已经成为事实标准。而Ubuntu作为最流行的Linux发行版之一,其稳定的LTS版本和良好的云原生支持使其成为部署Kubernetes的理想选择。1.23版本是Kubernetes的一个重要里程碑,它引入了多项关键改进,包括:
- 更稳定的容器存储接口(CSI)驱动支持
- 增强的Pod安全策略
- 改进的IPv6支持
- 更高效的资源管理
选择这个特定版本组合,既能获得成熟稳定的功能,又能避免最新版本可能存在的兼容性问题。我在生产环境中多次使用这个配置,其稳定性和性能表现都相当出色。
2. 环境准备与系统配置
2.1 硬件需求建议
虽然Kubernetes可以在单节点上运行,但为了获得最佳体验,建议至少准备:
- 控制平面节点:2核CPU/4GB内存/20GB存储
- 工作节点:根据工作负载调整,建议2核CPU/4GB内存起
- 所有节点间网络延迟<1ms
注意:生产环境请根据实际负载增加资源,特别是内存和存储。我曾遇到过因内存不足导致kubelet频繁崩溃的情况。
2.2 Ubuntu系统准备
推荐使用Ubuntu 20.04 LTS,它提供了5年的长期支持:
bash复制# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装基础工具
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 禁用swap(Kubernetes要求)
sudo swapoff -a
sudo sed -i '/swap/s/^/#/' /etc/fstab
2.3 内核参数调优
对于生产环境,建议调整以下内核参数:
bash复制cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
3. 容器运行时安装与配置
3.1 安装Docker
虽然Kubernetes已经支持containerd作为默认运行时,但Docker仍然是最常用的选择:
bash复制# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加Docker仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 配置Docker使用systemd作为cgroup驱动
sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
# 重启Docker
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
3.2 验证容器运行时
运行以下命令验证Docker安装:
bash复制sudo docker run hello-world
如果看到"Hello from Docker!"消息,说明安装成功。
4. Kubernetes组件安装
4.1 添加Kubernetes仓库
bash复制# 添加Kubernetes官方GPG密钥
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# 添加Kubernetes仓库
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 安装指定版本(1.23.x)的组件
sudo apt update
sudo apt install -y kubelet=1.23.* kubeadm=1.23.* kubectl=1.23.*
sudo apt-mark hold kubelet kubeadm kubectl
提示:使用apt-mark hold防止意外升级,Kubernetes版本升级需要谨慎操作。
4.2 初始化控制平面
选择一个节点作为控制平面节点,执行:
bash复制sudo kubeadm init --kubernetes-version=1.23.17 --pod-network-cidr=10.244.0.0/16
初始化完成后,会输出加入集群的命令,类似:
bash复制kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
保存这个命令,后续添加节点时需要。
4.3 配置kubectl
bash复制mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
验证集群状态:
bash复制kubectl get nodes
此时节点状态应为NotReady,因为尚未安装网络插件。
5. 网络插件安装
5.1 安装Flannel网络插件
Flannel是最简单的选择之一:
bash复制kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
等待几分钟后,再次检查节点状态:
bash复制kubectl get nodes
现在应该显示Ready状态。
5.2 网络插件选择考量
虽然Flannel简单易用,但在生产环境中可能需要考虑其他选项:
| 插件名称 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Flannel | 简单、稳定 | 功能有限 | 小型集群、测试环境 |
| Calico | 支持网络策略、高性能 | 配置复杂 | 生产环境、需要安全隔离 |
| Cilium | 基于eBPF、高性能 | 资源消耗大 | 高性能需求、云原生环境 |
我曾在一个项目中从Flannel迁移到Calico,因为需要实现Pod间的网络隔离策略,迁移过程需要谨慎规划。
6. 添加工作节点
在每个工作节点上重复以下步骤:
- 完成2.1-2.3的系统准备
- 完成3.1-3.2的Docker安装
- 完成4.1的Kubernetes组件安装
- 执行kubeadm join命令(之前保存的)
添加完成后,在主节点上运行:
bash复制kubectl get nodes
应该能看到所有节点状态为Ready。
7. 集群验证与测试
7.1 部署测试应用
bash复制kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
获取服务信息:
bash复制kubectl get svc nginx
访问测试(假设节点IP为192.168.1.100,端口为32080):
bash复制curl http://192.168.1.100:32080
应该能看到Nginx欢迎页面。
7.2 集群健康检查
bash复制kubectl get componentstatus
kubectl get pods -n kube-system
所有核心组件应显示为Healthy,所有系统Pod应显示为Running。
8. 生产环境建议
8.1 高可用配置
对于生产环境,建议配置高可用控制平面:
- 部署至少3个控制平面节点
- 使用外部etcd集群或堆叠式etcd
- 配置负载均衡器指向控制平面节点
初始化命令示例:
bash复制sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" \
--upload-certs --kubernetes-version=1.23.17 --pod-network-cidr=10.244.0.0/16
8.2 安全加固
- 启用RBAC(默认已启用)
- 配置Pod安全策略或Pod安全标准
- 限制kubelet权限
- 定期轮换证书
8.3 监控与日志
建议部署:
- Prometheus + Grafana用于监控
- EFK(Elasticsearch+Fluentd+Kibana)用于日志收集
- Kubernetes Dashboard或Lens用于可视化
9. 常见问题排查
9.1 kubeadm init卡住
常见原因:
- 镜像拉取失败:手动拉取镜像
kubeadm config images pull --kubernetes-version=1.23.17 - 网络问题:检查节点间网络连通性
- 资源不足:检查内存和CPU使用情况
9.2 Pod处于Pending状态
检查步骤:
kubectl describe pod <pod-name>查看事件kubectl get events查看集群事件- 检查资源配额和节点选择器
9.3 网络连接问题
排查方法:
- 检查Flannel Pod是否正常运行
- 检查节点路由表
ip route - 测试Pod间连通性
kubectl run -it --rm --image=alpine test -- sh
10. 升级与维护
10.1 升级Kubernetes版本
-
先升级kubeadm:
bash复制sudo apt update sudo apt install -y kubeadm=1.24.* sudo kubeadm upgrade plan sudo kubeadm upgrade apply v1.24.x -
升级节点:
bash复制sudo apt update sudo apt install -y kubelet=1.24.* kubectl=1.24.* sudo systemctl restart kubelet
重要:升级前务必备份etcd数据,并在测试环境验证升级过程。
10.2 日常维护命令
- 查看集群状态:
kubectl get all -A - 查看节点资源使用:
kubectl top nodes - 查看Pod资源使用:
kubectl top pods - 排空节点(维护前):
kubectl drain <node-name> --ignore-daemonsets
11. 性能优化技巧
11.1 kubelet配置优化
编辑/var/lib/kubelet/config.yaml:
yaml复制apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
memory.available: "500Mi"
nodefs.available: "10%"
nodefs.inodesFree: "5%"
imagefs.available: "15%"
kubeReserved:
cpu: "500m"
memory: "500Mi"
systemReserved:
cpu: "500m"
memory: "500Mi"
重启kubelet生效:
bash复制sudo systemctl restart kubelet
11.2 调度优化
- 使用节点亲和性和Pod亲和性
- 配置资源请求和限制
- 使用Pod拓扑分布约束
示例Pod配置:
yaml复制apiVersion: v1
kind: Pod
metadata:
name: optimized-pod
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
12. 备份与恢复
12.1 etcd备份
bash复制# 获取etcd Pod名称
ETCD_POD=$(kubectl get pods -n kube-system | grep etcd | awk '{print $1}')
# 执行备份
kubectl exec -n kube-system $ETCD_POD -- sh -c "ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /var/lib/etcd/snapshot.db"
# 将备份复制到本地
kubectl cp kube-system/$ETCD_POD:/var/lib/etcd/snapshot.db ./etcd-snapshot.db
12.2 恢复etcd
- 停止所有控制平面组件
- 恢复etcd数据
- 重启控制平面组件
具体步骤因环境而异,建议参考官方文档并先在测试环境演练。
13. 扩展功能
13.1 安装Ingress控制器
以Nginx Ingress为例:
bash复制kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml
13.2 配置持久化存储
- 安装CSI驱动(如本地存储、NFS、云存储等)
- 创建StorageClass
- 创建PersistentVolumeClaim
示例本地存储配置:
yaml复制apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
14. 安全最佳实践
14.1 证书管理
-
检查证书过期时间:
bash复制
kubeadm certs check-expiration -
更新证书:
bash复制
kubeadm certs renew all
14.2 网络策略
示例网络策略(限制default命名空间Pod只能访问特定端口):
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
egress:
- ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
15. 资源清理
15.1 重置节点
bash复制sudo kubeadm reset
sudo apt purge -y kubelet kubeadm kubectl
sudo rm -rf /etc/kubernetes /var/lib/kubelet /var/lib/etcd
15.2 完全卸载
bash复制sudo apt autoremove -y --purge docker-ce docker-ce-cli containerd.io
sudo rm -rf /var/lib/docker /etc/docker
sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /usr/share/keyrings/docker-archive-keyring.gpg
16. 实际部署经验分享
在多次部署Kubernetes 1.23集群的过程中,我积累了一些宝贵经验:
-
镜像拉取问题:国内环境可能会遇到gcr.io镜像拉取失败的问题。解决方案包括:
- 使用镜像仓库代理
- 预先拉取镜像并导入
- 配置Docker镜像加速器
-
证书问题:kubeadm init有时会因为证书问题失败。可以尝试:
bash复制sudo rm -rf /etc/kubernetes/pki sudo kubeadm init -
网络插件冲突:如果之前部署过其他网络插件,务必彻底清理:
bash复制kubectl delete -f [旧网络插件配置] ip link delete cni0 ip link delete flannel.1 -
资源监控:建议在部署完成后立即设置监控,我曾遇到过因未及时发现内存泄漏导致节点崩溃的情况。
-
文档记录:详细记录部署过程中的每个步骤和参数选择,这在后续排查问题和扩展集群时非常有用。
对于生产环境,我强烈建议先在测试环境完整演练整个部署过程,包括故障模拟和恢复演练。Kubernetes虽然功能强大,但复杂度也高,充分的准备可以避免很多问题。