Minimum Canlı Kubernetlər

Məqalənin tərcüməsi kursun başlaması ərəfəsində hazırlanıb "DevOps təcrübələri və alətləri".

Minimum Canlı Kubernetlər

Əgər bunu oxuyursunuzsa, yəqin ki, Kubernetes haqqında nəsə eşitmisiniz (və yoxsa, bura necə gəldiniz?) Bəs Kubernetes tam olaraq nədir? Bu “Sənaye tipli konteynerlərin orkestrasiyası”? Və ya "Bulud-Doğma Əməliyyat Sistemi"? Bu nə deməkdir?

Düzünü desəm, 100% əmin deyiləm. Ancaq məncə, daxili hissələrə baxmaq və Kubernetesdə çoxlu abstraksiyalar təbəqəsi altında həqiqətən nə baş verdiyini görmək maraqlıdır. Sadəcə əylənmək üçün gəlin minimal “Kubernetes klasteri”nin əslində necə göründüyünə nəzər salaq. (Bu, daha asan olacaq Kubernetes Çətin Yol.)

Güman edirəm ki, Kubernetes, Linux və konteynerlər haqqında əsas biliklərə sahibsiniz. Burada danışdığımız hər şey yalnız tədqiqat/öyrənmə məqsədləri üçündür, heç birini istehsalata qoymayın!

Review

Kubernetes bir çox komponentdən ibarətdir. görə Vikipediya, memarlıq belə görünür:

Minimum Canlı Kubernetlər

Burada göstərilən ən azı səkkiz komponent var, lakin biz onların əksəriyyətinə məhəl qoymayacağıq. Bildirmək istəyirəm ki, əsaslı şəkildə Kubernetes adlandırıla bilən minimum şey üç əsas komponentdən ibarətdir:

  • kubelet
  • kube-apiserver (etcd-dən asılıdır - onun verilənlər bazası)
  • konteyner işləmə vaxtı (bu halda Docker)

Gəlin görək sənədlərdə onların hər biri haqqında nə deyilir (rus., İngilis dili.). Əvvəlcə kubelet:

Klasterdəki hər bir qovşaqda işləyən agent. Konteynerlərin podda işlədiyinə əmin olur.

Kifayət qədər sadə səslənir. Nə haqqında konteyner işləmə müddətləri (konteyner işləmə müddəti)?

Konteynerin işləmə müddəti konteynerləri işə salmaq üçün nəzərdə tutulmuş proqramdır.

Çox məlumatlandırıcıdır. Ancaq Docker ilə tanışsınızsa, onun nə etdiyi barədə ümumi təsəvvürünüz olmalıdır. (Konteynerin işləmə vaxtı ilə kubelet arasında məsuliyyətlərin ayrılmasının təfərrüatları əslində olduqca incədir və mən burada onlara daxil olmayacağam.)

И API server?

API Server Kubernetes API-ni ifşa edən Kubernetes idarəetmə paneli komponentidir. API serveri Kubernetes idarəetmə panelinin müştəri tərəfidir

Kubernetes ilə heç bir iş görmüş hər kəs ya birbaşa, ya da kubectl vasitəsilə API ilə əlaqə saxlamalı olub. Bu, Kubernetes Kubernetes-i - hamımızın bildiyimiz və sevdiyimiz (?) YAML dağlarını işləyən infrastruktura çevirən beyinin ürəyidir. Aydın görünür ki, API bizim minimal konfiqurasiyamızda olmalıdır.

İlkin şərtlər

  • Linux virtual və ya kök çıxışı olan fiziki maşın (Mən virtual maşında Ubuntu 18.04 istifadə edirəm).
  • Və hamısı!

Darıxdırıcı quraşdırma

İstifadə edəcəyimiz maşına Docker quraşdırmalıyıq. (Docker və konteynerlərin necə işlədiyi barədə təfərrüata varmaq fikrində deyiləm; əgər maraqlanırsınızsa, orada gözəl məqalələr). Onunla quraşdıraq apt:

$ sudo apt install docker.io
$ sudo systemctl start docker

Bundan sonra biz Kubernetes ikili fayllarını almalıyıq. Əslində, "klasterimizin" ilkin işə salınması üçün bizə yalnız lazımdır kubelet, çünki digər server komponentlərini işə salmaq üçün istifadə edə bilərik kubelet. Çalışdıqdan sonra klasterimizlə qarşılıqlı əlaqə yaratmaq üçün biz də istifadə edəcəyik 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

Sadəcə qaçsaq nə olar kubelet?

$ ./kubelet
F0609 04:03:29.105194    4583 server.go:254] mkdir /var/lib/kubelet: permission denied

kubelet kök kimi işləməlidir. Tamamilə məntiqlidir, çünki o, bütün nodu idarə etməlidir. Onun parametrlərinə baxaq:

$ ./kubelet -h
<слишком много строк, чтобы разместить здесь>
$ ./kubelet -h | wc -l
284

Vay, çoxlu seçim! Xoşbəxtlikdən, onlardan yalnız bir neçəsinə ehtiyacımız var. Bizi maraqlandıran parametrlərdən biri budur:

--pod-manifest-path string

Statik podlar üçün faylları ehtiva edən kataloqa yol və ya statik podları təsvir edən fayla gedən yol. Nöqtələrlə başlayan fayllar nəzərə alınmır. (İSTƏNİLMİŞDİR: Bu seçim --config seçimi ilə Kubelet-ə ötürülən konfiqurasiya faylında quraşdırılmalıdır. Əlavə məlumat üçün baxın. kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file .)

Bu seçim bizə qaçmağa imkan verir statik qabıqlar — Kubernetes API vasitəsilə idarə olunmayan podlar. Statik podlar nadir hallarda istifadə olunur, lakin onlar klasteri sürətlə qaldırmaq üçün çox əlverişlidir və bu, bizə lazım olan şeydir. Biz bu böyük xəbərdarlığa məhəl qoymayacağıq (yenidən bunu istehsalda işə salmayın!) və podun işə salınıb-çalışdıra bilməyəcəyimizə baxın.

Əvvəlcə statik podlar üçün kataloq yaradacağıq və işə başlayacağıq kubelet:

$ mkdir pods
$ sudo ./kubelet --pod-manifest-path=pods

Sonra, başqa bir terminal/tmux pəncərəsində/nə olursa olsun, bir pod manifest yaradacağıq:

$ cat <<EOF > pods/hello.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello
spec:
  containers:
  - image: busybox
    name: hello
    command: ["echo", "hello world!"]
EOF

kubelet bəzi xəbərdarlıqlar yazmağa başlayır və sanki heç nə baş vermir. Amma bu doğru deyil! Docker-ə baxaq:

$ 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 Mən pod manifestini oxudum və Dockerə spesifikasiyalarımıza uyğun olaraq bir neçə konteyneri işə salmağı əmr etdim. (Əgər "fasilə" konteyneri ilə maraqlanırsınızsa, bu, Kubernetes hackidir - baxın bu blog.) Kubelet konteynerimizi işə salacaq busybox göstərilən əmrlə və statik pod silinənə qədər onu qeyri-müəyyən müddətə yenidən başladır.

Özünüzü təbrik edin. Biz indicə terminala mətn çıxarmağın ən qarışıq yollarından birini tapdıq!

Başla və s

Bizim əsas məqsədimiz Kubernetes API-ni işə salmaqdır, lakin bunu etmək üçün ilk öncə işə salmalıyıq və s. Parametrlərini pods kataloquna yerləşdirməklə minimal etcd klasterinə başlayaq (məsələn, 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-data

Əgər əvvəllər Kubernetes ilə işləmisinizsə, bu YAML faylları sizə tanış olmalıdır. Burada yalnız iki məqamı qeyd etmək lazımdır:

Biz host qovluğunu quraşdırdıq /var/lib/etcd podda belə ki, etcd məlumatları yenidən başladıldıqdan sonra qorunsun (əgər bu edilmədikdə, pod hər dəfə yenidən işə salındıqda klaster vəziyyəti silinəcək, bu, hətta minimal Kubernetes quraşdırması üçün də yaxşı olmayacaq).

Quraşdırmışıq hostNetwork: true. Təəccüblü deyil ki, bu parametr podun daxili şəbəkəsi əvəzinə host şəbəkəsindən istifadə etmək üçün etcd-ni konfiqurasiya edir (bu, API serverinin etcd klasterini tapmasını asanlaşdıracaq).

Sadə bir yoxlama, etcd-nin həqiqətən localhost-da işlədiyini və məlumatları diskdə saxladığını göstərir:

$ 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.wal

API serverinin işə salınması

Kubernetes API serverini idarə etmək daha asandır. Qəbul edilməli olan yeganə parametrdir --etcd-servers, gözlədiyinizi edir:

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

Bu YAML faylını qovluğa yerləşdirin pods, və API server başlayacaq. ilə yoxlanılır curl Kubernetes API-nin tamamilə açıq girişlə 8080 portunu dinlədiyini göstərir - autentifikasiya tələb olunmur!

$ curl localhost:8080/healthz
ok
$ curl localhost:8080/api/v1/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/pods",
    "resourceVersion": "59"
  },
  "items": []
}

(Yenə də, bunu istehsalda işə salmayın! Defolt parametrin bu qədər etibarsız olması məni bir az təəccübləndirdi. Amma bunun inkişafı və sınaqları asanlaşdırmaq üçün olduğunu təxmin edirəm.)

Və xoş sürpriz, kubectl heç bir əlavə parametr olmadan qutudan çıxır!

$ ./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.

problem

Ancaq bir az daha dərin qazsanız, bir şey səhv gedir:

$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.

Yaratdığımız statik podlar getdi! Əslində kubelet qovşağımız ümumiyyətlə aşkar edilmir:

$ ./kubectl get nodes
No resources found in default namespace.

Nə məsələdir? Bir neçə paraqrafı xatırlayırsınızsa, biz kubelet-i son dərəcə sadə komanda xətti parametrləri dəsti ilə işə saldıq, ona görə də kubelet API serveri ilə necə əlaqə saxlayacağını və ona vəziyyəti barədə məlumat verəcəyini bilmir. Sənədləri öyrəndikdən sonra müvafiq bayrağı tapırıq:

--kubeconfig string

Fayla gedən yol kubeconfig, API serverinə necə qoşulacağını müəyyən edir. Mövcudluq --kubeconfig API server rejimini aktivləşdirir, yox --kubeconfig oflayn rejimi işə salır.

Bütün bu müddət ərzində, bilmədən kubeleti “oflayn rejimdə” işlədirdik. (Əgər biz pedantik olsaydıq, müstəqil kubelet haqqında "minimum canlı Kubernetes" kimi düşünə bilərdik, lakin bu, çox darıxdırıcı olardı). "Real" konfiqurasiyanın işləməsi üçün kubeconfig faylını kubeletə ötürməliyik ki, o API serveri ilə necə danışacağını bilsin. Xoşbəxtlikdən bu, olduqca sadədir (çünki autentifikasiya və ya sertifikatlarla bağlı heç bir problemimiz yoxdur):

apiVersion: v1
kind: Config
clusters:
- cluster:
    server: http://127.0.0.1:8080
  name: mink8s
contexts:
- context:
    cluster: mink8s
  name: mink8s
current-context: mink8s

Bunu olaraq yadda saxlayın kubeconfig.yaml, prosesi öldürün kubelet və lazımi parametrlərlə yenidən başladın:

$ sudo ./kubelet --pod-manifest-path=pods --kubeconfig=kubeconfig.yaml

(Yeri gəlmişkən, kubelet işləmədikdə API-yə curl vasitəsilə daxil olmağa çalışsanız, onun hələ də işlədiyini görəcəksiniz! Kubelet Docker kimi podların “valideyn”i deyil, daha çox “nəzarət” kimidir. daemon.” Kubelet tərəfindən idarə olunan konteynerlər kubelet onları dayandırana qədər işləməyə davam edəcək.)

Bir neçə dəqiqəyə kubectl Bizə gözlədiyimiz kimi pod və qovşaqları göstərməlidir:

$ ./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    <none>   21h   v1.18.5   10.70.10.228   <none>        Ubuntu 18.04.4 LTS   4.15.0-109-generic   docker://19.3.6

Gəlin bu dəfə özümüzü həqiqətən təbrik edək (özümüzü artıq təbrik etdiyimi bilirəm) - tam funksional API ilə işləyən minimal Kubernetes "klasterimiz" var!

altında işə salırıq

İndi API-nin nəyə qadir olduğuna baxaq. Nginx pod ilə başlayaq:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx

Burada olduqca maraqlı bir səhv alırıq:

$ ./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.

Burada biz Kubernetes mühitimizin nə qədər natamam olduğunu görürük - xidmətlər üçün hesablarımız yoxdur. Gəlin əl ilə xidmət hesabı yaradaraq yenidən cəhd edək və nə baş verdiyini görək:

$ 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 account

Xidmət hesabını əl ilə yaratsaq belə, autentifikasiya nişanı yaradılmır. Minimalist "klasterimiz"lə təcrübə aparmağa davam etdikcə, adətən avtomatik olaraq baş verən faydalı şeylərin əksəriyyətinin itkin olacağını görəcəyik. Kubernetes API serveri olduqca minimalistdir, ağır yük qaldırma və avtomatik konfiqurasiyanın əksəriyyəti müxtəlif nəzarətçilərdə və hələ işləməyən fon işlərində baş verir.

Seçimi təyin etməklə bu problemi həll edə bilərik automountServiceAccountToken xidmət hesabı üçün (çünki biz hər halda ondan istifadə etmək məcburiyyətində qalmayacağıq):

$ 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          13m

Nəhayət, pod göründü! Amma əslində başlamayacaq, çünki bizdə yoxdur planlaşdırıcı (planlayıcı) Kubernetes-in digər vacib komponentidir. Yenə də görürük ki, Kubernetes API təəccüblü dərəcədə “laldır” – siz API-də Pod yaratdığınız zaman onu qeyd edir, lakin onu hansı node üzərində işlətəcəyini anlamağa çalışmır.

Əslində, podu işə salmaq üçün planlaşdırıcıya ehtiyacınız yoxdur. Parametrdə manifestə əl ilə node əlavə edə bilərsiniz nodeName:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
  nodeName: mink8s

(Əvəz edin mink8s qovşağın adına.) Sildikdən və tətbiq etdikdən sonra nginx-in işə düşdüyünü və daxili IP ünvanını dinlədiyini görürük:

$ ./kubectl delete pod nginx
pod "nginx" deleted
$ ./kubectl apply -f nginx.yaml
pod/nginx created
$ ./kubectl get pods -owide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          30s   172.17.0.2   mink8s   <none>           <none>
$ curl -s 172.17.0.2 | head -4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Podlar arasındakı şəbəkənin düzgün işlədiyinə əmin olmaq üçün başqa bir poddan curl işlədə bilərik:

$ 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>Welcome to nginx!</title>

Bu mühiti qazmaq və nəyin işlədiyini və nəyin olmadığını görmək olduqca maraqlıdır. Mən tapdım ki, ConfigMap və Secret gözlənildiyi kimi işləyir, lakin Service və Deployment yox.

Uğurlar!

Bu yazı uzanır, ona görə də qələbəni elan edəcəyəm və bunun "Kubernetes" adlandırıla bilən etibarlı konfiqurasiya olduğunu söyləyəcəyəm. Xülasə etmək üçün: dörd binar, beş komanda xətti parametri və "yalnız" 45 YAML sətri (yox Kubernetes standartlarına görə bu qədər) və bizdə işləyən bir neçə şey var:

  • Podlar adi Kubernetes API istifadə edərək idarə olunur (bir neçə hack ilə)
  • Siz ictimai konteyner şəkillərini yükləyə və idarə edə bilərsiniz
  • Podlar canlı qalır və avtomatik olaraq yenidən başlayır
  • Eyni node daxilində podlar arasında şəbəkə olduqca yaxşı işləyir
  • ConfigMap, Gizli və sadə saxlama montajı gözlənildiyi kimi işləyir

Lakin Kubernetes-i həqiqətən faydalı edən şeylərin çoxu hələ də yoxdur, məsələn:

  • Pod Planlayıcısı
  • Doğrulama/avtorizasiya
  • Çoxlu qovşaqlar
  • Xidmətlər şəbəkəsi
  • Kümelənmiş daxili DNS
  • Xidmət hesabları, yerləşdirmələr, bulud provayderləri ilə inteqrasiya və Kubernetes-in gətirdiyi digər üstünlüklərin əksəriyyəti üçün nəzarətçilər

Beləliklə, əslində nə əldə etdik? Öz-özünə işləyən Kubernetes API həqiqətən sadəcə bir platformadır konteyner avtomatlaşdırılması. Bu, çox şey etmir - bu API istifadə edən müxtəlif nəzarətçilər və operatorlar üçün bir işdir - lakin avtomatlaşdırma üçün ardıcıl mühit təmin edir.

Pulsuz vebinarda kurs haqqında ətraflı məlumat əldə edin.

Daha ətraflı:

Mənbə: www.habr.com

Добавить комментарий