Meie kogemus andmetega etcd Kubernetes'i klastris otse (ilma K8s API-ta)

Üha sagedamini paluvad kliendid meilt võimaldada juurdepääsu Kubernetese klastrile, et pääseda juurde klastrisisesetele teenustele: et saaksime otse mõne andmebaasi või teenusega ühenduse luua, et ühendada kohalik rakendus klastris olevate rakendustega...

Meie kogemus andmetega etcd Kubernetes'i klastris otse (ilma K8s API-ta)

Näiteks on vaja luua ühendus kohalikust masinast teenusega memcached.staging.svc.cluster.local. Pakume seda võimalust VPN-i abil klastris, millega klient ühenduse loob. Selleks anname kliendile teada podide, teenuste ja tõukeklastri DNS-i alamvõrkudest. Seega, kui klient proovib teenusega ühendust luua memcached.staging.svc.cluster.local, pöördub päring klastri DNS-i ja saab vastuseks selle teenuse aadressi klastri teenindusvõrgust või kausta aadressi.

Konfigureerime K8-klastreid kubeadmi abil, kus on vaiketeenuse alamvõrk 192.168.0.0/16, ja kaunade võrk on 10.244.0.0/16. Tavaliselt töötab kõik hästi, kuid on paar punkti:

  • Alamvõrk 192.168.*.* kasutatakse sageli kliendikontorite võrkudes ja veelgi sagedamini arendajate koduvõrkudes. Ja siis tekivad konfliktid: koduruuterid töötavad selles alamvõrgus ja VPN surub need alamvõrgud klastrist kliendile.
  • Meil on mitu klastrit (tootmis-, lava- ja/või mitu arendusklastrit). Siis on vaikimisi kõigil neil podide ja teenuste jaoks samad alamvõrgud, mis tekitab suuri raskusi mitme klastri teenustega samaaegsel töötamisel.

Oleme juba ammu kasutusele võtnud praktika, mille kohaselt kasutame sama projekti raames erinevaid alamvõrke teenuste ja kaubikute jaoks – üldiselt nii, et kõigil klastritel on erinevad võrgud. Siiski on töös suur hulk klastreid, mida ma ei tahaks nullist üle kanda, kuna need käitavad paljusid teenuseid, olekupõhiseid rakendusi jne.

Ja siis küsisime endalt: kuidas olemasolevas klastris alamvõrku muuta?

Otsuste otsimine

Kõige tavalisem praktika on taasloomine kõik ClusterIP tüüpi teenuseid. Võimalusena oskab nõu anda ja see:

Järgmises protsessis on probleem: kui kõik on seadistatud, tulevad kaustadele /etc/resolv.conf DNS-i nimeserverina vana IP-aadress.
Kuna ma ikka lahendust ei leidnud, pidin kogu klastri kubeadm resetiga lähtestama ja uuesti käivitama.

Kuid see ei sobi kõigile... Siin on meie juhtumi täpsemad tutvustused:

  • Kasutatakse flanelli;
  • Klastreid on nii pilvedes kui ka riistvaras;
  • Sooviksin vältida kõigi klastri teenuste ümberpaigutamist;
  • Üldiselt on vaja teha kõike minimaalse arvu probleemidega;
  • Kubernetese versioon on 1.16.6 (teised toimingud on siiski sarnased teiste versioonidega);
  • Peamine ülesanne on tagada, et klastris on juurutatud teenuse alamvõrguga kubeadm 192.168.0.0/16, asendage see 172.24.0.0/16.

Ja juhtus nii, et olime juba ammu huvitanud näha, mida ja kuidas Kuberneteses etcd-s talletatakse, mida sellega teha saab... Nii me siis mõtlesimegi: “Miks mitte lihtsalt värskendada etcd-s olevaid andmeid, asendades vanad IP-aadressid (alamvõrk) uutega? "

Otsides etcd-s andmetega töötamiseks valmis tööriistu, ei leidnud me midagi, mis probleemi täielikult lahendaks. (Muide, kui teate utiliitidest, mis võimaldavad otse jne andmetega töötada, oleksime linkide eest tänulikud.) Siiski on hea lähtepunkt etcdhelper OpenShiftist (aitäh selle autoritele!).

See utiliit saab sertifikaatide abil ühenduse luua etcd-ga ja sealt käskude abil andmeid lugeda ls, get, dump.

Lisage etcdhelper

Järgmine mõte on loogiline: "Mis takistab teil seda utiliiti lisamast, lisades võimaluse andmete kirjutamiseks etcd-sse?"

Sellest sai kahe uue funktsiooniga etcdhelperi modifitseeritud versioon changeServiceCIDR и changePodCIDR. tema peal näed koodi siin.

Mida uued funktsioonid teevad? Algoritm changeServiceCIDR:

  • luua deserialiseerija;
  • koostama regulaaravaldise CIDR-i asendamiseks;
  • läbime kõik klastris oleva ClusterIP-tüüpi teenused:
    • dekodeerida väärtus etcd-st objektiks Go;
    • regulaaravaldise abil asendame aadressi kaks esimest baiti;
    • määrake teenusele uuest alamvõrgust IP-aadress;
    • looge serialiseerija, teisendage objekt Go protobufiks, kirjutage uued andmed jne.

Funktsioon changePodCIDR sisuliselt sarnased changeServiceCIDR - ainult teenuse spetsifikatsiooni muutmise asemel teeme seda sõlme jaoks ja muudame .spec.PodCIDR uude alamvõrku.

Tava

Muutke teenust CIDR

Ülesande rakendamise plaan on väga lihtne, kuid see hõlmab seisakuid kõigi klastri kaunade uuesti loomise ajal. Peale peamiste sammude kirjeldamist jagame ka mõtteid, kuidas teoreetiliselt saaks seda seisakut minimeerida.

Ettevalmistavad sammud:

  • vajaliku tarkvara installimine ja paigatud etcdhelperi kokkupanek;
  • varukoopia jne ja /etc/kubernetes.

Lühike tegevuskava teenuseCIDR muutmiseks:

  • apiserveri ja kontroller-halduri manifestide muutmine;
  • sertifikaatide uuesti väljastamine;
  • ClusterIP teenuste muutmine jne;
  • klastri kõigi kaunade taaskäivitamine.

Allpool on üksikasjalik toimingute jada.

1. Installige andmetõmmise jaoks programm etcd-client:

apt install etcd-client

2. Ehitage etcdhelper:

  • Installige 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äästame enda jaoks etcdhelper.go, laadige alla sõltuvusi, koguge:
    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. Tehke varukoopia jne:

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. Muutke Kubernetese juhttasandi manifestides teenuse alamvõrku. Failides /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml muuta parameetrit --service-cluster-ip-range uude alamvõrku: 172.24.0.0/16 asemel 192.168.0.0/16.

5. Kuna muudame teenuse alamvõrku, millele kubeadm apiserveri jaoks sertifikaate väljastab (kaasa arvatud), tuleb need uuesti välja anda:

  1. Vaatame, millistele domeenidele ja IP-aadressidele on kehtiv sertifikaat välja antud:
    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. Valmistame ette kubeadmi minimaalse konfiguratsiooni:
    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. Kustutame vana crt ja võtme, kuna ilma selleta uut sertifikaati ei väljastata:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Väljastame API serveri sertifikaadid uuesti:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Kontrollime, kas sertifikaat on välja antud uue alamvõrgu jaoks:
    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. Pärast API serveri sertifikaadi uuesti väljastamist taaskäivitage selle konteiner:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Loome konfiguratsiooni uuesti admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Redigeerime etcd-s olevaid andmeid:
    ./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 

    Hoiatus! Praegu lakkab domeeni eraldusvõime klastris töötamast, kuna olemasolevates kaunades /etc/resolv.conf registreeritakse vana CoreDNS-i aadress (kube-dns) ja kube-puhverserver muudab iptablesi reeglid vanast alamvõrgust uueks. Edasi artiklis on kirjutatud võimalikest võimalustest seisakuaja minimeerimiseks.

  9. Parandame ConfigMapi nimeruumis kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - asendage siin clusterDNS kube-dns teenuse uuele IP-aadressile: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - teeme selle korda data.ClusterConfiguration.networking.serviceSubnet uude alamvõrku.

  10. Kuna kube-dns-i aadress on muutunud, on vaja värskendada kubeleti konfiguratsiooni kõigis sõlmedes:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Kõik, mis jääb üle, on taaskäivitada kõik klastri kaunad:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Vähendage seisakuid

Mõtteid seisakuaja minimeerimiseks:

  1. Pärast juhttasandi manifestide muutmist looge uus kube-dns-teenus, näiteks nimega kube-dns-tmp ja uus aadress 172.24.0.10.
  2. Tee if etddhelperis, mis ei muuda teenust kube-dns.
  3. Asendage aadress kõigis kubelites ClusterDNS uude, samas kui vana teenus jätkab tööd samaaegselt uuega.
  4. Oodake, kuni aplikatsiooniga kaunad kas loomulikel põhjustel või kokkulepitud ajal ümber lähevad.
  5. Kustuta teenus kube-dns-tmp ja muuta serviceSubnetCIDR kube-dns teenuse jaoks.

See plaan võimaldab teil teenuse eemaldamise ajaks vähendada seisakuid ~ minutini kube-dns-tmp ja teenuse alamvõrgu muutmine kube-dns.

Modifikatsioon podNetwork

Samal ajal otsustasime vaadata, kuidas modifitseerida podNetworki, kasutades saadud faili etcdhelper. Toimingute jada on järgmine:

  • konfiguratsioonide parandamine kube-system;
  • kube-controller-manager manifesti parandamine;
  • muuta podCIDR-i otse jne;
  • taaskäivitage kõik klastri sõlmed.

Nüüd rohkem nende toimingute kohta:

1. Muutke nimeruumis ConfigMapi kube-system:

kubectl -n kube-system edit cm kubeadm-config

- korrigeerimine data.ClusterConfiguration.networking.podSubnet uude alamvõrku 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

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

2. Muutke kontrolleri-halduri manifesti.

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

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

3. Vaadake praeguseid väärtusi .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses kõigi klastri sõlmede jaoks:

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. Asendage podCIDR, muutes otse faili etcd:

./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. Kontrollime, kas podCIDR on tõesti muutunud:

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. Taaskäivitame kõik klastri sõlmed ükshaaval.

7. Kui jätate vähemalt ühe sõlme vana podCIDR, siis ei saa kube-controller-manager käivituda ja klastris olevaid kaustasid ei ajastata.

Tegelikult saab podCIDR-i muuta veelgi lihtsamalt (näiteks nii). Kuid me tahtsime õppida, kuidas töötada otse etcd-ga, sest Kubernetese objektide redigeerimisel etcd-s on juhtumeid - üksi võimalik variant. (Näiteks ei saa te lihtsalt muuta välja Service ilma seisakuta spec.clusterIP.)

Summaarne

Artiklis käsitletakse võimalust töötada andmetega etcd-s otse, st. Kubernetes API-st mööda minnes. Mõnikord võimaldab see lähenemine teha "keerulisi asju". Testisime tekstis toodud tehteid päris K8s klastrite peal. Kuid nende laialdaseks kasutamiseks valmisoleku staatus on PoC (kontseptsiooni tõend). Seega, kui soovite oma klastrites kasutada utiliidi etcdhelper muudetud versiooni, tehke seda omal vastutusel.

PS

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar