pod 是一組並置的容器,代表了 Kubernetes 中的基本構建模塊。在實際應用中我們並不會單獨部署容器,更多的是針對一組 pod 的容器進行部署和操作。然而這並不意味着一個 pod 總是要包含多個容器:實際上只包含一個單獨容器的 pod 也是非常常見的。值得注意的是,當一個 pod 包含多個容器時,這些容器總是運行於同一個工作節點上,一個 pod 絕不會跨越多個工作節點:
使用 pod 而不是直接使用容器的優點:同一 pod 中容器之間的部分隔離
一、使用 YAML 或 JSON 描述文件創建 pod
可以使用下面命令,查看上一篇文章通過命令創建的 pod 的 YAML 描述文件:kubectl get pods hello-minikube-6895494d6d-wsfmx -o yaml
1.1. 創建 pod 的 YAML 描述文件
kubia-manual.yaml:
apiVersion: v1 # Kubernetes API 版本
kind: Pod # Kubernetes 對象/資源類型
metadata:
name: kubia-manual # pod 的名稱
spec:
containers:
- image: luksa/kubia
name: kubia # 容器的名稱
ports:
- containerPort: 8080 # 應用監聽的端口
protocol: TCP
1.2. 創建 pod
kubectl create -f kubia-manual.yaml
kubectl create -f 命令用於從 YAML 或 JSON 文件創建任何資源(不只是 pod)
查看 pod 的完整描述文件:kubectl get pod kubia-manual -o yaml
1.3. 查看應用程序日誌
kubectl logs kubia-manual
kubectl logs kubia-manual -c kubia # 如果 pod 包含多個容器,可以顯示指定容器名稱
1.4. 向 pod 發送請求
可以使用上一篇文章中的 kubectl expose 創建一個 service,也可以通過端口轉發:kubectl port-forward kubia-manual 8888:8080
可以在本地使用端口 8888 訪問程序
遇到的報錯:unable to do port forwarding: socat not found
yum install -y socat
二、標籤
通過標籤來組織 pod 和所有其他 Kubernetes 對象(一個資源可以擁有多個標籤),可以通過一次操作對屬於某個組的所有 pod 進行操作,而不必單獨爲每個 pod 執行操作。
2.1. 創建 pod 時指定標籤
kubia-manual-with-labels.yaml:
apiVersion: v1 kind: Pod metadata: name: kubia-manual-v2 labels: creation_method: manual # 標籤 1 env: prod # 標籤 2 spec: containers: - image: luksa/kubia name: kubia ports: - containerPort: 8080 protocol: TCP
創建 pod:
kubectl create -f kubia-manual-with-labels.yaml
查看 pod 的標籤:kubectl get pods --show-labels
2.2. 修改現有 pod 的標籤
添加:
kubectl label pod kubia-manual creation_method=manual
修改(需要使用 —overwrite 選項):kubectl label pod kubia-manual-v2 env=debug --overwrite
2.3. 標籤選擇器
kubectl get pods -l creation_method=manual # 包含 creation_method=manual kubectl get pods -l env # 包含 env 標籤 kubectl get pods -l '!env' # 不包含 env 標籤 kubectl get pods -l creation_method!=manual # 不包含 creation_method=manual kubectl get pods -l creation_method=manual,env=debug # 包含 creation_method=manual,env=debug
三、命名空間
在使用多個命名空間的前提下,我們可以將包含大量組件的複雜系統拆分爲更小的不同組,這些不同組也可以用於在多租戶環境中分配資源,將資源分配爲生產、開發和 QA 環境,或者以其他任何你需要的方式分配資源。資源名稱只需在命名空間內保持唯一即可,因此兩個不同的命名空間可以包含同名的資源。大多數類型的資源都與命名空間相關,但也有一些例外,例如,全局且未被約束於單一命名空間的節點資源。
查看集羣中所有命名空間列表:kubectl get namespaces # namespaces 可以縮寫爲 ns
可以看到有個名爲 default 的命名空間,我們之前的操作都是在這個命名空間,之前使用 kubectl get 時未明確指定命名空間,因此 kubectl 總是默認爲 default 命名空間,只顯示該命名空間下的對象。指定命令空間:kubectl get pods --namespace kube-system # --namespace 可以使用 -n 代替
命名空間使我們能夠將不屬於一組的資源分到不重疊的組中。如果有多個用戶或用戶組正在使用同一個 Kubernetes 集羣,並且它們都各自管理自己獨特的資源集合,那麼它們就應該分別使用各自的命名空間。這樣一來,它們就不用特別擔心無意中修改或刪除其他用戶的資源,也無須關心名稱衝突。3.1. 創建命名空間
方法一:
custom-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: custom-namespace
kubectl create -f custom-namespace.yaml
方法二:kubectl create namespace custom-namespace
命名空間名字中不能包含點號3.2. 管理其他命名空間中的對象
如果想要在上面創建的命名空間中創建資源,可以在 metadata 字段中添加 namespace: custom-namespace 屬性,也可以創建資源時指定命名空間:
kubectl create -f kubia-manual.yaml -n custom-namespace
此時我們有兩個重名的 pod(kubia-manual),一個在 default 命名空間,一個在 custom-namespace 命名空間
需要注意的是:儘管命名空間將對象分隔到不同的組,只允許你對屬於特定命名空間的對象進行操作,但實際上命名空間之間並不提供對正在運行的對象的任何隔離。例如,你可能會認爲當不同的用戶在不同的命名空間中部署 pod 時,這些 pod 應該彼此隔離,並且無法通信,但事實並非如此。命名空間之間是否提供網絡隔離取決於 Kubernetes 所使用的網絡解決方案。當該解決方案不提供命名空間間的網絡隔離時,如果命名空間 foo 的某個 pod 知道命名空間 bar 中 pod 的 IP 地址,那它就可以將流量(例如 HTTP 請求)發送到另一個 pod。四、停止和移除 pod
kubectl delete pod kubia-manual-v2 # 按照名字刪除 kubectl delete pod -l creation_method=manual # 按照標籤刪除 kubectl delete ns custom-namespace # 通過刪除整個命名空間來刪除 kubectl delete pod --all # 刪除命名空間中的所有 pod,但保留命名空間: all 代表所有實例 kubectl delete all --all # 刪除命名空間中的(幾乎)所有資源:第一個 all 代表所有資源類型,第二個 all 代表所有實例