Kubernetes集群搭建全攻略:從零到Hero
最近想學學k8s,但是網上的資料一言難盡,各種互抄錯誤的文章,只在第一步——安裝,就遇到了很大問題,讓人望而卻步。本文將帶你一步步了解如何準備環境、配置服務器以及最終創建一個功能齊全的Kubernetes集群。
1. 準備工作
環境要求
推薦準備3臺服務器(or 虛擬機),搭建一主兩從架構
- 服務器要求(Master/Node 節點):
最低 2 核 CPU
2GB 以上內存(最好4GB)
20GB 以上磁盤空間(建議最少40GB,20GB只夠k8s本身的基礎服務)
服務器環境配置
?? 注意:下方操作必須在所有節點都執行一遍
修改主機名(建議)
每個節點執行一個
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2
關閉 swap(必須)
swapoff -a
sed -i '/swap/d' /etc/fstab
Kubernetes 需要確保調度的 Pod 運行在資源可預測的環境下,而 swap(交換空間)可能導致內存分配不穩定。因此,Kubernetes 要求禁用 swap,保證節點上的內存管理更加穩定。
關閉防火墻(可選)
建議關閉以避免端口問題
systemctl stop firewalld && systemctl disable firewalld
配置內核參數(必須)
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat <<EOF | 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 --system
br_netfilter
必須配置,否則 Kubernetes 的網絡流量管理可能無法正常工作。
作用
br_netfilter
讓 Linux 處理橋接網絡流量時應用 iptables 規則
- Kubernetes 依賴
iptables
進行網絡策略、NAT 和轉發規則的管理。默認情況下,Linux 不會對網橋流量(bridge traffic)應用iptables
規則,因此需要手動啟用。
- 啟用 IPv4 轉發
- 默認情況下,Linux 可能不允許 IPv4 轉發(
net.ipv4.ip_forward=1
)。但 Kubernetes 依賴 IP 轉發功能,確保 Pod 網絡可以跨節點通信。
配置containerd(建議)
?? 注意:如果用containerd作為k8s的容器,必須配置
- 確保主機已經安裝了
containerd
,并確保containerd
正在運行
systemctl status containerd
如果沒有安裝,可以參考如下文章,安裝完docker之后,會自帶containerd
,并且服務器使用Docker的情況較多,推薦直接安裝docker
- 修改 containerd 配置文件
生成默認配置:
containerd config default | tee /etc/containerd/config.toml
**編輯 /etc/containerd/config.toml
**:
vi /etc/containerd/config.toml
- 找到并修改如下內容:
- 把
sandbox_image = "k8s.gcr.io/pause:3.8"
修改成sandbox_image = "registry.k8s.io/pause:3.10"
- k8s 版本為1.32.2,對應 pause:3.10
- 啟用 CRI 插件(確保
[plugins."io.containerd.grpc.v1.cri"]
沒有被注釋) - 修改
SystemdCgroup = true
(重要!否則 K8s 可能不兼容) - 修改
sandbox_image
- 在如下位置
[plugins."io.containerd.grpc.v1.cri"]
...
sandbox_image = "registry.k8s.io/pause:3.10"
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
重啟 containerd
systemctl restart containerd
配置 crictl.yaml
(必須)
需要手動指定 containerd
的 CRI socket,配置 containerd
連接k8s
創建或編輯 /etc/crictl.yaml
文件:
cat <<EOF | tee /etc/crictl.yaml
runtime-endpoint: "unix:///run/containerd/containerd.sock"
EOF
重啟 containerd
systemctl restart containerd
2.安裝kubeadm
Master 節點需要安裝 kubeadm
、kubelet
、kubectl
Node 節點,需要安裝 kubeadm
、kubelet
安裝 kubeadm
、kubelet
、kubectl
(確保版本一致):
以下指令適用于 Kubernetes 1.32
- 更新
apt
包索引并安裝使用 Kubernetesapt
倉庫所需要的包
# 更新軟件包索引
sudo apt-get update
# apt-transport-https 可能是一個虛擬包(dummy package);如果是的話,你可以跳過安裝這個包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
- 下載用于 Kubernetes 軟件包倉庫的公共簽名密鑰。所有倉庫都使用相同的簽名密鑰,因此你可以忽略URL中的版本:
# 如果 `/etc/apt/keyrings` 目錄不存在,則應在 curl 命令之前創建它
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
- 添加 Kubernetes
apt
倉庫。請注意,此倉庫僅包含適用于 Kubernetes 1.32 的軟件包;對于其他 Kubernetes 次要版本,則需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本
# 此操作會覆蓋 /etc/apt/sources.list.d/kubernetes.list 中現存的所有配置。
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
- 更新
apt
包索引,安裝 kubelet、kubeadm 和 kubectl,并鎖定其版本:
Master節點需要安裝 kubectl
# Master節點
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# 鎖定版本
sudo apt-mark hold kubelet kubeadm kubectl
node節點不需要安裝 kubectl
sudo apt-get update
sudo apt-get install -y kubelet kubeadm
# 鎖定版本
sudo apt-mark hold kubelet kubeadm
3. 使用 kubeadm 創建集群
注意:此操作只需要在Master節點執行
一、創建kubeadm-config.yaml
配置文件,寫入如下內容:
# k8s 集群配置
apiVersion:kubeadm.k8s.io/v1beta4
kind:ClusterConfiguration
# 安裝的 Kubernetes 版本
kubernetesVersion:1.32.0
# 單主節點可修改為主節點的 IP,端口不要修改
# 多主節點 應設置為 VIP 或負載均衡地址
controlPlaneEndpoint:192.168.204.128:6443
networking:
# 指定pod網段
podSubnet:10.244.0.0/16
# 指定Service網段
serviceSubnet:10.96.0.0/12
etcd:
local:
dataDir:"/var/lib/etcd"
controllerManager:{}
scheduler:{}
---
# kubeadm 初始化配置
apiVersion:kubeadm.k8s.io/v1beta4
kind:InitConfiguration
# 控制當前 master 節點上的 kube-apiserver 監聽 IP 和端口,只影響當前節點。
localAPIEndpoint:
# 設為當前master節點ip地址
advertiseAddress:192.168.204.128
bindPort:6443
nodeRegistration:
# 你的主節點名稱
name:"master"
# containerd 的默認 socket
criSocket:"unix:///run/containerd/containerd.sock"
taints:null
---
apiVersion:kubelet.config.k8s.io/v1beta1
kind:KubeletConfiguration
cgroupDriver:"systemd"
---
# kube-proxy 配置
apiVersion:kubeproxy.config.k8s.io/v1alpha1
kind:KubeProxyConfiguration
# 采用 IPVS 模式(更高效)
mode:"ipvs"
二、使用配置文件,初始化集群
初始化集群之前,可以先執行預檢,檢驗環境是否還有其他問題。
kubeadm init phase preflight --config kubeadm-config.yaml
會提示你可以先將k8s需要的鏡像拉取下來
kubeadm config images pull
如果沒有問題了,就可以執行初始化命令,初始化集群
kubeadm init --config=kubeadm-config.yaml --upload-certs
之后就可以看到執行成功的命令
而且他還提示你接下來需要執行的操作
圖片
圖片
4. 完成k8s集群搭建
接下來,你需要完成 幾個關鍵步驟 來讓 Kubernetes 集群正常工作:
1)配置 kubectl
訪問集群
配置kubectl的配置文件,相當于對kubectl進行授權,這樣kubectl命令可以使用此證書對k8s集群進行管理 所有控制節點創建成功后 均執行此命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
然后測試 kubectl
是否能正常連接集群:
kubectl get nodes
如果輸出 NotReady
,表示還需要部署 網絡插件。
例:
root@master:~# export KUBECONFIG=/etc/kubernetes/admin.conf
root@master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 6m10s v1.32.2
2)部署 Pod 網絡插件
Kubernetes 默認不包含 CNI(容器網絡接口)插件,你需要選擇一個來管理 Pod 網絡。
選擇使用 Calico 網絡插件,相比于 Flannel 更高效
這里k8s 集群的版本是 v1.32.2
,對應 Calico 的版本是 v3.29.2
其他版本對照參照:System requirements | Calico Documentation
文件地址是 https://raw.githubusercontent.com/projectcalico/calico/<版本號>/manifests/calico.yaml
wget -O calico.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/calico.yaml
kubectl apply -f calico.yaml
之后,檢查網絡插件是否正常運行:
kubectl get pods -n kube-system
等待 calico-node
的 Pod 變為 Running
狀態。
狀態變化:Pending
--> Init:0/3
--> Running
;這個過程可能需要數分鐘時間
3) 添加Node節點
確保已經在 Node 節點上安裝了 kubelet 和 kubeadm,并且 kubelet 是自啟動的
sudo systemctl enable --now kubelet
在 192.168.204.129 和 192.168.204.130 分別執行如下命令,就是在Master節點安裝完成之后提示的命令
kubeadm join 192.168.204.128:6443 --token emjun9.wvgusblbismxmczb \
--discovery-token-ca-cert-hash sha256:93811b04fda229a7560da0473bae1515d4f54f3f6ac9c074177e90b249ab46be
如果沒有保存命令,可以在master節點執行命令,重新生成
kubeadm token create --print-join-command
4. 驗證集群是否正常運行
執行以下命令,確認所有節點和組件都 Ready
:
kubectl get nodes
kubectl get pods -n kube-system
如果所有 Node
變成 Ready
,并且 kube-system
里的 Pod
狀態都變為 Running
,說明 Kubernetes 集群已經完全運行 ??!
剛加入集群時,可能會有 calico-node
在初始化狀態中,等待即可
完成后,你的 Kubernetes 集群就有 1 Master + 2 Node,正式可用了!
可選
root@master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 33m v1.32.2
node1 Ready <none> 12s v1.32.2
node2 Ready <none> 2m58s v1.32.2
node1
和 node2
在 kubectl get nodes
輸出中,ROLES
顯示為空,這是正常的,只是它們還沒有被賦予特定的角色。
默認情況下,kubeadm join
只是將它們加入集群為 Worker 節點,并不會自動分配角色。節點可以正常運行 Pod,不會影響集群功能。
如果你希望 kubectl get nodes
結果中顯示 worker
,可以給 node1
和 node2
添加 worker
角色:
kubectl label node node1 node-role.kubernetes.io/worker=
kubectl label node node2 node-role.kubernetes.io/worker=
然后再運行:
kubectl get nodes
現在 ROLES
列會顯示 worker
。