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到指定节点;


分享到:


相關文章: