Kubernetes Cookbook 编程指南 中文版教程
创建时间:2018-12-07  访问量:3665  7  0

Kubernetes Cookbook 编程指南 中文版教程

标签(Label)和选择器(Selector)的使用

标签是一个键/值对的集合,它被附加在对象元数据的后面。我们可以使用标签来选择,组织并分组对象,如Pod,副本控制器和服务。标签不需要唯一。对象可以通过要组相同的标签集获取。

标签选择器被用来通过标签查询对象。目录支持选择器类型如下所示:

  • 基于equality的标签选择器

  • 基于set的标签选择器

  • 基于empty的标签选择器

  • 基于null标签选择器

一个基于equality的标签选择器是一组相等性需求的集合,它可以通过相等或不相等的操作来过滤标签。一个基于set的标签选择可以用来通过一组值过滤标签,目前支持in和notin操作。当一个标签的值匹配in操作符,它可以通过选择器返回;相反,如果一个标签匹配的值不在notin中,它就会返回。empty标签选择器会选择所有的对象,null标签选择不会选择任何对象。选择器可以组合使用。Kubernetes将返回匹配选择器中所有需求的对象。

开始

在你将标签设置到对象之前,你应该考虑到键和值的有效命名约定。

一个有效的键应该遵循这些规则:

  • 一个带有可选前缀的名称,前缀以斜线分隔。

  • 前缀必须是一个DNS的子域,通过点号分隔,不能超过253个字符

  • 一个名称必须小于63个字符,是[a-z0-9A-Z]这些字母数字、披折号、下划线和点的组合。注意符号不能放在名称的开头和结尾。

一个有效的值应该遵循以下规则:

  • 一个名称必须少于63个字符,使用[a-z0-9A-Z]组合和破折号、下划线与点。注意符号放在名称的开头和结尾是不合法的。

你也应该考虑到用途。例如,我们在pilot项目的不同开发环境中有一个服务包含多个层。然后我们可以用这样的标签:

  • project: pilot

  • enviroment: development, environment: staging, environment: production

  • tier: frontend, tier: backend

如何去做...

我们尝试在脚手架和生产环境中都使用前面所说的标签来创建一个nginx pod:

  1. 我们将为Pod和与副本控制器(RC)类似生产环境创建相同的脚手架:

# cat staging-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
    name: nginx
    labels:
        project: pilot
        environment: staging
        tier: frontend
spec:
    containers:
        -
            image: nginx
            imagePullPolicy: IfNotPresent
            name: nginx
            ports:
            - containerPort: 80


// create the pod via configuration file
# kubectl create -f staging-nginx.yaml
pod "nginx" created
  1. 让我们来看一下Pod的详细信息:
# kubectl describe pod nginx
Name: nginx
Namespace: default
Image(s): nginx
Node: ip-10-96-219-231/
Start Time: Sun, 27 Dec 2015 18:12:31 +0000
Labels: environment=staging,project=pilot,tier=frotend
Status: Running
...

我们可以查看一下Pod中的标签描述为environment=staging,project=pilot,tier=frontend。

  1. 现在,继续使用命令行为生产环境创建RC:

$ kubectl run nginx-prod --image=nginx --replicas=2 --port=80 --la
bels="environment=production,project=pilot,tier=frontend"

这会创建一个有两个副本并且名为nginx-prod的RC,一个开放的80端口,并且标签为environment=production, project=pilot,tier=frontend。

  1. 我们可以看到目前这里总共有三个Pod。一个Pod是为脚手架创建的,另两个是为生产创建的:

# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 				1/1 Running 0 8s
nginx-prod-50345 	1/1 Running 0 19s
nginx-prod-pilb4 	1/1 Running 0 19s

让我们为选择Pod获取一些过滤器。例如,如果我想要在pilot项目中选择生产的Pod:

# kubectl get pods -l "project=pilot,environment=production"
NAME 				READY 	STATUS 	RESTARTS 	AGE
nginx-prod-50345 	1/1 	Running 0 			9m
nginx-prod-pilb4 	1/1 	Running 0 			9m

通过在键/值对后添加 -l 作为过滤需求,我们可以查看期望的Pods。

通过使用标签选择器将服务连接到副本控制器

Kubernetes中的服务用来为负载均衡暴露端口:

  1. 在某些情况下,你将需要在副本控制器前添加一个服务来向外界或均衡负载来暴露端口。我们将使用配置文件来为脚手架Pod创建服务,使用命令行为生产中的Pod创建服务,如下所示:

// example of exposing staging pod
# cat staging-nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
	name: nginx
	labels:
        project: pilot
        environment: staging
        tier: frontend
spec:
    ports:
        -
            protocol: TCP
            port: 80
            targetPort: 80
        selector:
            project: pilot
            environment: staging
            tier: frontend
        type: LoadBalancer


// create the service by configuration file
# kubectl create -f staging-nginx-service.yaml
service "nginx" created
  1. 使用kubectl describe来描述服务的详细信息:
// describe service
# kubectl describe service nginx
Name: nginx
Namespace: default
Labels: environment=staging,project=pilot,tier=frontend
Selector: environment=staging,project=pilot,tier=frontend
Type: LoadBalancer
IP: 192.168.167.68
Port: <unnamed> 80/TCP
Endpoints: 192.168.80.28:80
Session Affinity: None
No events.

使用curl ClusterIP可以返回nginx的欢迎页面。

  1. 接一步,让我们使用标签选择器为RC添加一个服务:

// add service for nginx-prod RC
# kubectl expose rc nginx-prod --port=80 --type=LoadBalancer --selector="project=pilot,environment=production,tier=frontend"
  1. 使用kubectl describe来描述服务的详细信息:
# kubectl describe service nginx-prod
Name: nginx-prod
Namespace: default
Labels: environment=production,project=pilot,tier=frontend
Selector: environment=production,project=pilot,tier=frontend
Type: LoadBalancer
IP: 192.168.200.173
Port: <unnamed> 80/TCP
NodePort: <unnamed> 32336/TCP
Endpoints: 192.168.80.31:80,192.168.80.32:80
Session Affinity: None
No events.

当我们使用 curl 192.168.200.173,我们可以看到与脚手架类似的nginx欢迎页面。

如果你通过选择器指定了一个空的pod,它将返回一个Connection reset by peer的错误。

不止这些...

在某些情况下,我们可能想要使用一些值为资源打标签,仅仅为了在程序或工具中引用。非标识行(non-identifying)标签可以使用注解代替,这可以使用结构化或非结构化数据。不像标签,注解不用于查询和选择。下面的示例将向你展示如何向一个Pod中添加注解,如何通过downward API在容器中使用它们:

# cat annotation-sample.yaml
apiVersion: v1
kind: Pod
metadata:
	name: annotation-sample
	labels:
        project: pilot
        environment: staging
    annotations:
        git: 6328af0064b3db8b913bc613876a97187afe8e19
        build: "20"
spec:
	containers:
		-
			image: busybox
            imagePullPolicy: IfNotPresent
            name: busybox
            command: ["sleep", "3600"]

你可以使用downward API来访问容器中的注解,downward API在卷这一节讨论过:

# cat annotation-sample-downward.yaml
apiVersion: v1
kind: Pod
metadata:
    name: annotation-sample
    labels:
        project: pilot
        environment: staging
    annotations:
        git: 6328af0064b3db8b913bc613876a97187afe8e19
        build: "20"
spec:
    containers:
        -
            image: busybox
            imagePullPolicy: IfNotPresent
            name: busybox
            command: ["sh", "-c", "while true; do if [[ -e /etc/annotations ]];
            then cat /etc/annotations; fi; sleep 5; done"]
            volumeMounts:
            - name: podinfo
            	mountPath: /etc
    volumes:
        - name: podinfo
            downwardAPI:
                items:
                    - path: "annotations"
                        fieldRef:
                             fieldPath: metadata.annotations

用这种方法,metadata.annotations将会在容器中以文件格式暴露在/etc/annotations目录下。我们也可以检查pod的日志,将文件内容打印到命令行输出:

// check the logs we print in command section
# kubectl logs -f annotation-sample
build="20"
git="6328af0064b3db8b913bc613876a97187afe8e19"
kubernetes.io/config.seen="2015-12-28T12:23:33.154911056Z"
kubernetes.io/config.source="api"

还可以参考

你可以通过以下章节来练习标签和选择器:

  • Pod的使用

  • 副本控制器的使用

  • 服务的使用

  • 卷的使用

  • 第3章玩转容器,配置文件的使用