本文中,介绍了使用 Kubeadm 部署具有一个主节点和两个工作节点的 kubernetes 集群的分步指南。
Kubeadm 是一个优秀的工具,可以在更短的时间内建立一个有效的 kubernetes 集群。它在设置所有 kubernetes 集群组件方面完成了所有繁重的工作。此外,它还遵循 kubernetes 集群的所有配置最佳实践。
什么是 Kubeadm?
Kubeadm 是一个无需复杂配置即可设置最小可行 Kubernetes 集群的工具。此外,Kubeadm 通过运行一系列预检查来简化整个过程,以确保服务器具有运行 Kubernetes 所需的所有基本组件和配置。它由官方 Kubernetes 社区开发和维护。还有其他选项,如 minikube、kind 等,它们非常容易部署。
Kubeadm 设置先决条件
以下是 Kubeadm Kubernetes 集群设置的先决条件。
- 至少两个 Ubuntu 节点 [一个主节点和一个工作节点]。您可以根据需要拥有更多工作器节点。
- 主节点应至少具有 2 个 vCPU 和 2GB RAM。
- 对于工作节点,建议至少使用 1 个 vCPU 和 2 GB RAM。
- 10.X.X.X/X 网络范围,具有主节点和工作节点的静态 IP。我们将使用 192.x.x.x 系列作为 Calico 网络插件将使用的 pod 网络范围。确保节点 IP 范围和 Pod IP 范围不重叠。
注意:如果要在代理后面的企业网络中设置集群,请确保设置代理变量并有权访问容器注册表和 docker hub。或者与您的网络管理员联系,将 registry.k8s.io 列入白名单,以提取所需的映像。
Kubeadm 端口要求
请参考下图,并确保控制平面(主节点)和工作节点允许所有端口。如果您正在部署 kubeadm 集群云服务器,请确保在防火墙配置中允许这些端口。
如果使用的是基于 vagrant 的 Ubuntu VM,则默认情况下将禁用防火墙。因此,您不必进行任何防火墙配置。
Vagrantfile、Kubeadm 脚本和清单
此外,本指南中用于主节点和工作节点配置的所有命令都托管在 GitHub 中。您可以克隆存储库以供参考。
git clone https://github.com/techiescamp/kubeadm-scripts
本指南旨在让您了解 Kubeadm 设置所需的每个配置。如果不想逐个运行命令,可以直接运行脚本文件。
使用 Kubeadm 部署 Kubernetes 集群
以下是设置基于 kubeadm 的 Kubernetes 集群所涉及的步骤。
- 在所有节点上安装容器运行时 - 我们将使用 cri-o。
- 在所有节点上安装 Kubeadm、Kubelet 和 kubectl。
- 在主节点上启动 Kubeadm 控制平面配置。
- 使用 Token 保存 node join 命令。
- 安装 Calico 网络插件。
- 使用 join 命令将工作节点加入主节点(控制平面)。
- 验证所有群集组件和节点。
- 安装 Kubernetes Metrics Server
- 部署示例应用并验证应用
本指南中给出的所有步骤都参考了 Kubernetes 官方文档和相关的 GitHub 项目页面。
现在让我们开始部署。
在所有节点上启用 iptables 桥接流量
在 IPtables 的所有节点上执行以下命令,以查看桥接的流量。在这里,我们将调整一些内核参数并使用 sysctl
进行设置。
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOFsudo modprobe overlay
sudo modprobe br_netfilter# sysctl params required by setup, params persist across reboots
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# Apply sysctl params without reboot
sudo sysctl --system
在所有节点上禁用 swap
要使 kubeadm 正常工作,您需要使用以下命令在所有节点上禁用交换。
sudo swapoff -a
(crontab -l 2>/dev/null; echo "@reboot /sbin/swapoff -a") | crontab - || true
该条目将确保交换在系统重新启动时处于关闭状态。fstab
您还可以使用 kubeadm 参数控制交换错误,我们将在后半部分中介绍它。--ignore-preflight-errors Swap
注意:从 1.28 开始,kubeadm 支持在 kubeadm 集群中使用 swap。阅读本文以了解更多信息。
在所有节点上安装 CRI-O 运行时
Kubernetes 集群的基本要求是容器运行时。可以具有以下任何一个容器运行时。
- CRI-O
- containerd
- Docker Engine
对于此设置,我们将使用 CRI-O 而不是 Docker,因为 Kubernetes 已弃用 Docker 引擎
作为第一步,我们需要在所有节点上安装。在所有节点上执行以下命令。cri-o
为版本 1.28 启用 cri-o 存储库
OS="xUbuntu_22.04"VERSION="1.28"cat <<EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /
EOF
cat <<EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /
EOF
将 CRI-O 的 GPG 密钥添加到系统的受信任密钥列表中。
curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -
更新并安装 crio 和 crio-tools。
sudo apt-get update
sudo apt-get install cri-o cri-o-runc cri-tools -y
重新加载 systemd 配置并启用 cri-o。
sudo systemctl daemon-reload
sudo systemctl enable crio --now
cri-tools 包含 crictl
,这是一个 CLI 实用程序,用于与容器运行时创建的容器进行交互。使用 Docker 以外的容器运行时时,可以使用 crictl 实用程序调试节点上的容器。此外,它在需要调试容器的 CKS 认证中也很有用。
在所有节点上安装 Kubeadm & Kubelet & Kubectl
安装所需的依赖项。
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
下载 Kubernetes APT 存储库的 GPG 密钥。
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
将 Kubernetes APT 存储库添加到您的系统。
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
更新 apt 存储库
sudo apt-get update -y
您可以使用以下命令查找最新版本。
sudo apt update
apt-cache madison kubeadm | tac
指定版本,如下所示。
sudo apt-get install -y kubelet=1.28.2-00 kubectl=1.28.2-00 kubeadm=1.28.2-00
或者,若要从存储库安装最新版本,请使用以下命令,而不指定任何版本。
sudo apt-get install -y kubelet kubeadm kubectl
为包添加保留以防止升级。
sudo apt-mark hold kubelet kubeadm kubectl
现在,我们已经拥有了使用 kubeadm 配置 Kubernetes 组件所需的所有实用程序和工具。
将节点 IP 添加到 .KUBELET_EXTRA_ARGS
sudo apt-get install -y jq
local_ip="$(ip --json a s | jq -r '.[] | if .ifname == "eth1" then .addr_info[] | if .family == "inet" then .local else empty end else empty end')"
cat > /etc/default/kubelet << EOF
KUBELET_EXTRA_ARGS=--node-ip=$local_ip
EOF
在主节点上初始化 kubeadm 以设置控制平面
在这里,您需要考虑两种选择。
- 具有私有 IP 的主节点:如果您的节点只有私有 IP 地址,则将通过主节点的私有 IP 访问 API 服务器。
- 具有公共 IP 的主节点: 如果您在云平台上设置 Kubeadm 集群,并且需要通过主节点服务器的公共 IP 访问主 Api 服务器。
只有 Kubeadm 初始化命令对于公共 IP 和私有 IP 有所不同。
仅在主节点上执行本节中的命令。
如果您为主节点使用私有 IP,
设置以下环境变量。替换为主节点的 IP 10.0.0.10
IPADDR="10.0.0.10"
NODENAME=$(hostname -s)
POD_CIDR="192.168.0.0/16"
如果要使用主节点的公有 IP,
设置以下环境变量。IPADDR 变量将使用 curl 调用自动设置为服务器的公共 IP。还可以将其替换为公共 IP 地址ifconfig.me
IPADDR=$(curl ifconfig.me && echo "")
NODENAME=$(hostname -s)
POD_CIDR="192.168.0.0/16"
现在,使用 kubeadm 命令初始化主节点控制平面配置。
对于基于私有 IP 地址的设置,请使用以下 init 命令。
sudo kubeadm init --apiserver-advertise-address=$IPADDR --apiserver-cert-extra-sans=$IPADDR --pod-network-cidr=$POD_CIDR --node-name $NODENAME --ignore-preflight-errors Swap
--ignore-preflight-errors Swap
实际上不是必需的,因为我们最初禁用了交换。
对于基于公共 IP 地址的设置,请使用以下 init 命令。
在这里,我们使用 API 服务器端点的参数来代替。 --apiserver-advertise-address
--control-plane-endpoint
sudo kubeadm init --control-plane-endpoint=$IPADDR --apiserver-cert-extra-sans=$IPADDR --pod-network-cidr=$POD_CIDR --node-name $NODENAME --ignore-preflight-errors Swap
所有其他步骤都与使用私有 IP 配置主节点相同。
在成功的 kubeadm 初始化后,您应该会得到一个带有 kubeconfig 文件位置的输出和带有令牌的 join 命令,如下所示。复制它并将其保存到文件中。我们将需要它来将工作节点连接到主节点。
使用输出中的以下命令创建 in master,以便您可以使用它与集群 API 进行交互。kubeconfig
kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
现在,通过执行以下 kubectl 命令来验证 kubeconfig,以列出命名空间中的所有 pod。kube-system
kubectl get po -n kube-system
您应看到以下输出。您将看到两个 Coredns Pod 处于挂起状态。这是预期的行为。一旦我们安装了网络插件,它就会处于运行状态
您可以使用以下命令验证所有群集组件运行状况。
kubectl get po -n kube-system
您可以使用以下命令获取集群信息。
kubectl get --raw='/readyz?verbose'
默认情况下,不会在主节点上计划应用。如果要使用主节点调度应用程序,请 taint 主节点。
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
安装用于 Pod 网络的 Calico 网络插件
Kubeadm 没有配置任何网络插件。您需要为 kubernetes pod 网络安装您选择的网络插件并启用网络策略。
我正在使用 Calico 网络插件进行此设置。
注意:请确保从配置文件的位置执行 kubectl 命令。从工作站的主站连接到 kubernetes API。
kubeconfig
执行以下命令,在集群上安装 Calico network plugin operator。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yamlcurl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml -Okubectl create -f custom-resources.yaml
几分钟后,如果检查命名空间中的 Pod,您将看到 calico Pod 和正在运行的 CoreDNS Pod。kube-system
将 Worker 节点加入 Kubernetes 主节点
我们还在工作节点上设置了 cri-o、kubelet 和 kubeadm 实用程序。
现在,让我们使用您在设置主节点时在输出中获得的 Kubeadm join 命令将工作节点加入主节点。
如果您错过了复制 join 命令,请在主节点中执行以下命令,以使用 join 命令重新创建令牌。
kubeadm token create --print-join-command
下面是该命令的样子。如果您以普通用户身份运行,请使用。此命令对节点执行 TLS 引导。sudo
sudo kubeadm join 10.128.0.37:6443 --token j4eice.33vgvgyf5cxw4u8i \--discovery-token-ca-cert-hash sha256:37f94469b58bcc8f26a4aa44441fb17196a585b37288f85e22475b00c36f1c61
成功执行后,您将看到输出显示“此节点已加入集群”。
现在从主节点执行 kubectl 命令,以检查节点是否已添加到主节点。
kubectl get nodes
示例输出,
root@master-node:/home/vagrant# kubectl get nodes
NAME STATUS ROLES AGE VERSION
controlplane Ready control-plane 14m v1.28.2
node01 Ready <none> 2m13s v1.28.2
node02 Ready <none> 2m5s v1.28.2
在上面的命令中,ROLE 用于工作节点。您可以使用以下命令向工作器节点添加标签。替换为要标记的工作器节点的主机名。<none>
worker-node01
kubectl label node worker-node01 node-role.kubernetes.io/worker=worker
您可以使用相同的 join 命令进一步添加更多节点。
设置 Kubernetes 指标服务器
Kubeadm 在初始化期间不会安装指标服务器组件。我们必须单独安装它。
为了验证这一点,如果运行 top 命令,您将看到错误。Metrics API not available
root@master-node:~# kubectl top nodes
error: Metrics API not available
要安装指标服务器,请执行以下指标服务器清单文件。它部署指标服务器版本v0.6.2
kubectl apply -f https://raw.githubusercontent.com/techiescamp/kubeadm-scripts/main/manifests/metrics-server.yaml
此清单取自官方指标 server repo。我已将该标志添加到容器中,使其在本地设置中工作并单独托管它。否则,您将收到以下错误。--kubelet-insecure-tls
because it doesn't contain any IP SANs" node=""
部署指标服务器对象后,您需要一分钟才能使用 top 命令查看节点和 Pod 指标。
kubectl top nodes
您应该能够查看节点指标,如下所示。
root@master-node:/home/vagrant# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master-node 111m 5% 1695Mi 44%
worker-node01 28m 2% 1078Mi 57%
worker-node02 219m 21% 980Mi 52%
您还可以使用以下命令查看 Pod CPU 和内存指标。
kubectl top pod -n kube-system
部署示例 Nginx 应用程序
现在我们已经拥有了使集群和应用程序工作的所有组件,让我们部署一个示例 Nginx 应用程序,看看我们是否可以通过 NodePort 访问它
创建 Nginx 部署。直接在命令行上执行以下命令。它将 Pod 部署在默认命名空间中。
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:selector:matchLabels:app: nginxreplicas: 2 template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:-
在 NodePort 32000 上公开 Nginx 部署
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector: app: nginxtype: NodePort ports:- port: 80targetPort: 80nodePort: 32000
EOF
使用以下命令检查 Pod 状态。
kubectl get pods
部署完成后,您应该能够在分配的 NodePort 上访问 Nginx 主页。
例如
可能的 kubeadm 问题
以下是您在 kubeadm 设置中可能遇到的问题。
- Pod 内存和 CPU 不足:主节点应至少具有 2 个 vCPU 和 2 GB 内存。
- 节点无法连接到主节点:检查节点之间的防火墙,并确保所有节点都可以在所需的 Kubernetes 端口上相互通信。
- Calico Pod 重新启动:有时,如果对节点和 Pod 网络使用相同的 IP 范围,则 Calico Pod 可能无法按预期工作。因此,请确保节点和 Pod 的 IP 范围不重叠。重叠的 IP 地址也可能导致群集上运行的其他应用程序出现问题。
如果服务器没有至少 2 个 vCPU,则会出现以下错误。
[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2
如果使用带参数的公有 IP,则主节点组件将出现故障,并显示以下错误。若要更正此错误,请将参数与公共 IP 地址一起使用。 --apiserver-advertise-address
--control-plane-endpoint
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'
在主节点重置后,当您尝试使用新令牌加入工作节点时,工作节点中会出现以下错误。要纠正此错误,请使用命令重置工作器节点。kubeadm reset
[ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists[ERROR Port-10250]: Port 10250 is in use[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists
Kubernetes 集群重要配置
以下是您应该了解的重要 Kubernetes 集群配置。
配置 | 位置 |
---|---|
静态 Pod 位置(etcd、api-server、控制器管理器和调度器) | /etc/kubernetes/manifests |
TLS 证书位置(kubernetes-ca、etcd-ca 和 kubernetes-front-proxy-ca) | /etc/kubernetes/pki |
Admin Kubeconfig 文件 | /etc/kubernetes/admin.conf |
Kubelet 配置 | /var/lib/kubelet/config.yaml |
有些配置是 Kubernetes 功能门控的一部分。如果要使用作为功能门控一部分的功能,则需要在 Kubeadm 初始化期间使用 kubeadm 配置文件启用它们。
Kubeadm 是如何工作的?
以下是 Kubeadm 设置的工作原理。
当您使用 Kubeadm 初始化 Kubernetes 集群时,它会执行以下操作。
- 初始化 kubeadm 时,首先它会运行所有预检检查以验证系统状态,然后从 registry.k8s.io 容器注册表下载所有必需的集群容器映像。
- 然后,它会生成所需的 TLS 证书,并将其存储在 /etc/kubernetes/pki 文件夹中。
- 接下来,它会在 /etc/kubernetes 文件夹中生成集群组件的所有 kubeconfig 文件。
- 然后,它启动 kubelet 服务,为所有集群组件生成静态 pod 清单,并将其保存在 /etc/kubernetes/manifests 文件夹中。
- 接下来,它从静态 Pod 清单启动所有控制平面组件。
- 然后安装核心 DNS 和 Kubeproxy 组件
- 最后,它生成节点引导令牌。
- 工作器节点使用此令牌加入控制平面。
如您所见,所有关键的集群配置都将出现在 /etc/kubernetes 文件夹下。
Kubeadm 常见问题
如何在 Kubeadm 中使用自定义 CA 证书?
默认情况下,kubeadm 会创建自己的 CA 证书。但是,如果您希望使用自定义 CA 证书,则应将它们放在 /etc/kubernetes/pki
文件夹中。当 kubeadm 运行时,如果找到现有证书,它将使用它们,并且不会覆盖它们。
如何生成 Kubeadm Join 命令?
您可以使用 command 生成 join 命令。kubeadm token create --print-join-command
结论
在这篇文章中,我们学习了使用 kubeadm 逐步安装 Kubernetes。
此外,还有许多其他 Kubeadm 配置,我没有在本指南中介绍,因为它超出了本指南的范围。请参考 Kubeadm 官方文档。通过在 VM 中设置整个群集,可以了解所有群集组件配置,并在组件故障时对群集进行故障排除。