背景
k8s集群使用过程中会涉及到根据条件对k8s资源进行筛选的场景. 比如查看属于某个application
的k8s资源,某个指定node
上运行的所有pod,以及删除某个namespace
下status为Unknown
的pod等等.这些场景丢涉及到本篇文章提到的技巧:使用选择器在集群内筛选满足条件的k8s资源.
选择器分类
k8s选择其主要分为两类字段选择器(field-selector)以及标签选择器(label-selector).
字段选择器(field-selector)
字段选择器是基于资源的字段值进行筛选的选择器,
官方对于此选择器的解释(kubectl get --help)
–field-selector=‘’:
Selector (field query) to filter on, supports ‘=’, ‘==’, and ‘!=’.(e.g. --field-selector
key1=value1,key2=value2). The server only supports a limited number of field queries per
type.
注意:官方给出的解释是只有部分字段支持字段选择器,并不是使用kubectl get pod -o yaml
看到的资源中的所有字段都可以作为筛选条件.且如果是多个筛选条件,以逗号隔开.
下面看一个例子.有如下的YAML资源文件中定义了两个pod(niginx-normal
和nginx-error
),其中nginx-normal
能正常启动,nginx-error
因为镜像版本过高不存在而不会正常启动:
# normal
apiVersion: v1
kind: Pod
metadata:
name: nginx-normal
labels:
app: nginx
release: normal
spec:
containers:
- name: nginx
image: nginx:1.25.4
ports:
- containerPort: 80
---
# image not exist
apiVersion: v1
kind: Pod
metadata:
name: nginx-error
labels:
app: nginx
release: error
spec:
containers:
- name: nginx
image: nginx:2.25.4
ports:
- containerPort: 80
在k8s集群中创建这两个pod
kubectl apply -f test.yaml -n test
查看pod
kubectl get pod -n test -o wide
NAME READY STATUS RESTARTS AGE
nginx-error 0/1 ImagePullBackOff 0 5m7s
nginx-normal 1/1 Running 0 5m7s
详细查看nginx-error
的资源运行状态:
kubectl get pod nginx-error -n test -o yaml
...
status:
phase: Pending
...
查看nginx-normal
的资源运行状态:
kubectl get pod nginx-normal -n test -o yaml
...
status:
phase: Running
...
这样依赖就可以使用--field-selector=status.phase=Running
筛选出运行状态正常的pod:
kubectl get pod --field-selector=status.phase=Running -n test
...
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 9m56s
同理也可以使用--file-selector=status.phase!=Running
筛选出运行状态不正常的pod:
kubectl get pod --field-selector=status.phase!=Running -n test
...
NAME READY STATUS RESTARTS AGE
nginx-error 0/1 ImagePullBackOff 0 12m
因此podnginx-error
可以被筛选出来.
如果想使用字段选择器达到标签选择器同样的筛选效果,使用如下指令
kubectl get pod --field-selector=metadata.labels.app=nginx -n test
...
Error from server (BadRequest): Unable to find "/v1, Resource=pods" that match label selector "", field selector "metadata.labels.app=nginx": field label not supported: metadata.labels.app
由此可见字段选择器并不能替代标签选择器,因为字段选择器不支持在字段metadata.labels.{label}
上做筛选.
标签选择器(label-selector)
标签选择器是根据资源的标签(metadata.labels.{label_name}
)进行资源的筛选.相比于字段选择器可以基于资源文件的有效字段
进行筛选,标签选择器只能基于资源标签(labels)
进行筛选.
官方对于标签选择器的解释:
-l, --selector=‘’:
Selector (label query) to filter on, supports ‘=’, ‘==’, and ‘!=’.(e.g. -l
key1=value1,key2=value2). Matching objects must satisfy all of the specified label
constraints.
比如筛选应用名称是nginx且release是normal的pod,使用如下指令:
kubectl get pod -l app=nginx,release=normal -n test
...
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 25m
以及筛选release不是error的pod,使用如下指令:
kubectl get pod --selector release!=error -n test
...
NAME READY STATUS RESTARTS AGE
nginx-normal 1/1 Running 0 27m
如果想尝试使用标签之外的字段进行筛选则无法获取想要的资源.
kubectl get pod -l status.phase=Running -n test
No resources found in test namespace.
总结
如果是基于资源的label筛选使用label-selector,如果是资源label之外的字段筛选使用field-selector.
参考
- https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/