etcd Kubernetes кластеріндегі деректермен тәжірибеміз тікелей (K8s API жоқ)

Клиенттер бізден кластер ішіндегі қызметтерге қол жеткізу үшін Kubernetes кластеріне кіруді қамтамасыз етуді сұрайды: кейбір дерекқорға немесе қызметке тікелей қосылу мүмкіндігі, кластер ішіндегі қолданбалармен жергілікті қолданбаны қосу...

etcd Kubernetes кластеріндегі деректермен тәжірибеміз тікелей (K8s API жоқ)

Мысалы, жергілікті құрылғыдан қызметке қосылу қажет memcached.staging.svc.cluster.local. Біз бұл мүмкіндікті клиент қосылатын кластердегі VPN арқылы қамтамасыз етеміз. Мұны істеу үшін біз подкасттардың, қызметтердің ішкі желілерін жариялаймыз және клиентке DNS кластерін итереміз. Осылайша, клиент қызметке қосылуға тырысқанда memcached.staging.svc.cluster.local, сұрау DNS кластеріне өтеді және жауап ретінде осы қызметтің мекенжайын кластерлік қызмет желісінен немесе подкаст мекенжайынан алады.

Біз K8s кластерлерін kubeadm арқылы конфигурациялаймыз, мұнда әдепкі қызмет ішкі желісі 192.168.0.0/16, ал түйіршіктер желісі болып табылады 10.244.0.0/16. Әдетте бәрі жақсы жұмыс істейді, бірақ бірнеше тармақ бар:

  • Ішкі желі 192.168.*.* жиі клиенттік кеңсе желілерінде, тіпті көбінесе әзірлеушілердің үй желілерінде қолданылады. Содан кейін біз қақтығыстармен аяқталамыз: үй маршрутизаторлары осы ішкі желіде жұмыс істейді және VPN бұл ішкі желілерді кластерден клиентке итереді.
  • Бізде бірнеше кластерлер бар (өндіріс, кезең және/немесе бірнеше әзірлеу кластері). Содан кейін, әдепкі бойынша, олардың барлығында қосқыштар мен қызметтер үшін бірдей ішкі желілер болады, бұл бірнеше кластердегі қызметтермен бір уақытта жұмыс істеу үшін үлкен қиындықтар тудырады.

Біз бір жоба аясында қызметтер мен подкасттар үшін әртүрлі ішкі желілерді пайдалану тәжірибесін әлдеқашан қабылдағанбыз - тұтастай алғанда, барлық кластерлердің әртүрлі желілері болуы үшін. Дегенмен, жұмыс істеп тұрған кластерлердің үлкен саны бар, мен оларды нөлден айналдырғым келмейді, өйткені олар көптеген қызметтерді, күйі бар қосымшаларды және т.б.

Содан кейін біз өзімізге сұрақ қойдық: бар кластердегі ішкі желіні қалай өзгертуге болады?

Шешімдерді іздеу

Ең көп таралған тәжірибе - қайта жасау барлық ClusterIP типті қызметтер. Опция ретінде, кеңес бере алады және осы:

Келесі процесте мәселе бар: барлығы конфигурацияланғаннан кейін, конфигурациялар /etc/resolv.conf ішінде DNS атау сервері ретінде ескі IP-мен келеді.
Мен әлі де шешім таба алмағандықтан, барлық кластерді kubeadm қалпына келтіру арқылы қалпына келтіріп, оны қайтадан іске қосуға тура келді.

Бірақ бұл бәріне жарамайды... Міне, біздің жағдайымыз үшін толығырақ кіріспе:

  • Фланель қолданылады;
  • Бұлттарда да, аппараттық құралдарда да кластерлер бар;
  • Мен кластердегі барлық қызметтерді қайта орналастырудан аулақ болғым келеді;
  • Жалпы алғанда, ең аз мәселелермен бәрін жасау қажет;
  • Kubernetes нұсқасы 1.16.6 (бірақ, келесі қадамдар басқа нұсқалар үшін ұқсас болады);
  • Негізгі міндет - кластерде kubeadm көмегімен қызметтік ішкі желімен орналастырылғанын қамтамасыз ету 192.168.0.0/16, онымен ауыстырыңыз 172.24.0.0/16.

Бізді Kubernetes-те не және қалай және etcd-де сақтауды, онымен не істеуге болатынын көптен бері қызықтырғанымыз болды... Сондықтан біз ойладық: «Неліктен ескі IP мекенжайларын (ішкі желі) жаңаларымен ауыстырып, etcd деректерін жаңартпаңыз?

etcd-де деректермен жұмыс істеуге арналған дайын құралдарды іздеп, біз мәселені толығымен шешетін ештеңе таппадық. (Айтпақшы, тікелей etcd ішінде деректермен жұмыс істеуге арналған утилиталар туралы білсеңіз, біз сілтемелерді бағалаймыз.) Дегенмен, жақсы бастау нүктесі etcdhelper OpenShift ішінен (авторларына рахмет!).

Бұл утилита сертификаттар арқылы etcd желісіне қосылып, пәрмендер арқылы сол жерден деректерді оқи алады ls, get, dump.

etcdhelper қосыңыз

Келесі ой қисынды: «etcd деректерін жазу мүмкіндігін қосу арқылы сізге бұл қызметтік бағдарламаны қосуға не кедергі?»

Ол екі жаңа функциясы бар etcdhelper бағдарламасының өзгертілген нұсқасы болды changeServiceCIDR и changePodCIDR. оған кодты көре аласыз осында.

Жаңа мүмкіндіктер не істейді? Алгоритм changeServiceCIDR:

  • сериядан шығарғышты жасау;
  • CIDR ауыстыру үшін тұрақты өрнек құрастыру;
  • біз кластердегі ClusterIP түрі бар барлық қызметтерден өтеміз:
    • etcd мәнін Go нысанына декодтау;
    • тұрақты өрнекті пайдаланып адрестің алғашқы екі байтын ауыстырамыз;
    • қызметке жаңа ішкі желіден IP мекенжайын тағайындаңыз;
    • сериализаторды жасаңыз, Go нысанын протобуфқа түрлендіріңіз, т.б. жаңа деректерді жазыңыз.

функция changePodCIDR негізінен ұқсас changeServiceCIDR - тек қызмет спецификациясын өңдеудің орнына біз оны түйін үшін жасаймыз және өзгертеміз .spec.PodCIDR жаңа ішкі желіге.

Тәжірибе

CIDR қызметін өзгерту

Тапсырманы орындау жоспары өте қарапайым, бірақ ол кластердегі барлық қосқыштар қайта жасалған кезде тоқтау уақытын қамтиды. Негізгі қадамдарды сипаттағаннан кейін біз теориялық тұрғыдан бұл тоқтап қалуды қалай азайтуға болатыны туралы ойлармен бөлісеміз.

Дайындық кезеңдері:

  • қажетті бағдарламалық құралды орнату және патчталған etcdhelper құрастыру;
  • сақтық көшірме т.б. және /etc/kubernetes.

CIDR қызметін өзгерту бойынша қысқаша әрекет жоспары:

  • аписервер мен контроллер-менеджер манифесттерін өзгерту;
  • сертификаттарды қайта шығару;
  • etcd ішіндегі ClusterIP қызметтерін өзгерту;
  • кластердегі барлық қосқыштарды қайта іске қосу.

Төменде егжей-тегжейлі әрекеттердің толық тізбегі берілген.

1. Деректерді шығару үшін etcd-client орнатыңыз:

apt install etcd-client

2. etcdhelper құрастырыңыз:

  • Голанг орнату:
    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
  • Біз өзіміз үшін сақтаймыз etcdhelper.go, тәуелділіктерді жүктеп алыңыз, жинаңыз:
    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. Сақтық көшірме жасау және т.б.:

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. Kubernetes басқару жазықтығының манифесттеріндегі қызмет ішкі желісін өзгертіңіз. Файлдарда /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml параметрді өзгерту --service-cluster-ip-range жаңа ішкі желіге: 172.24.0.0/16 орнына 192.168.0.0/16.

5. Біз kubeadm аписерверге (соның ішінде) сертификаттар беретін қызмет ішкі желісін өзгертіп жатқандықтан, оларды қайта шығару қажет:

  1. Ағымдағы сертификат қай домендер мен IP мекенжайлары үшін берілгенін көрейік:
    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. 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. Ескі crt және кілтті жойайық, өйткені онсыз жаңа сертификат берілмейді:
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. API сервері үшін сертификаттарды қайта шығарайық:
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. Сертификат жаңа ішкі желі үшін берілгенін тексерейік:
    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 сервер сертификатын қайта шығарғаннан кейін оның контейнерін қайта іске қосыңыз:
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. үшін конфигурацияны қалпына келтірейік admin.conf:
    kubeadm alpha certs renew admin.conf
  8. 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 

    Ескерту! Қазіргі уақытта домен ажыратымдылығы кластерде жұмысын тоқтатады, өйткені бұрыннан бар подкасттарда /etc/resolv.conf ескі CoreDNS мекенжайы (kube-dns) тіркелген және kube-прокси iptables ережелерін ескі ішкі желіден жаңасына өзгертеді. Әрі қарай мақалада тоқтау уақытын азайтудың ықтимал нұсқалары туралы жазылған.

  9. Атау кеңістігінде ConfigMap файлдарын түзетейік kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - мұнда ауыстырыңыз clusterDNS kube-dns қызметінің жаңа IP мекенжайына: kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - түзетеміз data.ClusterConfiguration.networking.serviceSubnet жаңа ішкі желіге.

  10. kube-dns мекенжайы өзгергендіктен, барлық түйіндерде kubelet конфигурациясын жаңарту қажет:
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. Кластердегі барлық қосқыштарды қайта іске қосу ғана қалады:
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

Тоқтау уақытын азайту

Тоқтау уақытын қалай азайтуға болатыны туралы ойлар:

  1. Басқару жазықтығының манифесттерін өзгерткеннен кейін жаңа kube-dns қызметін жасаңыз, мысалы, атымен kube-dns-tmp және жаңа мекенжай 172.24.0.10.
  2. Жасаңыз if etcdhelper ішінде, ол kube-dns қызметін өзгертпейді.
  3. Мекенжайды барлық кубелеттерде ауыстырыңыз ClusterDNS жаңасына, ал ескі қызмет жаңасымен бір уақытта жұмысын жалғастырады.
  4. Қолданбалары бар бөтелкелер табиғи себептермен немесе келісілген уақытта өздігінен ауысқанша күтіңіз.
  5. Қызметті жою kube-dns-tmp және өзгерту serviceSubnetCIDR kube-dns қызметі үшін.

Бұл жоспар тоқтау уақытын ~бір минутқа дейін азайтуға мүмкіндік береді - қызметті жою ұзақтығы үшін kube-dns-tmp және қызмет үшін ішкі желіні өзгерту kube-dns.

Модификация podNetwork

Сонымен бірге біз алынған etcdhelper көмегімен podNetwork-ті қалай өзгерту керектігін қарастыруды шештік. Әрекеттер реті келесідей:

  • конфигурацияларды түзету kube-system;
  • kube-контроллер-менеджер манифестін бекіту;
  • podCIDR тікелей etcd ішінде өзгерту;
  • барлық кластер түйіндерін қайта жүктеңіз.

Енді осы әрекеттер туралы толығырақ:

1. ConfigMaps қолданбасын аттар кеңістігінде өзгертіңіз kube-system:

kubectl -n kube-system edit cm kubeadm-config

- түзету data.ClusterConfiguration.networking.podSubnet жаңа ішкі желіге 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

- түзету data.config.conf.clusterCIDR: 10.55.0.0/16.

2. Контроллер-менеджер манифестін өзгертіңіз:

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

- түзету --cluster-cidr=10.55.0.0/16.

3. Ағымдағы мәндерді қараңыз .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses барлық кластер түйіндері үшін:

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. etcd файлына тікелей өзгертулер енгізу арқылы podCIDR ауыстырыңыз:

./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. PodCIDR шынымен өзгергенін тексерейік:

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. Барлық кластер түйіндерін бір-бірден қайта жүктейміз.

7. Кем дегенде бір түйін қалдырсаңыз ескі podCIDR, содан кейін kube-контроллер-менеджер іске қосылмайды және кластердегі қосқыштар жоспарланбайды.

Шын мәнінде, podCIDR өзгерту оңайырақ болуы мүмкін (мысалы, солай). Бірақ біз etcd-мен тікелей жұмыс істеуді үйренгіміз келді, өйткені Kubernetes нысандарын etcd-де өңдеу жағдайлары бар - жалғыз ықтимал нұсқа. (Мысалы, бос уақытсыз Қызмет өрісін жай ғана өзгерте алмайсыз spec.clusterIP.)

Нәтиже

Мақалада etcd деректерімен тікелей жұмыс істеу мүмкіндігі қарастырылады, яғни. Kubernetes API интерфейсін айналып өту. Кейде бұл тәсіл сізге «қиын нәрселерді» жасауға мүмкіндік береді. Біз мәтінде берілген амалдарды нақты K8s кластерлерінде сынап көрдік. Дегенмен, олардың кең тарауға дайын күйі PoC (тұжырымдаманың дәлелі). Сондықтан, etcdhelper утилитасының өзгертілген нұсқасын кластерлеріңізде пайдаланғыңыз келсе, мұны өз тәуекеліңізге байланысты орындаңыз.

PS

Біздің блогта да оқыңыз:

Ақпарат көзі: www.habr.com

пікір қалдыру