1. 项目概述
在当今云原生技术蓬勃发展的时代,Kubernetes已成为容器编排领域的事实标准。kubeadm作为官方推荐的集群部署工具,因其简洁高效而广受欢迎。但在实际生产环境中,我们常常面临内网隔离、安全合规等限制条件,无法直接从公网拉取镜像和依赖包。这时,离线部署方案就显得尤为重要。
本次我们将深入探讨如何使用kubeadm在内网环境中完整部署一个生产可用的Kubernetes集群,并对其进行全面测试验证。这个方案特别适用于金融、政务等对网络安全要求严格的行业场景,也适合需要在隔离环境中构建CI/CD流水线的研发团队。
2. 环境准备与离线资源打包
2.1 基础环境要求
在开始部署前,需要确保所有节点满足以下条件:
- 操作系统:CentOS 7.9/RHEL 7.9/Ubuntu 20.04 LTS等主流Linux发行版
- 硬件配置:控制节点至少2核CPU、4GB内存、50GB磁盘;工作节点根据负载需求调整
- 网络配置:所有节点间网络互通,关闭防火墙或放行必要端口(6443、2379-2380等)
- 主机名解析:/etc/hosts配置正确的IP-hostname映射
重要提示:所有节点需要保持时间同步,建议部署内网NTP服务。Kubernetes对时间同步非常敏感,时间偏差会导致证书验证失败等问题。
2.2 离线资源打包
在有外网连接的环境中,我们需要先准备离线安装包:
# 创建资源目录 mkdir -p /opt/k8s-offline/{images,rpms,binaries} cd /opt/k8s-offline # 下载kubeadm、kubelet、kubectl二进制 wget https://storage.googleapis.com/kubernetes-release/release/v1.26.1/bin/linux/amd64/{kubeadm,kubelet,kubectl} chmod +x kubeadm kubelet kubectl mv kubeadm kubelet kubectl binaries/ # 下载容器运行时(以containerd为例) wget https://github.com/containerd/containerd/releases/download/v1.6.8/containerd-1.6.8-linux-amd64.tar.gz tar -xzf containerd-1.6.8-linux-amd64.tar.gz -C binaries/ # 下载Kubernetes组件镜像 kubeadm config images list --kubernetes-version v1.26.1 | xargs -n1 docker pull docker save $(kubeadm config images list --kubernetes-version v1.26.1) -o images/k8s-images.tar # 下载系统依赖包(CentOS示例) yum install --downloadonly --downloaddir=rpms/ \ kubelet-1.26.1 kubeadm-1.26.1 kubectl-1.26.1 \ socat conntrack-tools ebtables ipset将/opt/k8s-offline目录打包后传输到内网环境:
tar -czf k8s-offline-v1.26.1.tar.gz -C /opt k8s-offline3. 节点初始化与组件安装
3.1 基础环境配置
在所有节点执行以下初始化操作:
# 关闭Swap swapoff -a sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 关闭SELinux setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # 配置内核参数 cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system # 加载内核模块 modprobe br_netfilter echo 'br_netfilter' > /etc/modules-load.d/br_netfilter.conf3.2 容器运行时安装
以containerd为例的离线安装步骤:
# 解压containerd tar -xzf k8s-offline/binaries/containerd-1.6.8-linux-amd64.tar.gz -C /usr/local/ # 生成配置文件 mkdir -p /etc/containerd containerd config default > /etc/containerd/config.toml # 修改sandbox镜像为内网仓库 sed -i 's|k8s.gcr.io/pause:3.6|registry.local:5000/pause:3.6|g' /etc/containerd/config.toml # 配置systemd服务 cat > /etc/systemd/system/containerd.service <<EOF [Unit] Description=containerd container runtime Documentation=https://containerd.io After=network.target local-fs.target [Service] ExecStartPre=-/sbin/modprobe overlay ExecStart=/usr/local/bin/containerd Restart=always RestartSec=5 Delegate=yes KillMode=process OOMScoreAdjust=-999 LimitNOFILE=1048576 LimitNPROC=infinity LimitCORE=infinity [Install] WantedBy=multi-user.target EOF # 启动服务 systemctl daemon-reload systemctl enable --now containerd4. 控制平面部署
4.1 初始化控制节点
# 安装kubeadm组件 rpm -ivh k8s-offline/rpms/kubeadm-1.26.1-0.x86_64.rpm # 加载镜像 docker load -i k8s-offline/images/k8s-images.tar # 初始化集群 kubeadm init \ --kubernetes-version v1.26.1 \ --apiserver-advertise-address 192.168.1.100 \ --pod-network-cidr 10.244.0.0/16 \ --service-cidr 10.96.0.0/12 \ --image-repository registry.local:5000 \ --upload-certs # 配置kubectl mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config4.2 网络插件安装
以Calico为例的离线部署方案:
# 预先下载Calico manifest curl https://docs.projectcalico.org/manifests/calico.yaml -o calico.yaml # 修改镜像地址为内网仓库 sed -i 's|docker.io/calico/|registry.local:5000/calico/|g' calico.yaml # 应用网络插件 kubectl apply -f calico.yaml5. 工作节点加入集群
在工作节点执行以下命令加入集群:
# 安装kubelet组件 rpm -ivh k8s-offline/rpms/kubelet-1.26.1-0.x86_64.rpm # 加载镜像 docker load -i k8s-offline/images/k8s-images.tar # 加入集群(使用控制节点生成的join命令) kubeadm join 192.168.1.100:6443 \ --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxx6. 集群验证与测试
6.1 基础功能验证
# 检查节点状态 kubectl get nodes -o wide # 检查核心组件状态 kubectl get pods -n kube-system # 部署测试应用 kubectl create deployment nginx --image=registry.local:5000/nginx:1.23 kubectl expose deployment nginx --port=80 --type=NodePort # 验证服务访问 curl $(kubectl get svc nginx -o jsonpath='{.spec.clusterIP}')6.2 高可用测试
# 模拟控制节点故障 systemctl stop kube-apiserver # 观察集群状态恢复 watch kubectl get nodes # 测试工作负载迁移 kubectl drain <node-name> --ignore-daemonsets6.3 性能基准测试
使用Sonobuoy进行集群一致性测试:
# 下载Sonobuoy二进制 wget https://github.com/vmware-tanzu/sonobuoy/releases/download/v0.56.16/sonobuoy_0.56.16_linux_amd64.tar.gz # 运行测试 ./sonobuoy run --mode=certified-conformance # 获取结果 results=$(./sonobuoy retrieve) ./sonobuoy results $results7. 运维注意事项
证书管理:kubeadm默认生成的证书有效期为1年,建议提前3个月续期
kubeadm certs renew all版本升级:离线环境升级需要预先下载新版本镜像和二进制
kubeadm upgrade plan kubeadm upgrade apply v1.26.2监控方案:建议部署Prometheus-Operator监控集群状态
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm install kube-prometheus prometheus-community/kube-prometheus-stack备份恢复:定期备份etcd数据
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 snapshot.db
在实际部署过程中,我发现以下几个关键点需要特别注意:
- 内网镜像仓库的TLS证书需要提前在所有节点信任
- 不同Kubernetes版本对容器运行时的要求可能不同
- 生产环境建议至少部署3个控制节点实现高可用
- 网络插件选择需要结合实际网络环境和性能需求
通过这套完整的离线部署方案,我们成功在隔离环境中构建了稳定可靠的Kubernetes集群,为后续应用部署提供了坚实的基础设施保障。