To wielostronicowy widok tej sekcji do wydrukowania.
Kliknij aby wydrukować.
Wróć do zwykłego widoku tej strony.
Przegląd
Kubernetes to przenośna, rozszerzalna platforma oprogramowania open-source służąca do zarządzania zadaniami i serwisami uruchamianymi w kontenerach. Umożliwia ich deklaratywną konfigurację i automatyzację. Kubernetes posiada duży i dynamicznie rozwijający się ekosystem. Szeroko dostępne są usługi, wsparcie i dodatkowe narzędzia.
Na tej stronie znajdziesz ogólne informacje o Kubernetesie.
Kubernetes to przenośna, rozszerzalna platforma oprogramowania open-source służąca do zarządzania zadaniami i serwisami uruchamianymi w kontenerach,
która umożliwia deklaratywną konfigurację i automatyzację. Ekosystem Kubernetesa jest duży i dynamicznie się rozwija.
Usługi dla Kubernetesa, wsparcie i narzędzia są szeroko dostępne.
Nazwa Kubernetes pochodzi z języka greckiego i oznacza sternika albo pilota.
Skrót K8s powstał poprzez zastąpienie ośmiu liter pomiędzy "K" i "s".
Google otworzyło projekt Kubernetes publicznie w 2014. Kubernetes korzysta z
piętnastoletniego doświadczenia Google w uruchamianiu wielkoskalowych serwisów
i łączy je z najlepszymi pomysłami i praktykami wypracowanymi przez społeczność.
Trochę historii
Aby zrozumieć, dlaczego Kubernetes stał się taki przydatny, cofnijmy sie trochę w czasie.

Era wdrożeń tradycyjnych:
Na początku aplikacje uruchamiane były na fizycznych serwerach. Nie było możliwości separowania zasobów poszczególnych aplikacji,
co prowadziło do problemów z alokacją zasobów.
Przykładowo, kiedy wiele aplikacji jest uruchomionych na jednym fizycznym serwerze,
część tych aplikacji może zużyć większość dostępnych zasobów, powodując spowolnienie działania innych.
Rozwiązaniem tego problemu mogło być uruchamianie każdej aplikacji na osobnej maszynie.
Niestety, takie podejście ograniczało skalowanie, ponieważ większość zasobów nie była w pełni wykorzystywana,
a utrzymanie wielu fizycznych maszyn było kosztowne.
Era wdrożeń w środowiskach wirtualnych: Jako rozwiązanie zaproponowano wirtualizację, która umożliwia
uruchamianie wielu maszyn wirtualnych (VM) na jednym procesorze fizycznego serwera. Wirtualizacja pozwala
izolować aplikacje pomiędzy maszynami wirtualnymi, zwiększając w ten sposób bezpieczeństwo, jako że informacje
związane z jedną aplikacją nie są w łatwy sposób dostępne dla pozostałych.
Wirtualizacja pozwala lepiej wykorzystywać zasoby fizycznego serwera i lepiej skalować,
ponieważ aplikacje mogą być łatwo dodawane oraz aktualizowane, pozwala ograniczyć koszty sprzętu
oraz ma wiele innych zalet.
Za pomocą wirtualizacji można udostępnić wybrane zasoby fizyczne jako klaster maszyn wirtualnych "wielokrotnego użytku".
Każda maszyna wirtualna jest pełną maszyną zawierającą własny system operacyjny
pracujący na zwirtualizowanej warstwie sprzętowej.
Era wdrożeń w kontenerach: Kontenery działają w sposób zbliżony do maszyn wirtualnych,
ale mają mniejszy stopnień wzajemnej izolacji, współdzieląc ten sam system operacyjny.
Kontenery określane są mianem "lekkich". Podobnie, jak maszyna wirtualna,
kontener posiada własny system plików, udział w zasobach procesora, pamięć, przestrzeń procesów itd.
Ponieważ kontenery są definiowane rozłącznie od leżących poniżej warstw infrastruktury,
mogą być łatwiej przenoszone pomiędzy chmurami i różnymi dystrybucjami systemu operacyjnego.
Kontenery zyskały popularność ze względu na swoje zalety, takie jak:
- Szybkość i elastyczność w tworzeniu i instalacji aplikacji:
obraz kontenera buduje się łatwiej niż obraz VM.
- Ułatwienie ciągłego rozwoju, integracji oraz wdrażania aplikacji (Continuous development, integration, and deployment):
obrazy kontenerów mogą być budowane w sposób wiarygodny i częsty.
W razie potrzeby, przywrócenie poprzedniej wersji aplikacji jest stosunkowo łatwie (ponieważ obrazy są niezmienne).
- Rozdzielenie zadań Dev i Ops: obrazy kontenerów powstają w fazie build/release,
a nie w trakcie procesu instalacji,
oddzielając w ten sposób aplikacje od infrastruktury.
- Obserwowalność obejmuje nie tylko informacje i metryki z poziomu systemu operacyjnego,
ale także poprawność działania samej aplikacji i inne sygnały.
- Spójność środowiska na etapach rozwoju oprogramowania, testowania i działania w trybie produkcyjnym:
działa w ten sam sposób na laptopie i w chmurze.
- Możliwość przenoszenia pomiędzy systemami operacyjnymi i platformami chmurowymi: Ubuntu, RHEL, CoreOS,
prywatnymi centrami danych, największymi dostawcami usług chmurowych czy gdziekolwiek indziej.
- Zarządzanie, które w centrum uwagi ma aplikacje: Poziom abstrakcji przeniesiony jest z warstwy systemu operacyjnego
działającego na maszynie wirtualnej na poziom działania aplikacji, która działa na systemie operacyjnym używając zasobów logicznych.
- Luźno powiązane, rozproszone i elastyczne "swobodne" mikro serwisy: Aplikacje podzielone są na mniejsze, niezależne komponenty,
które mogą być dynamicznie uruchamiane i zarządzane -
nie jest to monolityczny system działający na jednej, dużej maszynie dedykowanej na wyłączność.
- Izolacja zasobów: wydajność aplikacji możliwa do przewidzenia
- Wykorzystanie zasobów: wysoka wydajność i upakowanie.
Do czego potrzebujesz Kubernetesa i jakie są jego możliwości
Kontenery są dobrą metodą na opakowywanie i uruchamianie aplikacji.
W środowisku produkcyjnym musisz zarządzać kontenerami, w których działają aplikacje i pilnować, aby nie było żadnych przerw w ich dostępności.
Przykładowo, kiedy jeden z kontenerów przestaje działać, musi zostać wymieniony.
Nie byłoby prościej, aby takimi działaniami zajmował się jakiś system?
I tu właśnie przychodzi z pomocą Kubernetes!
Kubernetes zapewnia środowisko do uruchamiania systemów rozproszonych o wysokiej niezawodności.
Kubernetes obsługuje skalowanie aplikacji, przełączanie w sytuacjach awaryjnych, różne scenariusze wdrożeń itp.
Przykładowo, Kubernetes w łatwy sposób może zarządzać wdrożeniem nowej wersji oprogramowania zgodnie z metodyką canary deployments.
Kubernetes zapewnia:
- Detekcję nowych serwisów i balansowanie ruchu
Kubernetes może udostępnić kontener używając nazwy DNS lub swojego własnego adresu IP.
Jeśli ruch przychodzący do kontenera jest duży, Kubernetes może balansować obciążenie i przekierować ruch sieciowy,
aby zapewnić stabilność całej instalacji.
- Zarządzanie obsługą składowania danych
Kubernetes umożliwia automatyczne montowanie systemów składowania danych dowolnego typu —
lokalnych, od dostawców chmurowych i innych.
- Automatyczne wdrożenia i wycofywanie zmian
Możesz opisać oczekiwany stan instalacji za pomocą Kubernetesa,
który zajmie się doprowadzeniem w sposób kontrolowany stanu faktycznego do stanu oczekiwanego.
Przykładowo, przy pomocy Kubernetesa możesz zautomatyzować proces tworzenia nowych kontenerów
na potrzeby swojego wdrożenia, usuwania istniejących i przejęcia zasobów przez nowe kontenery.
- Automatyczne zarządzanie dostępnymi zasobami
Twoim zadaniem jest dostarczenie klastra maszyn, które Kubernetes może wykorzystać do uruchamiania zadań w kontenerach.
Określasz zapotrzebowanie na moc procesora i pamięć RAM dla każdego z kontenerów.
Kubernetes rozmieszcza kontenery na maszynach w taki sposób, aby jak najlepiej wykorzystać dostarczone zasoby.
- Samoczynne naprawianie
Kubernetes restartuje kontenery, które przestały działać, wymienia je na nowe, wymusza wyłączenie kontenerów,
które nie odpowiadają na określone zapytania o stan
i nie rozgłasza powiadomień o ich dostępności tak długo, dopóki nie są gotowe do działania.
- Zarządzanie informacjami poufnymi i konfiguracją
Kubernetes pozwala składować i zarządzać informacjami poufnymi, takimi jak hasła, tokeny OAuth czy klucze SSH.
Informacje poufne i zawierające konfigurację aplikacji mogą być dostarczane i zmieniane bez konieczności ponownego budowania obrazu kontenerów
i bez ujawniania poufnych danych w ogólnej konfiguracji oprogramowania.
Czym Kubernetes nie jest
Kubernetes nie jest tradycyjnym, zawierającym wszystko systemem PaaS (Platform as a Service).
Ponieważ Kubernetes działa w warstwie kontenerów, a nie sprzętu, posiada różne funkcjonalności ogólnego zastosowania,
wspólne dla innych rozwiązań PaaS, takie jak: instalacje (deployments), skalowanie i balansowanie ruchu,
umożliwiając użytkownikom integrację rozwiązań służących do logowania, monitoringu i ostrzegania.
Co ważne, Kubernetes nie jest monolitem i domyślnie dostępne rozwiązania są opcjonalne i działają jako wtyczki.
Kubernetes dostarcza elementy, z których może być zbudowana platforma deweloperska,
ale pozostawia użytkownikowi wybór i elastyczność tam, gdzie jest to ważne.
Kubernetes:
- Nie ogranicza typów aplikacji, które są obsługiwane. Celem Kubernetesa jest możliwość obsługi bardzo różnorodnego typu zadań,
włączając w to aplikacje bezstanowe (stateless), aplikacje ze stanem (stateful) i ogólne przetwarzanie danych.
Jeśli jakaś aplikacja może działać w kontenerze, będzie doskonale sobie radzić w środowisku Kubernetesa.
- Nie oferuje wdrażania aplikacji wprost z kodu źródłowego i nie buduje aplikacji.
Procesy Continuous Integration, Delivery, and Deployment (CI/CD) są zależne od kultury pracy organizacji,
jej preferencji oraz wymagań technicznych.
- Nie dostarcza serwisów z warstwy aplikacyjnej, takich jak warstwy pośrednie middleware (np. broker wiadomości),
środowiska analizy danych (np. Spark), bazy danych (np. MySQL),
cache ani klastrowych systemów składowania danych (np. Ceph) jako usług wbudowanych.
Te składniki mogą być uruchamiane na klastrze Kubernetes i udostępniane innym aplikacjom przez przenośne rozwiązania,
takie jak Open Service Broker.
- Nie wymusza użycia konkretnych systemów zbierania logów, monitorowania ani ostrzegania.
Niektóre z tych rozwiązań są udostępnione jako przykłady. Dostępne są też mechanizmy do gromadzenia i eksportowania różnych metryk.
- Nie dostarcza, ani nie wymusza języka/systemu używanego do konfiguracji (np. Jsonnet).
Udostępnia API typu deklaratywnego, z którego można korzystać za pomocą różnych metod wykorzystujących deklaratywne specyfikacje.
- Nie zapewnia, ani nie wykorzystuje żadnego ogólnego systemu do zarządzania konfiguracją,
utrzymaniem i samo-naprawianiem maszyn.
- Co więcej, nie jest zwykłym systemem planowania (orchestration). W rzeczywistości, eliminuje konieczność orkiestracji.
Zgodnie z definicją techniczną, orkiestracja to wykonywanie określonego ciągu zadań: najpierw A, potem B i następnie C. Dla kontrastu,
Kubernetes składa się z wielu niezależnych, możliwych do złożenia procesów sterujących,
których zadaniem jest doprowadzenie stanu faktycznego do stanu oczekiwanego. Nie ma znaczenia, w jaki sposób przechodzi się od A do C.
Nie ma konieczności scentralizowanego zarządzania. Dzięki temu otrzymujemy system, który jest potężniejszy,
bardziej odporny i niezawodny i dający więcej możliwości rozbudowy.
Co dalej?
2 - API Kubernetesa
API Kubernetesa służy do odpytywania i zmiany stanu obiektów Kubernetesa. Sercem warstwy sterowania Kubernetesa jest serwer API i udostępniane po HTTP API. Przez ten serwer odbywa się komunikacja pomiędzy użytkownikami, różnymi częściami składowymi klastra oraz komponentami zewnętrznymi.
Sercem warstwy sterowania
Kubernetesa jest serwer API.
Serwer udostępnia API poprzez HTTP, umożliwiając wzajemną
komunikację pomiędzy użytkownikami, częściami składowymi klastra i komponentami zewnętrznymi.
API Kubernetesa pozwala na sprawdzanie i zmianę stanu
obiektów (przykładowo: pody, Namespaces, ConfigMaps, Events).
Większość operacji może zostać wykonana poprzez interfejs
linii komend (CLI) kubectl lub
inne programy, takie jak kubeadm,
które używają API. Możesz też korzystać z API
bezpośrednio przez wywołania typu REST. Jeśli piszesz aplikację używającą
API Kubernetesa, warto rozważyć użycie jednej z
bibliotek klienckich.
Każdy klaster Kubernetesa publikuje specyfikację dostępnych interfejsów API. Dostępne
są dwa mechanizmy udostępniania tych specyfikacji, które
umożliwiają automatyczną integrację i interoperacyjność z narzędziami zewnętrznymi.
Na przykład narzędzie kubectl
pobiera i buforuje specyfikację API w celu
umożliwienia autouzupełniania wiersza poleceń i innych funkcji. Te dwa mechanizmy to:
-
Discovery API dostarcza informacji o interfejsach API
Kubernetesa: nazwach API, zasobach, wersjach i obsługiwanych operacjach. W
Kubernetesie ten termin ma szczególne znaczenie, ponieważ to odrębny
interfejs od OpenAPI i jest traktowany jako osobna część systemu. Jest to zwięzłe
podsumowanie dostępnych zasobów i nie obejmuje szczegółowych definicji
schematów. Szczegółowe informacje o strukturze zasobów można znaleźć w dokumencie OpenAPI.
-
Kubernetes OpenAPI Document
dostarcza (pełne) schematy OpenAPI v2.0 i 3.0
dla wszystkich endpointów API
Kubernetesa. OpenAPI v3 to zalecany sposób uzyskiwania dostępu do
specyfikacji API, ponieważ zapewnia pełniejszy i
dokładniejszy obraz. Zawiera wszystkie ścieżki API oraz komplet danych
wejściowych i wyjściowych dla każdej operacji na wszystkich endpointach.
Specyfikacja obejmuje także wszystkie
rozszerzenia wspierane przez klaster. Jest to pełna definicja API, która
znacząco przewyższa pod względem szczegółowości dane z Discovery API.
Discovery API
Kubernetes przez Discovery API udostępnia pełną listę obsługiwanych grup
API, ich wersji oraz zasobów. Dla każdego zasobu można uzyskać następujące dane:
- Nazwa
- Klaster lub zasięg w przestrzeni nazw
- URL endpointu oraz obsługiwane metody HTTP
- Alternatywne nazwy
- Grupa, wersja, typ
API jest dostępne zarówno w formie zagregowanej, jak i niezagregowanej.
W trybie zagregowanym Discovery API udostępnia dwa endpointy, natomiast
w trybie niezagregowanym jest to oddzielny endpoint dla każdej wersji grupy.
Zagregowane Discovery API
STATUS FUNKCJONALNOŚCI:
Kubernetes v1.30 [stable]
(enabled by default: true)
Kubernetes zapewnia stabilne wsparcie dla zagregowanego
Discovery API, publikując wszystkie zasoby obsługiwane przez klaster za
pośrednictwem dwóch endpointów (/api
i /apis
).
Korzystanie z tych endpointów znacząco ogranicza liczbę zapytań
potrzebnych do pobrania danych z klastra. Dostęp do tych danych
uzyskuje się, wysyłając żądanie na odpowiedni endpoint z
nagłówkiem Accept
, który wskazuje na zagregowany zasób Discovery:
Accept: application/json;v=v2;g=apidiscovery.k8s.io;as=APIGroupDiscoveryList
.
W przypadku braku nagłówka Accept
wskazującego
typ zasobu, zapytania do endpointów /api
i
/apis
zwracają domyślnie dane w formacie niezagregowanym.
Discovery document
znajduje się w oficjalnym repozytorium
GitHub Kubernetesa. Może on służyć jako odniesienie do podstawowego zestawu zasobów
dostępnych w Kubernetesie, gdy nie masz możliwości wykonania zapytania do rzeczywistego klastra.
Endpoint obsługuje także mechanizm ETag oraz możliwość przesyłania danych w formacie protobuf.
Niezagregowane Discovery API
W przypadku braku agregacji Discovery API, dane udostępniane są w strukturze
wielopoziomowej, w której główne endpointy publikują informacje prowadzące do podrzędnych dokumentów.
Wszystkie wersje grup API dostępnych w klastrze są
udostępniane pod endpointami /api i /apis. Oto przykład:
{
"kind": "APIGroupList",
"apiVersion": "v1",
"groups": [
{
"name": "apiregistration.k8s.io",
"versions": [
{
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
}
},
{
"name": "apps",
"versions": [
{
"groupVersion": "apps/v1",
"version": "v1"
}
],
"preferredVersion": {
"groupVersion": "apps/v1",
"version": "v1"
}
},
...
}
Żeby pobrać informacje o zasobach dostępnych w konkretnej
wersji API, trzeba wysłać osobne zapytanie pod
/apis/<group>/<version>
- np. /apis/rbac.authorization.k8s.io/v1alpha1
. Ten
endpoint zawiera listę typów zasobów w danej grupie. Używa go
polecenie kubectl, żeby dowiedzieć się, jakie zasoby są dostępne w klastrze.
Interfejs OpenAPI
Pełną specyfikację API udokumentowano za pomocą OpenAPI.
Kubernetes obsługuje zarówno OpenAPI 2.0, jak i 3.0. Wersja
3 jest preferowana, ponieważ umożliwia
dokładniejszy i kompletny opis zasobów (bez utraty
informacji). W OpenAPI 2 niektóre pola, np. default
,
nullable
, oneOf
, są pomijane z powodu ograniczeń formatu.
OpenAPI V2
Serwer API Kubernetesa udostępnia specyfikację
OpenAPI poprzez ścieżkę /openapi/v2
. Aby wybrać
format odpowiedzi, użyj nagłówków żądania zgodnie z tabelą:
Dopuszczalne wartości nagłówka żądania dla zapytań OpenAPI v2
Nagłówek |
Dopuszczalne wartości |
Uwagi |
Accept-Encoding |
gzip |
pominięcie tego nagłówka jest dozwolone |
Accept |
application/com.github.proto-openapi.spec.v2@v1.0+protobuf |
głównie do celu komunikacji wewnątrz klastra |
application/json |
domyślne |
* |
udostępnia application/json |
Ostrzeżenie:
Reguły walidacyjne publikowane w ramach schematów OpenAPI mogą być niekompletne – i zazwyczaj nie
zawierają wszystkich warunków. Dodatkowa walidacja realizowana jest przez serwer API. Aby uzyskać pełną i
precyzyjną weryfikację, zaleca się użycie polecenia kubectl apply --dry-run=server
, które uruchamia wszystkie
mechanizmy walidacji, również te wykonujące się podczas przyjmowania zasobów do klastra (ang. admission checks).
OpenAPI V3
STATUS FUNKCJONALNOŚCI:
Kubernetes v1.27 [stable]
(enabled by default: true)
Kubernetes publikuje własne API zgodnie ze specyfikacją OpenAPI v3.
Pod adresem /openapi/v3
można znaleźć listę wszystkich
dostępnych grup/wersji. Zwracane wartości są dostępne tylko w formacie
JSON. Grupy/wersje opisane są następującym schematem:
{
"paths": {
...,
"api/v1": {
"serverRelativeURL": "/openapi/v3/api/v1?hash=CC0E9BFD992D8C59AEC98A1E2336F899E8318D3CF4C68944C3DEC640AF5AB52D864AC50DAA8D145B3494F75FA3CFF939FCBDDA431DAD3CA79738B297795818CF"
},
"apis/admissionregistration.k8s.io/v1": {
"serverRelativeURL": "/openapi/v3/apis/admissionregistration.k8s.io/v1?hash=E19CC93A116982CE5422FC42B590A8AFAD92CDE9AE4D59B5CAAD568F083AD07946E6CB5817531680BCE6E215C16973CD39003B0425F3477CFD854E89A9DB6597"
},
....
}
}
Względne adresy URL wskazują na niezmieniające się opisy OpenAPI, aby umożliwić
trzymanie cache po stronie klienta. Serwer API zwraca
również odpowiednie nagłówki HTTP dla cache (Expires
ustawione na 1 rok wprzód,
Cache-Control
jako immutable
). Wysłanie zapytania do
nieaktualnego URL spowoduje przekierowanie przez serwer API do wersji najnowszej.
Serwer API Kubernetesa udostępnia specyfikację
OpenAPI v3 pod adresem /openapi/v3/apis/<group>/<version>?hash=<hash>
,
zgodnie z podziałem na grupy i wersje.
Tabela poniżej podaje dopuszczalne wartości nagłówków żądania.
Dopuszczalne wartości nagłówka żądania dla zapytań OpenAPI v3
Nagłówek |
Dopuszczalne wartości |
Uwagi |
Accept-Encoding |
gzip |
pominięcie tego nagłówka jest dozwolone |
Accept |
application/com.github.proto-openapi.spec.v3@v1.0+protobuf |
głównie do celu komunikacji wewnątrz klastra |
application/json |
domyślne |
* |
udostępnia application/json |
W pakiecie k8s.io/client-go/openapi3
znajduje się implementacja w Golang do pobierania OpenAPI V3.
Kubernetes 1.33 publikuje OpenAPI w wersji
2.0 i 3.0; nie ma planów wsparcia wersji 3.1 w najbliższej przyszłości.
Serializacja Protobuf
Kubernetes implementuje alternatywny format serializacji oparty na
Protobuf, który jest głównie przeznaczony do komunikacji w obrębie klastra. Aby
uzyskać więcej informacji na temat tego formatu, zobacz
Kubernetes Protobuf serialization propozycję
projektową oraz pliki Interface Definition Language
(IDL) dla każdego schematu znajdujące się w pakietach Go, które definiują obiekty API.
Przechowywanie stanu
Kubernetes przechowuje serializowany stan swoich
obiektów w etcd.
Grupy i wersje API
Aby ułatwić usuwanie poszczególnych pól lub restrukturyzację reprezentacji
zasobów, Kubernetes obsługuje równocześnie wiele wersji API, każde poprzez osobną
ścieżkę API, na przykład: /api/v1
lub /apis/rbac.authorization.k8s.io/v1alpha1
.
Rozdział wersji wprowadzony jest na poziomie całego API, a nie na poziomach
poszczególnych zasobów lub pól, aby być pewnym, że API odzwierciedla w sposób
przejrzysty i spójny zasoby systemowe i ich zachowania oraz pozwala na
kontrolowany dostęp do tych API, które są w fazie wycofywania lub fazie eksperymentalnej.
Aby ułatwić rozbudowę API Kubernetes, wprowadziliśmy
grupy API, które mogą
być włączane i wyłączane.
Zasoby API są rozróżniane poprzez przynależność do grupy API, typ zasobu,
przestrzeń nazw (namespace, o ile ma zastosowanie) oraz nazwę. Serwer API może przeprowadzać
konwersję między różnymi wersjami API w sposób niewidoczny dla użytkownika:
wszystkie te różne wersje reprezentują w rzeczywistości ten sam zasób.
Serwer API może udostępniać te same dane poprzez kilka różnych wersji API.
Załóżmy przykładowo, że istnieją dwie wersje v1
i v1beta1
tego
samego zasobu. Obiekt utworzony przez wersję v1beta1
może być
odczytany, zaktualizowany i skasowany zarówno przez wersję v1beta1
,
jak i v1
, do czasu aż wersja v1beta1
będzie przestarzała i
usunięta. Wtedy możesz dalej korzystać i modyfikować obiekt poprzez wersję v1
.
Zmiany w API
Z naszego doświadczenia wynika, że każdy system, który odniósł sukces, musi się nieustająco rozwijać w
miarę zmieniających się potrzeb. Dlatego Kubernetes został tak zaprojektowany, aby API mogło się zmieniać i
rozrastać. Projekt Kubernetes dąży do tego, aby nie wprowadzać zmian niezgodnych z istniejącymi aplikacjami
klienckimi i utrzymywać zgodność przez wystarczająco długi czas, aby inne projekty zdążyły się dostosować do zmian.
W ogólności, nowe zasoby i pola definiujące zasoby API są dodawane
stosunkowo często. Usuwanie zasobów lub pól jest regulowane przez
API deprecation policy.
Po osiągnięciu przez API statusu ogólnej dostępności (general availability - GA), oznaczanej
zazwyczaj jako wersja API v1
, bardzo zależy nam na utrzymaniu jej zgodności w kolejnych wydaniach.
Dodatkowo, Kubernetes zachowuje kompatybilność z danymi zapisanymi za pomocą wersji beta. Gdy dana
funkcja osiąga stabilność (GA), dane te mogą być automatycznie konwertowane i dostępne w docelowej wersji API.
Jeśli korzystasz z wersji beta API, musisz przejść na kolejną wersję beta lub stabilną, gdy
dana wersja zostanie wycofana. Najlepszy moment na migrację to okres wycofywania
wersji beta - wtedy obiekty są dostępne równocześnie w obu wersjach API. Po zakończeniu
tego okresu wersja beta przestaje być obsługiwana i konieczne jest użycie wersji docelowej.
Informacja:
Mimo, że Kubernetes stara się także zachować zgodność dla API w wersji alpha, zdarzają się przypadki, kiedy
nie jest to możliwe. Jeśli korzystasz z API w wersji alfa, przed aktualizacją klastra do nowej wersji zalecamy
sprawdzenie w informacjach o wydaniu, czy nie nastąpiła jakaś zmiana w tej części API. Może się okazać, że API
uległo niekompatybilnym zmianom, co wymaga usunięcia wszystkich istniejących obiektów alfa przed wykonaniem aktualizacji.
Zajrzyj do API versions reference
po szczegółowe definicje różnych poziomów wersji API.
Rozbudowa API
API Kubernetesa można rozszerzać na dwa sposoby:
- Definicje zasobów własnych (custom resources)
pozwalają deklaratywnie określać, jak serwer API powinien dostarczać wybrane przez Ciebie zasoby API.
- Można także rozszerzać API Kubernetesa implementując
warstwę agregacji.
Co dalej?
3 - 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
lub qa
.
- Drugi przykład wybiera wszystkie zasoby z kluczem równym
tier
i wartościami
innymi niż frontend
i backend
, oraz wszystkie zasoby bez etykiet z kluczem tier
.
- 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?