Containerd 介绍、安装和使用

Containerd介绍、安装和使用

文章目录

  • Containerd介绍、安装和使用
  • 1.containerd是什么?
  • 2.Containerd安装
    • 2.1 主机初始化
      • 2.1.1 设置ip地址
      • 2.1.2 配置镜像源
      • 2.1.3 关闭防火墙
      • 2.1.4 禁用SELinux
      • 2.1.5 禁用swap
      • 2.1.6 设置时区
    • 2.2 安装 containerd
      • 2.2.1 内核参数调整
      • 2.2.2 包安装 Containerd
        • 2.2.2.1 Rocky或CentOS安装containerd
        • 2.2.2.2 Ubuntu安装containerd
        • 2.2.2.3 配置 Containerd
        • 2.2.2.4 安装crictl工具
        • 2.2.2.5 安装CNI插件
      • 2.2.3 二进制安装 Containerd
        • 2.2.3.1 安装 containerd
        • 2.2.3.2 配置Containerd
      • 2.2.4 containerd 客户端工具 nerdctl
      • 2.2.5 一键安装containerd脚本
        • 2.2.5.1 基于镜像仓库一键安装containerd脚本
        • 2.2.5.2 基于二进制包一键安装containerd脚本
      • 2.2.6 Containerd 常见命令操作
        • 2.2.6.1 ctr命令使用
      • 2.2.7 nerdctl命令实战操作

1.containerd是什么?

在这里插入图片描述

containerd 是一种行业标准的容器运行时,强调简单、健壮和可移植性。它是 Linux 和 Windows 下的守护进程,可以管理其主机系统的整个容器生命周期:镜像传输和存储、容器执行和监管、底层存储和网络附加等。

containerd 是 CNCF 的成员,具有 "毕业 "资格。

containerd 的设计目的是嵌入到更大的系统中,而不是由开发人员或最终用户直接使用。

t1-2

2.Containerd安装

2.1 主机初始化

2.1.1 设置ip地址

Rocky 9和CentOS Stream 9:

# Rocky 9和CentOS Stream 9默认支持修改网卡名。
[root@rocky9 ~]# grep 'plugins' /etc/NetworkManager/NetworkManager.conf 
#plugins=keyfile,ifcfg-rh
# 因为网卡命名方式默认是keyfile,默认不支持修改网卡名,既然官方已经默认是keyfile那这里就不去更改网卡名了。[root@rocky9 ~]# ETHNAME=`ip addr | awk -F"[ :]" '/^2/{print $3}'`[root@rocky9 ~]# nmcli con delete ${ETHNAME} && nmcli connection add type ethernet con-name ${ETHNAME} ifname ${ETHNAME} ipv4.method manual ipv4.address "172.31.0.9/21" ipv4.gateway "172.31.0.2" ipv4.dns "223.5.5.5,180.76.76.76" autoconnect yes && nmcli con reload && nmcli con up ${ETHNAME}
# 172.31.0.9/21中172.31.0.9是ip地址,21是子网位数;172.31.0.2是网关地址;223.5.5.5, 180.76.76.76都是DNS,根据自己的需求修改。[root@rocky9 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:37:62:95 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 172.31.0.9/21 brd 172.31.7.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::51ca:fd5d:3552:677d/64 scope link noprefixroute valid_lft forever preferred_lft forever
# 可以看到ip地址已修改。

Rocky 8、CentOS Stream 8和CentOS 7:

# Rocky 8、CentOS Stream 8和CentOS 7支持修改网卡名。
[root@rocky8 ~]# grep 'plugins' /etc/NetworkManager/NetworkManager.conf 
#plugins=ifcfg-rh
# 因为网卡命名方式默认是ifcfg-rh,支持修改网卡名。# 修改网卡名称配置文件
[root@rocky8 ~]# sed -ri.bak '/^GRUB_CMDLINE_LINUX=/s@"$@ net.ifnames=0 biosdevname=0"@' /etc/default/grub
[root@rocky8 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
done# 修改网卡文件名
[root@rocky8 ~]# ETHNAME=`ip addr | awk -F"[ :]" '/^2/{print $3}'`
[root@rocky8 ~]# mv /etc/sysconfig/network-scripts/ifcfg-${ETHNAME} /etc/sysconfig/network-scripts/ifcfg-eth0[root@rocky8 ~]# shutdown -r now[root@rocky8 ~]# nmcli dev
DEVICE  TYPE      STATE      CONNECTION         
eth0    ethernet  connected  Wired connection 1 
lo      loopback  unmanaged  --
# 可以看到CONNECTION的名字是Wired connection 1,要改名才可以下面设置。[root@rocky8 ~]# ETHNAME=`ip addr | awk -F"[ :]" '/^2/{print $3}'`[root@rocky8 ~]# nmcli connection modify "Wired connection 1" con-name ${ETHNAME}
[root@rocky8 ~]# nmcli dev
DEVICE  TYPE      STATE      CONNECTION 
eth0    ethernet  connected  eth0       
lo      loopback  unmanaged  --  # 修改ip地址
[root@rocky8 ~]# nmcli con delete ${ETHNAME} && nmcli connection add type ethernet con-name ${ETHNAME} ifname ${ETHNAME} ipv4.method manual ipv4.address "172.31.0.8/21" ipv4.gateway "172.31.0.2" ipv4.dns "223.5.5.5,180.76.76.76" autoconnect yes && nmcli con reload && nmcli dev up eth0
# 172.31.0.8/21中172.31.0.8是ip地址,21是子网位数;172.31.0.2是网关地址;223.5.5.5, 180.76.76.76都是DNS,根据自己的需求修改。[root@rocky8 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:6f:65:d3 brd ff:ff:ff:ff:ff:ffaltname enp3s0altname ens160inet 172.31.0.8/21 brd 172.31.7.255 scope global noprefixroute eth0valid_lft forever preferred_lft foreverinet6 fe80::e9c9:aa93:4a58:2cc2/64 scope link noprefixroute valid_lft forever preferred_lft forever
# 重启系统后可以看到网卡名已经修改成eth0,ip地址也已修改。

Ubuntu:

# Ubuntu先启用root用户,并设置密码
raymond@ubuntu2204:~$ cat set_root_login.sh 
#!/bin/bashread -p "请输入密码: " PASSWORD
echo ${PASSWORD} |sudo -S sed -ri 's@#(PermitRootLogin )prohibit-password@\1yes@' /etc/ssh/sshd_config
sudo systemctl restart sshd
sudo -S passwd root <<-EOF
${PASSWORD}
${PASSWORD}
EOFraymond@ubuntu2204:~$ bash set_root_login.sh 
请输入密码: 123456
[sudo] password for raymond: New password: Retype new password: passwd: password updated successfullyraymond@ubuntu2204:~$ rm -rf set_root_login.sh# 使用root登陆,修改网卡名
root@ubuntu2204:~# sed -ri.bak '/^GRUB_CMDLINE_LINUX=/s@"$@net.ifnames=0 biosdevname=0"@' /etc/default/grub
root@ubuntu2204:~# grub-mkconfig -o /boot/grub/grub.cfg
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.0-88-generic
Found initrd image: /boot/initrd.img-5.15.0-88-generic
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done# Ubuntu 20.04设置ip地址
root@ubuntu2004:~# cat > /etc/netplan/00-installer-config.yaml <<-EOF
network:version: 2renderer: networkdethernets:eth0:dhcp4: nodhcp6: noaddresses: [172.31.0.20/21] gateway4: 172.31.0.2nameservers:addresses: [223.5.5.5, 180.76.76.76]
EOF
# 说明:Ubuntu20.04网卡配置文件是00-installer-config.yaml;172.31.0.20/21中172.31.0.20是ip地址,21是子网位数;172.31.0.2是网关地址;223.5.5.5, 180.76.76.76都是DNS,根据自己的需求修改。# Ubuntu 18.04设置ip地址
root@ubuntu1804:~# cat > /etc/netplan/01-netcfg.yaml <<-EOF
network:version: 2renderer: networkdethernets:eth0:dhcp4: nodhcp6: noaddresses: [172.31.0.18/21] gateway4: 172.31.0.2nameservers:addresses: [223.5.5.5, 180.76.76.76]
EOF
# 说明:Ubuntu18.04网卡配置文件是01-netcfg.yaml;172.31.0.18/21中172.31.0.18是ip地址,21是子网位数;172.31.0.2是网关地址;223.5.5.5, 180.76.76.76都是DNS,根据自己的需求修改。root@ubuntu2004:~# shutdown -r nowroot@ubuntu2004:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:e5:98:6f brd ff:ff:ff:ff:ff:ffinet 172.31.0.20/21 brd 172.31.7.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fee5:986f/64 scope link valid_lft forever preferred_lft forever
# 重启系统后可以看到网卡名已经修改成eth0,ip地址也已修改。# Ubuntu 22.04设置ip地址
root@ubuntu2204:~# cat > /etc/netplan/00-installer-config.yaml <<-EOF
network:version: 2renderer: networkdethernets:eth0:dhcp4: nodhcp6: noaddresses: [172.31.0.22/21]routes:- to: defaultvia: 172.31.0.2nameservers:addresses: [223.5.5.5, 180.76.76.76]
EOF
# 说明:Ubuntu22.04网卡配置文件是00-installer-config.yaml;172.31.0.22/21中172.31.0.22是ip地址,21是子网位数;172.31.0.2是网关地址,Ubuntu 22.04设置网关地址的方法发生了改变,参考上面的方法;223.5.5.5, 180.76.76.76都是DNS,根据自己的需求修改。root@ubuntu2204:~# shutdown -r now# 重启后使用新设置的ip登陆
root@ubuntu2204:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:a7:be:f2 brd ff:ff:ff:ff:ff:ffaltname enp2s1altname ens33inet 172.31.0.22/21 brd 172.31.7.255 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fea7:bef2/64 scope link valid_lft forever preferred_lft forever
# 重启系统后可以看到网卡名已经修改成eth0,ip地址也已修改。

2.1.2 配置镜像源

Rocky 8和9:

MIRROR=mirrors.sjtug.sjtu.edu.cn
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://'${MIRROR}'/rocky|g' /etc/yum.repos.d/[Rr]ocky*.repodnf clean all && dnf makecache

CentOS Stream 9:

cat update_mirror.pl
#!/usr/bin/perluse strict;
use warnings;
use autodie;# 要修改镜像源,请去修改url变量!
my $url = 'mirrors.aliyun.com';
my $mirrors = "https://$url/centos-stream";if (@ARGV < 1) {die "Usage: $0 <filename1> <filename2> ...\n";
}while (my $filename = shift @ARGV) {my $backup_filename = $filename . '.bak';rename $filename, $backup_filename;open my $input, "<", $backup_filename;open my $output, ">", $filename;while (<$input>) {s/^metalink/# metalink/;if (m/^name/) {my (undef, $repo, $arch) = split /-/;$repo =~ s/^\s+|\s+$//g;($arch = defined $arch ? lc($arch) : '') =~ s/^\s+|\s+$//g;if ($repo =~ /^Extras/) {$_ .= "baseurl=${mirrors}/SIGs/\$releasever-stream/extras" . ($arch eq 'source' ? "/${arch}/" : "/\$basearch/") . "extras-common\n";} else {$_ .= "baseurl=${mirrors}/\$releasever-stream/$repo" . ($arch eq 'source' ? "/" : "/\$basearch/") . ($arch ne '' ? "${arch}/tree/" : "os") . "\n";}}print $output $_;}
}rpm -q perl &> /dev/null || { echo -e "\\033[01;31m "安装perl工具,请稍等..."\033[0m";yum -y install perl ; }perl ./update_mirror.pl /etc/yum.repos.d/centos*.repodnf clean all && dnf makecache

CentOS Stream 8:

MIRROR=mirrors.aliyun.com
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' -e 's|^#baseurl=http://mirror.centos.org/$contentdir|baseurl=https://'${MIRROR}'/centos|g' /etc/yum.repos.d/CentOS-*.repodnf clean all && dnf makecache

CentOS 7:

MIRROR=mirrors.aliyun.com
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' -e 's|^#baseurl=http://mirror.centos.org|baseurl=https://'${MIRROR}'|g' /etc/yum.repos.d/CentOS-*.repoyum clean all && yum makecache

Ubuntu 22.04和20.04:

MIRROR=mirrors.aliyun.com
OLD_MIRROR=`sed -rn "s@^deb http(.*)://(.*)/ubuntu/? $(lsb_release -cs) main.*@\2@p" /etc/apt/sources.list`sed -i.bak 's/'${OLD_MIRROR}'/'${MIRROR}'/g' /etc/apt/sources.listapt update

Ubuntu 18.04:

MIRROR=mirrors.aliyun.com
OLD_MIRROR=`sed -rn "s@^deb http(.*)://(.*)/ubuntu/? $(lsb_release -cs) main.*@\2@p" /etc/apt/sources.list`sed -i.bak 's/'${OLD_MIRROR}'/'${MIRROR}'/g' /etc/apt/sources.listSECURITY_MIRROR=`sed -rn "s@^deb http(.*)://(.*)/ubuntu $(lsb_release -cs)-security main.*@\2@p" /etc/apt/sources.list`sed -i.bak 's/'${SECURITY_MIRROR}'/'${MIRROR}'/g' /etc/apt/sources.listapt update

2.1.3 关闭防火墙

# Rocky和CentOS
systemctl disable --now firewalld# CentOS 7
systemctl disable --now NetworkManager# Ubuntu
systemctl disable --now ufw

2.1.4 禁用SELinux

#CentOS
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config#Ubuntu
Ubuntu没有安装SELinux,不用设置

2.1.5 禁用swap

sed -ri 's/.*swap.*/#&/' /etc/fstab
swapoff -a# Ubuntu 20.04和22.04,执行下面命令
sed -ri 's/.*swap.*/#&/' /etc/fstab
SD_NAME=`lsblk|awk -F"[ └─]" '/SWAP/{printf $3}'`
systemctl mask dev-${SD_NAME}.swap
swapoff -a

2.1.6 设置时区

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' >/etc/timezone#Ubuntu还要设置下面内容
cat >> /etc/default/locale <<-EOF
LC_TIME=en_DK.UTF-8
EOF

2.2 安装 containerd

2.2.1 内核参数调整

如果是安装 Docker 会自动配置以下的内核参数,而无需手动实现

但是如果安装Contanerd,还需手动配置

允许 iptables 检查桥接流量,若要显式加载此模块,需运行 modprobe br_netfilter

为了让 Linux 节点的 iptables 能够正确查看桥接流量,还需要确认net.bridge.bridge-nf-call-iptables 设置为 1。

配置Containerd所需的模块:

[root@rocky9 ~]# cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

加载模块:

[root@rocky9 ~]# modprobe -- overlay
[root@rocky9 ~]# modprobe -- br_netfilter

配置Containerd所需的内核:

[root@rocky9 ~]# cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

加载内核:

[root@rocky9 ~]# sysctl --system

2.2.2 包安装 Containerd

2.2.2.1 Rocky或CentOS安装containerd
# step 1: 安装必要的一些系统工具
[root@rocky9 ~]# yum -y install yum-utils# Step 2: 添加软件源信息
[root@rocky9 ~]# yum-config-manager --add-repo https://mirrors.tencent.com/docker-ce/linux/centos/docker-ce.repo# Step 3: 更新Docker-CE镜像源
[root@rocky9 ~]# yum clean all
[root@rocky9 ~]# yum makecache# 安装指定版本的containerd:
# Step 4: 查找containerd.的版本:
[root@rocky9 ~]# yum list containerd.io --showduplicates
Last metadata expiration check: 0:00:15 ago on Thu 15 Feb 2024 01:39:55 PM CST.
Available Packages
containerd.io.x86_64                                   1.6.4-3.1.el9                                    docker-ce-stable
containerd.io.x86_64                                   1.6.6-3.1.el9                                    docker-ce-stable
containerd.io.x86_64                                   1.6.7-3.1.el9                                    docker-ce-stable
containerd.io.x86_64                                   1.6.8-3.1.el9                                    docker-ce-stable
containerd.io.x86_64                                   1.6.9-3.1.el9                                    docker-ce-stable
containerd.io.x86_64                                   1.6.10-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.11-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.12-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.13-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.14-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.15-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.16-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.18-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.19-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.20-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.21-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.22-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.24-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.25-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.26-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.27-3.1.el9                                   docker-ce-stable
containerd.io.x86_64                                   1.6.28-3.1.el9                                   docker-ce-stabl# Step5: 安装指定版本的containerd: (VERSION例如上面的1.6.28)
[root@rocky9 ~]# yum -y install containerd.io-1.6.28
2.2.2.2 Ubuntu安装containerd
# step 1: 安装必要的一些系统工具
root@ubuntu2204:~# apt update
root@ubuntu2204:~# apt -y install apt-transport-https ca-certificates curl software-properties-common# step 2: 安装GPG证书
root@ubuntu2204:~# curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -# Step 3: 写入软件源信息
root@ubuntu2204:~# add-apt-repository -y "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu/  $(lsb_release -cs) stable"# Step 4: 更新Containerd镜像源
root@ubuntu2204:~# apt update# 安装指定版本的Containerd:
# Step 5: 查找Containerd的版本:
root@ubuntu2204:~# apt-cache madison containerd.io
containerd.io |   1.6.28-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.27-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.26-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.25-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.24-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.22-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.21-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.20-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.19-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.18-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.16-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.15-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.14-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.13-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.12-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.11-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.6.10-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |    1.6.9-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |    1.6.8-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |    1.6.7-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |    1.6.6-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |    1.6.4-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.5.11-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages
containerd.io |   1.5.10-1 | https://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy/stable amd64 Packages# Step 6: 安装指定版本的containerd: (VERSION例如上面的1.6.12-0ubuntu1~22.04.3)
root@ubuntu2204:~# apt -y install containerd.io=1.6.28-1
2.2.2.3 配置 Containerd

配置Containerd的配置文件:

[root@rocky9 ~]# containerd config default | tee /etc/containerd/config.toml

将Containerd的Cgroup改为Systemd和修改containerd配置sandbox_image 镜像源设置为阿里google_containers镜像源:

[root@rocky9 ~]# vim /etc/containerd/config.toml
...[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] # 在这行下面找到SystemdCgroup。
...
# 把下面内容SystemdCgroup = false
# 改成下面内容SystemdCgroup = true # 把SystemdCgroup里的false改成true。
...
# 把下面内容sandbox_image = "registry.k8s.io/pause:3.6"
# 改成下面内容sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6" # 把sandbox_image的镜像改为阿里镜像源。# 使用下面命令修改
[root@rocky9 ~]# sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.toml

配置镜像加速:

[root@rocky9 ~]# vim /etc/containerd/config.toml
...[plugins."io.containerd.grpc.v1.cri".registry.mirrors] # 在这行下面配置镜像加速,注意每行前面都有2个缩进。
#下面两行是配置镜像加速[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]# 使用下面命令修改
[root@rocky9 ~]# sed -i '/.*registry.mirrors.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n          endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml

启动Containerd,并配置开机自启动:

[root@rocky9 ~]# systemctl daemon-reload && systemctl enable --now containerd# Ubuntu默认安装完Containerd已经启动了服务,需要重启一下服务才能配置生效。
root@ubuntu2204:~# systemctl restart containerd[root@rocky9 ~]# systemctl is-active containerd
active
2.2.2.4 安装crictl工具
# Rocky和CentOS
[root@rocky9 ~]# rpm -ql containerd.io
/etc/containerd
/etc/containerd/config.toml
/usr/bin/containerd
/usr/bin/containerd-shim
/usr/bin/containerd-shim-runc-v1
/usr/bin/containerd-shim-runc-v2
/usr/bin/ctr
/usr/bin/runc
/usr/lib/.build-id
/usr/lib/.build-id/50
/usr/lib/.build-id/50/6dc3841de9b492f9ccb6f0ea69ef642d755c1b
/usr/lib/.build-id/d6
/usr/lib/.build-id/d6/0988ba571e825119ce555ccc01a588bc8a23bf
/usr/lib/.build-id/f4
/usr/lib/.build-id/f4/20449290a3275cc0ac97f228938e87a88d299c
/usr/lib/systemd/system/containerd.service
/usr/share/doc/containerd.io
/usr/share/doc/containerd.io/README.md
/usr/share/licenses/containerd.io
/usr/share/licenses/containerd.io/LICENSE
/usr/share/man/man5/containerd-config.toml.5
/usr/share/man/man8/containerd-config.8
/usr/share/man/man8/containerd.8
/usr/share/man/man8/ctr.8
# 可以看到containerd已经装了ctr工具和runc,但是没有装crictl工具# Ubuntu
root@ubuntu2204:~# dpkg -L containerd.io
/.
/etc
/etc/containerd
/etc/containerd/config.toml
/lib
/lib/systemd
/lib/systemd/system
/lib/systemd/system/containerd.service
/usr
/usr/bin
/usr/bin/containerd
/usr/bin/containerd-shim
/usr/bin/containerd-shim-runc-v1
/usr/bin/containerd-shim-runc-v2
/usr/bin/ctr
/usr/bin/runc
/usr/share
/usr/share/doc
/usr/share/doc/containerd.io
/usr/share/doc/containerd.io/changelog.Debian.gz
/usr/share/doc/containerd.io/copyright
/usr/share/man
/usr/share/man/man5
/usr/share/man/man5/containerd-config.toml.5.gz
/usr/share/man/man8
/usr/share/man/man8/containerd-config.8.gz
/usr/share/man/man8/containerd.8.gz
/usr/share/man/man8/ctr.8.gz
# 可以看到containerd已经装了ctr工具和runc,但是没有装crictl工具[root@rocky9 ~]# wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.29.0/crictl-v1.29.0-linux-amd64.tar.gz[root@rocky9 ~]# tar zxvf crictl-v1.29.0-linux-amd64.tar.gz -C /usr/local/bin

配置crictl客户端连接的运行时位置:

[root@rocky9 ~]# cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF[root@rocky9 ~]# systemctl restart containerd

查看信息:

[root@rocky9 ~]# ctr version
Client:Version:  1.6.28Revision: ae07eda36dd25f8a1b98dfbf587313b99c0190bbGo version: go1.20.13Server:Version:  1.6.28Revision: ae07eda36dd25f8a1b98dfbf587313b99c0190bbUUID: cc7c669c-368d-4d06-ac44-761b10a28f5d[root@rocky9 ~]# crictl version
Version:  0.1.0
RuntimeName:  containerd
RuntimeVersion:  1.6.28
RuntimeApiVersion:  v1[root@rocky9 ~]# crictl info
{
..."lastCNILoadStatus": "cni config load failed: no network config found in /etc/cni/net.d: cni plugin not initialized: failed to load cni config","lastCNILoadStatus.default": "cni config load failed: no network config found in /etc/cni/net.d: cni plugin not initialized: failed to load cni config"
}
# 这里提示cni插件报错,因为没有装containerd的CNI插件.
2.2.2.5 安装CNI插件
[root@rocky9 ~]# wget https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz[root@rocky9 ~]# mkdir -p /opt/cni/bin/
[root@rocky9 ~]# tar xzvf cni-plugins-linux-amd64-v1.4.0.tgz -C /opt/cni/bin/# cni配置文件
[root@rocky9 ~]# mkdir -p /etc/cni/net.d/
[root@rocky9 ~]# cat > /etc/cni/net.d/10-containerd-net.conflist <<EOF
{"cniVersion": "1.0.0","name": "containerd-net","plugins": [{"type": "bridge","bridge": "cni0","isGateway": true,"ipMasq": true,"promiscMode": true,"ipam": {"type": "host-local","ranges": [[{"subnet": "10.88.0.0/16"}],[{"subnet": "2001:4860:4860::/64"}]],"routes": [{ "dst": "0.0.0.0/0" },{ "dst": "::/0" }]}},{"type": "portmap","capabilities": {"portMappings": true}}]
}
EOF[root@rocky9 ~]# systemctl restart containerd
[root@rocky9 ~]# crictl info
{"status": {"conditions": [{"type": "RuntimeReady","status": true,"reason": "","message": ""},{"type": "NetworkReady","status": true,"reason": "","message": ""}]},"cniconfig": {"PluginDirs": ["/opt/cni/bin"],"PluginConfDir": "/etc/cni/net.d","PluginMaxConfNum": 1,"Prefix": "eth","Networks": [{"Config": {"Name": "cni-loopback","CNIVersion": "0.3.1","Plugins": [{"Network": {"type": "loopback","ipam": {},"dns": {}},"Source": "{\"type\":\"loopback\"}"}],"Source": "{\n\"cniVersion\": \"0.3.1\",\n\"name\": \"cni-loopback\",\n\"plugins\": [{\n  \"type\": \"loopback\"\n}]\n}"},"IFName": "lo"},{"Config": {"Name": "containerd-net","CNIVersion": "1.0.0","Plugins": [{"Network": {"type": "bridge","ipam": {"type": "host-local"},"dns": {}},"Source": "{\"bridge\":\"cni0\",\"ipMasq\":true,\"ipam\":{\"ranges\":[[{\"subnet\":\"10.88.0.0/16\"}],[{\"subnet\":\"2001:4860:4860::/64\"}]],\"routes\":[{\"dst\":\"0.0.0.0/0\"},{\"dst\":\"::/0\"}],\"type\":\"host-local\"},\"isGateway\":true,\"promiscMode\":true,\"type\":\"bridge\"}"},{"Network": {"type": "portmap","capabilities": {"portMappings": true},"ipam": {},"dns": {}},"Source": "{\"capabilities\":{\"portMappings\":true},\"type\":\"portmap\"}"}],"Source": "{\n  \"cniVersion\": \"1.0.0\",\n  \"name\": \"containerd-net\",\n  \"plugins\": [\n    {\n      \"type\": \"bridge\",\n      \"bridge\": \"cni0\",\n      \"isGateway\": true,\n      \"ipMasq\": true,\n      \"promiscMode\": true,\n      \"ipam\": {\n        \"type\": \"host-local\",\n        \"ranges\": [\n          [{\n            \"subnet\": \"10.88.0.0/16\"\n          }],\n          [{\n            \"subnet\": \"2001:4860:4860::/64\"\n          }]\n        ],\n        \"routes\": [\n          { \"dst\": \"0.0.0.0/0\" },\n          { \"dst\": \"::/0\" }\n        ]\n      }\n    },\n    {\n      \"type\": \"portmap\",\n      \"capabilities\": {\"portMappings\": true}\n    }\n  ]\n}\n"},"IFName": "eth0"}]},"config": {"containerd": {"snapshotter": "overlayfs","defaultRuntimeName": "runc","defaultRuntime": {"runtimeType": "","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {},"privileged_without_host_devices": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0},"untrustedWorkloadRuntime": {"runtimeType": "","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {},"privileged_without_host_devices": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0},"runtimes": {"runc": {"runtimeType": "io.containerd.runc.v2","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {"BinaryName": "","CriuImagePath": "","CriuPath": "","CriuWorkPath": "","IoGid": 0,"IoUid": 0,"NoNewKeyring": false,"NoPivotRoot": false,"Root": "","ShimCgroup": "","SystemdCgroup": true},"privileged_without_host_devices": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0}},"noPivot": false,"disableSnapshotAnnotations": true,"discardUnpackedLayers": false,"ignoreRdtNotEnabledErrors": false},"cni": {"binDir": "/opt/cni/bin","confDir": "/etc/cni/net.d","maxConfNum": 1,"confTemplate": "","ipPref": ""},"registry": {"configPath": "","mirrors": {"docker.io": {"endpoint": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"]}},"configs": {},"auths": {},"headers": {}},"imageDecryption": {"keyModel": "node"},"disableTCPService": true,"streamServerAddress": "127.0.0.1","streamServerPort": "0","streamIdleTimeout": "4h0m0s","enableSelinux": false,"selinuxCategoryRange": 1024,"sandboxImage": "registry.aliyuncs.com/google_containers/pause:3.6","statsCollectPeriod": 10,"systemdCgroup": false,"enableTLSStreaming": false,"x509KeyPairStreaming": {"tlsCertFile": "","tlsKeyFile": ""},"maxContainerLogSize": 16384,"disableCgroup": false,"disableApparmor": false,"restrictOOMScoreAdj": false,"maxConcurrentDownloads": 3,"disableProcMount": false,"unsetSeccompProfile": "","tolerateMissingHugetlbController": true,"disableHugetlbController": true,"device_ownership_from_security_context": false,"ignoreImageDefinedVolumes": false,"netnsMountsUnderStateDir": false,"enableUnprivilegedPorts": false,"enableUnprivilegedICMP": false,"containerdRootDir": "/var/lib/containerd","containerdEndpoint": "/run/containerd/containerd.sock","rootDir": "/var/lib/containerd/io.containerd.grpc.v1.cri","stateDir": "/run/containerd/io.containerd.grpc.v1.cri"},"golang": "go1.20.13","lastCNILoadStatus": "OK","lastCNILoadStatus.default": "OK"
}
# 现在就没有cni插件报错了,到此containerd就安装完成了。

2.2.3 二进制安装 Containerd

官方下载链接:

https://github.com/containerd/containerd

Containerd有三种二进制安装包:

  • containerd-xxx :包含containerd和ctr,不包含runC、crictl、systemd 配置文件等相关文件,需要单独安装runC

    [root@rocky9-2 ~]# wget https://github.com/containerd/containerd/releases/download/v1.7.12/containerd-1.7.12-linux-amd64.tar.gz[root@rocky9-2 ~]# tar tf containerd-1.7.12-linux-amd64.tar.gz
    bin/
    bin/containerd-shim
    bin/containerd-stress
    bin/containerd-shim-runc-v1
    bin/ctr
    bin/containerd
    bin/containerd-shim-runc-v2
    
  • cri-containerd-xxx:包含containerd、runC,ctr、crictl、systemd 配置文件等相关文件,不包含cni插件,k8s不需要containerd的cni插件,所以选择这个二进制包安装

    [root@rocky9-2 ~]# wget https://github.com/containerd/containerd/releases/download/v1.7.12/cri-containerd-1.7.12-linux-amd64.tar.gz[root@rocky9-2 ~]# tar tf cri-containerd-1.7.12-linux-amd64.tar.gz
    cri-containerd.DEPRECATED.txt
    etc/crictl.yaml
    etc/systemd/
    etc/systemd/system/
    etc/systemd/system/containerd.service
    usr/
    usr/local/
    usr/local/bin/
    usr/local/bin/containerd-shim
    usr/local/bin/containerd-stress
    usr/local/bin/containerd-shim-runc-v1
    usr/local/bin/ctr
    usr/local/bin/crictl
    usr/local/bin/ctd-decoder
    usr/local/bin/critest
    usr/local/bin/containerd
    usr/local/bin/containerd-shim-runc-v2
    usr/local/sbin/
    usr/local/sbin/runc
    opt/containerd/
    opt/containerd/cluster/
    opt/containerd/cluster/version
    opt/containerd/cluster/gce/
    opt/containerd/cluster/gce/cloud-init/
    opt/containerd/cluster/gce/cloud-init/node.yaml
    opt/containerd/cluster/gce/cloud-init/master.yaml
    opt/containerd/cluster/gce/env
    opt/containerd/cluster/gce/cni.template
    opt/containerd/cluster/gce/configure.sh
    
  • cri-containerd-cni-xxx:包含containerd、runc、ctr、crictl、cni插件、systemd 配置文件等相关文件

    [root@rocky9-2 ~]# wget https://github.com/containerd/containerd/releases/download/v1.7.12/cri-containerd-cni-1.7.12-linux-amd64.tar.gz[root@rocky9-2 ~]# tar tf cri-containerd-cni-1.7.12-linux-amd64.tar.gz 
    cri-containerd.DEPRECATED.txt
    etc/
    etc/systemd/
    etc/systemd/system/
    etc/systemd/system/containerd.service
    etc/cni/
    etc/cni/net.d/
    etc/cni/net.d/10-containerd-net.conflist
    etc/crictl.yaml
    usr/
    usr/local/
    usr/local/bin/
    usr/local/bin/containerd-shim
    usr/local/bin/containerd-stress
    usr/local/bin/containerd-shim-runc-v1
    usr/local/bin/ctr
    usr/local/bin/crictl
    usr/local/bin/ctd-decoder
    usr/local/bin/critest
    usr/local/bin/containerd
    usr/local/bin/containerd-shim-runc-v2
    usr/local/sbin/
    usr/local/sbin/runc
    opt/
    opt/cni/
    opt/cni/bin/
    opt/cni/bin/bandwidth
    opt/cni/bin/firewall
    opt/cni/bin/host-local
    opt/cni/bin/static
    opt/cni/bin/vrf
    opt/cni/bin/dhcp
    opt/cni/bin/vlan
    opt/cni/bin/loopback
    opt/cni/bin/sbr
    opt/cni/bin/tuning
    opt/cni/bin/macvlan
    opt/cni/bin/portmap
    opt/cni/bin/dummy
    opt/cni/bin/bridge
    opt/cni/bin/host-device
    opt/cni/bin/ptp
    opt/cni/bin/ipvlan
    opt/containerd/
    opt/containerd/cluster/
    opt/containerd/cluster/version
    opt/containerd/cluster/gce/
    opt/containerd/cluster/gce/cloud-init/
    opt/containerd/cluster/gce/cloud-init/node.yaml
    opt/containerd/cluster/gce/cloud-init/master.yaml
    opt/containerd/cluster/gce/env
    opt/containerd/cluster/gce/cni.template
    opt/containerd/cluster/gce/configure.sh
    
2.2.3.1 安装 containerd
[root@rocky9-2 ~]# wget https://github.com/containerd/containerd/releases/download/v1.7.12/cri-containerd-cni-1.7.12-linux-amd64.tar.gz# cri-containerd-cni-1.7.12-linux-amd64.tar.gz 压缩包中已经按照官方二进制部署推荐的目录结构布局好。 里面包含了 systemd 配置文件,containerd 和ctr、crictl、cni插件等部署文件。 将解压缩到系统的根目录 / 中:[root@rocky9-2 ~]# tar xf cri-containerd-cni-1.7.12-linux-amd64.tar.gz -C /
2.2.3.2 配置Containerd

配置Containerd的配置文件:

[root@rocky9-2 ~]# mkdir -p /etc/containerd
[root@rocky9-2 ~]# containerd config default | tee /etc/containerd/config.toml

将Containerd的Cgroup改为Systemd和修改containerd配置sandbox_image 镜像源设置为阿里google_containers镜像源:

[root@rocky9 ~]# vim /etc/containerd/config.toml
...[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] # 在这行下面找到SystemdCgroup。
...
# 把下面内容SystemdCgroup = false
# 改成下面内容SystemdCgroup = true # 把SystemdCgroup里的false改成true。
...
# 把下面内容sandbox_image = "registry.k8s.io/pause:3.8"
# 改成下面内容sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8" # 把sandbox_image的镜像改为阿里镜像源。#使用下面命令修改
[root@rocky9 ~]# sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.toml

配置镜像加速:

[root@rocky9 ~]# vim /etc/containerd/config.toml
...[plugins."io.containerd.grpc.v1.cri".registry.mirrors] # 在这行下面配置镜像加速,注意每行前面都有2个缩进。
#下面两行是配置镜像加速[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]#使用下面命令修改
[root@rocky9 ~]# sed -i '/.*registry.mirrors.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n          endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml

使用crictl命令之前,需要先配置/etc/crictl.yaml如下:

[root@rocky9 ~]# cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

也可以通过命令进行设置:

crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock

启动Containerd,并配置开机自启动:

[root@rocky9 ~]# systemctl daemon-reload && systemctl enable --now containerd[root@rocky9 ~]# systemctl is-active containerd
active

查看信息:

[root@rocky9-2 ~]# ctr version
Client:Version:  v1.7.12Revision: 71909c1814c544ac47ab91d2e8b84718e517bb99Go version: go1.20.13Server:Version:  v1.7.12Revision: 71909c1814c544ac47ab91d2e8b84718e517bb99UUID: 46be7315-15ce-4a1f-922a-4902732c64a6[root@rocky9-2 ~]# crictl version
Version:  0.1.0
RuntimeName:  containerd
RuntimeVersion:  v1.7.12
RuntimeApiVersion:  v1[root@rocky9-2 ~]# crictl info
{"status": {"conditions": [{"type": "RuntimeReady","status": true,"reason": "","message": ""},{"type": "NetworkReady","status": true,"reason": "","message": ""}]},"cniconfig": {"PluginDirs": ["/opt/cni/bin"],"PluginConfDir": "/etc/cni/net.d","PluginMaxConfNum": 1,"Prefix": "eth","Networks": [{"Config": {"Name": "cni-loopback","CNIVersion": "0.3.1","Plugins": [{"Network": {"type": "loopback","ipam": {},"dns": {}},"Source": "{\"type\":\"loopback\"}"}],"Source": "{\n\"cniVersion\": \"0.3.1\",\n\"name\": \"cni-loopback\",\n\"plugins\": [{\n  \"type\": \"loopback\"\n}]\n}"},"IFName": "lo"},{"Config": {"Name": "containerd-net","CNIVersion": "1.0.0","Plugins": [{"Network": {"type": "bridge","ipam": {"type": "host-local"},"dns": {}},"Source": "{\"bridge\":\"cni0\",\"ipMasq\":true,\"ipam\":{\"ranges\":[[{\"subnet\":\"10.88.0.0/16\"}],[{\"subnet\":\"2001:4860:4860::/64\"}]],\"routes\":[{\"dst\":\"0.0.0.0/0\"},{\"dst\":\"::/0\"}],\"type\":\"host-local\"},\"isGateway\":true,\"promiscMode\":true,\"type\":\"bridge\"}"},{"Network": {"type": "portmap","capabilities": {"portMappings": true},"ipam": {},"dns": {}},"Source": "{\"capabilities\":{\"portMappings\":true},\"type\":\"portmap\"}"}],"Source": "{\n  \"cniVersion\": \"1.0.0\",\n  \"name\": \"containerd-net\",\n  \"plugins\": [\n    {\n      \"type\": \"bridge\",\n      \"bridge\": \"cni0\",\n      \"isGateway\": true,\n      \"ipMasq\": true,\n      \"promiscMode\": true,\n      \"ipam\": {\n        \"type\": \"host-local\",\n        \"ranges\": [\n          [{\n            \"subnet\": \"10.88.0.0/16\"\n          }],\n          [{\n            \"subnet\": \"2001:4860:4860::/64\"\n          }]\n        ],\n        \"routes\": [\n          { \"dst\": \"0.0.0.0/0\" },\n          { \"dst\": \"::/0\" }\n        ]\n      }\n    },\n    {\n      \"type\": \"portmap\",\n      \"capabilities\": {\"portMappings\": true}\n    }\n  ]\n}\n"},"IFName": "eth0"}]},"config": {"containerd": {"snapshotter": "overlayfs","defaultRuntimeName": "runc","defaultRuntime": {"runtimeType": "","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {},"privileged_without_host_devices": false,"privileged_without_host_devices_all_devices_allowed": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0,"snapshotter": "","sandboxMode": ""},"untrustedWorkloadRuntime": {"runtimeType": "","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {},"privileged_without_host_devices": false,"privileged_without_host_devices_all_devices_allowed": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0,"snapshotter": "","sandboxMode": ""},"runtimes": {"runc": {"runtimeType": "io.containerd.runc.v2","runtimePath": "","runtimeEngine": "","PodAnnotations": [],"ContainerAnnotations": [],"runtimeRoot": "","options": {"BinaryName": "","CriuImagePath": "","CriuPath": "","CriuWorkPath": "","IoGid": 0,"IoUid": 0,"NoNewKeyring": false,"NoPivotRoot": false,"Root": "","ShimCgroup": "","SystemdCgroup": true},"privileged_without_host_devices": false,"privileged_without_host_devices_all_devices_allowed": false,"baseRuntimeSpec": "","cniConfDir": "","cniMaxConfNum": 0,"snapshotter": "","sandboxMode": "podsandbox"}},"noPivot": false,"disableSnapshotAnnotations": true,"discardUnpackedLayers": false,"ignoreBlockIONotEnabledErrors": false,"ignoreRdtNotEnabledErrors": false},"cni": {"binDir": "/opt/cni/bin","confDir": "/etc/cni/net.d","maxConfNum": 1,"setupSerially": false,"confTemplate": "","ipPref": ""},"registry": {"configPath": "","mirrors": {"docker.io": {"endpoint": ["https://registry.docker-cn.com","https://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"]}},"configs": {},"auths": {},"headers": {}},"imageDecryption": {"keyModel": "node"},"disableTCPService": true,"streamServerAddress": "127.0.0.1","streamServerPort": "0","streamIdleTimeout": "4h0m0s","enableSelinux": false,"selinuxCategoryRange": 1024,"sandboxImage": "registry.aliyuncs.com/google_containers/pause:3.8","statsCollectPeriod": 10,"systemdCgroup": false,"enableTLSStreaming": false,"x509KeyPairStreaming": {"tlsCertFile": "","tlsKeyFile": ""},"maxContainerLogSize": 16384,"disableCgroup": false,"disableApparmor": false,"restrictOOMScoreAdj": false,"maxConcurrentDownloads": 3,"disableProcMount": false,"unsetSeccompProfile": "","tolerateMissingHugetlbController": true,"disableHugetlbController": true,"device_ownership_from_security_context": false,"ignoreImageDefinedVolumes": false,"netnsMountsUnderStateDir": false,"enableUnprivilegedPorts": false,"enableUnprivilegedICMP": false,"enableCDI": false,"cdiSpecDirs": ["/etc/cdi","/var/run/cdi"],"imagePullProgressTimeout": "5m0s","drainExecSyncIOTimeout": "0s","containerdRootDir": "/var/lib/containerd","containerdEndpoint": "/run/containerd/containerd.sock","rootDir": "/var/lib/containerd/io.containerd.grpc.v1.cri","stateDir": "/run/containerd/io.containerd.grpc.v1.cri"},"golang": "go1.20.13","lastCNILoadStatus": "OK","lastCNILoadStatus.default": "OK"
}

2.2.4 containerd 客户端工具 nerdctl

推荐使用 nerdctl,使用效果与 docker 命令的语法一致,github 下载链接:

https://github.com/containerd/nerdctl/releases

  • 精简 (nerdctl–linux-amd64.tar.gz): 只包含 nerdctl
  • 完整 (nerdctl-full–linux-amd64.tar.gz): 包含 containerd, runc, and CNI 等依赖

nerdctl 的目标并不是单纯地复制 docker 的功能,它还实现了很多 docker 不具备的功能,例如延迟拉取镜像(lazy-pulling)、镜像加密(imgcrypt)等。具体看 nerdctl。

t1-3

延迟拉取镜像功能可以参考这篇文章:Containerd 使用 Stargz Snapshotter 延迟拉取镜像

https://icloudnative.io/posts/startup-containers-in-lightning-speed-with-lazy-image-distribution-on-containerd/

1)安装 nerdctl(精简版):

[root@rocky9 ~]#  wget https://github.com/containerd/nerdctl/releases/download/v1.7.3/nerdctl-1.7.3-linux-amd64.tar.gz[root@rocky9 ~]# tar xf nerdctl-1.7.3-linux-amd64.tar.gz -C /usr/local/bin/# 配置nerdctl
cat > /etc/nerdctl/nerdctl.toml <<EOF
namespace      = "default"
insecure_registry = true
EOF[root@rocky9 ~]# cat /etc/nerdctl/nerdctl.toml 
namespace      = "default" # 设置nerdctl工具默认namespace
insecure_registry = true # 跳过安全镜像仓库检测

2)安装 buildkit 支持构建镜像:

buildkit GitHub 地址:

https://github.com/moby/buildkit

使用精简版 nerdctl 无法直接通过 containerd 构建镜像,需要与 buildkit 组全使用以实现镜像构建。当然你也可以安装上面的完整 nerdctl;buildkit 项目是 Docker 公司开源出来的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:

  • 服务端 buildkitd,当前支持 runc 和 containerd 作为 worker,默认是 runc;
  • 客户端 buildctl,负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求。

buildkit 是典型的C/S 架构,client 和 server 可以不在一台服务器上。而 nerdctl 在构建镜像方面也可以作为 buildkitd 的客户端。

[root@rocky9 ~]# wget https://github.com/moby/buildkit/releases/download/v0.12.5/buildkit-v0.12.5.linux-amd64.tar.gz[root@rocky9 ~]# tar xf buildkit-v0.12.5.linux-amd64.tar.gz -C /usr/local/

配置 buildkit 的启动文件,可以从这里下载:

https://github.com/moby/buildkit/tree/master/examples/systemd

buildkit 需要配置两个文件

  • /usr/lib/systemd/system/buildkit.socket

    [root@rocky9 ~]# cat > /usr/lib/systemd/system/buildkit.socket <<EOF
    [Unit]
    Description=BuildKit
    Documentation=https://github.com/moby/buildkit[Socket]
    ListenStream=%t/buildkit/buildkitd.sock
    SocketMode=0660[Install]
    WantedBy=sockets.target
    EOF
    
  • /usr/lib/systemd/system/buildkit.service

    [root@rocky9 ~]# cat > /usr/lib/systemd/system/buildkit.service << EOF
    [Unit]
    Description=BuildKit
    Requires=buildkit.socket
    After=buildkit.socket
    Documentation=https://github.com/moby/buildkit[Service]
    Type=notify
    ExecStart=/usr/local/bin/buildkitd --addr fd://[Install]
    WantedBy=multi-user.target
    EOF
    

启动 buildkit:

[root@rocky9 ~]# systemctl daemon-reload && systemctl enable --now buildkit [root@rocky9 ~]# systemctl status buildkit
● buildkit.service - BuildKitLoaded: loaded (/usr/lib/systemd/system/buildkit.service; enabled; preset: disabled)Active: active (running) since Thu 2024-02-01 21:33:36 CST; 22s ago
TriggeredBy: ● buildkit.socketDocs: https://github.com/moby/buildkitMain PID: 15218 (buildkitd)Tasks: 9 (limit: 10840)Memory: 13.7MCPU: 36msCGroup: /system.slice/buildkit.service└─15218 /usr/local/bin/buildkitd --addr fd://Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=warning msg="using host network as the >
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=warning msg="git source cannot be enabl>
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=info msg="found worker \"qc0w0cvit1te4m>
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=warning msg="using host network as the >
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=warning msg="git source cannot be enabl>
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=info msg="found worker \"8e8fqp2ogv0ipy>
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=info msg="found 2 workers, default=\"qc>
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=warning msg="currently, only the defaul>
Feb 01 21:33:36 rocky9 systemd[1]: Started BuildKit.
Feb 01 21:33:36 rocky9 buildkitd[15218]: time="2024-02-01T21:33:36+08:00" level=info msg="running server on /run/buildk>[root@rocky9 ~]# nerdctl version
Client:Version:	v1.7.3OS/Arch:	linux/amd64Git commit:	0a464409d0178e16d3d2bed36222937ec3fc9c77buildctl:Version:	v0.12.5GitCommit:	bac3f2b673f3f9d33e79046008e7a38e856b3dc6Server:containerd:Version:	v1.7.10GitCommit:	4e1fe7492b9df85914c389d1f15a3ceedbb280acrunc:Version:	1.1.10GitCommit:	v1.1.10-0-g18a0cb0f[root@rocky9 ~]# nerdctl info
Client:Namespace:	defaultDebug Mode:	falseServer:Server Version: v1.7.10Storage Driver: overlayfsLogging Driver: json-fileCgroup Driver: systemdCgroup Version: 2Plugins:Log: fluentd journald json-file syslogStorage: native overlayfsSecurity Options:seccompProfile: builtincgroupnsKernel Version: 5.14.0-362.8.1.el9_3.x86_64Operating System: Rocky Linux 9.3 (Blue Onyx)OSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 1.692GiBName: rocky9ID: b17950f1-e38a-4ec8-9857-21a7d572eae7

解决"WARNING: No swap limit support"报警提示:

# SWAP报警提示,只有在ubuntu 20.04和18.04里面有
root@ubuntu2004:~# sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grubroot@ubuntu2004:~# update-grub
root@ubuntu2004:~# rebootroot@ubuntu2004:~# nerdctl info
Client:Namespace:	defaultDebug Mode:	falseServer:Server Version: v1.6.8Storage Driver: overlayfsLogging Driver: json-fileCgroup Driver: cgroupfsCgroup Version: 1Plugins:Log: fluentd journald json-fileStorage: aufs native overlayfsSecurity Options:apparmorseccompProfile: defaultKernel Version: 5.4.0-125-genericOperating System: Ubuntu 20.04.4 LTSOSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 3.81GiBName: k8s-master01.example.localID: ab901e55-fa37-496e-9920-ee6eff687687
#现在就没有SWAP报警提示

2.2.5 一键安装containerd脚本

Shell脚本源码地址:

Gitee:https://gitee.com/raymond9/shell

Github:https://github.com/raymond999999/shell

可以去上面的Gitee或Github代码仓库拉取脚本。

2.2.5.1 基于镜像仓库一键安装containerd脚本
[root@rocky9 ~]# cat install_containerd.sh
#!/bin/bash
#
#*************************************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2024-02-15
#FileName:      install_containerd.sh
#URL:           raymond.blog.csdn.net
#Description:   install_containerd for CentOS 7 & CentOS Stream 8/9 & Ubuntu 18.04/20.04/22.04 & Rocky 8/9
#Copyright (C): 2024 All rights reserved
#*************************************************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \\033[01;31m"
END='\033[0m'
CONTAINERD_VERSION=1.6.28
URL='mirrors.aliyun.com'#crictl下载地址:“https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.29.0/crictl-v1.29.0-linux-amd64.tar.gz”,请提前下载。
CRICTL_FILE=crictl-v1.29.0-linux-amd64.tar.gz
#CNIl下载地址:“https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz”,请提前下载。
CNI_FILE=cni-plugins-linux-amd64-v1.4.0.tgz
#Netdctl下载地址:“https://github.com/containerd/nerdctl/releases/download/v1.7.3/nerdctl-1.7.3-linux-amd64.tar.gz”,请提前下载。
NETDCTL_FILE=nerdctl-1.7.3-linux-amd64.tar.gz
#Buildkit下载地址:“https://github.com/moby/buildkit/releases/download/v0.12.5/buildkit-v0.12.5.linux-amd64.tar.gz”,请提前下载。
BUILDKIT_FILE=buildkit-v0.12.5.linux-amd64.tar.gzos(){OS_ID=`sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release`OS_RELEASE_VERSION=`sed -rn '/^VERSION_ID=/s@.*="?([0-9]+)\.?.*"?@\1@p' /etc/os-release`
}check_file(){cd ${SRC_DIR}if [ ! -e ${CRICTL_FILE} ];then${COLOR}"缺少${CRICTL_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelif [ ! -e ${CNI_FILE} ];then${COLOR}"缺少${CNI_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelif [ ! -e ${NETDCTL_FILE} ];then${COLOR}"缺少${NETDCTL_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelif [ ! -e ${BUILDKIT_FILE} ];then${COLOR}"缺少${BUILDKIT_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelse${COLOR}"相关文件已准备好"${END}fi
}set_kernel(){cat > /etc/modules-load.d/containerd.conf <<-EOF
overlay
br_netfilter
EOFmodprobe -- overlaymodprobe -- br_netfiltercat > /etc/sysctl.d/99-kubernetes-cri.conf <<-EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOFsysctl --system &> /dev/null
}ubuntu_install_docker(){dpkg -s containerd &>/dev/null && ${COLOR}"Containerd已安装,退出"${END} && exit${COLOR}"开始安装Containerd依赖包,请稍等..."${END}apt update &> /dev/nullapt -y install apt-transport-https ca-certificates curl software-properties-common &> /dev/nullcurl -fsSL https://${URL}/docker-ce/linux/ubuntu/gpg | sudo apt-key add - &> /dev/nulladd-apt-repository -y "deb [arch=amd64] https://${URL}/docker-ce/linux/ubuntu  $(lsb_release -cs) stable" &> /dev/null apt update &> /dev/null${COLOR}"Containerd有以下版本"${END}apt-cache madison containerd.io${COLOR}"10秒后即将安装:Containerd-"${CONTAINERD_VERSION}"版本......"${END}${COLOR}"如果想安装其它Containerd版本,请按Ctrl+c键退出,修改版本再执行"${END}sleep 10${COLOR}"开始安装Containerd,请稍等..."${END}apt -y install containerd.io=${CONTAINERD_VERSION}-1 &> /dev/null || { ${COLOR}"apt源失败,请检查apt配置"${END};exit; }
}centos_install_docker(){rpm -q containerd &> /dev/null && ${COLOR}"Containerd已安装,退出"${END} && exit${COLOR}"开始安装Containerd依赖包,请稍等..."${END}yum -y install yum-utils &> /dev/nullyum-config-manager --add-repo https://${URL}/docker-ce/linux/centos/docker-ce.repo &> /dev/nullyum clean all &> /dev/nullyum makecache &> /dev/null${COLOR}"Containerd有以下版本"${END}yum list containerd.io --showduplicates${COLOR}"10秒后即将安装:Containerd-"${CONTAINERD_VERSION}"版本......"${END}${COLOR}"如果想安装其它Containerd版本,请按Ctrl+c键退出,修改版本再执行"${END}sleep 10${COLOR}"开始安装Containerd,请稍等..."${END}yum -y install containerd.io-${CONTAINERD_VERSION} &> /dev/null || { ${COLOR}"yum源失败,请检查yum配置"${END};exit; }
}config_containerd(){mkdir -p /etc/containerdcontainerd config default | tee /etc/containerd/config.toml &> /dev/null sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.tomlsed -i '/.*registry.mirrors.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n          endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.toml
}set_alias(){echo 'alias rmi="nerdctl images -qa|xargs nerdctl rmi -f"' >> ~/.bashrcecho 'alias rmc="nerdctl ps -qa|xargs nerdctl rm -f"' >> ~/.bashrc
}install_crictl_cni(){${COLOR}"开始安装Crictl工具,请稍等..."${END}tar xf ${CRICTL_FILE} -C /usr/local/bincat > /etc/crictl.yaml <<-EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF${COLOR}"开始安装CNI插件,请稍等..."${END}mkdir -p /opt/cni/bin/tar xf ${CNI_FILE} -C /opt/cni/bin/mkdir -p /etc/cni/net.d/cat > /etc/cni/net.d/10-containerd-net.conflist <<EOF
{"cniVersion": "1.0.0","name": "containerd-net","plugins": [{"type": "bridge","bridge": "cni0","isGateway": true,"ipMasq": true,"promiscMode": true,"ipam": {"type": "host-local","ranges": [[{"subnet": "10.88.0.0/16"}],[{"subnet": "2001:4860:4860::/64"}]],"routes": [{ "dst": "0.0.0.0/0" },{ "dst": "::/0" }]}},{"type": "portmap","capabilities": {"portMappings": true}}]
}
EOFsystemctl daemon-reload && systemctl enable --now containerd &> /dev/nullsystemctl restart containerdsystemctl is-active containerd &> /dev/null && ${COLOR}"Containerd 服务启动成功"${END} || { ${COLOR}"Containerd 启动失败"${END};exit; }ctr version &&  ${COLOR}"Containerd 安装成功"${END} || ${COLOR}"Containerd 安装失败"${END}    
}install_netdctl_buildkit(){${COLOR}"开始安装Netdctl..."${END}tar xf ${NETDCTL_FILE} -C /usr/local/bin/mkdir -p /etc/nerdctl/cat > /etc/nerdctl/nerdctl.toml <<EOF
namespace      = "default"
insecure_registry = true
EOF${COLOR}"开始安装Buildkit..."${END}tar xf ${BUILDKIT_FILE} -C /usr/local/cat > /usr/lib/systemd/system/buildkit.socket <<-EOF
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit[Socket]
ListenStream=%t/buildkit/buildkitd.sock
SocketMode=0660[Install]
WantedBy=sockets.target
EOFcat > /usr/lib/systemd/system/buildkit.service <<-EOF
[Unit]
Description=BuildKit
Requires=buildkit.socket
After=buildkit.socket
Documentation=https://github.com/moby/buildkit[Service]
Type=notify
ExecStart=/usr/local/bin/buildkitd --addr fd://[Install]
WantedBy=multi-user.target
EOFsystemctl daemon-reload && systemctl enable --now buildkit &> /dev/nullsystemctl is-active buildkit &> /dev/null && ${COLOR}"Buildkit 服务启动成功"${END} || { ${COLOR}"Buildkit 启动失败"${END};exit; }buildctl --version &&  ${COLOR}"Buildkit 安装成功"${END} || ${COLOR}"Buildkit 安装失败"${END}
}set_swap_limit(){if [ ${OS_RELEASE_VERSION} == "18" -o ${OS_RELEASE_VERSION} == "20" ];thengrep -q "swapaccount=1" /etc/default/grub && { ${COLOR}'"WARNING: No swap limit support"警告,已设置'${END};exit; }${COLOR}'设置Docker的"WARNING: No swap limit support"警告'${END}sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grubupdate-grub &> /dev/null${COLOR}"10秒后,机器会自动重启!"${END}sleep 10rebootfi
}main(){oscheck_fileset_kernelif [ ${OS_ID} == "CentOS" -o ${OS_ID} == "Rocky" ] &> /dev/null;thencentos_install_dockerelseubuntu_install_dockerficonfig_containerdset_aliasinstall_crictl_cniinstall_netdctl_buildkitset_swap_limit
}main
2.2.5.2 基于二进制包一键安装containerd脚本
[root@rocky9-2 ~]# cat install_containerd_binary.sh
#!/bin/bash
#
#******************************************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2024-02-15
#FileName:      install_containerd_binary.sh
#URL:           raymond.blog.csdn.net
#Description:   install_containerd_binary CentOS 7 & CentOS Stream 8/9 & Ubuntu 18.04/20.04/22.04 & Rocky 8/9
#Copyright (C): 2024 All rights reserved
#******************************************************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \\033[01;31m"
END='\033[0m'#Containerd下载地址:“https://github.com/containerd/containerd/releases/download/v1.7.12/cri-containerd-cni-1.7.12-linux-amd64.tar.gz”,请提前下载。
CONTAINERD_FILE=cri-containerd-cni-1.7.12-linux-amd64.tar.gz#Netdctl下载地址:“https://github.com/containerd/nerdctl/releases/download/v1.7.3/nerdctl-1.7.3-linux-amd64.tar.gz”,请提前下载。
NETDCTL_FILE=nerdctl-1.7.3-linux-amd64.tar.gz
#Buildkit下载地址:“https://github.com/moby/buildkit/releases/download/v0.12.5/buildkit-v0.12.5.linux-amd64.tar.gz”,请提前下载。
BUILDKIT_FILE=buildkit-v0.12.5.linux-amd64.tar.gzos(){OS_ID=`sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release`OS_RELEASE_VERSION=`sed -rn '/^VERSION_ID=/s@.*="?([0-9]+)\.?.*"?@\1@p' /etc/os-release`
}check_file (){cd ${SRC_DIR}if [ ! -e ${CONTAINERD_FILE} ];then${COLOR}"缺少${CONTAINERD_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelif [ ! -e ${NETDCTL_FILE} ];then${COLOR}"缺少${NETDCTL_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelif [ ! -e ${BUILDKIT_FILE} ];then${COLOR}"缺少${BUILDKIT_FILE}文件,请把文件放到${SRC_DIR}目录下"${END}exitelse${COLOR}"相关文件已准备好"${END}fi
}install_containerd(){ [ -f /usr/local/bin/containerd ] && { ${COLOR}"Containerd已存在,安装失败"${END};exit; }cat > /etc/modules-load.d/containerd.conf <<-EOF
overlay
br_netfilter
EOFmodprobe -- overlaymodprobe -- br_netfiltercat > /etc/sysctl.d/99-kubernetes-cri.conf <<-EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOFsysctl --system &> /dev/null${COLOR}"开始安装Containerd..."${END}tar xf ${CONTAINERD_FILE} -C /mkdir -p /etc/containerdcontainerd config default | tee /etc/containerd/config.toml &> /dev/null sed -ri -e 's/(.*SystemdCgroup = ).*/\1true/' -e "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.tomlsed -i '/.*registry.mirrors.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n          endpoint = ["https://registry.docker-cn.com" ,"https://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"]' /etc/containerd/config.tomlcat > /etc/crictl.yaml <<-EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOFsystemctl daemon-reload && systemctl enable --now containerd &> /dev/nullsystemctl is-active containerd &> /dev/null && ${COLOR}"Containerd 服务启动成功"${END} || { ${COLOR}"Containerd 启动失败"${END};exit; }ctr version &&  ${COLOR}"Containerd 安装成功"${END} || ${COLOR}"Containerd 安装失败"${END}
}set_alias(){echo 'alias rmi="nerdctl images -qa|xargs nerdctl rmi -f"' >> ~/.bashrcecho 'alias rmc="nerdctl ps -qa|xargs nerdctl rm -f"' >> ~/.bashrc
}install_netdctl_buildkit(){${COLOR}"开始安装Netdctl..."${END}tar xf ${NETDCTL_FILE} -C /usr/local/bin/mkdir -p /etc/nerdctl/cat > /etc/nerdctl/nerdctl.toml <<EOF
namespace      = "default"
insecure_registry = true
EOF${COLOR}"开始安装Buildkit..."${END}tar xf ${BUILDKIT_FILE} -C /usr/local/cat > /usr/lib/systemd/system/buildkit.socket <<-EOF
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit[Socket]
ListenStream=%t/buildkit/buildkitd.sock
SocketMode=0660[Install]
WantedBy=sockets.target
EOFcat > /usr/lib/systemd/system/buildkit.service <<-EOF
[Unit]
Description=BuildKit
Requires=buildkit.socket
After=buildkit.socket
Documentation=https://github.com/moby/buildkit[Service]
Type=notify
ExecStart=/usr/local/bin/buildkitd --addr fd://[Install]
WantedBy=multi-user.target
EOFsystemctl daemon-reload && systemctl enable --now buildkit &> /dev/nullsystemctl is-active buildkit &> /dev/null && ${COLOR}"Buildkit 服务启动成功"${END} || { ${COLOR}"Buildkit 启动失败"${END};exit; }buildctl --version &&  ${COLOR}"Buildkit 安装成功"${END} || ${COLOR}"Buildkit 安装失败"${END}
}set_swap_limit(){if [ ${OS_RELEASE_VERSION} == "18" -o ${OS_RELEASE_VERSION} == "20" ];thengrep -q "swapaccount=1" /etc/default/grub && { ${COLOR}'"WARNING: No swap limit support"警告,已设置'${END};exit; }${COLOR}'设置Docker的"WARNING: No swap limit support"警告'${END}sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ swapaccount=1"@' /etc/default/grubupdate-grub &> /dev/null${COLOR}"10秒后,机器会自动重启"${END}sleep 10rebootfi
}main(){oscheck_fileinstall_containerdset_aliasinstall_netdctl_buildkitset_swap_limit
}main

2.2.6 Containerd 常见命令操作

更换 Containerd 后,以往我们常用的 docker 命令也不再使用,取而代之的分别是 crictlctr 两个命令客户端。

  • crictl 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理容器运行时和镜像。
  • ctrcontainerd 的一个客户端工具。
  • ctr -v 输出的是 containerd 的版本,crictl -v 输出的是crictl的版本。
命令dockerctr(containerd)crictl(kubernetes)
查看运行的容器docker psctr task ls/ctr container lscrictl ps
查看镜像docker imagesctr image lscrictl images
查看容器日志docker logscrictl logs
查看容器数据信息docker inspectctr container infocrictl inspect
查看容器资源docker statscrictl stats
启动/关闭已有的容器docker start/stopctr task start/killcrictl start/stop
运行一个新的容器docker runctr run无(最小单元为 pod)
打标签docker tagctr image tag
创建一个新的容器docker createctr container createcrictl create
导入镜像docker loadctr image import
导出镜像docker savectr image export
删除容器docker rmctr container rmcrictl rm
删除镜像docker rmictr image rmcrictl rmi
拉取镜像docker pullctr image pullctictl pull
推送镜像docker pushctr image push
登录或在容器内部执行命令docker execcrictl exec
清空不用的容器docker image prunecrictl rmi --prune

更多命令操作,可以直接在命令行输入命令查看帮助。

docker --help
ctr --help
crictl --help

由于 Containerd 也有 namespaces 的概念,对于上层编排系统的支持,ctr 客户端 主要区分了 3 个命名空间分别是k8s.iomobydefault,以上我们用crictl操作的均在k8s.io命名空间,使用ctr 看镜像列表就需要加上-n 参数。crictl 是只有一个k8s.io命名空间,但是没有-n 参数。

【温馨提示】ctr images pull 拉取的镜像默认放在default,而 crictl pull 和 kubelet 默认拉取的镜像都在 k8s.io 命名空间下。所以通过ctr导入镜像的时候特别注意一点,最好指定命名空间。

2.2.6.1 ctr命令使用
# --address value, -a value 指定 containerd's GRPC server,默认 /run/containerd/containerd.sock# 下载镜像
[root@rocky9 ~]# ctr images pull docker.io/library/redis:alpine# 创建 container
[root@rocky9 ~]# ctr container create docker.io/library/redis:alpine redis-container# 查看
[root@rocky9 ~]# ctr container ls
CONTAINER          IMAGE                             RUNTIME                  
redis-container    docker.io/library/redis:alpine    io.containerd.runc.v2   # 后台启动
[root@rocky9 ~]# ctr task start -d redis-container# 查看 container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
redis-container    11741    RUNNING# 暂停容器运行
[root@rocky9 ~]# ctr task pause redis-container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
redis-container    11741    PAUSED# 恢复容器之前的状态
[root@rocky9 ~]# ctr task resume redis-container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
redis-container    11741    RUNNING# 删除container
[root@rocky9 ~]# ctr task rm redis-container
ERRO[0000] unable to delete redis-container              error="task must be stopped before deletion: running: failed precondition"
ctr: task must be stopped before deletion: running: failed precondition
# 运行的容器删不了# 停止容器运行
[root@rocky9 ~]# ctr task kill redis-container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
redis-container    11741    STOPPED
[root@rocky9 ~]# ctr task rm redis-container
[root@rocky9 ~]# ctr task ls
TASK    PID    STATUS
# 容器只有在STOPPED,状态才可以删除[root@rocky9 ~]# ctr container ls
CONTAINER          IMAGE                             RUNTIME                  
redis-container    docker.io/library/redis:alpine    io.containerd.runc.v2    
[root@rocky9 ~]# ctr container rm redis-container
[root@rocky9 ~]# ctr container ls
CONTAINER    IMAGE    RUNTIME  
#现在才彻底删除[root@rocky9 ~]# ctr images pull docker.io/library/nginx:1.24.0[root@rocky9 ~]# ctr container create docker.io/library/nginx:1.24.0 nginx-container
[root@rocky9 ~]# ctr container create docker.io/library/redis:alpine redis-container
[root@rocky9 ~]# ctr container ls
CONTAINER          IMAGE                             RUNTIME                  
nginx-container    docker.io/library/nginx:1.21.6    io.containerd.runc.v2    
redis-container    docker.io/library/redis:alpine    io.containerd.runc.v2  [root@rocky9 ~]# ctr task start -d nginx-container
[root@rocky9 ~]# ctr task start -d redis-container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
nginx-container    11977    RUNNING
redis-container    12052    RUNNING[root@rocky9 ~]# ctr task kill nginx-container
[root@rocky9 ~]# ctr task kill redis-container
[root@rocky9 ~]# ctr task ls
TASK               PID      STATUS    
nginx-container    11977    STOPPED
redis-container    12052    STOPPED[root@rocky9 ~]# ctr task rm nginx-container
[root@rocky9 ~]# ctr task rm redis-container
[root@rocky9 ~]# ctr task ls
TASK    PID    STATUS  # 删除所有容器
[root@rocky9 ~]# ctr container ls
CONTAINER          IMAGE                             RUNTIME                  
nginx-container    docker.io/library/nginx:1.21.6    io.containerd.runc.v2    
redis-container    docker.io/library/redis:alpine    io.containerd.runc.v2    
[root@rocky9 ~]# ctr container ls| awk -F" " 'NR!=1{print $1}'| xargs ctr container rm
[root@rocky9 ~]# ctr container ls
CONTAINER    IMAGE    RUNTIME # 查看命名空间
[root@rocky9 ~]# ctr ns ls
NAME    LABELS 
default # 查看 k8s 中正在运行的容器
[root@k8s-master01 ~]# ctr -n k8s.io task ls

配置私有镜像仓库http:

参考文档:https://github.com/containerd/cri/blob/master/docs/registry.md

[root@rocky9 ~]# vim /etc/containerd/config.toml
# 下面几行是配置私有仓库授权,如果没有私有仓库下面的不用设置[plugins."io.containerd.grpc.v1.cri".registry.configs] # 在这行下面配置如下内容[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.raymonds.cc".tls]insecure_skip_verify = true[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.raymonds.cc".auth]username = "admin"password = "123456"
...[plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://registry.docker-cn.com" ,"http://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"] # 在镜像加速后面配置下面配置
# 下面两行是配置私有仓库,如果没有私有仓库下面的不用设置[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.raymonds.cc"]endpoint = ["http://harbor.raymonds.cc"]# 使用下面命令修改
HARBOR_DOMAIN=harbor.raymonds.cc
sed -i -e '/.*registry.configs.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.configs."'''${HARBOR_DOMAIN}'''".tls]\n          insecure_skip_verify = true\n        [plugins."io.containerd.grpc.v1.cri".registry.configs."'''${HARBOR_DOMAIN}'''".auth]\n          username = "admin"\n          password = "123456"' -e '/.*endpoint = \[.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."'''${HARBOR_DOMAIN}'''"]\n          endpoint = ["http://'''${HARBOR_DOMAIN}'''"]' /etc/containerd/config.toml[root@rocky9 ~]# systemctl restart containerd[root@rocky9 ~]# cat >> /etc/hosts <<-EOF
172.31.0.29 harbor.raymonds.cc
EOF# 打tag
[root@rocky9 ~]# ctr images tag docker.io/library/redis:alpine  harbor.raymonds.cc/library/redis:alpine# push 上传镜像
[root@rocky9 ~]# ctr images push harbor.raymonds.cc/library/redis:alpine
...
----------------| 
elapsed: 0.1 s                                                                    total:   0.0 B (0.0 B/s)                                         
ctr: content digest sha256:431588b12459ea98eb57981ee240f8b0ea161145ab554f0d0a01d0815f0d7789: not found
# 注意可能会出现 ctr: content digest sha256:xxxxxx  not found,解决办法,下载完整的# 加“--all-platforms”参数就是下载完整的镜像
[root@rocky9 ~]# ctr image pull --all-platforms docker.io/library/redis:alpine[root@rocky9 ~]# ctr images rm harbor.raymonds.cc/library/redis:alpine[root@rocky9 ~]# ctr images tag docker.io/library/redis:alpine  harbor.raymonds.cc/library/redis:alpine[root@rocky9 ~]# ctr images push harbor.raymonds.cc/library/redis:alpine
...
ctr: failed to do request: Head "https://harbor.raymonds.cc/v2/library/redis/blobs/sha256:4f2827d94ec4fb6ff6a50d848af6a28207148465857aca97ed2ff7020f118f42": dial tcp 172.31.0.19:443: connect: connection refused
#使用了非https认证的harbor[root@rocky9 ~]# ctr images push --plain-http harbor.raymonds.cc/library/redis:alpine
...
ctr: push access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials
# 会出现ctr: no basic auth credentials[root@rocky9 ~]# ctr images push --plain-http -u admin harbor.raymonds.cc/library/redis:alpine
Password:
#这样才能上传镜像

从harbor上可以看到镜像已经被下载

在这里插入图片描述

# 导出镜像
[root@rocky9 ~]# ctr images export redis.tar docker.io/library/redis:alpine[root@rocky9 ~]# ctr images rm docker.io/library/redis:alpine# 导入镜像
[root@rocky9 ~]# ctr images import redis.tar[root@rocky9 ~]# ctr images ls -q |grep redis
docker.io/library/redis:alpine# 查看本地镜像
[root@rocky9 ~]# ctr images list -q# 删除所有镜像
[root@rocky9 ~]# ctr images list -q|xargs ctr images rm[root@rocky9 ~]# ctr images list -q# 从harbor拉取镜像到本地
[root@rocky9 ~]# ctr image pull --plain-http harbor.raymonds.cc/library/redis:alpine[root@rocky9 ~]# ctr images ls -q
harbor.raymonds.cc/library/redis:alpine

2.2.7 nerdctl命令实战操作

配置私有镜像仓库https:

参考文档:https://github.com/containerd/cri/blob/master/docs/registry.md

[root@rocky9-2 ~]# DOMAIN=raymonds.cc
[root@rocky9-2 ~]# mkdir -pv /etc/containerd/certs.d/harbor.${DOMAIN}
mkdir: created directory '/etc/containerd/certs.d'
mkdir: created directory '/etc/containerd/certs.d/harbor.raymonds.cc'[root@rocky9-4 ~]# DOMAIN=raymonds.cc
[root@rocky9-4 ~]# scp -r /apps/harbor/certs/{harbor.${DOMAIN}.cert,harbor.${DOMAIN}.key,ca.crt} 172.31.0.19:/etc/containerd/certs.d/harbor.${DOMAIN}[root@rocky9-2 ~]# tree /etc/containerd/certs.d/
-bash: tree: command not found
[root@rocky9-2 ~]# dnf -y install tree[root@rocky9-2 ~]# tree /etc/containerd/certs.d/harbor.raymonds.cc/
/etc/containerd/certs.d/harbor.raymonds.cc/
├── ca.crt
├── harbor.raymonds.cc.cert
└── harbor.raymonds.cc.key0 directories, 3 files[root@rocky9-2 ~]# vim /etc/containerd/config.toml
...
# 下面几行是配置私有仓库授权,如果没有私有仓库下面的不用设置[plugins."io.containerd.grpc.v1.cri".registry.configs] # 在这行下面配置如下内容[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.raymonds.cc".tls]ca_file = "/etc/containerd/certs.d/harbor.raymonds.cc/ca.crt"cert_file = "/etc/containerd/certs.d/harbor.raymonds.cc/harbor.raymonds.cc.cert"key_file = "/etc/containerd/certs.d/harbor.raymonds.cc/harbor.raymonds.cc.key"[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.raymonds.cc".auth]username = "admin"password = "123456"
...[plugins."io.containerd.grpc.v1.cri".registry.mirrors][plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]endpoint = ["https://registry.docker-cn.com" ,"http://hub-mirror.c.163.com" ,"https://docker.mirrors.ustc.edu.cn"] # 在镜像加速后面配置下面配置
# 下面两行是配置私有仓库,如果没有私有仓库下面的不用设置[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.raymonds.cc"]endpoint = ["https://harbor.raymonds.cc"]# 使用下面命令修改
sed -i -e '/.*registry.configs.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.'''${DOMAIN}'''".tls]\n          ca_file = "/etc/containerd/certs.d/harbor.'''${DOMAIN}'''/ca.crt"\n          cert_file = "/etc/containerd/certs.d/harbor.'''${DOMAIN}'''/harbor.'''${DOMAIN}'''.cert"\n          key_file = "/etc/containerd/certs.d/harbor.'''${DOMAIN}'''/harbor.'''${DOMAIN}'''.key"\n        [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.'''${DOMAIN}'''".auth]\n          username = "admin"\n          password = "123456"' -e '/.*endpoint = \[.*/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.'''${DOMAIN}'''"]\n          endpoint = ["https://harbor.'''${DOMAIN}'''"]' /etc/containerd/config.toml[root@rocky9-2 ~]# systemctl restart containerd[root@rocky9-2 ~]# cat >> /etc/hosts <<-EOF
172.31.0.39 harbor.raymonds.cc
EOF

1)拉取推送镜像

[root@rocky9-2 ~]# nerdctl pull redis:alpine[root@rocky9-2 ~]# nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED          PLATFORM       SIZE        BLOB SIZE
redis         alpine    1b503bb77079    2 seconds ago    linux/amd64    41.4 MiB    16.0 MiB[root@rocky9-2 ~]# nerdctl tag redis:alpine  harbor.raymonds.cc/library/redis:alpine
[root@rocky9-2 ~]# nerdctl images
REPOSITORY                          TAG       IMAGE ID        CREATED               PLATFORM       SIZE        BLOB SIZE
redis                               alpine    1b503bb77079    About a minute ago    linux/amd64    41.4 MiB    16.0 MiB
harbor.raymonds.cc/library/redis    alpine    1b503bb77079    2 seconds ago         linux/amd64    41.4 MiB    16.0 MiB# 通过 nerdctl 登录 harbor
[root@rocky9-2 ~]# nerdctl login harbor.raymonds.cc
Enter Username: admin
Enter Password: 
WARN[0004] skipping verifying HTTPS certs for "harbor.raymonds.cc" 
WARNING: Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded[root@rocky9-2 ~]# nerdctl push harbor.raymonds.cc/library/redis:alpine

登录harbor可以看到镜像已经被推送到镜像仓库了。

t1-5

[root@rocky9-2 ~]# nerdctl images -qa|xargs nerdctl rmi -f[root@rocky9-2 ~]# nerdctl pull harbor.raymonds.cc/library/redis:alpine[root@rocky9-2 ~]# nerdctl images
REPOSITORY                          TAG       IMAGE ID        CREATED           PLATFORM       SIZE        BLOB SIZE
harbor.raymonds.cc/library/redis    alpine    c476327f7a62    50 seconds ago    linux/amd64    41.4 MiB    16.0 MiB

2)镜像构建

[root@rocky9-2 ~]# cat > Dockerfile <<EOF
FROM nginx:alpine
RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html
EOF

然后在文件所在目录执行镜像构建命令:

# 不加-n指定命名空间,crictl看不到,kubelet也不能使用它,默认在default命名空间下
nerdctl build -t nginx:nerctl -f ./Dockerfile .
### 参数解释
# -t:指定镜像名称
# . :当前目录Dockerfile
# -f:指定Dockerfile路径
#  --no-cache:不缓存[root@rocky9-2 ~]# nerdctl build -t nginx:nerctl -f ./Dockerfile .
[+] Building 30.9s (6/6) FINISHED                                                                                       => [internal] load build definition from Dockerfile                                                               0.0s=> => transferring dockerfile: 131B                                                                               0.0s=> [internal] load metadata for docker.io/library/nginx:alpine                                                    5.9s=> [internal] load .dockerignore                                                                                  0.0s=> => transferring context: 2B                                                                                    0.0s=> [1/2] FROM docker.io/library/nginx:alpine@sha256:cedce0b6e276efe62bbf15345053f44cdc5d1c834a63ab7619aa8355093  18.5s=> => resolve docker.io/library/nginx:alpine@sha256:cedce0b6e276efe62bbf15345053f44cdc5d1c834a63ab7619aa8355093f  0.0s=> => sha256:a85ccd8c07bd7090e8a37ab878413b035a370e872367b145a0c0aaaaf60ccbdf 12.65MB / 12.65MB                  12.3s=> => sha256:e1c681003a03fff277ecf90fccf526881bcc2e006c9e371b58f45680d54c1954 1.40kB / 1.40kB                     3.7s=> => sha256:d6a456492aaa4c003389fec3da0939f31c505232fcf1925db314815a196c444f 1.21kB / 1.21kB                     3.7s=> => sha256:a101c9a82b88a3fa561030af162d98a130ca3bc0501b2e70594410dd426f2c9b 393B / 393B                         3.7s=> => sha256:c3ea3344e711fd7111dee02f17deebceb725ed1d0ee998f7fb472114dc1399ce 629B / 629B                         1.7s=> => sha256:018b9065ed0dfedff48bbd11f6014960bb496e71c395f772bfad123ab33a1800 1.90MB / 1.90MB                     9.8s=> => sha256:619be1103602d98e1963557998c954c892b3872986c27365e9f651f5bc27cab8 3.40MB / 3.40MB                    13.6s=> => sha256:c7059f3102784cd05dc96fff74a52bce9fa50fea724ece08748507fa3455999b 956B / 956B                         2.6s=> => extracting sha256:619be1103602d98e1963557998c954c892b3872986c27365e9f651f5bc27cab8                          0.2s=> => extracting sha256:018b9065ed0dfedff48bbd11f6014960bb496e71c395f772bfad123ab33a1800                          0.3s=> => extracting sha256:c3ea3344e711fd7111dee02f17deebceb725ed1d0ee998f7fb472114dc1399ce                          0.0s=> => extracting sha256:c7059f3102784cd05dc96fff74a52bce9fa50fea724ece08748507fa3455999b                          0.0s=> => extracting sha256:a101c9a82b88a3fa561030af162d98a130ca3bc0501b2e70594410dd426f2c9b                          0.0s=> => extracting sha256:d6a456492aaa4c003389fec3da0939f31c505232fcf1925db314815a196c444f                          0.0s=> => extracting sha256:e1c681003a03fff277ecf90fccf526881bcc2e006c9e371b58f45680d54c1954                          0.0s=> => extracting sha256:a85ccd8c07bd7090e8a37ab878413b035a370e872367b145a0c0aaaaf60ccbdf                          0.5s=> [2/2] RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html                              0.1s=> exporting to docker image format                                                                               6.2s=> => exporting layers                                                                                            5.6s=> => exporting manifest sha256:dab994ac6deff60045929e5b3ba15165a538b6054bb382f9bd3d884a73b86e32                  0.0s=> => exporting config sha256:e728497d739a1956f9ca87173fc1a5e89c2d0e392b9a04a453f6a21f79cd9497                    0.0s=> => sending tarball                                                                                             0.6s
unpacking docker.io/library/nginx:nerctl (sha256:dab994ac6deff60045929e5b3ba15165a538b6054bb382f9bd3d884a73b86e32)...
Loaded image: docker.io/library/nginx:nerctl[root@rocky9-2 ~]# nerdctl images
REPOSITORY                          TAG       IMAGE ID        CREATED           PLATFORM       SIZE        BLOB SIZE
nginx                               nerctl    dab994ac6def    48 seconds ago    linux/amd64    44.2 MiB    17.1 MiB
harbor.raymonds.cc/library/redis    alpine    c476327f7a62    5 minutes ago     linux/amd64    41.4 MiB    16.0 MiB

3)打标签 tag

[root@rocky9 ~]# nerdctl tag nginx:nerctl harbor.raymonds.cc/library/nginx:nerctl[root@rocky9-2 ~]# nerdctl images
REPOSITORY                          TAG       IMAGE ID        CREATED           PLATFORM       SIZE        BLOB SIZE
nginx                               nerctl    dab994ac6def    48 seconds ago    linux/amd64    44.2 MiB    17.1 MiB
harbor.raymonds.cc/library/redis    alpine    c476327f7a62    5 minutes ago     linux/amd64    41.4 MiB    16.0 MiB

4)将镜像推送到 Harbor

开始将镜像推送到 harbor

[root@rocky9-2 ~]# nerdctl push harbor.raymonds.cc/library/nginx:nerctl

可以看到镜像已经上传到harbor镜像仓库

t1-6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/779167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【八大排序】一篇文章搞定所有排序

文章目录 1.排序的概念2.常见排序算法的实现2.1 插入排序2.1.1直接插入排序2.1.2希尔排序 2.2选择排序2.2.1直接选择排序:2.2.2堆排序 2.3交换排序2.3.1冒泡排序2.3.2快速排序Hoare法前后指针法挖坑法非递归版本 2.4归并排序递归版本非递归版本 2.5计数排序3.排序的比较 1.排序…

2024年EDM邮件营销群发平台怎么选?

在2024年选择适合的EDM&#xff08;电子邮件直接营销&#xff09;邮件营销群发平台时&#xff0c;需要考虑以下几个关键要素来评估云衔科技以及其他供应商的产品或服务是否符合您的需求&#xff1a; 一、功能完备性&#xff1a; 1、智能自动化&#xff1a;确保云衔科技提供的…

用DataGrip连接hive时报错:User: root is not allowed to impersonate plck5,解决方法

你可以尝试关闭主机校验 修改hive安装目录下conf/hive-site.xml,将hive.server2.enable.doAs设置成false <property><name>hive.server2.enable.doAs</name><value>false</value><description>Setting this property to true will have H…

警惕.360勒索病毒:如何预防.360勒索病毒攻击

导言&#xff1a; 在网络安全领域&#xff0c;勒索病毒是一种非常危险的恶意软件&#xff0c;它以其独特的加密方式和高昂的赎金要求&#xff0c;给个人和企业带来了严重的损失。.360勒索病毒便是其中之一&#xff0c;它属于BeijingCrypt勒索病毒家族&#xff0c;具有高度的隐…

office安装和卸载

目录 安装文件下载安装破解卸载 安装文件下载 链接&#xff1a;https://pan.baidu.com/s/1cBRv-NwNOf2pQyd7XBRu6A?pwdabcd 提取码&#xff1a;abcd 提供内容如下: ├── pdf │ ├── Access2007宝典.pdf │ ├── Excel2007宝典.pdf │ ├── Project2007完全掌…

scGRN:人与鼠的GRN平台

基因调控网络GRN是包含转录因子TFs与其下游靶基因之间的调控相互作用的可解释图模型。了解GRN的拓扑结构和动力学是解释疾病病因机制和将相应发现转化为新疗法的基础。单细胞多组学技术的最新进展促使从单细胞转录组学和表观基因组学数据中以前所未有的分辨率推断GRN。在这里&a…

ClickHouse03-小白如何快速搭建ClickHouse集群

普通测试通常使用ClickHouse单节点就可以了&#xff0c;但是生产环境不免需要考虑多活、负载等高可用问题&#xff0c;集群就成了基础需求 ClickHouse在集群的选择上&#xff0c;作者已知的有两种&#xff1a; 使用ZooKeeper作为节点协调的组件&#xff0c;使用ClickHouse-Kee…

红米手机Redmi 不会自动弹出USB调试选项,如何处理?(红米小米均适用)

参考&#xff1a; 红米手机Redmi 不会自动弹出USB调试选项&#xff0c;如何处理&#xff1f;&#xff08;红米小米均适用&#xff09; - 知乎 以红米9A为例&#xff1b; 【设置】菜单进入后&#xff0c;找到【我的设备】&#xff0c; 选择【全部参数】&#xff0c; 对准miui版…

SQL96 返回顾客名称和相关订单号(表的普通联结、内联结inner join..on..)

方法一&#xff1a;普通联结 select cust_name, order_num from Customers C,Orders O where C.cust_id O.cust_id order by cust_name,order_num;方法二&#xff1a;使用内连接 select cust_name,order_num from Customers C inner join Orders O on C.cust_id O.cust_id …

测试人员如何提交一条高质量的bug

测试人员在测试软件过程中&#xff0c;发现bug是必然的&#xff0c;那么发现bug后就要提交bug到缺陷管理系统中&#xff0c;如何提交一条高质量的bug&#xff0c;是每一个测试人员值得深思的问题&#xff0c;如果bug提交的不规范&#xff0c;不准确会导致开发人员理解错误&…

Python工具箱系列(五十一)

九宫格与词云 对图片进行九宫格切割&#xff0c;并且放到微信朋友圈曾经风靡一时。对于python来说&#xff0c;这个也非常简单。 from PIL import Image import mathdef ninerectanglegrid(inputfilename):"""实现九宫格切割Args:inputfilename (string): 输入…

golang import引用项目下其他文件内函数

初始化项目 go mod init [module名字] go mod init project 项目结构 go mod 文件 代码 需要暴露给外界使用的变量/函数名必须大写 在main.go中引入&#xff0c;当前项目模块名/要引用的包名 package mainimport (// 这里的路径开头为项目go.mod中的module"project/…

DHCP设置二

华为ensp模拟实验 准备工作 需要设备&#xff1a;路由器 一台 交换机 两台 pc两台 ip划分网段 &#xff1a;192.168.10.0 24 192.168.20.0 24 当我们准备好之后就可以开机了 开机实验 点击菜单栏小三角&#xff0c;开启设备。 输入system-view进入系统视图&#x…

深度解析:Elasticsearch检索请求原理

在上一篇文章中&#xff0c;我们学习了 Elasticsearch 的写入流程&#xff0c;今天我们来学习一下 Elasticsearch 的读取流程&#xff0c;当一个检索请求到达 Elasticsearch 之后是如何进行检索的呢&#xff1f; 下面先说一下一个总的检索流程。 1、客户端发送请求到任意一个…

卓翼飞思全国合作伙伴火热招募,共筑智能生态

摘要&#xff1a;市场有可为&#xff0c;政策高扶持 抢占AI高地&#xff0c;共筑智能生态 卓翼飞思全国合作伙伴招募计划 在人工智能的浪潮下&#xff0c;我们正见证一个由数据驱动、智能主导的新时代的到来。无人智能技术作为人工智能领域的重要分支&#xff0c;正在以其独特…

Qt篇——Qt无法翻译tr()里面的字符串

最近遇到使用Qt语言家翻译功能时&#xff0c;ui界面中的中文都能够翻译成英文&#xff0c;但是tr("测试")这种动态设置给控件的中文&#xff0c;无法翻译&#xff08;lang_English.ts文件中的翻译已经正确添加了tr()字符串的翻译&#xff09;。 上网搜了很多资料&am…

Linux 常用命令(1)

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;专栏系列&#xff1a;Linux 随笔集合 …

【漏洞复现】通天星CMSV6 admin 弱口令漏洞(CVE-2024-29666)

0x01 产品简介 CMSV6平台是基于车辆位置信息服务和实时视频传输服务的创新技术和开放运营理念。为GPS运营商车辆硬件设备制造商、车队管理企业等车辆运营相关企业提供核心基础数据服务。 0x02 漏洞概述 CMSV6 7.31.0.2、7.32.0.3版本中存在弱密码漏洞&#xff0c;未授权的攻…

【Linux】图文详解Xshell远程连接服务器:以Amazon EC2 VPS为例

文章目录 问题描述解决方案Q&A 问题描述 本地cmd或powershell使用ssh -i “your.pem” user_nameip_address是可以登录Amazon EC2云服务器的。 然而&#xff0c;当使用XShell以SSH加载PEM文件方式登录亚马逊EC2云服务器&#xff0c;一直出现输入密码的问题&#xff0c;如…

小狐狸JSON-RPC:wallet_addEthereumChain(添加指定链)

wallet_addethereumchain&#xff08;添加网络&#xff09; var res await window.ethereum.request({"method": "wallet_addEthereumChain","params": [{"chainId": "0x64", // 链 ID &#xff08;必填&#xff09;"…