aws eks 集群初始化过程中pause容器的启动逻辑

news2024/11/20 12:28:16

eks集群默认策略在磁盘使用量达到threshold时会清除镜像,其中pause镜像也可能会被清除

https://aws.amazon.com/cn/premiumsupport/knowledge-center/eks-worker-nodes-image-cache/

pause容器能够为pod创建初始的名称空间,pod的内的容器共享其中的网络空间,该镜像的删除会导致pod无法启动

almighty-pause-container

The image whose network/ipc namespaces containers in each pod will use.

enter image description here

但是由于未知原因,kubelet无法从ecr仓库中再次拉取镜像,出现401错误

pulling from host 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn failed with status code [manifests 3.5]: 401 Unauthorized

kubelet中和认证相关的启动参数

之前的文章中我们提到了k8s的in-tree凭证提供者,从官方的态度来看,未来会把凭证提供程序作为外部插件来设计

https://github.com/kubernetes/cloud-provider-aws

https://github.com/kubernetes/cloud-provider-aws/blob/v1.26.0/cmd/ecr-credential-provider/main.go

The in-tree cloud provider code has mostly stopped accepting new features, so future development for the AWS cloud provider should continue here. The in-tree plugins will be removed in a future release of Kubernetes.

在1.24集群使用containerd作为运行时,设置为remote

I0224 02:39:02.722293    3523 flags.go:64] FLAG: --container-runtime="remote"
I0224 02:39:02.722297    3523 flags.go:64] FLAG: --container-runtime-endpoint="unix:///run/containerd/containerd.sock"

垃圾回收的参数,可能会清除镜像

I0224 02:39:02.722460    3523 flags.go:64] FLAG: --image-gc-high-threshold="85"
I0224 02:39:02.722463    3523 flags.go:64] FLAG: --image-gc-low-threshold="80"

登录节点查看pause容器

# ctr -n=k8s.io i ls -q | grep pause
918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
961992271922.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
961992271922.dkr.ecr.cn-northwest-1.amazonaws.com.cn/eks/pause:3.5

查看kubelet日志,确实将这个pause容器作为sandbox

Feb 24 02:39:02 ip-192-168-6-203.cn-north-1.compute.internal kubelet[3523]: I0224 02:39:02.722647    3523 flags.go:64] FLAG: --pod-infra-container-image="918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5"

containerd的配置文件同样指定了这个pause容器

cat /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5"

分析下eks启动脚本中的相关逻辑,通过将pause卸载环境变量中,在kubelet启动时读取

PAUSE_CONTAINER_VERSION="${PAUSE_CONTAINER_VERSION:-3.5}"
AWS_DEFAULT_REGION=$(imds 'latest/dynamic/instance-identity/document' | jq .region -r)
AWS_SERVICES_DOMAIN=$(imds 'latest/meta-data/services/domain')
...
ECR_URI=$(/etc/eks/get-ecr-uri.sh "${AWS_DEFAULT_REGION}" "${AWS_SERVICES_DOMAIN}" "${PAUSE_CONTAINER_ACCOUNT:-}")
PAUSE_CONTAINER_IMAGE=${PAUSE_CONTAINER_IMAGE:-$ECR_URI/eks/pause}
PAUSE_CONTAINER="$PAUSE_CONTAINER_IMAGE:$PAUSE_CONTAINER_VERSION"
...
cat << EOF > /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
[Service]
Environment='KUBELET_ARGS=--node-ip=$INTERNAL_IP --pod-infra-container-image=$PAUSE_CONTAINER --v=2'
EOF

手动删除pause镜像测试

手动删除镜像

ctr -n=k8s.io i rm 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5

创建pod,卡在ContainerCreating状态,kubelet返回以下错误

Warning  FailedCreatePodSandBox  4s    kubelet    Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5": failed to pull image "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5": failed to pull and unpack image "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5": failed to resolve reference "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5": pulling from host 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn failed with status code [manifests 3.5]: 401 Unauthorized                                              

手动拉取镜像,和pod报错一致即认证失败

$ ctr -n=k8s.io i pull 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
ctr: failed to resolve reference "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5": pulling from host 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn failed with status code [manifests 3.5]: 401 Unauthorized

手动鉴权之后拉取

aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn
nerdctl -n=k8s.io pull 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
or
AUTH_STRING=QVdTOmV5xxxxxxxx
crictl pull --auth $AUTH_STRING 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5

拉取镜像之后容器启动成功,kubelet不在出现错误日志

题外话,使用 containerd 作为 Kubernetes 容器运行时的时候,容器日志的落盘则由 kubelet 来完成了,被直接保存在 /var/log/pods/<CONTAINER> 目录下面,同时在 /var/log/containers 目录下创建软链接指向日志文件。默认的日志配置同样通过kubelet参数设置

I0224 02:39:02.722286    3523 flags.go:64] FLAG: --container-log-max-files="5"
I0224 02:39:02.722290    3523 flags.go:64] FLAG: --container-log-max-size="10Mi"

pause镜像的认证逻辑

虽然我们通过手动鉴权拉取镜像解决了问题,但此时如果再次删除pause镜像,kubelet仍旧会出现401错误,说明kubelet并没有完成鉴权

逻辑上,kubelet的鉴权是在kubelet启动过程中完成的,推测该行为只在启动时执行一次(pause镜像下载好即可)。那我们可以尝试手动执行bootstrap.sh脚本或者重启kubelet,迫使kubelet主动完成鉴权和拉取镜像的操作

// 删除pasue
ctr -n=k8s.io i rm 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
// 重启kubelet
systemctl restart kubelet
// 重启bootstrap
/etc/eks/bootstrap.sh cluster-name

能明显看到多了一个pause镜像,说明我们的推理是正确的

# nerdctl -n=k8s.io images | grep pause
918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause                          3.5                           529cf6b1b6e5    3 seconds ago     linux/amd64    668.0 KiB    291.7 KiB
961992271922.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause                          3.5                           529cf6b1b6e5    2 weeks ago       linux/amd64    668.0 KiB    291.7 KiB
961992271922.dkr.ecr.cn-northwest-1.amazonaws.com.cn/eks/pause                      3.5                           529cf6b1b6e5    2 weeks ago       linux/amd64    668.0 KiB    291.7 KiB

但问题在于,后续如果使用其他仓库的镜像,是能够自主完成鉴权的,例如以下pod使用了其他账号的镜像。那么为什么只有pause镜像仓库无法自主鉴权呢?推测pause镜像的下载逻辑和pod的镜像是不同的

kind: Pod
apiVersion: v1
metadata:
  name: test-temp
spec:
  containers:
  - name: test
    image: xxxxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn/nginx:latest

手动更换bootstrap脚本中的pause镜像源为public.ecr.aws/eks-distro/kubernetes/pause:3.5,重启bootstrap。之后不会再出现401,因为这个是公共仓库

# /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
[Service]
Environment='KUBELET_ARGS=--node-ip=192.168.6.203 --pod-infra-container-image=public.ecr.aws/eks-distro/kubernetes/pause:3.5 --v=2'

在bootstrap的时候出现以下输出

Using kubelet version 1.24.10
true
Using containerd as the container runtime
true
[Service]
Slice=runtime.slice
‘/etc/eks/containerd/containerd-config.toml’ -> ‘/etc/containerd/config.toml’
‘/etc/eks/containerd/sandbox-image.service’ -> ‘/etc/systemd/system/sandbox-image.service’
‘/etc/eks/containerd/kubelet-containerd.service’ -> ‘/etc/systemd/system/kubelet.service’
nvidia-smi not found

有一个服务专门用来管理sandbox镜像,在containerd之后启动并拉取sandbox镜像,所以我们也可以手动执行这个脚本

cat /etc/eks/containerd/sandbox-image.service
[Unit]
Description=pull sandbox image defined in containerd config.toml
# pulls sandbox image using ctr tool
After=containerd.service
Requires=containerd.service

[Service]
Type=oneshot
ExecStart=/etc/eks/containerd/pull-sandbox-image.sh

[Install]
WantedBy=multi-user.target

查看脚本的内容,实际上就是取拉取了sandbox镜像

cat /etc/eks/containerd/pull-sandbox-image.sh
#!/usr/bin/env bash
set -euo pipefail
source <(grep "sandbox_image" /etc/containerd/config.toml | tr -d ' ')
### Short-circuit fetching sandbox image if its already present
if [[ "$(sudo ctr --namespace k8s.io image ls | grep $sandbox_image)" != "" ]]; then
  exit 0
fi
/etc/eks/containerd/pull-image.sh "${sandbox_image}"

拉取镜像的具体逻辑

  • 从参数中解析具体信息
  • 重试多次拉取镜像
# cat /etc/eks/containerd/pull-image.sh
#!/usr/bin/env bash
img=$1
region=$(echo "${img}" | cut -f4 -d ".")
MAX_RETRIES=3
...
ecr_password=$(retry aws ecr get-login-password --region $region)
if [[ -z ${ecr_password} ]]; then
  echo >&2 "Unable to retrieve the ECR password."
  exit 1
fi
retry sudo ctr --namespace k8s.io content fetch "${img}" --user AWS:${ecr_password}

那么问题就在于以下这个黑魔法命令,完成了认证工作

ecr_password=$(aws ecr get-login-password --region cn-north-1)
ctr --namespace k8s.io content fetch "918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5" --user AWS:${ecr_password}

pod镜像的认证机制

现在看来,我们之前讨论过的credential-provider实际上为pod拉取镜像提供了凭证

把kubelet中的那两个参数去掉重新bootstrap

# vi /etc/eks/containerd/kubelet-containerd.service
ExecStart=/usr/bin/kubelet --cloud-provider aws \
    // 删除--image-credential-provider-config /etc/eks/ecr-credential-provider/ecr-credential-provider-config \
    // 删除--image-credential-provider-bin-dir /etc/eks/ecr-credential-provider \
    --config /etc/kubernetes/kubelet/kubelet-config.json \
    --kubeconfig /var/lib/kubelet/kubeconfig \
    --container-runtime remote \
    --container-runtime-endpoint unix:///run/containerd/containerd.sock \
    $KUBELET_ARGS $KUBELET_EXTRA_ARGS
# /etc/eks/bootstrap.sh test124
# systemctl daemon-reload
# systemctl restart kubelet

kubelet已经没有鉴权工具了

# systemctl status kubelet -l
● kubelet.service - Kubernetes Kubelet
   Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─10-kubelet-args.conf, 30-kubelet-extra-args.conf
   Active: active (running) since Sat 2023-03-04 11:52:29 UTC; 23min ago
     Docs: https://github.com/kubernetes/kubernetes
 Main PID: 11547 (kubelet)
   CGroup: /runtime.slice/kubelet.service
           └─11547 /usr/bin/kubelet --cloud-provider aws --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime remote --container-runtime-endpoint unix:///run/containerd/containerd.sock --node-ip=192.168.9.137 --pod-infra-container-image=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5 --v=2 --node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=test124,alpha.eksctl.io/nodegroup-name=test124-ng,eks.amazonaws.com/nodegroup-image=ami-0efac015e224c828a,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=test124-ng6,eks.amazonaws.com/sourceLaunchTemplateId=lt-0adf6b991b5366a98 --max-pods=110

逻辑上现在已经无法拉取ecr镜像了,因为我们无法鉴权,但实际上却没有任何影响,重启containerd和kubelet也一样

直接在bootstrap中把ecr-credential-provider删掉看看

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: text/x-shellscript; charset="us-ascii"
#!/bin/bash
set -ex
/etc/eks/bootstrap.sh test124 --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=test124,alpha.eksctl.io/nodegroup-name=test124-ng6,eks.amazonaws.com/nodegroup-image=ami-0efac015e224c828a,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=test124-ng6,eks.amazonaws.com/sourceLaunchTemplateId=lt-0adf6b991b5366a98 --max-pods=110' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false

--//--

出现以下报错

E0304 13:45:18.793749    4797 kuberuntime_manager.go:260] 
"Failed to register CRI auth plugins" 
err="plugin binary directory /etc/eks/ecr-credential-provider did not exist"
systemd[1]: kubelet.service: main process exited, code=exited, status=1/FAILURE

// kuberuntime_manager.go
if imageCredentialProviderConfigFile != "" || imageCredentialProviderBinDir != "" {
    if err := plugin.RegisterCredentialProviderPlugins(imageCredentialProviderConfigFile, imageCredentialProviderBinDir); err != nil {
        klog.ErrorS(err, "Failed to register CRI auth plugins")
        os.Exit(1)
    }
}

手动进入节点修改kubelet.service,之后启动kubelet将节点加入集群。

在该节点上创建pod,发现仍旧能够从ecr仓库拉取镜像,目前没看出这两个kubelet参数有什么用。。。。日后再说吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

库函数qsort 的模拟实现

在之前了解了库函数qsort的使用之后 我们来模拟实现一下上篇有介绍 qsort的底层实现是快速排序 由于害怕没有人了解过快速排序 我就用大家熟知的冒泡排序进行模拟实现 先来展示完整代码 以下代码为升序排序 如果降序将冒泡排序中的大于号改为小于号就可以了#define _CRT_SECURE…

malloc实现原理探究

2021年末面试蔚来汽车&#xff0c;面试官考察了malloc/free的实现机制。当时看过相关的文章&#xff0c;有一点印象&#xff0c;稍微说了一点东西&#xff0c;不过自己感到不满意。今天尝试研究malloc的实现细节&#xff0c;看了几篇博文&#xff0c;发现众说纷纭&#xff0c;且…

MySql启动错误(Mac系统 安装 mysql-8.0.32-macos13-arm64 后每次点击启动 无法启动) --- 已解决

MySql启动的时候: 立即变红! 查看日志如下: 2023-03-04T14:18:01.089671Z 0 [System] [MY-010910] [Server] /usr/local/mysql/bin/mysqld: Shutdown complete (mysqld 8.0.32) MySQL Community Server - GPL. 2023-03-04T14:18:10.304169Z 0 [System] [MY-010116] [Server]…

【EDA工具使用】——VCS和Verdi的联合仿真的简单使用

目录 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真&#xff08;最常用&#xff09;​编辑 4.两步式混合编译仿真​编辑 5.VCS的使用 ​6.verdi的使用 1.产生fsdb文件的两种方法​编辑 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真…

按位与为零的三元组[掩码+异或的作用]

掩码异或的作用前言一、按位与为零的三元组二、统计分组1、map统计分组2、异或掩码总结参考资料前言 当a b 0时&#xff0c;我们能够很清楚的知道b是个什么值&#xff0c;b 0 - a -a&#xff0c;如果当a & b 0时&#xff0c;我们能够很清楚的知道b是什么值吗&#xf…

Python GUI界面编程-初识

图形用户界面(Graphical User Interface&#xff0c;简称 GUI&#xff0c;又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。与早期计算机使用的命令行界面相比&#xff0c;图形界面对于用户来说在视觉上更易于接受。然而这界面若要通过在显示屏的特定位置&#xf…

HiveSQL一天一个小技巧:如何精准计算非连续日期累计值【闪电快车面试题】

0 需 求稀疏字段累计求和问题1 问题分析根据图片中数据变换的形式&#xff0c;可以看出是根据字段term补齐数据中缺失的日期&#xff0c;term为连续日期的个数&#xff0c;当为12时&#xff0c;表明由2018-12-21到2019-01-02连续日期个数为12&#xff0c;当补齐日期后&#xff…

sklearn中的逻辑回归

目录 一.名为“回归”的分类器 二.逻辑回归的优点 三.sklearn中的逻辑回归 四.linear_model.LogisticRegression 五.penalty & C(正则化) 六.逻辑回归中的特征工程 1.业务选择 2.PCA和SVD一般不用 3.统计方法可以使用&#xff0c;但不是非常必要 4.高效的嵌入法e…

【vulhub漏洞复现】CVE-2013-4547 Nginx 文件名逻辑漏洞

一、漏洞详情影响版本 Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7通过%00截断绕过后缀名的限制&#xff0c;使上传的php内容文件被解析执行。当Nginx得到一个用户请求时&#xff0c;首先对url进行解析&#xff0c;进行正则匹配&#xff0c;如果匹配到以.php后缀结尾的文件名&#x…

2022秋-2023-中科大-数字图像分析-期末考试试卷回忆版

今天晚上刚考完&#xff0c;心累&#xff0c;在这里继续授人以渔(仅供参考&#xff0c;切勿对着复习不看ppt&#xff0c;ppt一定要过两遍)。 注意:往年的经验贴&#xff0c;到此为止&#xff0c;全部作废&#xff0c;一个没考。千万不要只对着复习&#xff0c;SIFT没考&#x…

JavaScript(JS)

一、三种引入方式&#xff1a; 1、内部js 通过script标签嵌入到html里面 <script>alert(hello);</script> 2、外部js 写成一个单独的.js文件&#xff0c;让html引入进来 <script src"app.js"></script> 3、行内js 直接写到html内部 &…

Python爬虫——使用socket模块进行图片下载

Python爬虫——使用socket模块进行图片下载什么是socket爬虫的工作流程socket爬取图片为什么能用socket能下载图片socket下载图片和request下载图片的区别使用socket下载一张图片使用socket下载多张图片方法1方法2什么是socket Socket 是一种通信机制&#xff0c;用于实现网络…

AQS为什么用双向链表?

首先&#xff0c;在AQS中&#xff0c;等待队列是通过Node类来表示的&#xff0c;每个Node节点包含了等待线程的信息以及等待状态。下面是Node类的部分源码&#xff1a;static final class Node {// 等待状态volatile int waitStatus;// 前驱节点volatile Node prev;// 后继节点…

【AI绘图学习笔记】深度学习相关数学原理总结(持续更新)

如题&#xff0c;这是一篇深度学习相关数学原理总结文&#xff0c;由于深度学习中涉及到较多的概率论知识&#xff08;包括随机过程&#xff0c;信息论&#xff0c;概率与统计啥啥啥的)&#xff0c;而笔者概率知识储备属实不行&#xff0c;因此特意开一章来总结&#xff08;大部…

Jackson CVE-2017-17485 反序列化漏洞

0x00 前言 同CVE-2017-15095一样&#xff0c;是CVE-2017-7525黑名单绕过的漏洞&#xff0c;主要还是看一下绕过的调用链利用方式。 可以先看&#xff1a; Jackson 反序列化漏洞原理 或者直接看总结也可以&#xff1a; Jackson总结 涉及版本&#xff1a;2.8.10和2.9.x至2.…

leetcode_贪心算法

贪心算法相关题简单题目455.分发饼干1005.K次取反后最大化的数组和860.柠檬水找零序列问题376.摆动序列法一&#xff1a;贪心法法二&#xff1a;动态规划单调递增的数字简化版本有点难度53.最大子序和贪心算法动态规划134.加油站968.监控二叉树两个维度权衡问题分发糖果406.根据…

MATLAB——系统环境

MATLAB概述MATLAB的发展MATLAB:MATrix LABoratory1980年前后&#xff0c;Cleve Moler教授编写的Linpack 和Eispack的接口程序。1984年&#xff0c;MATLAB第1版(DOS版)1992年&#xff0c;MATLAB4.0版1994年&#xff0c;MATLAB 4.2版1997年&#xff0c;MATLAB 5.0版1999年&#x…

12-Trie树

Trie树&#xff08;又称字典树、单词查找树&#xff09;是一种树型的数据结构&#xff0c;常用于保存和查找字符串&#xff0c;是一种十分高效率的存储和检索方式。 Trie树原理 我们先假设有六个字符串需要存储&#xff1a;abc、abcd、abef、cfgh、bc、bcd。Trie树的存储原理…

Scala04 方法与函数

Scala04 方法与函数 Scala 中的也有方法和函数的概念。 Scala中的 方法 是类的一部分。 Scala中的 函数 是一个对象&#xff0c;可以赋值给变量。 在类中定义的函数就是方法 4.1 方法 Scala 中方法 与 Java 中类似&#xff0c;是组成类的一部分 4.1.1 语法结构 格式&#x…

数据库“啃”不动?CnosDB带你轻松阅读十万行源码!

最近一直有社区的小伙伴问&#xff0c;我们很感兴趣CnosDB&#xff0c;但从何开始阅读CnosDB的代码呢&#xff0c;其实这个问题在之前的CnosDB HiTea直播时就有聊到&#xff0c;今天我们就再来回顾一下。CnosDB的源代码主要分为Query Engine和Storage Engine。Query Engine在qu…