ProHoster > Blog > uprava > Naše iskustvo s podacima u etcd Kubernetes klasteru izravno (bez K8s API-ja)
Naše iskustvo s podacima u etcd Kubernetes klasteru izravno (bez K8s API-ja)
Sve češće klijenti od nas traže da omogućimo pristup Kubernetes klasteru kako bi mogli pristupiti uslugama unutar klastera: kako bi se mogli izravno povezati s nekom bazom podataka ili servisom, kako bi povezali lokalnu aplikaciju s aplikacijama unutar klastera...
Na primjer, postoji potreba za povezivanjem s vašeg lokalnog računala na uslugu memcached.staging.svc.cluster.local. Ovu mogućnost pružamo pomoću VPN-a unutar klastera na koji se klijent povezuje. Da bismo to učinili, klijentu najavljujemo podmreže podova, usluge i DNS klastera. Dakle, kada se klijent pokuša spojiti na uslugu memcached.staging.svc.cluster.local, zahtjev ide u DNS klastera i kao odgovor prima adresu ove usluge iz mreže servisa klastera ili adresu pod-a.
Konfiguriramo K8s klastere koristeći kubeadm, gdje je zadana servisna podmreža 192.168.0.0/16, a mreža mahuna je 10.244.0.0/16. Obično sve radi dobro, ali postoji nekoliko točaka:
Podmreža 192.168.*.* često se koristi u mrežama ureda klijenata, a još češće u kućnim mrežama programera. I onda dobijemo sukobe: kućni usmjerivači rade na ovoj podmreži, a VPN gura te podmreže iz klastera u klijenta.
Imamo nekoliko klastera (produkcija, faza i/ili nekoliko dev klastera). Tada će svi oni prema zadanim postavkama imati iste podmreže za podove i servise, što stvara velike poteškoće za istovremeni rad sa servisima u nekoliko klastera.
Odavno smo usvojili praksu korištenja različitih podmreža za usluge i podove unutar jednog projekta – općenito, tako da svi klasteri imaju različite mreže. Međutim, postoji velik broj klastera u funkciji koje ne bih želio ispočetka mijenjati, budući da pokreću mnoge usluge, aplikacije sa statusom itd.
I onda smo se zapitali: kako promijeniti podmrežu u postojećem klasteru?
Traženje odluka
Najčešća praksa je ponovno stvaranje sve usluge tipa ClusterIP. Kao opciju, može savjetovati i to:
Sljedeći proces ima problem: nakon što je sve konfigurirano, moduli dolaze sa starim IP-om kao DNS poslužiteljem imena u /etc/resolv.conf.
Budući da još uvijek nisam pronašao rješenje, morao sam resetirati cijeli klaster pomoću kubeadm reset i ponovno ga pokrenuti.
Ali ovo nije prikladno za svakoga... Evo detaljnijih uvoda za naš slučaj:
Koristi se flanel;
Postoje klasteri iu oblacima i na hardveru;
Želio bih izbjeći ponovnu implementaciju svih usluga u klasteru;
Općenito je potrebno učiniti sve s minimalnim brojem problema;
Verzija Kubernetesa je 1.16.6 (međutim, daljnji koraci bit će slični za druge verzije);
Glavni zadatak je osigurati da u klasteru koji se koristi kubeadm s servisnom podmrežom 192.168.0.0/16, zamijenite ga s 172.24.0.0/16.
I slučajno se dogodilo da nas je dugo zanimalo što i kako se u Kubernetesu pohranjuje u etcd, što se s tim može učiniti... Pa smo pomislili: “Zašto jednostavno ne ažurirati podatke u etcd, zamjenjujući stare IP adrese (subnet) novima? "
Nakon što smo tražili gotove alate za rad s podacima u itd., nismo pronašli ništa što bi u potpunosti riješilo problem. (Usput, ako znate za bilo kakve pomoćne programe za rad s podacima izravno u itd., cijenili bismo veze.) Međutim, dobro polazište je etcdhelper iz OpenShift-a(hvala njegovim autorima!).
Ovaj se uslužni program može spojiti na etcd pomoću certifikata i čitati podatke odatle pomoću naredbi ls, get, dump.
Dodaj etcdhelper
Sljedeća misao je logična: "Što vas sprječava da dodate ovaj uslužni program dodavanjem mogućnosti pisanja podataka u etcd?"
Postao je modificirana verzija etcdhelpera s dvije nove funkcije changeServiceCIDR и changePodCIDR. na njoj možete vidjeti kod здесь.
Što rade nove značajke? Algoritam changeServiceCIDR:
stvoriti deserializator;
sastaviti regularni izraz za zamjenu CIDR-a;
prolazimo kroz sve usluge s tipom ClusterIP u klasteru:
dekodirati vrijednost iz etcd u Go objekt;
korištenjem regularnog izraza zamjenjujemo prva dva bajta adrese;
dodijelite servisu IP adresu iz nove podmreže;
stvoriti serijalizator, pretvoriti Go objekt u protobuf, napisati nove podatke u itd.
Funkcija changePodCIDR bitno slični changeServiceCIDR - samo umjesto uređivanja specifikacije usluge, mi to radimo za čvor i mijenjamo .spec.PodCIDR na novu podmrežu.
Praksa
Promjena usluge CIDR
Plan za provedbu zadatka je vrlo jednostavan, ali uključuje prekid rada dok se sve jedinice u klasteru ponovno kreiraju. Nakon opisa glavnih koraka, također ćemo podijeliti razmišljanja o tome kako se, u teoriji, ovaj zastoj može svesti na minimum.
Pripremni koraci:
instaliranje potrebnog softvera i sastavljanje zakrpanog etcdhelpera;
sigurnosna kopija itd. i /etc/kubernetes.
Kratki akcijski plan za promjenu serviceCIDR-a:
mijenjanje manifesta apiservera i kontrolera-upravitelja;
Štedimo za sebe etcdhelper.go, preuzimanje ovisnosti, prikupljanje:
wget https://raw.githubusercontent.com/flant/examples/master/2020/04-etcdhelper/etcdhelper.go
go get go.etcd.io/etcd/clientv3 k8s.io/kubectl/pkg/scheme k8s.io/apimachinery/pkg/runtime
go build -o etcdhelper etcdhelper.go
4. Promijenite servisnu podmrežu u manifestima kontrolne ravnine Kubernetes. U datotekama /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml promijeniti parametar --service-cluster-ip-range na novu podmrežu: 172.24.0.0/16 umjesto 192.168.0.0/16.
5. Budući da mijenjamo servisnu podmrežu na koju kubeadm izdaje certifikate za apiserver (uključujući), potrebno ih je ponovno izdati:
Pogledajmo za koje domene i IP adrese je izdan trenutni certifikat:
openssl x509 -noout -ext subjectAltName </etc/kubernetes/pki/apiserver.crt
X509v3 Subject Alternative Name:
DNS:dev-1-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:apiserver, IP Address:192.168.0.1, IP Address:10.0.0.163, IP Address:192.168.199.100
Upozorenje! U ovom trenutku razlučivost domene prestaje raditi u klasteru, jer u postojećim podovima /etc/resolv.conf registrirana je stara CoreDNS adresa (kube-dns), a kube-proxy mijenja iptables pravila sa stare podmreže na novu. Dalje u članku piše se o mogućim opcijama za smanjenje vremena zastoja.
Popravimo ConfigMap u prostoru imena kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- zamijenite ovdje clusterDNS na novu IP adresu usluge kube-dns: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- mi ćemo to popraviti data.ClusterConfiguration.networking.serviceSubnet na novu podmrežu.
Budući da se kube-dns adresa promijenila, potrebno je ažurirati kubelet konfiguraciju na svim čvorovima:
Sve što preostaje je ponovno pokrenuti sve mahune u klasteru:
kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'
Smanjite vrijeme zastoja
Razmišljanja o tome kako minimizirati vrijeme zastoja:
Nakon promjene manifesta kontrolne ravnine, stvorite novu kube-dns uslugu, na primjer, s imenom kube-dns-tmp i nova adresa 172.24.0.10.
napraviti if u etcdhelperu, koji neće modificirati uslugu kube-dns.
Zamijenite adresu u svim kubeletima ClusterDNS na novu, dok će stara usluga nastaviti raditi istovremeno s novom.
Pričekajte dok se kapsule s aplikacijama ne prevrnu same od sebe iz prirodnih razloga ili u dogovoreno vrijeme.
Izbriši uslugu kube-dns-tmp i promijeniti serviceSubnetCIDR za uslugu kube-dns.
Ovaj plan će vam omogućiti da minimizirate vrijeme prekida rada na ~ minutu - za vrijeme trajanja uklanjanja usluge kube-dns-tmp i mijenjanje podmreže za uslugu kube-dns.
Modifikacija podNetwork
U isto vrijeme, odlučili smo pogledati kako modificirati podNetwork pomoću rezultirajućeg etcdhelpera. Slijed radnji je sljedeći:
popravljanje konfiguracija kube-system;
popravljanje manifesta kube-controller-manager;
promijenite podCIDR izravno u etcd;
ponovno pokrenite sve čvorove klastera.
Sada više o ovim akcijama:
1. Izmijenite ConfigMaps u prostoru naziva kube-system:
kubectl -n kube-system edit cm kubeadm-config
- ispravljanje data.ClusterConfiguration.networking.podSubnet na novu podmrežu 10.55.0.0/16.
6. Ponovno pokrenimo sve čvorove klastera jedan po jedan.
7. Ako napustite barem jedan čvor stari podCIDR, tada se kube-controller-manager neće moći pokrenuti, a moduli u klasteru neće biti zakazani.
Zapravo, mijenjanje podCIDR-a može se učiniti još jednostavnije (npr. tako). Ali željeli smo naučiti kako izravno raditi s etcd-om, jer postoje slučajevi kada se Kubernetes objekti uređuju u etcd-u - jedini moguća varijanta. (Na primjer, ne možete samo promijeniti polje usluge bez prekida rada spec.clusterIP.)
Ukupan
U članku se govori o mogućnosti izravnog rada s podacima u etcd-u, tj. zaobilazeći Kubernetes API. Ponekad vam ovaj pristup omogućuje da radite "škakljive stvari". Operacije navedene u tekstu testirali smo na stvarnim klasterima K8s. Međutim, njihov status spremnosti za široku upotrebu jest PoC (dokaz koncepta). Stoga, ako želite koristiti modificiranu verziju uslužnog programa etcdhelper na svojim klasterima, učinite to na vlastitu odgovornost.