k8s容器编排技术实践——使用containerd作为容器运行时部署k8s集群
k8s容器编排技术实践——k8s的介绍及其整体运行架构https://blog.csdn.net/xiaochenXIHUA/article/details/161011629一、安装前的准备1.1、安装规划本文搭建最基础的k8s集群即1个master2个work具体的规划内容如下主机名称IP地址集群角色系统版本k8smaster192.168.1.135masterAlmaLinux-9.3k8swork1192.168.1.136work1AlmaLinux-9.3k8swork2192.168.1.137work2AlmaLinux-9.3查看和修改Linux的主机名称https://coffeemilk.blog.csdn.net/article/details/152363961#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 EOF1.2、添加 overlay 和 br_netfilter 内核模块需要在k8s的每台服务器上【添加 overlay 和 br_netfilter 内核模块】#1-添加 overlay 和 br_netfilter 内核模块命令 tee /etc/modules-load.d/containerd.conf EOF overlay br_netfilter EOF #2-让添加的内核模块生效 modprobe overlay modprobe br_netfilter1.3、开启IPVS支持#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_vs1.4、关闭防火墙与selinux#K8s集群每个节点都需要关闭防火墙、selinux、交换分区 #1-关闭防火墙与selinux systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config grubby --update-kernel ALL --args selinux0 #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.confEOF 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与配置加速器#安装部署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.service2.2、安装Kubeadm、kubelet、kubectl工具#安装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] nameKubernetes baseurlhttps://pkgs.k8s.io/core:/stable:/v1.35/rpm/ enabled1 gpgcheck1 gpgkeyhttps://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key excludekubelet 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 --disableexcludeskubernetes #3-启动kubelet并设置开机自启 systemctl daemon-reload systemctl enable kubelet systemctl start kubelet #4-安装containerd命令行工具crictl配置【安装kubelet等工具的时候已经自动安装了crictl要使用这个命令还需要用crictl连接containerd进行如下配置】 cat /etc/crictl.yamlEOF runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false EOF #查看所有镜像、正在运行镜像critcl命令与docker命令使用方法一致 crictl images crictl ps2.3、初始化k8s集群#初始化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 --configkubeadm.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 exitkubeadm.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: systemd2.4、安装网络插件网络插件可以选择【calico】和【flannel】calico适合多节点大型复杂网络【推荐使用】flannel适合小型网络。#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国内无法访问若你配置了加速器还是无法访问的话可以尝试如下操作#解决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.yaml2.5、验证k8s集群是否部署成功#创建一个标准的 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与ctr3.1、crictl与ctr简介ctr是containerd本身的CLIcrictl 是Kubernetes社区定义的专门CLI工具【crictl】提供了类似于 docker 的命令行工具不需要通过 Kubelet 就可以通过 CRI 跟容器运行时通信。它是专门为 Kubernetes 设计的提供了Pod、容器和镜像等资源的管理命令可以帮助用户和开发者调试容器应用或者排查异常问题。crictl 可以用于所有实现了 CRI 接口的容器运行时。注意crictl 并非 kubectl 的替代品它只通过 CRI 接口与容器运行时通信可以用来调试和排错但并不用于运行容器。虽然 crictl 也提供运行 Pod 和容器的子命令但这些命令仅推荐用于调试。3.2、Crictl与docker命令对比功能DockerContainerd显示本地镜像列表docker imagescrictl images下载镜像docker pullcrictl pull上传镜像docker push无删除本地镜像docker rmicrictl rmi查看镜像详情docker inspect IMAGE-IDcrictl inspect IMAGE-ID显示容器列表docker pscrictl ps创建容器docker createcrictl create启动容器docker startcrictl start停止容器docker stopcrictl stop删除容器docker rmcrictl rm查看容器详情docker inspectcrictl inspectattachdocker attachcrictl attachexecdocker execcrictl execlogsdocker logscrictl logsstatsdocker statscrictl stats3.3、crictl与ctr的使用containerd相比于docker , 多了namespace概念, 每个image和container都会在各自的namespace下可见, 目前Crictl会使用k8s.io作为命名空间而ctr的默认命名空间是default。也就是说使用ctr命令下载的镜像不指定命名空间的话使用Crictl工具是看不到的。#指定命名空间后通过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#注意:下面的标记镜像、导入、导出镜像都是通过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