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...

Kokemuksemme datasta etcd Kubernetes -klusterissa suoraan (ilman K8s APIa)

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.

1. Asenna etcd-client datavedosta varten:

apt install etcd-client

2. Rakenna etcdhelper:

  • Asenna golang:
    GOPATH=/root/golang
    mkdir -p $GOPATH/local
    curl -sSL https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz | tar -xzvC $GOPATH/local
    echo "export GOPATH="$GOPATH"" >> ~/.bashrc
    echo 'export GOROOT="$GOPATH/local/go"' >> ~/.bashrc
    echo 'export PATH="$PATH:$GOPATH/local/go/bin"' >> ~/.bashrc
  • Säästämme itsellemme etcdhelper.go, lataa riippuvuuksia, kerää:
    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

3. Tee varmuuskopio etcd:

backup_dir=/root/backup
mkdir ${backup_dir}
cp -rL /etc/kubernetes ${backup_dir}
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --endpoints https://192.168.199.100:2379 snapshot save ${backup_dir}/etcd.snapshot

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:

  1. 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
  2. Tehdään kubeadmille minimaalinen konfiguraatio:
    cat kubeadm-config.yaml
    apiVersion: kubeadm.k8s.io/v1beta1
    kind: ClusterConfiguration
    networking:
      podSubnet: "10.244.0.0/16"
      serviceSubnet: "172.24.0.0/16"
    apiServer:
      certSANs:
      - "192.168.199.100" # IP-адрес мастер узла
  3. Poistetaan vanha crt ja avain, koska ilman tätä uutta varmennetta ei myönnetä:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Myönnetään uudelleen varmenteita API-palvelimelle:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Tarkistetaan, että varmenne on myönnetty uudelle aliverkolle:
    openssl x509 -noout -ext subjectAltName </etc/kubernetes/pki/apiserver.crt
    X509v3 Subject Alternative Name:
        DNS:kube-2-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:172.24.0.1, IP Address:10.0.0.163, IP Address:192.168.199.100
  6. Kun olet myöntänyt API-palvelinvarmenteen uudelleen, käynnistä sen säilö uudelleen:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Luodaan kokoonpano uudelleen admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Muokataan tietoja etcd:ssä:
    ./etcdhelper -cacert /etc/kubernetes/pki/etcd/ca.crt -cert /etc/kubernetes/pki/etcd/server.crt -key /etc/kubernetes/pki/etcd/server.key -endpoint https://127.0.0.1:2379 change-service-cidr 172.24.0.0/16 

    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.

  9. 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.

  10. Koska kube-dns-osoite on muuttunut, on tarpeen päivittää kubelet-kokoonpano kaikissa solmuissa:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Jäljelle jää vain käynnistää kaikki klusterin podit uudelleen:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Minimoi seisokit

Ajatuksia seisokkien minimoimiseksi:

  1. Kun olet muuttanut ohjaustason manifesteja, luo uusi kube-dns-palvelu esimerkiksi nimellä kube-dns-tmp ja uusi osoite 172.24.0.10.
  2. tehdä if etddhelperissä, joka ei muuta kube-dns-palvelua.
  3. Korvaa osoite kaikissa kubeleteissa ClusterDNS uuteen, kun taas vanha palvelu jatkaa toimintaansa samanaikaisesti uuden kanssa.
  4. Odota, kunnes applikoidut palot kaatuvat joko itsestään luonnollisista syistä tai sovittuna ajankohtana.
  5. Poista palvelu kube-dns-tmp ja muuttaa serviceSubnetCIDR kube-dns-palvelua varten.

Tämän suunnitelman avulla voit minimoida seisokit ~ minuuttiin - palvelun poiston ajaksi kube-dns-tmp ja palvelun aliverkon muuttaminen kube-dns.

Muutos podNetwork

Samaan aikaan päätimme tarkastella podNetworkin muokkaamista tuloksena olevan etcdhelperin avulla. Toimintojen järjestys on seuraava:

  • asetusten korjaaminen kube-system;
  • kube-controller-manager-luettelon korjaaminen;
  • muuta podCIDR suoraan etcd:ssä;
  • käynnistä kaikki klusterin solmut uudelleen.

Nyt lisää näistä toimista:

1. Muokkaa ConfigMapia nimiavaruudessa kube-system:

kubectl -n kube-system edit cm kubeadm-config

-korjaus data.ClusterConfiguration.networking.podSubnet uuteen aliverkkoon 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

-korjaus data.config.conf.clusterCIDR: 10.55.0.0/16.

2. Muokkaa Controller-Manager-luetteloa:

vim /etc/kubernetes/manifests/kube-controller-manager.yaml

-korjaus --cluster-cidr=10.55.0.0/16.

3. Katso nykyiset arvot .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses kaikille klusterin solmuille:

kubectl get no -o json | jq '[.items[] | {"name": .metadata.name, "podCIDR": .spec.podCIDR, "podCIDRs": .spec.podCIDRs, "InternalIP": (.status.addresses[] | select(.type == "InternalIP") | .address)}]'

[
  {
    "name": "kube-2-master",
    "podCIDR": "10.244.0.0/24",
    "podCIDRs": [
      "10.244.0.0/24"
    ],
    "InternalIP": "192.168.199.2"
  },
  {
    "name": "kube-2-master",
    "podCIDR": "10.244.0.0/24",
    "podCIDRs": [
      "10.244.0.0/24"
    ],
    "InternalIP": "10.0.1.239"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.244.1.0/24",
    "podCIDRs": [
      "10.244.1.0/24"
    ],
    "InternalIP": "192.168.199.222"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.244.1.0/24",
    "podCIDRs": [
      "10.244.1.0/24"
    ],
    "InternalIP": "10.0.4.73"
  }
]

4. Korvaa podCIDR tekemällä muutokset suoraan etcd:hen:

./etcdhelper -cacert /etc/kubernetes/pki/etcd/ca.crt -cert /etc/kubernetes/pki/etcd/server.crt -key /etc/kubernetes/pki/etcd/server.key -endpoint https://127.0.0.1:2379 change-pod-cidr 10.55.0.0/16

5. Tarkistetaan, että podCIDR on todella muuttunut:

kubectl get no -o json | jq '[.items[] | {"name": .metadata.name, "podCIDR": .spec.podCIDR, "podCIDRs": .spec.podCIDRs, "InternalIP": (.status.addresses[] | select(.type == "InternalIP") | .address)}]'

[
  {
    "name": "kube-2-master",
    "podCIDR": "10.55.0.0/24",
    "podCIDRs": [
      "10.55.0.0/24"
    ],
    "InternalIP": "192.168.199.2"
  },
  {
    "name": "kube-2-master",
    "podCIDR": "10.55.0.0/24",
    "podCIDRs": [
      "10.55.0.0/24"
    ],
    "InternalIP": "10.0.1.239"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.55.1.0/24",
    "podCIDRs": [
      "10.55.1.0/24"
    ],
    "InternalIP": "192.168.199.222"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.55.1.0/24",
    "podCIDRs": [
      "10.55.1.0/24"
    ],
    "InternalIP": "10.0.4.73"
  }
]

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.

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti