Yha rohkem ja rohkem pöördub klientide poole, kes soovivad tagada juurdepääsu Kubernetesi klastrisse, et saada ühendust klastris olevate teenustega: et saaks otse ühenduda teatud andmebaasi või teenusega, et siduda kohalikke rakendusi klastris olevate rakendustega…

Näiteks tekib vajadus ühendada oma lokaalmootor teenusega memcached.staging.svc.cluster.local. Me pakume sellist võimalust VPN-i kaudu klastris, millega klient ühendub. Selleks anname teada pod'ide, teenuste alamvõrgud ja edastame kliendile klastrite DNS-i. Nii et kui klient püüab teenusega ühendust saada memcached.staging.svc.cluster.local, siis päring läheb klastrite DNS-i ja vastuseks saab ta selle teenuse aadressi klastrite teenuste võrgus või pod'i aadressi.
K8s-kliima seadistame kubeadm'i abil, kus vaikimisi on teenuste alamvõrk - 192.168.0.0/16, ja pod'ide võrk - 10.244.0.0/16. Tavaliselt töötab kõik hästi, kuid on mõned asjad:
- Alamvõrk
192.168.*.*kasutatakse sageli kliendi kontorivõrkudes, ja veelgi sagedamini arendajate koduvõrkudes. Ja siis tekivad konfliktid: koduruuterid töötavad selles alamvõrgus ja VPN edastab need alamvõrgud kliendile klastrist. - Meil on mitmeid klasse (production klastrid, stage ja/või mitu dev-klassi). Nii et kõigis nendes on vaikimisi samad alamvõrgud pod'ide ja teenuste jaoks, mis tekitab suuri probleeme teenustega samaaegselt mitmetes klassides töötamiseks.
Oleme juba üsna kaua praktiseerinud erinevate alamvõrkude kasutamist teenustele ja pod'idele ühe projekti raames — et kõik klassid oleksid erinevate võrkudega. Kuid palju klasse on töös, mida ei soovi nullist üle teha, kuna neis on käivitatud palju teenuseid, stateful-rakendusi jne.
Ja siis küsisime endalt: kuidas muuta alamvõrku olemasolevas klassis?
Lahenduste otsimine
Levinum praktika on ümber luua kõik teenused tüüpi ClusterIP. Alternatiivina ja sellist asja:
Järgmine protsess on probleem: pärast kõike seadistamist kerkivad pod'id üles vana IP-ga DNS-nameserverina /etc/resolv.conf.
Kuna ma ei leidnud ikka veel lahendust, pidin kogu klastrit nullima kubeadm reset ja uuesti seadistama.
Kuid see ei sobi kõigile… Siin on rohkem üksikasjalikud sisendid meie juhtumi jaoks:
- Kasutatakse Flannelit;
- On klasse nii pilvedes kui ka riistvaral;
- Soovitame vältida kõigi teenuste korduvat juurutamist klastris;
- On vajadus teha kõik võimalikult väheste probleemidega;
- Kubernetes versioon — 1.16.6 (kuigi edasised toimingud on sarnased ka teiste versioonidega);
- Peamine ülesanne on asendada klastris, mis on üles seatud kubeadm-i abil teenuste alamvõrgu
192.168.0.0/16, see172.24.0.0/16.
Ja nii juhtus, et meil on juba ammu olnud huvi uurida, mida ja kuidas Kuberneteses etcd-s hoitakse, ning mida selle kõigega teha … Nii mõtlesime: "Miks mitte lihtsalt uuendada andmeid etcd-s, asendades vanad IP-aadressid (alamvõrk) uute?»
Otsides valmis tööriistu, et töötada andmete kohal etcd-s, ei leidnud me midagi, mis täielikult lahendaks seatud ülesande. (Muide, kui teate mingeid utiliite andmete otse töötlemiseks etcd-s — siis oleksime tänulikud linkide eest.) Kuid hea lähtepunkt oli (tänud selle autoritele!).
See utiliit oskab ühenduda etcd-ga sertifikaatide abil ja sealt andmeid lugeda komandodega ls, get, dump.
Me täiendame etcdhelperit
Järgmine mõte on loogiline: "Mis takistab selle utiliidi täiendamist, andes võimaluse andmete kirjutamiseks etcd-s?"
See on realiseeritud muudetud versioonis etcdhelperist, kus on kaks uut funktsiooni changeServiceCIDR ja changePodCIDR. Selle koodi saab vaadata .
Mida uued funktsioonid teevad? Algoritm changeServiceCIDR:
- loome deserialiseerija;
- kompime regulaaravaldisi CIDRi asendamiseks;
- läbime kõik teenused, mille tüüp on ClusterIP klastris:
- dekoodeerime väärtuse etcd-s Go-objektiks;
- regulaaravaldiste abil asendame aadressi kaks esimest baiti;
- mängime teenusele IP-aadressi uuest alamvõrgust;
- loome serialiseerija, teisendame Go-objekti protobufiks, kirjutame uued andmed etcd-sse.
Funktsioon changePodCIDR on põhjalikult sarnane changeServiceCIDR — ainult et teenuste spetsifikatsioonide redigeerimise asemel teeme seda sõlme jaoks ja muudame .spec.PodCIDR uue alamvõrgu vastu.
Praktika
ServiceCIDR vahetus
Tegevuskava, et saavutada seatud ülesanne — on väga lihtne, kuid see nõuab seisakut hetkel, kui kõik podid klastris uuesti luuakse. Pärast peamiste sammude kirjeldamist jagame ka mõtteid selle kohta, kuidas teoreetiliselt saate seda seisakut minimeerida.
Ettevalmistavad tegevused:
- vajalikku tarkvara installimine ja patcheeritud etcdhelperi koostamine;
- etcd varundamine ja
/etc/kubernetes.
Lühike tegevuskava serviceCIDR vahetamiseks:
- apiserver’i ja controller-manager’i manifestide muutmine;
- sertifikaatide uuendamine;
- ClusterIP teenuste muutmine etcd-s;
- kõigi pod'ide taaskäivitamine klastris.
Edasi on esitatud täielik teostuste jada üksikasjalikult.
1. Paigaldame etcd-klient andmete salvestamiseks:
apt install etcd-client2. Koostame etcdhelperi:
- Paigaldame golangi:
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 - Salvestame endale
etcdhelper.go, laadime sõltuvused ja koostame: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. Teeme etcd varukoopia:
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. Muudame Kubernetes control plane'i manifestid teenuse alamvõrgu osas. Failides /etc/kubernetes/manifests/kube-apiserver.yaml ja /etc/kubernetes/manifests/kube-controller-manager.yaml muudame parameetrit --service-cluster-ip-range uusaks alamvõrguks: 172.24.0.0/16 asemel 192.168.0.0/16.
5. Kuna muudame teenuse alamvõrku, kuhu kubeadm väljastab sertifikaadid apiserver'i jaoks (sh), tuleb need uuesti välja anda:
- Vaadake, milliste domeenide ja IP-aadresside jaoks praegune sertifikaat on väljastatud:
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 - Valmistame ette minimaalset konfiguratsiooni kubeadm jaoks:
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" # Master sõlme IP-aadress - Kustutame vanad crt ja key, kuna ilma selleta uus sertifikaat ei väljastu:
rm \/etc\/kubernetes\/pki\/apiserver.{key,crt} - Väljastame uuesti sertifikaadid API-serveri jaoks:
kubeadm init phase certs apiserver --config=kubeadm-config.yaml - Kontrollime, kas sertifikaat on väljastatud uue alamvõrgu jaoks:
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 - Pärast API-serveri sertifikaadi uuendamist käivitame selle konteineri uuesti:
docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart - Koodime uuesti konfi jaoks
admin.conf:kubeadm alpha certs renew admin.conf - Redigeerime andmeid etcd-s:
.\/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\/16Tähelepanu! Sel hetkel klastri domeenide resolveerimine peatub, kuna juba olemasolevates pod'ides on kirjutatud vana aadress CoreDNS (kube-dns), ning kube-proxy muutis iptables'i reegleid vanast alamvõrgust uue peale. Artiklis on edasi toodud, kuidas minimeerida seisakut.
/etc/resolv.confParandame ConfigMap'id nimede ruumis - kube-system
kubectl -n kube-system edit cm kubelet-config-1.16:— siia asendameclusterDNS
uue kube-dnsi teenuse IP-aadressiga:kubectl -n kube-system get svc kube-dnskubectl -n kube-system edit cm kubeadm-config.— parandamedata.ClusterConfiguration.networking.serviceSubnet
Kuna kube-dnsi aadress muutus, on vajalik uuendada kubeleti konfiguratsiooni kõigis sõlmedes:uue alamvõrgu vastu. - kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
Jääb üle taaskäivitada kõik pod'id klastris: - kubectl get pods --no-headers=true --all-namespaces |sed -r 's\/(S+)\s+(S+).*\/kubectl --namespace 1 delete pod 2\/e'
Seisaku minimeerimine
Mõtle, kuidas võiks daunitaimi minimeerida:
Pärast control plane'i manifestide muutmist luua uus kube-dnsi teenus, näiteks nimega
- kube-dns-tmp
ja uue aadressigaTeha172.24.0.10. - etcdhelperis, mis ei modifitseeri kube-dnsi teenust.
ifAsendada kõigis kubelet'ides aadress - ClusterDNS
uuega, samas kui vana teenus jätkab töötamist uue kõrval.Oodata, kuni rakenduste pod'id keerduvad kas ise loomulikelt või kokkulepitud ajal. - Kustutada teenus
- ja muuta
ja uue aadressigaserviceSubnetCIDRkube-dnsi teenuse jaoks.See plaan aitab minimeerida dauntaini ~ühe minutini — teenuse kustutamise ja alamvõrgu muutmise ajaks
Muutmine podNetwork ja uue aadressiga Samas tahame vaadata, kuidas modifitseerida podNetworki läbi loodud etcdhelperi. Tegevuste järjekord saab olema järgmine: kube-dns.
parandame konfiguratsioonid nimede ruumis
parandame kube-controller-manager'i manifesti;
- muudame podCIDR otse etcd's;
kubectl -n kube-system edit cm kubelet-config-1.16; - taaskäivitame kõik klastris sõlmed.
- Nüüd lähemalt nende tegevuste kohta:
- 1. Muudame ConfigMap'id nimede ruumis
— parandame
data.ClusterConfiguration.networking.podSubnet kubectl -n kube-system edit cm kubelet-config-1.16:
— parandame uue alamvõrgu jaoks kubectl -n kube-system edit cm kube-proxy data.config.conf.clusterCIDR: 10.55.0.0/16 10.55.0.0/16.
2. Muudame controller-manager'i manifesti: uue alamvõrgu jaoks vim /etc/kubernetes/manifests/kube-controller-manager.yaml.
--cluster-cidr=10.55.0.0/16
3. Vaata praeguseid väärtusi uue alamvõrgu jaoks .spec.podCIDR.
.spec.podCIDRs .InternalIP, .status.addresses, kõigi klastris sõlmede jaoks:, kubectl get no -o json | jq '[.items[] | {"name": .metadata.name, "podCIDR": .spec.podCIDR, "podCIDRs": .spec.podCIDRs, "InternalIP": (.status.addresses[] | select(.type == "InternalIP") | .address)}]' для всех узлов кластера:
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. Muudame podCIDR, tehes otse muudatusi etcd-s:
./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/165. Kontrollime, et podCIDR on tõepoolest muutunud:
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. Taaskäivitame järjest kõik klastris olevad sõlmed.
7. Kui ühelgi sõlmel jääb vana podCIDR, ei saa kube-controller-manager käivituda, ja pod'id klastris ei saa planeeritud olla.
Tegelikult on podCIDR-i muutmine võimalik ka lihtsamalt (näiteks, ). Kuid me tahtsime õppida, kuidas töötada etcd-ga otse, sest on juhtumeid, kus Kubernetes'e objektide muutmine etcd-s — ainus on võimalik variant. (Näiteks ei saa lihtsalt ilma seisakuta muuta Service väljal spec.clusterIP.)
Kokkuvõte
Artiklis käsitletakse võimalikku otsest töötamist andmetega etcd-s, st Kubernetes API-st mööda. Mõnikord võimaldab see lähenemine teha 'kavalad asjad'. Artiklis toodud toiminguid oleme testinud reaalsetes K8s-klastrites. Siiski, nende valmiduse staatus laiemaks kasutamiseks — PoC (proof of concept). Seetõttu, kui soovite kasutada muudetud versiooni utiliidist etcdhelper oma klastrites, tehke seda omal vastutusel.
P.S.
Lugege ka meie blogist:
- «»;
- «»;
- «»;
- «».
Allikas: habr.com
