一、初始化(所有节点机器都要执行)
1. 关闭firewall防火墙
arduino
systemctl disable firewalld.service
systemctl stop firewalld.service
2. 关闭SELinux
临时关闭
setenforce 0
永久关闭
vim /etc/selinux/config
ini
SELINUX=enforcing
改成
SELINUX=disabled
3. 关闭Swap交换空间
vim /etc/fstab
,把
UUID=6ec4e75d-31c0-465c-b376-33ec3aa9c95f swap swap defaults 0 0
行注释掉(不同机器下,swap的配置略有不同,只要认准第二列参数是swap的那行)
4. 规划设置主机名
master
节点
arduino
hostnamectl set-hostname master
node节点(根据自己的机器情况,按需设置)
arduino
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
ini
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
sysctl --system
命令使之生效
二、安装Docker(所有节点机器都要执行)
如果你之前安装过 docker,请先删掉
arduino
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站:
arduino
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
最后安装:
lua
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
配置镜像下载加速器和设置Cgroup驱动
json
{
"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://
所在行的内容如下所示
javascript
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
ini
[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
开机自启动
bash
systemctl enable kubelet
四、初始化Kubernetes各节点
1. 初始化节点
初始化Master节点(在Master机器节点上执行)
css
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
执行成功后,会输出下面的内容:
bash
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.19.101:6443 --token ayfht4.41uw0ls1j6c5zfj9 \
--discovery-token-ca-cert-hash sha256:0d315022caa726e987bbad7b64cf92b781f9aa24a6ca7e972e985cdd90fcfcbd
根据提示,在Master节点执行一下命令:
bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
执行 kubectl get node
,正常情况下,可以看到当前集群中master节点的相关信息。
接下来,把Node节点加入到集群(在Node机器节点上执行)
perl
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 配置文件
ruby
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 正常运行:
sql
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:
lua
sudo systemctl status docker
或者使用:
perl
ps aux | grep dockerd
对于 containerd:
lua
sudo systemctl status containerd
或者使用:
perl
ps aux | grep containerd
3. 使用crictl 工具
crictl 是一个 CLI 工具,用于与容器运行时交互。你可以使用它来查看运行时信息。
- 首先,确保已安装 crictl。如果没有安装,可以通过包管理器安装,例如在 Ubuntu 上使用:
arduino
sudo apt-get install crictl
运行 crictl 来查看容器运行时信息:
crictl info
输出中会包含运行时名称和版本信息,例如:
yaml
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 配置:
arduinosudo vim /etc/containerd/config.toml
-
在
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
部分添加国内镜像源:css[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 时指定国内镜像源
arduino
kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/library/nginx:latest
方法3:设置 Pod 的 imagePullPolicy
arduino
kubectl run nginx --image=nginx:latest --image-pull-policy=IfNotPresent
方法4:完全使用本地镜像(测试环境)
arduino
kubectl run nginx --image=nginx:latest --image-pull-policy=Never
验证配置是否生效
-
检查 containerd 配置:
perlsudo crictl info | grep -A 10 "registry"
-
测试拉取镜像:
sudo crictl pull nginx
其他可能需要的操作
-
检查节点网络连接:
arduinoping registry.cn-hangzhou.aliyuncs.com curl -v https://registry.cn-hangzhou.aliyuncs.com
-
配置 Kubernetes 使用 Docker 而非 containerd(不推荐): 修改 kubelet 配置,但这通常不是最佳实践。
-
使用私有镜像仓库: 如果经常遇到此类问题,可以考虑搭建本地镜像仓库缓存。
推荐的国内镜像源
arduino
阿里云: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
报错:
perl
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"
问题分析
-
警告信息:
perlWARN[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.
此警告表明使用默认的端点来连接容器运行时,不过默认设置现已被弃用,你得手动设置端点。
-
错误信息:
lessERRO[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
)里添加如下配置:
makefile
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
)里添加如下配置:
makefile
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
。你可以使用以下命令查看并修改该文件:
bash
sudo vi /etc/crictl.yaml
确保文件内容如下:
ruby
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 插件处于启用状态。