如何修补pod';s容器规范通过kubernetes准入控制器用我的exec版本启动容器?

如何修补pod';s容器规范通过kubernetes准入控制器用我的exec版本启动容器?,kubernetes,Kubernetes,我正在编写一个准入控制器,负责用我的exec版本启动所有容器,比如myexec 我知道,我可以在pod的容器规范中修改命令,以myexec作为前缀 但是我被困在pod的容器规范中没有命令的情况下。在这种情况下,根据我的理解,我必须找到容器将要加载的图像的入口点命令/脚本。我需要将命令设置为myexec entrypoint.sh 这看起来很棘手而且很昂贵,因为我必须检查图像,找到入口点,所有这些都在入口控制器内 我想提到的是,kubernetes已经在拉取映像(如果映像之前已经拉入或在集群中预先

我正在编写一个准入控制器,负责用我的
exec
版本启动所有容器,比如
myexec

我知道,我可以在pod的容器规范中修改
命令
,以
myexec
作为前缀

但是我被困在pod的容器规范中没有
命令的情况下。在这种情况下,根据我的理解,我必须找到容器将要加载的图像的入口点命令/脚本。我需要将
命令设置为
myexec entrypoint.sh

这看起来很棘手而且很昂贵,因为我必须检查图像,找到入口点,所有这些都在入口控制器内


我想提到的是,kubernetes已经在拉取映像(如果映像之前已经拉入或在集群中预先显式加载),并且在其节点上有清单,它可能会以容器配置的形式发送这些入口点信息,但我不知道如何在进入期间捕获这些信息

所以我在寻找一些我没有意识到的暗示、技巧或方法来实现我的目标

PS:我无法更改映像配置。

有一个项目允许您查询任何容器注册表中的元数据,例如入口点和命令

您可以使用skopeo cmd工具对其进行测试

按照下面的步骤安装它

现在,请尝试以下操作:

$ skopeo inspect --config  docker://nginx:latest
你可能看到的是大量的输出。对于我们的用例,我们不需要它的大部分。 我们感兴趣的是
.config
下的内容。我使用
jq
来查询它。看看:

$ skopeo inspect --config  docker://nginx:latest | jq ".config"
{
  "ExposedPorts": {
    "80/tcp": {}
  },
  "Env": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "NGINX_VERSION=1.19.5",
    "NJS_VERSION=0.4.4",
    "PKG_RELEASE=1~buster"
  ],
  "Entrypoint": [
    "/docker-entrypoint.sh"
  ],
  "Cmd": [
    "nginx",
    "-g",
    "daemon off;"
  ],
  "Labels": {
    "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
  },
  "StopSignal": "SIGQUIT"
}
$skopeo inspect--configdocker://nginx:latest |jq“.config”
{
“公开端口”:{
“80/tcp”:{}
},
“环境”:[
“路径=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”,
“NGINX_版本=1.19.5”,
“NJS_版本=0.4.4”,
“PKG_RELEASE=1~buster”
],
“入口点”:[
“/docker entrypoint.sh”
],
“Cmd”:[
“nginx”,
“-g”,
“守护进程关闭;”
],
“标签”:{
“维护者”:“NGINX Docker维护者”
},
“停止信号”:“SIGQUIT”
}
请注意以下字段:
Entrypoint
Cmd
。我相信这就是你要找的。所有这些都是在不拉任何图像的情况下完成的。那有多酷


您可能需要源代码(它在apache许可证下,因此可以随意修改),使用rest服务,并让准入控制器查询有关端点/CMD的信息。

谢谢您的回答。但正如你所看到的,这个问题已经提到了“这看起来很棘手而且很昂贵,因为我必须检查图像,找到入口点,都在入口控制器内。”而且即使我主持rest服务,这也会让入口速度慢一点。我想提到的是,kubernetes已经在拉取映像并在其节点上拥有清单,它可能正在发送这些入口点,但我不知道如何捕获这些入口点。从文档中可以看出:“准入控制器是一段代码,在对象持久化之前拦截对kubernetes API服务器的请求[…]”。这意味着在对象gis创建之前,在调度程序收到关于对象的通知之前,以及pod分配给节点和kubelet开始拉取图像之前,许可运行。“kubernetes已经拉取图像并在其节点上有清单”-一旦pod对象创建,您不能仅仅修补飞行中的pod对象。豆荚是不可变的。如果你想更改pod规范中的某个内容,你需要删除它并创建一个新的。此外,在分配给节点之前,它不会提取任何内容。Kubelet它将图像拉到节点,但只有在调度程序告诉它这样做之后,图像才会被拉到节点。一旦pod被创建,图像就会被拉。但在某些情况下,图像已经加载。当已经拉入图像时,我不能从拉入图像数据库获取关于其入口点的信息吗?一旦pod被分配其节点运行,图像将由kubelet拉入(通常由调度器)。如果已经提取了图像,则该图像位于特定节点上,因此您可以转到该节点并检查该图像,但k8s不提供任何api来检查节点上的图像,因此您需要自己解决该问题。这种方法会产生一些问题。你有一个带标签的pod是什么?有文件证明,k8s在图像有
latest
标签时,总是强制拉取所有新图像。现在,如果您在本地检查此图像,但存储库中的图像不同,该怎么办?