Mūsu pieredze ar datiem tieŔi etcd Kubernetes klasterī (bez K8s API)

Arvien biežāk klienti lÅ«dz nodroÅ”ināt piekļuvi Kubernetes klasterim, lai varētu piekļūt klastera pakalpojumiem: lai varētu tieÅ”i izveidot savienojumu ar kādu datu bāzi vai pakalpojumu, savienot lokālo lietojumprogrammu ar lietojumprogrammām klasterÄ«...

Mūsu pieredze ar datiem tieŔi etcd Kubernetes klasterī (bez K8s API)

Piemēram, ir nepiecieÅ”ams izveidot savienojumu no vietējās maŔīnas ar pakalpojumu memcached.staging.svc.cluster.local. Mēs nodroÅ”inām Å”o iespēju, izmantojot VPN klasterÄ«, ar kuru klients izveido savienojumu. Lai to izdarÄ«tu, mēs klientam paziņojam par podziņu, pakalpojumu un push klastera DNS apakÅ”tÄ«kliem. Tādējādi, kad klients mēģina izveidot savienojumu ar pakalpojumu memcached.staging.svc.cluster.local, pieprasÄ«jums tiek nosÅ«tÄ«ts uz klastera DNS un kā atbilde tiek saņemta Ŕī pakalpojuma adrese no klastera pakalpojumu tÄ«kla vai pod adreses.

Mēs konfigurējam K8s klasterus, izmantojot kubeadm, kur ir noklusējuma pakalpojumu apakÅ”tÄ«kls 192.168.0.0/16, un podiņu tÄ«kls ir 10.244.0.0/16. Parasti viss darbojas labi, taču ir daži punkti:

  • ApakÅ”tÄ«kls 192.168.*.* bieži izmanto klientu biroju tÄ«klos un vēl biežāk izstrādātāju mājas tÄ«klos. Un tad rodas konflikti: mājas marÅ”rutētāji strādā Å”ajā apakÅ”tÄ«klā, un VPN nospiež Å”os apakÅ”tÄ«klus no klastera uz klientu.
  • Mums ir vairākas kopas (ražoÅ”anas, skatuves un/vai vairākas izstrādātāju kopas). Tad pēc noklusējuma visiem tiem bÅ«s vienādi apakÅ”tÄ«kli podiem un pakalpojumiem, kas rada lielas grÅ«tÄ«bas vienlaicÄ«gam darbam ar pakalpojumiem vairākos klasteros.

Mēs jau sen esam pieņēmuÅ”i praksi izmantot dažādus apakÅ”tÄ«klus pakalpojumiem un podiem viena projekta ietvaros - kopumā, lai visiem klasteriem bÅ«tu dažādi tÄ«kli. Tomēr darbojas liels skaits klasteru, kurus es negribētu pārcelt no nulles, jo tie nodroÅ”ina daudzus pakalpojumus, statusa lietojumprogrammas utt.

Un tad mēs sev jautājām: kā mainÄ«t apakÅ”tÄ«klu esoÅ”ajā klasterÄ«?

Lēmumu meklÄ“Å”ana

Visizplatītākā prakse ir radīt no jauna viss pakalpojumus ar tipu ClusterIP. Kā opciju, var ieteikt un Ŕī:

Tālāk norādÄ«tajā procesā ir problēma: pēc tam, kad viss ir konfigurēts, podi tiek parādÄ«ti vecajā IP adresē kā DNS nosaukuma serveris mapē /etc/resolv.conf.
Tā kā es joprojām neatradu risinājumu, man nācās atiestatÄ«t visu klasteru, izmantojot kubeadm atiestatÄ«Å”anu, un vēlreiz to iniciēt.

Bet tas nav piemērots visiem... Šeit ir sīkāks ievads mūsu gadījumam:

  • tiek izmantots flanelis;
  • Ir kopas gan mākoņos, gan aparatÅ«rā;
  • Es vēlētos izvairÄ«ties no visu klastera pakalpojumu atkārtotas izvietoÅ”anas;
  • Kopumā viss ir jādara ar minimālu problēmu skaitu;
  • Kubernetes versija ir 1.16.6 (tomēr turpmākās darbÄ«bas bÅ«s lÄ«dzÄ«gas citām versijām);
  • Galvenais uzdevums ir nodroÅ”ināt, ka klasterÄ« tiek izvietots, izmantojot kubeadm ar pakalpojumu apakÅ”tÄ«klu 192.168.0.0/16, nomainiet to ar 172.24.0.0/16.

Un sagadÄ«jās, ka mums jau sen bija interese paskatÄ«ties, kas un kā Kubernetes tiek glabāts etcd, ko ar to var izdarÄ«t... Tā nu izdomājām: ā€œKāpēc gan vienkārÅ”i neatjaunināt datus etcd, aizstājot vecās IP adreses (apakÅ”tÄ«klu) ar jaunām? "

Meklējot gatavus rÄ«kus darbam ar datiem programmā etcd, mēs neatradām neko, kas pilnÄ«bā atrisinātu problēmu. (Starp citu, ja zināt kādu utilÄ«tu darbam ar datiem tieÅ”i programmā etcd, mēs priecāsimies par saitēm.) Tomēr labs sākumpunkts ir etcdhelper no OpenShift (paldies tās autoriem!).

Šī utilīta var izveidot savienojumu ar etcd, izmantojot sertifikātus, un nolasīt datus no turienes, izmantojot komandas ls, get, dump.

Pievienojiet etcdhelper

Nākamā doma ir loÄ£iska: "Kas jums traucē pievienot Å”o utilÄ«tu, pievienojot iespēju rakstÄ«t datus uz etcd?"

Tā kļuva par modificētu etcdhelper versiju ar divām jaunām funkcijām changeServiceCIDR Šø changePodCIDR. uz viņas jÅ«s varat redzēt kodu Å”eit.

Ko dara jaunās funkcijas? Algoritms changeServiceCIDR:

  • izveidot deserializatoru;
  • sastādÄ«t regulāro izteiksmi, lai aizstātu CIDR;
  • mēs ejam cauri visiem pakalpojumiem ar klastera tipu ClusterIP:
    • atÅ”ifrēt vērtÄ«bu no etcd uz Go objektu;
    • izmantojot regulāro izteiksmi aizstājam adreses pirmos divus baitus;
    • pieŔķirt pakalpojumam IP adresi no jaunā apakÅ”tÄ«kla;
    • izveidojiet serializētāju, pārveidojiet Go objektu par protobuf, ierakstiet jaunus datus uz etcd.

Funkcija changePodCIDR bÅ«tÄ«bā lÄ«dzÄ«gi changeServiceCIDR - tikai tā vietā, lai rediģētu pakalpojuma specifikāciju, mēs to darām mezglam un mainām .spec.PodCIDR uz jaunu apakÅ”tÄ«klu.

Prakse

Mainīt pakalpojumu CIDR

Uzdevuma Ä«stenoÅ”anas plāns ir ļoti vienkārÅ”s, taču tas ietver dÄ«kstāvi, kamēr tiek atjaunoti visi klastera podi. Pēc galveno soļu aprakstÄ«Å”anas padalÄ«simies arÄ« pārdomās par to, kā teorētiski Å”o dÄ«kstāvi var samazināt lÄ«dz minimumam.

SagatavoŔanas soļi:

  • nepiecieÅ”amās programmatÅ«ras instalÄ“Å”ana un patched etcdhelper montāža;
  • dublējums etcd un /etc/kubernetes.

ÄŖss darbÄ«bas plāns pakalpojuma CIDR maiņai:

  • apiservera un kontroliera-pārvaldnieka manifestu maiņa;
  • sertifikātu atkārtota izsniegÅ”ana;
  • mainot ClusterIP pakalpojumus etcd;
  • restartējiet visas klastera pākstis.

Tālāk ir sniegta detalizēta darbību secība.

1. Instalējiet etcd-client datu izgāztuvei:

apt install etcd-client

2. Izveidojiet etcdhelper:

  • Instalējiet 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
  • Mēs krājam sev etcdhelper.go, lejupielādēt atkarÄ«bas, apkopot:
    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. Izveidojiet dublējumu 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. Mainiet pakalpojuma apakÅ”tÄ«klu Kubernetes vadÄ«bas plaknes manifestos. Failos /etc/kubernetes/manifests/kube-apiserver.yaml Šø /etc/kubernetes/manifests/kube-controller-manager.yaml mainÄ«t parametru --service-cluster-ip-range uz jaunu apakÅ”tÄ«klu: 172.24.0.0/16 nevis 192.168.0.0/16.

5. Tā kā mēs mainām pakalpojumu apakÅ”tÄ«klu, kuram kubeadm izsniedz sertifikātus apiserverim (tostarp), tie ir jāizsniedz atkārtoti:

  1. ApskatÄ«sim, kuriem domēniem un IP adresēm ir izsniegts paÅ”reizējais sertifikāts:
    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. Sagatavosim minimālo kubeadm konfigurāciju:
    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. Izdzēsīsim veco crt un atslēgu, jo bez tā jaunais sertifikāts netiks izsniegts:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Atkārtoti izsniegsim sertifikātus API serverim:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Pārbaudīsim, vai sertifikāts ir izsniegts jaunajam apakŔtīklam:
    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ēc API servera sertifikāta atkārtotas izsniegÅ”anas restartējiet tā konteineru:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Reģenerēsim konfigurāciju admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Rediģēsim datus programmā 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-service-cidr 172.24.0.0/16 

    UzmanÄ«bu! Å obrÄ«d domēna izŔķirtspēja klasterÄ« pārstāj darboties, jo esoÅ”ajos podiņos /etc/resolv.conf tiek reÄ£istrēta vecā CoreDNS adrese (kube-dns), un kube-proxy maina iptables noteikumus no vecā apakÅ”tÄ«kla uz jauno. Tālāk rakstā ir rakstÄ«ts par iespējamām iespējām, kā samazināt dÄ«kstāves laiku.

  9. Nosaukumvietā labosim ConfigMap kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - nomainiet Ŕeit clusterDNS uz jauno kube-dns pakalpojuma IP adresi: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - mēs to salabosim data.ClusterConfiguration.networking.serviceSubnet uz jaunu apakÅ”tÄ«klu.

  10. Tā kā kube-dns adrese ir mainījusies, ir jāatjaunina kubelet konfigurācija visos mezglos:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Atliek tikai restartēt visas klastera podi:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Samaziniet dīkstāves laiku

Domas par to, kā samazināt dīkstāves laiku:

  1. Pēc vadības plaknes manifestu maiņas izveidojiet jaunu kube-dns pakalpojumu, piemēram, ar nosaukumu kube-dns-tmp un jauna adrese 172.24.0.10.
  2. Marka if programmā etcdhelper, kas nemainīs kube-dns pakalpojumu.
  3. Aizstāt adresi visos kubeletos ClusterDNS uz jaunu, savukārt vecais pakalpojums turpinās strādāt vienlaikus ar jauno.
  4. Pagaidiet, lÄ«dz pākstis ar aplikācijām apgāzÄ«sies vai nu paÅ”as dabisku iemeslu dēļ, vai saskaņotā laikā.
  5. Dzēst pakalpojumu kube-dns-tmp un mainīt serviceSubnetCIDR kube-dns pakalpojumam.

Å is plāns ļaus jums samazināt dÄ«kstāves laiku lÄ«dz ~ minÅ«tei pakalpojuma noņemÅ”anas laikā kube-dns-tmp un pakalpojuma apakÅ”tÄ«kla maiņa kube-dns.

Modifikācija podNetwork

Tajā paŔā laikā mēs nolēmām apskatÄ«t, kā modificēt podNetwork, izmantojot iegÅ«to etcdhelper. DarbÄ«bu secÄ«ba ir Ŕāda:

  • konfigurāciju laboÅ”ana kube-system;
  • kube-controller-manager manifesta laboÅ”ana;
  • mainÄ«t podCIDR tieÅ”i uttd;
  • pārstartējiet visus klastera mezglus.

Tagad vairāk par Ŕīm darbībām:

1. Modificējiet ConfigMaps nosaukumu telpā kube-system:

kubectl -n kube-system edit cm kubeadm-config

- labojot data.ClusterConfiguration.networking.podSubnet uz jaunu apakŔtīklu 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

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

2. Modificējiet kontroliera-pārziņa manifestu:

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

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

3. Apskatiet paÅ”reizējās vērtÄ«bas .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses visiem klastera mezgliem:

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. Nomainiet podCIDR, veicot izmaiņas tieÅ”i 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. PārbaudÄ«sim, vai podCIDR patieŔām ir mainÄ«jies:

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. Restartēsim visus klastera mezglus pa vienam.

7. Ja atstājat vismaz vienu mezglu vecais podCIDR, tad kube-controller-manager nevarēs startēt un klastera podi netiks ieplānoti.

Faktiski podCIDR nomaiņu var veikt vēl vienkārŔāk (piemēram, tā). Bet mēs gribējām iemācÄ«ties strādāt ar etcd tieÅ”i, jo ir gadÄ«jumi, kad rediģēt Kubernetes objektus etcd - vienÄ«gais iespējamais variants. (Piemēram, jÅ«s nevarat vienkārÅ”i mainÄ«t pakalpojumu lauku bez dÄ«kstāves spec.clusterIP.)

Kopsavilkums

Rakstā apskatÄ«ta iespēja strādāt ar datiem etcd tieÅ”i, t.i. apejot Kubernetes API. Dažreiz Ŕī pieeja ļauj jums veikt "grÅ«tas lietas". Mēs pārbaudÄ«jām tekstā norādÄ«tās darbÄ«bas reālos K8 klasteros. Tomēr to gatavÄ«bas statuss plaÅ”ai lietoÅ”anai ir PoC (koncepcijas pierādÄ«jums). Tāpēc, ja savās kopās vēlaties izmantot modificētu utilÄ«ta etcdhelper versiju, dariet to uz savu risku.

PS

Lasi arī mūsu emuārā:

Avots: www.habr.com

Pievieno komentāru