Artikli tÔlge on koostatud kursuse alguse eelÔhtul .

Kui te seda loete, olete tĂ”enĂ€oliselt kuulnud Kubernetesest (ja kui ei, siis kuidas te siia sattusite?). Aga mis Kubernetes tegelikult on? See on ? ĐлО ? ЧŃĐŸ ĐČĐŸĐŸĐ±ŃĐ” ŃŃĐŸ Đ·ĐœĐ°ŃĐžŃ?
Ausalt öeldes ei ole ma 100% kindel. Aga arvan, et on huvitav uurida, mis toimub Kuberneteses selle paljude abstraktsioonikihtide all. Nii et huvi pÀrast, vaatame, kuidas tegelikult nÀeb vÀlja minimaalne "Kubernetes klaster". (See on palju lihtsam kui .)
Ma arvan, et teil on pÔhiteadmised Kubernetesest, Linuxist ja konteineritest. KÔik, millest me siin rÀÀgime, on mÔeldud ainult uurimiseks/Ôppimiseks, Àrge kÀitage seda tootmises!
Ălevaade
Kubernetes sisaldab palju komponente. Vastavalt , nÀeb arhitektuur vÀlja jÀrgmiselt:

Siin on nÀidatud vÀhemalt kaheksa komponenti, kuid enamik neist me ignoreerime. Soovin mÀrkida, et minimaalne asi, mida tÔeliselt vÔiks nimetada Kuberneteseks, koosneb kolmest pÔhikomponendist:
- kubelet
- kube-apiserver (mis sĂ”ltub etcd-st â selle andmebaasist)
- konteinerite töötlemiskeskkond (antud juhul Docker)
Vaatame, mida öeldakse igaĂŒhe kohta dokumentatsioonis (., .). Esiteks kubelet:
Agent, mis töötab igas klastris asuvas sÔlmes. See jÀlgib, et konteinerid oleksid podis kÀimas.
KÔlab piisavalt lihtsalt. Aga kuidas on konteinerite töötlemiskeskkonnaga (container runtime)?
Konteinerite töötlemiskeskkond on programm, mis on mÔeldud konteinerite kÀitamiseks.
VĂ€ga informatiivne. Aga kui olete Dockeriga tuttav, peaks teil olema ĂŒldine arusaam sellest, mida see teeb. (Detailid konteinerite töötlemiskeskkonna ja kubeleti vastutuse jaotamise vahel on tegelikult ĂŒsna peened ja ma ei sĂŒvene nendesse siin.)
ma saan kasutada API-server?
API-server on Kubernetes juhtpaneeli komponent, mis esindab Kubernetes API-t. API-server on Kubernetes juhtpaneeli kliendipoolne osa.
IgaĂŒhel, kes on kunagi Kubernetesega midagi teinud, tuli API-ga suhelda kas otse vĂ”i kubectl'i kaudu. See on sĂŒda, mis muudab kĂ”ik need YAML-id, mida me kĂ”ik tunneme ja armastame (?), töötavaks infrastruktuuriks. Tundub ilmselge, et API peab olema meie minimaalses konfiguratsioonis kohal.
Eeltingimused
- Virtuaalne vĂ”i fĂŒĂŒsiline Linuxi masin root-privileegidega (kasutan virtuaalmasinas Ubuntu 18.04).
- Ja see on kÔik!
Igav paigaldamine
Meie kasutatavale masinale tuleb paigaldada Docker. (Ma ei plaani detailselt seletada, kuidas Docker ja konteinerid toimivad; kui see teid huvitab, on ). Lihtsalt paigaldame selle kasutades apt:
$ sudo apt install docker.io
$ sudo systemctl start docker PÀrast seda peame hankima Kubernetes'e binaarfailid. Tegelikult on meie "klastri" algseks kÀivitamiseks vajalik ainult kubelet, kuna teiste serveri komponentide kÀitamiseks saame kasutada kubelet. Kliendiga suhtlemiseks pÀrast meie klastri töölepanekut kasutame ka kubectl.
$ curl -L https://dl.k8s.io/v1.18.5/kubernetes-server-linux-amd64.tar.gz > server.tar.gz
$ tar xzvf server.tar.gz
$ cp kubernetes/server/bin/kubelet .
$ cp kubernetes/server/bin/kubectl .
$ ./kubelet --version
Kubernetes v1.18.5 Mis juhtub, kui me lihtsalt kÀivitame kubelet?
$ ./kubelet
F0609 04:03:29.105194 4583 server.go:254] mkdir /var/lib/kubelet: permission denied kubelet peab töötama root kasutajana. Piisavalt loogiline, kuna ta peab kogu sÔlme haldama. Vaatame tema parameetreid:
$ ./kubelet -h
$ ./kubelet -h | wc -l
284Vau, nii palju valikuid! Ănneks vajame ainult mĂ”nda neist. Siin on ĂŒks meile huvitav parameeter:
--pod-manifest-path stringTeekond katalooge, mis sisaldab staatiliste pod'ide faile, vĂ”i tee staatiliste pod'ide kirjelduse failini. Punktiga algavad failid jĂ€etakse kĂ”rvale. (AEGUNUD: see parameeter tuleks seadistada konfiguratsioonifailis, mis antakse Kubelet'ile lĂ€bi âconfig valiku. Lisainformatsiooni leiate .)
See parameeter vĂ”imaldab meil kĂ€itada â pod'id, mida ei hallata Kubernetes API kaudu. Staatilisi pod'e kasutatakse harva, kuid need on vĂ€ga mugavad klastri kiireks ĂŒles seadmiseks, just seda me vajame. Ignorerime selle valjuhÀÀlse hoiatuse (veel kord, Ă€rge kĂ€itage seda tootmises!) ja vaatame, kas suudame pod'i kĂ€ivitada.
Esmalt loome katalooge staatiliste pod'ide jaoks ja kÀivitame kubelet:
$ mkdir pods
$ sudo ./kubelet --pod-manifest-path=podsSeejÀrel, teises terminalis/tmux aknas/vÔi kuskil mujal, loome pod'i manti:
$ cat < pods/hello.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- image: busybox
name: hello
command: ["echo", "hello world!"]
EOF kubelet algab kirjutama erinevaid hoiatusi ja tundub, et midagi ei toimu. Aga see ei ole tÔsi! Vaatame Dockerit:
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c8a35e26663 busybox "echo 'hello world!'" 36 seconds ago Exited (0) 36 seconds ago k8s_hello_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_4
68f670c3c85f k8s.gcr.io/pause:3.2 "/pause" 2 minutes ago Up 2 minutes k8s_POD_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_0
$ sudo docker logs k8s_hello_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_4
hello world! kubelet lugesin konteineri manifesti ja andsin Dockerile kĂ€su kĂ€ivitada paar konteinerit vastavalt meie spetsifikatsioonile. (Kui teid huvitab "pause" konteiner, siis see on Kubernetes'i nipp â lisainfot leiate .) Kubelet kĂ€ivitab meie konteineri busybox antud kĂ€suga ja taaskĂ€ivitab seda lĂ”putult, kuni staatiline pod on kustutatud.
Palju Ă”nne! Me just leiutasime ĂŒhe kĂ”ige keerulisema viisi teksti terminalis kuvamiseks!
KĂ€ivitame etcd
Meie lÔppeesmÀrk on kÀivitada Kubernetes API, kuid selleks peame esmalt kÀivitama . KÀivitage minimaalne etcd klaster, paigutades selle seadistused kausta pods (nÀiteks, pods/etcd.yaml):
apiVersion: v1
kind: Pod
metadata:
name: etcd
namespace: kube-system
spec:
containers:
- name: etcd
command:
- etcd
- --data-dir=/var/lib/etcd
image: k8s.gcr.io/etcd:3.4.3-0
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
hostNetwork: true
volumes:
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-dataKui olete kunagi töötanud Kubernetesega, peaksid sellised YAML-failid olema teile tuttavad. Siin tuleks mÀrkida ainult kahte punkti:
Oleme mountinud hostide kausta /var/lib/etcd pod'i, et etcd andmed sÀiliksid pÀrast taaskÀivitamist (kui seda ei tehta, siis klastriseisund kustutatakse iga pod'i taaskÀivitamisega, mis ei ole isegi kÔige minimaalsema Kubernetes'i installatsiooni jaoks hea).
Me oleme seadnud hostNetwork: true. See parameeter, mis ei ole ĂŒllatav, seadistab etcd kasutama hosti vĂ”rku sisemise pod'i vĂ”rgu asemel (see lihtsustab API-serveri jaoks etcd klastrite leidmist).
Lihtne kontroll nÀitab, et etcd on tÔepoolest localhostis kÀimas ja salvestab andmeid kettale:
$ curl localhost:2379/version
{"etcdserver":"3.4.3","etcdcluster":"3.4.0"}
$ sudo tree /var/lib/etcd/
/var/lib/etcd/
âââ member
âââ snap
â âââ db
âââ wal
âââ 0.tmp
âââ 0000000000000000-0000000000000000.walAPI-serveri kĂ€ivitamine
Kubernetes API-serveri kÀivitamine on veelgi lihtsam. Ainus parameeter, mida tuleb edastada, --etcd-servers, teeb seda, mida ootate:
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
command:
- kube-apiserver
- --etcd-servers=http://127.0.0.1:2379
image: k8s.gcr.io/kube-apiserver:v1.18.5
hostNetwork: true Asetage see YAML-fail katalooge pods, ja API-server kĂ€ivitub. Kontrollimine kasutades curl nĂ€itab, et Kubernetes API kuulab porti 8080 tĂ€ieliku juurdepÀÀsuga â autentimist ei nĂ”uta!
$ curl localhost:8080/healthz
ok
$ curl localhost:8080/api/v1/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "59"
},
"items": []
}(Ărge kĂ€itage seda tootmises! Ma olin natuke ĂŒllatunud, et vaikeseade on nii ebaturvaline. Kuid ma arvan, et see on tehtud arenduse ja testimise lihtsustamiseks.)
Ja meeldiv ĂŒllatus, et kubectl töötab vĂ€lja pakendamata ilma igasuguste lisaseadeteta!
$ ./kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:47:41Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:39:24Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
$ ./kubectl get pod
No resources found in default namespace.Probleem
Kuid kui sĂŒveneda, siis tundub, et midagi on valesti:
$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.KĂ€ivitunud staatilised podid on kadunud! Tegelikult ei tuvastata meie kubelet-sĂ”lme ĂŒldse:
$ ./kubectl get nodes
No resources found in default namespace.Mis toimub? Kui mĂ€letate, siis mĂ”ned lĂ”igud tagasi kĂ€ivitasime kubeleti ÀÀrmiselt vĂ€ikese kĂ€surea parameetrite kogumiga, seega ei tea kubelet, kuidas API-serveriga ĂŒhendust vĂ”tta ja oma staatust teavitada. Dokumentatsiooni uurides leidsime sobiva lipu:
--kubeconfig string
Tee faili kubeconfig, milles on mÀÀratud, kuidas API-serveritega ĂŒhendust vĂ”tta. Kui --kubeconfig on olemas, siis lĂŒlitub API-serveri reĆŸiimi, puudumine --kubeconfig lĂŒlitab iseseisva reĆŸiimi sisse.
Kogu selle aja oleme teadmata kĂ€ivitanud kubeleti «iseseisvas reĆŸiimis». (Kui me oleksime pedantsed, vĂ”iks iseseisvat kubeleti reĆŸiimi pidada «minimaalselt elujĂ”uliseks Kuberneteseks», aga see oleks igav). Et «pĂ€ris» konfiguratsioon töötaks, peame edastama kubeletile kubeconfigi faili, et see teaks, kuidas API-serveriga suhelda. Ănneks on see pĂ€ris lihtne (kuna meil ei ole autentimise vĂ”i sertifikaatidega probleeme):
apiVersion: v1
kind: Config
clusters:
- cluster:
server: http://127.0.0.1:8080
name: mink8s
contexts:
- context:
cluster: mink8s
name: mink8s
current-context: mink8s Salvige see kui kubeconfig.yaml, lÔpetage protsess kubelet ja kÀivitage taas vajalike parameetritega:
$ sudo ./kubelet --pod-manifest-path=pods --kubeconfig=kubeconfig.yaml(Muide, kui proovite API-le pöörduda curliga, kui kubelet ei tööta, siis avastate, et see töötab ikka! Kubelet ei ole oma pod'ide «vanem», sarnaselt Docker'ile, ta on rohkem nagu âhaldurâ. Kubeleti haldatavad konteinerid töötavad, kuni kubelet neid ei peata.)
MÔne minuti pÀrast kubectl peaks meile nÀitama pod'id ja sÔlmed, nagu ootasime:
$ ./kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default hello-mink8s 0/1 CrashLoopBackOff 261 21h
kube-system etcd-mink8s 1/1 Running 0 21h
kube-system kube-apiserver-mink8s 1/1 Running 0 21h
$ ./kubectl get nodes -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
mink8s Ready 21h v1.18.5 10.70.10.228 Ubuntu 18.04.4 LTS 4.15.0-109-generic docker://19.3.6Sel korral tuleb end tĂ”eliselt Ă”nnitleda (ma tean, et olen juba Ă”nnitlenud) â meil on saanud minimaalselt töötav «Kubernetes» klaster, millel on tĂ€ieĂ”iguslik API!
KĂ€ivitame pod'i
NĂŒĂŒd vaatame, milleks API suuteline on. Alustame nginx pod'iga:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginxSiin saame ĂŒsna huvitava vea:
$ ./kubectl apply -f nginx.yaml
Error from server (Forbidden): error when creating "nginx.yaml": pods "nginx" is
forbidden: error looking up service account default/default: serviceaccount
"default" not found
$ ./kubectl get serviceaccounts
No resources found in default namespace.Siin nĂ€eme, kui kohutavalt poolik meie Kubernetes keskkond on â meil puuduvad teenusekontod. Proovime jĂ€lle, luues teenusekonto kĂ€sitsi, ja vaatame, mis juhtub:
$ cat <<EOS | ./kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
EOS
serviceaccount/default created
$ ./kubectl apply -f nginx.yaml
Error from server (ServerTimeout): error when creating "nginx.yaml": No API
token found for service account "default", retry after the token is
automatically created and added to the service accountIsegi kui me loome teenuse konto kĂ€sitsi, ei genereerita autentimistokene. JĂ€tkates katsetamist meie minimalistliku "klastriga", avastame, et enamik kasulikest asjadest, mis tavaliselt automaatselt juhtuvad, on puuduvad. Kubernetes API server on ĂŒsna minimalistlik, suurem osa raskest automaatsetest seadistustest toimub erinevates kontrollides ja taustatöödes, mis veel ei tööta.
Saame selle probleemi ĂŒletada seadistades valiku automountServiceAccountToken teenuse konto jaoks (kuna me ei pea seda kasutama):
$ cat <<EOS | ./kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
automountServiceAccountToken: false
EOS
serviceaccount/default configured
$ ./kubectl apply -f nginx.yaml
pod/nginx created
$ ./kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 Pending 0 13mLĂ”puks ilmus pod! Kuid tegelikult see ei kĂ€ivitu, kuna meil pole (scheduler) â veel ĂŒks oluline Kubernetes komponent. JĂ€llegi nĂ€eme, et Kubernetes API on ĂŒllatavalt "idiot" â kui loote pod'i API-s, registreerib see selle, kuid ei ĂŒrita vĂ€lja selgitada, millisel sĂ”lmel seda kĂ€ivitada.
Tegelikult pole pod'i kÀivitamiseks planeerijat vaja. Saame kÀsitsi lisada sÔlme manifesti parameetrisse nodeName:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
nodeName: mink8s
(Asenda mink8s sÔlme nimega.) PÀrast kustutamist ja rakendamist nÀeme, et nginx kÀivitub ja kuulab sise-IP-aadressi:
$ . /kubectl delete pod nginx
pod "nginx" kustutatud
$ . /kubectl apply -f nginx.yaml
pod/nginx loodud
$ . /kubectl get pods -owide
NIMI VALMIS OLEK ÜMBERSTARTIMI KORDAD VANUS IP SÕLM NOMINEERITUD SÕLM VALMIDUSE VÄRAVAD
nginx 1/1 Käib 0 30s 172.17.0.2 mink8s <none> <none>
$ curl -s 172.17.0.2 | head -4
<!DOCTYPE html>
<html>
<head>
<title>Tere tulemast nginx!</title>Kinnitamaks, et vĂ”rguĂŒhendus pod'ide vahel töötab korralikult, saame kĂ€ivitada curl teisest pod'ist:
$ cat <<EOS | .\/kubectl apply -f -\napiVersion: v1\nkind: Pod\nmetadata:\n name: curl\nspec:\n containers:\n - image: curlimages\/curl\n name: curl\n command: ["curl", "172.17.0.2"]\n nodeName: mink8s\nEOS\npod\/curl created\n$ .\/kubectl logs curl | head -6\n % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed
<!DOCTYPE html>
<html>
<head>
<title>Tere tulemast nginx!</title>On huvitav uurida seda keskkonda ja vaadata, mis töötab ja mis mitte. Olen avastanud, et ConfigMap ja Secret toimivad oodatult, kuid Service ja Deployment ei tööta.
Edu!
See postitus muutub suureks, seega kavatsema kuulutada vĂ”itu ja vĂ€ita, et see on elujĂ”uline konfiguratsioon, mida vĂ”ib nimetada "Kubernetes". KokkuvĂ”tteks: neli binaarfaili, viis kĂ€surea parameetrit ja "ainult" 45 rida YAML (Kubernetes standardite kohaselt mitte nii palju) ja meil töötab ĂŒsna palju asju:
- Podid hallatakse tavalise Kubernetes API abil (mÔningate trikkidega)
- Saate laadida ĂŒles avalikke konteineripilte ja nendega töötada
- Podid jÀÀvad ellu ja taaskÀivituvad automaatselt
- Podide vaheline vĂ”rk ĂŒhe sĂ”lme raames töötab pĂ€ris hĂ€sti
- ConfigMap, Secret ja lihtne salvestuse monteerimine toimib nagu peab
Kuid suur osa sellest, mis teeb Kubernetes tÔeliselt kasulikuks, on endiselt puuduv, nÀiteks:
- Podide planeerija
- Autentimine / autoriseerimine
- Mitu sÔlme
- Teenuste vÔrk
- Klastri sisemine DNS
- Teenusekontode, juurutamiste, pilveteenuste pakkujatega integreerimise ja enamiku teiste "toodete" jaoks, mida Kubernetes pakub, kontrollerid
Kuidas me tĂ”eliselt saime? Kubernetes API, mis töötab iseseisvalt, on tegelikult lihtsalt platvorm konteinerite automatiseerimiseks.Ta ei tee palju â see on erinevate kontrollerite ja operaatorite töö, kes kasutavad API-d â kuid see tagab jĂ€rjepideva keskkonna automatiseerimiseks.
Lugeda rohkem:
Allikas: habr.com
