一、版本信息
内核版本:5.19.12-1.el7.elrepo.x86_64
系统版本:CentOS Linux release 7.9.2009
二、下载文件:
wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.25.0/crictl-v1.25.0-linux-amd64.tar.gz
wget https://github.com/containerd/containerd/releases/download/v1.6.8/containerd-1.6.8-linux-amd64.tar.gz
上面下载的文件说明
runc.amd64:cri-containerd-cni-1.6.8-linux-amd64.tar.gz 包中包含的 runc 在 CentOS 7 下的动态链接有问题,这里需要从 runc 的 github 上单独下载 runc,并替换安装 containerd 后中的 runc
containerd-1.6.8-linux-amd64.tar.gz:包含containerd和它的containerd-shim以及命令行工具ctr
crictl-v1.25.0-linux-amd64.tar.gz:包含CRI的命令行工具crictl
三、添加相关的模块
1、运行docker时,出现以下信息,我们需要修改存储驱动的默认文件系统
问题原因:
centos系统docker默认使用存储驱动是devicemapper,而这种存储驱动有两种模式loop-lvm和direct-lvm,不巧默认又使用了比较低效的loop-lvm
解决方案一:使用direct-lvm,配置方式网上很多 ,百度一下就行了
解决方案二:使用overlay文件系统,因为这个方案比较简单,
配置步骤如下:
# 添加自开启自动加载模块 cat << EOF > /etc/modules-load.d/containerd.conf overlay br_netfilter EOF # 如果 containerd 已经运行着,需要删除永久存储的数据 # rm -rf /var/lib/containerd/
另外提示:docker需要修改这个配置
# 如果 docker 已经运行着,需要删除永久存储的数据 # rm -rf /var/lib/docker vim /usr/lib/systemd/system/docker.service # ExecStart=/usr/bin/dockerd ExecStart=/usr/bin/dockerd --storage-driver=overlay -g /opt/docker
2、br_netfilter 模块用于将桥接流量转发至 iptables 链,br_netfilter 内核参数需要开启转发,如果不部署k8s的话,可以不用加载这个模块
3、手动加载模块
modprobe overlay
modprobe br_netfilter
# 检查模块情况
lsmod | grep -E 'overlay|br_netfilter'
四、部署containerd
mkdir /data/software/containerd
mkdir /etc/containerd
tar zxf containerd-1.6.8-linux-amd64.tar.gz -C /data/software/containerd/
tar zxf crictl-v1.25.0-linux-amd64.tar.gz -C /data/software/containerd/bin/
mv runc.amd64 /data/software/containerd/bin/runc
chmod +x /data/software/containerd/bin/runc
cat > /etc/profile.d/containerd_home.sh <<'EOF'
export CONTAINERD_HOME=/data/software/containerd
export PATH=$PATH:$CONTAINERD_HOME/bin
EOF
source /etc/profile
建立运行时 runc 软链接,不然会报错,说找到这个环境的命令,(个人猜测: 应该是运行时的用户环境不一样,导致在这个用户的环境下找不到该命令: runc)
ln -s /data/software/containerd/bin/runc /usr/local/bin/
五、生成containerd的默认配置文件/etc/containerd/config.toml
containerd config default > /etc/containerd/config.toml
修改数据永久存储位置、修改拉取镜像默认地址(改为国内源)、改为 systemd 作为管理containerd容器服务
mkdir /data/software/containerd/data
vim /etc/containerd/config.toml
# 大概在第6行
root = "/data/software/containerd/data"
# 大概在第61行
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
六、配置/etc/crictl.yaml
不然会报错
cat > /etc/crictl.yaml <<'EOF'
runtime-endpoint: "unix:///run/containerd/containerd.sock"
image-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 0
debug: false
pull-image-on-create: false
disable-pull-on-run: false
EOF
# 或者执行下面的两条命令来生成配置文件
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock
七、配置管理 containerd 的 system 配置文件
cat > /usr/lib/systemd/system/containerd.service <<'EOF'
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/data/software/containerd/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
八、启动 containerd 并设置开机自启
systemctl enable containerd --now
九、测试
systemctl status containerd.service
crictl images
十、命令差别信息
1、crictl缺少对具体镜像的管理能力,crictl是k8s中CRI(容器运行时接口)的客户端,k8s使用该客户端和containerd进行交互,crictl命令运行的默认 命名空间 是在:k8s.io
2、ctr是containerd自带的CLI命令行工具,ctr命令运行的默认 命名空间 是在:default
3、这里我先验证一下
1)ctr查看命名空间
ctr ns ls
一、1)不指定 命名空间 拉取镜像。ctr比较严格,需要完整的URL路径:docker.io/library/[镜像名称]:[tag]
ctr image pull docker.io/library/redis:latest
一、2)命令 crictl 查看镜像情况(查不到上面拉取的镜像)
crictl image ls
一、3)命令 ctr 查看镜像情况(可以查到上面拉取的镜像)
ctr image ls
二、1)指定 命名空间 拉取镜像
ctr -n k8s.io image pull docker.io/library/redis:latest
二、2)命令 crictl 查看镜像情况(可以查到 ctr 指定 命名空间 下拉取的镜像)
crictl image ls
二、3)命令 ctr 查看镜像情况,要指定 命令空间名称 才能查看的到
ctr -n k8s.io image ls
十一、部分命令使用总结
命令 | docker |
查看命名空间 | 无 |
指定命令运行命令 | 无 |
查看镜像 | docker images |
拉取镜像 | docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 |
修改镜像标签 | docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 172.17.0.10:5000/pause:3.5 |
推送镜像 | docker login 172.17.0.42:5000 docker push 172.17.0.10:5000/pause:3.5 |
导出镜像 | docker save 172.17.0.10:5000/pause:3.5 -o pause.tar |
删除镜像 | docker rmi 172.17.0.10:5000/pause:3.5 |
导入镜像 | docker load -i pause.tar |
创建一个新的容器,但不运行 | docker create |
运行一个新的容器 | docker run |
查看运行的容器 | docker ps |
查看容器日志 | docker logs |
查看容器数据信息 | docker inspect |
查看容器资源 | docker stats |
启动/关闭已有的容器 | docker start/stop |
删除容器 | docker rm |
在容器内部执行命令 | docker exec |
命令 | ctr(containerd) |
查看命名空间 | ctr ns ls |
指定命令运行命令 | ctr -n 命名空间名称(如: k8s.io) 命令(如:image ls) |
查看镜像 | ctr image ls |
拉取镜像 | ctr -n k8s.io image pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 (这里有个问题,如果pull私有仓库,你的私有仓库必须有配置https) |
修改镜像标签 | ctr -n k8s.io image tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 172.17.0.10:5000/pause:3.5 |
推送镜像 | ctr -n k8s.io image push 172.17.0.10:5000/pause:3.5 --user admin:Harbor12345 (这里有个问题,你的私有仓库必须有配置https) |
导出镜像 | ctr -n k8s.io image export pause.tar 172.17.0.10:5000/pause:3.5 |
删除镜像 | ctr -n k8s.io image rm 172.17.0.10:5000/pause:3.5 |
导入镜像 | ctr -n k8s.io image import pause.tar |
创建一个新的容器,但不运行 | ctr -n k8s.io task/container create docker.io/library/centos:latest centos(运行容器的名称) |
运行一个新的容器 | ctr -n k8s.io image pull docker.io/library/redis:alpine3.13 ctr -n k8s.io run -d docker.io/library/redis:alpine3.13 redis(运行容器的名称) |
查看运行的容器 | ctr -n k8s.io task/container ls |
查看容器日志 | 无 |
查看容器数据信息 | ctr -n k8s.io task/container info redis(运行容器的名称) |
查看容器资源 | 无 |
启动/关闭已有的容器 | ctr task/container start/kill |
删除容器 | ctr task/container rm |
在容器内部执行命令 | 无 |
命令 | crictl(kubernetes) |
查看命名空间 | 无 |
指定命令运行命令 | 无 |
查看镜像 | crictl images |
拉取镜像 | crictl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5 |
修改镜像标签 | 无 |
推送镜像 | 无 |
导出镜像 | 无 |
删除镜像 | crictl rmi 172.17.0.10:5000/pause:3.5(它会把源:registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5一起删了) |
导入镜像 | 无 |
创建一个新的容器,但不运行 | crictl create |
运行一个新的容器 | 无(最小单元为pod) |
查看运行的容器 | crictl ps |
查看容器日志 | crictl logs |
查看容器数据信息 | crictl inspect |
查看容器资源 | crictl stats |
启动/关闭已有的容器 | crictl start/stop |
删除容器 | crictl rm |
在容器内部执行命令 | crictl exec |
十二、ctr(containerd)命令总结
下载镜像
ctr image pull docker.io/library/redis:alpine3.13
查看镜像:ctr images ls 可以简写成: ctr i ls
ctr images ls
运行容器
ctr run -d docker.io/library/redis:alpine3.13 redis
查看容器运行信息
ctr container ls
查看容器运行状态(其实是查看任务,这个跟 ctr container ls 是分开的)
ctr task ls
进入容器(--exec-id redis-sh意思是: 进入容器时的一个名称,是唯一不能重复使用的,如果发送断开再用这个名称就报错了,只能用另外一个名称)
ctr container exec -t --exec-id redis-sh redis sh
暂停容器
ctr task pause redis
ctr task ls
恢复容器为启动状态
ctr tasks resume redis
ctr task ls
停止容器
ctr task kill redis
ctr task ls
停止的容器是不能恢复启动状态的
ctr task resume redis
ctr task ls
删除容器
ctr task delete redis
ctr task ls
ctr container ls
ctr container rm redis
ctr container ls
只有停止的容器才能删除(所以要先删任务,再来操作删除容器)
十三、代替docker命令的工具(nerdctl)
nerdctl工具包有精简版和全包版,这里只要精简版就可以了
1、通过代理下载 nerdctl 工具
wget https://ghproxy.com/https://github.com/containerd/nerdctl/releases/download/v0.23.0/nerdctl-0.23.0-linux-amd64.tar.gz
2、安装 nerdctl 工具
tar zxf nerdctl-0.23.0-linux-amd64.tar.gz
mv nerdctl /usr/local/bin/
rm -f containerd-rootless-setuptool.sh containerd-rootless.sh
3、配置docker命令通用
ln -s /usr/local/bin/nerdctl /usr/local/bin/docker
# 配置tab补全,弄了docke的软链接可以用,但不能用tab去补全相关的参数
echo 'source <(nerdctl completion bash)' >> /root/.bashrc
source /root/.bashrc
4、配置默认命名空间
nerdctl ns ls
nerdctl ps
mkdir /etc/nerdctl/
cat >> /etc/nerdctl/nerdctl.toml <<'EOF'
namespace = "k8s.io"
EOF
nerdctl ps
十四、配置容器打包工具(buildkit)
1、通过代理下载 buildkit 工具
wget https://ghproxy.com/https://github.com/moby/buildkit/releases/download/v0.10.5/buildkit-v0.10.5.linux-amd64.tar.gz
2、安装 buildkit 工具
tar -zxvf buildkit-v0.10.5.linux-amd64.tar.gz -C /data/software/containerd/
ll /data/software/containerd/bin/
# 配置 systemd 管理
cat > /etc/systemd/system/buildkit.socket <<'EOF'
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit
[Socket]
ListenStream=%t/buildkit/buildkitd.sock
[Install]
WantedBy=sockets.target
EOF
cat > /etc/systemd/system/buildkit.service <<'EOF'
[Unit]
Description=BuildKit
Requires=buildkit.socket
After=buildkit.socketDocumentation=https://github.com/moby/buildkit
[Service]
ExecStart=/data/software/containerd/bin/buildkitd --oci-worker=false --containerd-worker=true
[Install]
WantedBy=multi-user.target
EOF
3、启动 buildkit 工具并设置开机自启
# 重新加载
systemctl daemon-reload
# 启动并设置开启自启
systemctl enable --now buildkit
# 检查
systemctl status buildkit
4、编写dockerfile
cat > Dockerfile <<'EOF'
FROM alpine:3.13.5
# Here we install GNU libc (aka glibc) and set C.UTF-8 locale as default.
ENV LANG=C.UTF-8
RUN echo "**** install packages ****" && \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
ALPINE_GLIBC_BASE_URL="http://192.168.240.189:88/chfs/shared" && \
ALPINE_GLIBC_PACKAGE_VERSION="2.33-r0" && \
ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
echo \
"-----BEGIN PUBLIC KEY-----\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApZ2u1KJKUu/fW4A25y9m\
y70AGEa/J3Wi5ibNVGNn1gT1r0VfgeWd0pUybS4UmcHdiNzxJPgoWQhV2SSW1JYu\
tOqKZF5QSN6X937PTUpNBjUvLtTQ1ve1fp39uf/lEXPpFpOPL88LKnDBgbh7wkCp\
m2KzLVGChf83MS0ShL6G9EQIAUxLm99VpgRjwqTQ/KfzGtpke1wqws4au0Ab4qPY\
KXvMLSPLUp7cfulWvhmZSegr5AdhNw5KNizPqCJT8ZrGvgHypXyiFvvAH5YRtSsc\
Zvo9GI2e2MaZyo9/lvb+LbLEJZKEQckqRj4P26gmASrZEPStwc+yqy1ShHLA0j6m\
1QIDAQAB\
-----END PUBLIC KEY-----" | sed 's/ */\n/g' > "/etc/apk/keys/sgerrand.rsa.pub" && \
wget \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
apk add --no-cache \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
\
rm "/etc/apk/keys/sgerrand.rsa.pub" && \
/usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true && \
echo "export LANG=$LANG" > /etc/profile.d/locale.sh && \
\
apk del glibc-i18n && \
\
rm -f "/root/.wget-hsts" && \
apk del .build-dependencies && \
rm \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME"
RUN apk update --no-cache && apk add ca-certificates --no-cache && \
apk add tzdata --no-cache && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
EOF
5、测试打包镜像
docker build -t base-alpine .
nerdctl image ls