如何在 Debian 11 上使用 Kubeadm 设置 Kubernetes 集群
在此页
- 先决条件
- 设置系统
- 设置 /etc/hosts 文件
- 设置 UFW 防火墙
- 启用内核模块并禁用 SWAP
- 安装容器运行时:CRI-O
- 安装 Kubernetes 包
- 初始化 Kubernetes 控制平面
- 向 Kubernetes 添加工作节点
- 在 Kubernetes 集群上部署 Nginx Pod
- 结论
Kubernetes 或 k8s 是用于容器编排的开源平台,可自动部署、管理和扩展容器化应用程序。 Kubernetes 是谷歌创建的容器编排,现已成为开源项目,成为现代应用程序部署和计算平台的标准。
Kubernetes 是现代容器部署时代的解决方案。它提供服务发现和负载平衡、存储编排、自动推出和回滚、自我修复服务、秘密和配置管理。 Kubernetes 支持经济高效的云原生开发。
在本教程中,您将通过以下方式设置 Kubernetes 集群:
- 设置系统,包括 - 设置 /etc/hosts 文件、启用内核模块和禁用 SWAP。
- 通过添加 Kubernetes 和 CNI 插件 (Calico) 所需的一些端口来设置 UFW 防火墙。
- 安装 CRI-O 作为 Kubernetes 的容器运行时。
- 安装 Kubernetes 软件包,例如 kubelet、kubeadm 和 kubectl。
- 初始化一个控制平面节点并添加两个工作节点。
先决条件
要完成本教程,您需要满足以下要求:
- 三台或更多 Debian 11 服务器。
- 具有根/管理员权限的非根用户。
设置系统
在开始为 Kubernetes 部署安装任何包之前,您需要根据 Kubernetes 部署的要求设置所有系统。这包括以下配置:
- 设置正确的 /etc/hosts 文件:每个服务器主机名必须解析为正确的 IP 地址。这可以通过多种方式完成,但最简单的方式是在所有服务器上使用 /etc/hosts 文件。
- 设置 UFW 防火墙:对于生产环境,始终建议在控制平面和工作节点上启用防火墙。您将为 Kubernetes 控制平面、工作节点和 CNI 插件 Calico 设置 UFW 防火墙。
- 启用内核模块:Kubernetes 需要在 Linux 系统上启用一些内核模块。内核模块“overlay”和“br_netfilter”是让 iptables 看到桥接流量所必需的。
- 禁用 SWAP:这是强制性的,您必须在所有 Kubernetes 节点上禁用 SWAP,包括控制平面和工作节点。否则,kubelet 服务将运行有问题。
设置 /etc/hosts 文件
在第一步中,您将在所有服务器上设置系统主机名和 /etc/hosts 文件。对于此演示,我们将使用以下服务器。
Hostname IP Address Used as
--------------------------------------------
k8s-master 192.168.5.10 control-plane
k8s-worker1 192.168.5.115 worker node
k8s-worker2 192.168.5.116 worker node
在下面运行以下 hostnamectl 命令以在每台服务器上设置系统主机名。
对于控制平面节点,运行以下命令将系统主机名设置为“k8s-master”。
sudo hostnamectl set-hostname k8s-master
对于 Kubernetes 工作程序节点,运行以下 hostnamectl 命令。
# setup hostname k8s-worker1
sudo hostnamectl set-hostname k8s-worker1
# setup hostname k8s-worker2
sudo hostnamectl set-hostname k8s-worker2
接下来,使用以下命令编辑所有服务器上的 /etc/hosts 文件。
sudo nano /etc/hosts
将以下配置添加到文件中。确保每个主机名都指向正确的 IP 地址。
192.168.5.10 k8s-master
192.168.5.115 k8s-worker1
192.168.5.116 k8s-worker2
完成后保存并关闭文件。
最后,如果您对每个主机名运行 ping 命令,您将指向 /etc/hosts 文件中定义的正确 IP 地址。
ping k8s-master -c3
ping k8s-worker1
ping k8s-worker2 -c3
设置 UFW 防火墙
Kubernetes 需要在您的所有系统上打开一些端口。在默认的 Ubuntu 系统上,UFW 防火墙被用作默认防火墙。您将在所有 Debian 系统上安装 UFW 防火墙,并为 Kubernetes 部署添加一些 UFW 规则。
对于 Kubernetes 控制平面,您需要打开以下端口:
Protocol Direction Port Range Purpose Used By
-----------------------------------------------
TCP Inbound 6443 Kubernetes API server All
TCP Inbound 2379-2380 etcd server client API kube-apiserver, etcd
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 10259 kube-scheduler Self
TCP Inbound 10257 kube-controller-manager Self
对于 Kubernetes 工作节点,您需要打开以下端口:
Protocol Direction Port Range Purpose Used By
--------------------------------------------------
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 30000-32767 NodePort Services† All
在此示例中,我们将使用 Calico 作为 CNI(容器网络接口)插件。因此,您将在下面打开一些额外的端口:
Protocol Direction Port Range Purpose Used By
-------------------------------------------------------
TCP Bidirectional 179 Calico networking (BGP)
UDP Bidirectional 4789 Calico networking with VXLAN enabled
TCP Incoming 2379 etcd datastore
UDP Bidirectional 4789 flannel networking (VXLAN)
使用以下 apt 命令将 UFW 包安装到您的 Debian 服务器。输入Y确认安装,回车,开始安装。
sudo apt install ufw

接下来,使用以下命令将 OpenSSH 应用程序添加到防火墙。然后,启用 UFW 防火墙。当提示确认时,输入“y”以启用并运行 UFW 防火墙。
sudo ufw allow "OpenSSH"
sudo ufw enable

在控制平面节点“k8s-master”上,运行以下 ufw 命令打开端口。然后,检查并验证 UFW 规则。
Kubernetes 控制平面的防火墙规则。
sudo ufw allow 6443/tcp
sudo ufw allow 2379:2380/tcp
sudo ufw allow 10250/tcp
sudo ufw allow 10259/tcp
sudo ufw allow 10257/tcp
Calico CNI 插件的防火墙规则。
sudo ufw allow 179/tcp
sudo ufw allow 4789/udp
sudo ufw allow 4789/tcp
sudo ufw allow 2379/tcp
sudo ufw status

在工作节点 \k8s-worker1\ 和 \k8s-worker2\ 上,运行以下 ufw 命令打开一些端口。然后,检查 UFW 防火墙规则。
Kubernetes 工作节点的防火墙规则。
sudo ufw allow 10250/tcp
sudo ufw allow 30000:32767/tcp
Kubernetes 工作节点上 Calico 的防火墙规则。
sudo ufw allow 179/tcp
sudo ufw allow 4789/udp
sudo ufw allow 4789/tcp
sudo ufw allow 2379/tcp
sudo ufw status

启用内核模块并禁用 SWAP
Kubernetes 要求在所有服务器上启用内核模块“overlay”和“br_netfilter”。这将使 iptbales 看到桥接的流量。此外,您还需要启用端口转发并禁用 SWAP。
运行以下命令以启用内核模块 \overlay\ 和 \br_netfilter\。
sudo modprobe overlay
sudo modprobe br_netfilter
要使其永久化,请使用以下命令将配置文件创建到 \/etc/modules-load.d/k8s.conf\。这将允许 Linux 系统在系统引导期间启用内核模块。
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

接下来,使用以下命令创建所需的 systemctl 参数。
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
要在不重新启动的情况下应用新的 sysctl 配置,请使用下面的 sysctl 命令。您应该获得系统上的默认 sysctl 参数列表,并确保获得刚刚添加到文件 \k8s.conf\ 中的 sysctl 参数。
sudo sysctl --system

要禁用 SWAP,您需要对 \/etc/fstab\ 文件中的 SWAP 配置进行注释。这可以通过 sed(流编辑器)使用单个命令或手动编辑 /etc/fstab 文件来完成。
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
或者
sudo nano /etc/fstab
接下来,使用以下命令关闭当前会话的 SWAP。然后,使用 \free -m\ 命令验证 SWAP 是否关闭。您应该看到 SWAP 的值为“0”,这意味着它现在已禁用。
sudo swapoff -a
free -m

安装容器运行时:CRI-O
要设置 Kubernetes 集群,您必须在所有服务器上安装容器运行时,以便 Pod 可以运行。多个容器运行时可用于 Kubernetes 部署,例如 containerd、CRI-O、Mirantis Container Runtime 和 Docker Engine(通过 cri-dockerd)。
在此演示中,我们将使用“CRI-O”作为 Kubernetes 部署的容器。因此,您将在所有服务器、控制平面和工作节点上安装 CRI-O。
在安装 CRI-O 之前,运行下面的 apt 命令来安装基本包“gnupg2\”和“apt-transport-https\”。输入 Y 确认安装并按 ENTER。
sudo apt install gnupg2 apt-transport-https

现在为 CRI-O 安装创建一个新的环境变量。值为“Debian_11”的变量“$OS”和值为“1.24”的变量“$VERSION”。在此示例中,我们将为“Debian_11”系统安装 CRI-O 容器 v1.24(当前版本)。
export OS=Debian_11
export VERSION=1.24
运行以下命令为 Debian 11 系统添加 CRI-O 存储库。
echo "deb [signed-by=/usr/share/keyrings/libcontainers-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb [signed-by=/usr/share/keyrings/libcontainers-crio-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
运行以下命令为 CRI-O 存储库添加 GPG 密钥。
mkdir -p /usr/share/keyrings
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-archive-keyring.gpg
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-crio-archive-keyring.gpg

现在使用以下命令更新系统存储库并刷新包索引。您应该会看到 CRI-O 存储库已添加到 Debian 11 服务器。
sudo apt update

要安装 CRI-O 容器运行时,请运行以下 apt 命令。输入 Y 确认安装并按 ENTER,CRI-O 安装将开始。
sudo apt install cri-o cri-o-runc cri-tools

安装完成后,使用以下命令编辑 CRI-O 配置 \/etc/crio/crio.conf\。
sudo nano /etc/crio/crio.conf
在 \[crio.network]\ 部分,取消注释选项 \network_dir\ 和 \plugin_dir\。
# The crio.network table containers settings pertaining to the management of
# CNI plugins.
[crio.network]
# The default CNI network name to be selected. If not set or "", then
# CRI-O will pick-up the first one found in network_dir.
# cni_default_network = ""
# Path to the directory where CNI configuration files are located.
network_dir = "/etc/cni/net.d/"
# Paths to directories where CNI plugin binaries are located.
plugin_dirs = [
"/opt/cni/bin/",
]
完成后,保存并关闭文件。
接下来,使用以下命令编辑 CRI-O 网桥配置\/etc/cni/net.d/100-crio-bridge.conf\。
sudo nano /etc/cni/net.d/100-crio-bridge.conf
使用自定义子网更改 IP 地址的默认子网。此子网 IP 地址将用于 Kubernetes 集群上的 Pod。此外,您还需要确保子网 IP 地址与 CNI 插件上的 IP 地址配置相匹配。
在此示例中,我们将为 Kubernetes 集群上的 Pod 使用子网 IP 地址“10.42.0.0/24”。
...
"ranges": [
[{ "subnet": "10.42.0.0/24" }],
[{ "subnet": "1100:200::/24" }]
]
...
完成后保存并关闭文件。
接下来,运行以下 systemctl 命令以重新启动 CRI-O 服务并应用新的更改。
sudo systemctl restart crio
最后,启用 CRI-O 服务以在系统启动时运行。然后,检查并验证 CRI-O 服务状态。并且您应该看到 CRI-O 服务已启用,并且当前状态为正在运行。
sudo systemctl enable crio
sudo systemctl status crio

安装 Kubernetes 包
您已经安装了 CRI-O 容器运行时。现在您将在所有 Debian 系统上安装 Kubernetes 包。这包括用于引导 Kubernetes 集群的 kubeadm、Kubernetes 集群的主要组件 kubelet 以及用于管理 Kubernetes 集群的命令行实用程序 kubectl。
在此示例中,我们将使用 Kubernetes 提供的存储库安装 Kubernetes 包。因此,您会将 Kubernetes 存储库添加到所有 Debian 系统。
运行以下命令以添加 Kubernetes 存储库和 GPG 密钥。
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
更新并刷新您的 Ubuntu 存储库和包索引。
sudo apt update

更新完成后,使用以下 apt 命令安装 Kubernetes 包。输入 Y 确认安装,按 ENTER 继续,安装将开始。
sudo apt install kubelet kubeadm kubectl

安装完成后,运行以下命令固定当前版本的 Kubernetes 包。这将防止 Kubernetes 包自动更新并防止 Kubernetes 包之间的版本偏差。
sudo apt-mark hold kubelet kubeadm kubectl

初始化 Kubernetes 控制平面
您已经完成了部署 Kubernetes 集群的所有依赖项和要求。现在,您将通过首次初始化控制平面节点来启动 Kubernetes 集群。在此示例中,Kubernetes 控制平面将安装在 IP 地址为“192.168.5.10”的“k8s-master”服务器上。
在初始化 Control Plane 节点之前,运行以下命令来检查“br_netfilter”内核模块是否已启用。如果您从命令中获得输出,则意味着“br_netfilter”模块已启用。
lsmod | grep br_netfilter
接下来,运行以下命令以下载 Kubernetes 集群所需的映像。此命令将下载创建 Kubernetes 集群所需的所有容器镜像,例如 coredns、kube-api server、etcd、kube-controller、kube-proxy 和 pause 容器镜像。
sudo kubeadm config images pull

下载完成后,运行下面的“crictl”命令,查看“k8s-master”服务器上的可用镜像列表。您应该会看到将用于创建 Kubernetes 集群的图像列表。
sudo crictl images

接下来,运行以下“kubeadm init”命令在“k8s-master”服务器上初始化 Kubernetes 集群。这个节点“k8s-master”将自动被选为 Kubernetes 控制平面,因为这是第一次初始化集群。
此外,在此示例中,我们将 Pod 的网络指定为 \10.42.0.0/24\,这与 CRI-O 网桥配置相同的子网\/etc/cni/net.d/100 -crio-bridge.conf\.
\--apiserver-advertise-address\ 确定 Kubernetes API 服务器将在哪个 IP 地址中运行,这个例子使用内部 IP 地址“192.168.5.10”。
对于此处的“--cri-socket”选项,我们将 CRI 套接字指定为在“/var/run/crio/crio.sock 上可用的 CRI-O 容器运行时套接字” \”。如果您使用不同的 Container Runtime,那么您必须更改 socket 文件的路径,或者您可以删除此选项 \--cri-socket\ 因为 kubeadm 将检测 Container Runtime自动套接字。
sudo kubeadm init --pod-network-cidr=10.42.0.0/24 \
--apiserver-advertise-address=192.168.5.10 \
--cri-socket=unix:///var/run/crio/crio.sock
以下是在“k8s-master”服务器上初始化 Kubernetes 集群时的输出。

初始化完成后,您会看到诸如“您的 Kubernetes 控制平面已成功初始化!”之类的消息,以及一些用于设置 Kubernetes 凭据和部署 Pod 网络附加组件的重要输出消息,如何添加Kubernetes 集群的工作节点。

在开始使用“kubectl”工具管理 Kubernetes 集群之前,您需要设置 Kubernetes 凭据。运行以下命令以设置 Kubernetes 凭据。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
现在您可以使用 \kubectl\ 命令与您的 Kubernetes 集群交互。运行以下“kubectl”命令来检查 Kubernetes 集群信息。你应该看到 Kubernetes 控制平面和 coredns 正在运行。
kubectl cluster-info
要获取有关您的 Kubernetes 的完整信息,您可以使用选项 dump - so \kubectl cluster-info dump\。

Kubernetes 运行后,您将为 Kubernetes 集群设置 Calico CNI 插件。运行以下命令下载 Calico 清单文件 \calico.yaml\。然后,使用 nano 编辑器编辑文件 \calico.yaml\。
curl https://docs.projectcalico.org/manifests/calico.yaml -O
nano calico.yaml
取消注释配置“CALICO_IPV4POOL_CIDR”并将网络子网更改为“10.42.0.0/24”。此子网配置必须与 CRI-O 网桥配置和 Kubernetes 初始化期间使用“kubeadm init”命令的“--pod-network-cidr”配置相同的子网。
...
- name: CALICO_IPV4POOL_CIDR
value: "10.42.0.0/24"
...
完成后,保存并关闭文件。
接下来,运行下面的“kubectl”命令,使用自定义清单文件“calico.yaml”部署 Calico CNI 插件。此命令将为 Calico CNI 插件创建多个 Kubernetes 资源。此外,这将下载 Calico 图像并为 Calico 创建新的 Pod。
sudo kubectl apply -f calico.yml

现在运行下面的 kubectl 命令来检查 Kubernetes 集群上的可用 Pod。您应该会看到两个额外的 Pod \calico-node-xxx\ 和 \calico-kube-controller-xxx\。
kubectl get pods --all-namespaces

向 Kubernetes 添加工作节点
在“k8s-master”服务器上初始化 Kubernetes 控制平面后,您将向 Kubernetes 集群添加工作节点“k8s-worker1”和“k8s-worker2”。
移至“k8s-worker1”服务器并运行下面的“kubeadm join”命令以将“k8s-worker1”添加到 Kubernetes 集群。您可能有不同的令牌和 ca-cert-hash,您可以在初始化控制平面节点时在输出消息上看到此信息的详细信息。
kubeadm join 192.168.5.10:6443 --token dbgk8h.nwzqqp1v5aqif5fy \
--discovery-token-ca-cert-hash sha256:7a543a545585358b143ce3e8633a8d673b6f628c5abc995939a58606c6dd219c
在以下输出中,您可以看到“k8s-worker1”服务器已加入 Kubernetes 集群。

接下来,移动到“k8s-worker2”服务器并运行“kubeadm join”命令将“k8s-worker2”添加到 Kubernetes 集群。
kubeadm join 192.168.5.10:6443 --token dbgk8h.nwzqqp1v5aqif5fy \
--discovery-token-ca-cert-hash sha256:7a543a545585358b143ce3e8633a8d673b6f628c5abc995939a58606c6dd219c
该过程完成后,您将看到相同的输出消息。

现在回到控制平面服务器 k8s-master\ 并运行以下命令来检查 Kubernetes 集群上所有正在运行的 pod。您应该看到所有命名空间上的每个 Kubernetes 组件都有额外的 pod。
kubectl get pods --all-namespaces
或者
kubectl get pods -o wide --all-namespaces

最后,使用下面的 kubectl\ 命令检查并验证 Kubernetes 集群上的所有可用节点。您应该看到 cplane1\ 服务器作为 Kubernetes 控制平面运行,并且 \k8s-worker1\ 和 \k8s- worker2\ 服务器作为工作节点运行。
kubectl get nodes -o wide

在 Kubernetes 集群上部署 Nginx Pod
运行以下命令为 Nginx Web 服务器创建新的部署。在此示例中,我们将基于图像 \nginx:alpine\ 和两个副本创建新的 Nginx Pod。
kubectl create deployment nginx --image=nginx:alpine --replicas=2
现在创建一个新的服务类型“NodePort”,它将使用以下 kubectl 命令公开 Nginx 部署。此命令将创建一个名为 \nginx\ 的新 Kubernetes 服务,类型为 \NodePort\ 并为 Pod 公开端口 \80\。
kubectl create service nodeport nginx --tcp=80:80
接下来,运行以下 kubectl 命令来检查 Kubernetes 集群上正在运行的 pod 列表。您应该会看到两个 Nginx pod 正在运行。
kubectl get pods
现在使用以下命令检查 Kubernetes 上的可用服务列表。您应该看到 \nginx\ 服务类型 NodePort 在 Kubernetes 主机上公开了端口 \80\ 和端口 \31277\。服务 NodePort 将始终公开 30000-32767 范围内的端口。
kubectl get svc

运行下面的 curl 命令以访问您的 Nginx 部署。
curl k8s-worker1:31277
curl k8s-worker2:31277
下面是来自“k8s-worker1”节点的 index.html 源代码的输出。

下面是来自“k8s-worker2”节点的 index.html 代码。

结论
在本教程中,您已经完成了具有三个节点和 Debian 11 服务器的 Kubernetes 集群的部署。 Kubernetes 集群运行有一个控制平面和两个工作节点。它与 CRI-O 一起运行,作为 Kubernetes 集群的容器运行时,以及用于集群上 Pod 网络的 Calico CNI 插件。此外,您已成功在 Kubernetes 集群中部署了 Nginx Web 服务器。
您已完全配置 Kubernetes 集群,您可以开始将您的应用程序部署到 Kubernetes 集群或尝试安装 Kubernetes Dashboard 以了解有关您的 Kubernetes 环境的更多信息。