内容摘要
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 的文章