7.2.1 在Docker中定义命令与参数
容器中运行的完整指令由两部分组成:命令、参数。
了解ENTRYPOINT与CMD
Dockerfile中的两种指令分别定义命令与参数这两个部分:
- ENTRYPOINT 定义容器启动时被调用的可执行程序。
- CMD 指定传递给ENTRYPOINT的参数。
尽管可以直接使用CMD指令指定镜像运行时想要执行的命令,正确的做法依旧是借助ENTRYPOINT指令,仅仅用CMD指定所需的默认参数。这样,镜像可以直接运行,无须添加任何参数:
$ docker run
或者是添加一些参数,覆盖Dockerfile中任何由CMD指定的默认参数值:
$ docker run
了解shell与exec形式的区别
上述两条指令均支持以下两种形式:
- shell形式——如:ENTRYPOINT command param1 param2
- exec形式——如:ENTRYPOINT [“executable”, “param1”, “param2”]
两者的区别在于指定的命令是否是在shell中被调用。
可以从容器中的运行进程列表看出使用哪种方式:
#exec形式:
shell形式:
可以看出,主进程(PID 1)是shell进程而非node进程,node进程(PID 7)在shell中启动。shell进程往往是多余的,因此通常可以直接采用exec形式的ENTRYPOINT指令。
使fortune镜像中的INTERVAL参数可配置
mkdir -p /root/Dockerfile/fortune-agrs
cd /root/Dockerfile/fortune-agrs
cat >fortuneloop.sh <<'EOF'
#!/bin/bash
trap "exit" SIGINT
INTERVAL=$1
echo Configured to generate new fortune every $INTERVAL seconds
mkdir -p /var/htdocs
while :
do
echo $(date) Writing fortune to /var/htdocs/index.html
/usr/games/fortune > /var/htdocs/index.html
sleep $INTERVAL
done
EOF
chmod +x fortuneloop.sh
cat >Dockerfile <<'EOF'
FROM ubuntu:latest
RUN apt-get update ; apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
ENTRYPOINT ["/bin/fortuneloop.sh"]
CMD ["10"]
EOF
docker build -t 10.0.0.10:5000/luksa/fortune:args .
docker push 10.0.0.10:5000/luksa/fortune:args
docker run -it 10.0.0.10:5000/luksa/fortune:args
docker run -it 10.0.0.10:5000/luksa/fortune:args 15
7.2.2在Kubernetes中覆盖命令和参数
在Kubernetes中定义容器时,镜像的ENTRYPOINT和CMD均可以被覆盖,仅需在容器定义中设置属性command和args的值。
绝大多数情况下,只需要设置自定义参数。命令一般很少被覆盖,除非针对一些未定义ENTRYPOINT的通用镜像,例如busybox。
注意: command和args字段在pod创建后无法被修改。
用自定义INTERVAL参数运行fortune pod
多参数值的情况可以采用如下标记:
args:
- foo
- bar
- “15”
提示: 字符串值无须用引号标记,数值需要。(把数值型15转换成字符串”15”,因为args是字符串数组)
cd /root/k8s/
cat >fortune-pod-args.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: fortune2s
spec:
containers:
- image: 10.0.0.10:5000/luksa/fortune:args
args: ["2"]
name: html-generator
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: 10.0.0.10:5000/luksa/nginx
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html
emptyDir: {}
EOF
kubectl create -f fortune-pod-args.yaml
#检查实验结果(方法一)
kubectl port-forward fortune2s 8080:80
#另开一个终端
curl localhost:8080
#检查实验结果(方法二)
kubectl logs fortune2s -c html-generator -f