首页 > 其他分享 >3.Containerd容器运行时的配置浅析与知识扩充实践

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

时间:2022-12-27 21:32:06浏览次数:68  
标签:容器 etc grpc Containerd v1 io containerd config 浅析

公众号关注「WeiyiGeek



本章目录:

  • 0x00 Containerd 容器运行时配置指南
  • 如何配置 Containerd 的 systemd 守护进程服务?
  • 如何查看 Containerd 相关插件及其存目录?
  • 如何生成 Containerd 默认的 config.toml 配置文件?
  • 如何配置 Containerd 让其支持懒拉取 (eStargz)?
  • 如何配置 Containerd 在 harbor 私有仓库拉取镜像?
  • 如何进行 Containerd 基本配置?


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 runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
# 允许 containerd 及其运行时管理它所创建的容器的 cgroups
Delegate=yes
# 确保在 containerd 被关闭时仅终止 containerd 守护程序,而不终止任何子进程,如填充程序和容器
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 相关插件及其存目录?

描述:在 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/bin
Environment=IPFS_PATH=/home/cqzk/.local/share/ipfs
ExecStart="/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 $MAINPID
RestartSec=2
Restart=always
Type=simple
KillMode=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-alpine
INFO[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.top
ctr: 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.toml
version = 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.toml
sed -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: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: "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.toml
version = 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/v1
kind: RuntimeClass
metadata:
name: crun
handler: crun
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: gvisor
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata

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


apiVersion: v1
kind: Pod
spec:
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.toml
server = "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.toml
server = "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://weiyigeek.top​​】

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





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





标签:容器,etc,grpc,Containerd,v1,io,containerd,config,浅析
From: https://blog.51cto.com/weiyigeek/5973612

相关文章

  • 通过使用阿里云容器镜像服务构建k8s下载不到的镜像
    前因:因为要搭建ingress-nginx,根据官方提供的yaml文档,里面有2处用的到的镜像是需要从registry.k8s.io下载的,虚拟机无法访问到该地址,因为我们这里使用阿里云的容器镜像服务来......
  • 浅析OpenCV中的BlobDetector
    ​​​​一、blob基础所谓Blob就是图像中一组具有某些共同属性(例如,灰度值)的连接像素。在上图中,深色连接区域是斑点,斑点检测的目的是识别并标记这些区域。OpenCV提供了一......
  • Docker基本操作(镜像操作?容器操作?)(四)
    Docker的基本原理我们已经了解了,也已经安装上了,接下来我们就一起来学习下Docker的常用操作,实际上主要就是DockerCLI的一些常用命令使用。一、镜像操作之前我们提......
  • Spring之Bean注入Spring容器中的方式
     向spring容器中加入bean有以下方式:通过<Bean>标签@Configuration+@Bean@Component+组件扫描@Import导入【见 Spring注解之@Import】实现FactoryB......
  • Docker基本概念(LXC?镜像、容器、仓库是什么?容器和虚拟机又是什么?)(一)
    学习Docker前,我们有必要了解下Docker的前生LXC(LinuxContainer)。一、LXC介绍LXC可以提供轻量级的虚拟化,用来隔离进程和资源,和我们传统观念中的全虚拟化完全不一样,非常轻......
  • Docker容器与Docker网络模式
    一、Docker容器操作1、容器创建将镜像加载到容器的过程。新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器1234567格式......
  • Pod容器健康探测
    百度网盘链接:https://pan.baidu.com/s/15t_TSH5RRpCFXV-93JHpNw?pwd=8od3 提取码:8od38Pod容器健康探测8.1为什么要对容器做探测?在Kubernetes中Pod是最小的计算单元,......
  • 详解如何进入、退出docker容器的方法
    参考地址:https://blog.csdn.net/qq_46416934/article/details/1244909781启动docker服务首先需要知道启动docker服务是:servicedockerstart或者:systemctlstartdoc......
  • Docker操作镜像、容器
                                                         ......
  • Spring IOC源码(九):IOC容器之 单例对象的创建
    1、源码解析getBean(name)是在IOC容器的顶级接口BeanFactory中定义,由其子类AbstractBeanFactory实现的方法。是IOC容器启动过程中的核心方法。核心方法流程getBean-......