Skip to content
章节导航

快速部署一套 K8s 集群

准备服务器环境

Kubernetes集群节点规划

集群角色主机名操作系统IP地址
Masterk8s-masterUbuntu Server 22.04 TLS192.168.100.81
Nodek8s-node1Ubuntu Server 22.04 TLS192.168.100.82
Nodek8s-node2Ubuntu Server 22.04 TLS192.168.100.83

当服务器在一个防火墙环境中,需要开放相关端口,Kubernetes 涉及端口

系统初始化配置

在搭建Kubernetes集群之前,需要对操作系统进行一系列配置,以满足环境要求。在所有节点上操作如下:

关闭 Swap 交换分区

Swap 是一种虚拟内存技术,它允许系统将部分内存数据写到硬盘上的特定分区,从而释放更多物理内存。由于硬盘读写性能相比物理内存低,因此使用 Swap 会影响系统处理性能。并且 Kubelet 组件默认要求关闭 Swap,以提高系统的稳定性和可靠性。

  • 查看分区
shell
free -m
  • 关闭 Swap 交换分区
shell
swapoff -a

该命令为临时生效。

  • 设置开机启动生效 为了确保重启系统后继续有效,将系统表文件 “/etc/fstab” 中文件系统类型为 “swap” 的行注释。
shell
vi /etc/fstab

注释之后如下图:

  • 查看是否生效 通过命令 free -m 查看,若都是 0 则生效,如下图

设置主机名

shell
hostnamectl set-hostname <主机>

设置后通过命令 bash 刷新主机名

配置内核参数

某些 Kubernetes 网络插件可能会用到网络桥接(Bridge),为了确保网络桥接的数据包经过 Iptables 处理,启用相关的内核参数:

shell
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

同步系统时间

shell
apt install ntpdate
  • 设置时区
shell
timedatectl set-timezone Asia/Shanghai
  • 同步 windows 时间
shell
ntpdate time.windows.com

安装 Docker

在所有节点上安装并启动Docker。

下载阿里云APT软件源文件

shell
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
shell
cat <<EOF >/etc/apt/sources.list.d/docker.list
deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial stable
EOF

安装Docker

shell
apt-get update
shell
apt-get install docker-ce -y

查看 docker 信息

shell
docker info

配置镜像下载加速器:

shell
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

启动并设置开机启动:

shell
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

下载后上传到所有节点上并进行安装:

shell
dpkg -i cri-dockerd_0.3.4.3-0.ubuntu-focal_amd64.deb

安装完成后,修改Systemd服务文件指定依赖的Pause镜像为国内镜像地址:

shell
vi /usr/lib/systemd/system/cri-docker.service
shell
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

重启 cri-docker

shell
systemctl daemon-reload
shell
systemctl restart cri-docker

查看是否安装成功

shell
ps -ef |grep docker

正常情况下, 会出现 cri-docker 和 docker

设置开机启动:

shell
systemctl enable cri-docker

安装 kubeadm 和 kubelet

在所有节点上安装 kubeadm、kubectl 和 kubelet 组件。 但这些软件包未包含在系统默认软件源中,需要额外配置APT软件源,

配置阿里云的软件源:

shell
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
shell
echo "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
  • 查看源的位置
shell
ls /etc/apt/sources.list.d
  • 更新索引
shell
apt update

安装指定版本 kubeadm、kubectl 和 kubelet

shell
apt-get update
shell
apt-get install -y kubectl=1.32.0-1.1 kubeadm=1.32.0-1.1 kubelet=1.32.0-1.1

仅设置开机启动

kubeadmkubectl 仅是一个集群搭建工具和管理工具,不涉及启动。而 kubelet 是一个守护进程程序,由 kubeadm 在搭建过程中自动启动,这里仅设置开机启动即可:

shell
systemctl enable kubelet

部署 Master 节点

在 Master 节点执行以下命令初始化 Kubernetes 管理节点:

shell
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 插件。

紧接着,输出初始化成功的信息:

xml
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

根据上述提示,执行以下命令开始使用集群:

shell
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 集群。

shell
kubeadm join 192.168.100.81:6443 --token qrbzfp.g5kd35d6oolcfi0w \
        --discovery-token-ca-cert-hash sha256:fb1573641c774b5be0880221e43b37432b6a788d46470d90ae57e96784a076e4

部署 Node 节点

日志中出现的 kubeadm join 日志, 在工作节点上执行, 例如下面语句, 表示将工作几点添加到 Master 节点, 后面需要带上 --cri-socket,以将这些工作节点加入到集群中:

shell
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 命令。

shell
unzip calico-operator.zip

安装 Calico 网络插件

shell
kubectl create -f tigera-operator.yaml
shell
kubectl create -f custom-resources.yaml

查看 Pod 对象

shell
kubectl get pods -n calico-system

结果呈现如下:

xml
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的资源文件(或者上传镜像包):

shell
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

将 Service 的类型设置为 “NodePort” 类型并指定访问端口,以便将其暴露到集群外部访问,修改如下:

shell
vi recommended.yaml
shell
kind: 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

在集群中创建资源

shell
kubectl apply -f kubernetes-dashboard.yaml

查看Pod对象

shell
kubectl get pods -n kubernetes-dashboard

所有 Pod 的状态都显示为 “Running”,说明 Dasboard 安装成功。浏览器访问 “https://<节点IP地址>:30001 ”, 将看到登录界面,如图所示

创建一个服务账号并授予集群管理员权限

shell
kubectl create serviceaccount admin-user -n kubernetes-dashboard
kubectl create clusterrolebinding admin-user --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user

根据服务账号创建Token

shell
kubectl create token admin-user -n kubernetes-dashboard

输入 token 登录后可查看节点信息