內容摘要
Pod標籤
Pod標籤選擇器
標籤是K8S系統對資源的一種描述,可以有效的分類資源。在現在的應用中,一個應用往往可以包含多個服務,有的服務功能基本一致,那麼如何區分這些服務呢?使用標籤就可以做到。比如系統中如果有兩個tomcat服務,我們可以使用不同標籤區分它們。本章主要講解標籤以及常用操作,最後還會講解如何使用標籤實現Pod調度到相關節點。
創建帶標籤的Pod
首先構建容器鏡像,步驟如下:
1、創建Dockerfile
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
2、創建app.js
const http = require('http');
const os = require('os');
console.log("server starting...");
var handler = function(request, response) {
console.log("server Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("server You've hit " + os.hostname() + "\\n");
};
var www = http.createServer(handler);
www.listen(8080);
3、構建鏡像
構建鏡像,名稱為app1,並推送到倉庫,方法可以參考上一節的內容。
4、創建Pod
配置如下:
apiVersion: v1
kind: Pod
metadata:
name: apppod1
labels:
app: myapp1
rel: v1.0
spec:
containers:
- image: huqianakls/app1:latest
name: appcon1
ports:
- containerPort: 8080
protocol: TCP
在metadata下使用labels指定該Pod的標籤,app標籤表示名稱,rel是版本信息。
Pod創建成功後,查詢該Pod詳細信息,內容如下:
可以看到我們創建Pod時,設置的標籤。
在查詢時,可以使用 --show-labels 參數顯示標籤,截圖如下:
也可以使用 -L 參數,將標籤顯示為列,截圖如下:
常用操作
增加標籤
命令為:
kubectl label pod Pod名稱 標籤鍵值對
注意:如果該Pod已經存在該標籤時,增加失敗。
操作截圖如下:
上面操作中,第1次試圖增加app標籤,由於該標籤失敗,所以操作失敗。
修改標籤
命令為:
kubectl label pod Pod名稱 標籤鍵值對 --overwrite
比如,將上面的標籤app改為app1,操作截圖如下:
根據標籤查詢Pod
為了測試,創建1個新Pod,配置內容為:
apiVersion: v1
kind: Pod
metadata:
name: apppod2
labels:
app: myapp2
rel: v2.0
spec:
containers:
- image: huqianakls/app1:latest
name: appcon2
ports:
- containerPort: 8080
protocol: TCP
下面我來測試下查詢Pod:
1、查詢標籤app值為myapp2的Pod
命令為:
kubectl get pod -l app=myapp2
2、查詢帶有rel標籤的Pod
命令為:
kubectl get pod -l rel
3、查詢沒有帶rel標籤的Pod
為了測試創建下面Pod,配置如下:
apiVersion: v1
kind: Pod
metadata:
name: apppod3
labels:
app: myapp3
spec:
containers:
- image: huqianakls/app1:latest
name: appcon3
ports:
- containerPort: 8080
protocol: TCP
該Pod沒有rel標籤,只有app標籤。
下面我們查詢沒有帶rel標籤的Pod,命令為:
kubectl get pod -l '!rel'
只有apppod3,其他兩個Pod沒有查詢到,因為它們沒有rel標籤。
注意上面的查詢參數是一個表達式,!表示否定,表達式要使用單引號包圍。
4、查詢標籤app為app1的Pod
命令為:
kubectl get pod -l 'app=app1'
5、查詢標籤app值為app1或myapp3的Pod
命令為:
kubectl get pod -l 'app in (app1, myapp3)'
6、查詢標籤app值不為為app1或myapp3的Pod
命令為:
kubectl get pod -l 'app notin (app1, myapp3)'
7、查詢不帶desc以及rel標籤的Pod
命令為:
kubectl get pod -l '!desc,!rel'
注意這裡使用逗號將多個表達式連起來,逗號表示邏輯“與”的關係。
刪除標籤
命令為:
kubectl label pod apppod3 app-
注意:在標籤後面使用短橫,即可刪除標籤。
標籤選擇器
標籤不僅可以用來分類Pod等K8S資源,也可以用來做調度業務,關於調度這裡不深究,下面我們做個實驗將Pod調度到K8S集群中的某個特定節點。
為了測試,我們需要增加一個節點做測試,請參考前面章節的K8S安裝指南,創建2節點K8S集群。
在控制節點上查詢工作節點添加命令,結果為:
kubeadm token create --print-join-command --ttl 0
在工作節點執行上述命令,運行結果如下圖:
在控制節點查詢集群節點信息,結果如下:
前面我們給Pod資源打了標籤,下面我們給節點資源也打上標籤,我們選擇worker1,命令如下:
kubectl label node worker1 ssd=true
給節點worker1增加標籤ssd=true,這表示該節點使用ssd硬盤。這裡可以看出標籤的用法,對於工作節點,我們可以使用標籤來標記該節點的特性,比如硬盤,CPU,內存,是否帶有GPU等。
查詢節點信息,以及標籤,結果如下:
可以看到,在LABELS列下,不僅有自己設置的標籤,也有系統自帶的。
下面我們創建Pod,使該Pod調度到worker1節點,Pod配置如下:
apiVersion: v1
kind: Pod
metadata:
name: apppod4
labels:
app: myapp4
spec:
nodeSelector:
ssd: "true"
containers:
- image: huqianakls/app1:latest
name: appcon4
ports:
- containerPort: 8080
protocol: TCP
注意:我們使用了nodeSelector屬性,下面使用了ssd=true標籤,該標籤將會使該Pod被調度到含有該標籤的節點上。
創建該Pod,查詢結果如下:
可以看到NODE列,該列顯示Pod的節點信息。剛才創建的Pod沒有在master上,而是調度到worker1節點上。
問題:如果系統中沒有節點帶有ssd=true標籤,那麼Pod會創建成功嗎?
下面我們測試下,首先刪除worker1節點的標籤,命令如下:
kubectl label node worker1 ssd-
刪除apppod4,重新創建Pod,結果如下:
該Pod一致處於Pending狀態,查詢詳情,可以看到事件信息,結果如下:
從最後的Events可以看出,沒有節點能夠匹配nodeSelector屬性,Pod的狀態一致處於Pending。
實驗
1、創建帶有標籤的Pod;
2、測試標籤的常用操作;
3、使用nodeSelector屬性調度Pod到指定節點;
閱讀更多 HandFirstDocker 的文章