如何在运行时将容器添加到Kubernetes容器

时间:2018-07-17 07:54:28

标签: docker kubernetes google-kubernetes-engine

我有多个Jobs 在k8s上运行。

这些作业运行一个自定义代理,该代理复制一些文件并为用户(受信任)提供的容器运行设置环境。 该代理在用户容器的一侧运行,捕获日志,等待容器退出并处理生成的结果。

为此,我们安装了Docker的套接字/var/run/docker.sock并作为特权容器运行,并且在代理内部,我们使用docker-py与用户容器进行交互(设置,运行,捕获日志,终止)。

这几乎可以正常工作,但我认为这是一个hack。由于用户容器是通过直接在节点上调用docker创建的,因此k8s并不知道它的存在。自从我们的监控工具与K8交互以来,这一直引起麻烦,并且无法看到这些独立的用户容器。由于用户容器的限制(cpu /内存)未计入对pod的请求,因此这也使pod调度更加难以管理。

我知道了init containers,但是这些与本用例并不完全匹配,因为我们要保持代理运行并监视用户容器,直到完成为止。

在容器上运行的容器是否可以请求Kubernetes将其他容器添加到代理正在运行的同一容器上?如果是这样,代理是否还可以请求Kubernetes随意删除用户容器(例如,满足某些自定义条件)?

5 个答案:

答案 0 :(得分:2)

this GitHub issue中,答案似乎是不可能在容器中添加或删除容器,因为容器规范中的容器列表是不可变的。

答案 1 :(得分:1)

在kubernetes 1.16中,有一个alpha功能可以创建临时容器,该容器可以“添加”到运行的容器中。请注意,这要求在相关组件(例如kubelet。对于云提供商提供的托管服务(例如EKS),可能很难在控制平面上启用它。

API Reference 1.16

Simple tutorial

答案 2 :(得分:0)

我认为您无法更改正在运行的pod,但是您可以定义自己的pod并使用API​​编程运行

我的意思是,您应该使用用户容器和任何其他所需的容器定义一个容器,并将其作为一个单元运行。您有可能需要进行活动检查,以便在用户容器死后完成后处理

答案 3 :(得分:0)

您可以使用shared volumes在容器中的多个容器之间共享数据。这将使您的代理容器从写在用户容器上的日志文件读取,并将配置文件放入共享卷中进行设置。

这样,您可以将用户容器和代理容器作为作业运行,并且两个容器都位于容器中。当两个容器都退出时,作业将完成。

您似乎在上面指示您正在手动终止用户容器。除非您执行了类似强制用户在共享卷上存在文件的情况下终止其执行的操作,否则共享卷将不会支持该操作。

  

在Pod上运行的容器是否可以请求Kubernetes   将其他容器添加到代理正在运行的同一容器中?和   如果是这样,代理是否还可以请求Kubernetes删除用户   集装箱(例如满足某些自定义条件)?

我不知道将容器添加到现有Job Pod定义中的任何方法。乔布斯没有副本选项,因此您无法像在“部署”中那样通过从0-> 1更改副本来破解它。

我不知道有什么方法可以使用kubectl来删除容器,而不是整个容器。参见kubectl delete

如果要杀死用户容器(而不是使其运行到完成状态),则必须进入主机并在用户容器上使用docker kill <sha>。确保在用户容器上设置.spec.template.spec.restartPolicy = "Never",否则k8s将重新启动它。

我建议:

  • 具有共享的卷以将日志传输到代理,以便代理可以设置用户容器
  • 使用户容器期望自己退出并从共享卷中读取配置

我不知道您正在做什么工作或用户如何制作容器,因此可能无法实现。如果您无法决定用户如何构建容器,则上述方法可能无效。

另一个选择是提供一个二进制文件,该二进制文件充当用户容器上的命令API。该二进制文件可以通过RPC接受“设置”,“运行”,“终止”,“传输日志”等命令,这将是其Docker容器中的主要过程。

然后,您可以为用户创建程序,例如:

  • 从您的容器中使用二进制:最新
  • 在此输入您想要的任何内容 容器并设置ENV JOB_PATH = / path / to / executable / code(或放置代码) 在特定位置)

无论采用哪种方式,都会有很多活动部件。

答案 4 :(得分:0)

您可以通过https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/

将容器动态注入容器中。
  

准入控制器是一段代码,用于拦截对   在持久化对象之前先使用Kubernetes API服务器,但是   在请求经过验证和授权后。控制器   由下面的列表组成,被编译到kube-apiserver中   二进制文件,并且只能由集群管理员配置。在   该列表有两个特殊的控制器:MutatingAdmissionWebhook   和ValidatingAdmissionWebhook。这些执行变异和   验证(分别)准入控制网络钩子   在API中配置。

     

准入控制器可以是“正在验证”,“正在变异”或两者兼而有之。   变异控制器可以修改其允许的对象;证实   控制器可能不会。

您可以通过https://kubernetes.io/docs/concepts/workloads/pods/podpreset/

向Pod注入其他运行时要求
  

Pod预设是用于注入额外运行时的API资源   需求在创建时放入Pod。您使用标签选择器   指定要应用给定Pod预设的Pod。