k8s容器编排技术实践——使用containerd作为容器运行时部署k8s集群

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
相关推荐
2301_780789663 小时前
手游遇到攻击为什么要用SDK游戏盾手游遇到攻击为什么要用 SDK 游戏盾?
安全·web安全·游戏·架构·kubernetes·ddos
珂玥c4 小时前
k8s集群ingress碎碎念
云原生·容器·kubernetes
佳杰云星4 小时前
如何给大模型集群选“大脑”?智算调度与管理平台 10 维选型指南(附选型评分表)
人工智能·kubernetes·大模型·云计算·gpu·算力调度·智算中心
比特森林探险记6 小时前
context 在 gRPC / Gin / K8s 中的实战
容器·kubernetes·gin
汪汪大队u7 小时前
基于 K8s 的物联网平台运维体系:Ansible+Zabbix 自动化监控与故障自愈(三)—— Zabbix Server 启动排错记
运维·kubernetes·ansible
日取其半万世不竭8 小时前
OpenCost:Kubernetes 成本监控,开源的云资源费用分析
容器·kubernetes·开源
Cat_Rocky9 小时前
k8s zabbix7学习-设置告警
学习·容器·kubernetes
云游牧者10 小时前
K8S-Ingress流量治理全解-Traefik从入门到实战完全指南
云原生·中间件·容器·kubernetes·ingress·traefik
AI云原生11 小时前
容器网络模型与服务发现:从踩坑到精通,Kubernetes 网络问题排查全指南
服务器·网络·云原生·容器·kubernetes·云计算·服务发现