官网链接:https://github.com/containerd/containerd/blob/main/docs/getting-started.md
介绍
containerd是一个推行简单、健壮和可移植的容器运行时行业标准,可以运行在windows和linux后台,可以实现容器生命周期管理,比如镜像传输与存储、容器执行与监管、底层存储和网络插件等。containerd是一个CNCF毕业项目。
优势
- 自定义参数
containerd的配置文件在/etc/containerd/config.toml,具体配置可以看here
,可以使用如下指令生成默认配置:
containerd config default > /etc/containerd/config.toml
- 实现自定义containerd client
具体实现可以参考ctr和nerdctr,下边给一个demo:
package main
import (
"context"
"fmt"
"log"
"syscall"
"time"
"github.com/containerd/containerd/v2/cio"
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/oci"
"github.com/containerd/containerd/v2/namespaces"
)
func main() {
if err := redisExample(); err != nil {
log.Fatal(err)
}
}
func redisExample() error {
// create a new client connected to the default socket path for containerd
client, err := containerd.New("/run/containerd/containerd.sock")
if err != nil {
return err
}
defer client.Close()
// create a new context with an "example" namespace
ctx := namespaces.WithNamespace(context.Background(), "example")
// pull the redis image from DockerHub
image, err := client.Pull(ctx, "docker.io/library/redis:alpine", containerd.WithPullUnpack)
if err != nil {
return err
}
// create a container
container, err := client.NewContainer(
ctx,
"redis-server",
containerd.WithImage(image),
containerd.WithNewSnapshot("redis-server-snapshot", image),
containerd.WithNewSpec(oci.WithImageConfig(image)),
)
if err != nil {
return err
}
defer container.Delete(ctx, containerd.WithSnapshotCleanup)
// create a task from the container
task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
if err != nil {
return err
}
defer task.Delete(ctx)
// make sure we wait before calling start
exitStatusC, err := task.Wait(ctx)
if err != nil {
return err
}
// call start on the task to execute the redis server
if err := task.Start(ctx); err != nil {
return err
}
// sleep for a lil bit to see the logs
time.Sleep(3 * time.Second)
// kill the process and get the exit status
if err := task.Kill(ctx, syscall.SIGTERM); err != nil {
return err
}
// wait for the process to fully exit and print out the exit status
status := <-exitStatusC
code, _, err := status.Result()
if err != nil {
return err
}
fmt.Printf("redis-server exited with status: %d\n", code)
return nil
}
运行如下:
> go build main.go
> sudo ./main
1:C 04 Aug 20:41:37.682 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 04 Aug 20:41:37.682 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 04 Aug 20:41:37.682 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 04 Aug 20:41:37.682 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
1:M 04 Aug 20:41:37.682 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
1:M 04 Aug 20:41:37.682 # Current maximum open files is 1024. maxclients has been reduced to 992 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
1:M 04 Aug 20:41:37.683 * Running mode=standalone, port=6379.
1:M 04 Aug 20:41:37.683 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 04 Aug 20:41:37.684 # Server initialized
1:M 04 Aug 20:41:37.684 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 04 Aug 20:41:37.684 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
1:M 04 Aug 20:41:37.684 * Ready to accept connections
1:signal-handler (1501879300) Received SIGTERM scheduling shutdown...
1:M 04 Aug 20:41:40.791 # User requested shutdown...
1:M 04 Aug 20:41:40.791 * Saving the final RDB snapshot before exiting.
1:M 04 Aug 20:41:40.794 * DB saved on disk
1:M 04 Aug 20:41:40.794 # Redis is now ready to exit, bye bye...
redis-server exited with status: 0
实现原理
containerd设计师嵌入一个大的系统,而不是直接被开发人员或者终端用户使用。其设计架构如下:部署
- 第一种方式 使用官方二进制
注:这种方式需要知道自己系统的架构是amd64、x86_64还是arm64,其次需要安装好runc
和CNI插件CNI plugins
(1)安装containerd
使用下载链接下载官方二进制,校验过hash后,放置在/usr/local路径
如果通过systemd来启动containerd,需要地址下载containerd.service,之后放置在/usr/local/lib/systemd/system/containerd.service下,使用如下指令启动:
systemctl daemon-reload
systemctl enable --now containerd
(2)安装runc
通过runc下载对应架构的二进制,校验过hash后,放置在/usr/local/sbin/runc路径,runc二进制适配所有linux平台,或者使用如下指令:
$ install -m 755 runc.amd64 /usr/local/sbin/runc
(3)安装CNI插件
通过cni下载CNI插件放置到系统路径/opt/cni/bin下,使用如下指令:
$ mkdir -p /opt/cni/bin
$ tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz
./
./macvlan
./static
./vlan
./portmap
./host-local
./vrf
./bridge
./tuning
./firewall
./host-device
./sbr
./loopback
./dhcp
./ptp
./ipvlan
./bandwidth
- 第二种方式 通过apt-get或dnf
不同的系统有不同的下载方式,提供4种常见的方式:
- 第三种方式 源代码构建
源码构建可以参考BUILDING.md
与containerd交互的cli有以下三个:
| Name | Community | API | Target | Web site |
| --- | --- | --- | --- | --- |
|ctr
| containerd | Native | For debugging only | (None, seectr --help
to learn the usage) |
|nerdctl
| containerd (non-core) | Native | General-purpose | https://github.com/containerd/nerdctl |
|crictl
| Kubernetes SIG-node | CRI | For debugging only | https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md |
ctr是containerd内置的指令,其他的指令需要手动安装。下边是ctr的指令demo:
ctr images pull docker.io/library/redis:alpine
ctr run docker.io/library/redis:alpine redis