DevOps
CICD
K8s
Docker
今天我們開始進入 K8s
元件的介紹,筆者想說還是先介紹一些基本的東東,但是會盡量focus在一些比較不容易注意到的事,那就開始吧~
在 K8s
中有一點是非常重要的,那就是我們無法直接對Container操作,我們只能操作Pod
。Pod是在 K8s
中能創建和操作的最小單位。
一個
image
被run成Conatiner
,Pod
運行這個Container
在Node
上
Pod的YAML範例如下:
$ vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
創建這個Pod
可以透過kubectl
命令:
$ kubectl apply -f pod.yaml
## or
$ kubectl create -f pod.yaml
kubectl create
v.s.kubectl apply
kubectl create
:
kubectl create
是所謂的"命令式管理"(Imperative Management
)。通過這種方法,可以告訴Kubernetes API你要創建,替換或刪除的內容。kubectl create
命令,是先刪除所有現有的東西,重新根據YAML文件生成新的。所以要求YAML文件中的配置必須是完整的kubectl create
命令,用同一個YAML文件重複創建會失敗。
kubectl apply
:
kubectl apply
是"聲明式管理"(Declarative Management
)方法的一部分,在該方法中,即使對目標用了其他更改,也可以"保持"你對目標(即按比例縮放)應用的更改。kubectl apply
命令,根據配置文件裡面列出来的内容,生及現有的。所以YAML文件的内容可以只寫需要升级的欄位簡單理解就是,
kubectl apply
可以重複創建;kubectl create
只能創建一次
Pod
相關指令如下(這些先列舉一些,更詳細的會在之後幾天的【K8s常用指令&Cheat Sheet】主題作介紹)
## 創建po
$ kubectl apply -f pod.yaml
$ kubectl create -f pod.yaml
$ kubectl run po <pod-name> --image=<image-name> --restart=Never --dry-run=client
## 查看現有pod
$ kubectl get po
## 查看該pod詳細資訊
$ kubectl describe po <pod-name>
## 刪除pod
$ kubectl delete po
## 查看pod log
$ kubectl logs <pod-name>
因為Pod QoS
跟資源配置有關,一般教學文章可能會省略這邊,但考試還滿常出現的,所以特別拉出一個QoS
的主題來介紹~
當 Kubernetes
創建一個 Pod
時,它會给 Pod
分配一個 QoS
等級,分為:
要给 Pod
分配 QoS
等級為 Guaranteed
:
Pod
裡的每個Container
都必須有memory limit和request,而且必須是一樣的。Pod
裡的每個Container
都必須有CPU limit和request,而且必須是一樣的。創建一個Pod
$ kubectl run nginx --image=nginx --limits cpu=1,memory=200Mi --restart=Never --dry-run=client -o yaml > pod.yaml
$ kubectl apply -f pod.yaml
查看Pod
訊息
$ kubectl describe po nginx
...
Limits:
cpu: 1
memory: 200Mi
Requests:
cpu: 1
memory: 200Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-68jm7 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-68jm7:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-68jm7
Optional: false
QoS Class: Guaranteed
...
最後一行顯示QoS
為Guaranteed
等級,且limit=request
如果一個容器配置了cpu/memory limit,但是没有配置cpu/memory request,那
Kubernetes
會自動给容器分配一個符合cpu/memory limit的request。也就是說,其實K8s
為Pod
提供的預設QoS
等級是Guaranteed
要给 Pod
分配 QoS
等級為 Burstable
:
Pod
不滿足 QoS
等级 Guaranteed
的要求。Pod
裡至少有一個容器有memory或CPU request。例子 1 :
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
例子 2
一個含有两個容器的 Pod
的配置文件,其中一個容器指定了memory request為 200MB ,另外一個沒有任何request或limit。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-4
namespace: qos-example
spec:
containers:
- name: qos-demo-4-ctr-1
image: nginx
resources:
requests:
memory: "200Mi"
- name: qos-demo-4-ctr-2
image: redis
注意到這個 Pod
滿足了 QoS
等級為 Burstable
的要求。即,不滿足 Guaranteed
的要求,而且其中一個容器有memory request。
要给 Pod
分配 QoS
等級為 BestEffort
:
Pod
裡的容器必須沒有任何memory或者 CPU 的limit或request。例如 :
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
當越來越多使用者存取Pod
時,會讓Pod
負擔增高,這時K8s
會啟動Scaling
的機制,幫忙分擔大量的服務需求。有兩種可能的Scaling
方式:
Pod
內增加一個一樣Container
Pod
,包含裡面的Container
大家覺得哪種方法比較好呢?
K8s
採用的方法是 第2種: 增加一個一樣的Pod,包含裡面的Container啦~
看到這你可能會想,是不是一個Pod
內只能有一個Container
?其實不然,一個Pod
可以由一個或多個Conatiner
組成,但是在同個Pod內的Container,通常彼此之間有緊密的關係,會互相搭配使用。
舉例來說,一個Web Application
會需要一個主要的Web Server
,其他輔助的像是Database
、使用者輸入、檔案處理和身分驗證等等的,我們會將這些都拆分成一個個Container
,包在同一個Pod
內。我們稱這些輔助型Container
為Helper Containers
,這個Pod
則稱為Multi-Container Pod
。
前面提到Pod Scaling
的策略,那麼這個策略是怎麼做到的呢?今天當我們要把一個 Pod
做橫向擴展,也就是複製多個相同的 Pod
在 Cluster
中同時提供服務,並監控若有 Pod
當機就需重新啟動。如果我們要一個 Pod
一個 Pod
透過指令建立並監控是很花時間的。因此,Deployment
這個特殊元件就是用來幫我們達成上述的要求。
Deployment
最主要的功能之一就是自動佈署一個容器應用的多份備份,以及持續監控備份的數量,在集群內始終維持使用者指定的備份數量
當我們說一個Application時,其實指的就是一個
Deployment
Deployment
範例YAML檔 :
$ vim deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
我們看一下spce
裡的information
Pod
,在這邊給的數字是所謂的 Desire State,當 Cluster 運行時如果 Pod
數量低於此數字,Kubernetes
就會自動幫我們增加 Pod
,反之就會幫我們關掉 Pod
,若有 Pod
故障,也會自動刪除此 Pod
,並新增一個新的。(是不是很神奇阿~)Deployment
所建立的 Pod
的設定,重建後的 Pod
也依此設定重建。可直接將 Pod
YAML內metadata
和spec
的欄位資料貼上就行了Deployment
的規則要適用到哪些 Pod
,可依據 Pod
的label
來選取Deployment
創建後,會同步創建ReplcaSet
和 Pod
,他們的關係是這樣
Deployment
的另外一個好處就是系統無縫更新,當 Pod
需要更新時,Kubernetes
不會直接砍掉我們所有的 Pod
,而是會先建立新的 Pod
,該 Pod
開始正常運行後,才會刪除舊的 Pod
,如此就可達到無停機的系統升級(Zero Downtime Rollout)。
可參考這篇教學。
今天我們開始介紹 K8s
中的 resource-object
,介紹了最小運行單元 Pod
,以及 Pod
的 QoS
,筆者覺得這部分還滿重要的,考試也經常看到此類題型,因此特別拉出來介紹;也介紹了經常用到的 Deployment
,跳過了Replication Controller
和 ReplicaSet
,主要是因為篇幅不夠,而這兩者又通常和 Deployment
一同使用,所以筆者就只介紹 Deployment
。好啦,今天就到這囉~ 謝謝大家~
Kubernetes 基礎教學(二)實作範例
Zero-downtime Deployment in Kubernetes with Jenkins
What are Pods in Kubernetes?
You can find me on