k8s創建pod資源對象-03

創建一個http應用程序

1)創建一個應用程序,我們使用 "kubectl run " 命令,是 “kubectl run -h” 查看命令使用幫助,命令說明告訴我們這個命令可以創建一個deployment或者job的容器(deployment和job是什麼意思,我們後續再講)
[root@master ~]# kubectl run nginx-deploy --image=nginx --port=80
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx-deploy created

[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
httpd-app 2/2 2 2 6m51s
nginx-deploy 1/1 1 1 8s

[root@master ~]# kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deploy 1/1 1 1 22s nginx-deploy nginx run=nginx-deploy
[root@master ~]# kubectl get pod -o wide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-5c9b546997-r24bq 1/1 Running 0 36s 10.244.1.7 node01 <none> <none>

[root@master ~]# curl 10.244.1.7  -I
HTTP/1.1 200 OK
當我們在集羣之外訪問是發現無法訪問,那麼集羣之外的客戶端如何才能訪問呢?這就需要我們的service服務了,下面我們就創建一個service,是外部客戶端可以訪問我們的pod
[root@master ~]# kubectl expose deployment nginx-deploy --name=myweb --port=80 --type=NodePort
service/myweb exposed
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d2h
myweb NodePort 10.106.20.142 <none> 80:32438/TCP 11s
nginx-svc ClusterIP 10.99.171.202 <none> 8080/39393/TCP 107m
在這裏插入圖片描述

pod應用程序的擴容與伸縮

[root@master ~]# kubectl scale deployment nginx-deploy --replicas=2
deployment.extensions/nginx-deploy scaled

[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-5c9b546997-n7mhg 1/1 Running 0 11s 10.244.2.7 node02 <none> <none>
nginx-deploy-5c9b546997-r24bq 1/1 Running 0 14m 10.244.1.7 node01 <none> <none>

也可以通過編寫容器的yaml配置文件來進行設置
[root@master ~]# kubectl edit deployment nginx-deploy
deployment.extensions/nginx-deploy edited

[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-5c9b546997-ls5nn 1/1 Running 0 6s 10.244.1.8 node01 <none> <none>
nginx-deploy-5c9b546997-n7mhg 1/1 Running 0 91s 10.244.2.7 node02 <none> <none>
nginx-deploy-5c9b546997-r24bq 1/1 Running 0 15m 10.244.1.7 node01 <none> <none>

服務的升級與回滾
[root@master ~]# kubectl describe deployments. nginx-deploy
Image: nginx
[root@master ~]# kubectl set image deployment nginx-deploy nginx-deploy=nginx:1.15
[root@master ~]# kubectl describe deployments. nginx-deploy
Image: nginx:1.15

應用程序服務的回滾

describe顯示容器的詳細信息
[root@master ~]# kubectl describe deployments nginx-deploy
----省略部分代碼----
Pod Template:
Labels: run=nginx-deploy
Containers:
nginx-deploy:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
----省略部分代碼----

升級版本
[root@master ~]# kubectl set image deployment nginx-deploy nginx-deploy=nginx:1.15
deployment.extensions/nginx-deploy image updated

[root@master ~]# kubectl describe deployments. nginx-deploy
----省略部分代碼----
Pod Template:
Labels: run=nginx-deploy
Containers:
nginx-deploy:
Image: nginx:1.15
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
----省略部分代碼----

回滾到之前版本
[root@master ~]# kubectl rollout undo deployment nginx-deploy
deployment.extensions/nginx-deploy rolled back

[root@master ~]# kubectl describe deployments nginx-deploy
----省略部分代碼----
Pod Template:
Labels: run=nginx-deploy
Containers:
nginx-deploy:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
----省略部分代碼----

kubectl常用命令集合

kubectl run #創建一個deployment或job來管理創建的容器
kubectl get #顯示一個或多個資源,可以使用標籤過濾,默認查看當前名稱空間的資源
kubectl expose #將一個資源暴露爲一個新的kubernetes的service資源,資源包括pod (po), service (svc), replicationcontroller (rc),deployment(deploy), replicaset (rs)
kubectl describe #顯示特定資源或資源組的詳細信息
kubectl scale #可以對Deployment, ReplicaSet, Replication Controller, 或者StatefulSet設置新的值,可以指定一個或多個先決條件
kubectl set #更改現有的應用程序資源
kubectl rollout #資源回滾管理

創建資源的方法:資源清單

APIserver僅接受JSON格式的資源定義;
Yaml格式提供配置清單,apiserver可以無損、自動的將其轉爲json格式,而後再提交;

  1. 什麼是資源清單
    在k8s中,一般使用yaml格式的文件來創建符合我們預期期望的pod,這樣的yaml文件我們一般稱爲資源清單
  2. 資源清單的格式
apiVersion: group/apiversion   #如果沒有給定group名稱,那麼默認爲croe,可以使用kubectl api-versions 獲取當前k8s版本上所有的apiVersion版本信息(每個版本可能不同)
kind:       #資源類別
metadata:  #資源元數據
   name
   namespace  #k8s自身的namespace
   lables
   annotations   #主要目的是方便用戶閱讀查找
spec:期望的狀態(disired state)
status:當前狀態,本字段有kubernetes自身維護,用戶不能去定義

大部分資源的配置清單都有五個一級字段組成:
apiVersion :group/version
在終端執行kubectl api-versions 查看一下可以看到這個分好組了已經,分組的好處是,如果一個組做出了改變,其他組不收影響,再者一個組加版本號以後,可以在同一個組並存。
版本號級別:

  1. v1:Pod是最核心資源,它屬於V1,而控制器等其他屬於apps/v1組
  2. Beta(貝塔)屬於公測版本,不是公共廁所。裏邊大部分內容都有測試過,還有極少數內容,還需要測試,待定。還有阿爾法:(內測版本)

kind:資源類別
這個有內建的,也可以自定義,不過要按照一定的書寫格式來寫

metadata: 叫元數據
name,(必須是唯一的),namespace(k8s的和之前提到過的6項隔離的定義是不一樣的),labels:(標籤),annotations(資源註解),每個資源的引用PATH(路徑)/api/GROUP/VERSION/namespaces/NAMESPACE/TYPE/NAME

Spec:disred state(期望的狀態)
最重要,可以嵌套二級或三級字段,不同的類型資源,其spec應該是各不相同的。

Status:當前狀態
本字段由kubernetes集羣維護;用戶不能自定義。

如何編寫yaml,可先查看例子
[root@master ~]# kubectl explain pods //看到Object,就注意會嵌套跟多二級字段
[root@master ~]# kubectl explain pods.metadata //查看某個字段怎麼寫
String是字符串,[ ]括號是列表。Map表示是json格式的,由衆多K\V組成的json格式的數組。
[root@master ~]# kubectl explain pods.spec
其中containers <Object> -required- 有required是比寫字段。

[root@master ~]# kubectl explain pods.spec.containers //查看嵌套字段怎麼寫
Command(自定義)、ENV定義環境變量、ENVFROM從其他地方獲取環境變量、imagePullicy(鏡像獲取策略)

編寫一個yaml文件

[root@master ~]# mkdir /usr/local/k8s/yaml_conf/ -p
[root@master ~]# cd /usr/local/k8s/yaml_conf/
[root@master yaml_conf]# vim nginx.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: web_server
    spec:
      containers:
      - name: nginx
        image: nginx

[root@master yaml_conf]# kubectl apply -f nginx.yaml
deployment.extensions/nginx-deployment created

部署成功。同樣地,通過 kubectl get 查看 nginx-deployment 的各種資源:
[root@master yaml_conf]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 6m42s

[root@master yaml_conf]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-855b6b9dc8-flq48 1/1 Running 0 6m56s 10.244.1.11 node01 <none> <none>
nginx-deployment-855b6b9dc8-wjx5m 1/1 Running 0 6m56s 10.244.2.10 node02 <none> <none>

Deployment、ReplicaSet、Pod 都已經就緒。如果要刪除這些資源,執行 kubectl delete deployment nginx-deployment 或者 kubectl delete -f nginx.yml。
[root@master yaml_conf]# kubectl delete -f nginx.yaml
deployment.extensions “nginx-deployment” deleted

資源屬性定義的兩種方式:基於命令的方式、基於配置文件的方式
資源的屬性寫在配置文件中,文件格式爲 YAML。
下面對這兩種方式進行比較。

  • 基於命令的方式:
    簡單直觀快捷,上手快。
    適合臨時測試或實驗。
  • 基於配置文件的方式:
    配置文件描述了 What,即應用最終要達到的狀態。
    配置文件提供了創建資源的模板,能夠重複部署。
    可以像管理代碼一樣管理部署。
    適合正式的、跨環境的、規模化部署。
    這種方式要求熟悉配置文件的語法,有一定難度。
    後面我們都將採用配置文件的方式,大家需要儘快熟悉和掌握。

kubectl apply 不但能夠創建 Kubernetes 資源,也能對資源進行更新,非常方便。不過 Kubernets 還提供了幾個類似的命令,例如 kubectl create、kubectl replace、kubectl edit 和 kubectl patch。
爲避免造成不必要的困擾,我們會盡量只使用 kubectl apply,此命令已經能夠應對超過 90% 的場景,事半功倍。
接下來修改配置文件,將副本數減少爲 3 個,重新執行 kubectl apply:

詳解 Deployment 的配置文件格式

如何讀懂 Deployment YAML 文件?
既然要用 YAML 配置文件部署應用,現在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常類似。
還是以 nginx-deployment 爲例,配置文件如下圖所示:
在這裏插入圖片描述
① apiVersion 是當前配置格式的版本。
② kind 是要創建的資源類型,這裏是 Deployment。
③ metadata 是該資源的元數據,name 是必需的元數據項。
④ spec 部分是該 Deployment 的規格說明。
⑤ replicas 指明副本數量,默認爲 1。
⑥ template 定義 Pod 的模板,這是配置文件的重要部分。
⑦ metadata 定義 Pod 的元數據,至少要定義一個 label。label 的 key 和 value 可以任意指定。
⑧ spec 描述 Pod 的規格,此部分定義 Pod 中每一個容器的屬性,name 和 image是必需的。
上面的nginx.yml 是一個最簡單的 Deployment 配置文件,後面我們學習 Kubernetes 各項功能時會逐步豐富這個文件。

如何Scal Up Down Deployment

伸縮是指在線增加或減少 Pod 的副本數。
Deployment nginx-deployment 初始是兩個副本,k8s-node1 和 k8s-node2 上各跑了一個副本。現在修改 nginx.yml,將副本改成 5 個。
[root@master yaml_conf]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-855b6b9dc8-dhb7v 1/1 Running 0 4m23s 10.244.2.3 node02 <none> <none>
nginx-deployment-855b6b9dc8-jnsk9 1/1 Running 0 4m23s 10.244.1.3 node01 <none> <none>

在這裏插入圖片描述
[root@master yaml_conf]# kubectl apply -f nginx.yaml
deployment.extensions/nginx-deployment configured

[root@master yaml_conf]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-855b6b9dc8-5sr95 1/1 Running 0 5s 10.244.2.4 node02 <none> <none>
nginx-deployment-855b6b9dc8-cl4fd 1/1 Running 0 5s 10.244.1.4 node01 <none> <none>
nginx-deployment-855b6b9dc8-dhb7v 1/1 Running 0 19m 10.244.2.3 node02 <none> <none>
nginx-deployment-855b6b9dc8-jnsk9 1/1 Running 0 19m 10.244.1.3 node01 <none> <none>
nginx-deployment-855b6b9dc8-jp8ws 1/1 Running 0 5s 10.244.1.5 node01 <none> <none>

在master上運行pod
出於安全考慮,默認配置下 Kubernetes 不會將 Pod 調度到 Master 節點。如果希望將 k8s-master 也當作 Node 使用,可以執行如下命令:

kubectl taint node master node-role.kubernetes.io/master-
#node後面的master爲節點名稱(主機名)
如果要恢復 Master Only 狀態,執行如下命令:
kubectl taint node master node-role.kubernetes.io/master="":NoSchedule
接下來修改配置文件,將副本數減少爲 3 個,重新執行 kubectl apply:在這裏插入圖片描述可以看到兩個副本被刪除,最終保留了 3 個副本。

k8s 的 Failover(失效備援)

接上節,現在模擬 k8s-node2 故障,關閉該節點。
[root@node02 ~]# halt -h
PolicyKit daemon disconnected from the bus.
We are no longer a registered authentication agent.
Connection to 192.168.83.5 closed by remote host.
Connection to 192.168.83.5 closed.

[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 8d v1.14.1
node01 Ready <none> 8d v1.14.1
node02 NotReady <none> 8d v1.14.1

[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-855b6b9dc8-59qtv 1/1 Running 0 21m 10.244.1.2 node01 <none> <none>
nginx-deployment-855b6b9dc8-6p6tt 1/1 Running 0 3m38s 10.244.1.5 node01 <none> <none>
nginx-deployment-855b6b9dc8-d7t6h 1/1 Terminating 0 21m 10.244.2.2 node02 <none> <none>
nginx-deployment-855b6b9dc8-fx6tx 1/1 Running 0 13m 10.244.1.3 node01 <none> <none>
nginx-deployment-855b6b9dc8-h65gm 1/1 Terminating 0 13m 10.244.2.3 node02 <none> <none>
nginx-deployment-855b6b9dc8-m7gp7 1/1 Running 0 3m38s 10.244.1.4 node01 <none> <none>

當 k8s-node2 恢復後,Unknown 的 Pod 會被刪除,不過已經運行的 Pod 不會重新調度回 k8s-node2。

[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-855b6b9dc8-59qtv 1/1 Running 0 26m 10.244.1.2 node01 <none> <none>
nginx-deployment-855b6b9dc8-6p6tt 1/1 Running 0 9m6s 10.244.1.5 node01 <none> <none>
nginx-deployment-855b6b9dc8-fx6tx 1/1 Running 0 19m 10.244.1.3 node01 <none> <none>
nginx-deployment-855b6b9dc8-m7gp7 1/1 Running 0 9m6s 10.244.1.4 node01 <none> <none>

用 label 控制 Pod 的位置

默認配置下,Scheduler 會將 Pod 調度到所有可用的 Node。不過有些情況我們希望將 Pod 部署到指定的 Node,比如將有大量磁盤 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 需要 GPU,需要運行在配置了 GPU 的節點上。
Kubernetes 是通過 label 來實現這個功能的。
label 是 key-value 對,各種資源都可以設置 label,靈活添加各種自定義屬性。比如執行如下命令標註 k8s-node1 是配置了 SSD 的節點。
kubectl label node node01 disktype=ssd
然後通過 kubectl get node --show-labels 查看節點的 label。
在這裏插入圖片描述
disktype=ssd 已經成功添加到 k8s-node1,除了 disktype,Node 還有幾個 Kubernetes 自己維護的 label。
有了 disktype 這個自定義 label,接下來就可以指定將 Pod 部署到 k8s-node1。編輯 nginx.yml:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 6
  template:
    metadata:
      labels:
        app: web_server
    spec:
      containers:
      - name: nginx
        image: nginx
      nodeSelector:
        disktype: ssd

在這裏插入圖片描述
全部 6 個副本都運行在 k8s-node1 上,符合我們的預期。
要刪除 label disktype,執行如下命令:
kubectl label node node01 disktype-
在這裏插入圖片描述
不過此時 Pod 並不會重新部署,依然在 k8s-node1 上運行。
在這裏插入圖片描述
除非在 nginx.yml 中刪除 nodeSelector 設置,然後通過 kubectl apply 重新部署。
Kubernetes 會刪除之前的 Pod 並調度和運行新的 Pod。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章