快速部署一套 K8s 集群
准备服务器环境
Kubernetes集群节点规划
| 集群角色 | 主机名 | 操作系统 | IP地址 |
|---|---|---|---|
| Master | k8s-master | Ubuntu Server 22.04 TLS | 192.168.100.81 |
| Node | k8s-node1 | Ubuntu Server 22.04 TLS | 192.168.100.82 |
| Node | k8s-node2 | Ubuntu Server 22.04 TLS | 192.168.100.83 |
当服务器在一个防火墙环境中,需要开放相关端口,Kubernetes 涉及端口 
系统初始化配置
在搭建Kubernetes集群之前,需要对操作系统进行一系列配置,以满足环境要求。在所有节点上操作如下:
关闭 Swap 交换分区
Swap 是一种虚拟内存技术,它允许系统将部分内存数据写到硬盘上的特定分区,从而释放更多物理内存。由于硬盘读写性能相比物理内存低,因此使用 Swap 会影响系统处理性能。并且 Kubelet 组件默认要求关闭 Swap,以提高系统的稳定性和可靠性。
- 查看分区
free -m- 关闭 Swap 交换分区
swapoff -a该命令为临时生效。
- 设置开机启动生效 为了确保重启系统后继续有效,将系统表文件 “/etc/fstab” 中文件系统类型为 “swap” 的行注释。
vi /etc/fstab注释之后如下图: 
- 查看是否生效 通过命令
free -m查看,若都是 0 则生效,如下图
设置主机名
hostnamectl set-hostname <主机名>设置后通过命令 bash 刷新主机名 
配置内核参数
某些 Kubernetes 网络插件可能会用到网络桥接(Bridge),为了确保网络桥接的数据包经过 Iptables 处理,启用相关的内核参数:
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效
同步系统时间
apt install ntpdate- 设置时区
timedatectl set-timezone Asia/Shanghai- 同步 windows 时间
ntpdate time.windows.com
安装 Docker
在所有节点上安装并启动Docker。
下载阿里云APT软件源文件
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -cat <<EOF >/etc/apt/sources.list.d/docker.list
deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial stable
EOF安装Docker
apt-get updateapt-get install docker-ce -y查看 docker 信息
docker info配置镜像下载加速器:
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://docker.ketches.cn","https://docker.1ms.run","https://hub1.nat.tf"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF启动并设置开机启动:
systemctl restart docker && systemctl enable docker安装 cri-docker
在 Kubernetes 早期版本中,Docker 作为默认容器运行时,并在 Kubelet 程序中开发了一个名为 “Dockershim” 的代理程序,负责 Kubelet 与 Docker 通信,如下图所示。 
随着 Kubernetes 生态系统的发展,涌现出多种容器运行时,例如 containerd、cri-o、rkt 等。为了支持这些容器运行时,Kubernetes 引入 CRI(Container Runtime Interface,容器运行时接口)标准,使得第三方容器运行时只需对接 CRI 即可与 Kubernetes 集成。
后来,在 Kubernetes 1.20 版本发布时宣布:为了优化核心代码,减少维护负担,将在 1.24 版本中正式移除 “Dockershim”,而当时 Docker 又不支持 CRI,这就意味着 Kubernetes 无法再 Docker 作为容器运行时。Docker 官方为了解决这个问题,与 Mirantis 公司合作,开发了一个名为 “cri-dockerd” 的代理程序,负责 Kubelet 与 Docker 通信,如图下图所示。
因此从 Kubernetes 1.24 版本及更高版本开始,使用 Docker 作为容器运行时,需要安装 cri-dockerd。
安装 cri-docker
下载地址: https://github.com/Mirantis/cri-dockerd/releases
下载后上传到所有节点上并进行安装:
dpkg -i cri-dockerd_0.3.4.3-0.ubuntu-focal_amd64.deb安装完成后,修改Systemd服务文件指定依赖的Pause镜像为国内镜像地址:
vi /usr/lib/systemd/system/cri-docker.serviceExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9
重启 cri-docker
systemctl daemon-reloadsystemctl restart cri-docker查看是否安装成功
ps -ef |grep docker正常情况下, 会出现 cri-docker 和 docker
设置开机启动:
systemctl enable cri-docker安装 kubeadm 和 kubelet
在所有节点上安装 kubeadm、kubectl 和 kubelet 组件。 但这些软件包未包含在系统默认软件源中,需要额外配置APT软件源,
配置阿里云的软件源:
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpgecho "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list- 查看源的位置
ls /etc/apt/sources.list.d- 更新索引
apt update安装指定版本 kubeadm、kubectl 和 kubelet
apt-get updateapt-get install -y kubectl=1.32.0-1.1 kubeadm=1.32.0-1.1 kubelet=1.32.0-1.1仅设置开机启动
kubeadm 和 kubectl 仅是一个集群搭建工具和管理工具,不涉及启动。而 kubelet 是一个守护进程程序,由 kubeadm 在搭建过程中自动启动,这里仅设置开机启动即可:
systemctl enable kubelet部署 Master 节点
在 Master 节点执行以下命令初始化 Kubernetes 管理节点:
kubeadm init \
--apiserver-advertise-address=192.168.100.81 \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.32.0 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--cri-socket=unix:///var/run/cri-dockerd.sock该命令中各参数含义如下
| 参数 | 描述 | |-------------------------------|----------------------------------------------------------| | --apiserver-advertise-address | 指定 API Server 监听的 IP 地址。如果没有设置,将使用默认的网络接口。 | | --image-repository | 指定镜像仓库地址。默认值为 “registry.k8s.io”,但该仓库在国内无法访问,因此这里指定阿里云仓库。 | | --kubernetes-version | 指定 Kubernetes 版本。 | | --pod-network-cidr | 指定 Pod 网络的 CIDR 地址范围。 | | --service-cidr | 指定 Service 网络的 CIDR 地址范围。 | | --cri-socket | 指定 kubelet 连接容器运行时的 Unix 套接字文件。 |
命令执行后,kubeadm会执行一系列任务,大概如下:
- [preflight]:该阶段执行一系列检查,验证当前系统环境是否满足Kubernetes的安装要求,包括: 1、CPU和内存是否满足最低要求; 2、网络是否正常; 3、操作系统版本是否满足; 4、容器运行时是否可以连接; 5、内核参数是否正确配置; 6、下载所需的容器镜像。
- [certs]:生成 Kubernetes 组件所需的 HTTPS 证书和秘钥,并存放到 “/etc/kubernetes/pki” 目录;
- [kubeconfig]:生成 kubeconfig 文件,该文件包含 API Server 地址、客户端证书等信息,并存放到 “/etc/kubernetes” 目录。
- [kubelet-start]:生成 kubelet 配置文件 “/var/lib/kubelet/config.yaml” 并启动 kubelet 服务。
- [control-plane]:为 kube-apiserver、kube-controller-manager 和 kube-scheduler 创建静态Pod资源文件,并存储到 “/etc/kubernetes/manifests” 目录。
- [etcd]:为 etcd 创建静态 Pod 资源文件,并存储到 “/etc/kubernetes/manifests” 目录。
- [wait-control-plane]:等待 kubelet 从目录 “/etc/kubernetes/manifest” 中以静态 Pod 的形式启动 Master 组件。
- [apiclient]:检查 Master 组件是否健康。
- [upload-config]:将 kubeadm 配置存储到 ConfigMap 对象中。
- [kubelet]:将 kubelet 配置存储到 ConfigMap 对象中。
- [upload-certs]:提示用户跳过证书上传。
- [mark-control-plane]:给 Master 节点添加标签和污点。
- [bootstrap-token]:生成引导令牌,用于 Node 节点在加入集群时使用。
- [kubelet-finalize]:更新 kubelet 配置文件(/etc/kubernetes/kubelet.conf)。
- [addons]:安装 CoreDNS 和 kube-proxy 插件。
紧接着,输出初始化成功的信息:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.100.81:6443 --token qrbzfp.g5kd35d6oolcfi0w \
--discovery-token-ca-cert-hash sha256:fb1573641c774b5be0880221e43b37432b6a788d46470d90ae57e96784a076e4根据上述提示,执行以下命令开始使用集群:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config这些命令是将文件 “/etc/kubernetes/admin.conf” 复制到 “$HOME/.kube/config”,以便 kubectl 根据该配置文件连接和管理 Kubernetes 集群。
kubeadm join 192.168.100.81:6443 --token qrbzfp.g5kd35d6oolcfi0w \
--discovery-token-ca-cert-hash sha256:fb1573641c774b5be0880221e43b37432b6a788d46470d90ae57e96784a076e4部署 Node 节点
日志中出现的 kubeadm join 日志, 在工作节点上执行, 例如下面语句, 表示将工作几点添加到 Master 节点, 后面需要带上 --cri-socket,以将这些工作节点加入到集群中:
kubeadm join 192.168.100.81:6443 --token qrbzfp.g5kd35d6oolcfi0w \
--discovery-token-ca-cert-hash sha256:fb1573641c774b5be0880221e43b37432b6a788d46470d90ae57e96784a076e4 \
--cri-socket=unix:///var/run/cri-dockerd.sock命令执行后,将看到以下内容:
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
可以在 Master 节点执行 kubectl get nodes 命令查看节点,结果如下: 
部署网络插件
在上述结果中,节点状态显示为 “NotReady”,表示节点尚未准备就绪。这是由于 kubelet 服务未发现网络插件导致的,kubelet 日志中也有相关说明(“network plugin is not ready”)。 Kubernetes 网络插件主要用于实现集群内部Pod通信,它负责配置和管理Pod的网络。常见的网络插件包括 Calico、Flannel、Cilium 等,这里选择使用 Calico 作为 Kubernetes 网络插件。
解压 calico
将 Calico 包上传至服务器, 并解压, 如果不能解压, 需要执行 apt install unzip 命令。
unzip calico-operator.zip安装 Calico 网络插件
kubectl create -f tigera-operator.yamlkubectl create -f custom-resources.yaml查看 Pod 对象
kubectl get pods -n calico-system结果呈现如下:
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6bb86c78b4-72j7t 1/1 Running 0 38m
calico-node-5hlbr 1/1 Running 0 38m
calico-node-jv7bg 1/1 Running 0 38m
calico-node-qqqfl 1/1 Running 0 38m
calico-typha-6c9f86b48-7x692 1/1 Running 0 38m
calico-typha-6c9f86b48-mt4g2 1/1 Running 0 38m
csi-node-driver-djppj 2/2 Running 0 38m
csi-node-driver-jgc8p 2/2 Running 0 38m
csi-node-driver-v4drl 2/2 Running 0 38m所有 Pod 的状态均显示为 Running,说明 Calico 安装成功。再通过 kubectl get nodes 命令查看节点,状态转为 “Ready”,表示节点准备就绪。
需要注意的是,Kubernetes 考虑到安全性,“kubeadm join” 命令中的Token有效期为24小时,过期后不可再使用。届时,可以通过 kubeadm token create --print-join-command 命令创建新的 Token,以添加新的工作节点。
部署 Dashboard
Dashboard 是官方开发的一个 Web 管理系统,通过它可以管理集群资源、查看应用概览、查看容器日志和进入容器等操作。
下载Dashboard的资源文件(或者上传镜像包):
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml将 Service 的类型设置为 “NodePort” 类型并指定访问端口,以便将其暴露到集群外部访问,修改如下:
vi recommended.yamlkind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort # 指定NodePort类型
ports:
- port: 443
targetPort: 8443
nodePort: 30001 # 指定访问端口
selector:
k8s-app: kubernetes-dashboard在集群中创建资源
kubectl apply -f kubernetes-dashboard.yaml查看Pod对象
kubectl get pods -n kubernetes-dashboard所有 Pod 的状态都显示为 “Running”,说明 Dasboard 安装成功。浏览器访问 “https://<节点IP地址>:30001 ”, 将看到登录界面,如图所示 
创建一个服务账号并授予集群管理员权限
kubectl create serviceaccount admin-user -n kubernetes-dashboard
kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user根据服务账号创建Token
kubectl create token admin-user -n kubernetes-dashboard输入 token 登录后可查看节点信息 
剑鸣秋朔