实就是概念上的 主进程/命令参数

contextcommand/processargs
dockerfileENTRYPOINTCMD
docker-composeentrypointcommand
k8scommandargs

Dockerfile 中的 CMD 与 ENTRYPOINT

  • CMD: 定义容器启动时的默认命令或参数。

    • 若容器没有 ENTRYPOINT,CMD 指定的命令将作为主进程运行
    • 可被 docker run 命令行参数轻易覆盖
    • 一个 Dockerfile 中只有最后一个 CMD 指令生效
  • ENTRYPOINT: 设置容器启动时必须执行的命令,不易被覆盖。

    • 作为容器的主进程运行
    • 更适合运行固定不变的命令
  • 组合使用: 当 CMD 与 ENTRYPOINT 同时存在时:

    • ENTRYPOINT 是实际执行的命令
    • CMD 内容会作为参数传递给 ENTRYPOINT
    • 例如:ENTRYPOINT ["nginx"]CMD ["-g", "daemon off;"] 会运行 nginx -g "daemon off;"

Docker Compose 配置

  • entrypoint:

    • 对应Dockerfile中的ENTRYPOINT
    • 会完全覆盖Dockerfile中定义的ENTRYPOINT
    • 定义容器必须执行的命令
  • command:

    • 对应Dockerfile中的CMD
    • 会覆盖Dockerfile中定义的CMD
    • 提供默认命令或参数
  • 覆盖规则:

    • docker-compose.yml中的设置优先级高于Dockerfile
    • 允许在不修改镜像的情况下调整容器启动行为
    • 实现同一镜像在不同环境中的灵活配置
  • 组合使用:

    • 与Dockerfile逻辑相同,command作为entrypoint的参数
    • 例:entrypoint: ["php"] + command: ["-S", "0.0.0.0:8000"] = php -S 0.0.0.0:8000

Kubernetes 中的 command 和 args

  • command: 指定主进程, 表现上覆盖了容器启动时的默认入口命令(即 Dockerfile 中的 ENTRYPOINT)。
  • args: 指定参数, 表现上覆盖了容器启动时的默认参数(即 Dockerfile 中的 CMD),如果没有 command 被指定,args 的第一个就是主进程命令。
  • 如果你在 Kubernetes 的 Pod 配置中使用了 command,Dockerfile 中的 CMDENTRYPOINT 会被覆盖。如果你在 Pod 配置中使用了 args,但没有使用 command,那么 Dockerfile 中的 ENTRYPOINT 将作为入口命令,而 args 将覆盖 Dockerfile 中的 CMD

示例对比

例子1: 仅 CMD

Dockerfile

FROM ubuntu
CMD ["echo", "Hello, Docker!"]

Kubernetes Pod

containers:
- name: mycontainer
  image: myimage

最终命令: echo Hello, Docker!

Docker Compose

version: '3'
services:
  myservice:
    image: myimage

最终命令: echo Hello, Docker!


例子2: 仅 ENTRYPOINT

Dockerfile

FROM ubuntu
ENTRYPOINT ["echo"]

Kubernetes Pod

containers:
- name: mycontainer
  image: myimage
  args: ["Hello, Kubernetes!"]

最终命令: echo Hello, Kubernetes!

Docker Compose

version: '3'
services:
  myservice:
    image: myimage
    command: ["Hello, Docker Compose!"]

最终命令: echo Hello, Docker Compose!


例子3: 同时有 CMD 和 ENTRYPOINT

Dockerfile

FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["Hello, Docker!"]

Kubernetes Pod

containers:
- name: mycontainer
  image: myimage

最终命令: echo Hello, Docker!

Docker Compose

version: '3'
services:
  myservice:
    image: myimage

最终命令: echo Hello, Docker!


例子4: ENTRYPOINT + CMD,Kubernetes 有 command 和 args

Dockerfile

FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["Hello, Docker!"]

Kubernetes Pod

containers:
- name: mycontainer
  image: myimage
  command: ["cat"]
  args: ["/etc/os-release"]

最终命令: cat /etc/os-release

Docker Compose

version: '3'
services:
  myservice:
    image: myimage
    entrypoint: ["cat"]
    command: ["/etc/os-release"]

最终命令: cat /etc/os-release


例子5: 无 CMD 和 ENTRYPOINT,Kubernetes 有 command 和 args

Dockerfile

FROM ubuntu

Kubernetes Pod

containers:
- name: mycontainer
  image: myimage
  command: ["cat"]
  args: ["/etc/os-release"]

最终命令: cat /etc/os-release

Docker Compose

version: '3'
services:
  myservice:
    image: myimage
    command: ["cat", "/etc/os-release"]

最终命令: cat /etc/os-release