docker - 将 args 传递给容器时 Kubernetes pod/部署?

标签 docker kubernetes yaml args

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

这是一个简单的测试来验证。我制作了一个带有脚本的自定义图像:
角色.sh:

#!/bin/sh
ROLE=$1
echo "You are running "$ROLE" version of your app"

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}"]

如果我使用以下命令通过 docker 启动此容器:
docker run -dit --name test docker.local:5000/test master

我最终得到以下日志,这正是我正在寻找的:
You are running master version of your app

现在我想使用 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"]

我看到了很多不同的方法来做到这一点,我必须说我仍然不明白 ARG 和 ENV 之间的区别。

我也试过
 - name: test-master-container
   image: docker.local:5000/test
   env:
     - name: ROLE
       value: master


 - name: test-master-container
   image: docker.local:5000/test    
   args:
     - master

但这些都不起作用,我的 pod 总是处于 CrashLoopBackOff 状态..
在此先感谢您的帮助!

最佳答案

在具体领域方面:

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

  • 有几种或多或少等效的方法可以执行您所描述的操作。 (为了紧凑起见,我将使用 docker run 语法。)可能最灵活的方法是使用 ROLE设置为环境变量;当您运行入口点脚本时,您可以假设 $ROLE有一个值(value),但值得检查。

    #!/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 "$@"
    

    docker run --rm -e ROLE=some_role docker.local:5000/test /bin/true
    

    在这种情况下,您可以指定默认值 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"]
    

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

    #!/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 "$@"
    

    docker run --rm docker.local:5000/test some_role /bin/true
    

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

    至于你的pod为什么会“crash”:Kubernetes一般都希望pods是长时间运行的,所以如果你写了一个容器,只是打印了一些东西就退出了,Kubernetes会重启它,当它不熬夜的时候,它会一直收尾 CrashLoopBackOff状态。对于您现在正在尝试做的事情,请不要担心并查看 kubectl logs pod 的。考虑设置 pod 规范的 restart policy如果这困扰你。

    关于docker - 将 args 传递给容器时 Kubernetes pod/部署?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256980/

    相关文章:

    docker - Docker-Compose通过服务IP

    perl - 我如何告诉 CPAN.pm 从哪里获取模块?

    docker - 在构建系统中创建Docker容器的惯用策略是什么

    linux - 使用 docker 在本地开发中用于包管理器的容器?

    windows - 在Windows上安装Kubectl插件

    amazon-web-services - 节点缩放后的 K8s StatfullSets "pending"

    kubernetes - 在 kubernetes 中更改代理模式

    Azure DevOps YAML 模板传递哈希集/映射/字典/对象 - 键值?

    Java:帮助使用 Jackson 读取 YAML 中的关联数组

    c# - 来自 Docker 的多个 Mysql 连接 -> 套接字错误