一、初始化(所有節點機器都要執行)
1. 關閉firewall防火墻
systemctl disable firewalld.service
systemctl stop firewalld.service
2. 關閉SELinux
臨時關閉
setenforce 0
永久關閉
vim /etc/selinux/config
SELINUX=enforcing
改成
SELINUX=disabled
3. 關閉Swap交換空間
vim /etc/fstab
,把
UUID=6ec4e75d-31c0-465c-b376-33ec3aa9c95f swap swap defaults 0 0
行注釋掉(不同機器下,swap的配置略有不同,只要認準第二列參數是swap的那行)
4. 規劃設置主機名
master
節點
hostnamectl set-hostname master
node節點(根據自己的機器情況,按需設置)
hostnamectl set-hostname node1
在hosts
文件中增加ip映射 vim /etc/hosts
(根據自己的虛擬機ip進行配置)
192.168.72.135 master
192.168.72.136 node1
192.168.72.137 node2
5. 確保網絡橋接的數據表經過iptables處理
確保網絡橋接的數據包經過iptables
處理,啟用相關的內核參數vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
sysctl --system
命令使之生效
二、安裝Docker(所有節點機器都要執行)
如果你之前安裝過 docker,請先刪掉
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
安裝依賴,下載 repo 文件,并把軟件倉庫地址替換為鏡像站:
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
最后安裝:
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
配置鏡像下載加速器和設置Cgroup驅動
{"registry-mirrors": ["https://dockerproxy.com","https://docker.mirrors.ustc.edu.cn","https://docker.nju.edu.cn"],"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl daemon-reload
使之生效
安裝cri-dockerd
(Docker與Kubernetes通信的中間程序)
https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.2/cri-dockerd-0.3.2-3.el7.x86_64.rpm
下載安裝包
安裝服務
rpm -ivh cri-dockerd-0.3.2-3.el7.x86_64.rpm
指定依賴鏡像地址為國內鏡像地址 vim /usr/lib/systemd/system/cri-docker.service
,修改文件中ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd://
所在行的內容如下所示
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9
systemctl daemon-reload
使之生效
設置開機啟動systemctl enable cri-docker.service
啟動服務systemctl start cri-docker.service
三、部署Kubernetes集群(所有節點機器都要執行)
添加阿里云YUM軟件源vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=kubernetes
baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/yum/repos/kubernetes-el7-$basearch
name=Kubernetes
baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/core:/stable:/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
安裝kubeadm
、kubelet
、kubectl
,版本選擇1.28.0
yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0
設置kubelet
開機自啟動
systemctl enable kubelet
四、初始化Kubernetes各節點
1. 初始化節點
初始化Master節點(在Master機器節點上執行)
kubeadm init --apiserver-advertise-address=192.168.19.101 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.28.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock
執行成功后,會輸出下面的內容:
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/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou 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.19.101:6443 --token ayfht4.41uw0ls1j6c5zfj9 \--discovery-token-ca-cert-hash sha256:0d315022caa726e987bbad7b64cf92b781f9aa24a6ca7e972e985cdd90fcfcbd
根據提示,在Master節點執行一下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configexport KUBECONFIG=/etc/kubernetes/admin.conf
執行 kubectl get node
,正常情況下,可以看到當前集群中master節點的相關信息。
接下來,把Node節點加入到集群(在Node機器節點上執行)
kubeadm join 192.168.72.135:6443 --token vz8a67.xkfn0evy90dlcvbg \--discovery-token-ca-cert-hash sha256:bc3ffe75a72f4f5a9a014bbc082a5f38a50ec19eb7424d73ae45dc3a32c65bb7 --cri-socket=unix:///var/run/cri-dockerd.sock
Master節點查看集群的各節點狀態 kubectl get node
2. 安裝Flannel 網絡插件
當前使用kubectl get node
命令可以看到集群中所有節點,但是每個節點的狀態是NotReady,這是因為我們還需要安裝網絡插件。這里我們選擇安裝Flannel網絡插件。
下載 Flannel 配置文件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
修改 Flannel 配置文件
編輯 kube-flannel.yml 配置文件,確保 Network 字段使用你在 kubeadm init 時設置的 pod-network-cidr,例如:
network: "10.244.0.0/16"
將修改后的 kube-flannel.yml 上傳到 Kubernetes Master 節點。在 Master 節點上運行以下命令應用 Flannel 配置:
kubectl apply -f /root/kube-flannel.yml
驗證 Flannel 網絡插件
確保 Flannel 插件成功啟動,可以查看其 Pod 狀態:
kubectl get pods --all-namespaces
你應該看到類似以下的輸出,表示 Flannel 正常運行:
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-5l6qg 1/1 Running 0 5m
kube-flannel-ds-g9gdq 1/1 Running 0 5m
問題與解決方案
一、如何查看kubernetes的容器運行時是用的docker還是containerd
在 Kubernetes 中,容器運行時可以是 Docker、containerd 或其他兼容 OCI (Open Container Initiative) 標準的運行時。要確定 Kubernetes 集群中使用的容器運行時,可以通過以下幾種方法進行檢查:
1. 查看 kubelet 的配置
Kubernetes 的 kubelet 組件負責管理容器運行時的交互。你可以查看 kubelet 的配置來了解它使用的是哪種容器運行時。
對于 Docker:
-
查看 kubelet 的配置文件(通常位于 /var/lib/kubelet/config.yaml 或通過 --config 參數指定)。
-
查找 containerRuntimeEndpoint 配置項。例如:
containerRuntimeEndpoint: unix:///var/run/dockershim.sock
如果看到類似于這樣的配置,表示 kubelet 正在通過 dockershim 與 Docker 交互。
對于 containerd:
查看 containerRuntimeEndpoint 配置項。例如:
containerRuntimeEndpoint: unix:///run/containerd/containerd.sock
如果看到類似這樣的配置,表示 kubelet 直接與 containerd 交互。
2. 檢查容器運行時服務狀態
你可以檢查系統上運行的容器運行時服務來確定正在使用哪個。
對于 Docker:
sudo systemctl status docker
或者使用:
ps aux | grep dockerd
對于 containerd:
sudo systemctl status containerd
或者使用:
ps aux | grep containerd
3. 使用crictl 工具
crictl 是一個 CLI 工具,用于與容器運行時交互。你可以使用它來查看運行時信息。
- 首先,確保已安裝 crictl。如果沒有安裝,可以通過包管理器安裝,例如在 Ubuntu 上使用:
sudo apt-get install crictl
運行 crictl 來查看容器運行時信息:
crictl info
輸出中會包含運行時名稱和版本信息,例如:
Runtime Name: containerd
Runtime Version: 1.4.3
...
通過上述方法,你可以確定 Kubernetes 集群中使用的容器運行時是 Docker 還是 containerd。
二、解決 Kubernetes 拉取鏡像超時問題(即使 Docker 已配置鏡像加速器)
您遇到的情況是:雖然 Docker 已經配置了國內鏡像加速器,但使用 kubectl run
創建 Pod 時仍然出現連接 Docker Hub 超時的錯誤。這是因為 Kubernetes 和 Docker 的鏡像拉取機制有所不同。
問題根源
-
Kubernetes 不使用 Docker 的鏡像加速配置
- Kubernetes 默認使用 containerd 而不是直接使用 Docker
- 即使 Docker 配置了鏡像加速器,Kubernetes 可能仍會直接嘗試訪問 Docker Hub
-
containerd 需要單獨配置鏡像加速
- Kubernetes 1.20+ 默認使用 containerd 作為容器運行時
- containerd 的鏡像加速配置是獨立的
解決方案
方法1:為 containerd 配置鏡像加速器(推薦)
-
修改 containerd 配置:
sudo vim /etc/containerd/config.toml
-
在
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
部分添加國內鏡像源:[plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://registry.cn-hangzhou.aliyuncs.com", "https://docker.mirrors.ustc.edu.cn"]
-
重啟 containerd:
sudo systemctl restart containerd
方法2:使用 kubectl 時指定國內鏡像源
kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/library/nginx:latest
方法3:設置 Pod 的 imagePullPolicy
kubectl run nginx --image=nginx:latest --image-pull-policy=IfNotPresent
方法4:完全使用本地鏡像(測試環境)
kubectl run nginx --image=nginx:latest --image-pull-policy=Never
驗證配置是否生效
-
檢查 containerd 配置:
sudo crictl info | grep -A 10 "registry"
-
測試拉取鏡像:
sudo crictl pull nginx
其他可能需要的操作
-
檢查節點網絡連接:
ping registry.cn-hangzhou.aliyuncs.com curl -v https://registry.cn-hangzhou.aliyuncs.com
-
配置 Kubernetes 使用 Docker 而非 containerd(不推薦):
修改 kubelet 配置,但這通常不是最佳實踐。 -
使用私有鏡像倉庫:
如果經常遇到此類問題,可以考慮搭建本地鏡像倉庫緩存。
推薦的國內鏡像源
阿里云:https://registry.cn-hangzhou.aliyuncs.com
騰訊云:https://mirror.ccs.tencentyun.com
中科大:https://docker.mirrors.ustc.edu.cn
網易:https://hub-mirror.c.163.com
通過以上配置,您應該能夠解決 Kubernetes 拉取鏡像超時的問題。如果仍有問題,可能需要檢查節點的網絡防火墻設置或 DNS 配置。
三、Kubelet未指定容器運行時的連接斷點
執行crictl info
報錯:
WARN[0000] runtime connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
ERRO[0000] validate service connection: validate CRI v1 runtime API for endpoint "unix:///var/run/dockershim.sock": rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial unix /var/run/dockershim.sock: connect: no such file or directory"
問題分析
-
警告信息:
WARN[0000] runtime connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
此警告表明使用默認的端點來連接容器運行時,不過默認設置現已被棄用,你得手動設置端點。
-
錯誤信息:
ERRO[0000] validate service connection: validate CRI v1 runtime API for endpoint "unix:///var/run/dockershim.sock": rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial unix /var/run/dockershim.sock: connect: no such file or directory"
該錯誤顯示在嘗試連接
unix:///var/run/dockershim.sock
時,系統找不到/var/run/dockershim.sock
文件。dockershim
是 Kubernetes 早期用于與 Docker 通信的組件,在 Kubernetes v1.24 及之后的版本中已被移除。
解決辦法
1. 確認 Kubernetes 版本
若你使用的是 Kubernetes v1.24 及之后的版本,dockershim
已被移除,你需要采用其他容器運行時,例如 containerd
或者 cri-o
。
2. 配置使用 containerd
若你打算使用 containerd
,可以按以下步驟操作:
- 保證
containerd
已經安裝并正在運行。 - 對 kubelet 配置文件進行修改,使其使用
containerd
作為容器運行時。一般而言,你需要在kubelet
的配置文件(通常是/var/lib/kubelet/config.yaml
)里添加如下配置:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
containerRuntimeEndpoint: “unix:///run/containerd/containerd.sock”
- 重新啟動
kubelet
服務:
sudo systemctl restart kubelet
3. 配置使用 cri-o
若你打算使用 cri-o
,可以按以下步驟操作:
- 保證
cri-o
已經安裝并正在運行。 - 對 kubelet 配置文件進行修改,使其使用
cri-o
作為容器運行時。在kubelet
的配置文件(通常是/var/lib/kubelet/config.yaml
)里添加如下配置:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
containerRuntimeEndpoint: unix:///run/crio/crio.sock
- 重新啟動
kubelet
服務:
sudo systemctl restart kubelet
補充
crictl
有自己的配置文件,你需要確保該配置文件中指定的端點與你修改的 kubelet
配置文件中的端點一致。
檢查并修改 crictl 配置文件
crictl
的配置文件通常位于 /etc/crictl.yaml
。你可以使用以下命令查看并修改該文件:
sudo vi /etc/crictl.yaml
確保文件內容如下:
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
四、如果設置isabled_plugins = [“cri”],kubectl run nginx --image=nginx是不是就無法拉取鏡像?
是的,如果在 containerd
的配置文件 /etc/containerd/config.toml
中設置了 disabled_plugins = ["cri"]
,使用 kubectl run nginx --image=nginx
命令將無法拉取鏡像并創建容器,下面為解釋原因:
1. Kubernetes 與容器運行時的交互機制
Kubernetes 是一個容器編排系統,它本身并不直接管理容器,而是通過 CRI(Container Runtime Interface)與容器運行時(如 containerd
)進行通信。CRI 定義了一套標準的接口,使得 Kubernetes 能夠對容器運行時進行通用化的操作,比如創建、啟動、停止容器以及拉取鏡像等。
2. disabled_plugins = ["cri"]
的影響
containerd
作為一個容器運行時,提供了 CRI 插件以支持與 Kubernetes 的集成。當你在 containerd
的配置文件中設置 disabled_plugins = ["cri"]
時,意味著 containerd
在啟動過程中不會加載 CRI 插件。這就切斷了 Kubernetes 與 containerd
之間基于 CRI 的通信渠道。
3. 執行 kubectl run nginx --image=nginx
的結果
當你執行 kubectl run nginx --image=nginx
命令時,Kubernetes 會嘗試創建一個使用 nginx
鏡像的 Pod。此時,Kubernetes 需要通過 CRI 向 containerd
發送拉取鏡像和創建容器的請求。但由于 containerd
的 CRI 插件已被禁用,Kubernetes 無法與 containerd
建立有效的通信,也就無法觸發鏡像拉取和容器創建的操作。
4. 現象表現
在 Kubernetes 集群中,你會觀察到以下現象:
- Pod 狀態:新創建的 Pod 會一直處于
Pending
狀態,因為 Kubernetes 無法完成容器的創建。 - 事件信息:使用
kubectl describe pod <pod-name>
命令查看 Pod 的詳細信息時,可能會看到類似 “Failed to create pod sandbox” 或 “Failed to connect to container runtime” 的錯誤信息,這表明 Kubernetes 無法與容器運行時進行交互。
5. 總結
設置 disabled_plugins = ["cri"]
會導致 containerd
無法為 Kubernetes 提供 CRI 服務,從而使得 kubectl run nginx --image=nginx
這樣的命令無法拉取鏡像并創建容器。如果需要在 Kubernetes 集群中使用 containerd
作為容器運行時,應該確保 CRI 插件處于啟用狀態。