Containerd【轻量级容器管理工具】

文章目录

  • Containerd【轻量级容器管理工具】
    • 一、Containerd介绍
      • 1、Containerd的由来
      • 2、Containerd概念
      • 3、Containerd架构
      • 4、几个概念区分
    • 二、Containerd安装
      • step1:安装containerd
      • step2:安装runC
      • step3:安装cni插件和cni工具包
    • 三、ctr命令行操作
      • 1、Containerd镜像管理
      • 2、Containerd容器管理
      • 3、Containerd命名空间管理
      • 4、Containerd网络管理
      • 5、Containerd数据持久化
      • 6、Docker集成Container容器管理

Containerd【轻量级容器管理工具】

Kubernetes v1.24 之前的版本直接集成了 Docker Engine 的一个组件,名为 dockershim [用于调用Docker]。 这种特殊的直接整合不再是 Kubernetes 的一部分 (这次删除被作为 v1.20 发行版本的一部分宣布)。 这意味Kubernetes从版本1.24开始就弃用Docker作为容器运行时,取而代之的是更加轻量级的Containerd。

containerd可用作 Linux 和 Windows 的守护进程。它管理其主机系统的完整容器生命周期,从图像传输和存储到容器执行和监督,再到低级存储到网络附件等等。

一、Containerd介绍

1、Containerd的由来

【Docker名噪一时,捐出runC】2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司说服Docker公司把其容器核心技术libcontainer捐给OCI(Open Container Intiative),并更名为runC

【CNCF成立,kubernetes被迫开源】为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公司带领RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市场——大规模容器编排应用场景。Google公司把自己内部使用的Brog系统开源——Kubernetes,也就是我们今天所说的云原生技术生态。

【Docker妥协,贡献出Containerd】2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes。至此,Docker在大规模容器编排应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,依此说明Docker依旧是一个PaaS平台。

【k8s宣布不支持Docker,Containerd成为CRI主角】2020年CNCF基金会宣布Kubernetes 1.20版本将不再仅支持Docker容器管理工具,此事的起因主要也与Docker捐给CNCF基金会的Containerd有关,早期为了实现Kubernetes能够使用Docker实现容器管理,专门在Kubernetes组件中集成一个shim技术,用来将Kubernetes 容器运行时接口(CRI,Container Runntime Interface)调用翻译成Docker的API,这样就可以很好地使用Docker了。但是随着Kubernetes在全球技术市场的广泛应用,有更多的容器管理工具的出现,它们都想能够借助于Kubernetes被用户所使用,所以就提出标准化容器运行时接口,只要适配了这个接口就可以集成到Kubernetes生态当中,所以Kubernetes取消了对shim的维护,并且由于Containerd技术的成功,可以实现无缝对接Kubernetes,所以接下来Kubernetes容器运行时的主角是Containerd。

2、Containerd概念

早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。

和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。另外独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

Containerd是一个工业标准的容器运行时,重点是它简洁,健壮,便携,在Linux和window上可以作为一个守护进程运行,它可以管理主机系统上容器的完整的生命周期:镜像传输和存储,容器的执行和监控,低级别的存储和网络。

每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。

Containerd和docker不同,containerd重点是集成在大规模的系统中,例如kubernetes、Swarm、Mesos等【对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。】。Containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用

Containerd的特点:

  • 简洁的基于 gRPC 的 API 和 client library。
  • 完整的 OCI 支持(runtime 和 image spec)。
  • 同时具备稳定性和高性能的定义良好的容器核心功能。
  • 一个解耦的系统(让 image、filesystem、runtime 解耦合),实现插件式的扩展和重用。

Containerd的作用:

  • 管理容器的生命周期(从创建容器到销毁容器)。
  • 拉取/推送容器镜像。
  • 存储管理(管理镜像及容器数据的存储)。
  • 调用 runC 运行容器(与 runC 等容器运行时交互)。
  • 管理容器网络接口及网络。

使用 bucketbench 对 Docker、crio 和 Containerd 的性能测试结果,包括启动、停止和删除容器,以比较它们所耗的时间,可以发现Containerd 在各个方面都表现良好,总体性能优于 Docker 和 crio。

3、Containerd架构

Containerd 采用标准的 C/S 架构:服务端通过 GRPC 协议提供稳定的 API;客户端通过调用服务端的 API 进行高级的操作。

为了实现解耦,Containerd 将不同的职责划分给不同的组件,每个组件就相当于一个子系统(subsystem)。连接不同子系统的组件被称为模块。

Containerd 被分为三个大块: Storage 、 Metadata 和 Runtime。

Containerd 两大子系统为:
Bundle : 在 Containerd 中,Bundle 包含了配置、元数据和根文件系统数据,你可以理解为 容器的文件系统。而 Bundle 子系统允许用户从镜像中提取和打包 Bundles。
Runtime : Runtime 子系统用来执行 Bundles,比如创建容器。其中,每一个子系统的行为都由一个或多个模块协作完成(架构图中的 Core 部分)。

Containerd【轻量级容器管理工具】_第1张图片

4、几个概念区分

containerd 是一个高级容器运行时,又名容器管理器。简单来说,它是一个守护进程,在单个主机上管理完整的容器生命周期:创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。

ctr 是作为 containerd 项目的一部分提供的命令行客户端。该ctr界面 [显然] 与 Docker CLI不兼容,乍一看,可能看起来不太用户友好。因为它的主要受众是测试守护进程的容器开发人员。ctr + containerd比docker + dockerd更接近实际的容器。

nerdctl 是一个相对较新的containerd命令行客户端。与ctr不同,nerdctl的目标是用户友好和docker兼容。在某种程度上,nerdctl + containerd可以无缝地替代docker + dockerd。

crictl 是一个命令行客户端,用于 [kubernetes] CRI兼容的容器运行时。引入 Kubernetes 容器运行时接口 (CRI)以使 Kubernetes 容器运行时不可知。Kubernetes节点代理kubelet实现了 CRI客户端 API,可以使用任何实现 CRI 服务器 API的容器运行时来管理其节点上的容器和 Pod。

二、Containerd安装

containerd官网:https://containerd.io/

containerd官方安装步骤:https://github.com/containerd/containerd/blob/main/docs/getting-started.md

下载好相应的安装部署包【所有安装包都可在github上进行下载】如下:

$ ll
-rw-r--r-- 1 root root   118639 Sep  2 08:32 cni-1.1.2.tar.gz      # cni工具源码包[注意要与cni插件兼容]# cni工具1.1.2兼容cni插件1.0.0
-rw-r--r-- 1 root root 36336160 Sep  1 13:49 cni-plugins-linux-amd64-v1.0.0.tgz #cni插件
-rw-r--r-- 1 root root 44458241 Sep  1 13:20 containerd-1.6.8-linux-amd64.tar.gz #containerd
-rw-r--r-- 1 root root 10685899 Sep  1 14:36 nerdctl-0.22.2-linux-amd64.tar.gz #nerdctl
-rw-r--r-- 1 root root  9431456 Sep  1 13:58 runc.amd64 #runC

step1:安装containerd

$ tar Cxzvf /usr/local containerd-1.6.8-linux-amd64.tar.gz

将containerd服务设置卫开机启动,先配置为系统服务

$ vim /etc/systemd/system/containerd.service

内容如下:

$ cat /etc/systemd/system/containerd.service
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
#uncomment to enable the experimental sbservice (sandboxed) version of containerd/cri integration
#Environment="ENABLE_CRI_SANDBOXES=sandboxed"
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/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=infinity
# 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

将containerd服务设置卫开机启动。

$ systemctl enable --now containerd
# 验证
$ ctr version
Client:
  Version:  v1.6.8
  Revision: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
  Go version: go1.17.13

Server:
  Version:  v1.6.8
  Revision: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
  UUID: 87222662-9eb1-44cb-998a-689c9efce638

至此,containerd安装完成。

step2:安装runC

由于二进制包中提供的runC默认需要系统中安装seccomp支持,需要单独安装,且不同版本runC 对seccomp版本要求一致,所以建议单独下载runC二进制包进行安装,里面包含了seccomp模块支持。

$ install -m 755 runc.amd64 /usr/local/sbin/runc
# 验证
$ runc -v
runc version 1.1.4
commit: v1.1.4-0-g5fd4c4d1
spec: 1.0.2-dev
go: go1.17.10
libseccomp: 2.5.4

step3:安装cni插件和cni工具包

$ mkdir -p /home/cni-plugins
$ tar Cxzvf /home/cni-plugins cni-plugins-linux-amd64-v1.0.0.tgz
## 该二进制文件是静态构建的,可以在任何 Linux 发行版上运行
# cni工具1.1.2兼容cni插件1.0.0
$ mkdir -p /home/cni-tools
$ tar Cxzvf /home/cni-tools cni-1.1.2.tar.gz

完成。

三、ctr命令行操作

ctr是作为 containerd 项目的一部分提供的命令行客户端。

该ctr界面 [显然] 与 Docker CLI不兼容,乍一看,可能看起来不太用户友好。显然,它的主要受众是测试守护进程的容器开发人员。但是,由于它最接近实际的 containerd API,因此它可以作为一种很好的探索手段——通过检查可用命令,可以大致了解 containerd可以做什么和不可以做什么。

$ ctr --help
NAME:
   ctr - 
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI


USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.6.8

DESCRIPTION:
   
ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.

COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

1、Containerd镜像管理

# 拉取镜像  拉取镜像,完全合格的参考似乎是必需的,所以不能忽略镜像仓库或标签部分。
$ ctr images pull --all-platforms docker.io/library/nginx:alpine
# --all-platforms  指定所有平台镜像  
# --platform       指定系统平台
$ ctr images pull --platform linux/amd64 docker.io/library/nginx:latest

# 查看镜像
$ ctr images ls

# 挂载镜像
$ ctr images mount docker.io/library/nginx:alpine /mnt
$ ls /mnt
$ umount /mnt

# 镜像导出,并保存为nginx.img文件
$ ctr i export --all-platforms nginx.img docker.io/library/nginx:alpine
$ ls -l
-rw-r--r-- 1 root root 70138368 Sep  2 16:33 nginx.img

# 镜像导入
$ ctr images import nginx.img

# 镜像打tag
$ ctr images tag docker.io/library/nginx:alpine nginx:alpine

# 镜像对比
$ ctr images check

2、Containerd容器管理

# 创建【静态】容器
# 该命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个container对象只是包含了运行一个容器所需的资源及配置的数据结构,例如: namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程(本案例为nginx)还没有启动。需要使用`ctr tasks`命令才能获取一个动态容器。
$ ctr container create docker.io/library/nginx:alpine testnginx1

# 启动【动态】容器  创建容器和任务子命令分离
$ ctr task start -d testnginx1

# 直接运行一个动态容器【容器的IP就是宿主机的IP】
# ctr运行命令实际上是ctr容器创建+ ctr任务启动的快捷方式
$ ctr run -d --net-host docker.io/library/nginx:alpine testnginx2

# 查看【静态】容器
$ ctr container ls

# 查看【动态】容器
$ ctr task ps testnginx1
PID      INFO
64574    -
64613    -
64614    -
64615    -
64616    -
# 物理机上查看
$ ps -ef | grep nginx
root      64574  64553  0 16:41 ?        00:00:00 nginx: master process nginx -g daemon off;
101       64613  64574  0 16:41 ?        00:00:00 nginx: worker process
101       64614  64574  0 16:41 ?        00:00:00 nginx: worker process
101       64615  64574  0 16:41 ?        00:00:00 nginx: worker process
101       64616  64574  0 16:41 ?        00:00:00 nginx: worker process

# 进入容器
$ ctr task exec --exec-id 1 testnginx2 sh
# 查看网卡
ifconfig  
ens33     Link encap:Ethernet  HWaddr 00:0C:29:32:CC:B0  
          inet addr:192.168.168.201  Bcast:192.168.168.255  Mask:255.255.255.0
          inet6 addr: fe80::63d5:da66:d3db:fa1c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:476940 errors:0 dropped:0 overruns:0 frame:0
          TX packets:595381 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:175687016 (167.5 MiB)  TX bytes:149770479 (142.8 MiB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
# 为容器中运行的网站添加网站文件
echo "hello nginx2" > /usr/share/nginx/html/index.html
# 在容器里访问
curl 127.0.0.1
# 退出容器          
exit

# 在宿主机上访问
$ curl 192.168.168.201
hello nginx2

# 暂停容器
$ ctr task pause testnginx2

# 恢复容器
$ ctr task resume testnginx2

# 停止容器
$ ctr task kill testnginx2

# 删除动态容器【必须先停止】
$ ctr task delete testnginx2

# 删除静态容器
$ ctr container delete testnginx2

3、Containerd命名空间管理

containerd中namespace的作用为:隔离运行的容器,可以实现运行多个容器。

# 拉取镜像
$ ctr namespace --help

# 创建命名空间
$ ctr ns create testns

# 查看命名空间
$ ctr ns ls

# 在命名空间中进行镜像、容器等相关操作
$ ctr -n testns images pull docker.io/library/nginx:latest
$ ctr -n testns images ls
$ ctr -n testns container create docker.io/library/nginx:latest
$ ctr -n testns container ls

# 删除命名空间
$ ctr ns rm testns

4、Containerd网络管理

默认Containerd管理的容器仅有lo网络,无法访问容器之外的网络,可以为其添加网络插件,使用容器可以连接外网,CNI(Container Network Interface)

cni插件和cni工具包已经在前面第二章节已经部署完毕。

# cni插件目录
$ cd /home/cni-plugins
# cni工具包目录
$ cd /home/cni-tools/cni-1.1.2
# cni工具1.1.2兼容cni插件1.0.0
  • 下面先开始准备容器网络配置文件,用于为容器提供网关、IP地址等。
$ vim /etc/cni/net.d/10-mynet.conf
$ vim /etc/cni/net.d/99-loopback.conf
$ cat /etc/cni/net.d/10-mynet.conf
{
    "cniVersion": "1.0.0",
    "name": "mynet",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.66.0.0/16",
        "routes": [
            {
                "dst": "0.0.0.0/0"
            }
        ]
    }
}
$ cat /etc/cni/net.d/99-loopback.conf
{
    "cniVerion": "1.0.0",
    "name": "lo",
    "type": "loopback"
}
  • 生成cni网络
# 获取epel源
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

#安装jq【jq是一个'出色'的'针对-->JSON处理器'的命令行】
$ yum -y install jq

# 进入cni工具目录
$ cd /home/cni-tools/cni-1.1.2

# 执行脚本文件,基于/etc/cni/net.d/目录中的*.conf配置文件生成容器网络
# CNI_PATH是cni插件安装的目录
$ CNI_PATH=/home/cni-plugins ./priv-net-run.sh echo "Hello World"
# cni插件和cni工具包版本要兼容,否则可能会报错如下:
mynet : error executing ADD: {
    "code": 1,
    "msg": "incompatible CNI versions",
    "details": "config is \"1.0.0\", plugin supports [\"0.1.0\" \"0.2.0\" \"0.3.0\" \"0.3.1\" \"0.4.0\"]"
}

#安装成功后,在宿主机上查看是否生成容器网络名为cni0的网桥
$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
...
7: cni0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 6a:32:bc:eb:0f:23 brd ff:ff:ff:ff:ff:ff
    inet 10.66.0.1/16 brd 10.66.255.255 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::6832:bcff:feeb:f23/64 scope link 
       valid_lft forever preferred_lft forever
  • 创建容器
$ ctr images pull docker.io/library/busybox:latest
$ ctr run -d docker.io/library/busybox:latest busybox
$ ctr tasks exec --exec-id $RANDOM -t busybox sh
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0

#获取容器进程ID及其网络命名空间
$ pid=$(ctr tasks ls | grep busybox | awk '{print $2}') && echo $pid
39287
$ netnspath=/proc/$pid/ns/net && echo $netnspath
/proc/39287/ns/net

# 进入目录为指定容器添加网络配置
$ cd /home/cni-tools/cni-1.1.2/scripts/
$ CNI_PATH=/home/cni-plugins ./exec-plugins.sh add $pid $netnspath
  • 验证容器网络与宿主机网络的互访功能
# 验证
# 进入容器确认是否添加网卡信息
$ ctr tasks exec --exec-id $RANDOM -t busybox sh
/ # ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 5a:36:90:c1:33:b1 brd ff:ff:ff:ff:ff:ff
    inet 10.66.0.4/16 brd 10.66.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5836:90ff:fec1:33b1/64 scope link 
       valid_lft forever preferred_lft forever
# 在容器中ping容器宿主机IP地址
/ # ping -c 2 192.168.168.201
PING 192.168.168.201 (192.168.168.201): 56 data bytes
64 bytes from 192.168.168.201: seq=0 ttl=64 time=0.067 ms
64 bytes from 192.168.168.201: seq=1 ttl=64 time=0.070 ms

--- 192.168.168.201 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.068/0.070 ms

# 在容器中ping容器宿主机IP地址
/ # ping -c 2 192.168.168.2
PING 192.168.168.2 (192.168.168.2): 56 data bytes
64 bytes from 192.168.168.2: seq=0 ttl=127 time=0.141 ms
64 bytes from 192.168.168.2: seq=1 ttl=127 time=0.324 ms

--- 192.168.168.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.141/0.232/0.324 ms

# 在容器中ping容器宿主机IP地址
/ # ping -c 2 192.168.168.202
PING 192.168.168.201 (192.168.168.202): 56 data bytes
64 bytes from 192.168.168.202: seq=0 ttl=64 time=0.067 ms
64 bytes from 192.168.168.202: seq=1 ttl=64 time=0.070 ms

--- 192.168.168.202 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.068/0.070 ms

# 在容器中开启httpd服务
/ # echo "containerd net web test" > /tmp/index.html
/ # httpd -h /tmp
/ # wget -O - -q 127.0.0.1
containerd net web test
/ # exit

#在宿主机访问容器提供的httpd服务
$ curl 10.66.0.4
containerd net web test

5、Containerd数据持久化

实现把宿主机目录挂载至Containerd容器中,实现容器数据持久化存储

# 创建一个静态容器,实现宿主机目录与容器挂载,src=/tmp 为宿主机目录 dst=/hostdir 为容器中目录
$ ctr container create docker.io/library/busybox:latest busybox3 --mount type=bind,src=/tmp,dst=/hostdir,options=rbind:rw

# 运行用户进程
$ ctr tasks start -d busybox3 bash
$ ctr t ls
TASK        PID       STATUS    
busybox     39287     RUNNING
busybox3    105003    RUNNING

# 进入容器,查看是否挂载成功
$ ctr tasks exec --exec-id $RANDOM -t busybox3 sh
/ # ls /hostdir/
ks-script-GSRMK8                                                         vmware-root_6389-1958486695
systemd-private-cc74dd8802f0428490924757e690c750-chronyd.service-9TDICh  vmware-root_6511-1689719547
vmware-root_6359-1949639453                                              yum.log
# 向容器中挂载目录中添加文件
/ # echo "hello world" > /hostdir/test.txt
/ # ls /hostdir/
ks-script-GSRMK8                                                         vmware-root_6389-1958486695
systemd-private-cc74dd8802f0428490924757e690c750-chronyd.service-9TDICh  vmware-root_6511-1689719547
test.txt                                                                 yum.log
vmware-root_6359-1949639453
# 在宿主机上查看被容器挂载的目录中是否添加了新的文件,已添加表明被容器挂载成功,并可以读写此目录中内容。
$ cat /tmp/test.txt 
hello world

6、Docker集成Container容器管理

目前Containerd主要任务还在于解决容器运行时的问题,对于其周边生态还不完善,所以有时需要借助:Docker结合Containerd来实现Docker完整的功能应用。

Docker安装与使用教程:https://blog.csdn.net/qq_41822345/article/details/107123094

docker运行的容器默认在moby命名空间下。

# 安装docker
$ yum install docker
# 启动docker
$ systemctl start docker

# 运行一个容器
$ docker run -d nginx:latest
$ docker ps

# 查看ctr命令下的namespace,发现多了一个moby命名空间。moby即为docker使用的命名空间。
$ ctr namespace ls
NAME    LABELS 
default        
k8s.io         
moby

# 查看moby命名空间下的容器和任务
$ ctr -n moby container ls
$ ctr -n moby tasks ls

你可能感兴趣的:(容器技术,GO,container,docker,kubernetes)