1. 程式人生 > 實用技巧 >k8s 基本使用(下)

k8s 基本使用(下)

如果你沒有看過上篇的話,推薦閱讀完 k8s 基本使用(上)後再閱讀本篇內容。

kubectl create 建立資源!

k8s 中的所有東西都可以通過kubectl create命令建立,無論你是想建立一個 pod 還是一個大型的滾動升級服務deploymentcreate命令都可以做到。使用create生成一個資源主要有兩種常用方法,yaml配置檔案建立簡易建立

yaml配置檔案建立

如果你想讓 k8s 生成一個和你想象中一模一樣的資源,那你就要充分而詳細的描述這個資源,k8s 就提供了這麼一個方法,你可以使用yaml格式建立一個檔案,按照 k8s 指定好的結構定義一個物件,然後使用如下方法將該檔案傳遞給 k8s。它就可以按照你的描述進行生成了:

kubectl create -f <配置檔名.yaml>

例如,使用下面的配置檔案就可以建立一個最簡單的 pod:

kubia-manual.yaml

apiVersion: v1
kind: Pod
metadata:
  name: kubia-manual
spec:
  containers:
  - image: luksa/kubia
    name: kubia
    ports:
    - containerPort: 8080
      protocol: TCP

然後使用kubectl create -f kubia-manual.yaml即可建立

root@master1:~/k8s-yaml# k create -f kubia-manual.yaml 
pod/kubia-manual created

如果你的配置檔案有問題的話那麼 k8s 就會報錯,如下,錯誤一般都是拼寫導致的,比如下面這個就是Pod.spec.containers[0].ports[0]中存在一個無法識別的名稱contaienrPort

root@master1:~/k8s-yaml# k create -f kubia-manual.yaml 
error: error validating "kubia-manual.yaml": 
error validating data: [ValidationError(Pod.spec.containers[0].ports[0]): unknown field "contaienrPort" in io.k8s.api.core.v1.ContainerPort, 
ValidationError(Pod.spec.containers[0].ports[0]): missing required field "containerPort" in io.k8s.api.core.v1.ContainerPort]; 
if you choose to ignore these errors, turn validation off with --validate=false

這時你可能會問了,這配置檔案裡一大堆名字我看不懂啊,不要著急,下一條命令就會解答這個疑惑,但是在此之前,我們先來看一下更簡單的 簡易建立 模式。

簡易建立

k8s 為一些常用的資源提供了簡易建立的方法,比如說servicenamespacedeployment等,這些方法可以使用kubectl create <資源型別> <資源名>的方式建立。例如我想建立一個名叫hello-world的名稱空間,直接使用下面命令即可:

kubectl create namespace hello-world

這樣就不用再跟大而全的配置檔案打交道了,如果你想了解都有哪些資源可以快速生成的話,使用kubectl create -h命令檢視。

小結

kubectl create可以通過指定-f <配置檔名.yaml>引數來從一個yaml檔案生成資源,也可用使用kubectl create <資源型別> <資源名>來快速生成一個資源。

kubectl explain 解釋配置!

從上一小節中我們可以知道,k8s 可以通過配置檔案來生成資源,而為了儘可能詳細的描述資源的模樣,k8s 提供了數量龐大的配置項,那麼有沒有一種方式可以快速的瞭解到某個配置項的作用呢?有,那就是explain(解釋)命令。

kubectl explain <配置名>

咱們來實踐一下,翻到上一小節裡提到的生成 pod 的配置檔案。首先,我想要了解建立 pod 的哪些基本屬性都是幹什麼的,輸入kubectl explain pod即可:

root@master1:~/k8s-yaml# kubectl explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

   spec <Object>
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

   status       <Object>
     Most recently observed status of the pod. This data may not be up to date.
     Populated by the system. Read-only. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

可以看到,給出的解釋非常詳細,並且每個解釋的最後都附帶了一條連結,便於更加深入的進行了解,好了,那我想要了解matedata(元資料)欄位都有哪些配置項怎麼辦呢?

kubectl explain pod.matedata
root@master1:~/k8s-yaml# kubectl explain pod.metadata
KIND:     Pod
VERSION:  v1

RESOURCE: metadata <Object>

DESCRIPTION:
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

     ObjectMeta is metadata that all persisted resources must have, which
     includes all objects users must create.

FIELDS:
   annotations  <map[string]string>
     Annotations is an unstructured key value map stored with a resource that
     may be set by external tools to store and retrieve arbitrary metadata. They
     are not queryable and should be preserved when modifying objects. More
     info: http://kubernetes.io/docs/user-guide/annotations

   clusterName  <string>
     The name of the cluster which the object belongs to. This is used to
     distinguish resources with same name and namespace in different clusters.
     This field is not set anywhere right now and apiserver is going to ignore
     it if set in create or update request.

    ...

又是一排十分詳細的解釋,通過這種方式,我們可以瞭解到每一個資源的每一個配置項。想了解某個屬性的子屬性,就加個.繼續查。不要說看不懂,我覺得 谷歌翻譯 這種東西已經挺常見了。

kubectl delete 刪除一切!

delete命令的使用非常簡單,如下:

kubectl delete <資源型別> <資源名>

比如說你想刪除一個名為kubia-4n2tg的 pod。就可以這麼寫:

kubectl delete pod kubia-4n2tg

如果你想刪除所有的 pod,就可以這麼寫:

kubectl delete pod --all

如果你想刪除一切!那就這麼寫:

kubectl delete all --all

注意!執行刪除一切命令沒有二次驗證,所有資源均會被直接刪除,在執行前先考慮下跑路成本。

kubectl edit 修改配置!

如果在日常維護過程中,因為某些原因我們需要變更一些服務的設定該怎麼辦呢?從建立新資源小節我們可以瞭解到,每個資源都是通過一個yaml配置檔案生成的,哪怕是簡易建立的資源,也是 k8s 從一個預設的配置檔案建立而來的。

我們可以在get命令後附加-o yaml檔案檢視某個現有資源的配置項。例如,檢視 pod kubia-manual的配置項:

kubectl get pod kubia-manual -o yaml

執行之後就可以看到一個很長的配置列表,你也可以試一下自己建立的 pod 的配置項,你會發現同樣很長,這就是因為 k8s 會讀取你提供的資訊,並將必要但是你沒有提供的其他資訊設為預設值填寫進去。而kubectl edit就可以編輯剛才開啟的這個列表。例如,編輯在create小節中建立的 pod kubia-manual

kubectl edit pod kubia-manual

之後就會彈出系統設定的預設編輯器。這時我們就可以做任意修改,例如將名稱改為kubia-manual-v2。首先定位到metadata.name欄位,然後修改他的值:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2019-07-07T07:31:11Z"
  name: kubia-manual # > kubia-manual-v2
  namespace: default
  resourceVersion: "790349"
  selfLink: /api/v1/namespaces/default/pods/kubia-manual
  uid: 51eaa1e6-5749-4e79-aec9-12cf2a3e485d
spec:
  ...

修改完成後輸入:wq儲存,隨後你會發現, k8s 居然報錯了

A copy of your changes has been stored to "/tmp/kubectl-edit-vj0ts.yaml"
error: At least one of apiVersion, kind and name was changed

不要著急,這個是 k8s 做出的限制,你無法修改一個執行中資源的名稱或型別。那我們就來修改一下他的其他屬性好了。例如將拉取映象的標籤指定為latest。重新edit配置檔案,找到spec。containers.image欄位,然後在最後新增:latest後儲存。隨後 k8s 會彈出儲存成功,如下:

pod/kubia-manual edited

這時我們再kubectl describe pod kubia-manual檢視該 pod 的詳情,就可以發現對應的欄位已經更新了:

Name:         kubia-manual
Namespace:    default
Priority:     0
Node:         worker1/192.168.56.21
Start Time:   Sun, 07 Jul 2019 07:31:11 +0000
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.1.14
Containers:
  kubia:
    Container ID:   docker://89617ffcc9b1455c514e5129a9b2694c43a2aff9b4c0449d5efc4aea1fe41db6
    # 已經顯式的應用了 latest 標籤
    Image:          luksa/kubia:latest
    Image ID:       docker-pullable://luksa/kubia@sha256:3f28e304dc0f63dc30f273a4202096f0fa0d08510bd2ee7e1032ce600616de24
    Port:           8080/TCP

小節

kubectl edit <資源型別> <資源名> 可以編輯一個資源的具體配置項,更詳細的文件請參考 k8s 中文網 - kubectl editedit命令在實際使用中更偏向於人工修改某個配置項來解決問題,例如修改映象地址解決拉取不到映象的問題。更常用的編輯命令請參見下一節kubectl apply

kubectl apply 應用配置!

上一節我們知道了一個簡單快捷的編輯配置方法kubectl edit,但是如果我們想對資源進行大範圍的修改呢?總不能開啟配置項一個一個手動修改吧。這時候就可以用到我們的kubectl apply命令了。基本用法如下:

kubectl apply -f <新配置檔名.yaml>

kubeclt apply可以說是edit命令的升級版,它和edit最大的區別就是,apply接受一個yaml配置檔案,而不是開啟一個編輯器去修改。k8s 在接受到這個配置檔案後,會根據metadata中的元資料來查詢目標資源,如果沒有的話則直接新建,如果找到的話就依次比對配置檔案之間有什麼不同點,然後應用不同的配置

這麼做的好處有很多,例如你通過kubectl apply -f https://some-network-site/resourse.yaml命令從一個網站上部署了你的資源,這樣當它的管理者更新了這個配置檔案後,你只需要再次執行這個命令就可以應用更新後的內容了,而且完全不用關心修改了哪些配置項。

除了修改手段不同以外,apply命令的行為和edit保持一致,你可以訪問 k8s 中文網 - kubectl apply 來檢視更多用法。

總結

本本介紹瞭如何新建create、刪除delete和修改edit, apply k8s 中的資源。閱讀完本文之後,相信你已經對 k8s 不再陌生,並且在學習 k8s 的重頭戲 不同資源的用法和特性 時能起到不小的幫助。接下來你可以通過 k8s 如何讓你的應用活的更久 來了解 k8s 中的重要資源 - 副本控制器ReplicationControllerReplicaSet