ラベル(Labels)とセレクター(Selectors)
ラベル(Labels) はPodなどのオブジェクトに割り当てられたキーとバリューのペアです。
ラベルはユーザーに関連した意味のあるオブジェクトの属性を指定するために使われることを目的としています。しかしKubernetesのコアシステムに対して直接的にその意味を暗示するものではありません。
ラベルはオブジェクトのサブセットを選択し、グルーピングするために使うことができます。また、ラベルはオブジェクトの作成時に割り当てられ、その後いつでも追加、修正ができます。
各オブジェクトはキーとバリューのラベルのセットを定義できます。各キーは、単一のオブジェクトに対してはユニークである必要があります。
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
ラベルは効率的な検索・閲覧を可能にし、UIやCLI上での利用に最適です。 識別用途でない情報は、アノテーションを用いて記録されるべきです。
ラベルを使う動機
ラベルは、クライアントにそのマッピング情報を保存することを要求することなく、ユーザー独自の組織構造をシステムオブジェクト上で疎結合にマッピングできます。
サービスデプロイメントとバッチ処理のパイプラインは多くの場合、多次元のエンティティとなります(例: 複数のパーティション、Deployment、リリーストラック、ティアー、ティアー毎のマイクロサービスなど)
管理は分野横断的な操作が必要になることが多く、それによって厳密な階層表現、特にユーザーによるものでなく、インフラストラクチャーによって定義された厳格な階層のカプセル化が破られます。
ラベルの例:
"release" : "stable"
,"release" : "canary"
"environment" : "dev"
,"environment" : "qa"
,"environment" : "production"
"tier" : "frontend"
,"tier" : "backend"
,"tier" : "cache"
"partition" : "customerA"
,"partition" : "customerB"
"track" : "daily"
,"track" : "weekly"
これらは単によく使われるラベルの例です。ユーザーは自由に規約を決めることができます。 ラベルのキーは、ある1つのオブジェクトに対してユニークである必要があることは覚えておかなくてはなりません。
構文と文字セット
ラベルは、キーとバリューのベアです。正しいラベルキーは2つのセグメントを持ちます。
それは/
によって分割されたオプショナルなプレフィックスと名前です。
名前セグメントは必須で、63文字以下である必要があり、文字列の最初と最後は英数字([a-z0-9A-Z]
)で、文字列の間ではこれに加えてダッシュ(-
)、アンダースコア(_
)、ドット(.
)を使うことができます。
プレフィックスはオプションです。もしプレフィックスが指定されていた場合、プレフィックスはDNSサブドメイン形式である必要があり、それはドット(.
)で区切られたDNSラベルのセットで、253文字以下である必要があり、最後にスラッシュ(/
)が続きます。
もしプレフィックスが省略された場合、ラベルキーはそのユーザーに対してプライベートであると推定されます。
エンドユーザーのオブジェクトにラベルを追加するような自動化されたシステムコンポーネント(例: kube-scheduler
kube-controller-manager
kube-apiserver
kubectl
やその他のサードパーティツール)は、プレフィックスを指定しなくてはなりません。
kubernetes.io/
とk8s.io/
プレフィックスは、Kubernetesコアコンポーネントのために予約されています。
正しいラベル値は63文字以下の長さで、空文字か、もしくは開始と終了が英数字([a-z0-9A-Z]
)で、文字列の間がダッシュ(-
)、アンダースコア(_
)、ドット(.
)と英数字である文字列を使うことができます。
例えば、environment: production
とapp: nginx
の2つのラベルを持つPodの設定ファイルは下記のようになります。
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
ラベルセレクター
名前とUIDとは異なり、ラベルはユニーク性を提供しません。通常、多くのオブジェクトが同じラベルを保持することを想定します。
ラベルセレクター を介して、クライアントとユーザーはオブジェクトのセットを指定できます。ラベルセレクターはKubernetesにおいてコアなグルーピング機能となります。
Kubernetes APIは現在2タイプのセレクターをサポートしています。
それは等価ベース(equality-based) と集合ベース(set-based) です。
単一のラベルセレクターは、コンマ区切りの複数の要件(requirements) で構成されています。
複数の要件がある場合、コンマセパレーターは論理積 AND(&&
)オペレーターと同様にふるまい、全ての要件を満たす必要があります。
空文字の場合や、指定なしのセレクターに関するセマンティクスは、コンテキストに依存します。 そしてセレクターを使うAPIタイプは、それらのセレクターの妥当性とそれらが示す意味をドキュメントに記載するべきです。
備考: ReplicaSetなど、いくつかのAPIタイプにおいて、2つのインスタンスのラベルセレクターは単一の名前空間において重複してはいけません。重複していると、コントローラがそれらのラベルセレクターがコンフリクトした操作とみなし、どれだけの数のレプリカを稼働させるべきか決めることができなくなります。
注意: 等価ベース、集合ベースともに、論理OR (||
) オペレーターは存在しません。フィルターステートメントが意図した通りになっていることを確認してください。
等価ベース(Equality-based) の要件(requirement)
等価ベース(Equality-based) もしくは不等ベース(Inequality-based) の要件は、ラベルキーとラベル値によるフィルタリングを可能にします。
要件に一致したオブジェクトは、指定されたラベルの全てを満たさなくてはいけませんが、それらのオブジェクトはさらに追加のラベルも持つことができます。
そして等価ベースの要件においては、3つの種類のオペレーターの利用が許可されています。=
、==
、!=
となります。
最初の2つのオペレーター(=
、==
)は等価(Equality) を表現し(この2つは単なる同義語)、最後の1つ(!=
)は不等(Inequality) を意味します。
例えば
environment = production
tier != frontend
最初の例は、キーがenvironment
で、値がproduction
である全てのリソースを対象にします。
次の例は、キーがtier
で、値がfrontend
とは異なるリソースと、tier
という名前のキーを持たない全てのリソースを対象にします。
コンマセパレーター,
を使って、production
の中から、frontend
のものを除外するようにフィルターすることもできます。
environment=production,tier!=frontend
等価ベースのラベル要件の1つの使用シナリオとして、PodにおけるNodeの選択要件を指定するケースがあります。
例えば、下記のサンプルPodは、ラベルaccelerator=nvidia-tesla-p100
をもったNodeを選択します。
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
集合ベース(Set-based) の要件(requirement)
集合ベース(Set-based) のラベルの要件は値のセットによってキーをフィルタリングします。
in
、notin
、exists
の3つのオペレーターをサポートしています(キーを特定するのみ)。
例えば:
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 最初の例では、キーが
environment
で、値がproduction
かqa
に等しいリソースを全て選択します。 - 第2の例では、キーが
tier
で、値がfrontend
とbackend
以外のもの、そしてtier
キーを持たないリソースを全て選択します。 - 第3の例では、
partition
というキーをもつラベルを全て選択し、値はチェックしません。 - 第4の例では、
partition
というキーを持たないラベルを全て選択し、値はチェックしません。
同様に、コンマセパレーターは、AND オペレーターと同様にふるまいます。そのため、partition
とenvironment
キーの値がともにqa
でないラベルを選択するには、partition,environment notin (qa)
と記述することで可能です。
集合ベース のラベルセレクターは、environment=production
という記述がenvironment in (production)
と等しいため、一般的な等価形式となります。 !=
とnotin
も同様に等価となります。
集合ベース の要件は、等価ベース の要件と混在できます。
例えば:
partition in (customerA, customerB),environment!=qa
.
API
LISTとWATCHによるフィルタリング
LISTとWATCHオペレーションは、単一のクエリパラメータを使うことによって返されるオブジェクトのセットをフィルターするためのラベルセレクターを指定できます。
集合ベース と等価ベース のどちらの要件も許可されています(ここでは、URLクエリストリング内で出現します)。
- 等価ベース での要件:
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- 集合ベース での要件:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
上記の2つの形式のラベルセレクターはRESTクライアントを介してリストにしたり、もしくは確認するために使われます。
例えば、kubectl
によってapiserver
をターゲットにし、等価ベース の要件でフィルターすると以下のように書けます。
kubectl get pods -l environment=production,tier=frontend
もしくは、集合ベース の要件を指定すると以下のようになります。
kubectl get pods -l 'environment in (production),tier in (frontend)'
すでに言及したように、集合ベース の要件は、等価ベース の要件より表現力があります。
例えば、値に対する OR オペレーターを実装して以下のように書けます。
kubectl get pods -l 'environment in (production, qa)'
もしくは、exists オペレーターを介して、否定マッチングによる制限もできます。
kubectl get pods -l 'environment,environment notin (frontend)'
APIオブジェクトに参照を設定する
Service
と ReplicationController
のような、いくつかのKubernetesオブジェクトでは、ラベルセレクターをPodのような他のリソースのセットを指定するのにも使われます。
ServiceとReplicationController
Service
が対象とするPodの集合は、ラベルセレクターによって定義されます。
同様に、ReplicationController
が管理するべきPod数についてもラベルセレクターを使って定義されます。
それぞれのオブジェクトに対するラベルセレクターはマップを使ってjson
もしくはyaml
形式のファイルで定義され、等価ベース のセレクターのみサポートされています。
"selector": {
"component" : "redis",
}
もしくは
selector:
component: redis
このセレクター(それぞれjson
またはyaml
形式)は、component=redis
またはcomponent in (redis)
と等価です。
集合ベース の要件指定をサポートするリソース
Job
やDeployment
、ReplicaSet
やDaemonSet
などの比較的新しいリソースは、集合ベース での要件指定もサポートしています。
selector:
matchLabels:
component: redis
matchExpressions:
- {key: tier, operator: In, values: [cache]}
- {key: environment, operator: NotIn, values: [dev]}
matchLabels
は、{key,value}
ペアのマップです。matchLabels
内の単一の{key,value}
は、matchExpressions
の要素と等しく、それは、key
フィールドがキー名で、operator
が"In"で、values
配列は単に"値"を保持します。
matchExpressions
はPodセレクター要件のリストです。対応しているオペレーターはIn
、NotIn
、Exists
とDoesNotExist
です。values
のセットは、In
とNotIn
オペレーターにおいては空文字を許容しません。
matchLabels
とmatchExpressions
の両方によって指定された全ての要件指定はANDで判定されます。つまり要件にマッチするには指定された全ての要件を満たす必要があります。
Nodeのセットを選択する
ラベルを選択するための1つのユースケースはPodがスケジュールできるNodeのセットを制限することです。
さらなる情報に関しては、Node選定 のドキュメントを参照してください。