本系列記錄了筆者剛剛接觸并學習 Kubernetes 時動手做過的一些練習,這裡分享出自己的 Kubernetes 學習曆程,希望對廣大 Kubernetes 初學者有所幫助。
練習1 - 如何在 Kubernetes 裡建立一個 Nginx 應用
使用指令行 kubectl run --image=nginx nginx-app --port=80 建立一個名為 nginx-app 的應用
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SM5UzN2EWYmZGO2ITYklDNyYzXyIjMzEDM0AzLcRDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
結果: deployment.apps/nginx-app created
使用指令行
kubectl get pods
檢視建立結果,狀态已經為
running
:
使用指令行
kubectl describe pods
檢視 pod 明細:
把 pod id 記下來: nginx-app-f75d46bd9-q6c76
使用該 pod id 可以執行一些指令:
- kubectl exec nginx-app-f75d46bd9-q6c76 ps aux
- kubectl describe pod nginx-app-f75d46bd9-q6c76
- kubectl logs nginx-app-f75d46bd9-q6c76
練習2 - 如何在 Kubernetes 裡建立一個 Nginx Service
前一個練習,我們已經使用
kubectl
指令行建立了 Pod,但是在 kubernetes 中,Pod 的 IP 位址會随着 Pod 的重新開機而變化,是以用 Pod 的 IP 位址來通路我們部署的 nginx 應用不太合适。
Kubernetes 裡推薦的方式是用 Service 來消費 nginx 服務。
Service 為一組 Pod 提供一個統一的入口,并為它們提供負載均衡和服務發現支援。
使用如下指令行基于 pod 建立一個 service:
kubectl expose deployment nginx-app --type=NodePort --port=80
收到 service/nginx-app exposed 消息。
使用指令行拿到建立成功的 service 的明細:
kubectl describe service nginx-app
使用
http://<node_id>:32624
通路這個 nginx 應用:
看到上圖說明通路 nginx 成功了。
使用指令行檢視 nginx 通路日志:
kubectl logs nginx-app-f75d46bd9-q6c76
練習3 - Kubenetes 裡 Pod 和 Service 綁定的實作方式
前一個練習,我們介紹了如何建立一個 Kubernetes pod 和 service,使用的方法是指令
kubectl run
.
本文介紹另一種方式,通過這種方式來學習 Kubernetes 裡 pod 和對應的 service 是如何綁定的。
首先使用下面的指令行建立一個名稱為 jerry-nginx-1982 的 deployment:
kubectl create deployment jerry-nginx-1982 --image=nginx
然後使用指令行
kubectl get deployment
得到建立好的 deployment:
然後建立一個同名的 service,類型為 nodeport.
kubectl create service nodeport jerry-nginx-1982 --tcp 80:80
建立完成後,使用指令行 kubectl get svc 得到名稱為 jerry-nginx-1982 對外暴露的端口号:31954:
然後就能通過這個端口号通路nginx server了:
那麼這兩個同名的 pod 和 service 是如何關聯的呢?
首先打開 kubernetes dashboard,找到之前建立的 pod:
其明細為:jerry-nginx-1982-67cb658cb8-9hl99
再打開同名service:
再打開這個 service 裡的 pod,發現就是我們前面找到的 jerry-nginx-1982-67cb658cb8-9hl99,說明 pod 和 service 是通過名稱關聯的。
我們可以做一個 negative 測試,直接建立一個名為 test 的 service,但不給它預先建立名為 test 的 pod:
kubectl create service nodeport test --tcp 80:80
service 建立成功後,打開這個 service,發現裡面沒有配置設定任何 pod:
這個結果和我們預測的一緻。
練習4 - 使用 Kubernetes 裡的 job 計算圓周率後 2000 位
使用 Kubernetes 裡的 job(作業),我們可以很友善地執行一些比較耗時的操作。
建立一個 job.ymal 檔案:
定義了一個 Kubernetes job,名稱為 pi,類型為 job,容器名稱為 pi,鏡像為 perl,執行的 perl 指令為 print bpi(2000):
這個 ymal 檔案的完整内容:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
name: pi
spec:
containers:
name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
使用指令
kubectl create -f
導入這個 yaml 檔案,建立一個新的 job:
之後在 Kubernetes 的 dashboard 裡能看到這個建立的 job:
job 對應的 pod 狀态為 Waiting ContainerCreating:
稍後,其狀态從 Running 變為了 Terminated:Completed,總共花了 14 分鐘。
在 pod 的事件日志裡,能看到大部分時間花在了 perl 鏡像的下載下傳上:
點選 dashboard 的 logs 按鈕,就能看到這個 2000 位圓周率的計算結果:
練習5 - Kubernetes 裡的 ConfigMap 的用途
顧名思義,ConfigMap 用于儲存配置資料的鍵值對,可以用來儲存單個屬性,也可以用來儲存配置檔案。
ConfigMap 同 Kubernetes 的另一個概念 secret 類似,差別是 ConfigMap 主要用于儲存不包含敏感資訊的明文字元串。
建立方式:
kubectl create configmap special-config --from-literal=i042416=jerry
上述指令行建立了一個名為
special-config
的鍵值對,
key為 i042416, 值為 jerry
接下來我希望用這個 key 為 i042416 的值"jerry"來定義成 pod 裡的一個環境變量。
下面是我的 yaml 檔案:
apiVersion: v1
2 kind: Pod
3 metadata:
4 name: jerry-config-pod
5 spec:
6 containers:
7 - name: test-container
8 image: http://gcr.io/google_containers/busybox
9 command: [ "/bin/sh", "-c", "env" ]
10 env:
11 - name: JERRY_NAME
12 valueFrom:
13 configMapKeyRef:
14 name: special-config
15 key: i042416
16 restartPolicy: Never
可以看到第 15 行引用了我的 ConfigMap 的 key:i042416
下面使用
create -f
将該 yaml 檔案導入,建立一個新的 pod:
建立之後,能在 pod 的明細頁面看到 configMap 的 key 已經作為環境變量顯示出來了:
因為我 yaml 檔案裡指定 pod 執行的 script 為 /bin/sh -c env, 是以最後會将容器裡所有的環境變量都列印出來,我們定義在 ConfigMap 裡的 i042416 的值 jerry 也被顯示了出來:
這種定義環境變量的做法和 SAP 雲平台 CloudFoundry 環境裡定義環境變量的方式很類似。
CloudFoundry環境變量一覽表:
https://docs.run.pivotal.io/devguide/deploy-apps/environment-variable.html
- CF_INSTANCE_ADDR
- CF_INSTANCE_GUID
- CF_INSTANCE_INDEX
- CF_INSTANCE_IP
- CF_INSTANCE_INTERNAL_IP
- CF_INSTANCE_PORT
- CF_INSTANCE_PORTS
- DATABASE_URL
- HOME
- LANG
- MEMORY_LIMIT
- PORT
- PWD
- TMPDIR
- USER
- VCAP_APP_PORT
- VCAP_APPLICATION
- VCAP_SERVICES
當使用 cf push 指令将本地應用部署到 SAP 雲平台的 CloudFoundry 環境下時,某些環境變量會自動被系統寫入相應的值,這個行為同 ABAP 的 sy-sysid 自動被設定為目前系統 ID 具有一樣的邏輯。
比如 app router 會把使用者通路請求重定向到 XSUAA 執行個體上。
app router 在 manifest.yml 裡定義的 XSUAA 執行個體名稱為 xsuaa-jerry-demo,
在運作時這個 XSUAA 的 id 會被 SAP 雲平台自動寫入環境變量 VCAP_SERVICES 裡:
總結
本文介紹了每一個 Kubernetes 從業者的實際工作中幾乎都會使用的步驟:建立 Deployment 和 Service,同時通過實際例子講解了 Pod 和 Service 綁定的實作方式,介紹了使用 Kubernetes Job 計算圓周率這種費時的操作,希望對 Kubernetes 初學者能有所幫助。