ProHoster > Blog > podávání > Naše zkušenosti s daty přímo v clusteru etcd Kubernetes (bez K8s API)
Naše zkušenosti s daty přímo v clusteru etcd Kubernetes (bez K8s API)
Stále častěji nás klienti žádají o poskytnutí přístupu ke clusteru Kubernetes, aby měli přístup ke službám v rámci clusteru: abychom se mohli přímo připojit k nějaké databázi nebo službě, abychom propojili lokální aplikaci s aplikacemi v rámci clusteru...
Například je potřeba se z místního počítače připojit ke službě memcached.staging.svc.cluster.local. Tuto možnost poskytujeme pomocí VPN v rámci clusteru, ke kterému se klient připojuje. K tomu klientovi oznamujeme podsítě podů, služeb a push clusteru DNS. Tedy, když se klient pokusí připojit ke službě memcached.staging.svc.cluster.local, požadavek přejde do clusteru DNS a jako odpověď obdrží adresu této služby ze sítě clusterových služeb nebo adresy pod.
Klastry K8s konfigurujeme pomocí kubeadm, kde je výchozí podsíť služeb 192.168.0.0/16, a síť podů je 10.244.0.0/16. Obvykle vše funguje dobře, ale existuje několik bodů:
Podsíť 192.168.*.* často používané v sítích klientských kanceláří a ještě častěji v domácích sítích vývojářů. A pak se dostáváme ke konfliktům: domácí routery fungují na této podsíti a VPN tyto podsítě tlačí z clusteru ke klientovi.
Máme několik clusterů (produkční, etapový a/nebo několik vývojových clusterů). Ve výchozím nastavení pak všechny budou mít stejné podsítě pro pody a služby, což vytváří velké potíže pro současnou práci se službami v několika clusterech.
Již dávno jsme přijali praxi používání různých podsítí pro služby a moduly v rámci stejného projektu – obecně tak, že všechny clustery mají různé sítě. V provozu je však velké množství clusterů, které bych nerad převaloval od nuly, protože na nich běží mnoho služeb, stavových aplikací atd.
A pak jsme si položili otázku: jak změnit podsíť ve stávajícím clusteru?
Hledejte řešení
Nejběžnější praxí je rekreace vše služby typu ClusterIP. Jako možnost může poradit a tohle:
Následující proces má problém: poté, co vše nakonfigurujete, pody přijdou se starou IP jako DNS nameserver v /etc/resolv.conf.
Protože jsem stále nenašel řešení, musel jsem resetovat celý cluster pomocí resetu kubeadm a znovu jej spustit.
To ale není vhodné pro každého... Zde jsou podrobnější úvody pro náš případ:
Používá se flanel;
Existují clustery jak v cloudech, tak na hardwaru;
Rád bych se vyhnul opětovnému nasazení všech služeb v clusteru;
Všeobecně je potřeba dělat vše s minimálním počtem problémů;
Verze Kubernetes je 1.16.6 (další kroky však budou pro ostatní verze podobné);
Hlavním úkolem je zajistit, aby v clusteru nasazeném pomocí kubeadm byla podsíť služeb 192.168.0.0/16, nahraďte jej 172.24.0.0/16.
A tak se stalo, že nás dlouho zajímalo, co a jak je v Kubernetes uloženo v etcd, co se s tím dá dělat... Tak jsme si řekli: “Proč prostě neaktualizovat data v etcd a nahradit staré IP adresy (podsítě) novými? "
Po hledání hotových nástrojů pro práci s daty v etcd jsme nenašli nic, co by problém úplně vyřešilo. (Mimochodem, pokud víte o nějakých utilitách pro práci s daty přímo v etcd, budeme rádi za odkazy.) Nicméně, dobrý výchozí bod je etcdhelper z OpenShift(díky jejím autorům!).
Tento nástroj se může připojit k etcd pomocí certifikátů a číst data odtud pomocí příkazů ls, get, dump.
Přidejte etcdhelper
Další myšlenka je logická: "Co vám brání přidat tento nástroj přidáním možnosti zapisovat data do etcd?"
Stala se upravenou verzí etcdhelper se dvěma novými funkcemi changeServiceCIDR и changePodCIDR. na ní můžete vidět kód zde.
Co dělají nové funkce? Algoritmus changeServiceCIDR:
vytvořit deserializátor;
zkompilovat regulární výraz, který nahradí CIDR;
procházíme všechny služby s typem ClusterIP v clusteru:
dekódovat hodnotu z etcd do objektu Go;
pomocí regulárního výrazu nahradíme první dva bajty adresy;
přiřadit službě IP adresu z nové podsítě;
vytvořit serializátor, převést objekt Go na protobuf, zapsat nová data do etcd.
Funkce changePodCIDR v podstatě podobný changeServiceCIDR - pouze místo úpravy specifikace služby to uděláme pro uzel a změnu .spec.PodCIDR do nové podsítě.
Praxe
Změna služby CIDR
Plán implementace úlohy je velmi jednoduchý, ale zahrnuje prostoje v době opětovného vytvoření všech modulů v clusteru. Po popisu hlavních kroků se také podělíme o myšlenky, jak lze teoreticky tyto prostoje minimalizovat.
Přípravné kroky:
instalace potřebného softwaru a sestavení opraveného etcdhelper;
Šetříme pro sebe etcdhelper.go, stáhnout závislosti, shromáždit:
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. Změňte podsíť služeb v manifestech řídicí roviny Kubernetes. V souborech /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml změnit parametr --service-cluster-ip-range do nové podsítě: 172.24.0.0/16 místo 192.168.0.0/16.
5. Protože měníme podsíť služeb, do které kubeadm vydává certifikáty pro apiserver (včetně), je třeba je znovu vydat:
Podívejme se, pro které domény a IP adresy byl vydán aktuální certifikát:
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
Varování! V tuto chvíli přestává v clusteru fungovat rozlišení domény, protože ve stávajících podech /etc/resolv.conf stará adresa CoreDNS (kube-dns) je zaregistrována a kube-proxy změní pravidla iptables ze staré podsítě na novou. Dále se v článku píše o možných možnostech minimalizace prostojů.
Opravme ConfigMap ve jmenném prostoru kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- vyměňte zde clusterDNS na novou IP adresu služby kube-dns: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- opravíme to data.ClusterConfiguration.networking.serviceSubnet do nové podsítě.
Protože se adresa kube-dns změnila, je nutné aktualizovat konfiguraci kubelet na všech uzlech:
6. Restartujme všechny uzly clusteru jeden po druhém.
7. Pokud ponecháte alespoň jeden uzel starý podCIDR, pak se kube-controller-manager nebude moci spustit a pody v clusteru nebudou naplánovány.
Ve skutečnosti lze změnu podCIDR provést ještě jednodušeji (např. tak). Chtěli jsme se ale naučit pracovat s etcd přímo, protože existují případy, kdy editujete Kubernetes objekty v etcd - jediný možná varianta. (Například nemůžete jen změnit pole Služba bez výpadku spec.clusterIP.)
Celkový
Článek pojednává o možnosti práce s daty v etcd přímo, tzn. obcházení Kubernetes API. Někdy vám tento přístup umožňuje dělat „ošidné věci“. Operace uvedené v textu jsme testovali na skutečných clusterech K8s. Jejich stav připravenosti k širokému použití je však takový PoC (proof of concept). Pokud tedy chcete na svých clusterech používat upravenou verzi utility etcdhelper, činíte tak na vlastní nebezpečí.