Mūsų patirtis naudojant duomenis etcd Kubernetes klasteryje tiesiogiai (be K8s API)
Vis dažniau klientai prašo suteikti prieigą prie Kubernetes klasterio, kad galėtume pasiekti paslaugas klasteryje: kad būtų galima tiesiogiai prisijungti prie kokios nors duomenų bazės ar paslaugos, sujungti vietinę programą su klasteryje esančiomis programomis...
Pavyzdžiui, iš vietinio įrenginio reikia prisijungti prie paslaugos memcached.staging.svc.cluster.local. Šią galimybę teikiame naudodami VPN klasteryje, prie kurio prisijungia klientas. Norėdami tai padaryti, klientui pranešame apie podiklių, paslaugų ir klasterio DNS potinklius. Taigi, kai klientas bando prisijungti prie paslaugos memcached.staging.svc.cluster.local, užklausa siunčiama į klasterio DNS ir atsakant gauna šios paslaugos adresą iš klasterio paslaugų tinklo arba pod adreso.
K8s grupes sukonfigūruojame naudodami kubeadm, kur yra numatytasis paslaugų potinklis 192.168.0.0/16, o ankščių tinklas yra 10.244.0.0/16. Paprastai viskas veikia gerai, tačiau yra keletas dalykų:
Potinklis 192.168.*.* dažnai naudojamas klientų biurų tinkluose, o dar dažniau – kūrėjų namų tinkluose. Ir tada mes gauname konfliktų: namų maršrutizatoriai dirba šiame potinklyje, o VPN perkelia šiuos potinklius iš klasterio į klientą.
Turime keletą grupių (gamybos, scenos ir (arba) kelių kūrėjų grupių). Tada pagal numatytuosius nustatymus visi jie turės tuos pačius podų ir paslaugų potinklius, o tai sukuria didelių sunkumų dirbant vienu metu su paslaugomis keliose grupėse.
Mes jau seniai pritaikėme praktiką naudoti skirtingus potinklius paslaugoms ir podiams tame pačiame projekte – apskritai, kad visos klasteriai turėtų skirtingus tinklus. Tačiau veikia daug klasterių, kurių nenorėčiau perkelti nuo nulio, nes juose veikia daug paslaugų, būsenos programų ir pan.
Ir tada mes paklausėme savęs: kaip pakeisti potinklį esamame klasteryje?
Sprendimų paieška
Dažniausia praktika – atkurti visi paslaugas su tipu ClusterIP. Kaip pasirinkimas, gali patarti ir šis:
Šis procesas turi problemą: viską sukonfigūravus, ankštys pateikia seną IP kaip DNS vardų serverį /etc/resolv.conf.
Kadangi vis dar neradau sprendimo, turėjau iš naujo nustatyti visą klasterį su kubeadm reset ir vėl jį įvesti.
Bet tai tinka ne visiems... Čia yra išsamesnės mūsų atvejo įvadai:
Naudojama flanelė;
Yra grupių ir debesyse, ir aparatinėje įrangoje;
Norėčiau išvengti visų klasterio paslaugų perskirstymo;
Apskritai reikia daryti viską su minimaliu problemų skaičiumi;
Kubernetes versija yra 1.16.6 (tačiau tolesni veiksmai bus panašūs ir kitose versijose);
Pagrindinė užduotis yra užtikrinti, kad klasteryje būtų naudojamas kubeadm su paslaugų potinkliu 192.168.0.0/16, pakeiskite jį 172.24.0.0/16.
Ir taip atsitiko, kad mums jau seniai buvo įdomu pamatyti, kas ir kaip Kubernetes yra saugoma etcd, ką su juo galima padaryti... Taigi pagalvojome: “Kodėl gi ne tiesiog atnaujinti etcd duomenų, pakeičiant senus IP adresus (potinklį) naujais? "
Ieškodami paruoštų įrankių darbui su duomenimis etcd, neradome nieko, kas visiškai išspręstų problemą. (Beje, jei žinote kokių nors paslaugų, skirtų darbui su duomenimis tiesiogiai etcd, būtume dėkingi už nuorodas.) Tačiau geras atspirties taškas yra etcdhelper iš OpenShift(ačiū jos autoriams!).
Ši programa gali prisijungti prie etcd naudodama sertifikatus ir nuskaityti duomenis iš ten naudodama komandas ls, get, dump.
Pridėti etcdhelper
Kita mintis yra logiška: „Kas trukdo jums pridėti šią priemonę, pridedant galimybę rašyti duomenis į etcd?
Tai tapo modifikuota etcdhelper versija su dviem naujomis funkcijomis changeServiceCIDR и changePodCIDR. ant jos galite pamatyti kodą čia.
Ką daro naujos funkcijos? Algoritmas changeServiceCIDR:
sukurti deserializatorių;
sudaryti reguliariąją išraišką, kuri pakeistų CIDR;
mes atliekame visas paslaugas, kurių klasteryje yra ClusterIP tipas:
dekoduoti reikšmę iš etcd į Go objektą;
naudojant reguliariąją išraišką pakeičiame pirmuosius du adreso baitus;
priskirti paslaugai IP adresą iš naujo potinklio;
sukurti serializatorių, konvertuoti Go objektą į protobuf, įrašyti naujus duomenis į etcd.
Funkcija changePodCIDR iš esmės panašus changeServiceCIDR - tik vietoj paslaugos specifikacijos redagavimo mes tai darome mazgui ir keičiame .spec.PodCIDR į naują potinklį.
Praktika
Pakeiskite paslaugą CIDR
Užduoties įgyvendinimo planas yra labai paprastas, tačiau jis apima prastovą, kai iš naujo sukuriamos visos klasterio ankštys. Aprašę pagrindinius žingsnius, taip pat pasidalinsime mintimis, kaip teoriškai šią prastovą galima sumažinti iki minimumo.
Parengiamieji žingsniai:
reikiamos programinės įrangos įdiegimas ir pataisyto etcdhelper surinkimas;
atsarginė kopija etcd ir /etc/kubernetes.
Trumpas paslaugų CIDR keitimo veiksmų planas:
apiserverio ir valdiklio-vadybininko manifestų keitimas;
Taupome sau etcdhelper.go, atsisiųsti priklausomybes, rinkti:
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. Pakeiskite paslaugų potinklį Kubernetes valdymo plokštumos aprašuose. Failuose /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml pakeisti parametrą --service-cluster-ip-range į naują potinklį: 172.24.0.0/16 vietoj 192.168.0.0/16.
5. Kadangi keičiame paslaugų potinklį, kuriam kubeadm išduoda apiserverio sertifikatus (įskaitant), juos reikia išduoti iš naujo:
Pažiūrėkime, kuriems domenams ir IP adresams buvo išduotas dabartinis sertifikatas:
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
Dėmesio! Šiuo metu domeno skyra nustoja veikti klasteryje, nes esamose grupėse /etc/resolv.conf registruojamas senasis CoreDNS adresas (kube-dns), o kube-proxy pakeičia iptables taisykles iš senojo potinklio į naują. Toliau straipsnyje rašoma apie galimas prastovos sumažinimo galimybes.
Belieka iš naujo paleisti visas klasterio ankštis:
kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'
Sumažinkite prastovos laiką
Mintys, kaip sumažinti prastovos laiką:
Pakeitę valdymo plokštumos aprašus, sukurkite naują kube-dns paslaugą, pavyzdžiui, su pavadinimu kube-dns-tmp ir naujas adresas 172.24.0.10.
Padaryti if programoje etcdhelper, kuri nepakeis kube-dns paslaugos.
Pakeiskite adresą visuose kubeletuose ClusterDNS į naują, o senoji paslauga veiks kartu su nauja.
Palaukite, kol ankštys su aplikacijomis apvirs savaime dėl natūralių priežasčių arba sutartu laiku.
Ištrinti paslaugą kube-dns-tmp ir keisti serviceSubnetCIDR kube-dns paslaugai.
Šis planas leis jums sumažinti prastovos laiką iki ~ minutės per visą paslaugos pašalinimo laikotarpį kube-dns-tmp ir pakeisti paslaugos potinklį kube-dns.
Modifikacija podNetwork
Tuo pačiu metu nusprendėme pažvelgti į tai, kaip modifikuoti podNetwork naudojant gautą etcdhelper. Veiksmų seka yra tokia:
konfigūracijų taisymas kube-system;
kube-controller-manager manifesto taisymas;
pakeisti podCIDR tiesiai į etcd;
iš naujo paleiskite visus klasterio mazgus.
Dabar daugiau apie šiuos veiksmus:
1. Pakeiskite ConfigMap vardų srityje kube-system:
kubectl -n kube-system edit cm kubeadm-config
- pataisyti data.ClusterConfiguration.networking.podSubnet į naują potinklį 10.55.0.0/16.
7. Jei paliksite bent vieną mazgą senas podCIDR, tada kube-controller-manager nepavyks paleisti, o grupės grupės nebus suplanuotos.
Tiesą sakant, podCIDR pakeisti galima dar paprasčiau (pvz., taip). Bet mes norėjome išmokti dirbti su etcd tiesiogiai, nes yra atvejų, kai redaguojame Kubernetes objektus etcd - vienišas galimas variantas. (Pavyzdžiui, jūs negalite tiesiog pakeisti paslaugų lauko be prastovos spec.clusterIP.)
Visas
Straipsnyje aptariama galimybė dirbti su duomenimis etcd tiesiogiai, t.y. apeinant Kubernetes API. Kartais šis metodas leidžia daryti „keblius dalykus“. Tekste pateiktas operacijas išbandėme realiose K8 klasteriuose. Tačiau jų būklė yra parengta plačiai naudoti PoC (koncepcijos įrodymas). Todėl, jei savo grupėse norite naudoti modifikuotą priemonės etcdhelper versiją, darykite tai savo pačių rizika.