使用containerd容器运行时的Kubernetes集群如何配置访问http私有仓库(insecure-registries)?

在使用docker容器运行时,配置访问http私有仓库的方法较为简单,类似如下即可:

#  cat /etc/docker/daemon.json 
{
  "insecure-registries": ["192.168.0.4:5500"]
}

而当Kubernetes使用containerd时,其配置文件就相对复杂了。总的来说,有两种方式可以实现http仓库的访问。

方法一:registry.configs

修改/etc/containerd/config.toml中如下位置,默认配置为:

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = ""

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]

      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

例如添加私有仓库http://192.168.0.4:5500,则添加如下配置:

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = ""

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]
        [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.4:5500".tls]
          insecure_skip_verify = true
      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.0.4:5500"]
          endpoint = ["http://192.168.0.4:5500"]

修改完成后重启containerd

systemctl restart containerd

查看最新配置

containerd config dump

测试镜像拉取:

#  crictl pull 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0
Image is up to date for sha256:69547dffc18fcddd4f41b7696a046ad7252ceeabce944106da94fa4bfb3c6b24

如需配置仓库认证信息,可参考:https://github.com/containerd/containerd/blob/main/docs/cri/registry.md

按照文档的说法,这种配置方式只支持到v1.6,目前我们的生产环境最高版本也是1.6,因此尚未测试这种方式在v1.7是否可行。

方法二:hosts.toml

这种方式较为推荐,因为它可以做到不同仓库的配置文件分开管理,首先我们将默认配置文件修改为(即修改config_path):

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "etc/containerd/certs.d"

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]

      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

接着创建配置文件夹:

cd /etc/containerd/
mkdir certs.d

然后创建仓库配置文件夹(以下也称主机命名空间namespace)及配置文件hosts.toml,文件夹名称为仓库域名或者[IP address][:port],本例中为:

mkdir certs.d/192.168.0.4:5500
touch certs.d/192.168.0.4:5500/hosts.toml

创建完成后文件树如下:

#  tree /etc/containerd/certs.d
/etc/containerd/certs.d
└── 192.168.0.4:5500
    └── hosts.toml

hosts.toml写入如下配置:

#  cat /etc/containerd/certs.d/192.168.0.4\:5500/hosts.toml 
server = "http://192.168.0.4:5500"

[host."http://192.168.0.4:5500"]
  capabilities = ["pull", "resolve", "push"]
  skip_verify = true

重启containerd,并测试镜像拉取:

#  systemctl restart containerd

#  crictl pull 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0
Image is up to date for sha256:69547dffc18fcddd4f41b7696a046ad7252ceeabce944106da94fa4bfb3c6b24

hosts.toml文件详解

hosts.toml中指定的文件必须为绝对路径或相对于hosts.toml的相对路径

  • server字段
    该主机命名空间的默认服务器地址,也即Registry
  • host字段
    Mirror,镜像地址(serverhost的关系,就是Registrymirror的关系,例如Docker HubRegistry,而国内的镜像源如阿里镜像源则是Mirror),如果配置了host,当客户端试图拉取或推送镜像时,会根据配置文件中定义的顺序和能力去尝试这些镜像服务器。
  • capabilities字段
    表示该主机被信任执行的一系列操作集合。
  • skip_verify
    表示是否跳过证书链验证,默认为false,即不跳过验证。
  • ca字段
    指定ca证书路径或路径集合。
  • client字段
    指定客户端证书或证书集合。
  • header字段
    指定请求header,由一系列键值对组成
  • override_path字段
    表示主机的API根路径是在URL路径中定义的,而不是通过API规范定义的。这个参数主要用于与那些不遵循OCI(Open Container Initiative)标准、缺少/v2前缀的非合规Registry配合使用。在Docker或其他容器引擎与Registry交互时,默认情况下会按照OCI规范去访问Registry API,即请求通常以 /v2/ 开头,例如:https://registry.example.com/v2/<image>/<tag>。然而,某些非标准的Registry可能并未遵循这一规范,其API根路径可能直接是注册表名之后的某个自定义路径。在这种情况下,通过将 override_path 设置为 true 并提供相应的路径,客户端就可以正确地定位到这些非标准Registry的API根路径,以实现与它们的有效通信。例如,如果API根路径是 https://registry.example.com/custom/api,则可以通过配置 override_path 来适应这种特殊格式。

一个示例配置文件如下:

server = "https://registry-1.docker.io"

[host."https://mirror.registry"]
  capabilities = ["pull"]
  ca = "/etc/certs/mirror.pem"
  skip_verify = false
  [host."https://mirror.registry".header]
    x-custom-2 = ["value1", "value2"]

[host."https://mirror-bak.registry/us"]
  capabilities = ["pull"]
  skip_verify = true

[host."http://mirror.registry"]
  capabilities = ["pull"]

[host."https://test-1.registry"]
  capabilities = ["pull", "resolve", "push"]
  ca = ["/etc/certs/test-1-ca.pem", "/etc/certs/special.pem"]
  client = [["/etc/certs/client.cert", "/etc/certs/client.key"],["/etc/certs/client.pem", ""]]

[host."https://test-2.registry"]
  client = "/etc/certs/client.pem"

[host."https://test-3.registry"]
  client = ["/etc/certs/client-1.pem", "/etc/certs/client-2.pem"]

[host."https://non-compliant-mirror.registry/v2/upstream"]
  capabilities = ["pull"]
  override_path = true

注意一:两种方法不能混用

笔者在撰文时使用的测试环境恰好碰到该问题,因此也顺手记录。当两者混用时,即有如下配置:

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "etc/containerd/certs.d"

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]
        [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.4:5500".tls]
          insecure_skip_verify = true
      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.0.4:5500"]
          endpoint = ["http://192.168.0.4:5500"]

此时systemctl restart containerd,然后测试拉取镜像,会有如下报错:

#  crictl pull 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0
FATA[0000] validate service connection: validate CRI v1 image API for endpoint "unix:///run/containerd/containerd.sock": rpc error: code = Unimplemented desc = unknown service runtime.v1.ImageService 

对此问题进行排查,检查节点状态发现已NotReady

#  kubectl get node
NAME                  STATUS     ROLES           AGE   VERSION
kcs-zrjtest-m-c8ggl   NotReady   control-plane   29h   v1.25.7-eki.3.0.0
kcs-zrjtest-m-mqtb5   Ready      control-plane   29h   v1.25.7-eki.3.0.0
kcs-zrjtest-m-tbqmq   Ready      control-plane   29h   v1.25.7-eki.3.0.0
kcs-zrjtest-s-h8gvl   Ready      <none>          29h   v1.25.7-eki.3.0.0
kcs-zrjtest-s-k7n9f   Ready      <none>          29h   v1.25.7-eki.3.0.0
kcs-zrjtest-s-q6tbt   Ready      <none>          29h   v1.25.7-eki.3.0.0
kcs-zrjtest-s-sczsh   Ready      <none>          29h   v1.25.7-eki.3.0.0
kcs-zrjtest-s-v9svm   Ready      <none>          29h   v1.25.7-eki.3.0.0

检查节点kubelet日志,有如下报错:

#  journalctl -u kubelet -f
Apr 10 17:27:31 kcs-zrjtest-m-c8ggl kubelet[15698]: E0410 17:27:31.681528   15698 remote_runtime.go:391] "ListPodSandbox with filter from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService" filter="nil"
Apr 10 17:27:31 kcs-zrjtest-m-c8ggl kubelet[15698]: E0410 17:27:31.681561   15698 kuberuntime_sandbox.go:297] "Failed to list pod sandboxes" err="rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
Apr 10 17:27:31 kcs-zrjtest-m-c8ggl kubelet[15698]: E0410 17:27:31.681571   15698 generic.go:205] "GenericPLEG: Unable to retrieve pods" err="rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"

问题指向容器运行时,检查containerd日志:

Apr 10 17:23:32 kcs-zrjtest-m-c8ggl containerd[116927]: time="2024-04-10T17:23:32.560557543+08:00" level=warning msg="failed to load plugin io.containerd.grpc.v1.cri" error="invalid plugin config: `mirrors` cannot be set when `config_path` is provided"

即当指定了config_path时,是不能再配置mirrors的([plugins."io.containerd.grpc.v1.cri".registry.mirrors])。

解决办法也即方法一和方法二只保留其一。

注意二:这两种方法是用来配置cri的,因此不适用于ctrnerdctl命令

有些同学在配置完成后,使用ctrnerdctl命令进行拉取测试,会发现测试无效:

#  ctr images pull 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0
INFO[0000] trying next host                              error="failed to do request: Head \"https://192.168.0.4:5500/v2/registry.k8s.io/ingress-nginx/kube-webhook-certgen/manifests/v1.3.0\": http: server gave HTTP response to HTTPS client" host="192.168.0.4:5500"
ctr: failed to resolve reference "192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0": failed to do request: Head "https://192.168.0.4:5500/v2/registry.k8s.io/ingress-nginx/kube-webhook-certgen/manifests/v1.3.0": http: server gave HTTP response to HTTPS client

这是因为以上配置是为cri准备的( [plugins."io.containerd.grpc.v1.cri".registry]),因此只适用于cri客户端如crictlkubectl,上文中也是使用crictl进行的测试。

如果使用ctr测试,可以使用--hosts-dir指定配置文件:

ctr images pull --hosts-dir "/etc/containerd/certs.d" 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0

或者直接使用--plain-http参数指定使用http

ctr images pull --plain-http 192.168.0.4:5500/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.3.0
<think>嗯,用户想了解Excel中的VLOOKUP函数的用法和参数含义。首先,我需要回忆一下VLOOKUP的基本结构。VLOOKUP是垂直查找函数,用于在表格的首列查找指定的值,然后返回该行中指定列的数据。它的四个参数分别是查找值、表格范围、列索引号和匹配模式。 接下来,我得确认每个参数的具体作用。第一个参数是lookup_value,也就是用户要查找的值,比如产品ID或者姓名。第二个参数是table_array,即查找的范围,这里要注意的是,查找值必须位于这个范围的第一列,否则函数无法正确工作。第三个参数是col_index_num,也就是用户想要返回的数据在表格范围中的第几列,这个列数是从表格范围的第一列开始算起的,不是整个工作表的列。第四个参数是range_lookup,决定是精确匹配还是近似匹配,通常用FALSE或0来指定精确匹配,避免错误。 然后,用户可能需要一个具体的例子来理解如何使用。比如,假设有一个产品价格表,用户想根据产品ID查找对应的价格。这时候,VLOOKUP就可以在ID列查找,然后返回价格列的数据。同时,要提醒用户注意表格范围最好使用绝对引用,比如$A$2:$C$100,这样在拖动公式时范围不会变化。 可能遇到的问题也需要考虑。比如,如果查找值不在表格的第一列,或者列索引号超过了表格的列数,函数会返回错误。此外,数据格式不一致也可能导致问题,比如查找值是数字,而表格中是文本格式的数字,这时候需要统一格式。还有,当出现#N/A错误时,可能是查找值不存在,或者匹配模式设置不正确,需要检查参数是否正确。 用户可能还会问到如何避免常见的错误,比如部分数据匹配出错的情况。这时候需要检查是否有多余的空格,或者数据格式不一致,或者表格范围没有锁定导致拖动时偏移。此外,XLOOKUP作为VLOOKUP的升级版,可能在某些情况下更方便,比如可以向左查找或者返回多列数据,这也是可以提及的内容。 最后,整理步骤,从基础语法到参数说明,再到具体案例,逐步引导用户理解如何使用VLOOKUP函数。同时,提供常见错误和解决方法,帮助用户在实际应用中避免问题。如果有必要,还可以比较VLOOKUP和其他查找函数的区别,比如HLOOKUP或XLOOKUP,但根据用户的问题,主要集中在VLOOKUP本身即可。</think>### Excel VLOOKUP函数详解 #### 一、基础语法与参数说明 VLOOKUP函数的语法为: $$=VLOOKUP(lookup\_value, table\_array, col\_index\_num, [range\_lookup])$$ 包含4个参数: 1. **lookup_value**(必填):要查找的值(如单元格引用或具体值) 2. **table_array**(必填):包含数据的表格范围(必须包含查找列和返回列) 3. **col_index_num**(必填):返回值所在列的序号(从table_array第一列开始计数) 4. **range_lookup**(可选):匹配类型 - `TRUE`/`1`:近似匹配(默认值,需数据升序排列) - `FALSE`/`0`:精确匹配(常用选项) [^1][^2] #### 二、使用步骤演示(工资表查询案例) 假设需要根据员工编号查询工资: 1. 建立查询单元格(如`B12`) 2. 输入公式: ```excel =VLOOKUP(A12, $A$2:$D$100, 4, 0) ``` - `A12`:待查询的员工编号 - `$A$2:$D$100`:锁定数据区域(绝对引用) - `4`:返回第4列(工资列) - `0`:精确匹配 [^2][^3] #### 三、常见错误与解决方法 | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | #N/A | 查找值不存在 | 检查数据源或改用`IFERROR`容错 | | #REF! | 列序号超出范围 | 确认col_index_num ≤ 表格列数 | | 部分匹配失败 | 数据格式不一致 | 统一数值/文本格式 | | 结果错位 | 表格未锁定 | 使用`$`符号固定区域引用 | [^3][^4] #### 四、进阶技巧 1. **多条件查询**: 使用辅助列合并多个条件字段 ```excel =VLOOKUP(A2&B2, $D$2:$F$100, 3, 0) ``` 2. **通配符匹配**: `"*"`匹配任意字符,`"?"`匹配单个字符 ```excel =VLOOKUP("张*", $A$2:$C$100, 3, 0) ``` 3. **跨表查询**: 引用其他工作表数据 ```excel =VLOOKUP(A2, Sheet2!$A$2:$D$100, 4, 0) ``` [^1][^4]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洒满阳光的午后

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值