Etykiety i selektory
Etykiety to pary klucz/wartość, które są dołączane do obiektów takich jak Pody. Etykiety służą do określania identyfikacyjnych atrybutów obiektów, które są istotne i ważne dla użytkowników, ale bezpośrednio nie wpływają na semantykę głównego systemu. Etykiety mogą być używane do organizowania i wybierania podzbiorów obiektów. Etykiety mogą być dołączane do obiektów w momencie ich tworzenia, a następnie mogą być dodawane i modyfikowane w dowolnym momencie. Każdy obiekt może mieć zdefiniowany zestaw etykiet w postaci par klucz/wartość. Każdy klucz musi być unikalny dla konkretnego obiektu.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
Etykiety umożliwiają wydajne zapytania i obserwacje, co czyni je idealnym rozwiązaniem do użycia w interfejsach użytkownika (UI) i interfejsach wiersza poleceń (CLI). Informacje nieidentyfikujące powinny być rejestrowane przy użyciu adnotacji.
Motywacja
Etykiety umożliwiają użytkownikom odwzorowanie własnych struktur organizacyjnych na obiekty systemowe w sposób luźno powiązany, bez konieczności przechowywania tych odwzorowań przez klientów.
Rozmieszczanie usług i przetwarzanie wsadowe to często byty wielowymiarowe (np. wiele partycji lub wdrożeń, wiele ścieżek wydania, wiele poziomów, wiele mikrousług na poziom). Zarządzanie często wymaga operacji przekrojowych, co łamie enkapsulację ściśle hierarchicznych reprezentacji, zwłaszcza sztywnych hierarchii określanych przez infrastrukturę, a nie przez użytkowników.
Przykłady etykiet:
"release" : "stable"
,"release" : "canary"
"environment" : "dev"
,"environment" : "qa"
,"environment" : "production"
"tier" : "frontend"
,"tier" : "backend"
,"tier" : "cache"
"partition" : "customerA"
,"partition" : "customerB"
"track" : "daily"
,"track" : "weekly"
Oto przykłady zalecanych etykiet ; możesz swobodnie opracowywać własne konwencje. Pamiętaj, że klucz etykiety musi być unikalny dla danego obiektu.
Składnia i zestaw znaków
Etykiety to pary klucz/wartość. Prawidłowe klucze etykiet mają dwa segmenty: opcjonalny
prefiks i nazwę, oddzielone ukośnikiem (/
). Segment nazwy jest
wymagany i musi mieć maksymalnie 63 znaki, zaczynając i kończąc się znakiem
alfanumerycznym ([a-z0-9A-Z]
), z myślnikami (-
), podkreśleniami (_
),
kropkami (.
) i znakami alfanumerycznymi pomiędzy. Prefiks jest opcjonalny. Jeśli
jest podany, prefiks musi być subdomeną DNS: serią etykiet DNS oddzielonych
kropkami (.
), o długości nieprzekraczającej łącznie 253 znaków, zakończoną ukośnikiem (/
).
Jeśli prefiks zostanie pominięty, uważa się, że klucz etykiety jest prywatny dla użytkownika.
Zautomatyzowane komponenty systemowe (np. kube-scheduler
,
kube-controller-manager
, kube-apiserver
, kubectl
lub inne zewnętrzne
automatyzacje), które dodają etykiety do obiektów końcowego użytkownika, muszą określać prefiks.
Prefiksy kubernetes.io/
i k8s.io/
są
zarezerwowane dla podstawowych komponentów Kubernetesa.
Prawidłowa wartość etykiety:
- musi mieć 63 znaki lub mniej (może być puste),
- o ile ciąg nie jest pusty, musi zaczynać się i kończyć znakiem alfanumerycznym (
[a-z0-9A-Z]
), - może zawierać myślniki (
-
), podkreślenia (_
), kropki (.
) oraz znaki alfanumeryczne pomiędzy.
Na przykład, oto manifest dla Poda, który ma dwie
etykiety environment: production
oraz app: nginx
:
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
Selektory etykiet
W przeciwieństwie do nazw i identyfikatorów UID, etykiety nie zapewniają unikalności. Ogólnie rzecz biorąc, oczekujemy, że wiele obiektów będzie miało te same etykiety.
Za pomocą selektora etykiet klient/użytkownik może zidentyfikować zestaw obiektów. Selektor etykiet jest podstawowym mechanizmem grupującym w Kubernetesie.
API obecnie obsługuje dwa typy selektorów: oparte na równości i
oparte na zbiorach. Selektor etykiet może składać się z wielu wymagań, które
są oddzielone przecinkami. W przypadku wielu wymagań, wszystkie muszą być
spełnione, więc separator przecinka działa jako logiczny operator AND (&&
).
Semantyka pustych lub nieokreślonych selektorów jest zależna od kontekstu, a typy API, które używają selektorów, powinny dokumentować ich ważność i znaczenie.
Informacja:
Dla niektórych typów API, takich jak ReplicaSets, selektory etykiet dwóch instancji nie mogą się nakładać w obrębie jednej przestrzeni nazw, ponieważ kontroler może to uznać za sprzeczne polecenia i nie będzie w stanie określić, ile replik powinno być obecnych.Uwaga:
Zarówno dla warunków opartych na równości, jak i warunków opartych na zbiorach nie istnieje operator logiczny OR (||
).
Upewnij się, że twoje instrukcje filtrujące są odpowiednio skonstruowane.Wymóg oparty na równości
Wymagania oparte na równości lub nierówności umożliwiają filtrowanie
według kluczy i wartości etykiet. Pasujące obiekty muszą spełniać wszystkie
określone ograniczenia etykiet, chociaż mogą mieć również dodatkowe etykiety.
Dopuszczalne są trzy rodzaje operatorów: =
,==
,!=
. Pierwsze dwa reprezentują
równość (i są synonimami), podczas gdy ostatni reprezentuje nierówność. Na przykład:
environment = production
tier != frontend
Poprzedni wybiera wszystkie zasoby, których klucz jest równy environment
, a wartość równa się
production
. Drugi wybiera wszystkie zasoby, których klucz jest równy tier
, a wartość różni się od
frontend
, oraz wszystkie zasoby bez etykiet z kluczem tier
. Można filtrować zasoby w
production
wyłączając frontend
przy użyciu operatora przecinka: environment=production,tier!=frontend
Jednym ze scenariuszy użycia dla wymagań etykiet opartych na równości jest
specyfikacja kryteriów wyboru węzła przez Pody. Na przykład, poniższy przykładowy Pod wybiera
węzły, na których etykieta accelerator
istnieje i jest ustawiona na nvidia-tesla-p100
.
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
Wymagania oparte na zbiorach
Wymagania dotyczące etykiet bazujących na zbiorach (Set-based)
umożliwiają filtrowanie kluczy według zbioru wartości. Obsługiwane są trzy rodzaje
operatorów: in
, notin
oraz exists
(tylko identyfikator klucza). Na przykład:
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- Pierwszy przykład wybiera wszystkie zasoby z kluczem
równym
environment
i wartością równąproduction
lubqa
. - Drugi przykład wybiera wszystkie zasoby z kluczem równym
tier
i wartościami innymi niżfrontend
ibackend
, oraz wszystkie zasoby bez etykiet z kluczemtier
. - Trzeci przykład wybiera wszystkie zasoby zawierające
etykietę z kluczem
partition
; wartości nie są sprawdzane. - Czwarty przykład wybiera wszystkie zasoby bez
etykiety z kluczem
partition
; wartości nie są sprawdzane.
Podobnie separator przecinka działa jako operator AND.
Filtrowanie zasobów z kluczem partition
(bez względu na wartość) i z
environment
innym niż qa
można osiągnąć używając
partition,environment notin (qa)
. Selekcja etykiet oparta na zbiorach
jest ogólną formą równości, ponieważ environment=production
jest równoważne environment in (production)
; podobnie dla !=
i notin
.
Wymagania oparte na zbiorach mogą być mieszane z wymaganiami opartymi na
równości. Na przykład: partition in (customerA, customerB),environment!=qa
.
API
Filtrowanie LIST i WATCH
Dla operacji list i watch można określić selektory etykiet, aby filtrować zestawy zwracanych obiektów; filtr określasz za pomocą parametru zapytania. (Aby dowiedzieć się więcej o mechanizmie watch w Kubernetesie, przeczytaj o wydajnym wykrywaniu zmian ). Oba wymagania są dozwolone (przedstawione tutaj tak, jak mogą się pojawić w ciągu zapytania URL):
- wymagania oparte na równości:
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- _wymagania oparte na zbiorach:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
Oba style selektorów etykiet mogą być używane do wylistowania lub obserwacji zasobów za pomocą klienta
REST. Na przykład, kierując się na apiserver
z kubectl
i używając selekcji opartej na równości, można napisać:
kubectl get pods -l environment=production,tier=frontend
lub używając wymagań opartych na zbiorach:
kubectl get pods -l 'environment in (production),tier in (frontend)'
Jak już wspomniano, wymagania oparte na zbiorach są bardziej wyraziste. Na przykład mogą implementować operator LUB na wartościach:
kubectl get pods -l 'environment in (production, qa)'
lub ograniczenie dopasowywania negatywnego za pomocą operatora notin:
kubectl get pods -l 'environment,environment notin (frontend)'
Ustaw referencje w obiektach API
Niektóre obiekty Kubernetesa, takie jak
services
i replicationcontrollers
,
również używają selektorów etykiet do
określania zbiorów innych zasobów, takich jak pods.
Usługa i Kontroler Replikacji
Zestaw podów, na które skierowana jest usługa (service
), jest określany za pomocą selektora
etykiet. Podobnie, populacja podów, którą powinien zarządzać kontroler
replikacji (replicationcontroller
), jest również określana za pomocą selektora etykiet.
Selektory etykiet dla obu obiektów są definiowane w plikach json
lub
yaml
za pomocą map, i obsługiwane są tylko selektory wymagań oparte na równości:
"selector": {
"component" : "redis",
}
lub
selector:
component: redis
Ten selektor (odpowiednio w formacie json
lub yaml
)
jest równoważny z component=redis
lub component in (redis)
.
Zasoby, które obsługują wymagania oparte na zbiorach
Nowsze zasoby, takie jak Job
,
Deployment
,
ReplicaSet
oraz DaemonSet
,
obsługują również wymagania oparte na zbiorach.
selector:
matchLabels:
component: redis
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
matchLabels
to mapa par {klucz,wartość}
. Pojedyncza para {klucz,wartość}
w
mapie matchLabels
jest równoważna elementowi matchExpressions
, którego pole
key
to "klucz", operator
to "In", a tablica values
zawiera wyłącznie "wartość". matchExpressions
to lista wymagań selektora podów. Prawidłowe operatory to In,
NotIn, Exists i DoesNotExist. Zbiór wartości musi być niepusty w przypadku In i
NotIn. Wszystkie wymagania zarówno z matchLabels
, jak i matchExpressions
są
łączone za pomocą operatora AND - muszą być wszystkie spełnione, aby dopasowanie było możliwe.
Wybieranie zestawów węzłów
Jednym z przypadków użycia wybierania w oparciu o etykiety jest ograniczenie zestawu węzłów, na które można umieścić pod. Więcej informacji można znaleźć w dokumentacji na temat wyboru węzła.
Skuteczne wykorzystywanie etykiet
Możesz zastosować pojedynczą etykietę do dowolnych zasobów, ale nie zawsze jest to najlepsza praktyka. Istnieje wiele scenariuszy, w których należy użyć wielu etykiet, aby odróżnić zestawy zasobów od siebie nawzajem.
Na przykład różne aplikacje mogą używać różnych wartości dla etykiety app
, ale aplikacja
wielowarstwowa, taka jak przykład książki gości,
będzie dodatkowo musiała rozróżniać każdą warstwę. Frontend mógłby nosić następujące etykiety:
labels:
app: guestbook
tier: frontend
podczas gdy instancje master i replica Redis miałyby różne etykiety
tier
, a być może nawet dodatkową etykietę role
:
labels:
app: guestbook
tier: backend
role: master
i
labels:
app: guestbook
tier: backend
role: replica
Etykiety umożliwiają sortowanie i filtrowanie zasobów według dowolnego wymiaru określonego przez etykietę:
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-replica-2q2yf 1/1 Running 0 1m guestbook backend replica
guestbook-redis-replica-qgazl 1/1 Running 0 1m guestbook backend replica
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
kubectl get pods -lapp=guestbook,role=replica
NAME READY STATUS RESTARTS AGE
guestbook-redis-replica-2q2yf 1/1 Running 0 3m
guestbook-redis-replica-qgazl 1/1 Running 0 3m
Aktualizacja etykiet
Czasami możesz chcieć zmienić etykiety istniejących podów i innych zasobów przed
utworzeniem nowych zasobów. Można to zrobić za pomocą kubectl label
. Na
przykład, jeśli chcesz oznaczyć wszystkie swoje pody NGINX jako warstwę frontendową, wykonaj:
kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
Najpierw filtruje wszystkie pody z etykietą "app=nginx", a następnie nadaje im etykietę "tier=fe". Aby zobaczyć pody, które zostały oznaczone etykietą, uruchom:
kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
To wyświetla wszystkie pody z etykietą "app=nginx", z dodatkową kolumną
etykiet reprezentującą warstwę podów (określoną za pomocą -L
lub --label-columns
).
Aby uzyskać więcej informacji, zobacz kubectl label.
Co dalej?
- Dowiedz się, jak dodać etykietę do węzła
- Zobacz Well-known labels, Annotations and Taints
- Zobacz Zalecane etykiety
- Enforce Pod Security Standards with Namespace Labels
- Przeczytaj blog Writing a Controller for Pod Labels