04 - Commands and Arguments

CMD vs ENTRYPOINT 差異比較

CMD 是什麼?

  • CMD 用來指定預設要執行的命令或參數
  • 如果你在執行容器時提供了命令或參數,那麼 CMD 的內容會被覆蓋掉
  • 通常搭配 ENTRYPOINT 使用,用來提供預設參數。

範例:
```
CMD ["echo", "Hello from CMD"]
```

執行:
```
docker run myimage
# 輸出:Hello from CMD

docker run myimage echo "我自訂的訊息"
# 輸出:我自訂的訊息(CMD 被覆蓋)
```


ENTRYPOINT 是什麼?

  • ENTRYPOINT 用來定義容器啟動時一定會執行的主命令
  • 不會被 docker run 的參數覆蓋(除非你用 --entrypoint 明確指定)。
  • 適合讓容器專注執行某個固定的程式或腳本。
範例:
```
ENTRYPOINT ["echo"]
```

執行:
```
docker run myimage "來自 ENTRYPOINT"
# 輸出:來自 ENTRYPOINT
```


CMD + ENTRYPOINT 一起使用

當你同時使用這兩個指令時:

  • ENTRYPOINT 是主命令(command)
  • CMD 是預設參數(arguments)

範例:
```
ENTRYPOINT ["echo"]
CMD ["Hello from CMD"]

```

執行:
```
docker run myimage
# 輸出:Hello from CMD

docker run myimage "嗨!"
# 輸出:嗨!(CMD 被自訂參數取代)
```

總結比較表



Q: What is the command used to run the pod ubuntu-sleeper?

$ kubectl describe pod ubuntu-sleeper | grep -i command -A 5          

Ans: sleep 4800


Q: Create a pod with the `ubuntu` image to run a container to `sleep` for `5000 seconds`. Modify the file `ubuntu-sleeper-2.yaml`.

  • Pod Name: ubuntu-sleeper-2
  • Command: sleep 5000

$ vim ubuntu-sleeper-2.yaml                       
$ kubectl apply -f ubuntu-sleeper-2.yaml     
```
apiVersion: v1
kind: Pod 
metadata:
  name: ubuntu-sleeper-2
spec:
  containers:
  - name: ubuntu
    image: ubuntu
    command:
      - "sleep"
      - "5000"

```
or 
```
apiVersion: v1
kind: Pod 
metadata:
  name: ubuntu-sleeper-2
spec:
  containers:
  - name: ubuntu
    image: ubuntu
    command: ["sleep", "5000"]
```
or 
```
apiVersion: v1
kind: Pod 
metadata:
  name: ubuntu-sleeper-2
spec:
  containers:
  - name: ubuntu
    image: ubuntu
    command: ["sleep"]
    args: ["5000"]
```

Q: Create a pod using the file named ubuntu-sleeper-3.yaml. There is something wrong with it. Try to fix it!

  • Pod Name: ubuntu-sleeper-3
  • Command: sleep 1200


```
apiVersion: v1
kind: Pod 
metadata:
  name: ubuntu-sleeper-3
spec:
  containers:
  - name: ubuntu
    image: ubuntu
    command:
      - "sleep"
      - "1200"       # Fix: 必須是 "string"
```


Q: Update pod ubuntu-sleeper-3 to sleep for 2000 seconds.

  • Pod Name: ubuntu-sleeper-3
  • Command: sleep 2000

$ kubectl edit pod ubuntu-sleeper-3         

$ kubectl replace --force -f /tmp/kubectl-edit-1983640283.yaml        



Q: Inspect the file Dockerfile2 given at /root/webapp-color directory. What command is run at container startup?

Ans: `python app.py --color red`

Inspect the ENTRYPOINT and CMD in Dockerfile2.


Q: Inspect the two files under directory webapp-color-2. What command is run at container startup?

Ans: `--color green`
The ENTRYPOINT in the Dockerfile is overridden by the command in the pod definition file.
Since the entrypoint is overridden in the pod definition, the command that will be run is just --color green.


webapp-color-2/Dockerfile
```
FROM python:3.6-alpine
RUN pip install flask
COPY . /opt/
EXPOSE 8080
WORKDIR /opt
ENTRYPOINT ["python", "app.py"]
CMD ["--color", "red"]

預設會執行:python app.py --color red
```

webapp-color-2/webapp-color-pod.yaml
```
apiVersion: v1
kind: Pod 
metadata:
  name: webapp-green
  labels:
      name: webapp-green
spec:
  containers:
  - name: simple-webapp
    image: kodekloud/webapp-color
    command: ["--color","green"]

Kubernetes 這裡的 command 實際上會取代 Dockerfile 中的 ENTRYPOINT,而不是 CMD
✅ Kubernetes 的 command 對應 Docker 的 ENTRYPOINT
✅ Kubernetes 的 args 對應 Docker 的 CMD
```



Q: Inspect the two files under directory webapp-color-3. What command is run at container startup?

Ans: `python app.py --color pink`

webapp-color-2/Dockerfile
```
FROM python:3.6-alpine
RUN pip install flask
COPY . /opt/
EXPOSE 8080
WORKDIR /opt
ENTRYPOINT ["python", "app.py"]
CMD ["--color", "red"]
```

webapp-color-2/webapp-color-pod.yaml
```
apiVersion: v1
kind: Pod 
metadata:
  name: webapp-green
  labels:
      name: webapp-green
spec:
  containers:
  - name: simple-webapp
    image: kodekloud/webapp-color
    command: ["python", "app.py"]
    args: ["--color", "pink"]
```


Q: Create a pod with the given specifications. By default it displays a `blue` background. Set the given command line arguments to change it to `green`.

  • Pod Name: webapp-green
  • Image: kodekloud/webapp-color
  • Command line arguments: --color=green
$ kubectl run webapp-green --image kodekloud/webapp-color -- --color green   
```
apiVersion: v1 
kind: Pod 
metadata:
  name: webapp-green
  labels:
      name: webapp-green 
spec:
  containers:
  - name: simple-webapp
    image: kodekloud/webapp-color
    args: ["--color", "green"]
```

留言