7.2.1 在Docker中定义命令与参数

容器中运行的完整指令由两部分组成:命令、参数。

了解ENTRYPOINT与CMD

Dockerfile中的两种指令分别定义命令与参数这两个部分:

  • ENTRYPOINT 定义容器启动时被调用的可执行程序。
  • CMD 指定传递给ENTRYPOINT的参数。

尽管可以直接使用CMD指令指定镜像运行时想要执行的命令,正确的做法依旧是借助ENTRYPOINT指令,仅仅用CMD指定所需的默认参数。这样,镜像可以直接运行,无须添加任何参数:
$ docker run 7.2 向容器传递命令行参数 - 图2
或者是添加一些参数,覆盖Dockerfile中任何由CMD指定的默认参数值:
$ docker run 7.2 向容器传递命令行参数 - 图3

了解shell与exec形式的区别

上述两条指令均支持以下两种形式:

  • shell形式——如:ENTRYPOINT command param1 param2
  • exec形式——如:ENTRYPOINT [“executable”, “param1”, “param2”]

两者的区别在于指定的命令是否是在shell中被调用。

可以从容器中的运行进程列表看出使用哪种方式:
#exec形式:
image.png

shell形式:
image.png

可以看出,主进程(PID 1)是shell进程而非node进程,node进程(PID 7)在shell中启动。shell进程往往是多余的,因此通常可以直接采用exec形式的ENTRYPOINT指令。

使fortune镜像中的INTERVAL参数可配置

image.png
image.png
image.png
image.png
image.png

  1. mkdir -p /root/Dockerfile/fortune-agrs
  2. cd /root/Dockerfile/fortune-agrs
  3. cat >fortuneloop.sh <<'EOF'
  4. #!/bin/bash
  5. trap "exit" SIGINT
  6. INTERVAL=$1
  7. echo Configured to generate new fortune every $INTERVAL seconds
  8. mkdir -p /var/htdocs
  9. while :
  10. do
  11. echo $(date) Writing fortune to /var/htdocs/index.html
  12. /usr/games/fortune > /var/htdocs/index.html
  13. sleep $INTERVAL
  14. done
  15. EOF
  16. chmod +x fortuneloop.sh
  17. cat >Dockerfile <<'EOF'
  18. FROM ubuntu:latest
  19. RUN apt-get update ; apt-get -y install fortune
  20. ADD fortuneloop.sh /bin/fortuneloop.sh
  21. ENTRYPOINT ["/bin/fortuneloop.sh"]
  22. CMD ["10"]
  23. EOF
  24. docker build -t 10.0.0.10:5000/luksa/fortune:args .
  25. docker push 10.0.0.10:5000/luksa/fortune:args
  26. docker run -it 10.0.0.10:5000/luksa/fortune:args
  27. docker run -it 10.0.0.10:5000/luksa/fortune:args 15

7.2.2在Kubernetes中覆盖命令和参数

在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD均可以被覆盖,仅需在容器定义中设置属性command和args的值。
image.png
绝大多数情况下,只需要设置自定义参数。命令一般很少被覆盖,除非针对一些未定义ENTRYPOINT的通用镜像,例如busybox。

注意: command和args字段在pod创建后无法被修改。

image.png

用自定义INTERVAL参数运行fortune pod

image.png
多参数值的情况可以采用如下标记:
args:
- foo
- bar
- “15”
提示: 字符串值无须用引号标记,数值需要。(把数值型15转换成字符串”15”,因为args是字符串数组)

  1. cd /root/k8s/
  2. cat >fortune-pod-args.yaml <<'EOF'
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: fortune2s
  7. spec:
  8. containers:
  9. - image: 10.0.0.10:5000/luksa/fortune:args
  10. args: ["2"]
  11. name: html-generator
  12. volumeMounts:
  13. - name: html
  14. mountPath: /var/htdocs
  15. - image: 10.0.0.10:5000/luksa/nginx
  16. name: web-server
  17. volumeMounts:
  18. - name: html
  19. mountPath: /usr/share/nginx/html
  20. readOnly: true
  21. ports:
  22. - containerPort: 80
  23. protocol: TCP
  24. volumes:
  25. - name: html
  26. emptyDir: {}
  27. EOF
  28. kubectl create -f fortune-pod-args.yaml
  29. #检查实验结果(方法一)
  30. kubectl port-forward fortune2s 8080:80
  31. #另开一个终端
  32. curl localhost:8080
  33. #检查实验结果(方法二)
  34. kubectl logs fortune2s -c html-generator -f