Pangalaman kami sareng data dina kluster Kubernetes jsb langsung (tanpa API K8s)

Langkung seueur, klien naroskeun kami pikeun nyayogikeun aksés kana klaster Kubernetes pikeun tiasa ngaksés jasa dina kluster: pikeun tiasa langsung nyambung ka sababaraha pangkalan data atanapi jasa, pikeun nyambungkeun aplikasi lokal sareng aplikasi dina kluster...

Pangalaman kami sareng data dina kluster Kubernetes jsb langsung (tanpa API K8s)

Salaku conto, aya anu peryogi pikeun nyambungkeun tina mesin lokal anjeun ka jasa memcached.staging.svc.cluster.local. Kami nyayogikeun kamampuan ieu nganggo VPN dina kluster anu dihubungkeun ku klien. Jang ngalampahkeun ieu, kami ngumumkeun subnet pods, jasa sareng nyorong DNS kluster ka klien. Ku kituna, nalika klien nyoba nyambung ka layanan nu memcached.staging.svc.cluster.local, pamundut nu mana ka DNS klaster sarta respon narima alamat layanan ieu ti jaringan layanan klaster atawa alamat pod.

Urang ngonpigurasikeun klaster K8s ngagunakeun kubeadm, dimana subnet layanan standar 192.168.0.0/16, jeung jaringan pods nyaeta 10.244.0.0/16. Biasana sadayana tiasa dianggo saé, tapi aya sababaraha titik:

  • Subnet 192.168.*.* mindeng dipaké dina jaringan kantor klien, komo leuwih mindeng dina jaringan asal pamekar. Teras we meunang konflik: routers imah dianggo dina subnet ieu sarta VPN ngadorong subnets ieu ti klaster ka klien nu.
  • Kami ngagaduhan sababaraha klaster (produksi, panggung sareng / atanapi sababaraha klaster dev). Teras, sacara standar, sadayana bakal gaduh subnet anu sami pikeun pod sareng jasa, anu nyiptakeun kasusah anu ageung pikeun damel sakaligus sareng jasa dina sababaraha klaster.

Kami parantos lami ngadopsi prakték ngagunakeun subnet anu béda pikeun jasa sareng pods dina proyék anu sami - sacara umum, supados sadaya klaster gaduh jaringan anu béda. Sanajan kitu, aya angka nu gede ngarupakeun klaster dina operasi nu Abdi teu hoyong gulung leuwih ti scratch, saprak maranéhna ngajalankeun loba jasa, aplikasi stateful, jsb.

Teras we naros ka diri urang sorangan: kumaha carana ngarobih subnet dina klaster anu tos aya?

Pilarian kaputusan

Prakték anu paling umum nyaéta nyiptakeun deui sadaya jasa kalawan tipe ClusterIP. Salaku pilihan, tiasa mamatahan sareng ieu:

Prosés handap boga masalah: sanggeus sagalana ngonpigurasi, pods datang nepi ka IP heubeul salaku nameserver DNS di /etc/resolv.conf.
Kusabab kuring masih henteu mendakan solusina, kuring kedah ngareset sadayana klaster kalayan reset kubeadm sareng ngamimitian deui.

Tapi ieu henteu cocog kanggo sadayana ... Ieu perkenalan anu langkung rinci pikeun kasus urang:

  • Flannel dipaké;
  • Aya klaster boh dina awan sareng dina hardware;
  • Abdi hoyong ulah ulang deploying sagala jasa dina klaster;
  • Aya peryogi umumna ngalakukeun sagalana kalawan jumlah minimum masalah;
  • Vérsi Kubernetes nyaéta 1.16.6 (tapi, léngkah-léngkah salajengna bakal sami pikeun versi anu sanés);
  • Tugas utama nyaéta pikeun mastikeun yén dina klaster disebarkeun nganggo kubeadm kalayan subnet jasa 192.168.0.0/16, diganti ku 172.24.0.0/16.

Sarta eta ngan jadi kajadian nu urang geus lila kabetot dina ningali naon jeung kumaha di Kubernetes disimpen dina etcd, naon anu bisa dilakukeun ku eta... Jadi urang mikir: “Naha henteu ngan ngamutahirkeun data dina jsb, ngaganti alamat IP heubeul (subnet) jeung nu anyar? »

Saatos milarian alat-alat anu siap-siap pikeun damel sareng data dina jsb, kami henteu mendakan naon waé anu parantos ngarengsekeun masalah. (Ku jalan kitu, upami anjeun terang ngeunaan naon waé utilitas pikeun damel sareng data langsung di jsb, kami bakal ngahargaan tautan.) Nanging, titik awal anu saé nyaéta jsbdhelper ti OpenShift (Hatur nuhun ka pangarang na!).

Utiliti ieu tiasa nyambung ka etcd nganggo sertipikat sareng maca data ti dinya nganggo paréntah ls, get, dump.

Tambahkeun jsbdhelper

Pikiran salajengna logis: "Naon anu ngahalangan anjeun tina nambihan utilitas ieu ku cara nambihan kamampuan nyerat data kana jsb?"

Ieu janten versi dirobah tina etcdhelper dua fungsi anyar changeServiceCIDR и changePodCIDR. dina dirina anjeun tiasa ningali kode di dieu.

Naon anu dilakukeun ku fitur anyar? Algoritma changeServiceCIDR:

  • nyieun deserializer a;
  • nyusun éksprési biasa pikeun ngaganti CIDR;
  • urang ngaliwat sadaya jasa kalayan jinis ClusterIP dina kluster:
    • decode nilai tina etcd kana obyek Go;
    • ngagunakeun ekspresi biasa urang ngaganti dua bait mimiti alamat;
    • napelkeun jasa alamat IP ti subnet anyar;
    • nyieun serializer a, ngarobah obyek Go kana protobuf, nulis data anyar pikeun etcd.

fungsi changePodCIDR dasarna sarupa changeServiceCIDR - ngan tinimbang ngédit spésifikasi jasa, urang ngalakukeun eta pikeun titik jeung robah .spec.PodCIDR ka subnet anyar.

praktek

Robah jasa CIDR

Rencana pikeun ngalaksanakeun tugas saderhana pisan, tapi ngalibatkeun downtime dina waktos nyiptakeun deui sadaya pods dina kluster. Saatos ngajéntrékeun léngkah-léngkah utama, urang ogé bakal ngabagi pikiran ngeunaan kumaha, dina téori, downtime ieu tiasa diminimalkeun.

Léngkah persiapan:

  • masang software diperlukeun tur assembling nu patched etcdhelper;
  • cadangan jsbd na /etc/kubernetes.

Rencana aksi ringkes pikeun ngarobah layananCIDR:

  • ngarobah apiserver jeung controller-manajer manifests;
  • penerbitan ulang sertipikat;
  • ngarobah jasa ClusterIP di jsb;
  • balikan deui sadaya pods dina kluster.

Di handap ieu runtuyan lengkep lampah di jéntré.

1. Pasang etcd-client pikeun dump data:

apt install etcd-client

2. Ngawangun jsbdhelper:

  • Pasang 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
  • Urang nyimpen keur diri urang sorangan etcdhelper.go, unduh dependensi, kumpulkeun:
    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. Jieun cadangan jsb:

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. Ngarobah subnet layanan dina pesawat kontrol Kubernetes manifests. Dina file /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml ngarobah parameter --service-cluster-ip-range ka subnet anyar: 172.24.0.0/16 tibatan 192.168.0.0/16.

5. Kusabab urang ngarobah subnet layanan nu kubeadm ngaluarkeun sertipikat pikeun apiserver (kaasup), aranjeunna perlu reissued:

  1. Hayu urang tingali domain sareng alamat IP mana sertipikat ayeuna parantos dikaluarkeun pikeun:
    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. Hayu urang nyiapkeun config minimal pikeun 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. Hayu urang ngahapus crt sareng konci anu lami, sabab tanpa ieu sertipikat énggal moal dikaluarkeun:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. Hayu urang ngaluarkeun deui sertipikat pikeun server API:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Hayu urang pariksa yen sertipikat ieu dikaluarkeun pikeun subnet anyar:
    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. Saatos ngaluarkeun deui sertipikat server API, balikan deui wadahna:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. Hayu urang regenerate config pikeun admin.conf:
    kubeadm alpha certs renew admin.conf
  8. Hayu urang ngédit data dina jsb:
    ./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 

    Awas! Dina waktos ayeuna, résolusi domain lirén damel di kluster, sabab aya dina pods /etc/resolv.conf alamat CoreDNS heubeul (kube-dns) didaptarkeun, sarta kube-proxy ngarobah aturan iptables ti subnet heubeul ka nu anyar. Salajengna dina artikel ieu ditulis ngeunaan kamungkinan pilihan pikeun ngaleutikan downtime.

  9. Hayu urang ngalereskeun ConfigMap di namespace kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - ngaganti dieu clusterDNS ka alamat IP anyar tina layanan kube-dns: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - urang bakal ngalereskeun eta data.ClusterConfiguration.networking.serviceSubnet ka subnet anyar.

  10. Kusabab alamat kube-dns parantos robih, anjeun kedah ngapdet konfigurasi kubelet dina sadaya titik:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Sadaya anu tetep nyaéta ngamimitian deui sadaya pods dina kluster:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Ngaleutikan downtime

Pikiran ngeunaan cara ngaminimalkeun downtime:

  1. Saatos ngarobah pesawat kontrol manifests, nyieun hiji layanan kube-dns anyar, contona, jeung ngaran kube-dns-tmp jeung alamat anyar 172.24.0.10.
  2. nyieun if dina etcdhelper, anu moal ngarobih jasa kube-dns.
  3. Ngaganti alamat dina sakabéh kubelets ClusterDNS ka nu anyar, sedengkeun jasa heubeul bakal terus dianggo sakaligus jeung nu anyar.
  4. Antosan nepi ka pods kalawan aplikasi gulung leuwih ku sorangan alesan alam atawa dina waktu sapuk.
  5. Pupus jasa kube-dns-tmp jeung robah serviceSubnetCIDR pikeun layanan kube-dns.

Rencana ieu bakal ngidinan Anjeun pikeun ngaleutikan downtime ka ~samenit - pikeun lilana panyabutan jasa kube-dns-tmp jeung ngarobah subnet pikeun layanan nu kube-dns.

Modifikasi podNetwork

Dina waktos anu sami, urang mutuskeun pikeun ningali kumaha ngarobih podNetwork nganggo etcdhelper anu dihasilkeun. Runtuyan tindakan nyaéta kieu:

  • ngalereskeun configs di kube-system;
  • ngalereskeun manifes kube-controller-manager;
  • ngarobah podCIDR langsung di jsb;
  • reboot sadaya titik klaster.

Ayeuna langkung seueur ngeunaan tindakan ieu:

1. Ngaropea ConfigMap urang dina namespace kube-system:

kubectl -n kube-system edit cm kubeadm-config

- ngabenerkeun data.ClusterConfiguration.networking.podSubnet ka subnet anyar 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

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

2. Robah manifest controller-manajer:

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

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

3. Tingali dina nilai ayeuna .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses pikeun sakabéh titik klaster:

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. Ganti podCIDR ku nyieun parobahan langsung ka 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. Hayu urang pariksa yén podCIDR geus bener robah:

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. Hayu urang reboot sadaya titik klaster hiji-hiji.

7. Lamun ninggalkeun sahanteuna hiji titik podCIDR heubeul, teras kube-controller-manager moal tiasa ngamimitian, sareng pods dina kluster moal dijadwalkeun.

Nyatana, ngarobih podCIDR tiasa dilakukeun langkung saderhana (contona, janten). Tapi kami hoyong diajar kumaha damel sareng etcd langsung, sabab aya kasus nalika ngédit objék Kubernetes dina etcd - ngan varian mungkin. (Contona, anjeun teu tiasa ngan ukur ngarobih widang Service tanpa waktos downtime spec.clusterIP.)

hasil

Artikel ngabahas kamungkinan gawé bareng data dina jsb langsung, i.e. bypassing API Kubernetes. Kadang pendekatan ieu ngidinan Anjeun pikeun ngalakukeun "hal tricky". Urang diuji operasi dibikeun dina téks dina K8s klaster nyata. Sanajan kitu, status maranéhanana kesiapan pikeun pamakéan nyebar nyaeta PoC (bukti konsep). Ku alatan éta, upami anjeun hoyong nganggo vérsi anu dirobih tina utilitas etcdhelper dina klaster anjeun, lakukeun ku résiko anjeun nyalira.

PS

Baca ogé dina blog urang:

sumber: www.habr.com

Tambahkeun komentar