Kubernetes 系列第二篇: 使用 kubectl 命令創建 Kubernetes 應用

1. 簡介

k8s 的 API Server 提供了 RESTful 風格的網關接口, 允許用戶通過這個接口向 k8s 集羣發起請求。如創建一個 Pod 或銷燬一個 Pod 等操作
用戶可以通過編程語言遵循 API Server 提供的網關接口規範和 API Server 進行通信, 也可以通過 k8s 自帶的 kubectl 命令和 API Server 進行通信, 或者通過由 Dashboard 提供的 Web UI 和 API Server 進行通信
其中 kubectl 是官方提供的用於和 API Server 通信的 CLI 工具, 且是最爲常用的交互式命令行工具

2. kubectl

2.1. 查看命令幫助

# 查看 kubectl 命令幫助
[root@master ~]# kubectl --help
# 基礎命令(適合初學者使用)
Basic Commands (Beginner):
  create         創建資源, k8s 支持從 yaml 文件或者命令行參數直接創建資源
  expose         暴露服務
  run            運行 Pod 
  set            設置對象屬性

# 基礎命令
Basic Commands (Intermediate):
  explain        
  get            獲取資源信息
  edit           編輯資源
  delete         刪除資源

# 部署命令
Deploy Commands:
  rollout        更新管理
  scale          手動管理副本
  autoscale      自動管理副本

# 集羣管理命令
Cluster Management Commands:
  certificate    證書管理
  cluster-info   查看集羣信息
  top            顯示資源(CPU/內存/存儲)使用情況
  cordon         將指定 node 設定爲"不可用"(unschedulable)狀態
  uncordon       將指定 node 設定爲"可用"(schedulable)狀態
  drain          排空節點
  taint          爲 node 聲明污點及標準行爲

# 故障排除和調試命令
Troubleshooting and Debugging Commands:
  describe       顯示特定資源或資源組的詳細信息
  logs           打印 Pod 中的容器日誌
  attach         連接到正在運行的容器
  exec           在容器中執行命令
  port-forward   將一個或多個本地端口轉發到 Pod 中
  proxy          運行 k8s API Server 代理
  cp             跨容器之間複製文件或目錄
  auth           檢查授權

# 高級命令
Advanced Commands:
  apply          基於文件或 stdin 將配置應用於資源
  patch          使用策略合併補丁更新資源字段
  replace        基於文件或 stdin 替換一個資源
  wait           目前處於測試階段, 在一個或多個資源上等待一個條件
  convert        爲不同的 API 版本轉換配置文件

# 資源設置
Settings Commands:
  label          更新資源上的標籤(label)
  annotate       更新資源的a nnotation
  completion     輸出指定的 shell 的補全碼

# 其他命令
Other Commands:
  alpha          Commands for features in alpha
  api-resources  在服務器上打印支持的 API 資源
  api-versions   以 "group/version" 格式打印服務器支持的 API 版本信息
  config         修改 kubeconfig 文件
  plugin         運行命令行插件
  version        查看 k8s 版本

# 使用格式
Usage:
  kubectl [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

2.2. 使用 kubectl 運行一個 Pod

# 運行一個由 deployment 管理器管理的 pod
[root@master ~]# kubectl run nginx --image=nginx:1.14-alpine --replicas=5
deployment.apps/nginx created

# 查看 pod
[root@master ~]# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP           NODE
nginx-65759d8bcb-96kgd   1/1       Running   0          7s       10.244.3.6   node02
nginx-65759d8bcb-97dch   1/1       Running   0          7s       10.244.1.5   node01
nginx-65759d8bcb-mzzwh   1/1       Running   0          8s       10.244.1.4   node01
nginx-65759d8bcb-vxs74   1/1       Running   0          8s       10.244.3.5   node02
nginx-65759d8bcb-z6d4r   1/1       Running   0          8s       10.244.3.4   node02

NAME        Pod 名稱
READY       這個 Pod 內應該運行幾個容器/已經準備好幾個容器
STATUS      運行狀態
RESTARTS    Pod 重啓次數
AGE         已存在多長時間, 單位秒(s)
IP          Pod IP(這個地址只能在集羣內部使用, 且 Pod IP 隨時都會發生改變)
NODE        運行節點

# 查看 deployment 管理器
[root@master ~]# kubectl get deployment
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     5         5         5            5           18s

NAME            deployment 管理器名稱
DESIRED         期望有多少個副本
CURRENT         當前有多少個副本
UP-TO-DATE      處於最新狀態的 Pod 數量
AVAILABLE       活躍的 Pod 數量
AGE             已存在多長時間, 單位秒(s)

# 在集羣內部訪問 Pod
[root@master ~]# curl 10.244.1.5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.3. 使用 service 暴露服務

Pod 的客戶端主要分爲兩類, 集羣外客戶端集羣內客戶端。集羣內客戶可以直接通過 Pod IP 訪問 Pod 而集羣外部客戶端則不能通過 Pod IP 訪問, 且 Pod IP 隨時有可能會發生改變所有即便只是在集羣內部訪問我們也不應該直接使用 Pod IP 進行訪問
而 service 主要就是爲了解決這兩個問題而存在的, 通過創建 service 給與 service 一個固定的訪問接口並且將相關的 Pod 綁定到這個 service 中, 當訪問 service 是自動將客戶端瀏覽分發到後端的 Pod 中
如果 k8s 安裝了 CoreDNS 則可以通過 CoreDNS 爲所有 Pod 都分配一個 DNS, 如果 service 發生改變 CoreDNS 也會更新其內部的解析記錄, 以保證 DNS 解析記錄的有效性

# 創建 service
[root@master ~]# kubectl expose deployment nginx --name=nginx-service --port=80 --target-port=80 --protocol=TCP --type=ClusterIP
service/nginx-service exposed

kubectl expose          創建 service 關鍵字
deployment nginx        綁定的 Pod 管理器(將會暴露此 Pod 管理器所管理的所有 Pod)
--name                  指定 service 的名稱
--port                  暴露的端口
--target-port           目標端口
--protocol              暴露的協議(默認爲 TCP)
--type                  service 類型, ClusterIP 爲集羣 IP, 此類型的 service 在集羣外部也不能被訪問

# 查看已存在的 service
[root@master ~]# kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   6d
nginx-service   ClusterIP   10.107.73.166   <none>        80/TCP    33s

# 查看 service 的詳細信息
[root@master ~]# kubectl describe service nginx-service
Name:              nginx-service
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
# 關聯標籤 run 且 run 爲 nginx 的所有 pod(通過此項完成 pod 和 service 的綁定)
Selector:          run=nginx
Type:              ClusterIP
IP:                10.107.73.166
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.1.5:80,10.244.3.4:80 + 2 more...
Session Affinity:  None
Events:            <none>

# 顯示各 pod 的 label
[root@master ~]# kubectl get pod --show-labels      
NAME                     READY     STATUS    RESTARTS   AGE       LABELS
client                   1/1       Running   0          54m       run=client
nginx-65759d8bcb-96kgd   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-97dch   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-mzzwh   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-vxs74   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-z6d4r   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx

# 使用 service ip 訪問 Pod
[root@master ~]# curl 10.107.73.166
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.4. 使用 DNS 名稱訪問 Pod

# 查看 kube-dns(真實使用的爲 CoreDNS) 的 service 地址
[root@master ~]# kubectl get service -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP   7d

[root@master ~]# kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   7d
nginx-service   ClusterIP   10.107.73.166   <none>        80/TCP    46m

# 使用 CoreDNS 解析主機名, nginx-service 爲 service 名稱, default.svc.cluster.local 爲 DNS 後綴
[root@master ~]# dig -t A nginx-service.default.svc.cluster.local @10.96.0.10
......
# 解析結果
nginx-service.default.svc.cluster.local. 5 IN A 10.107.73.166

;; Query time: 7 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Thu Feb 28 16:36:29 CST 2019
;; MSG SIZE  rcvd: 123

# 建立一個客戶端 Pod
[root@master ~]# kubectl run client --image=busybox -it --restart=Never

# 在 Pod 內部使用 service 名稱訪問
/ # wget -O - -q nginx-service
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.5. 動態修改 pod 副本數量

# 將副本數量修改爲 2
[root@master ~]# kubectl scale --replicas=2 deployment nginx
deployment.extensions/nginx scaled

# 查看 nginx 控制器的詳細信息
[root@master ~]# kubectl describe deployment nginx
Name:                   nginx
Namespace:              default
CreationTimestamp:      Thu, 28 Feb 2019 12:05:59 +0800
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision=1
Selector:               run=nginx
# 副本詳細信息
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-65759d8bcb (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  1m    deployment-controller  Scaled down replica set nginx-65759d8bcb to 2

2.6. 更新

# 查看當前 Pod 的詳細信息
[root@master ~]# kubectl describe pod nginx-65759d8bcb-97dch
Name:               nginx-65759d8bcb-97dch
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node01/192.168.1.51
Start Time:         Thu, 28 Feb 2019 12:06:00 +0800
Labels:             pod-template-hash=2131584676
                    run=nginx
Annotations:        <none>
Status:             Running
IP:                 10.244.1.5
Controlled By:      ReplicaSet/nginx-65759d8bcb
# pod 內運行的容器
Containers:
  # 容器名稱
  nginx:
    Container ID:   docker://2a97be8c74ac715569b4cbd542cb1df0b52f49cd1ee89f1d7bdf15464678d274
    # 容器鏡像
    Image:          nginx:1.14-alpine
    Image ID:       docker-pullable://nginx@sha256:b96aeeb1687703c49096f4969358d44f8520b671da94848309a3ba5be5b4c632
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 28 Feb 2019 12:06:01 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-t9pnn (ro)
# pod 內運行的第二個容器, 這兒只有一個容器
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-t9pnn:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-t9pnn
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>

# 更新鏡像版本
[root@master ~]# kubectl set image deployment nginx nginx=nginx:alpine
deployment.extensions/nginx image updated

kubectl set image       更新進行關鍵字
deployment nginx        nginx deployment 控制器
nginx                   pod 內的容器名稱(更新時只能指定更新容器)
nginx:alpine            鏡像版本

# 查看更新過程
[root@master ~]# kubectl rollout status deployment nginx
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out

# 查看更新完成後的 pod
[root@master ~]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
client                   1/1       Running   0          1h
nginx-5557945897-87st5   1/1       Running   0          1m
nginx-5557945897-zgggq   1/1       Running   0          1m

# 查看 pod 詳細信息
[root@master ~]# kubectl describe pod nginx-5557945897-87st5
Name:               nginx-5557945897-87st5
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node02/192.168.1.52
Start Time:         Thu, 28 Feb 2019 17:52:21 +0800
Labels:             pod-template-hash=1113501453
                    run=nginx
Annotations:        <none>
Status:             Running
IP:                 10.244.3.8
Controlled By:      ReplicaSet/nginx-5557945897
Containers:
  nginx:
    Container ID:   docker://fcb8166d53a6c2c6392bc14f80cd9161caf13e3e26cad433ed0d9da133b41c6b
    Image:          nginx:alpine
    Image ID:       docker-pullable://nginx@sha256:0f7920c93d6b60f3e13c1b847f1863f423c3149d06e53475e64560933d168adc
    ......

2.7. 回滾

# 回滾到指定版本, 默認回滾到上一個版本
[root@master ~]# kubectl rollout undo deployment nginx
deployment.extensions/nginx

kubectl rollout undo    關鍵字
deployment nginx        控制器
--to-revision           指定回滾到那個版本

[root@master ~]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
client                   1/1       Running   0          1h
nginx-65759d8bcb-gm4sj   1/1       Running   0          1m
nginx-65759d8bcb-n2222   1/1       Running   0          1m

# 查看回滾後的 pod 信息
[root@master ~]# kubectl describe deployment nginx nginx-65759d8bcb-gm4sj
Name:                   nginx
Namespace:              default
CreationTimestamp:      Thu, 28 Feb 2019 12:05:59 +0800
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision=5
Selector:               run=nginx
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>

2.8. 將服務發佈到集羣外部

# 新創建一個 service, service 的 NodePort 模式允許外部流量訪問 k8s 集羣
[root@master ~]# kubectl expose deployment nginx --name=nginx-service-internet --port=80 --type=NodePort
service/nginx-service-internet exposed

# 在外部訪問 k8s 任意節點的 32081 即可訪問 nginx pod
[root@master ~]# kubectl get service
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP        7d
nginx-service            ClusterIP   10.107.73.166    <none>        80/TCP         18h
nginx-service-internet   NodePort    10.107.217.105   <none>        80:32081/TCP   11s

# 或者修改現有 service 的 type 將其發佈到集羣外部
[root@master ~]# kubectl edit service nginx-service
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2019-02-28T07:50:21Z
  labels:
    run: nginx
  name: nginx-service
  namespace: default
  resourceVersion: "474911"
  selfLink: /api/v1/namespaces/default/services/nginx-service
  uid: 7f7ef303-3b2d-11e9-9b82-000c292a04ff
spec:
  clusterIP: 10.107.73.166
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31987
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  sessionAffinity: None
  # 修改爲 NodePort
  type: NodePort
status:
  loadBalancer: {}

# 現在訪問任意節點的 31987 和 32081 都能夠訪問到後端 pod 資源
[root@master ~]# kubectl get service               
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP        7d
nginx-service            NodePort    10.107.73.166    <none>        80:31987/TCP   18h
nginx-service-internet   NodePort    10.107.217.105   <none>        80:32081/TCP   3m
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章