Përkthimi i artikullit është përgatitur para fillimit të kursit .

If you're reading this, you probably have heard something about Kubernetes (and if not, how did you end up here?) But what exactly is Kubernetes? It is ? ĐлО ? ЧŃĐŸ ĐČĐŸĐŸĐ±ŃĐ” ŃŃĐŸ Đ·ĐœĐ°ŃĐžŃ?
Honestly, I'm not 100% sure. But I think it's interesting to dig into the internals and see what really happens in Kubernetes under its many layers of abstraction. So, out of curiosity, let's see what a minimal âKubernetes clusterâ actually looks like. (It will be much simpler than .)
I assume you have a basic understanding of Kubernetes, Linux, and containers. Everything weâll discuss here is intended only for exploration/study; do not run any of this in production!
Përmbledhje
Kubernetes contains many components. According to , the architecture looks as follows:

Here are at least eight components shown, but we will ignore most of them. I want to state that the minimal thing that can reasonably be called Kubernetes consists of three main components:
- kubelet
- kube-apiserver (which depends on etcd â its database)
- container runtime (in this case, Docker)
Let's see what is mentioned about each of them in the documentation (., .) First kubelet:
An agent running on each node in the cluster. It ensures that containers are running in the pod.
Sounds pretty straightforward. What about the container runtime? (container runtime)?
A container runtime is a program designed to execute containers.
Very informative. But if you're familiar with Docker, you should have a general idea of what it does. (The details about the division of responsibilities between the container runtime and kubelet are actually quite subtle and I wonât delve into them here.)
DHE API server?
The API server is a Kubernetes control plane component that exposes the Kubernetes API. The API server is the client-facing part of the Kubernetes control plane.
Ădo person qĂ« ka bĂ«rĂ« ndonjĂ«herĂ« diçka me Kubernetes ka pasur kontakt me API-nĂ« ose drejtpĂ«rdrejt ose pĂ«rmes kubectl. Kjo Ă«shtĂ« thelbi i asaj qĂ« e bĂ«n Kubernetes Kubernetes â truri qĂ« kthen malet e YAML, qĂ« tĂ« gjithĂ« i njohim dhe i duam (?), nĂ« njĂ« infrastrukturĂ« funksionale. Duket e qartĂ« se API duhet tĂ« jetĂ« e pranishme nĂ« konfigurimin tonĂ« minimal.
Kërkesat paraardhëse
- Një makinë virtuale ose fizike Linux me akses root (unë përdor Ubuntu 18.04 në një makinë virtuale).
- Dhe kjo është e gjitha!
Instalim i mërzitshëm
Në makinën që do të përdorim, ne duhet të instalojmë Docker. (Nuk do të flas në detaje se si funksionon Docker dhe kontejnerët; nëse jeni të interesuar, ka ). Le të instalohet me apt:
$ sudo apt install docker.io
$ sudo systemctl start docker Pasi tĂ« bĂ«het kjo, na nevojiten binarĂ«t e Kubernetes. NĂ« fakt, pĂ«r tĂ« filluar âklasterinâ tonĂ«, na nevojitet vetĂ«m kubelet, pasi pĂ«r tĂ« mundĂ«suar komponentĂ«t e tjerĂ« server, ne do tĂ« mund tĂ« pĂ«rdorim kubelet. PĂ«r tĂ« ndĂ«rvepruar me klasterin tonĂ« pasi tĂ« nisĂ«, ne gjithashtu do tĂ« pĂ«rdorim 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 ĂfarĂ« do tĂ« ndodhĂ« nĂ«se thjesht e nisim kubelet?
$ ./kubelet
F0609 04:03:29.105194 4583 server.go:254] mkdir /var/lib/kubelet: permission denied kubelet duhet të punojë nga root. Mjaft e arsyeshme, pasi duhet të menaxhojë të gjithë nyjën. Le të shohim parametrat e tij:
$ ./kubelet -h
$ ./kubelet -h | wc -l
284Wow, ka shumë opsione! Për fat të mirë, na nevojiten vetëm disa nga ato. Ja një nga parametrat që na intereson:
--pod-manifest-path stringRruga pĂ«r katalogun qĂ« pĂ«rmban skedarĂ«t pĂ«r podet statike, ose rruga pĂ«r njĂ« skedĂ« pĂ«r pĂ«rshkrimin e podĂ«ve statike. SkedarĂ«t qĂ« fillojnĂ« me pika injorohen. (E DĂMTUAR: ky parameter duhet tĂ« vendoset nĂ« skedarin e konfigurimit, tĂ« cilin e kalojmĂ« nĂ« Kubelet pĂ«rmes opsionit âconfig. PĂ«r mĂ« shumĂ« informacion shih .)
Ky parametrin na lejon tĂ« nisim â pods qĂ« nuk administrohen pĂ«rmes API-sĂ« Kubernetes. Pods statike pĂ«rdoren rrallĂ«, por ato janĂ« shumĂ« tĂ« dobishme pĂ«r ngritjen e shpejtĂ« tĂ« njĂ« klasteri, dhe kjo Ă«shtĂ« pikĂ«risht ajo qĂ« na nevojitet. Do ta injorojmĂ« kĂ«tĂ« paralajmĂ«rim tĂ« zhurmshĂ«m (sĂ«rish, mos e aktivizoni kĂ«tĂ« nĂ« prodhim!) dhe do tĂ« shohim nĂ«se mund ta nisim podin.
Fillimisht do të krijojmë një katalog për pods statike dhe do ta aktivizojmë. kubelet:
$ mkdir pods
$ sudo ./kubelet --pod-manifest-path=podsPastaj në një terminal tjetër/faqe tmux/ndonjë vend tjetër, do të krijojmë manifestin e podit:
$ cat < pods/hello.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- image: busybox
name: hello
command: ["echo", "hello world!"]
EOF kubelet fillon të shkruajë disa paralajmërime dhe duket se nuk po ndodh asgjë. Por nuk është kështu! Le të shohim në Docker:
$ 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 lexoi manifestin e podit dhe i dha Docker-it urdhrin pĂ«r tĂ« nisur disa kontejnerĂ« sipas specifikimit tonĂ«. (NĂ«se jeni tĂ« interesuar tĂ« dini rreth kontejnerit âpauseâ, kjo Ă«shtĂ« njĂ« hile Kubernetes â detajet mund tĂ« shikoni nĂ« .) Kubelet do tĂ« aktivizojĂ« kontejnerin tonĂ« busybox me urdhrin e specifikuar dhe do ta rinisĂ« atĂ« pafundĂ«sisht derisa podi statik tĂ« hiqet.
Keni arsye t'i përgëzoni vetes. Sapo kemi krijuar një nga mënyrat më të komplikuara për të nxjerrë tekst në terminal!
Po aktivizojmë etcd
Qëllimi ynë përfundimtar është aktivizimi i Kubernetes API, por për këtë na nevojitet më parë të aktivizojmë . Le ta aktivizojmë një klaster minimal etcd, duke vendosur configurimet e tij në katalogun pods (p.sh., 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-dataNëse keni punuar ndonjëherë me Kubernetes, këto skedarë YAML duhet të jenë të njohur për ju. Ka vetëm dy aspekte për të theksuar këtu:
Ne montuam dosjen e hostit /var/lib/etcd në pod, në mënyrë që të dhënat e etcd të ruhen pas rinisjes (nëse nuk e bëni këtë, gjendja e klasterit do të fshihet me çdo rinisje të pod-it, që do të ishte problematike edhe për një instalim minimal të Kubernetes).
Ne kemi instaluar hostNetwork: true. Ky parametër, që nuk është befasi, konfigurimi etcd për të përdorur rrjetin e hostit në vend të rrjetit të brendshëm të pod-it (kjo do ta lehtësojë gjetjen e klasterit etcd nga API-server).
Një kontroll i thjeshtë tregon se etcd në të vërtetë është në funksionim në localhost dhe ruan të dhënat në disk:
$ 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.walNisja e API-serverit
Nisja e API-serverit Kubernetes është edhe më e thjeshtë. Parametrin e vetëm që duhet të kaloni, --etcd-servers, bën atë që prisni:
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 Vendosni kĂ«tĂ« skedari YAML nĂ« katalog pods, dhe API-server do tĂ« niset. NjĂ« kontroll me curl tregon se API i Kubernetes po dĂ«gjon portin 8080 me akses tĂ« plotĂ« â nuk kĂ«rkohet autentifikim!
$ curl localhost:8080/healthz
ok
$ curl localhost:8080/api/v1/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "59"
},
"items": []
}(Përsëri, mos e këtë në prodhim! Kam qenë paksa i befasuar që konfigurimi i parazgjedhur është kaq i pa sigurt. Por supozoj se është bërë për të lehtësuar zhvillimin dhe testimin.)
Dhe, një surprizë e këndshme, kubectl funksionon nga kutia pa ndonjë konfigurim shtesë!
$ ./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.Problemi
Por nëse shfletojmë pak më thellë, duket se diçka nuk po shkon siç duhet:
$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.Pods statike që kemi krijuar janë zhdukur! Në të vërtetë, nodi ynë kubelet nuk po zbulon asnjëherë:
$ ./kubectl get nodes
No resources found in default namespace.ĂfarĂ« ndodh? NĂ«se e mbani mend, disa paragrafe mĂ« parĂ« lançuam kubelet me njĂ« grup shumĂ« tĂ« thjeshtĂ« parametrash tĂ« komandĂ«s, prandaj kubelet nuk e di si tĂ« lidhet me serverin API dhe ta njoftojĂ« pĂ«r gjendjen e tij. Duke studiuar dokumentacionin, gjejmĂ« flamurin pĂ«rkatĂ«s:
--kubeconfig string
Rruga drejt skedarit kubeconfig, i cili tregon si të lidheni me serverin API. Prania e --kubeconfig aktivizon modin e serverit API, mungesa e --kubeconfig aktivizon modin autonom.
Gjatë gjithë këtij kohë, pa e ditur, kemi lançuar kubelet në "modin autonom". (Nëse do të ishim pedantë, mund të konsideronim modin autonom të kubelet si "Kubernetes minimalisht funksional", por kjo do të ishte shumë e mërzitshme). për të funksionuar konfigurimi "real", na nevojitet të kalojmë skedarin kubeconfig tek kubelet, që ai të dijë si të komunikojë me serverin API. Me fat, kjo është mjaft e thjeshtë (pasi nuk kemi probleme me autentifikimin ose sertifikatat):
apiVersion: v1
kind: Config
clusters:
- cluster:
server: http://127.0.0.1:8080
name: mink8s
contexts:
- context:
cluster: mink8s
name: mink8s
current-context: mink8s Ruani këtë si kubeconfig.yaml, ndaloni procesin kubelet dhe rilansoni me parametrat e nevojshme:
$ sudo ./kubelet --pod-manifest-path=pods --kubeconfig=kubeconfig.yaml(Me rastin e kësaj, nëse provoni të qaseni në API përmes curl, kur kubelet nuk punon, do të zbuloni se ai është ende në funksion! Kubelet nuk është "prindi" i podëve të tij, siç është Docker, ai është më shumë si një "demon menaxhues". Kontejnerët e menaxhuar nga kubelet do të punojnë derisa kubelet t'i ndalojë ata.)
Pas disa minutash kubectl duhet të na tregojë podët dhe nyjat, siç e presim:
$ ./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.6Tani pĂ«r kĂ«tĂ« herĂ«, le tĂ« pĂ«rgĂ«zojmĂ« vetveten vĂ«rtet (e di, qĂ« tashmĂ« kam pĂ«rgĂ«zuar) â kemi krijuar njĂ« "klaster" minimal Kubernetes qĂ« funksionon me API tĂ« plotĂ«!
Të lançojmë podin
Tani le të shohim çfarë mund të bëjë API. Le të fillojmë me podin nginx:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginxKëtu do të marrim një gabim mjaft interesant:
$ ./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.KĂ«tu shohim sa e tmerrshme Ă«shtĂ« mjedisi ynĂ« Kubernetes â nuk kemi llogari shĂ«rbimi. Le tĂ« provojmĂ« pĂ«rsĂ«ri, duke krijuar njĂ« llogari shĂ«rbimi manualisht dhe tĂ« shohim se çfarĂ« do tĂ« ndodhĂ«:
$ 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 accountEdhe kur krijuam manualisht llogarinë e shërbimit, tokeni i autentikimit nuk krijohet. Ndërsa vazhdojmë të eksperimentojmë me "klusterin" tonë minimalist, do të zbulojmë se shumica e gjërave të dobishme, të cilat zakonisht ndodhin automatikisht, do të mungojnë. Serveri Kubernetes API është mjaft minimalist, pjesa më e madhe e konfigurimeve të rënda automatike ndodhin në kontrollet e ndryshme dhe punët në sfond që ende nuk po ekzekutohen.
Ne mund ta rregullojmë këtë problem duke vendosur opsionin automountServiceAccountToken për llogarinë e shërbimit (pasi nuk do ta përdorim):
$ 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 13mNĂ« fund, podi u shfaq! Por nĂ« tĂ« vĂ«rtetĂ« ai nuk do tĂ« nisĂ«, sepse nuk kemi (scheduler) â njĂ« tjetĂ«r komponent i rĂ«ndĂ«sishĂ«m i Kubernetes. PĂ«rsĂ«ri, shohim se API Kubernetes Ă«shtĂ« befasuese "e paaftĂ«" â kur krijoni njĂ« pod nĂ« API, ai e regjistron atĂ«, por nuk pĂ«rpiqet tĂ« kuptojĂ« se nĂ« cilin nod do ta ekzekutojĂ«.
Në të vërtetë, për të nisur një pod nuk nevojitet një planifikues. Mund të shtoni manualisht një nod në manifest në parametrin nodeName:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
nodeName: mink8s
(Zëvendësoni mink8s me emrin e nodit.) Pasi të fshini dhe aplikoni, shohim se nginx ka startuar dhe po dëgjon adresën IP të brendshme:
$ .\/kubectl fshi pod nginx
pod "nginx" u fshi
$ .\/kubectl aplikoni -f nginx.yaml
pod\/nginx u krijua
$ .\/kubectl merrni pod-et -owide
EMRI GATI STATUS RIMEDHJE MOSHAT IP NODE NODE I NOMINUAR PORTAT E GATSHMËRISË
nginx 1\/1 Duke funksionuar 0 30s 172.17.0.2 mink8s <none> <none>
$ curl -s 172.17.0.2 | head -4
<!DOCTYPE html>
<html>
<head>
<title>Mirë se vini në nginx!</title>PĂ«r t'u siguruar qĂ« rrjeti midis podave funksionon siç duhet, mund tĂ« ekzekutojmĂ« curl nga njĂ« pod tjetĂ«r:
$ cat <<EOS | .\/kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: curl
spec:
containers:
- image: curlimages\/curl
name: curl
command: ["curl", "172.17.0.2"]
nodeName: mink8s
EOS
pod\/curl created
$ .\/kubectl logs curl | head -6
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
<!DOCTYPE html>
<html>
<head>
<title>Mirë se vini në nginx!</title>ĂshtĂ« mjaft interesante tĂ« eksperimentosh nĂ« kĂ«tĂ« mjedis dhe tĂ« shohĂ«sh çfarĂ« funksionon dhe çfarĂ« jo. Kam zbuluar se ConfigMap dhe Secret funksionojnĂ« siç pritet, ndĂ«rsa ShĂ«rbimi dhe Implementimi jo.
Sukses!
Ky kyç po bëhet i madh, prandaj do të shpall fitoren dhe do të them se kjo është një konfigurim i qëndrueshëm, i quajtur "Kubernetes". Në përmbledhje: katër skedarë binarë, pesë parametra të linjës së komandës dhe "shumë pak" 45 rreshta YAML (nuk është aq shumë sipas standardeve të Kubernetes) dhe kemi një sërë gjërash që funksionojnë:
- Pods menaxhohen me API-në e zakonshëm të Kubernetes (me disa hacks)
- Mund të ngarkoni imazhe publike të kontejnerëve dhe t'i menaxhoni ato
- Pods qëndrojnë aktive dhe ri-startohen automatikisht
- Rrjeti midis pods brenda një nodi funksionon mjaft mirë
- ConfigMap, Secret dhe montimi më i thjeshtë i ruajtjes funksionojnë siç duhet
Por shumë nga ajo që e bën Kubernetes me të vërtetë të dobishëm, ende mungon, për shembull:
- Planifikuesi i pods
- Autentikimi / autorizimi
- Disa nod
- Rrjeti i shërbimeve
- DNS-i i brendshëm i klasterit
- Kontrollerët për llogaritë e shërbimeve, vendosjet, integrimin me ofruesit e cloud dhe shumicën e "mishave" të tjera që sjell Kubernetes
Pra, çfarë kemi marrë për të vërtetë? API e Kubernetes-it, e cila funksionon vetë, në të vërtetë është thjesht një platformë për automatizimin e konteinerëve.Ajo nuk bën shumë - kjo është puna për kontrollet dhe operatorët e ndryshëm që përdorin API-në, - por ofron një ambient të qëndrueshëm për automatizim.
Lexoni më shumë:
Burimi: habr.com
