简体   繁体   English

在Kubernetes中的Pod创建时是否可以指定Docker映像构建参数?

[英]Is it possible to specify a Docker image build argument at pod creation time in Kubernetes?

I have a Node.JS based application consisting of three services. 我有一个由三个服务组成的基于Node.JS的应用程序。 One is a web application, and two are internal APIs. 一个是Web应用程序,两个是内部API。 The web application needs to talk to the APIs to do its work, but I do not want to hard-code the IP address and ports of the other services into the codebase. Web应用程序需要与API对话才能完成其工作,但是我不想将其他服务的IP地址和端口硬编码到代码库中。

In my local environment I am using the nifty envify Node.JS module to fix this. 在我的本地环境中,我正在使用漂亮的envify Node.JS模块来解决此问题。 Basically, I can pretend that I have access to environment variables while I'm writing the code, and then use the envify CLI tool to convert those variables to hard-coded strings in the final browserified file. 基本上,我可以假装在编写代码时可以访问环境变量,然后使用envify CLI工具将这些变量转换为最终浏览器化文件中的硬编码字符串。

I would like to containerize this solution and deploy it to Kubernetes. 我想将这个解决方案容器化并将其部署到Kubernetes。 This is where I run into issues... 这是我遇到问题的地方...

I've defined a couple of ARG variables in my Docker image template. 我在Docker映像模板中定义了几个ARG变量。 These get turned into environment variables via RUN export FOO=${FOO} , and after running npm run-script build I have the container I need. 这些通过RUN export FOO=${FOO}变成环境变量,在运行npm run-script build我有了所需的容器。 OK, so I can run: 好的,所以我可以运行:

docker build . -t residentmario/my_foo_app:latest --build-arg FOO=localhost:9000 BAR=localhost:3000

And then push that up to the registry with docker push . 然后使用docker push送到注册表。

My qualm with this approach is that I've only succeeded in punting having hard-coded variables to the container image. 我对这种方法的不满是,我仅成功地将硬编码的变量添加到了容器映像中。 What I really want is to define the paths at pod initialization time. 真正想要的是在pod初始化时定义路径。 Is this possible? 这可能吗?

Edit : Here are two solutions. 编辑 :这是两个解决方案。

PostStart 开始后

Kubernetes comes with a lifecycle hook called PostStart . Kubernetes带有一个称为PostStart的生命周期挂钩。 This is described briefly in " Container Lifecycle Hooks ". 这在“ 容器生命周期挂钩 ”中进行了简要描述。

This hook fires as soon as the container reaches ContainerCreated status, eg the container is done being pulled and is fully initialized. 容器达到ContainerCreated状态后即会触发该钩子,例如,容器已完成拉出并已完全初始化。 You can then use the hook to jump into the container and run arbitrary commands. 然后,您可以使用钩子跳入容器并运行任意命令。

In our case, I can create a PostStart event that, when triggered, rebuilds the application with the correct paths. 在我们的例子中,我可以创建一个PostStart事件,该事件在触发时将使用正确的路径重建应用程序。

Unless you created a Docker image that doesn't actually run anything (which seems wrong to me, but let me know if this is considered an OK practice), this does require some duplicate work: stopping the application, rerunning the build process, and starting the application up again. 除非您创建了一个实际上不运行任何东西的Docker映像(这对我来说似乎是错的,但是请告诉我是否认为这是可以的做法),否则这确实需要一些重复的工作:停止应用程序,重新运行构建过程以及再次启动应用程序。

Command 命令

Per the comment below, this event doesn't necessarily fire at the right time. 根据下面的评论,此事件不一定在正确的时间触发。 Here's another way to do it that's guaranteed to work (and hence, superior). 这是保证可以正常工作的另一种方法(因此是上乘的)。

A useful Docker container ends with some variant on a CMD serving the application. 一个有用的Docker容器在为应用程序提供服务的CMD上带有一些变体。 You can overwrite this run command in Kubernetes, as explained in the "Define a Command and Arguments for a Container" section of the documentation. 您可以在Kubernetes中覆盖此运行命令,如文档的“定义容器的命令和参数”部分中所述。

So I added a command to the pod definition that ran a shell script that (1) rebuilt the application using the correct paths, provided as an environment variable to the pod and (2) started serving the application: 因此,我在pod定义中添加了一个command ,该command运行一个shell脚本,该脚本(1)使用正确的路径重建应用程序,并作为环境变量提供给pod,并且(2)开始为该应用程序提供服务:

command: ["/bin/sh"]
args: ["./scripts/build.sh"]

Worked like a charm. 像魅力一样工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM