在将args传递到容器时Kubernetes的pod /部署?

IsK*_*Kor 2 yaml args docker kubernetes

我是docker / k8s世界的新手,有人问我是否可以使用args部署容器来修改行为(通常是应用程序在“主”版本还是“从”版本中工作)。也许不是最佳解决方案,但它可以工作:

这是验证的简单测试。我用一个脚本创建了一个自定义图像:role.sh:

#!/bin/sh
ROLE=$1
echo "You are running "$ROLE" version of your app"
Run Code Online (Sandbox Code Playgroud)

Dockerfile:

FROM centos:7.4.1708

COPY ./role.sh /usr/local/bin
RUN chmod a+x /usr/local/bin/role.sh
ENV ROLE=""
ARG ROLE

ENTRYPOINT ["role.sh"]
CMD ["${ROLE}"]
Run Code Online (Sandbox Code Playgroud)

如果我使用以下命令从docker启动此容器:

docker run -dit --name test docker.local:5000/test master
Run Code Online (Sandbox Code Playgroud)

我最终得到以下日志,这正是我要查找的内容:

You are running master version of your app
Run Code Online (Sandbox Code Playgroud)

现在,我想使用yaml文件在k8s上具有相同的行为。我尝试了几种方法,但是都没有用。

YAML文件:

apiVersion: v1
kind: Pod
metadata:
  name: master-pod
  labels:
     app: test-master
spec:
  containers:
    - name: test-master-container
      image: docker.local:5000/test
      command: ["role.sh"]
      args: ["master"]
Run Code Online (Sandbox Code Playgroud)

我看到了很多不同的方法可以做到这一点,但我必须说,我仍然没有理解ARG和ENV之间的区别。

我也尝试过

 - name: test-master-container
   image: docker.local:5000/test
   env:
     - name: ROLE
       value: master
Run Code Online (Sandbox Code Playgroud)

 - name: test-master-container
   image: docker.local:5000/test    
   args:
     - master
Run Code Online (Sandbox Code Playgroud)

但是这些都不起作用,我的吊舱始终处于CrashLoopBackOff状态。。在此先感谢您的帮助!

Dav*_*aze 5

在特定领域方面:

  • Kubernetes的command:匹配Docker的“入口点”概念,此处指定的任何内容均作为容器的主要过程运行。command:如果您的Dockerfile已经正确,则无需在pod规范中指定ENTRYPOINT
  • Kubernetes的args:匹配Docker的“命令”概念,此处指定的任何内容均作为命令行参数传递给入口点。
  • Docker和Kubernetes中的环境变量都具有其通常的Unix语义。
  • Dockerfile ARG指定映像的构建时配置设置。该扩展规则和环境变量的相互作用是有点奇怪。以我的经验,这有几个有用的用例(“我实际上要针对哪个JVM版本构建?”),但是从映像构建的每个容器都将具有相同的继承ARG值。这不是用于运行时配置的好机制。
  • 对于可以在Dockerfile或运行时中设置的各种内容(ENV变量,EXPOSEd端口,默认值CMD,尤其是VOLUME),没有必要特别在Dockerfile中“声明”它们以便能够在运行时进行设置。

有两种或多或少的等效方法可以完成您所描述的事情。(docker run为了简洁起见,我将使用语法。)可能最灵活的方法是将其ROLE设置为环境变量。当您运行入口点脚本时,您可以假定它$ROLE具有一个值,但是值得检查。

#!/bin/sh
# --> I expect $ROLE to be set
# --> Pass some command to run as additional arguments
if [ -z "$ROLE" ]; then
  echo "Please set a ROLE environment variable" >&2
  exit 1
fi
echo "You are running $ROLE version of your app"
exec "$@"
Run Code Online (Sandbox Code Playgroud)
docker run --rm -e ROLE=some_role docker.local:5000/test /bin/true
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以ROLE根据需要在Dockerfile中指定默认值。

FROM centos:7.4.1708
COPY ./role.sh /usr/local/bin
RUN chmod a+x /usr/local/bin/role.sh
ENV ROLE="default_role"
ENTRYPOINT ["role.sh"]
Run Code Online (Sandbox Code Playgroud)

第二条路径是将角色用作命令行参数:

FROM centos:7.4.1708
COPY ./role.sh /usr/local/bin
RUN chmod a+x /usr/local/bin/role.sh
ENV ROLE="default_role"
ENTRYPOINT ["role.sh"]
Run Code Online (Sandbox Code Playgroud)
#!/bin/sh
# --> pass a role name, then a command, as parameters
ROLE="$1"
if [ -z "$ROLE" ]; then
  echo "Please pass a role as a command-line option" >&2
  exit 1
fi
echo "You are running $ROLE version of your app"
shift        # drops first parameter
export ROLE  # makes it an environment variable
exec "$@"
Run Code Online (Sandbox Code Playgroud)

我可能更喜欢环境变量路径,因为它更容易提供多个不相关的选项,并且不会在Docker调用的“命令”部分中混合“设置”和“命令”。

关于您的Pod为何“崩溃”的原因:Kubernetes通常期望Pod可以长时间运行,因此,如果您编写一个仅打印某些内容并退出的容器,Kubernetes将会重新启动它,并且当它不出现时,它将始终结束CrashLoopBackOff状态。对于您现在要尝试执行的操作,不必担心,请看一下kubectl logspod的。如果这困扰您,请考虑设置Pod规范的重启策略