k8s容器编排技术实践------k8s的介绍及其整体运行架构
https://blog.csdn.net/xiaochenXIHUA/article/details/161011629
一、安装前的准备
1.1、安装规划
本文搭建最基础的k8s集群(即:1个master+2个work),具体的规划内容如下:
| 主机名称 | IP地址 | 集群角色 | 系统版本 |
|---|---|---|---|
| k8smaster | 192.168.1.135 | master | AlmaLinux-9.3 |
| k8swork1 | 192.168.1.136 | work1 | AlmaLinux-9.3 |
| k8swork2 | 192.168.1.137 | work2 | AlmaLinux-9.3 |
查看和修改Linux的主机名称
https://coffeemilk.blog.csdn.net/article/details/152363961
bash
#1-修改主机名称并让其生效(如:修改主机名称为【k8smaster】)
hostnamectl set-hostname k8smaster
systemctl restart systemd-hostnamed
exec bash
hostname
#2-给这三台服务器都配置本地的域名解析
cat >>/etc/hosts <<EOF
192.168.1.135 k8smaster
192.168.1.136 k8swork1
192.168.1.137 k8swork2
EOF




1.2、添加 overlay 和 br_netfilter 内核模块
需要在k8s的每台服务器上【添加 overlay 和 br_netfilter 内核模块】
bash
#1-添加 overlay 和 br_netfilter 内核模块命令
tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
#2-让添加的内核模块生效
modprobe overlay
modprobe br_netfilter

1.3、开启IPVS支持
bash
#1-开启IPVS支持命令(每台k8s服务器都要执行)
cat >/etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
nf_conntrack
EOF
#2-直接重启系统让开启的模块自动加载
reboot
#3-查看模块加载
lsmod | grep ip_vs


1.4、关闭防火墙与selinux
bash
#K8s集群每个节点都需要关闭防火墙、selinux、交换分区
#1-关闭防火墙与selinux
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
grubby --update-kernel ALL --args selinux=0
#2-关闭系统的交换分区
swapoff -a
cp /etc/fstab /etc/fstab.bak
cat /etc/fstab.bak | grep -v swap > /etc/fstab
#3-修改iptables设置,在【/etc/sysctl.conf】中添加如下内容
cat >>/etc/sysctl.conf<<EOF
vm.swappiness = 0
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
#4-让设置生效
sysctl -p
二、安装部署Containerd及其配置加速器
2.1、安装 Containerd与配置加速器
bash
#安装部署Containerd【每台k8s服务器都需要部署】
#1-安装Containerd
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum list | grep containerd
dnf install containerd.io -y
containerd -v
#2-生成containerd配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
#打开config.toml文件,找到如下内容:
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ''
#将config_path的值修改为如下:
config_path = '/etc/containerd/certs.d'
#3配置containerd镜像加速器
#3.1-# docker hub镜像加速
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."https://docker.1ms.run"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://docker.xuanyuan.me"]
capabilities = ["pull", "resolve"]
EOF
#3.2-registry.k8s.io镜像加速
mkdir -p /etc/containerd/certs.d/registry.k8s.io
tee /etc/containerd/certs.d/registry.k8s.io/hosts.toml << 'EOF'
server = "https://registry.k8s.io"
[host."https://k8s.1ms.run"]
capabilities = ["pull", "resolve", "push"]
[host."https://registry.aliyuncs.com/google_containers"]
capabilities = ["pull", "resolve", "push"]
[host."https://k8s.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
[host."https://k8s.chenby.cn"]
capabilities = ["pull", "resolve", "push"]
EOF
#4-优化containerd配置文件【在国内实现加速拉取】
sed -i "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.toml
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
#5-启动Containerd并设置开机自启
systemctl daemon-reload && systemctl enable containerd && systemctl restart containerd
systemctl status containerd.service





2.2、安装Kubeadm、kubelet、kubectl工具
bash
#安装Kubeadm、kubelet、kubectl工具【k8s的每台服务器都需要配置】
#1-配置k8s的在线yum源仓库地址【若访问缓慢,可使用阿里云镜像站替代:https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/】
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
#2-安装 kubeadm、kubelet、kubectl(若要升级则需要先移除已安装内容,且【/etc/yum.repos.d/kubernetes.repo】里面的版本需要更新为对应的版本: yum remove -y kubelet kubeadm kubectl cri-tools kubernetes-cni)
yum install -y kubelet kubeadm kubectl cri-tools --disableexcludes=kubernetes
#3-启动kubelet并设置开机自启
systemctl daemon-reload && systemctl enable kubelet && systemctl start kubelet
#4-安装containerd命令行工具crictl配置【安装kubelet等工具的时候已经自动安装了crictl,要使用这个命令,还需要用crictl连接containerd进行如下配置】
cat >>/etc/crictl.yaml<<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
#查看所有镜像、正在运行镜像(critcl命令与docker命令使用方法一致)
crictl images
crictl ps



2.3、初始化k8s集群
bash
#初始化k8s集群【只用在一个节点配置就可以(一般是在master节点操作)】
#1-查看安装k8s的安装源和版本
kubeadm config print init-defaults
#2-查询需要的镜像(默认是从registry.k8s.io这个地址下载镜像)
kubeadm config images list
#3-在master节点配置kubeadm初始化文件
kubeadm config print init-defaults > kubeadm.yaml
#3.1-编辑【kubeadm.yaml】文件,修改其中的【advertiseAddress】【criSocket】【name】【imageRepository】 【kubernetesVersion】的值,同时,添加了kube-proxy的模式为ipvs,且需要注意的是,由于我们使用的containerd作为运行时,所以在初始化节点的时候需要指定cgroupDriver为systemd详细操作请看下面的表格
#4-在【kubeadm.yaml】文件所在路径进行初始化【注意:初始化成功后,一定要记录下最后的加入k8s集群命令,这个命令是用于将其他k8s节点加入到集群中:
#kubeadm join 192.168.1.135:6443 --token abcdef.0123456789abcdef \
# --discovery-token-ca-cert-hash sha256:13ff697a0ce60521a2888bd91af661917b696f8dda5ec646f634f5c3a4949598
systemctl status containerd.service
kubeadm init --config=kubeadm.yaml
#4.1-初始化完成后,根据提示,在master节点执行如下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#4.2-获取k8s集群下的所有节点【注意:查看k8s集群中的节点都是NotReady 状态,这是因为还没有安装网络插件,接下来会配置安装】
kubectl get nodes
#4.3-在其他k8s节点(如:192.168.1.136、192.168.1.137)中执行刚才在master节点下初始化成功后末尾的加入k8s集群命令即可将这些节点加入到集群中
##注意:在这里的--token来自前面kubeadm init输出提示,如果当时没有记录下来可以通过【kubeadm token create --ttl 0 --print-join-command】命令找回, token是有24小时有效期的:
kubeadm join 192.168.1.135:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:13ff697a0ce60521a2888bd91af661917b696f8dda5ec646f634f5c3a4949598
#4.4-为了使用更便捷,启用 kubectl 命令的自动补全功能
echo "source <(kubectl completion bash)" >> ~/.bashrc
exit
| kubeadm.yaml文件修改属性 | 说明 |
|---|---|
| advertiseAddress | 值配置k8s中的master节点所在服务器IP,可通过【ip a】命令获取 |
| criSocket | 值配置containerd.sock所在路径(默认是:unix:///var/run/containerd/containerd.sock); 可通过执行【find / -name containerd.sock】命令查找 |
| name | 值配置文件所在主机的名称,可通过【hostname】命令获取 |
| imageRepository | 值是镜像仓库地址(默认是【registry.k8s.io】; 国内可修改为【registry.aliyuncs.com/google_containers】) |
| kubernetesVersion | 值是版本信息,必须与我们安装的k8s组件版本一致,可通过【kubelet --version】或【kubeadm version】或【kubectl version】命令获取 |
| 指定kube-proxy的模式为ipvs | 在【kubeadm.yaml】文件末尾添加 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs |
| 指定cgroupDriver为systemd | 在【kubeadm.yaml】文件末尾添加: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd |









2.4、安装网络插件
网络插件可以选择【calico】和【flannel】;calico适合多节点大型复杂网络【推荐使用】,flannel适合小型网络。
bash
#Calico网络插件的下载安装
#1-下载Calico网络插件配置
wget https://docs.projectcalico.org/manifests/calico.yaml
#2-安装Calico网络插件
kubectl apply -f calico.yaml
#2.1-Calico网络插件的安装过程,需要下载三个镜像文件【docker.io/calico/cni】【docker.io/calico/node】【docker.io/calico/kube-controllers】(可通过【cat calico.yaml | grep image】命令查看到是这几个镜像),下载完成,网络插件即可正常工作。等网络插件镜像下载完成以后,看到node的状态会变成ready,执行如下命令查看:
crictl images
kubectl get nodes
#2.2-【可选】如果发现某个节点还是处于NotReady状态,可以重启此节点的kubelet服务,然后此节点就会重新下载需要的镜像。
systemctl restart kubelet
systemctl status kubelet
#2.3-查看pod状态
kubectl get pods -n kube-system
注意:calico插件在安装过程中,需要从docker.io下载3个镜像,目前ocker.io国内无法访问,若你配置了加速器还是无法访问的话,可以尝试如下操作:
bash
#解决calico插件在安装过程中下载不了calico镜像问题
#1、将calico.yaml中所有带有docker.io的镜像地址修改为加速器的地址,例如:
#找到 image: docker.io/calico/cni:v3.25.0
#修改为image: docker.1ms.run/calico/cni:v3.25.0
#2、其中【docker.1ms.run】是镜像加速器地址,此地址目前能用,但不保证一直能用,其它2个镜像都按照这个方法进行修改
#3、手动在节点服务器拉取calico所需的镜像
crictl pull docker.1ms.run/calico/cni:v3.25.0
crictl pull docker.1ms.run/calico/kube-controllers:v3.25.0
crictl pull docker.1ms.run/calico/node:v3.25.0
#4、最后在master节点服务器上再次执行部署插件命令
kubectl apply -f calico.yaml


2.5、验证k8s集群是否部署成功
bash
#创建一个标准的 Kubernetes Deployment 资源定义文件用来验证k8s集群是否安装成功
#1-创建一个名为 http-deployment 的 Deployment
#2-启动 3 个副本的 Nginx Pod
#3-使用标签 app: http_server 进行 Pod 管理
#4-容器镜像为官方仓库中的 nginx:v1.21.0
mkdir -p /data/k8s/verify && cd /data/k8s/verify
vi httptest.yml
#【httptest.yml】文件完整内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-deployment
spec:
replicas: 3
selector:
matchLabels:
app: http_server
template:
metadata:
labels:
app: http_server
spec:
containers:
- name: http-web
image: docker.1ms.run/library/nginx:1.28.3
ports:
- containerPort: 80
#在k8s的master节点上直接部署该服务
kubectl apply -f httptest.yml
#查看运行状态
kubectl get pods
#让外部网络可以访问到k8s集群内部的服务
vi service.yml
#【service.yml】
apiVersion: v1
kind: Service
metadata:
name: service-httpd
spec:
type: NodePort
selector:
app: http_server
ports:
- protocol: TCP
port: 8080
targetPort: 80
#创建service
kubectl apply -f service.yml
#查看service信息
kubectl get svc service-httpd
#最后在浏览器输入k8s集群的任意节点IP:端口即可访问到部署好的nginx服务,则表示k8s部署成功


到这里,恭喜你,k8s安装部署完成,且测试通过。
三、containerd中crictl与ctr
3.1、crictl与ctr简介
- ctr:是containerd本身的CLI;
- crictl :是Kubernetes社区定义的专门CLI工具;
【crictl】提供了类似于 docker 的命令行工具,不需要通过 Kubelet 就可以通过 CRI 跟容器运行时通信。它是专门为 Kubernetes 设计的,提供了Pod、容器和镜像等资源的管理命令,可以帮助用户和开发者调试容器应用或者排查异常问题。crictl 可以用于所有实现了 CRI 接口的容器运行时。
注意:crictl 并非 kubectl 的替代品,它只通过 CRI 接口与容器运行时通信,可以用来调试和排错,但并不用于运行容器。虽然 crictl 也提供运行 Pod 和容器的子命令,但这些命令仅推荐用于调试。
3.2、Crictl与docker命令对比
| 功能 | Docker | Containerd |
|---|---|---|
| 显示本地镜像列表 | docker images |
crictl images |
| 下载镜像 | docker pull |
crictl pull |
| 上传镜像 | docker push |
无 |
| 删除本地镜像 | docker rmi |
crictl rmi |
| 查看镜像详情 | docker inspect IMAGE-ID |
crictl inspect IMAGE-ID |
| 显示容器列表 | docker ps |
crictl ps |
| 创建容器 | docker create |
crictl create |
| 启动容器 | docker start |
crictl start |
| 停止容器 | docker stop |
crictl stop |
| 删除容器 | docker rm |
crictl rm |
| 查看容器详情 | docker inspect |
crictl inspect |
| attach | docker attach |
crictl attach |
| exec | docker exec |
crictl exec |
| logs | docker logs |
crictl logs |
| stats | docker stats |
crictl stats |
3.3、crictl与ctr的使用
containerd相比于docker , 多了namespace概念, 每个image和container都会在各自的namespace下可见, 目前Crictl会使用k8s.io作为命名空间,而ctr的默认命名空间是default。也就是说,使用ctr命令下载的镜像,不指定命名空间的话,使用Crictl工具是看不到的。
bash
#指定命名空间后,通过crictl命令是能看到下载的镜像的
ctr -n k8s.io images pull docker.1ms.run/library/redis:6.2.1
crictl images ls
#不指定命名空间,执行行【crictl images ls】命令是看不到的。因为ctr下载的镜像默认放到了default命名空间了。
ctr images pull docker.1ms.run/library/redis:6.2.1
crictl images ls
ctr images ls

bash
#注意:下面的标记镜像、导入、导出镜像都是通过ctr工具实现的,原因是crictl并没有这些功能。
#所以,在执行ctr命令时,都要指定命名空间,因为crictl默认的命名空间是k8s.io。
#标记镜像【-n表示namespace】【i表示image】【语法:ctr i tag 原名字 原名字】:
ctr -n k8s.io i tag docker.io/calico/cni:v3.25.0 ck/calico/cni:v3.25.0
#导出镜像:
ctr -n k8s.io i export calico-cni-v3.25.0.tar docker.io/calico/cni:v3.25.0
#导入镜像:
ctr -n k8s.io image import calico-cni-v3.25.0.tar