暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

3.Containerd容器运行时的配置浅析与知识扩充实践

WeiyiGeek 2022-04-26
3379

公众号关注「WeiyiGeek

设为「特别关注」,每天带你玩转网络安全运维、应用开发、物联网IOT学习!


本章目录:

  • 0x00 Containerd 容器运行时配置指南

    • 如何配置 Containerd 的 systemd 守护进程服务?

    • 如何查看 Containerd 相关插件及其存目录?

    • 如何生成 Containerd 默认的 config.toml 配置文件?

    • 如何配置 Containerd 让其支持懒拉取 (eStargz)?

    • 如何配置 Containerd 在 harbor 私有仓库拉取镜像?

    • 如何进行 Containerd 基本配置?


原文地址: https://blog.weiyigeek.top/2021/6-30-581.html


0x00 Containerd 容器运行时配置指南

描述: containerd 是一个在任何系统上运行的简单守护程序。它提供了一个带有旋钮的最小配置,用于配置守护程序以及在必要时使用哪些插件。

在当前最新的 Containerd v1.6.2版本中其/etc/containerd/config.toml
配置文件项存在变化, 下面的文档中提供了常用配置以及CRI插件配置的说明。

官方参考地址: https://github.com/containerd/containerd/blob/main/docs/cri/config.md


如何配置 Containerd 的 systemd 守护进程服务?

$ cat lib/systemd/system/containerd.service[Unit]Description=containerd container runtimeDocumentation=https://containerd.ioAfter=network.target local-fs.target[Service]ExecStartPre=-/sbin/modprobe overlayExecStart=/usr/bin/containerdType=notify# 允许 containerd 及其运行时管理它所创建的容器的 cgroupsDelegate=yes# 确保在 containerd 被关闭时仅终止 containerd 守护程序,而不终止任何子进程,如填充程序和容器KillMode=processRestart=alwaysRestartSec=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=infinityLimitCORE=infinityLimitNOFILE=infinity# Comment TasksMax if your systemd version does not supports it.Only systemd 226 and above support this version.TasksMax=infinityOOMScoreAdjust=-999[Install]WantedBy=multi-user.target


如何查看 Containerd 相关插件及其存目录?

描述:在 containerd 配置文件中,您将找到持久性和运行时存储位置的设置,以及各种 API 的 grpc、调试和指标地址。containerd 在主机系统上还有两个不同的存储位置, 一个用于持久性数据,另一个用于运行时状态

  • root将用于存储容器的任何类型的持久性数据。快照、内容、容器和映像的元数据以及任何插件数据都将保留在此位置。根目录也为容器加载的插件提供了命名空间。每个插件都有自己的目录来存储数据。containerd本身实际上没有任何需要存储的持久性数据,其功能来自加载的插件。

/var/lib/containerd/├── io.containerd.content.v1.content│   ├── blobs│   └── ingest├── io.containerd.metadata.v1.bolt│   └── meta.db├── io.containerd.runtime.v2.task│   ├── default│   └── example├── io.containerd.snapshotter.v1.btrfs└── io.containerd.snapshotter.v1.overlayfs    ├── metadata.db    └── snapshots
  • state将用于存储任何类型的临时数据, 套接字、pids、运行时状态、挂载点和其他在重新启动之间不得保留的插件数据存储在此位置。

/run/containerd├── containerd.sock├── debug.sock├── io.containerd.runtime.v2.task│   └── default│       └── redis│           ├── config.json│           ├── init.pid│           ├── log.json│           └── rootfs│               ├── bin│               ├── data│               ├── dev│               ├── etc│               ├── home│               ├── lib│               ├── media│               ├── mnt│               ├── proc│               ├── root│               ├── run│               ├── sbin│               ├── srv│               ├── sys│               ├── tmp│               ├── usr│               └── var└── runc    └── default        └── redis            └── state.json


如何生成 Containerd 默认的 config.toml 配置文件?

$ mkdir -vp etc/containerd/ && containerd config default > etc/containerd/config.toml


如何配置 Containerd 让其支持懒拉取 (eStargz)?

描述: 从 v1.4 版本开始 containerd 便支持懒拉取, Stargz Snapshotter
 是使 containerd 能够处理 eStargz的插件,在 Kubernetes 上我们可以通过如下配置/etc/containerd/config.toml
启用了此功能。

Stargz Snapshotter插件(containerd-stargz-grpc二进制文件)也需要作为单独的进程运行, 其启动示例文件为:

# etc/systemd/system/stargz-snapshotter.service[Unit]Description=stargz snapshotter (Rootless)PartOf=containerd.service[Service]Environment=PATH=/usr/local/bin:/sbin:/usr/sbin:/usr/local/elasticsearch-7.15.0/jdk/bin:/usr/local/elasticsearch-7.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/binEnvironment=IPFS_PATH=/home/cqzk/.local/share/ipfsExecStart="/usr/local/bin/containerd-rootless-setuptool.sh" nsenter -- containerd-stargz-grpc -address "/run/user/1000/containerd-stargz-grpc/containerd-stargz-grpc.sock" -root "/home/cqzk/.local/share/containerd-stargz-grpc" -config "/home/cqzk/.config/containerd-stargz-grpc/config.toml"ExecReload=/bin/kill -s HUP $MAINPIDRestartSec=2Restart=alwaysType=simpleKillMode=mixed[Install]WantedBy=default.target

温馨提示: 官方systemd示例地址(https://github.com/containerd/stargz-snapshotter/blob/v0.6.0/script/config/etc/systemd/system/stargz-snapshotter.service)

修改 etc/containerd/config.toml 配置文件示例:

version = 2# Plug stargz snapshotter into containerd Containerd recognizes stargz snapshotter through specified socket address.[proxy_plugins]  [proxy_plugins.stargz]    type = "snapshot"    address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock"# Use stargz snapshotter through CRI[plugins."io.containerd.grpc.v1.cri".containerd]  snapshotter = "stargz"  disable_snapshot_annotations = false


如何配置 Containerd 在 harbor 私有仓库拉取镜像?

描述: 在k8s的1.20版本发布之后,对外宣称在1.23.x不再使用dokershim作为默认的底层容器运行时,而是通过Container Runtime Interface(CRI)
使用containerd来作为容器运行时, 因此原来在docker中配置的个人仓库环境不再起作用,导致k8s配置pods时拉取镜像失败, 本节将进行演示如何在 containerd
 配置从私有仓库拉取镜像。

Step 1.kubernetes 使用 containerd 拉取harbor仓库中镜像配置说明, 项目地址介绍: https://github.com/containerd/cri/blob/master/docs/registry.md


Step 2.containerd 的配置文件 (相当于docker 的 daemon.json)

$ vim etc/containerd/config.toml[plugins."io.containerd.grpc.v1.cri".registry]   [plugins."io.containerd.grpc.v1.cri".registry.mirrors]      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]        endpoint = ["https://xlx9erfu.mirror.aliyuncs.com"]                         # 使用阿里镜像源到此为配置文件默认生成,之后为需要添加的内容      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.weiyigeek.top"] # 内部私有仓库配置        endpoint = ["https://harbor.weiyigeek.top"]                                [plugins."io.containerd.grpc.v1.cri".registry.configs]     [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.weiyigeek.to"]        [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.weiyigeek.top".auth]   # harbor 认证的账号密码 配置         username = "admin"                                                               password = "Harbor12345"         auth = ""         identitytoken = ""       [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.weiyigeek.top".tls]    # harbor 证书认证配置         insecure_skip_verify = false                     # 是否跳过证书认证         ca_file   = "/etc/containerd/harbor/ca.crt"      # CA 证书         cert_file = "/etc/containerd/harbor/harbor.crt"  # harbor 证书         key_file  = "/etc/containerd/harbor/harbor.key"  # harbor 私钥


Step 3.重载 systemd 的 daemon守护进程并重启containerd.service服务, 然后k8s集群便可正常从 harbor.weiyigeek.top 拉取镜像了。

systemctl daemon-reload && systemctl restart containerd.service


Step 4.虽然上面的方式可以使k8s直接拉取镜像,但是在利用 ctl命令 进行手动拉取镜像此时会报如下错误(巨坑-经过无数次失败测试,原本以为是CA证书签发的harbor证书问题),即使你在config.toml中配置insecure_skip_verify为true也是不行的。

# 错误信息$ ctr -n k8s.io i pull harbor.weiyigeek.top/devops/jenkins-jnlp:3.13.8-alpineINFO[0000] trying next host  error="failed to do request: Head \"https://harbor.weiyigeek.top/v2/devops/jenkins-jnlp/manifests/3.13.8-alpine\": x509: certificate signed by unknown authority" host=harbor.weiyigeek.topctr: failed to resolve reference "harbor.weiyigeek.top/devops/jenkins-jnlp:3.13.8-alpine": failed to do request: Head "https://harbor.weiyigeek.top/v2/devops/jenkins-jnlp/manifests/3.13.8-alpine": x509: certificate signed by unknown authority# 解决办法1.指定 -k 参数跳过证书校验。$ ctr -n k8s.io i pull -k harbor.weiyigeek.top/devops/jenkins-jnlp:3.13.8-alpine# 解决办法2.指定CA证书、Harbor相关证书文件路径。$ ctr -n k8s.io i pull --tlscacert ca.crt --tlscert harbor.crt --tlskey harbor.key  harbor.weiyigeek.top/devops/jenkins-jnlp:3.13.6-alpine


如何进行 Containerd 基本配置?

  • 自定义配置 containerd 持久化目录和 containerd 运行时状态信息进行。

cat etc/containerd/config.tomlversion = 2# containerd 持久化目录root = "/var/lib/containerd"# containerd 运行时状态信息state = "/run/containerd"oom_score = 0
  • 由于国内环境原因我们需要将 sandbox_image 镜像源设置为阿里云google_containers镜像源。

$ vim etc/containerd/config.toml  [plugins."io.containerd.grpc.v1.cri"]  sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6"# 或者$ sed -i "s#k8s.gcr.io/pause#registry.cn-hangzhou.aliyuncs.com/google_containers/pause#g"  etc/containerd/config.toml


  • 为了快速docker.io镜像拉取速度,同样我们需要为其设置国内镜像源。

$ vim etc/containerd/config.toml  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]      endpoint = ["https://xlx9erfu.mirror.aliyuncs.com"]# 或者执行sed -i '/registry.mirrors]/a\ \ \ \ \ \ \ \ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]' etc/containerd/config.tomlsed -i '/registry.mirrors."docker.io"]/a\ \ \ \ \ \ \ \ \ \ endpoint = ["https://xlx9erfu.mirror.aliyuncs.com"]' etc/containerd/config.toml


  • 使用虽然 containerd 和 Kubernetes 默认使用旧版驱动程序来管理 cgroups,但建议在基于 systemd 的主机上使用该驱动程序,以符合 cgroup 的“单编写器”规则。

$ vim etc/containerd/config.toml[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]  SystemdCgroup = true# 或者$ sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' etc/containerd/config.toml

于此同时, 我们需要在K8S的KubeletConfiguration资源清单中, 还必须将 cgroup 驱动程序配置为使用 “systemd”。

kind: KubeletConfigurationapiVersion: kubelet.config.k8s.io/v1beta1cgroupDriver: "systemd"


  • 设置CRI插件默认快照器设置为 overlayfs(类似于 Docker 的存储驱动程序), 一般是无需更改默认即为overlayfs.

$ vim etc/containerd/config.toml  [plugins."io.containerd.grpc.v1.cri".containerd]    snapshotter = "overlayfs"# 或者sed -ri 's#snapshotter = "\w*"#snapshotter = "overlayfs"#' etc/containerd/config.toml


  • 设置运行时类, 下面的示例将自定义运行时注册到 containerd 中:

# 默认配置[plugins."io.containerd.grpc.v1.cri".containerd]  default_runtime_name = "runc" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]      base_runtime_spec = ""      container_annotations = []      pod_annotations = []      privileged_without_host_devices = false      runtime_engine = ""      runtime_root = ""      runtime_type = "io.containerd.runc.v2"            [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]        BinaryName = ""        CriuImagePath = ""        CriuPath = ""        CriuWorkPath = ""        IoGid = 0        IoUid = 0        NoNewKeyring = false        NoPivotRoot = false        Root = ""        ShimCgroup = ""        SystemdCgroup = true# 自定义别名为crun的运行时$ vim etc/containerd/config.tomlversion = 2[plugins."io.containerd.grpc.v1.cri".containerd]  default_runtime_name = "crun"   # 注意别名  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]    # crun: https://github.com/containers/crun    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]      runtime_type = "io.containerd.runc.v2"      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]        BinaryName = "/usr/local/bin/crun"    # gVisor: https://gvisor.dev/    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.gvisor]      runtime_type = "io.containerd.runsc.v1"    # Kata Containers: https://katacontainers.io/    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]      runtime_type = "io.containerd.kata.v2"

此外,还必须将以下RuntimeClass资源安装到具有该角色的群集中 cluster-admin

apiVersion: node.k8s.io/v1kind: RuntimeClassmetadata:  name: crunhandler: crun---apiVersion: node.k8s.io/v1kind: RuntimeClassmetadata:  name: gvisorhandler: gvisor---apiVersion: node.k8s.io/v1kind: RuntimeClassmetadata:  name: katahandler: kata

要将运行时类应用于 pod,请设置.spec.runtimeClassName

apiVersion: v1kind: Podspec:  runtimeClassName: crun


  • 在 config.toml 中为容器设置私有仓库主机配置的简单示例在配置路径处创建一个目录树, 其中包含一个表示要配置的主机命名空间的目录, 然后在中添加一个文件以配置主机命名空间。

# 例如, 公共的 docker.io 镜像仓库为例$ tree etc/containerd/certs.d/etc/containerd/certs.d└── docker.io    └── hosts.toml$ cat etc/containerd/certs.d/docker.io/hosts.tomlserver = "https://docker.io"[host."https://registry-1.docker.io"]  capabilities = ["pull", "resolve"]# 例如, 私有的 hub.weiyigeek.top 镜像仓库配置$ mkdir -vp etc/containerd/certs.d/hub.weiyigeek.top/$ touch etc/containerd/certs.d/hub.weiyigeek.top/hosts.toml$ vim  etc/containerd/certs.d/hub.weiyigeek.top/hosts.tomlserver = "https://hub.weiyigeek.top"[host."https://hub.weiyigeek.top"]
ca = "/path/to/ca.crt"
  • Bolt 元数据插件允许在命名空间之间配置内容共享策略。
    默认模式“shared”将使 Blob 在被拉入任何命名空间后在所有命名空间中都可用, 如果使用后端中已存在的“Expected”摘要打开编写器,则 Blob 将被拉入命名空间, 备用模式“隔离”要求客户端在将 Blob 添加到命名空间之前,通过向引入提供所有内容来证明它们有权访问内容。

默认值为“共享”。虽然这在很大程度上是最需要的策略,但可以通过以下配置更改为“隔离”模式:


$ vim /etc/containerd/config.toml
version = 2
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "isolated"

补充说明: 在“隔离”模式下,还可以通过将标签添加到特定命名空间来仅共享该命名空间的内容。这将使其 Blob 在所有其他命名空间中都可用,即使内容共享策略设置为“隔离”也是如此。如果标签值设置为 除 以外的任何内容,则不会共享命名空间内容。



本文至此完毕,更多技术文章,尽情期待下一章节!


原文地址: https://blog.weiyigeek.top/2021/6-30-581.html


欢迎各位志同道合的朋友一起学习交流,如文章有误请在下方留下您宝贵的经验知识,个人邮箱地址【master#weiyigeek.top】
或者个人公众号【WeiyiGeek】
联系我。


更多文章来源于【WeiyiGeek Blog 个人博客 - 为了能到远方,脚下的每一步都不能少 】

个人主页: 【 https://weiyigeek.top

博客地址: 【 https://blog.weiyigeek.top 


专栏书写不易,如果您觉得这个专栏还不错的,请给这篇专栏 【点个赞、投个币、收个藏、关个注,转个发,留个言】(人间六大情),这将对我的肯定,谢谢!。



  • echo  "【点个赞】,动动你那粗壮的拇指或者芊芊玉手,亲!"

  • printf("%s", "【投个币】,万水千山总是情,投个硬币行不行,亲!")

  • fmt.Printf("【收个藏】,阅后即焚不吃灰,亲!")  

  • console.info("【转个发】,让更多的志同道合的朋友一起学习交流,亲!")

  • System.out.println("【关个注】,后续浏览查看不迷路哟,亲!")

  • cout << "【留个言】,文章写得好不好、有没有错误,一定要留言哟,亲! " << endl;

 往期相关文章

1.Containerd容器运行时初识与尝试

2.基于Containerd运行时搭建Kubernetes集群实践

【转载】使用 RBAC 模型限制对 Kubernetes 资源的访问原理浅析




更多网络安全、系统运维、应用开发、全栈文章,尽在【个人博客 - https://blog.weiyigeek.top】站点,谢谢支持!


↓↓↓ 更多文章,请点击下方阅读原文。

文章转载自WeiyiGeek,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论