Kubernetes Basics
Podstawy Kubernetes
Oryginalnym autorem tej strony jest Jorge (przeczytaj jego oryginalny post tutaj)
Architektura i podstawy
Co robi Kubernetes?
Pozwala na uruchamianie kontenera/kontenerów w silniku kontenerów.
Harmonogram umożliwia efektywne wykonywanie kontenerów.
Utrzymuje kontenery w stanie działającym.
Umożliwia komunikację między kontenerami.
Umożliwia techniki wdrażania.
Zarządza woluminami informacji.
Architektura
Node: system operacyjny z podem lub podami.
Pod: Opakowanie wokół kontenera lub wielu kontenerów. Pod powinien zawierać tylko jedną aplikację (zwykle pod uruchamia tylko 1 kontener). Pod jest sposobem, w jaki Kubernetes abstrahuje technologię kontenerów.
Service: Każdy pod ma 1 wewnętrzny adres IP z wewnętrznego zakresu węzła. Jednak może być również udostępniony za pomocą usługi. Usługa ma również adres IP, a jej celem jest utrzymanie komunikacji między podami, więc jeśli jeden pod umrze, nowa replika (z innym wewnętrznym adresem IP) będzie dostępna pod tym samym adresem IP usługi. Może być skonfigurowana jako wewnętrzna lub zewnętrzna. Usługa działa również jako wyważarka obciążenia, gdy 2 pody są podłączone do tej samej usługi. Po utworzeniu usługi można znaleźć punkty końcowe każdej usługi, uruchamiając
kubectl get endpoints
Kubelet: Główny agent węzła. Komponent, który nawiązuje komunikację między węzłem a kubectl i może uruchamiać tylko pod (za pośrednictwem serwera API). Kubelet nie zarządza kontenerami, które nie zostały utworzone przez Kubernetes.
Kube-proxy: jest usługą odpowiedzialną za komunikację (usługi) między serwerem API a węzłem. Podstawą są IPtables dla węzłów. Bardziej doświadczeni użytkownicy mogą zainstalować inne kube-proxy od innych dostawców.
Kontener pomocniczy (Sidecar container): Kontenery pomocnicze to kontenery, które powinny działać razem z głównym kontenerem w podzie. Ten wzorzec kontenera pomocniczego rozszerza i ulepsza funkcjonalność istniejących kontenerów bez ich zmiany. Obecnie wiemy, że używamy technologii kontenerowej do opakowania wszystkich zależności potrzebnych do uruchomienia aplikacji w dowolnym miejscu. Kontener robi tylko jedną rzecz i robi to bardzo dobrze.
Proces główny:
Serwer API: Jest to sposób, w jaki użytkownicy i pod używają do komunikacji z procesem głównym. Tylko uwierzytelnione żądania powinny być dozwolone.
Scheduler: Harmonogramowanie oznacza dopasowanie podów do węzłów, aby Kubelet mógł je uruchomić. Ma wystarczającą inteligencję, aby zdecydować, który węzeł ma więcej dostępnych zasobów i przypisać do niego nowy pod. Należy zauważyć, że scheduler nie uruchamia nowych podów, tylko komunikuje się z procesem Kubelet działającym wewnątrz węzła, który uruchomi nowy pod.
Kube Controller Manager: Sprawdza zasoby, takie jak zbiory replik lub wdrożenia, aby sprawdzić, czy na przykład uruchomione jest prawidłowe liczba podów lub węzłów. Jeśli brakuje poda, skontaktuje się z planistą, aby uruchomić nowy. Kontroluje replikacje, tokeny i usługi konta w API.
etcd: Przechowywanie danych, trwałe, spójne i rozproszone. Jest to baza danych Kubernetes i magazyn klucz-wartość, w którym przechowuje pełny stan klastrów (każda zmiana jest tutaj rejestrowana). Komponenty takie jak Scheduler lub Kube Controller Manager zależą od tych danych, aby wiedzieć, jakie zmiany nastąpiły (dostępne zasoby węzłów, liczba uruchomionych podów...)
Cloud Controller Manager: Jest to specyficzny kontroler do sterowania przepływem i aplikacjami, np. jeśli masz klastry w AWS lub OpenStack.
Należy zauważyć, że może być wiele węzłów (uruchamiających wiele podów), może również być wiele procesów głównych, których dostęp do serwera API jest zrównoważony obciążeniowo, a ich etcd jest zsynchronizowane.
Woluminy:
Kiedy pod tworzy dane, które nie powinny zostać utracone, gdy pod zniknie, powinny być one przechowywane w woluminie fizycznym. Kubernetes umożliwia dołączenie woluminu do poda w celu zachowania danych. Wolumen może znajdować się na lokalnej maszynie lub w zdalnym magazynie. Jeśli uruchamiasz pod w różnych fizycznych węzłach, powinieneś użyć zdalnego magazynu, aby wszystkie pod mogły do niego uzyskać dostęp.
Inne konfiguracje:
ConfigMap: Możesz skonfigurować adresy URL do dostępu do usług. Pod pobierze dane stąd, aby wiedzieć, jak komunikować się z resztą usług (podów). Należy jednak pamiętać, że to nie jest zalecane miejsce do przechowywania poufnych danych!
Secret: To jest miejsce do przechowywania poufnych danych, takich jak hasła, klucze API... zakodowane w B64. Pod będzie mógł uzyskać dostęp do tych danych, aby używać wymaganych poświadczeń.
Deployments: Tutaj wskazuje się komponenty, które mają być uruchamiane przez Kubernetes. Użytkownik zwykle nie będzie bezpośrednio pracować z podami, podami są abstrahowane w ReplicaSets (liczba replikowanych tych samych podów), które są uruchamiane za pomocą wdrożeń. Należy zauważyć, że wdrożenia są przeznaczone dla aplikacji bezstanowych. Minimalną konfiguracją dla wdrożenia jest nazwa i obraz do uruchomienia.
StatefulSet: Ten komponent jest przeznaczony specjalnie dla aplikacji takich jak bazy danych, które muszą uzyskać dostęp do tego samego magazynu.
Ingress: Jest to konfiguracja, która służy do **udostępniania aplikacji
Infrastruktura PKI - Certyfikatowy Urząd CA:
CA jest zaufanym źródłem dla wszystkich certyfikatów w klastrze.
Umożliwia komponentom wzajemną weryfikację.
Wszystkie certyfikaty klastra są podpisane przez CA.
ETCd ma swój własny certyfikat.
typy:
certyfikat apiservera.
certyfikat kubeleta.
certyfikat schedulera.
Podstawowe działania
Minikube
Minikube można użyć do przeprowadzenia szybkich testów na kubernetes bez konieczności wdrażania całego środowiska kubernetes. Uruchomi on procesy master i node na jednym komputerze. Minikube będzie używać virtualboxa do uruchomienia node'a. Zobacz tutaj, jak go zainstalować.
Podstawy Kubectl
Kubectl
to narzędzie wiersza poleceń dla klastrów Kubernetes. Komunikuje się z serwerem API procesu głównego, aby wykonywać działania w Kubernetes lub pytać o dane.
Panel Minikube
Panel umożliwia łatwe sprawdzenie, co jest uruchomione w minikube. Możesz znaleźć URL dostępu do niego w:
Przykłady plików konfiguracyjnych YAML
Każdy plik konfiguracyjny składa się z 3 części: metadata, specification (co ma zostać uruchomione) i status (pożądany stan). Wewnątrz specyfikacji pliku konfiguracyjnego dla wdrożenia można znaleźć szablon zdefiniowany za pomocą nowej struktury konfiguracji określającej obraz do uruchomienia:
Przykład wdrożenia + usługi zadeklarowane w tym samym pliku konfiguracyjnym (z tutaj)
Ponieważ usługa zazwyczaj jest powiązana z jednym wdrożeniem, można zadeklarować oba w tym samym pliku konfiguracyjnym (usługa zadeklarowana w tej konfiguracji jest dostępna tylko wewnętrznie):
Przykład konfiguracji zewnętrznej usługi
Ta usługa będzie dostępna z zewnątrz (sprawdź atrybuty nodePort
i type: LoadBalancer
):
To jest przydatne do testowania, ale w produkcji powinieneś mieć tylko wewnętrzne usługi i Ingress do wystawienia aplikacji.
Przykład pliku konfiguracyjnego Ingress
To wystawi aplikację pod adresem http://dashboard.com
.
Przykład pliku konfiguracyjnego dla tajemnic
Zauważ, jak hasła są zakodowane w B64 (co nie jest bezpieczne!)
Przykład ConfigMap
ConfigMap to konfiguracja, która jest dostarczana do podów, aby wiedziały, jak zlokalizować i uzyskać dostęp do innych usług. W tym przypadku każdy pod będzie wiedział, że nazwa mongodb-service
to adres poda, z którym mogą się komunikować (ten pod będzie wykonywał mongodb):
Następnie, wewnątrz konfiguracji deploymentu, ten adres można określić w następujący sposób, aby został załadowany do środowiska poda:
Przykład konfiguracji woluminu
Możesz znaleźć różne przykłady plików konfiguracyjnych yaml dla konfiguracji pamięci masowej na stronie https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Zauważ, że woluminy nie są wewnątrz przestrzeni nazw
Przestrzenie nazw
Kubernetes obsługuje wiele wirtualnych klastrów opartych na tym samym fizycznym klastrze. Te wirtualne klastry nazywane są przestrzeniami nazw. Są one przeznaczone do użytku w środowiskach z wieloma użytkownikami rozproszonymi na wiele zespołów lub projektów. Dla klastrów z kilkoma do kilkudziesięciu użytkowników, nie powinieneś w ogóle musieć tworzyć lub myśleć o przestrzeniach nazw. Przestrzenie nazw powinny być używane tylko w celu lepszego kontrolowania i organizacji każdej części aplikacji wdrażanej w kubernetes.
Przestrzenie nazw zapewniają zakres dla nazw. Nazwy zasobów muszą być unikalne w obrębie przestrzeni nazw, ale nie między przestrzeniami nazw. Przestrzenie nazw nie mogą być zagnieżdżane wewnątrz siebie i każdy zasób Kubernetes może znajdować się tylko w jednej przestrzeni nazw.
Domyślnie istnieje 4 przestrzenie nazw, jeśli korzystasz z minikube:
kube-system: Nie jest przeznaczony do użytku przez użytkowników i nie powinno się go dotykać. Służy do procesów mastera i kubectl.
kube-public: Publicznie dostępne dane. Zawiera configmapę, która zawiera informacje o klastrze.
kube-node-lease: Określa dostępność węzła.
default: Przestrzeń nazw, którą użytkownik będzie używał do tworzenia zasobów.
Należy zauważyć, że większość zasobów Kubernetes (np. podów, usług, kontrolerów replikacji i innych) znajduje się w pewnych przestrzeniach nazw. Jednak inne zasoby, takie jak zasoby przestrzeni nazw i zasoby niskiego poziomu, takie jak węzły i persistenVolumes, nie znajdują się w przestrzeni nazw. Aby zobaczyć, które zasoby Kubernetes są i które nie są w przestrzeni nazw:
Możesz zapisać przestrzeń nazw dla wszystkich kolejnych poleceń kubectl w tym kontekście.
Helm
Helm jest menedżerem pakietów dla Kubernetes. Pozwala na pakietowanie plików YAML i ich dystrybucję w publicznych i prywatnych repozytoriach. Te pakiety nazywane są Helm Charts.
Helm to również silnik szablonów, który umożliwia generowanie plików konfiguracyjnych z zmiennymi:
Sekrety Kubernetes
Secret to obiekt, który zawiera poufne dane, takie jak hasło, token lub klucz. Takie informacje mogą być umieszczone w specyfikacji Podu lub w obrazie. Użytkownicy mogą tworzyć sekrety, a system również tworzy sekrety. Nazwa obiektu Secret musi być prawidłową nazwą poddomeny DNS. Przeczytaj tutaj oficjalną dokumentację.
Sekrety mogą być takie jak:
Klucze API, SSH.
Tokeny OAuth.
Poświadczenia, hasła (tekst zwykły lub b64 + szyfrowanie).
Informacje lub komentarze.
Kod łączenia z bazą danych, ciągi... .
W Kubernetes istnieją różne typy sekretów
Wbudowany typ | Użycie |
---|---|
Opaque | dowolne dane zdefiniowane przez użytkownika (domyślnie) |
kubernetes.io/service-account-token | token konta usługi |
kubernetes.io/dockercfg | zserializowany plik ~/.dockercfg |
kubernetes.io/dockerconfigjson | zserializowany plik ~/.docker/config.json |
kubernetes.io/basic-auth | poświadczenia do uwierzytelniania podstawowego |
kubernetes.io/ssh-auth | poświadczenia do uwierzytelniania SSH |
kubernetes.io/tls | dane dla klienta lub serwera TLS |
bootstrap.kubernetes.io/token | dane tokena rozruchowego |
Typ Opaque jest domyślny, to typowy para klucz-wartość zdefiniowany przez użytkowników.
Jak działają sekrety:
Poniższy plik konfiguracyjny definiuje sekret o nazwie mysecret
z dwoma parami klucz-wartość username: YWRtaW4=
i password: MWYyZDFlMmU2N2Rm
. Definiuje również pod o nazwie secretpod
, który będzie miał username
i password
zdefiniowane w mysecret
wystawione jako zmienne środowiskowe SECRET_USERNAME
i SECRET_PASSWOR
. Będzie również montować sekret username
wewnątrz mysecret
w ścieżce /etc/foo/my-group/my-username
z uprawnieniami 0640
.
Tajemnice w etcd
etcd to spójny i wysoko dostępny sklep klucz-wartość używany jako magazyn danych klastra Kubernetes. Pozwala nam uzyskać dostęp do przechowywanych w etcd tajemnic:
Zobaczysz, że certyfikaty, klucze i adresy URL są przechowywane w systemie plików. Po ich uzyskaniu będziesz w stanie połączyć się z etcd.
Gdy już uda ci się nawiązać komunikację, będziesz w stanie uzyskać tajemnice:
Dodawanie szyfrowania do ETCD
Domyślnie wszystkie tajemnice są przechowywane w postaci czystego tekstu wewnątrz etcd, chyba że zastosujesz warstwę szyfrowania. Poniższy przykład oparty jest na https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Następnie musisz ustawić flagę --encryption-provider-config
na kube-apiserver
, aby wskazać lokalizację utworzonego pliku konfiguracyjnego. Możesz zmodyfikować /etc/kubernetes/manifest/kube-apiserver.yaml
i dodać następujące linie:
Przewiń w dół do volumeMounts:
Przewiń w dół do volumeMounts do hostPath:
Weryfikacja, czy dane są zaszyfrowane
Dane są szyfrowane podczas zapisu do etcd. Po ponownym uruchomieniu kube-apiserver
, nowo utworzone lub zaktualizowane tajemnice powinny być zaszyfrowane podczas przechowywania. Aby to sprawdzić, można użyć programu wiersza poleceń etcdctl
, aby pobrać zawartość tajemnicy.
Utwórz nową tajemnicę o nazwie
secret1
w przestrzeni nazwdefault
:
Za pomocą polecenia etcdctl odczytaj tę tajemnicę z etcd:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
gdzie [...]
muszą być dodatkowe argumenty do połączenia z serwerem etcd. 3. Zweryfikuj, czy przechowywana tajemnica ma prefiks k8s:enc:aescbc:v1:
, co wskazuje, że dostawca aescbc
zaszyfrował dane wynikowe. 4. Zweryfikuj, czy tajemnica jest poprawnie odszyfrowana podczas pobierania za pomocą interfejsu API:
powinno pasować do mykey: bXlkYXRh
, mydata jest zakodowane, sprawdź dekodowanie tajemnicy, aby całkowicie odkodować tajemnicę.
Ponieważ tajemnice są szyfrowane podczas zapisu, wykonanie aktualizacji tajemnicy spowoduje zaszyfrowanie tego zawartości:
Ostateczne wskazówki:
Staraj się nie przechowywać tajemnic w systemie plików, pobieraj je z innych miejsc.
Sprawdź https://www.vaultproject.io/, aby zwiększyć ochronę swoich tajemnic.
Referencje
Last updated