Ein profiad o weithio gyda data yng nghlwstwr Kubernetes ac ati yn uniongyrchol (heb K8s API)

Yn gynyddol, mae cleientiaid yn gofyn i ni ddarparu mynediad i glwstwr Kubernetes i allu cyrchu gwasanaethau o fewn y clwstwr: fel y gallant gysylltu'n uniongyrchol â rhywfaint o gronfa ddata neu wasanaeth, i gysylltu cymhwysiad lleol â rhaglenni o fewn y clwstwr...

Ein profiad o weithio gyda data yng nghlwstwr Kubernetes ac ati yn uniongyrchol (heb K8s API)

Er enghraifft, mae angen cysylltu o'ch peiriant lleol i wasanaeth memcached.staging.svc.cluster.local. Rydym yn darparu'r gallu hwn gan ddefnyddio VPN o fewn y clwstwr y mae'r cleient yn cysylltu ag ef. I wneud hyn, rydym yn cyhoeddi is-rwydweithiau o godau, gwasanaethau a gwthio DNS clwstwr i'r cleient. Felly, pan fydd cleient yn ceisio cysylltu â'r gwasanaeth memcached.staging.svc.cluster.local, mae'r cais yn mynd i'r clwstwr DNS ac mewn ymateb yn derbyn cyfeiriad y gwasanaeth hwn o'r rhwydwaith gwasanaeth clwstwr neu'r cyfeiriad pod.

Rydym yn ffurfweddu clystyrau K8s gan ddefnyddio kubeadm, lle mae'r is-rwydwaith gwasanaeth diofyn 192.168.0.0/16, ac mae rhwydwaith y codennau yn 10.244.0.0/16. Fel arfer mae popeth yn gweithio'n dda, ond mae un neu ddau o bwyntiau:

  • Subnet 192.168.*.* a ddefnyddir yn aml mewn rhwydweithiau swyddfa cleientiaid, a hyd yn oed yn amlach mewn rhwydweithiau cartref datblygwyr. Ac yna rydyn ni'n cael gwrthdaro: mae llwybryddion cartref yn gweithio ar yr is-rwydwaith hwn ac mae'r VPN yn gwthio'r isrwydweithiau hyn o'r clwstwr i'r cleient.
  • Mae gennym sawl clwstwr (cynhyrchu, llwyfan a/neu sawl clwstwr datblygu). Yna, yn ddiofyn, bydd gan bob un ohonynt yr un is-rwydweithiau ar gyfer codennau a gwasanaethau, sy'n creu anawsterau mawr ar gyfer gweithio ar yr un pryd gyda gwasanaethau mewn sawl clwstwr.

Rydym wedi mabwysiadu'r arfer ers tro o ddefnyddio gwahanol is-rwydweithiau ar gyfer gwasanaethau a phodiau o fewn yr un prosiect - yn gyffredinol, fel bod gan bob clwstwr rwydweithiau gwahanol. Fodd bynnag, mae nifer fawr o glystyrau ar waith na hoffwn eu trosglwyddo o’r dechrau, gan eu bod yn rhedeg llawer o wasanaethau, cymwysiadau nodedig, ac ati.

Ac yna fe ofynnon ni i'n hunain: sut i newid yr is-rwydwaith mewn clwstwr presennol?

Chwilio am benderfyniadau

Yr arfer mwyaf cyffredin yw ail-greu holl gwasanaethau gyda math ClusterIP. Fel opsiwn, yn gallu cynghori a hyn:

Mae gan y broses ganlynol broblem: ar ôl popeth wedi'i ffurfweddu, mae'r codennau'n dod o hyd i'r hen IP fel gweinydd enw DNS yn /etc/resolv.conf.
Gan nad oeddwn yn dod o hyd i'r ateb o hyd, bu'n rhaid i mi ailosod y clwstwr cyfan gydag ailosod kubeadm a'i gychwyn eto.

Ond nid yw hyn yn addas i bawb... Dyma gyflwyniadau manylach ar gyfer ein hachos:

  • Defnyddir gwlanen;
  • Mae clystyrau yn y cymylau ac ar galedwedd;
  • Hoffwn osgoi ail-leoli pob gwasanaeth yn y clwstwr;
  • Yn gyffredinol, mae angen gwneud popeth gydag isafswm o broblemau;
  • Fersiwn Kubernetes yw 1.16.6 (fodd bynnag, bydd camau pellach yn debyg ar gyfer fersiynau eraill);
  • Y brif dasg yw sicrhau bod mewn clwstwr a ddefnyddir gan ddefnyddio kubeadm gydag is-rwydwaith gwasanaeth 192.168.0.0/16, yn ei le 172.24.0.0/16.

Ac fe ddigwyddodd fel ein bod ni wedi bod â diddordeb ers tro mewn gweld beth a sut yn Kubernetes sy'n cael ei storio mewn ac ati, beth ellir ei wneud ag ef... Felly roeddem yn meddwl: “Beth am ddiweddaru'r data mewn ac ati, gan ddisodli'r hen gyfeiriadau IP (is-rwydwaith) gyda rhai newydd? »

Ar ôl chwilio am offer parod ar gyfer gweithio gyda data mewn ac ati, ni ddaethom o hyd i unrhyw beth a oedd yn datrys y broblem yn llwyr. (Gyda llaw, os ydych yn gwybod am unrhyw gyfleustodau ar gyfer gweithio gyda data yn uniongyrchol mewn ac ati, byddem yn gwerthfawrogi'r dolenni.) Fodd bynnag, man cychwyn da yw etcdhelper gan OpenShift (diolch i'w hawduron!).

Gall y cyfleustodau hwn gysylltu ag ac ati gan ddefnyddio tystysgrifau a darllen data oddi yno gan ddefnyddio gorchmynion ls, get, dump.

Ychwanegu etcdhelper

Mae'r meddwl nesaf yn rhesymegol: “Beth sy'n eich atal rhag ychwanegu'r cyfleustodau hwn trwy ychwanegu'r gallu i ysgrifennu data at ac ati?”

Daeth yn fersiwn wedi'i addasu o etcdhelper gyda dwy swyddogaeth newydd changeServiceCIDR и changePodCIDR. arni gallwch weld y cod yma.

Beth mae'r nodweddion newydd yn ei wneud? Algorithm changeServiceCIDR:

  • creu dadgyfeirydd;
  • llunio mynegiant rheolaidd i ddisodli CIDR;
  • rydym yn mynd drwy’r holl wasanaethau gyda’r math ClusterIP yn y clwstwr:
    • dadgodio'r gwerth o etcd i wrthrych Go;
    • gan ddefnyddio mynegiant rheolaidd rydym yn disodli dau beit cyntaf y cyfeiriad;
    • aseinio cyfeiriad IP i'r gwasanaeth o'r is-rwydwaith newydd;
    • creu cyfresydd, trosi'r gwrthrych Go yn brotobuf, ysgrifennu data newydd i etcd.

Swyddogaeth changePodCIDR debyg yn y bôn changeServiceCIDR - dim ond yn lle golygu'r fanyleb gwasanaeth, rydym yn ei wneud ar gyfer y nod a'r newid .spec.PodCIDR i is-rwydwaith newydd.

Ymarfer

Newid gwasanaeth CIDR

Mae'r cynllun ar gyfer gweithredu'r dasg yn syml iawn, ond mae'n golygu amser segur ar adeg ail-greu holl godennau'r clwstwr. Ar ôl disgrifio'r prif gamau, byddwn hefyd yn rhannu syniadau ar sut, mewn egwyddor, y gellir lleihau'r amser segur hwn.

Camau paratoi:

  • gosod y meddalwedd angenrheidiol a chydosod y etcdhelper glytiog;
  • wrth gefn etcd a /etc/kubernetes.

Cynllun gweithredu cryno ar gyfer newid gwasanaethCIDR:

  • newid maniffestau'r gweinydd a'r rheolydd-rheolwr;
  • ailgyhoeddi tystysgrifau;
  • newid gwasanaethau ClusterIP yn ac ati;
  • ailgychwyn yr holl godennau yn y clwstwr.

Mae'r canlynol yn gyfres gyflawn o gamau manwl.

1. Gosod etcd-cleient ar gyfer dympio data:

apt install etcd-client

2. Adeiladu etcdhelper:

  • Gosod 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
  • Rydym yn arbed i ni ein hunain etcdhelper.go, lawrlwytho dibyniaethau, casglu:
    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. Gwneud copi wrth gefn ac ati:

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. Newid yr is-rwydwaith gwasanaeth ym maniffestau awyren reoli Kubernetes. Mewn ffeiliau /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml newid y paramedr --service-cluster-ip-range i is-rwydwaith newydd: 172.24.0.0/16 yn hytrach na 192.168.0.0/16.

5. Gan ein bod yn newid yr is-rwydwaith gwasanaeth y mae kubeadm yn rhoi tystysgrifau ar gyfer gweinydd gwenyn iddi (gan gynnwys), mae angen eu hailgyhoeddi:

  1. Gadewch i ni weld pa barthau a chyfeiriadau IP y mae'r dystysgrif gyfredol wedi'i chyhoeddi ar eu cyfer:
    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. Gadewch i ni baratoi cyfluniad lleiaf posibl ar gyfer kubeadm:
    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. Gadewch i ni ddileu'r hen crt a'r allwedd, oherwydd heb hyn ni fydd y dystysgrif newydd yn cael ei chyhoeddi:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Gadewch i ni ailgyhoeddi tystysgrifau ar gyfer y gweinydd API:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Gadewch i ni wirio bod y dystysgrif wedi'i chyhoeddi ar gyfer yr is-rwydwaith newydd:
    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. Ar ôl ail-gyhoeddi tystysgrif gweinydd API, ailgychwynwch ei gynhwysydd:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Gadewch i ni adfywio'r ffurfwedd ar gyfer admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Gadewch i ni olygu'r data yn ac ati:
    ./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 

    Sylw! Ar hyn o bryd, mae datrysiad parth yn stopio gweithio yn y clwstwr, ers hynny mewn codennau presennol /etc/resolv.conf mae'r hen gyfeiriad CoreDNS (kube-dns) wedi'i gofrestru, ac mae kube-proxy yn newid rheolau iptables o'r hen is-rwydwaith i'r un newydd. Ymhellach yn yr erthygl mae'n cael ei ysgrifennu am opsiynau posibl i leihau amser segur.

  9. Gadewch i ni drwsio ConfigMap yn y gofod enwau kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - disodli yma clusterDNS i gyfeiriad IP newydd y gwasanaeth kube-dns: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - byddwn yn ei drwsio data.ClusterConfiguration.networking.serviceSubnet i is-rwydwaith newydd.

  10. Gan fod y cyfeiriad kube-dns wedi newid, mae angen diweddaru'r ffurfwedd kubelet ar bob nod:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Y cyfan sydd ar ôl yw ailgychwyn pob cod yn y clwstwr:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Lleihau amser segur

Syniadau ar sut i leihau amser segur:

  1. Ar ôl newid y maniffestau awyren reoli, creu gwasanaeth kube-dns newydd, er enghraifft, gyda'r enw kube-dns-tmp a chyfeiriad newydd 172.24.0.10.
  2. I'w wneud if yn etcdhelper, na fydd yn addasu'r gwasanaeth kube-dns.
  3. Amnewid y cyfeiriad ym mhob kubelets ClusterDNS i un newydd, tra bydd yr hen wasanaeth yn parhau i weithio ar yr un pryd â'r un newydd.
  4. Arhoswch nes bod y codennau gyda chymwysiadau yn rholio drosodd naill ai ar eu pen eu hunain am resymau naturiol neu ar amser y cytunwyd arno.
  5. Dileu gwasanaeth kube-dns-tmp a newid serviceSubnetCIDR ar gyfer y gwasanaeth kube-dns.

Bydd y cynllun hwn yn caniatáu ichi leihau'r amser segur i ~ funud - am gyfnod y dileu gwasanaeth kube-dns-tmp a newid yr is-rwydwaith ar gyfer y gwasanaeth kube-dns.

podNetwork addasu

Ar yr un pryd, penderfynasom edrych ar sut i addasu podNetwork gan ddefnyddio'r etcdhelper canlyniadol. Mae'r dilyniant o gamau gweithredu fel a ganlyn:

  • gosod cyfluniadau i mewn kube-system;
  • trwsio maniffest y ciwb-rheolwr-rheolwr;
  • newid podCIDR yn uniongyrchol mewn ac ati;
  • ailgychwyn pob nod clwstwr.

Nawr mwy am y camau hyn:

1. Addasu ConfigMap yn y gofod enwau kube-system:

kubectl -n kube-system edit cm kubeadm-config

- cywiro data.ClusterConfiguration.networking.podSubnet i is-rwydwaith newydd 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

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

2. Addasu maniffest y rheolydd-rheolwr:

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

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

3. Edrychwch ar y gwerthoedd cyfredol .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses ar gyfer pob nod clwstwr:

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. Amnewid podCIDR trwy wneud newidiadau yn uniongyrchol i ac ati:

./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. Gadewch i ni wirio bod podCIDR wedi newid mewn gwirionedd:

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. Gadewch i ni ailgychwyn pob nod clwstwr fesul un.

7. Os byddwch yn gadael o leiaf un nod hen podCIDR, yna ni fydd kube-controller-manager yn gallu cychwyn, ac ni fydd codennau yn y clwstwr yn cael eu hamserlennu.

Mewn gwirionedd, gellir gwneud newid podCIDR hyd yn oed yn symlach (er enghraifft, felly). Ond roedden ni eisiau dysgu sut i weithio gydag ac ati yn uniongyrchol, oherwydd mae yna achosion wrth olygu gwrthrychau Kubernetes yn ac ati - yr unig amrywiad posibl. (Er enghraifft, ni allwch newid y maes Gwasanaeth heb amser segur yn unig spec.clusterIP.)

Cyfanswm

Mae’r erthygl yn trafod y posibilrwydd o weithio gyda data mewn ac ati yn uniongyrchol, h.y. osgoi API Kubernetes. Weithiau mae'r dull hwn yn caniatáu ichi wneud "pethau anodd." Fe wnaethon ni brofi'r gweithrediadau a roddwyd yn y testun ar glystyrau K8s go iawn. Fodd bynnag, mae eu statws o barodrwydd ar gyfer defnydd eang PoC (prawf o gysyniad). Felly, os ydych chi am ddefnyddio fersiwn wedi'i addasu o'r cyfleustodau etcdhelper ar eich clystyrau, gwnewch hynny ar eich menter eich hun.

PS

Darllenwch hefyd ar ein blog:

Ffynhonnell: hab.com

Ychwanegu sylw