ProHoster > Blog > Amministrazione > A nostra sperienza cù dati in eccd Kubernetes cluster direttamente (senza API K8s)
A nostra sperienza cù dati in eccd Kubernetes cluster direttamente (senza API K8s)
Sempre più, i clienti ci dumandanu di furnisce l'accessu à u cluster Kubernetes per pudè accede à i servizii in u cluster: per pudè cunnette direttamente à una basa di dati o serviziu, per cunnette una applicazione locale cù applicazioni in u cluster ...
Per esempiu, ci hè bisognu di cunnette da a vostra macchina locale à un serviziu memcached.staging.svc.cluster.local. Offremu sta capacità utilizendu una VPN in u cluster à quale u cliente si cunnetta. Per fà questu, annunziemu subnets di pods, servizii è push cluster DNS à u cliente. Cusì, quandu un cliente prova à cunnette à u serviziu memcached.staging.svc.cluster.local, a dumanda va à u cluster DNS è in risposta riceve l'indirizzu di stu serviziu da a reta di serviziu di u cluster o l'indirizzu pod.
Cunfiguremu clusters K8s usendu kubeadm, induve a subnet di serviziu predeterminata hè 192.168.0.0/16, è a reta di pods hè 10.244.0.0/16. Di solitu tuttu funziona bè, ma ci sò parechji punti:
Subnet 192.168.*.* spessu usatu in e rete di l'uffiziu di u cliente, è ancu più spessu in e rete di casa di sviluppatore. E poi finiscemu cun cunflitti: i routers di casa travaglianu in questa subnet è a VPN spinge sti subnets da u cluster à u cliente.
Avemu parechji clusters (produzzione, stage è / o parechji dev clusters). Allora, per difettu, tutti averebbenu i stessi subnets per pods è servizii, chì creanu grandi difficultà per u travagliu simultaneo cù servizii in parechji clusters.
Avemu longu aduttatu a pratica di utilizà diverse subnets per servizii è pods in u stessu prughjettu - in generale, per chì tutti i clusters anu rete diverse. Tuttavia, ci sò un gran numaru di clusters in funziunamentu chì ùn vogliu micca vultà da zero, postu chì eseguinu assai servizii, applicazioni stateful, etc.
E poi avemu dumandatu: cumu cambià a subnet in un cluster esistente?
Ricerca di decisioni
A pratica più cumuna hè di ricreà tutte e servizii cù u tipu ClusterIP. Comu opzione, pò cunsiglià è questu:
U prucessu seguente hà un prublema: dopu à tuttu cunfiguratu, i pods venenu cù l'antica IP cum'è un servitore di nome DNS in /etc/resolv.conf.
Siccomu ùn aghju micca trovu a suluzione, aghju avutu à resettate tuttu u cluster cù kubeadm reset è init di novu.
Ma questu ùn hè micca adattatu per tutti... Eccu introduzioni più dettagliate per u nostru casu:
Flannel hè utilizatu;
Ci sò clusters in i nuvuli è in hardware;
Mi piacerebbe evità di ridistribuisce tutti i servizii in u cluster;
Ci hè bisognu di fà in generale tuttu cù un numeru minimu di prublemi;
A versione di Kubernetes hè 1.16.6 (in ogni casu, altri passi seranu simili per altre versioni);
U compitu principale hè di assicurà chì in un cluster implementatu cù kubeadm cù una subnet di serviziu 192.168.0.0/16, rimpiazzà cù 172.24.0.0/16.
È hè accadutu chì eramu longu interessatu à vede ciò chì è cumu in Kubernetes hè almacenatu in etcd, ciò chì si pò fà cun ellu ... Allora avemu pensatu: "Perchè micca solu aghjurnà e dati in etcd, rimpiazzà i vechji indirizzi IP (subnet) cù novi?
Dopu avè cercatu arnesi pronti per travaglià cù dati in etcd, ùn avemu micca truvatu nunda chì risolve u prublema cumplettamente. (Per via, se sapete di qualsiasi utilità per travaglià cù dati direttamente in etcd, apprezzemu i ligami.) Tuttavia, un bonu puntu di partenza hè etcdhelper da OpenShift(grazie à i so autori!).
Questa utilità pò cunnette à etcd cù certificati è leghje e dati da quì cù cumandamenti ls, get, dump.
Aghjunghjite etcdhelper
U prossimu pensamentu hè logicu: "Chì vi impedisce di aghjunghje sta utilità aghjunghjendu a capacità di scrive dati à etcd?"
Hè diventata una versione mudificata di etcdhelper cù duie funzioni novi changeServiceCIDR и changePodCIDR. nantu à ella pudete vede u codice ccà.
Chì facenu i novi funziunalità? Algoritmu changeServiceCIDR:
creà un deserializatore;
compilà una espressione regulare per rimpiazzà CIDR;
andemu per tutti i servizii cù u tipu ClusterIP in u cluster:
decode u valore da etcd in un oggettu Go;
usendu una espressione regulare rimpiazzà i primi dui bytes di l'indirizzu;
assignà u serviziu un indirizzu IP da a nova subnet;
criemu un serializzatore, cunvertisce l'ughjettu Go in protobuf, scrivite novi dati à etcd.
funziunava changePodCIDR essenzialmente simili changeServiceCIDR - solu invece di edità a specificazione di u serviziu, facemu per u node è cambià .spec.PodCIDR à una nova subnet.
Prutizzioni
Cambia u serviziu CIDR
U pianu per l'implementazione di u compitu hè assai simplice, ma implica downtime à u mumentu di a ricreazione di tutti i pods in u cluster. Dopu avè descrittu i passi principali, avemu ancu sparte pinsamenti nantu à cumu, in teoria, stu downtime pò esse minimizatu.
Passi preparatori:
installà u software necessariu è assemblà u etcdhelper patchatu;
backup etcd è /etc/kubernetes.
Breve pianu d'azzione per cambià u serviziu CIDR:
cambià i manifesti apiserver è controller-manager;
riemissione di certificati;
cambià i servizii ClusterIP in etcd;
riavvia tutti i pods in u cluster.
A seguita hè una sequenza cumpleta di l'azzioni in dettagliu.
Salvemu per noi stessi etcdhelper.go, scaricate dipendenze, raccoglie:
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. Cambia a subnet di serviziu in i manifesti di u pianu di cuntrollu di Kubernetes. In i schedari /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml cambià u paràmetru --service-cluster-ip-range à una nova subnet: 172.24.0.0/16 invece di 192.168.0.0/16.
5. Siccomu avemu cambiatu a subnet di serviziu à quale kubeadm emette certificati per apiserver (cumpresu), anu da esse riedutu:
Videmu per quali domini è indirizzi IP u certificatu attuale hè statu emessu:
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
Attenzione! À questu mumentu, a risoluzione di u duminiu ferma di travaglià in u cluster, postu chì in pods esistenti /etc/resolv.conf u vechju indirizzu CoreDNS (kube-dns) hè registratu, è kube-proxy cambia e regule iptables da a vechja subnet à a nova. In più in l'articulu hè scrittu annantu à l'opzioni pussibuli per minimizzà i tempi di inattività.
Fixemu ConfigMap in u spaziu di nomi kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- rimpiazzà quì clusterDNS à u novu indirizzu IP di u serviziu kube-dns: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- l'avemu da riparà data.ClusterConfiguration.networking.serviceSubnet à una nova subnet.
Siccomu l'indirizzu kube-dns hè cambiatu, hè necessariu aghjurnà a cunfigurazione di kubelet in tutti i nodi:
Tuttu ciò chì resta hè di riavvià tutti i pods in u cluster:
kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'
Minimizà i tempi di inattività
Pensieri nantu à cumu minimizzà i tempi di inattività:
Dopu avè cambiatu i manifesti di u pianu di cuntrollu, creanu un novu serviziu kube-dns, per esempiu, cù u nome kube-dns-tmp è novu indirizzu 172.24.0.10.
Fate if in etcdhelper, chì ùn mudificà micca u serviziu kube-dns.
Sustituisce l'indirizzu in tutti i kubelets ClusterDNS à un novu, mentri u vechju serviziu cuntinuà à travaglià simultaneamente cù u novu.
Aspettate finu à chì i baccelli cù l'applicazioni passanu per elli stessi per ragioni naturali o à un tempu accunsentutu.
Sguassà u serviziu kube-dns-tmp è cambia serviceSubnetCIDR per u serviziu kube-dns.
Stu pianu vi permetterà di minimizzà u downtime à ~ un minutu - per a durata di a rimozione di u serviziu kube-dns-tmp è cambià a subnet per u serviziu kube-dns.
Mudificazione podNetwork
À u listessu tempu, avemu decisu di guardà cumu mudificà podNetwork utilizendu u etcdhelper risultatu. A sequenza di l'azzioni hè a siguenti:
riparà e cunfigurazioni in kube-system;
riparà u manifestu kube-controller-manager;
cambia podCIDR direttamente in etcd;
riavvia tutti i nodi di cluster.
Avà più nantu à queste azzioni:
1. Mudificà ConfigMap in u namespace kube-system:
kubectl -n kube-system edit cm kubeadm-config
- currezzione data.ClusterConfiguration.networking.podSubnet à una nova subnet 10.55.0.0/16.
7. Sè vo lascià almenu un node vechju podCIDR, allura kube-controller-manager ùn serà micca pussibule di inizià, è i pods in u cluster ùn saranu micca pianificati.
In fattu, cambià podCIDR pò esse fattu ancu più simplice (per esempiu, tantu). Ma vulemu amparà à travaglià direttamente cù etcd, perchè ci sò casi quandu editate l'uggetti Kubernetes in etcd - u solu varianti pussibuli. (Per esempiu, ùn pudete micca solu cambià u campu di serviziu senza downtime spec.clusterIP.)
U risultatu
L'articulu discute a pussibilità di travaglià cù dati in etcd direttamente, i.e. ignora l'API Kubernetes. Calchì volta stu approcciu vi permette di fà "cose difficili". Avemu pruvatu l'operazioni datu in u testu nantu à i clusters K8s reali. Tuttavia, u so statutu di prontezza per l'usu generalizatu hè PoC (prova di cuncettu). Dunque, sè vo vulete usà una versione mudificata di l'utilità etcdhelper nantu à i vostri clusters, fate cusì à u vostru propiu risicu.