Kokemuksemme datasta etcd Kubernetes -klusterissa suoraan (ilman K8s APIa)
Yhä useammin asiakkaat pyytävät meiltä pääsyä Kubernetes-klusteriin, jotta he voivat käyttää klusterin palveluita: jotta he voivat muodostaa suoran yhteyden johonkin tietokantaan tai palveluun, yhdistää paikallisen sovelluksen klusterin sovelluksiin...
On esimerkiksi tarpeen muodostaa yhteys paikalliselta koneeltasi palveluun memcached.staging.svc.cluster.local. Tarjoamme tämän ominaisuuden käyttämällä VPN:ää klusterin sisällä, johon asiakas muodostaa yhteyden. Tätä varten ilmoitamme asiakkaalle podien, palveluiden ja push-klusterin DNS-aliverkot. Näin ollen, kun asiakas yrittää muodostaa yhteyden palveluun memcached.staging.svc.cluster.local, pyyntö menee klusterin DNS:lle ja vastaanottaa vastauksena tämän palvelun osoitteen klusterin palveluverkosta tai pod-osoitteesta.
Konfiguroimme K8s-klusterit kubeadm-ohjelmalla, jossa oletuspalvelun aliverkko on 192.168.0.0/16, ja podien verkosto on 10.244.0.0/16. Yleensä kaikki toimii hyvin, mutta on pari kohtaa:
Aliverkko 192.168.*.* käytetään usein asiakastoimistoverkoissa ja vielä useammin kehittäjien kotiverkoissa. Ja sitten saamme ristiriitoja: kotireitittimet toimivat tässä aliverkossa ja VPN työntää nämä aliverkot klusterista asiakkaalle.
Meillä on useita klustereita (tuotanto-, vaihe- ja/tai useita kehittäjäklustereita). Tällöin kaikilla niillä on oletusarvoisesti samat aliverkot podille ja palveluille, mikä vaikeuttaa useiden klustereiden samanaikaista työtä.
Olemme jo kauan sitten omaksuneet käytännön käyttää eri aliverkkoja palveluille ja podille saman projektin sisällä - yleisesti ottaen siten, että kaikilla klustereilla on erilaiset verkot. Toiminnassa on kuitenkin suuri määrä klustereita, joita en haluaisi siirtää tyhjästä, koska ne tarjoavat monia palveluita, tilallisia sovelluksia jne.
Ja sitten kysyimme itseltämme: kuinka muuttaa aliverkkoa olemassa olevassa klusterissa?
Päätösten etsiminen
Yleisin käytäntö on luoda uudelleen kaikki palvelut, joiden tyyppi on ClusterIP. Vaihtoehtona osaa neuvoa ja tämä:
Seuraavassa prosessissa on ongelma: kun kaikki on määritetty, podit keksivät vanhan IP-osoitteen DNS-nimipalvelimeksi tiedostossa /etc/resolv.conf.
Koska en vieläkään löytänyt ratkaisua, minun piti nollata koko klusteri kubeadm resetillä ja käynnistää se uudelleen.
Mutta tämä ei sovi kaikille... Tässä on tarkemmat esittelyt tapauksemme:
Flanellia käytetään;
Klustereita on sekä pilvissä että laitteistossa;
Haluaisin välttää kaikkien klusterin palveluiden käyttöönoton uudelleen;
Yleensä kaikki on tehtävä mahdollisimman pienellä määrällä ongelmia;
Kubernetes-versio on 1.16.6 (mutta jatkovaiheet ovat samanlaisia muissa versioissa);
Päätehtävänä on varmistaa, että klusterissa on otettu käyttöön kubeadm ja palvelun aliverkko 192.168.0.0/16, korvaa se 172.24.0.0/16.
Ja niin sattui, että olimme pitkään olleet kiinnostuneita näkemään, mitä ja miten Kubernetesissa etcd:ssä on tallennettu, mitä sillä voi tehdä... Joten ajattelimme: ”Miksi ei vain päivittää etcd:n tiedot korvaamalla vanhat IP-osoitteet (aliverkko) uusilla? "
Etsiessämme valmiita työkaluja tietojen käsittelyyn etcd:ssä emme löytäneet mitään, mikä olisi täysin ratkaissut ongelman. (Muuten, jos tiedät apuohjelmia tietojen käsittelyyn suoraan etcd:ssä, olisimme kiitollisia linkeistä.) Hyvä lähtökohta on kuitenkin etcdhelper OpenShiftistä(kiitos sen tekijöille!).
Tämä apuohjelma voi muodostaa yhteyden etcd:hen sertifikaattien avulla ja lukea tietoja sieltä komentojen avulla ls, get, dump.
Lisää etcdhelper
Seuraava ajatus on looginen: "Mikä estää sinua lisäämästä tätä apuohjelmaa lisäämällä mahdollisuuden kirjoittaa tietoja etcd:hen?"
Siitä tuli muunneltu versio etcdhelperistä kahdella uudella toiminnolla changeServiceCIDR и changePodCIDR. hänen päällänsä näet koodin täällä.
Mitä uudet ominaisuudet tekevät? Algoritmi changeServiceCIDR:
luo deserialisoija;
kääntää säännöllinen lauseke korvaamaan CIDR;
käymme läpi kaikki ClusterIP-tyypin palvelut klusterissa:
purkaa etcd:n arvo Go-objektiksi;
säännöllisen lausekkeen avulla korvaamme osoitteen kaksi ensimmäistä tavua;
määritä palvelulle IP-osoite uudesta aliverkosta;
Luomme serialisaattorin, muunnamme Go-objektin protobufiksi, kirjoitamme uusia tietoja etcd:hen.
Toiminto changePodCIDR olennaisesti samanlaisia changeServiceCIDR - vain sen sijaan, että muokkaamme palvelumäärittelyä, teemme sen solmulle ja vaihdamme .spec.PodCIDR uuteen aliverkkoon.
Käytäntö
Vaihda palvelu CIDR
Suunnitelma tehtävän toteuttamiseksi on hyvin yksinkertainen, mutta siihen sisältyy seisokkeja, kun kaikki klusterin podit luodaan uudelleen. Päävaiheiden kuvauksen jälkeen jaamme myös ajatuksia siitä, kuinka tämä seisokki voidaan teoriassa minimoida.
Valmistelevat vaiheet:
tarvittavien ohjelmistojen asentaminen ja korjatun etcdhelperin kokoaminen;
varmuuskopio jne. ja /etc/kubernetes.
Lyhyt toimintasuunnitelma palvelun CIDR:n muuttamiseen:
apiserver- ja controller-manager-luetteloiden muuttaminen;
todistusten uudelleen myöntäminen;
ClusterIP-palvelujen muuttaminen etcd:ssä;
käynnistä kaikki klusterin podit uudelleen.
Seuraava on täydellinen toimintosarja yksityiskohtaisesti.
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. Muuta palvelun aliverkkoa Kubernetes-ohjaustason luetteloissa. Tiedostoissa /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml muuta parametria --service-cluster-ip-range uuteen aliverkkoon: 172.24.0.0/16 sen sijasta 192.168.0.0/16.
5. Koska muutamme palvelun aliverkkoa, jolle kubeadm myöntää varmenteita apiserverille (mukaan lukien), ne on myönnettävä uudelleen:
Katsotaanpa, mille toimialueille ja IP-osoitteille nykyinen varmenne on myönnetty:
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
Varoitus! Tällä hetkellä verkkotunnuksen resoluutio lakkaa toimimasta klusterissa, koska olemassa olevissa podissa /etc/resolv.conf vanha CoreDNS-osoite (kube-dns) rekisteröidään, ja kube-proxy muuttaa iptables-säännöt vanhasta aliverkosta uuteen. Lisäksi artikkelissa kirjoitetaan mahdollisista vaihtoehdoista seisokkien minimoimiseksi.
Korjataan ConfigMap nimiavaruudessa kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- vaihda tähän clusterDNS kube-dns-palvelun uuteen IP-osoitteeseen: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- korjaamme sen data.ClusterConfiguration.networking.serviceSubnet uuteen aliverkkoon.
Koska kube-dns-osoite on muuttunut, on tarpeen päivittää kubelet-kokoonpano kaikissa solmuissa:
6. Käynnistetään uudelleen kaikki klusterin solmut yksitellen.
7. Jos jätät vähintään yhden solmun vanha podCIDR, silloin kube-controller-manager ei voi käynnistyä eikä klusterin podeja ajoiteta.
Itse asiassa podCIDR:n muuttaminen voidaan tehdä vieläkin yksinkertaisemmin (esim. niin). Mutta halusimme oppia työskentelemään etcd:n kanssa suoraan, koska on tapauksia, joissa Kubernetes-objekteja muokataan etcd:ssä - ainoa mahdollinen variantti. (Et esimerkiksi voi muuttaa vain Palvelu-kenttää ilman seisokkeja spec.clusterIP.)
Koko
Artikkelissa käsitellään mahdollisuutta työskennellä datan kanssa etcd:ssä suoraan, ts. ohittamalla Kubernetes API. Joskus tämä lähestymistapa antaa sinun tehdä "hankalia asioita". Testasimme tekstissä annettuja operaatioita oikeilla K8s-klustereilla. Niiden tila on kuitenkin valmiina laajaan käyttöön PoC (konseptin todiste). Siksi, jos haluat käyttää muokattua versiota etcdhelper-apuohjelmasta klustereissasi, tee se omalla vastuullasi.