ProHoster > Blog > Uprava > Naše izkušnje s podatki v gruči etcd Kubernetes neposredno (brez API-ja K8s)
Naše izkušnje s podatki v gruči etcd Kubernetes neposredno (brez API-ja K8s)
Vse pogosteje nas naročniki prosijo, da jim omogočimo dostop do gruče Kubernetes, da lahko dostopamo do storitev znotraj gruče: da se lahko neposredno povežemo z neko bazo ali storitvijo, da povežemo lokalno aplikacijo z aplikacijami znotraj gruče ...
Na primer, obstaja potreba po povezavi z vašega lokalnega računalnika na storitev memcached.staging.svc.cluster.local. To možnost zagotavljamo z uporabo VPN znotraj gruče, na katero se odjemalec poveže. Da bi to naredili, odjemalcu objavimo podomrežja podov, storitev in DNS potisne gruče. Torej, ko se odjemalec poskuša povezati s storitvijo memcached.staging.svc.cluster.local, gre zahteva v DNS gruče in kot odgovor prejme naslov te storitve iz omrežja storitev gruče ali naslov pod.
Konfiguriramo gruče K8s z uporabo kubeadm, kjer je privzeto servisno podomrežje 192.168.0.0/16, mreža pods pa je 10.244.0.0/16. Ponavadi vse deluje dobro, vendar obstaja nekaj točk:
Podomrežje 192.168.*.* pogosto uporablja v pisarniških omrežjih strank in še pogosteje v domačih omrežjih razvijalcev. In potem pride do konfliktov: domači usmerjevalniki delujejo v tem podomrežju in VPN potisne ta podomrežja iz gruče v odjemalca.
Imamo več grozdov (production, stage in/ali več dev grozdov). Potem bodo privzeto vsi imeli enaka podomrežja za pode in storitve, kar ustvarja velike težave pri hkratnem delu s storitvami v več grozdih.
Že zdavnaj smo sprejeli prakso uporabe različnih podomrežij za storitve in pode znotraj istega projekta – na splošno tako, da imajo vsi grozdi različna omrežja. Vendar pa deluje veliko število gruč, ki jih ne bi želel prenoviti iz nič, saj izvajajo številne storitve, aplikacije s stanjem itd.
In potem smo se vprašali: kako spremeniti podomrežje v obstoječi gruči?
Iskanje odločitev
Najpogostejša praksa je poustvarjanje Vsi storitev tipa ClusterIP. Kot možnost, lahko svetuje in to:
Naslednji postopek ima težavo: ko je vse konfigurirano, pods prikažejo stari IP kot imenski strežnik DNS v /etc/resolv.conf.
Ker še vedno nisem našel rešitve, sem moral ponastaviti celotno gručo s kubeadm reset in jo znova zagnati.
Vendar to ni primerno za vsakogar ... Tukaj je podrobnejši uvod za naš primer:
Uporablja se flanel;
Grozdi so tako v oblakih kot na strojni opremi;
Rad bi se izognil ponovni umestitvi vseh storitev v gruči;
Na splošno je treba narediti vse z minimalnim številom težav;
Različica Kubernetes je 1.16.6 (vendar bodo nadaljnji koraki podobni za druge različice);
Glavna naloga je zagotoviti, da je v gruči, razporejeni z uporabo kubeadm, s servisnim podomrežjem 192.168.0.0/16, ga nadomestite z 172.24.0.0/16.
In zgodilo se je, da nas je že dolgo zanimalo, kaj in kako je v Kubernetesu shranjeno v etcd, kaj je mogoče narediti s tem ... Pa smo pomislili: “Zakaj ne bi preprosto posodobili podatkov v etcd in zamenjali stare naslove IP (podomrežje) z novimi? "
Ko smo iskali že pripravljena orodja za delo s podatki v etcd, nismo našli ničesar, kar bi popolnoma rešilo težavo. (Mimogrede, če poznate kakšne pripomočke za delo s podatki neposredno v etcd, bomo cenili povezave.) Vendar pa je dobro izhodišče etcdhelper iz OpenShift(hvala avtorjem!).
Ta pripomoček se lahko poveže z etcd z uporabo potrdil in bere podatke od tam z uporabo ukazov ls, get, dump.
Dodaj etcdhelper
Naslednja misel je logična: "Kaj vam preprečuje, da dodate ta pripomoček tako, da dodate možnost zapisovanja podatkov v etcd?"
Postal je spremenjena različica etcdhelperja z dvema novima funkcijama changeServiceCIDR и changePodCIDR. na njej si lahko ogledate kodo tukaj.
Kaj počnejo nove funkcije? Algoritem changeServiceCIDR:
ustvarite deserializator;
prevedite regularni izraz za zamenjavo CIDR;
gremo skozi vse storitve s tipom ClusterIP v gruči:
dekodirajte vrednost iz etcd v objekt Go;
z uporabo regularnega izraza zamenjamo prva dva bajta naslova;
storitvi dodeli naslov IP iz novega podomrežja;
ustvarite serializator, pretvorite objekt Go v protobuf, zapišite nove podatke v itd.
Funkcija changePodCIDR v bistvu podobni changeServiceCIDR - le da namesto urejanja specifikacije storitve to naredimo za vozlišče in spremembo .spec.PodCIDR v novo podomrežje.
Practice
Spremenite storitev CIDR
Načrt za izvedbo naloge je zelo preprost, vendar vključuje izpade v času ponovne izdelave vseh podov v gruči. Po opisu glavnih korakov bomo delili tudi misli o tem, kako je teoretično mogoče te izpade zmanjšati.
Pripravljalni koraki:
namestitev potrebne programske opreme in sestavljanje popravljenega etcdhelperja;
varnostno kopiranje itd. in /etc/kubernetes.
Kratek akcijski načrt za spremembo storitve CIDR:
spreminjanje manifestov apiserver in controller-manager;
Varčujemo zase etcdhelper.go, prenesite odvisnosti, zberite:
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. Spremenite storitveno podomrežje v manifestih nadzorne ravnine Kubernetes. V datotekah /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml spremenite parameter --service-cluster-ip-range v novo podomrežje: 172.24.0.0/16 namesto 192.168.0.0/16.
5. Ker spreminjamo storitveno podomrežje, kateremu kubeadm izdaja potrdila za apiserver (vključno), jih je treba ponovno izdati:
Poglejmo, za katere domene in naslove IP je bil 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
Opozorilo! V tem trenutku razrešitev domene preneha delovati v gruči, saj v obstoječih sklopih /etc/resolv.conf stari naslov CoreDNS (kube-dns) je registriran, kube-proxy pa spremeni pravila iptables iz starega podomrežja v novo. Nadalje v članku je napisano o možnih možnostih za zmanjšanje izpadov.
Popravimo ConfigMap v imenskem prostoru kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- zamenjajte tukaj clusterDNS na nov naslov IP storitve kube-dns: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- bomo popravili data.ClusterConfiguration.networking.serviceSubnet v novo podomrežje.
Ker se je naslov kube-dns spremenil, je treba posodobiti konfiguracijo kubeleta na vseh vozliščih:
Vse, kar ostane, je, da znova zaženete vse pode v gruči:
kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'
Zmanjšajte izpade
Razmišljanja o tem, kako zmanjšati čas nedelovanja:
Ko spremenite manifeste nadzorne ravnine, ustvarite novo storitev kube-dns, na primer z imenom kube-dns-tmp in nov naslov 172.24.0.10.
Naredi if v etcdhelperju, ki ne bo spremenil storitve kube-dns.
Zamenjajte naslov v vseh kubeletih ClusterDNS na novo, medtem ko bo stara storitev delovala sočasno z novo.
Počakajte, da se stroki z aplikacijami prevrnejo sami iz naravnih razlogov ali ob dogovorjenem času.
Izbriši storitev kube-dns-tmp in spremeniti serviceSubnetCIDR za storitev kube-dns.
Ta načrt vam bo omogočil, da zmanjšate čas nedelovanja na ~ minuto - za čas odstranitve storitve kube-dns-tmp in spreminjanje podomrežja za storitev kube-dns.
Sprememba podNetwork
Hkrati smo se odločili pogledati, kako spremeniti podNetwork z uporabo nastalega etcdhelperja. Zaporedje dejanj je naslednje:
popravljanje konfiguracij kube-system;
popravljanje manifesta kube-controller-manager;
spremenite podCIDR neposredno v etcd;
znova zaženite vsa vozlišča gruče.
Zdaj pa več o teh dejanjih:
1. Spremenite ConfigMap v imenskem prostoru kube-system:
kubectl -n kube-system edit cm kubeadm-config
- popravljanje data.ClusterConfiguration.networking.podSubnet v novo podomrežje 10.55.0.0/16.
6. Ponovno zaženimo vsa vozlišča gruče enega za drugim.
7. Če zapustite vsaj eno vozlišče stari podCIDR, potem se kube-controller-manager ne bo mogel zagnati in podi v gruči ne bodo načrtovani.
Pravzaprav je spreminjanje podCIDR mogoče narediti celo preprosteje (npr. Tako). Želeli pa smo se naučiti, kako neposredno delati z etcd, ker obstajajo primeri, ko urejamo predmete Kubernetes v etcd - edini možna varianta. (Na primer, ne morete samo spremeniti polja storitve brez izpadov spec.clusterIP.)
Skupaj
Članek obravnava možnost neposrednega dela s podatki v etcd, tj. mimo API-ja Kubernetes. Včasih vam ta pristop omogoča "zapletene stvari". Operacije, navedene v besedilu, smo preizkusili na realnih gručah K8s. Vendar pa je njihov status pripravljenosti za široko uporabo PoC (dokaz koncepta). Zato, če želite uporabiti spremenjeno različico pripomočka etcdhelper na svojih gručah, to storite na lastno odgovornost.