前言
Kubernetes(简称K8s)作为容器编排领域的事实标准,已成为企业构建云原生架构、实现应用弹性部署与高效运维的核心工具。本文档基于Kubernetes 1.20.11版本,针对生产环境常见的中小型集群场景,提供从环境初始化到功能验证的完整部署指南。
文档设计遵循"分步操作、重点标注"原则:从基础环境准备(防火墙/SELinux/Swap关闭、内核参数优化),到Docker与K8s组件安装,再到Master初始化、Node节点加入、网络插件部署,最后通过Dashboard可视化与Harbor私有仓库集成,形成"部署-验证-应用"的完整闭环。每个步骤均提供明确的命令示例与参数说明,同时标注关键注意事项(如IPVS模式启用、证书生成、Token保存等),既适用于新手入门实践,也可作为企业部署的参考手册,帮助使用者快速搭建可用的K8s集群并掌握核心运维能力。
一、环境规划
| 节点角色 | 主机名 | IP地址 | 硬件配置 | 所需软件组件 | 
|---|---|---|---|---|
| Master | master01 | 192.168.10.120 | 2C/4G(CPU核心数≥2) | Docker、kubeadm、kubelet、kubectl、flannel | 
| Node | node01 | 192.168.10.126 | 2C/2G | Docker、kubeadm、kubelet、kubectl、flannel | 
| Node | node02 | 192.168.10.127 | 2C/2G | Docker、kubeadm、kubelet、kubectl、flannel | 
| Harbor 私有仓库 | hub.mgb.com | 192.168.10.128 | 无特定要求 | Docker、docker-compose、harbor-offline-v1.2.2 | 
二、环境准备(所有节点执行)
2.1 基础环境配置
关闭防火墙、SELinux、Swap,清理iptables规则:
            
            
              bash
              
              
            
          
          # 关闭并禁用防火墙
systemctl stop firewalld
systemctl disable firewalld
# 临时关闭SELinux,永久禁用SELinux
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
# 清理iptables规则
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
# 临时关闭Swap,永久禁用Swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
        2.2 加载IPVS模块
            
            
              bash
              
              
            
          
          for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do 
    echo $i; 
    /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;
done
        2.3 配置主机名与Hosts映射
(1)设置主机名(分别在对应节点执行)
- Master节点:
hostnamectl set-hostname master01 - Node01节点:
hostnamectl set-hostname node01 - Node02节点:
hostnamectl set-hostname node02 - Harbor节点:
hostnamectl set-hostname hub.mgb.com 
(2)所有节点配置Hosts映射
            
            
              bash
              
              
            
          
          vim /etc/hosts
# 添加以下内容
192.168.10.120 master01
192.168.10.126 node01
192.168.10.127 node02
192.168.10.128 hub.mgb.com  # Harbor节点(所有节点需添加)
        2.4 调整内核参数
            
            
              bash
              
              
            
          
          cat > /etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
EOF
# 生效内核参数
sysctl --system
        三、所有节点安装Docker
3.1 安装Docker依赖
            
            
              bash
              
              
            
          
          yum install -y yum-utils device-mapper-persistent-data lvm2
        3.2 配置Docker阿里云镜像源
            
            
              bash
              
              
            
          
          yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        3.3 安装Docker并配置
            
            
              bash
              
              
            
          
          yum install -y docker-ce docker-ce-cli containerd.io
yum install docker-ce-20.10.18 docker-ce-cli-20.10.18 containerd.io
# 创建Docker配置目录(Harbor节点后续需追加私有仓库配置,此处先统一基础配置)
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF
# 重启Docker并设置开机自启
systemctl daemon-reload
systemctl restart docker.service
systemctl enable docker.service
# 验证Cgroup驱动
docker info | grep "Cgroup Driver"  # 预期输出:Cgroup Driver: systemd
        四、所有节点安装kubeadm、kubelet、kubectl
4.1 配置Kubernetes阿里云YUM源
            
            
              bash
              
              
            
          
          cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
        4.2 安装指定版本(1.20.11)
            
            
              bash
              
              
            
          
          yum install -y kubelet-1.20.11 kubeadm-1.20.11 kubectl-1.20.11
        4.3 设置kubelet开机自启
            
            
              bash
              
              
            
          
          systemctl enable kubelet.service
        五、部署Kubernetes Master节点
5.1 准备Kubernetes镜像
(1)查看所需镜像列表
            
            
              bash
              
              
            
          
          kubeadm config images list
        (2)加载镜像(本地加载推荐)
- 
将
v1.20.11.zip上传至Master节点/opt目录,解压加载:bashunzip v1.20.11.zip -d /opt/k8s cd /opt/k8s/v1.20.11 for i in $(ls *.tar); do docker load -i $i; done - 
将镜像复制到Node节点:
bashscp -r /opt/k8s root@node01:/opt # node01 IP:192.168.10.126 scp -r /opt/k8s root@node02:/opt # node02 IP:192.168.10.127 # 在Node01、Node02节点执行镜像加载命令(同Master步骤) 
5.2 初始化Master节点(两种方式)
方式一:配置文件初始化(推荐)
(1)生成并修改配置文件
            
            
              bash
              
              
            
          
          kubeadm config print init-defaults > /opt/kubeadm-config.yaml
vim /opt/kubeadm-config.yaml
        关键参数修改:
            
            
              yaml
              
              
            
          
          11 localAPIEndpoint:
12   advertiseAddress: 192.168.10.120  # Master新IP(192.168.10.120)
13   bindPort: 6443
......
34 kubernetesVersion: v1.20.11
35 networking:
36   dnsDomain: cluster.local
37   podSubnet: "10.244.0.0/16"
38   serviceSubnet: 10.96.0.0/16
39 scheduler: {}
# 末尾添加IPVS配置
--- 
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
        (2)执行初始化并记录日志
            
            
              bash
              
              
            
          
          sudo swapoff -a #关闭交换分区
sudo sed -i '/swap/s/^/#/' /etc/fstab
        
            
            
              bash
              
              
            
          
          kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
kubeadm init --config=/opt/kubeadm-config.yaml --upload-certs --ignore-preflight-errors=SystemVerification | tee kubeadm-init.log
        关键保存 :初始化成功后输出的kubeadm join命令,示例格式:
            
            
              bash
              
              
            
          
          kubeadm join 192.168.10.120:6443 --token xxxx.xxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
kubeadm join 192.168.10.120:6443 --token 49hgxs.w7xvbm5mm1e3e7p6 \
    --discovery-token-ca-cert-hash sha256:59e58b17cb1c07c0f2aaa7ce5d7bc9fa5f932dc98c8209c41e8aa9b361539f4f
        
方式二:命令行参数初始化
            
            
              bash
              
              
            
          
          kubeadm init \
--apiserver-advertise-address=192.168.10.120 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.20.11 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \
--token-ttl=0
        5.3 配置kubectl(Master节点)
            
            
              bash
              
              
            
          
          mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# root用户额外配置(可选)
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
source /etc/profile
        5.4 修复集群健康状态(若需)
            
            
              bash
              
              
            
          
          # 修改kube-scheduler和kube-controller-manager配置
vim /etc/kubernetes/manifests/kube-scheduler.yaml
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
# 两处文件均修改:
1. --bind-address=127.0.0.1 → --bind-address=192.168.10.120
2. httpGet下的hosts: 127.0.0.1 → hosts: 192.168.10.120(共两处)
3. 注释--port=0
# 重启kubelet
systemctl restart kubelet
        六、部署flannel网络插件
6.1 部署flannel(Master节点执行,所有节点需加载镜像)
方式一:本地部署
- 
所有节点加载
flannel.tar(上传至/opt):bashcd /opt && docker load < flannel.tar - 
Master节点上传
kube-flannel.yml,执行部署:bashkubectl apply -f kube-flannel.yml 
方式二:在线部署
            
            
              bash
              
              
            
          
          kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
        6.2 验证flannel状态
            
            
              bash
              
              
            
          
          kubectl get pods -n kube-system | grep flannel  # 所有节点Pod需为Running
        
七、添加Node节点到集群
7.1 执行Join命令(Node01、Node02分别执行)
使用Master初始化时保存的包含新IP(192.168.10.120) 的kubeadm join命令,示例:
            
            
              bash
              
              
            
          
          # Node01(192.168.10.126)和Node02(192.168.10.127)均执行
kubeadm join 192.168.10.120:6443 --token xxxx.xxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        7.2 验证节点状态(Master节点)
            
            
              bash
              
              
            
          
          kubectl get nodes  # 预期输出master01、node01、node02均为Ready状态
        
八、测试集群功能
8.1 创建Nginx Deployment
            
            
              bash
              
              
            
          
          kubectl create deployment nginx --image=nginx
kubectl get pods -o wide  # 查看Pod是否正常运行
        拉不下来镜像试一下使用华为云的仓库:
kubectl set image deployment/nginx nginx=swr.cn-north-4.myhuaweicloud.com/library/nginx:latest
8.2 暴露Service(NodePort)
            
            
              bash
              
              
            
          
          kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc  # 获取NodePort端口(如32XXX)
        
8.3 访问测试
            
            
              bash
              
              
            
          
          # 访问Node01(192.168.10.126)或Node02(192.168.10.127)+ NodePort
curl http://192.168.10.126:32XXX  # 替换32XXX为实际端口
        
8.4 扩展副本
            
            
              bash
              
              
            
          
          kubectl scale deployment nginx --replicas=3
kubectl get pods -o wide  # 查看副本分布在两个Node节点
        
九、部署Kubernetes Dashboard
9.1 部署Dashboard(Master节点)
- 
上传
recommended.yaml至/opt/k8s,修改Service为NodePort:bashvim /opt/k8s/recommended.yaml修改
Service部分(添加nodePort: 30001和type: NodePort):yamlkind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: ports: - port: 443 targetPort: 8443 nodePort: 30001 # 固定端口,便于访问 type: NodePort selector: k8s-app: kubernetes-dashboard - 
执行部署:
bashkubectl apply -f /opt/k8s/recommended.yaml 
9.2 获取登录Token
            
            
              bash
              
              
            
          
          # 创建管理员账户
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取Token
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
        9.3 访问Dashboard
浏览器访问:https://192.168.10.120:30001或https://192.168.10.126:30001,粘贴Token登录。
十、部署Harbor私有仓库(新IP:192.168.10.128)
10.1 配置Harbor节点Docker(添加私有仓库)
            
            
              bash
              
              
            
          
          # 覆盖Docker配置,添加Harbor(192.168.10.128)的私有仓库
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "insecure-registries": ["https://hub.mgb.com"]  # Harbor域名(映射到192.168.10.128)
}
EOF
# 重启Docker
systemctl daemon-reload
systemctl restart docker
        10.2 所有Node节点配置Docker访问Harbor
同Harbor节点配置,修改/etc/docker/daemon.json,添加"insecure-registries": ["https://hub.mgb.com"],重启Docker。
10.3 安装Docker Compose(Harbor节点)
- 
上传
docker-compose至/opt,配置权限:bashcp /opt/docker-compose /usr/local/bin/ chmod +x /usr/local/bin/docker-compose docker-compose --version # 验证安装 
10.4 安装并配置Harbor
(1)解压Harbor安装包
            
            
              bash
              
              
            
          
          cd /opt
tar zxvf harbor-offline-installer-v1.2.2.tgz
cd harbor/
        (2)修改Harbor配置文件
            
            
              bash
              
              
            
          
          vim harbor.cfg
# 关键参数(域名hub.mgb.com已映射到192.168.10.128)
5  hostname = hub.mgb.com
9  ui_url_protocol = https
24 ssl_cert = /data/cert/server.crt
25 ssl_cert_key = /data/cert/server.key
59 harbor_admin_password = Harbor12345
        (3)生成SSL证书(Harbor节点)
            
            
              bash
              
              
            
          
          mkdir -p /data/cert && cd /data/cert
# 1. 生成私钥
openssl genrsa -des3 -out server.key 2048  # 输入密码(如123456)
# 2. 生成CSR(Common Name填hub.mgb.com)
openssl req -new -key server.key -out server.csr
# 输入信息:Country=CN, State=BJ, City=BJ, Org=mgb, OU=mgb, CN=hub.mgb.com, Email=admin@mgb.com
# 3. 清除私钥密码
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key  # 输入密码
# 4. 生成自签名证书
openssl x509 -req -days 1000 -in server.csr -signkey server.key -out server.crt
# 5. 赋予权限
chmod +x /data/cert/*
        (4)安装Harbor
            
            
              bash
              
              
            
          
          cd /opt/harbor/
./install.sh
        10.5 使用Harbor
(1)Web访问
浏览器访问:https://hub.mgb.com(自动解析到192.168.10.128),登录admin/Harbor12345。
(2)推送镜像到Harbor(Node节点)
            
            
              bash
              
              
            
          
          # 登录Harbor
docker login -u admin -p Harbor12345 https://hub.mgb.com
# 标记并推送Nginx镜像
docker tag nginx:latest hub.mgb.com/library/nginx:v1
docker push hub.mgb.com/library/nginx:v1
        (3)Kubernetes使用Harbor镜像
            
            
              bash
              
              
            
          
          # 删除旧Deployment,使用Harbor镜像创建新Deployment
kubectl delete deployment nginx
kubectl create deployment nginx-harbor --image=hub.mgb.com/library/nginx:v1 --port=80 --replicas=3
# 暴露Service(NodePort)
kubectl expose deployment nginx-harbor --port=80 --type=NodePort
kubectl get svc  # 获取NodePort端口
# 访问测试(使用Node新IP)
curl http://192.168.10.126:<NodePort>  # Node01新IP
        十一、关键命令总结
| 功能描述 | 命令示例 | 
|---|---|
| 查看节点状态 | kubectl get nodes | 
| 访问Dashboard | 浏览器打开https://192.168.10.120:30001 | 
| 访问Harbor | 浏览器打开https://hub.mgb.com(映射到192.168.10.128) | 
| 测试Nginx服务 | curl http://192.168.10.126:<NodePort> | 
| 验证IPVS规则 | ipvsadm -Ln | 
| 查看Harbor推送的镜像 | `docker images | 
总结
本文档围绕Kubernetes 1.20.11版本集群部署展开,通过10个核心章节完成从环境准备到应用落地的全流程实现,关键成果与核心要点总结如下:
一、集群环境与组件部署成果
- 节点规划落地 :完成4个节点(1个Master、2个Worker、1个Harbor)的IP与主机名配置,新IP段
192.168.10.120-128已通过/etc/hosts映射生效,确保节点间通信正常。 - 基础环境标准化:所有节点统一关闭防火墙/SELinux/Swap,加载IPVS模块并优化内核参数,为K8s组件运行提供稳定的底层环境;Docker通过阿里云镜像加速与Systemd Cgroup驱动配置,解决镜像拉取慢与组件兼容性问题。
 - K8s组件部署完成 :Master节点通过配置文件/命令行两种方式完成初始化,Node节点成功加入集群,
kubectl get nodes可显示所有节点为Ready状态;flannel网络插件部署后,Pod间跨节点通信正常,kube-system命名空间下核心组件(coredns、kube-proxy、etcd等)均运行稳定。 
二、核心功能验证与应用集成
- 集群功能验证 :通过创建Nginx Deployment、暴露NodePort Service、扩展副本数等操作,验证K8s的Pod调度、服务暴露与弹性伸缩能力,访问
NodeIP:NodePort可正常获取Nginx页面,证明集群业务承载能力正常。 - 可视化与运维优化 :Dashboard通过NodePort类型暴露,结合管理员Token实现集群资源的可视化管理;Harbor私有仓库完成SSL证书配置与Docker客户端对接,支持镜像推送与拉取,解决K8s集群镜像依赖的私有化存储问题,同时通过
insecure-registries配置避免非信任证书报错。 
三、关键注意事项与经验总结
- 参数一致性是核心 :Master初始化时的
advertiseAddress需与实际IP匹配,Pod网段(10.244.0.0/16)需与flannel默认网段一致,Harbor域名与IP的映射需在所有节点同步,避免因参数不匹配导致的集群异常。 - 关键信息需留存 :Master初始化后输出的
kubeadm join命令(含Token与CA哈希)、Dashboard管理员Token、Harbor证书密码等信息需妥善保存,避免后续节点加入或登录时重新生成的麻烦。 - 排障思路需明确 :若出现节点
NotReady、Pod调度失败等问题,可优先检查网络插件运行状态(kubectl get pods -n kube-system)、Docker与kubelet服务状态(systemctl status docker/kubelet)、IP与端口通信(ping/telnet),定位问题多源于网络或配置不一致。 
通过本文档操作,可快速搭建一个功能完整、可用于实际业务测试的K8s集群,同时掌握集群部署的核心逻辑与运维要点,为后续基于K8s的应用部署(如微服务、CI/CD集成)奠定基础。