Gure esperientzia etcd Kubernetes klusterrean datuekin zuzenean (K8s APIrik gabe)

Gero eta gehiago, bezeroek Kubernetes klustererako sarbidea eskaintzeko eskatzen digute kluster barruko zerbitzuetara sartu ahal izateko: datu-base edo zerbitzu batera zuzenean konektatzeko, aplikazio lokal bat kluster barruko aplikazioekin konektatzeko...

Gure esperientzia etcd Kubernetes klusterrean datuekin zuzenean (K8s APIrik gabe)

Adibidez, tokiko makinatik zerbitzu batera konektatu beharra dago memcached.staging.svc.cluster.local. Gaitasun hori bezeroa konektatzen den kluster barruan VPN bat erabiliz eskaintzen dugu. Horretarako, pods, zerbitzu eta push cluster DNS azpisareak iragartzen dizkiogu bezeroari. Horrela, bezero bat zerbitzura konektatzen saiatzen denean memcached.staging.svc.cluster.local, eskaera klusterreko DNSra doa eta erantzunez zerbitzu honen helbidea jasotzen du cluster zerbitzuaren saretik edo pod helbidea.

K8s klusterrak kubeadm erabiliz konfiguratzen ditugu, non zerbitzuaren azpisare lehenetsia dagoen 192.168.0.0/16, eta leken sarea da 10.244.0.0/16. Normalean dena ondo funtzionatzen du, baina puntu pare bat daude:

  • Azpisarea 192.168.*.* maiz erabiltzen da bezeroen bulegoko sareetan, eta are maizago garatzaileen etxeko sareetan. Eta orduan gatazkak sortzen dira: etxeko bideratzaileek azpisare honetan lan egiten dute eta VPNak azpisare hauek klusteretik bezerora bultzatzen ditu.
  • Hainbat kluster ditugu (produkzioa, etapa eta/edo hainbat garapen kluster). Ondoren, lehenespenez, guztiek izango dituzte azpisare berdinak pod eta zerbitzuetarako, eta horrek zailtasun handiak sortzen ditu hainbat klustertako zerbitzuekin aldi berean lan egiteko.

Aspaldi hartu dugu azpisare desberdinak proiektu berdinaren barruan zerbitzu eta pods erabiltzeko praktika, oro har, kluster guztiek sare desberdinak izan ditzaten. Hala ere, kluster kopuru handia dago martxan, eta ez nuke hutsetik iraultzea gustatuko litzaidake, zerbitzu asko, egoera-aplikazioak, etab.

Eta orduan galdetu genion geure buruari: nola aldatu lehendik dagoen kluster batean azpisarea?

Erabakiak bilatzea

Praktika ohikoena birsortzea da guztiak ClusterIP motako zerbitzuak. Aukera gisa, aholkatu dezake eta hau:

Ondorengo prozesuak arazo bat du: dena konfiguratu ondoren, podek IP zaharra DNS izen-zerbitzari gisa ateratzen dute /etc/resolv.conf-en.
Oraindik irtenbidea aurkitu ez nuenez, kubeadm berrezarri eta berriro hasi behar izan nuen kluster osoa berrezarri.

Baina hau ez da guztiontzat egokia... Hona hemen gure kasurako sarrera zehatzagoak:

  • Flanela erabiltzen da;
  • Klusterrak daude bai hodeietan eta baita hardwarean ere;
  • Klusterreko zerbitzu guztiak berriro zabaltzea saihestu nahiko nuke;
  • Orokorrean dena gutxieneko arazoekin egin beharra dago;
  • Kubernetes bertsioa 1.16.6 da (hala ere, urrats gehiago antzekoak izango dira beste bertsioetarako);
  • Zeregin nagusia kubeadm erabiliz inplementatutako kluster batean zerbitzu azpisare batekin ziurtatzea da 192.168.0.0/16, ordezkatu 172.24.0.0/16.

Eta gertatu zen aspaldian interesatuta geundela ikusteko Kubernetes-en zer eta nola gordetzen den etcd-n, zer egin daitekeen horrekin... Beraz, pentsatu genuen: β€œZergatik ez eguneratu datuak etcd-en, IP helbide zaharrak (azpisarea) berriekin ordezkatuz? "

Etcd-en datuekin lan egiteko prest dauden tresnak bilatu ondoren, ez dugu arazoa guztiz konpontzen duen ezer aurkitu. (Bide batez, datuekin zuzenean etcd-n lan egiteko utilitateren bat ezagutzen baduzu, estekak eskertuko genituzke.) Hala ere, abiapuntu ona da etcdhelper OpenShift-etik (eskerrik asko bere egileei!).

Utilitate honek etcd-ra konektatu daiteke ziurtagiriak erabiliz eta hortik datuak irakurri komandoak erabiliz ls, get, dump.

Gehitu etcdhelper

Hurrengo pentsamendua logikoa da: "Zerk geldiarazten zaitu utilitate hau gehitzea, datuak etcd-en idazteko gaitasuna gehituta?"

Etcdhelper-en bertsio aldatua bihurtu zen bi funtzio berrirekin changeServiceCIDR ΠΈ changePodCIDR. haren gainean kodea ikus dezakezu Hemen.

Zer egiten dute funtzio berriek? Algoritmoa changeServiceCIDR:

  • deserializatzaile bat sortu;
  • konpilatu adierazpen erregular bat CIDR ordezkatzeko;
  • ClusterIP motako zerbitzu guztietatik pasatzen gara klusterrean:
    • deskodetu etcd-tik balioa Go objektu batean;
    • adierazpen erregular bat erabiliz helbidearen lehen bi byteak ordezkatzen ditugu;
    • esleitu zerbitzuari azpisare berriko IP helbide bat;
    • sortu serializatzaile bat, bihurtu Go objektua protobuf, idatzi datu berriak etcd-en.

Funtzioa changePodCIDR funtsean antzekoa changeServiceCIDR - Zerbitzuaren zehaztapena editatu beharrean, nodorako egiten dugu eta aldatzen dugu .spec.PodCIDR azpisare berri batera.

Praktika

Aldatu zerbitzua CIDR

Ataza ezartzeko plana oso erraza da, baina klusterreko pod guztiak birsortzeko unean geldialdi-denbora dakar. Urrats nagusiak deskribatu ondoren, teorian, geldialdi hori gutxitzeko moduari buruzko gogoetak ere partekatuko ditugu.

Prestaketa urratsak:

  • beharrezko softwarea instalatzea eta adabakia etcdhelper muntatzea;
  • backup etcd eta /etc/kubernetes.

Zerbitzua aldatzeko ekintza-plan laburra CIDR:

  • apiserver eta controller-kudeatzailearen manifestuak aldatzea;
  • ziurtagiriak berriro igortzea;
  • ClusterIP zerbitzuak etcd-n aldatzea;
  • klusterreko pod guztiak berrabiarazi.

Jarraian ekintzen sekuentzia osoa da xehetasunez.

1. Instalatu etcd-client datuak iraultzeko:

apt install etcd-client

2. Eraiki etcdhelper:

  • Instalatu 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
  • Guretzat gordetzen dugu etcdhelper.go, deskargatu mendekotasunak, bildu:
    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. Egin babeskopia bat, 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. Aldatu zerbitzuaren azpisarea Kubernetes kontrol-planoko manifestuetan. Fitxategietan /etc/kubernetes/manifests/kube-apiserver.yaml ΠΈ /etc/kubernetes/manifests/kube-controller-manager.yaml parametroa aldatu --service-cluster-ip-range azpisare berri batera: 172.24.0.0/16 ordez 192.168.0.0/16.

5. Kubeadm-ek apiserver-erako ziurtagiriak igortzen dituen zerbitzu azpisarea aldatzen ari garenez (barne), berriro igorri behar dira:

  1. Ikus dezagun uneko ziurtagiria zein domeinu eta IP helbidetarako igorri den:
    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. Presta dezagun kubeadm-rako konfigurazio minimo bat:
    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. Ezabatu ditzagun crt zaharra eta gakoa, hau gabe ez baita ziurtagiri berria emango:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Igor ditzagun berriro API zerbitzarirako ziurtagiriak:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Egiaztatu dezagun azpisare berrirako ziurtagiria igorri dela:
    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. API zerbitzariaren ziurtagiria berriro igorri ondoren, berrabiarazi bere edukiontzia:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Birsor dezagun konfigurazioa admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Editatu ditzagun datuak etcd-n:
    ./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 

    Arreta! Momentu honetan, domeinuaren ebazpenak klusterrean funtzionatzeari uzten dio, lehendik dauden podetan /etc/resolv.conf CoreDNS helbide zaharra (kube-dns) erregistratuta dago, eta kube-proxy iptables arauak azpisare zaharretik berrira aldatzen ditu. Aurrerago artikuluan geldialdi-denbora minimizatzeko aukera posibleei buruz idatzita dago.

  9. Konpon ditzagun ConfigMap izenen eremuan kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - ordezkatu hemen clusterDNS kube-dns zerbitzuaren IP helbide berrira: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - konponduko dugu data.ClusterConfiguration.networking.serviceSubnet azpisare berri batera.

  10. Kube-dns helbidea aldatu denez, beharrezkoa da kubelet konfigurazioa eguneratzea nodo guztietan:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Klusterreko pod guztiak berrabiaraztea da geratzen dena:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Murriztu geldialdi-denbora

Geldialdi-denbora minimizatzeko gogoetak:

  1. Kontrol-planoaren manifestuak aldatu ondoren, sortu kube-dns zerbitzu berri bat, adibidez, izenarekin kube-dns-tmp eta helbide berria 172.24.0.10.
  2. egiteko if etcdhelper-en, kube-dns zerbitzua aldatuko ez duena.
  3. Ordeztu helbidea kubelet guztietan ClusterDNS berri batera, zerbitzu zaharrak, berriz, berriarekin aldi berean lanean jarraituko du.
  4. Itxaron aplikazioak dituzten lekak arrazoi naturalengatik edo hitzartutako ordu batean irauli arte.
  5. Ezabatu zerbitzua kube-dns-tmp eta aldatu serviceSubnetCIDR kube-dns zerbitzurako.

Plan honi esker, geldialdi-denbora ~ minutu batekoa izango da - zerbitzua kentzen den bitartean kube-dns-tmp eta zerbitzuaren azpisarea aldatzea kube-dns.

PodNetwork aldaketa

Aldi berean, ondoriozko etcdhelper erabiliz podNetwork nola aldatu aztertzea erabaki genuen. Ekintzen sekuentzia hau da:

  • konfigurazioak konpontzen kube-system;
  • kube-controller-manager manifestua konpontzea;
  • aldatu podCIDR zuzenean etcd-n;
  • berrabiarazi klusterreko nodo guztiak.

Orain ekintza hauei buruz gehiago:

1. Aldatu ConfigMap-ak izen-eremuan kube-system:

kubectl -n kube-system edit cm kubeadm-config

- zuzentzea data.ClusterConfiguration.networking.podSubnet azpisare berri batera 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

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

2. Aldatu kontroladore-kudeatzailearen manifestua:

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

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

3. Erreparatu egungo balioei .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses cluster nodo guztientzat:

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. Ordeztu podCIDR zuzenean etcd-en aldaketak eginez:

./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. Egiazta dezagun podCIDR benetan aldatu dela:

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. Berrabiarazi ditzagun kluster nodo guztiak banan-banan.

7. Gutxienez nodo bat uzten baduzu podCIDR zaharra, orduan kube-controller-manager ezin izango da abiarazi eta klusterreko pod-ak ez dira programatuko.

Izan ere, podCIDR aldatzea are errazago egin daiteke (adibidez, beraz,). Baina etcd-rekin zuzenean nola lan egiten ikasi nahi genuen, Kubernetes objektuak etcd-en editatzen direnean kasuak daudelako. bakarra aldaera posiblea. (Adibidez, ezin duzu Zerbitzuaren eremua aldatu denborarik gabe spec.clusterIP.)

Guztira

Artikuluak etcd-n datuekin zuzenean lan egiteko aukera aztertzen du, hau da. Kubernetes APIa saihestuz. Batzuetan, ikuspegi honek "gauza zailak" egiteko aukera ematen dizu. Testuan emandako eragiketak K8s multzo errealetan probatu ditugu. Hala ere, erabilera zabalerako prest dauden egoera da PoC (kontzeptuaren froga). Beraz, etcdhelper erabilgarritasunaren bertsio aldatu bat erabili nahi baduzu zure klusterretan, egin ezazu zure ardurapean.

PS

Irakurri ere gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria