🚀 Kubernetes(K8s) 作为云原生时代的核心编排工具,已成为 DevOps 和运维工程师的必备技能。但手动部署 K8s 集群往往耗时且复杂,如何快速、稳定地搭建一套生产可用的集群?
本文将以 Containerd + Kubeadm 为核心,手把手带你10分钟内完成 K8s 集群搭建,涵盖:✅ 一键安装依赖(无需手动配置)✅ 高可用集群部署(Master/Worker 节点)✅ 网络插件(Calico/Flannel)自动集成
✅ 仪表盘(Dashboard)Web 页面访问
✅ 常见避坑指南(解决证书错误、镜像源拉取失败等问题)
无论你是初学者还是进阶用户,这篇指南都能帮你跳过繁琐步骤,直达生产级集群!
现在开始,让你的 K8s 之旅快人一步!
1. 安装要求
在开始之前,部署Kubernetes集群机器需要满足以下几个条件:
三台机器,操作系统 CentOS7.x-86_x64 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多 集群中所有机器之间网络互通 可以访问外网,需要拉取镜像 禁止swap分区
2. 学习目标
在所有节点上安装Containerd和kubeadm 部署Kubernetes Master 部署容器网络插件 部署 Kubernetes Node,将节点加入Kubernetes集群中 部署Dashboard Web页面,可视化查看Kubernetes资源
3. 准备环境

Kubernetes 架构图

所有机器操作:本次实验三台机器IP地址:192.168.234.131,192.168.234.132,192.168.234.133
关闭防火墙:$ systemctl stop firewalld$ systemctl disable firewalld关闭selinux:$ sed -i 's/enforcing/disabled/' /etc/selinux/config $ setenforce 0关闭swap:$ swapoff -a $ 临时$ vim /etc/fstab $ 永久注释 有"swap"的一列 $ swapoff -a && sed -i '/ swap / s/^/#/' /etc/fstab添加主机名与IP对应关系(记得设置主机名):$ cat /etc/hosts192.168.234.131 k8s-master192.168.234.132 k8s-node1192.168.234.133 k8s-node2将桥接的IPv4流量传递到iptables的链:$ cat > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1EOF# 加载br_netfilter模块$ modprobe br_netfilter# 查看是否加载$ lsmod | grep br_netfilter# 生效 $ sysctl --system#时间同步$ yum install ntpdate -y$ ntpdate time.windows.com
4.所有节点安装containerd/kubeadm/kubelet/kubectl
版本信息:
kubeadm/kubelet/kubectl:v1.28.2containerd:1.6.33
Kubernetes 1.24+ 以上版本默认使用containterd 做为容器引擎。
注意:Kubernetes 1.24+ 版本已彻底移除 dockershim,即使你安装了 Docker,也需要通过 cri-dockerd
适配器才能兼容,因此我们这里使用containerd 作为容器引擎。
4.1 安装containerd
安装需要的软件包, yum-util 提供yum-config-manager功能$ yum -y install yum-utilsContainerd软件包及依赖存放于Docker仓库$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo查看是否添加成功$ ls /etc/yum.repos.d/docker-ce.repocontainer.io 需要依赖 container-selinux 包,因此需要配置CentOS 仓库 $ wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo$ sed -i 's/$releasever/7/g' CentOS-Base.repo安装Containerd$ yum -y install containerd.io启动并设置开机自启$ systemctl enable containerd 查看版本:$ containerd -v
4.2 添加阿里云YUM软件源
$ cat > /etc/yum.repos.d/kubernetes.repo [kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64enabled=1gpgcheck=1repo_gpgcheck=0gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF
4.3 安装kubeadm,kubelet和kubectl
由于版本更新频繁,这里指定版本号部署:
$ yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2$ systemctl enable kubelet $ systemctl start kubelet (由于没有生成配置文件,节点没有初始化无法启动,三个节点都安装完成之后,在其中一个master初始化之后启动,执行kubeadm init 语句)$ journalctl _PID= 如果报错查看详情
5. 部署Kubernetes Master
在192.168.234.131(Master)执行。
$ kubeadm init --apiserver-advertise-address=192.168.234.131 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.28.2 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16## 执行完之后命令行最后会回显类似如下内容,在node节点执行即可加入到master节点: kubeadm join 192.168.233.133:6443 --token uil7uf.b7g6vt6kcvzfeqnu --discovery-token-ca-cert-hash sha256:35add0964b670b4b2d8060ec5e055d5b4badc4e59ed79ecb639e276edc393ea1 说明:kubeadm init 会 pull 必要的镜像,可能时间会比较长 (kubeadm config images pull 可测试是否可以拉取镜像,如果加了 --image-repository registry.aliyuncs.com/google_containers,不会担心在国内拉取镜像问题)注意: 如下执行如上命令初始化报如下错:[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s[kubelet-check] Initial timeout of 40s passed.Unfortunately, an error has occurred: timed out waiting for the conditionThis error is likely caused by: - The kubelet is not running - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands: - 'systemctl status kubelet' - 'journalctl -xeu kubelet'Additionally, a control plane component may have crashed or exited when started by the container runtime.To troubleshoot, list all containers using your preferred container runtimes CLI.Here is one example how you may list all running Kubernetes containers by using crictl: - 'crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -a | grep kube | grep -v pause' Once you have found the failing container, you can inspect its logs with: - 'crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock logs CONTAINERID'error execution phase wait-control-plane: couldn't initialize a Kubernetes clusterTo see the stack trace of this error execute with --v=5 or higher/var/log/messages 文件报:failed to get sandbox image \“registry.k8s.io/pause:3.6\“: failed to pull image \“registry.k8解决方法:修改/etc/containerd/config.toml 文件1、要先containerd config default > /etc/containerd/config.toml找到sandbox_image = "registry.k8s.io/pause:3.6"改为sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"然后systemctl restart containerd————————————————
如果前面kubeadm init 命令配置有误,可以执行如下命令进行重置:$ kubeadm reset --force$ rm -rf $HOME/.kube/*之后再次使用 kubeadm init 搭建集群 记得删除前面创建的 $HOME/.kube 目录,未删重新创建,会有如下报错:Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes"
6. 安装Pod网络插件(CNI)
## 在Master节点部署CNI网络插件(可能会失败,如果失败,请下载到本地,然后安装):wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
确保能够访问到quay.io这个registery。 master执行如下指令查看pod 状态
# kubectl get pods -n kube-system
7. 加入Kubernetes Node
在192.168.234.132/133(Node)执行。
向集群添加新节点,执行在kubeadm init 输出的kubeadm join命令:
$ kubeadm join 192.168.234.133:6443 --token uil7uf.b7g6vt6kcvzfeqnu --discovery-token-ca-cert-hash sha256:35add0964b670b4b2d8060ec5e055d5b4badc4e59ed79ecb639e276edc393ea1 如果无法加入请检查:1、检查firewalld,selinux,swap 等是都满足启动kubelet条件2、有可能是 iptables 规则乱了,通过执行以下命令解决1.回到kubernees-maser 依次输入列命令systemctl stop kubeletsystemctl stop containerdiptables --flushiptables -tnat --flushsystemctl start kubeletsystemctl start containerd2、在kubernetse-master重新生成token:# kubeadm token create 424mp7.nkxx07p940mkl2nd# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' d88fb55cb1bd659023b11e61052b39bbfe99842b0636574a16c76df186fd5e0d3.在kubernetes-slave中执行此命令重新join# kubeadm join 192.168.234.133:6443 --token 424mp7.nkxx07p940mkl2nd --discovery-token-ca-cert-hash sha256:d88fb55cb1bd659023b11e61052b39bbfe99842b0636574a16c76df186fd5e0d
默认的token有效期为24小时,当过期之后,该token就不能用了,这时可以使用如下的命令创建token:$ kubeadm token create --print-join-command# 生成一个永不过期的token$ kubeadm token create --ttl 0
8. 测试kubernetes集群
在Kubernetes集群中创建一个pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx$ kubectl expose deployment nginx --port=80 --type=NodePort$ kubectl get pod,svc$ kubectl get pod,svc -o wide
完成集群部署之后若node 节点无法执行kubectl 命令的,想要node节点执行命令复制:config (admin.conf)文件到node节点下即可。如下:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config/etc/kubernetes/admin.conf //主节点执行mkdir -p $HOME/.kubescp /root/.kube/config root@k8s-node1:/root/.kube/
9. 部署 Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml默认Dashboard只能集群内部访问,需要修改service为nodePort类型,暴露到外部,执行命令将配置文件下载下来wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
修改这个文件vi recommended.yaml找到这段,增加红包部分,冒号后面有一个空格,千万要注意kind: ServiceapiVersion: v1metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-systemspec:type: NodePort //声明服务类型 ports: - port: 443 targetPort: 8443 nodePort: 30001 //注意如果这里的nodePort写成nodeport或者存在其他书写问题,就会报如下的错 selector: k8s-app: kubernetes-dashboard
$ kubectl apply -f kubernetes-dashboard.yaml
访问地址:https://NodeIP:30001
注意:这里必须是https的方式,如果谷哥浏览器不能访问,谷哥有的版本没有添加信任的地方,无法访问,可使用firefox或者其它浏览器。
创建service account并绑定默认cluster-admin管理员集群角色:
方式一:之后使用Token登录# 创建新的 ServiceAccountkubectl create serviceaccount dashboard-admin -n kubernetes-dashboard# 绑定 cluster-admin 角色kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin## 在 Kubernetes 1.24+ 版本,ServiceAccount 默认不会自动生成 Secret Token,必须手动创建。手动创建 Token Secret:cat apiVersion: v1kind: Secretmetadata: name: dashboard-admin-token namespace: kubernetes-dashboard annotations: kubernetes.io/service-account.name: dashboard-admintype: kubernetes.io/service-account-tokenEOF# 获取新 ServiceAccount 的令牌ADMIN_SECRET=$(kubectl get secrets -n kubernetes-dashboard | grep dashboard-admin-token | awk '{print $1}')ADMIN_TOKEN=$(kubectl describe secret $ADMIN_SECRET -n kubernetes-dashboard | grep "^token" | awk '{print $2}');echo"$ADMIN_TOKEN"使用输出的token登录Dashboard。方式2:使用配置文件登录:########################################################################################APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')cat dashboard-admin.kubeconfigapiVersion: v1kind: Configclusters:- cluster: certificate-authority-data: $(kubectl get secret dashboard-admin-token -n kubernetes-dashboard -o jsonpath='{.data.ca.crt}') server: ${APISERVER} name: kubernetescontexts:- context: cluster: kubernetes user: dashboard-admin name: dashboard-admin@kubernetescurrent-context: dashboard-admin@kubernetesusers:- name: dashboard-admin user: token: ${ADMIN_TOKEN}EOF# 然后使用这个令牌创建 kubeconfig 文件登录dashboard