Shpesh po na drejtohen klientët me kërkesën për të siguruar qasje në Kubernetes cluster për mundësinë e qasjes në shërbimet brenda klasterit: që të mund të lidhen direkt me ndonjë bazë të dhënash ose shërbim, për lidhjen e aplikacionit lokal me aplikacione brenda klasterit...

Për shembull, lind nevoja për t'u lidhur nga makina juaj lokale me shërbimin memcached.staging.svc.cluster.local. Ne ofrojmë këtë mundësi përmes VPN brenda klasterit, të cilit i bashkohet klienti. Për këtë, ne shpallim subnet-et e podëve, shërbimeve dhe e dërgojmë DNS-in e klasterit tek 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ëti shërbimi nga rrjeti i shërbimeve të klasterit ose adresën e pod-it.
Ne konfigurojmĂ« K8s-kat me kubeadm, ku rrjeti i shĂ«rbimeve pĂ«rveçse â 192.168.0.0/16, dhe rrjeti i podĂ«ve â 10.244.0.0/16. Zakonisht gjithçka funksionon mirĂ«, por ka disa momente:
- Rrjeti
192.168.*.*pĂ«rdoret shpesh nĂ« rrjetet zyrtare tĂ« klientĂ«ve, dhe mĂ« shpesh â nĂ« rrjetet shtĂ«piake tĂ« zhvilluesve. Dhe kĂ«shtu, kemi pĂ«rplasje: routerĂ«t shtĂ«piakĂ« funksionojnĂ« nĂ« kĂ«tĂ« rrjet dhe VPN dĂ«rgon kĂ«to rrjete nga klasteri tek klienti. - Kemi disa klasterĂ« (klasterĂ« prodhimi, stage, dhe/ose disa klasterĂ« dev). AtĂ«herĂ« nĂ« tĂ« gjithĂ« ata do tĂ« ketĂ« rrjete tĂ« njĂ«jta pĂ«r podĂ«t dhe shĂ«rbimet, çka krijon vĂ«shtirĂ«si tĂ« mĂ«dha pĂ«r punĂ«n e pĂ«rbashkĂ«t me shĂ«rbimet nĂ« disa klasterĂ«.
Kemi pranuar praktikĂ«n pĂ«r pĂ«rdorimin e rretheve tĂ« ndryshme pĂ«r shĂ«rbimet dhe podĂ«t brenda njĂ« projekti â thjesht qĂ« tĂ« gjithĂ« klasterĂ«t tĂ« kenĂ« rrjete tĂ« ndryshme. MegjithatĂ«, ka shumĂ« klasterĂ« nĂ« punĂ« qĂ« nuk do tĂ« ishin dĂ«shirat pĂ«r t'i rikthyer nga e para, pasi aty janĂ« tĂ« nisura shumĂ« shĂ«rbime, aplikacione stateful, etj.
Dhe atëherë na erdhi mendja: si mund ta ndryshojmë subnet-in në një klaster ekzistues?
Kërkimi i zgjidhjeve
Praktika mĂ« e zakonshme â Ă«shtĂ« ri-krijimi i tĂ« gjithĂ« shĂ«rbimeve me tipin ClusterIP. Si alternativĂ«, dhe kĂ«shtu:
Procesi në vijim ka një problem: pas konfigurimit të gjithçkaje, pod-et dalin me IP-në e vjetër si server DNS në /etc/resolv.conf.
Pasi akoma nuk e kam gjetur zgjidhjen, më duhej të riformatoja klasterin e gjithë duke përdorur kubeadm reset dhe ta init përsëri.
Por kjo nuk i përshtatet të gjithëve⊠Këtu janë disa hyrje më të detajuar për rastin tonë:
- Përdoret Flannel;
- Ekzistojnë klastera si në re ashtu edhe në harduer;
- Do të doja të shmang ndërrimin e përsëritur të të gjitha shërbimeve në klaster;
- Ka nevojë për të bërë gjithçka me sa më pak probleme të jetë e mundur;
- Versions Kubernetes - 1.16.6 (sidoqoftë, veprimet e mëtejshme do të jenë të ngjashme edhe për versione të tjera);
- Detyra kryesore përfshin që në klasterin që është krijuar me kubeadm me subnet shërbimi
192.168.0.0/16, ta zëvendësojmë atë me172.24.0.0/16.
Dhe ndodhi që na kishte interesuar për një kohë të gjatë të shihnim se çfarë dhe si ruhet në Kubernetes në etcd, çfarë mund të bëhet me të... Pra, menduam: "Pse të mos përditësojmë thjesht të dhënat në etcd, duke zëvendësuar adresat e vjetra IP (subnet) me të rejat?»
Pas kërkimit të mjeteve të gatshme për punë me të dhënat në etcd, nuk gjetëm asgjë që të zgjidhte plotësisht problemin e ngritur. (P.S. nëse dini për ndonjë utilitar për të punuar drejtpërdrejt me të dhënat në etcd - do të ishim mirënjohës për lidhjet.) Megjithatë, një pikë e mirë fillestare ishte (faleminderit autores së tij!).
Ky utilitar mund të lidhet me etcd nëpërmjet certifikatave dhe të lexojë të dhëna atje duke përdorur komandat ls, merr, dump.
Shtojmë etcdhelper
Mendimi i ardhshĂ«m Ă«shtĂ« i natyrshĂ«m: "ĂfarĂ« pengon tĂ« shkruajmĂ« kĂ«tĂ« utilitar duke i shtuar mundĂ«sinĂ« pĂ«r tĂ« shkruar tĂ« dhĂ«na nĂ« etcd?"
Ai u realizua në një version të modifikuar të etcdhelper me dy funksione të reja changeServiceCIDR dhe changePodCIDR. Mund të shihni për kodin e saj .
ĂfarĂ« bĂ«jnĂ« funksionet e reja? Algoritmi changeServiceCIDR:
- krijon një deserializues;
- kompilon një shprehje të rregullt për zëvendosjen e CIDR;
- kalon përmes të gjitha shërbimeve me llojin ClusterIP në klaster:
- dekodosh vlerën nga etcd në një objekt në Go;
- përdor një shprehje të rregullt për të zëvendësuar dy bajtat e parë të adresës;
- i cakton shërbimit një adresë IP nga subneti i ri;
- krijon një serializues, e kthen objektin Go në protobuf, shkruan të dhënat e reja në etcd.
Funksioni changePodCIDR esencialisht Ă«shtĂ« e ngjashme changeServiceCIDR â vetĂ«m nĂ« vend tĂ« redaktimit tĂ« specifikimeve tĂ« shĂ«rbimeve ne e bĂ«jmĂ« kĂ«tĂ« pĂ«r nodin dhe ndryshojmĂ« .spec.PodCIDR nĂ« subnetin e ri.
Praktika
Ndryshimi i serviceCIDR
Plani pĂ«r realizimin e problemit tĂ« ngritur - Ă«shtĂ« shumĂ« i thjeshtĂ«, por nĂ«nkupton ndĂ«rrimin gjatĂ« kohĂ«s sĂ« krijimit tĂ« tĂ« gjitha podâave nĂ« klaster. Pas pĂ«rshkrimit tĂ« hapave kryesorĂ« do tĂ« ndajmĂ« gjithashtu mendimet se si teorikisht mund ta minimizojmĂ« kĂ«tĂ« thjesht.
Veprime përgatitore:
- instalimi i softuerit të nevojshëm dhe ndërtimi i etcdhelper të propatuar;
- backup i etcd dhe
/etc/kubernetes.
Një plan i shkurtër veprimesh për ndryshimin e serviceCIDR:
- ndryshimi i manifestëve të apiserver dhe controller-manager;
- ri-lëshimi i certifikatave;
- ndryshimi i shërbimeve ClusterIP në etcd;
- rindërtojmë të gjitha pod-et në klaster.
Më poshtë paraqitet sekvenca e plotë e hapat në detaje.
1. Instalojmë etdc-client për dump të të dhënave:
apt install etcd-client2. Krijojmë etcdhelper:
- Instalojmë 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 - Ruajmë
etcdhelper.go, shkarkojmë varësitë, krijojmë: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ëjmë 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ë subnet-in e shërbimeve në manifestët e planeve të kontrollit të Kubernetes. Në skedarët /etc/kubernetes/manifests/kube-apiserver.yaml dhe /etc/kubernetes/manifests/kube-controller-manager.yaml ndryshojmë parametrin --service-cluster-ip-range në subnet-in e ri: 172.24.0.0/16 në vend të 192.168.0.0/16.
5. Pasi ndryshojmë subnet-in e shërbimeve, për të cilin kubeadm lëshon certifikata për apiserver (përfshirë), është e nevojshme të ri-lëshojmë ato:
- Shikojmë për cilat domene dhe adresa IP është lëshuar aktualisht certifikata:
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" # Adresa IP e nodit kryesor - Të heqim certifikat e vjetra crt dhe key, sepse pa këtë certifikata e re nuk do të lëshohet:
rm /etc/kubernetes/pki/apiserver.{key,crt} - Rialësojmë certifikatat për API-serverin:
kubeadm init phase certs apiserver --config=kubeadm-config.yaml - Kontrollojmë nëse certifikata është lëshuar për subnet-in 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 rialëshimit të certifikatës së API-serverit, rindërtojmë containerin e tij:
docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart - Rikrijojmë konfigurimin për
admin.conf:kubeadm alpha certs renew admin.conf - Redaktojmë 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 domeneve ndalon nĂ« klaster, pasi nĂ« podâĂ«t ekzistues Ă«shtĂ«
/etc/resolv.confshĂ«nuar adresa e vjetĂ«r CoreDNS (kube-dns), ndĂ«rsa kube-proxy ka ndryshuar rregullat e iptables nga subneti i vjetĂ«r nĂ« tĂ« riun. MĂ« pas nĂ« artikull do tĂ« flitet pĂ«r mundĂ«sitĂ« pĂ«r tĂ« minimizuar kohĂ«n e pezullimit. - Do tĂ« korrigjojmĂ« ConfigMapâĂ«t nĂ« hapĂ«sirĂ«n emĂ«rorĂ«
kube-system:kubectl -n kube-system edit cm kubelet-config-1.16â kĂ«tu do tĂ« zĂ«vendosim
clusterDNSme adresĂ«n e re IP tĂ« shĂ«rbimit kube-dns:kubectl -n kube-system get svc kube-dns.kubectl -n kube-system edit cm kubeadm-configâ do tĂ« korrigjojmĂ«
data.ClusterConfiguration.networking.serviceSubnetnë subnetin e ri. - Duke qenë se adresa kube-dns ka ndryshuar, është e nevojshme të përditësojmë konfigurimin e kubelet në të gjitha nyjet:
kubeadm upgrade node phase kubelet-config && systemctl restart kubelet - Kjo mbetet pĂ«r tĂ« rinisur tĂ« gjitha podâĂ«t 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 pezullimeve
Mendime për si të minimizohet kohën e pezullimit:
- Pas ndryshimeve të manifestëve të planeve kontrolluese, krijoni një shërbim të ri kube-dns, p.sh., me emrin
kube-dns-tmpdhe adresën e re172.24.0.10. - Bëni
nĂ«senĂ« etcdhelper, i cili nuk do tĂ« modifikojĂ« shĂ«rbimin kube-dns. - ZĂ«vendĂ«soni nĂ« tĂ« gjithĂ« kubeletâĂ«t adresĂ«n
ClusterDNSme tĂ« rejĂ«n, ndĂ«rsa shĂ«rbimi i vjetĂ«r do tĂ« vazhdojĂ« tĂ« funksionojĂ« paralelisht me tĂ« riun. - Prisni derisa podâĂ«t me aplikacione tĂ« kalojnĂ« ose pĂ«r shkak tĂ« arsyeve 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Ă« pezullimit deri nĂ« ~minuta â nĂ« kohĂ«n e fshirjes sĂ« shĂ«rbimit kube-dns-tmp dhe zĂ«vendĂ«simit tĂ« subnetit pĂ«r shĂ«rbimin kube-dns.
Modifikimi i podNetwork
NĂ« tĂ« njĂ«jtĂ«n kohĂ«, ne vendosĂ«m tĂ« shohim se si tĂ« modifikojmĂ« podNetwork me ndihmĂ«n e etcdhelperâit qĂ« Ă«shtĂ« krijuar. Sequenta e veprimeve Ă«shtĂ« si mĂ« poshtĂ«:
- korrigjojmë konfigurimet në
kube-system; - korrigjojmĂ« manifestin e kube-controller-managerâit;
- ndryshojmë podCIDR direkt në etcd;
- Rinisim të gjitha nyjet e klasterit.
Tani më shumë për këto veprime:
1. ModifikojmĂ« ConfigMapâĂ«t nĂ« hapĂ«sirĂ«n emĂ«rorĂ« kube-system:
kubectl -n kube-system edit cm kubeadm-config â korrigjojmĂ« data.ClusterConfiguration.networking.podSubnet me subnetin e ri 10.55.0.0/16.
kubectl -n kube-system edit cm kube-proxy â korrigjojmĂ« data.config.conf.clusterCIDR: 10.55.0.0/16.
2. ModifikojmĂ« manifestin e controller-managerâit:
vim /etc/kubernetes/manifests/kube-controller-manager.yaml â korrigjojmĂ« --cluster-cidr=10.55.0.0/16.
3. Shikoni vlerat aktuale .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses për të gjitha nyjet 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. Do të zëvendësojmë podCIDR duke bërë ndryshime direkt 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 në 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. Gradualisht do të rinisim të gjitha nyjat e klasterit.
7. Nëse të paktën një nyje ruan podCIDR-in e vjetër, atëherë kube-controller-manager nuk do të mund të nisë, dhe pod-et në klaster nuk do të planifikohen.
NĂ« tĂ« vĂ«rtetĂ«, ndryshimi i podCIDR mund tĂ« bĂ«het edhe mĂ« thjeshtĂ« (p.sh. ). Por ne do tĂ« donim tĂ« mĂ«sonim tĂ« punojmĂ« direkt me etcd, sepse ka rastet kur redaktimi i objekteve Kubernetes nĂ« etcd â Ă«shtĂ« opsioni i vetĂ«m mĂ« i mundshĂ«m. (P.sh., nuk mund tĂ« ndryshoni thjesht fushĂ«n spec.clusterIP.)
Përfundimi
Ky artikull shqyrton mundĂ«sinĂ« e punĂ«s me tĂ« dhĂ«nat nĂ« etcd direkt, duke anashkaluar Kubernetes API. NdonjĂ«herĂ« ky qasje lejon tĂ« bĂ«ni âtruke tĂ« zgjuaraâ. Operacionet e paraqitura nĂ« tekst ne i kemi testuar nĂ« klasterĂ«t e vĂ«rtetĂ« K8s. MegjithatĂ«, statusi i tyre i gatshmĂ«risĂ« pĂ«r pĂ«rdorim tĂ« gjerĂ« â PoC (provĂ« e konceptit). Prandaj, nĂ«se doni tĂ« pĂ«rdorni njĂ« version tĂ« modifikuar tĂ« utilitarit etcdhelper nĂ« klasterĂ«t tuaj, bĂ«jeni kĂ«tĂ« me rrezik.
P.S.
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «»;
- «».
Burimi: habr.com
