Po na drejtohen gjithnjĂ« e mĂ« shpesh klientĂ«t me kĂ«rkesĂ«n pĂ«r tĂ« siguruar akses nĂ« klasterin Kubernetes pĂ«r tĂ« pasur mundĂ«si pĂ«r tĂ« kontaktuar shĂ«rbimet brenda klasterit: pĂ«r t'u lidhur direkt me ndonjĂ« bazĂ« tĂ« dhĂ«nash ose shĂ«rbim, pĂ«r lidhjen e aplikacioneve lokale me aplikacionet brenda klasteritâŠ

Për shembull, krijohet nevoja për t'u lidhur nga makina juaj lokale me shërbimin memcached.staging.svc.cluster.local. Ne ofrojmë një mundësi të tillë përmes VPN brenda klasterit, me të cilin lidhet klienti. Për këtë, njoftojmë subnetet e pod-ëve, shërbimeve dhe dërgojmë DNS-in e klasterit te klienti. Kështu, kur klienti përpiqet të lidhet me shërbimin memcached.staging.svc.cluster.local, kërkesa shkon në DNS-in e klasterit dhe në përgjigje merr adresën e këtij shërbimi nga rrjeti shërbimesh të klasterit ose adresën e pod-it.
Ne konfigurojmë klasterët K8s me kubeadm, ku nënkuptohet që subneti i shërbimit është 192.168.0.0/16, dhe rrjeti i pod-ëve është 10.244.0.0/16. Zakonisht gjithçka funksionon mirë, por ka disa momente:
- Subneta
192.168.*.*shpĂ«rdoret shpesh nĂ« rrjetet e zyrave tĂ« klientĂ«ve, dhe mĂ« shpesh ende â nĂ« rrjetet shtĂ«piake tĂ« zhvilluesve. Dhe kĂ«shtu kemi konflikte: routerat shtĂ«piakĂ« punojnĂ« nĂ« kĂ«tĂ« nĂ«nrrjetĂ« dhe VPN e shtyn kĂ«to nĂ«nrrjeta nga klasteri te klienti. - Kemi disa klasterĂ« (klasterĂ« production, stage dhe/ose disa klasterĂ« dev). AtĂ«herĂ« nĂ« tĂ« gjithĂ« klasterĂ«t do tĂ« kenĂ« nĂ«nrrjeta tĂ« njĂ«jta pĂ«r podĂ«t dhe shĂ«rbimet, gjĂ« qĂ« krijon vĂ«shtirĂ«si tĂ« mĂ«dha pĂ«r tĂ« punuar njĂ«kohĂ«sisht me shĂ«rbimet nĂ« disa klasterĂ«.
Qysh prej njĂ« kohe tĂ« gjatĂ« kemi pranuar praktikĂ«n e pĂ«rdorimit tĂ« nĂ«nrrjetave tĂ« ndryshme pĂ«r shĂ«rbimet dhe podĂ«t brenda njĂ« projekti â nĂ« pĂ«rgjithĂ«si, pĂ«r tĂ« siguruar qĂ« tĂ« gjithĂ« klasterĂ«t tĂ« kenĂ« rrjete tĂ« ndryshme. MegjithatĂ«, ka njĂ« numĂ«r tĂ« madh klasterĂ«sh nĂ« punĂ«, tĂ« cilĂ«t nuk do tĂ« dĂ«shironim t'i rikthinim nga e para, pasi nĂ« to janĂ« aktivizuar shumĂ« shĂ«rbime, aplikacione stateful, etj.
Dhe kështu na erdhi në mendje pyetja: si ta ndryshojmë nënrrjetën në një klaster ekzistues?
Kërkimi i zgjidhjeve
Praktika mĂ« e zakonshme â pĂ«r ta krijuar pĂ«rsĂ«ri tĂ« gjitha shĂ«rbimet me tipin ClusterIP. Si njĂ« mundĂ«si, dhe diçka tĂ« tillĂ«:
Proçesi në vazhdim ka një problem: pas konfigurimit të gjithçkaje, podët dalin me IP-në e vjetër si një server DNS në /etc/resolv.conf.
Deri sa nuk e gjeta zgjidhjen, më duhej të rivendosja tërë klasterin me kubeadm reset dhe ta filloja atë përsëri.
Por, nuk është e përshtatshme për të gjithë... Këtu janë disa informacione më të detajuara për rastin tonë:
- Përdoret Flannel;
- Ka klastera si në re ashtu edhe në hardware;
- Do të doja të evitonim ri-deploy të të gjitha shërbimeve në klaster;
- Ka një nevojë për të bërë gjithçka me sa më pak probleme të jetë e mundur;
- Versioni i Kubernetes është 1.16.6 (megjithatë, veprimet e mëtejshme do të jenë të ngjashme edhe për versione të tjera);
- Detyra kryesore përfshin që në klasterin e ndërtuar me kubeadm me nënrrjetë shërbimi
192.168.0.0/16, ta zëvendësojmë atë me172.24.0.0/16.
Dhe ndodhi që na kishte interesuar prej një kohë të shihnim se çfarë dhe si ruhet në Kubernetes në etcd, çfarë mund të bëjmë me të... Prandaj menduam: "Pse të mos përditësojmë thjesht të dhënat në etcd, duke zëvendësuar IP-të e vjetra (nënrrjetë) me të rejat??»
Pasi kĂ«rkuam mjete tĂ« gatshme pĂ«r tĂ« punuar me tĂ« dhĂ«nat nĂ« etcd, nuk gjetĂ«m asgjĂ« qĂ« tĂ« zgjidhte plotĂ«sisht detyrĂ«n. (P.S. nĂ«se dini pĂ«r ndonjĂ« utilitare pĂ«r tĂ« punuar drejtpĂ«rdrejt me tĂ« dhĂ«nat nĂ« etcd â do jemi mirĂ«njohĂ«s pĂ«r lidhjet.) MegjithatĂ«, njĂ« pikĂ« e mirĂ« prej nga filluam ishte (faleminderit autorĂ«ve tĂ« tij!).
Ky utilitar ka aftësinë të lidhë me etcd përmes certifikateve dhe të lexojë të dhëna nga aty me anë të komandave ls, merr, dump.
Shtojmë etcdhelper
Mendimi tjetĂ«r Ă«shtĂ« i dukshĂ«m: «ĂfarĂ« e pengon tĂ« shtojmĂ« kĂ«tĂ« utilitar duke shtuar mundĂ«sinĂ« pĂ«r tĂ« shkruar tĂ« dhĂ«na nĂ« etcd?»
Ajo është realizuar në një version të modifikuar të etcdhelper me dy funksione të reja changeServiceCIDR dhe changePodCIDR. Në kodin e saj mund të shihni .
ĂfarĂ« bĂ«jnĂ« funksionet e reja? Algoritmi changeServiceCIDR:
- krijon një deserializues;
- kompilon një shprehje të rregullt për të zëvendësuar CIDR;
- kalon nëpër të gjitha shërbimet me llojin ClusterIP në klaster:
- dekodifikon vlerën nga etcd në objektin Go;
- me anë të shprehjes së rregullt zëvendëson dy bajtat e para të adresës;
- i jep shërbimit një adresë IP nga subneti i ri;
- krijon një serializues, transformon objektin Go në protobuf, shkruan të dhënat e reja në etcd.
Funksioni changePodCIDR nĂ« thelb Ă«shtĂ«analogjike changeServiceCIDR â vetĂ«m se nĂ« vend tĂ« redaktimit tĂ« specifikimeve tĂ« shĂ«rbimeve ne e bĂ«jmĂ« kĂ«tĂ« pĂ«r nyjĂ«n dhe ndryshojmĂ« .spec.PodCIDR nĂ« subnetin e ri.
Praktika
Ndryshimi i serviceCIDR
Plani pĂ«r realizimin e detyrĂ«s sĂ« caktuar Ă«shtĂ« shumĂ« i thjeshtĂ«, por pĂ«rfshin ndalesa gjatĂ« ripĂ«rtĂ«ritjes sĂ« tĂ« gjithĂ« podâave nĂ« klaster. Pas pĂ«rshkrimit tĂ« hapat kryesorĂ«, do tĂ« ndajmĂ« gjithashtu mendimet tona se si, nĂ« teori, mund tĂ« minimalizohet kjo ndalesĂ«.
Veprimet përgatitore:
- instalimi i softuerit të nevojshëm dhe ndërtimi i etcdhelper të patch-it;
- backup i etcd dhe
/etc/kubernetes.
Një plan i shkurtër veprimi për ndryshimin e serviceCIDR:
- ndryshimi i manifestëve të apiserver-it dhe controller-manager-it;
- rishpërndarja e certifikatave;
- ndryshimi i ClusterIP të shërbimeve në etcd;
- ri-ngritja e tĂ« gjithĂ« podâave nĂ« klaster.
Më poshtë është e paraqitur sekuenca e plotë e veprimeve në detaje.
1. Instaloni etcd-client për dump të të dhënave:
apt install etcd-client2. Ndërtojmë etcdhelper:
- Instaloni 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 - Ruani
etcdhelper.go, shkarkoni varësitë, ndërtoni: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. Bëni një backup të 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. Ndryshojmë subnetin e shërbimeve në manifestet e Kubernetes control plane. Në skedarët /etc/kubernetes/manifests/kube-apiserver.yaml dhe /etc/kubernetes/manifests/kube-controller-manager.yaml ndryshojmë parametrin --service-cluster-ip-range në subnetin e ri: 172.24.0.0/16 në vend të 192.168.0.0/16.
5. Pasi po ndryshojmĂ« subnetin e shĂ«rbimeve, pĂ«r tĂ« cilin kubeadm lĂ«shon certifikatat pĂ«r apiserverâin (pĂ«rfshirĂ«), Ă«shtĂ« e nevojshme tĂ« ripublikojmĂ«:
- Le të shikojmë për çfarë domenesh dhe IP adresash është lëshuar certifikati aktual:
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 - Të përgatisim një konfigurim minimal për 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 adresa e nodit master - Do të fshijmë crt dhe key-të e vjetra, pasi pa këtë certifikati i ri nuk do të lëshohet:
rm /etc/kubernetes/pki/apiserver.{key,crt} - Do të ripublikojmë certifikatat për API-serverin:
kubeadm init phase certs apiserver --config=kubeadm-config.yaml - Do të kontrollojmë që certifikati është lëshuar për subnetin e ri:
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 - Pas rivendosjes së certifikatës së API-serverit, do të rindiznim kontejnerin e tij:
docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart - Rregullojmë konfigurimin për
admin.conf:kubeadm alpha certs renew admin.conf - Modifikojmë të dhënat në 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/16Kujdes! Në këtë moment, rezolvimi i domain-eve në klaster pushon së funksionuari, pasi në pod-at ekzistues ka ende adresën e vjetër të CoreDNS (kube-dns), ndërsa kube-proxy e ka ndryshuar rregulloren e iptables nga subneti i vjetër në të riun. Më tej në artikull diskutohet për opsionet për të minimizuar pezullimin.
/etc/resolv.confKorrigjojmë ConfigMap-at në hapësirën emri - kube-system
kubectl -n kube-system edit cm kubelet-config-1.16:â kĂ«tu do tĂ« zĂ«vendĂ«sojmĂ«clusterDNS
me adresĂ«n e re IP tĂ« shĂ«rbimit kube-dns:kubectl -n kube-system get svc kube-dnskubectl -n kube-system edit cm kubeadm-config.â do tĂ« korrigjojmĂ«data.ClusterConfiguration.networking.serviceSubnet
Duke qenë se adresa e kube-dns ndryshoi, është e nevojshme të përditësojmë konfigurimin e kubelet në të gjithë nyjet:në subnetin e ri. - kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
kubeadm upgrade node phase kubelet-config && systemctl restart kubelet - Përfundoni ripërshtimin e të gjitha pod-eve në klaster:
kubectl get pods --no-headers=true --all-namespaces | sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'
Minimizimi i kohës së ndalimit
Mendoni se si mund të minimizoni kohën e ndalimit:
- Pas ndryshimeve në manifestet e kontrollit, krijoni një shërbim të ri kube-dns, për shembull me emrin
kube-dns-tmpdhe një adresë të re172.24.0.10. - Bëni
nësenë etcdhelper, i cili nuk do të modifikojë shërbimin kube-dns. - Zëvendësoni në të gjitha kubelet-at adresën
ClusterDNSme të re, ndërsa shërbimi i vjetër do të vazhdojë të funksionojë njëkohësisht me të riun. - Prisni deri sa pod-et me aplikacione të kalojnë ose vetë për arsye natyrore, ose në një kohë të caktuar.
- Fshini shërbimin
kube-dns-tmpdhe ndryshoniserviceSubnetCIDRpër shërbimin kube-dns.
Ky plan do tĂ« lejojĂ« minimizimin e kohĂ«s sĂ« ndalimit deri nĂ« ~minuta â pĂ«r kohĂ«n e fshirjes sĂ« shĂ«rbimit kube-dns-tmp dhe zĂ«vendĂ«simin e subnetit pĂ«r shĂ«rbimin kube-dns.
Modifikimi i podNetwork
Për njëherë, ne vendosëm të shihnim se si të modifikojmë podNetwork me ndihmën e etcdhelper-it të krijuar. Seanca e veprimeve është si më poshtë:
- rregulloni konfigurimet në
kubectl -n kube-system edit cm kubelet-config-1.16; - rregulloni manifestin e kube-controller-manager-it;
- ndryshoni podCIDR drejtpërdrejt në etcd;
- rindizni të gjithë nodet e klasterit.
Tani më shumë për këto veprime:
1. Modifikojmë ConfigMap të në hapësirën e emrave kubectl -n kube-system edit cm kubelet-config-1.16:
â do tĂ« korrigjojmĂ« â rregullojmĂ« data.ClusterConfiguration.networking.podSubnet nĂ« maskĂ« tĂ« re 10.55.0.0/16.
kubectl -n kube-system edit cm kube-proxy â rregullojmĂ« data.config.conf.clusterCIDR: 10.55.0.0/16.
2. Modifikojmë manifestin e menaxherit të controller-it:
vim /etc/kubernetes/manifests/kube-controller-manager.yaml â rregullojmĂ« --cluster-cidr=10.55.0.0/16.
3. Shohim vlerat aktuale .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses për të gjithë nodet e klasterit:
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. Zëvendësojmë podCIDR, duke bërë rregullime drejtpërdrejt në 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/165. Do të kontrollojmë nëse podCIDR me të vërtetë është ndryshuar:
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. Ne do të rindezim një nga një të gjithë nyjet e klasterit.
7. Nëse të paktën një nyje e lë podCIDR të vjetër, atëherë kube-controller-manager nuk do të mund të startojë, dhe pod-et në klaster nuk do të planifikohen.
Në të vërtetë, mund të bëhet dhe më lehtë (p.sh., ). Por ne dëshironim të mësoheshim të punonim me etcd drejtpërdrejt, sepse ka raste kur modifikimi i objekteve Kubernetes në etcd është i vetmi opsion i mundshëm. (P.sh., nuk mund ta ndryshosh në mënyrë të thjeshtë fushën spec.clusterIP.)
Përfundimi
Artikulli shqyrton mundĂ«sinĂ« e punĂ«s me tĂ« dhĂ«nat nĂ« etcd drejtpĂ«rdrejt, pra, duke e anashkaluar Kubernetes API. NdonjĂ«herĂ«, ky qasje lejon tĂ« bĂ«hen 'trikĂ« tĂ« zgjuara'. Operacionet e paraqitura nĂ« tekst i kemi testuar nĂ« klastera tĂ« vĂ«rtetĂ« K8s. MegjithatĂ«, statusi i tyre i gatishmĂ«risĂ« pĂ«r pĂ«rdorim tĂ« gjerĂ« Ă«shtĂ« â PoC (provĂ« e konceptit). Prandaj, nĂ«se dĂ«shironi tĂ« pĂ«rdorni versionin e modifikuar tĂ« utilitetit etcdhelper nĂ« klasterĂ«t tuaj, bĂ«jeni kĂ«tĂ« me rrezikun tuaj.
P.S.
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «»;
- «».
Burimi: habr.com
