---
# System prepended metadata

title: 使用 kubectl exec 在 Kubernetes Pod 裡執行命令
tags: [kubectl, pod, kubernetes]

---

# kubectl get pods

## 在 app 命名空間中，找出所有 label 為 app=hello-mtls 的 Pod，然後只顯示第一個符合條件的 Pod 名稱，不輸出其餘資訊

```shell!
echo $(kubectl get pods -l app=hello-mtls -n app -o jsonpath='{$.items[0].metadata.name}')
```

> [!Tip]
> - -l app=hello-mtls：這是 label selector，依據 Pod 上標註的 label 來篩選 Pod。這裡是選擇 label key 為 app，value 為 hello-mtls 的所有 Pod。
> - -n app：指定在 app 這個命名空間(namespace)內查詢 Pod。Kubernetes 中 Pod 是有命名空間隔離的資源，這可以限定查詢範圍
> - -o jsonpath='{$.items.metadata.name}'：-o 指定輸出格式，jsonpath 是一種透過 JSONPath 表達式來篩選 JSON 結構中特定欄位的格式 
>   - `$.items.metadata.name`：`items` 是 Pod 列表的陣列，`` 裡指的是選擇該陣列的第一個 Pod，`metadata.name` 則是該 Pod 的名字。即此輸出格式會直接回傳符合條件 Pod 清單中第一個 Pod 的名稱

## 在 kubernetes pod 裡執行指令

```shell!
export HELLO_MTLS=$(kubectl get pods -l app=hello-mtls -o jsonpath='{$.items[0].metadata.name}')
kubectl exec -it $HELLO_MTLS -c hello-mtls -- ls /var/run/autocert.step.sm
```

> [!Tip]
> - `kubectl exec`：在 Kubernetes Pod 裡執行一個指令。
> - `-i`：啟用標準輸入（stdin）。
> - `-t`：分配一個終端（TTY），可互動執行命令。
> - `$HELLO_MTLS`：Pod 名稱，從環境變數中取得。
> - `-c hello-mtls`：指定 Pod 中的目標容器名稱，因一個 Pod 可能包含多個容器，必須指定操作哪一個。
> - `--`：分隔符，後面接的是要在容器內執行的命令，不會被 kubectl 當作參數解析。
> - `ls /var/run/autocert.step.sm`：在容器內實際執行的命令，列出該目錄下的檔案。

**整句意思**
名稱為 `$HELLO_MTLS` 的 Pod 中，針對名字叫 `hello-mtls` 的容器，以互動終端模式執行 `ls /var/run/autocert.step.sm` 這個命令。

**重點提醒**
`-c` 是重要參數，讓 kubectl 知道對哪個容器操作，因為一個 Pod 內可能有多個容器。