K8S動手教程2.3:Pod標籤和選擇器

內容摘要

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詳細信息,內容如下:

K8S動手教程2.3:Pod標籤和選擇器

可以看到我們創建Pod時,設置的標籤。

在查詢時,可以使用 --show-labels 參數顯示標籤,截圖如下:

K8S動手教程2.3:Pod標籤和選擇器

也可以使用 -L 參數,將標籤顯示為列,截圖如下:

K8S動手教程2.3:Pod標籤和選擇器


常用操作

增加標籤

命令為:

kubectl label pod Pod名稱 標籤鍵值對 

注意:如果該Pod已經存在該標籤時,增加失敗。

操作截圖如下:

K8S動手教程2.3:Pod標籤和選擇器

上面操作中,第1次試圖增加app標籤,由於該標籤失敗,所以操作失敗。


修改標籤

命令為:

kubectl label pod Pod名稱 標籤鍵值對 --overwrite

比如,將上面的標籤app改為app1,操作截圖如下:

K8S動手教程2.3:Pod標籤和選擇器


根據標籤查詢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
K8S動手教程2.3:Pod標籤和選擇器

2、查詢帶有rel標籤的Pod

命令為:

kubectl get pod -l rel
K8S動手教程2.3:Pod標籤和選擇器

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'
K8S動手教程2.3:Pod標籤和選擇器

只有apppod3,其他兩個Pod沒有查詢到,因為它們沒有rel標籤。

注意上面的查詢參數是一個表達式,!表示否定,表達式要使用單引號包圍。

4、查詢標籤app為app1的Pod

命令為:

kubectl get pod -l 'app=app1'
K8S動手教程2.3:Pod標籤和選擇器

5、查詢標籤app值為app1或myapp3的Pod

命令為:

kubectl get pod -l 'app in (app1, myapp3)'
K8S動手教程2.3:Pod標籤和選擇器

6、查詢標籤app值不為為app1或myapp3的Pod

命令為:

kubectl get pod -l 'app notin (app1, myapp3)'
K8S動手教程2.3:Pod標籤和選擇器

7、查詢不帶desc以及rel標籤的Pod

命令為:

kubectl get pod -l '!desc,!rel'
K8S動手教程2.3:Pod標籤和選擇器

注意這裡使用逗號將多個表達式連起來,逗號表示邏輯“與”的關係。


刪除標籤

命令為:

kubectl label pod apppod3 app-
K8S動手教程2.3:Pod標籤和選擇器

注意:在標籤後面使用短橫,即可刪除標籤。


標籤選擇器

標籤不僅可以用來分類Pod等K8S資源,也可以用來做調度業務,關於調度這裡不深究,下面我們做個實驗將Pod調度到K8S集群中的某個特定節點。

為了測試,我們需要增加一個節點做測試,請參考前面章節的K8S安裝指南,創建2節點K8S集群。

在控制節點上查詢工作節點添加命令,結果為:

kubeadm token create --print-join-command --ttl 0
K8S動手教程2.3:Pod標籤和選擇器

在工作節點執行上述命令,運行結果如下圖:

K8S動手教程2.3:Pod標籤和選擇器

在控制節點查詢集群節點信息,結果如下:

K8S動手教程2.3:Pod標籤和選擇器

前面我們給Pod資源打了標籤,下面我們給節點資源也打上標籤,我們選擇worker1,命令如下:

kubectl label node worker1 ssd=true

給節點worker1增加標籤ssd=true,這表示該節點使用ssd硬盤。這裡可以看出標籤的用法,對於工作節點,我們可以使用標籤來標記該節點的特性,比如硬盤,CPU,內存,是否帶有GPU等。

查詢節點信息,以及標籤,結果如下:

K8S動手教程2.3:Pod標籤和選擇器

可以看到,在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,查詢結果如下:

K8S動手教程2.3:Pod標籤和選擇器

可以看到NODE列,該列顯示Pod的節點信息。剛才創建的Pod沒有在master上,而是調度到worker1節點上。

問題:如果系統中沒有節點帶有ssd=true標籤,那麼Pod會創建成功嗎?

下面我們測試下,首先刪除worker1節點的標籤,命令如下:

kubectl label node worker1 ssd-

刪除apppod4,重新創建Pod,結果如下:

K8S動手教程2.3:Pod標籤和選擇器

該Pod一致處於Pending狀態,查詢詳情,可以看到事件信息,結果如下:

K8S動手教程2.3:Pod標籤和選擇器

從最後的Events可以看出,沒有節點能夠匹配nodeSelector屬性,Pod的狀態一致處於Pending。


實驗

1、創建帶有標籤的Pod;

2、測試標籤的常用操作;

3、使用nodeSelector屬性調度Pod到指定節點;


分享到:


相關文章: