Kiwango cha chini cha Kubernetes zinazoweza kutumika

Tafsiri ya kifungu hicho ilitayarishwa usiku wa kuamkia kozi hiyo "Mazoea na zana za DevOps".

Kiwango cha chini cha Kubernetes zinazoweza kutumika

Ikiwa unasoma hili, labda umesikia kitu kuhusu Kubernetes (na kama sivyo, uliishiaje hapa?) Lakini Kubernetes ni nini hasa? Hii "Upangaji wa makontena ya kiwango cha viwandani"? Au "Mfumo wa Uendeshaji wa Wingu-Asili"? Hii ina maana gani hata?

Kuwa mkweli, sina uhakika 100%. Lakini nadhani inafurahisha kuchimba mambo ya ndani na kuona kile kinachoendelea katika Kubernetes chini ya tabaka zake nyingi za vifupisho. Kwa hivyo kwa ajili ya kujifurahisha tu, hebu tuangalie ni jinsi gani β€œkundi ndogo ya Kubernetes” inaonekana. (Hii itakuwa rahisi zaidi kuliko Kubernetes Njia Ngumu.)

Nadhani una maarifa ya kimsingi ya Kubernetes, Linux, na vyombo. Kila kitu tunachozungumza hapa ni kwa madhumuni ya utafiti/kujifunza tu, usiweke chochote katika uzalishaji!

Pitia

Kubernetes ina vipengele vingi. Kulingana na wikipedia, usanifu unaonekana kama hii:

Kiwango cha chini cha Kubernetes zinazoweza kutumika

Kuna angalau vijenzi vinane vilivyoonyeshwa hapa, lakini tutavipuuza vingi. Ninataka kusema kwamba kitu cha chini ambacho kinaweza kuitwa Kubernetes kinajumuisha sehemu kuu tatu:

  • mchemraba
  • kube-apiserver (ambayo inategemea etcd - hifadhidata yake)
  • wakati wa kukimbia wa chombo (Docker katika kesi hii)

Wacha tuone nyaraka zinasema nini juu ya kila mmoja wao (rus., Kiingereza.). Mara ya kwanza mchemraba:

Wakala anayeendesha kwenye kila nodi kwenye nguzo. Inahakikisha kwamba vyombo vinaendesha kwenye ganda.

Inaonekana rahisi kutosha. Vipi kuhusu nyakati za kukimbia za chombo (muda wa kukimbia wa chombo)?

Muda wa matumizi ya kontena ni programu iliyoundwa ili kuendesha vyombo.

Taarifa sana. Lakini ikiwa unamfahamu Docker, basi unapaswa kuwa na wazo la jumla la kile kinachofanya. (Maelezo ya mgawanyo wa majukumu kati ya muda wa kukimbia kwa kontena na kubelet kwa kweli ni ya hila na sitayaingia hapa.)

И Seva ya API?

Seva ya API ni sehemu ya paneli dhibiti ya Kubernetes inayofichua API ya Kubernetes. Seva ya API ni upande wa mteja wa paneli dhibiti ya Kubernetes

Mtu yeyote ambaye amewahi kufanya chochote na Kubernetes amelazimika kuingiliana na API moja kwa moja au kupitia kubectl. Huu ndio moyo wa kile kinachofanya Kubernetes Kubernetes - ubongo unaogeuza milima ya YAML sote tunaijua na kuipenda (?) kuwa miundombinu ya kufanya kazi. Inaonekana dhahiri kuwa API inapaswa kuwepo katika usanidi wetu mdogo.

Masharti

  • Linux virtual au kimwili mashine na upatikanaji wa mizizi (Ninatumia Ubuntu 18.04 kwenye mashine virtual).
  • Na yote!

Ufungaji wa boring

Tunahitaji kufunga Docker kwenye mashine tutakayotumia. (Sitaenda kwa undani juu ya jinsi Docker na vyombo hufanya kazi; ikiwa una nia, kuna makala nzuri) Wacha tuisakinishe na apt:

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

Baada ya hapo, tunahitaji kupata jozi za Kubernetes. Kwa kweli, kwa uzinduzi wa awali wa "nguzo" yetu tunahitaji tu kubelet, kwani kuendesha vipengee vingine vya seva tunaweza kutumia kubelet. Ili kuingiliana na nguzo yetu baada ya kufanya kazi, tutatumia pia 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

Nini kinatokea ikiwa tunakimbia tu kubelet?

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

kubelet lazima kukimbia kama mzizi. Ni mantiki kabisa, kwani anahitaji kusimamia nodi nzima. Wacha tuangalie vigezo vyake:

$ ./kubelet -h
<слишком ΠΌΠ½ΠΎΠ³ΠΎ строк, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ здСсь>
$ ./kubelet -h | wc -l
284

Lo, chaguzi nyingi! Kwa bahati nzuri, tunahitaji michache tu yao. Hapa kuna moja ya vigezo ambavyo tunavutiwa navyo:

--pod-manifest-path string

Njia ya saraka iliyo na faili za maganda tuli, au njia ya faili inayoelezea maganda tuli. Faili zinazoanza na vitone hazizingatiwi. (IMEACHILIWA: Chaguo hili lazima liwekwe katika faili ya usanidi iliyopitishwa kwa Kubelet kupitia --config chaguo. Kwa maelezo zaidi, ona. kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file .)

Chaguo hili linatuwezesha kukimbia maganda tuli - maganda ambayo hayadhibitiwi kupitia Kubernetes API. Pods tuli haitumiwi sana, lakini ni rahisi sana kwa kuinua nguzo haraka, na hii ndiyo hasa tunayohitaji. Tutapuuza onyo hili kubwa (tena, usiendeshe hili katika uzalishaji!) na tuone kama tunaweza kufanya ganda liendeshe.

Kwanza tutaunda saraka kwa pods tuli na kukimbia kubelet:

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

Halafu, kwenye terminal/tmux dirisha lingine/chochote, tutaunda onyesho la pod:

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

kubelet huanza kuandika maonyo kadhaa na inaonekana kama hakuna kinachoendelea. Lakini hiyo si kweli! Wacha tuangalie 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 Nilisoma onyesho la ganda na nikampa Docker amri ya kuzindua vyombo kadhaa kulingana na maelezo yetu. (Ikiwa unashangaa juu ya kontena la "sitisha", ni utapeli wa Kubernetes - ona blog hii.) Kubelet itazindua kontena letu busybox kwa amri iliyoainishwa na itaanzisha tena kwa muda usiojulikana hadi ganda tuli lifutwe.

Hongera mwenyewe. Tumepata njia moja tu ya kutatanisha ya kutoa maandishi kwenye terminal!

Zindua nk

Lengo letu kuu ni kuendesha Kubernetes API, lakini ili kufanya hivyo tunahitaji kuendesha kwanza nk. Wacha tuanze nguzo ndogo ya etcd kwa kuweka mipangilio yake kwenye saraka ya maganda (kwa mfano, 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

Ikiwa umewahi kufanya kazi na Kubernetes, faili hizi za YAML zinapaswa kufahamika kwako. Kuna mambo mawili tu ya kuzingatia hapa:

Tumeweka folda ya mwenyeji /var/lib/etcd kwenye ganda ili data ya etcd ihifadhiwe baada ya kuanzishwa upya (ikiwa hii haijafanywa, hali ya nguzo itafutwa kila wakati ganda linapoanzishwa upya, ambayo haitakuwa nzuri kwa usakinishaji mdogo wa Kubernetes).

Tumeweka hostNetwork: true. Mpangilio huu, bila ya kushangaza, husanidi etcd kutumia mtandao wa seva pangishi badala ya mtandao wa ndani wa pod (hii itarahisisha kwa seva ya API kupata kundi la etcd).

Cheki rahisi inaonyesha kuwa etcd inafanya kazi kwenye localhost na kuhifadhi data kwenye diski:

$ 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

Kuanzisha seva ya API

Kuendesha seva ya Kubernetes API ni rahisi zaidi. Parameter pekee ambayo inahitaji kupitishwa ni --etcd-servers, hufanya kile unachotarajia:

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

Weka faili hii ya YAML kwenye saraka pods, na seva ya API itaanza. Kuangalia na curl inaonyesha kuwa API ya Kubernetes inasikiliza kwenye bandari 8080 na ufikiaji wazi kabisa - hakuna uthibitishaji unaohitajika!

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

(Tena, usiendeshe hili katika uzalishaji! Nilishangaa kidogo kuwa mpangilio chaguo-msingi sio salama. Lakini nadhani hii ni kurahisisha usanidi na majaribio.)

Na, mshangao mzuri, kubectl hufanya kazi nje ya kisanduku bila mipangilio yoyote ya ziada!

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

tatizo

Lakini ukichimba zaidi kidogo, kuna kitu kinaonekana kuwa kibaya:

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

Maganda tuli tuliyounda yametoweka! Kwa kweli, nodi yetu ya kubelet haijagunduliwa hata kidogo:

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

Kuna nini? Ikiwa unakumbuka aya chache zilizopita, tulianza kubelet na seti rahisi sana ya vigezo vya mstari wa amri, kwa hivyo kubelet haijui jinsi ya kuwasiliana na seva ya API na kuijulisha hali yake. Baada ya kusoma nyaraka, tunapata bendera inayolingana:

--kubeconfig string

Njia ya faili kubeconfig, ambayo inabainisha jinsi ya kuunganisha kwenye seva ya API. Upatikanaji --kubeconfig inawezesha hali ya seva ya API, hapana --kubeconfig huwezesha hali ya nje ya mtandao.

Wakati huu wote, bila kujua, tulikuwa tukiendesha kubelet katika "hali ya nje ya mtandao." (Kama tungekuwa tukitembea kwa miguu, tunaweza kufikiria kubelet inayojitegemea kama "Kubernetes inayoweza kutumika", lakini hiyo ingekuwa ya kuchosha sana). Ili kufanya usanidi wa "halisi" ufanye kazi, tunahitaji kupitisha faili ya kubeconfig kwa kubelet ili ijue jinsi ya kuzungumza na seva ya API. Kwa bahati nzuri ni rahisi sana (kwani hatuna masuala ya uthibitishaji au cheti):

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

Hifadhi hii kama kubeconfig.yaml, kuua mchakato kubelet na uanze tena na vigezo muhimu:

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

(Kwa njia, ikiwa utajaribu kupata API kupitia curl wakati kubelet haifanyi kazi, utagundua kuwa bado inaendelea! Kubelet sio "mzazi" wa maganda yake kama Docker, ni kama "control". daemon.” Kontena zinazosimamiwa na kubelet zitaendelea kufanya kazi hadi kubelet zitakapozisimamisha.)

Katika dakika chache kubectl inapaswa kutuonyesha maganda na nodi kama tunavyotarajia:

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

Wacha tujipongeze sana wakati huu (najua tayari nimejipongeza) - tunayo "nguzo" ndogo ya Kubernetes inayoendesha na API inayofanya kazi kikamilifu!

Tunazindua chini

Sasa hebu tuone API ina uwezo gani. Wacha tuanze na ganda la nginx:

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

Hapa tunapata kosa la kuvutia zaidi:

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

Hapa tunaona jinsi mazingira yetu ya Kubernetes yasivyokamilika - hatuna akaunti za huduma. Hebu tujaribu tena kwa kuunda mwenyewe akaunti ya huduma na tuone kitakachotokea:

$ 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

Hata tulipounda akaunti ya huduma kwa mikono, tokeni ya uthibitishaji haijatolewa. Tunapoendelea kufanya majaribio na "nguzo" yetu ndogo, tutagundua kwamba vitu vingi muhimu ambavyo kawaida hufanyika kiotomatiki vitakosekana. Seva ya Kubernetes API ni ndogo kabisa, huku sehemu kubwa ya unyanyuaji mzito na usanidi otomatiki ukifanyika katika vidhibiti mbalimbali na kazi za chinichini ambazo bado hazijafanya kazi.

Tunaweza kutatua tatizo hili kwa kuweka chaguo automountServiceAccountToken kwa akaunti ya huduma (kwa kuwa hata hivyo hatutahitaji kuitumia):

$ 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

Hatimaye, ganda limeonekana! Lakini kwa kweli haitaanza kwa sababu hatuna mpangaji (mratibu) ni sehemu nyingine muhimu ya Kubernetes. Tena, tunaona kwamba Kubernetes API ni "bubu" ya kushangaza - unapounda Pod kwenye API, inasajili, lakini haijaribu kujua ni nodi gani ya kuiendesha.

Kwa kweli, hauitaji kipanga ratiba ili kuendesha ganda. Unaweza kuongeza nodi kwa faili ya maelezo katika kigezo nodeName:

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

(Badilisha mink8s kwa jina la nodi.) Baada ya kufuta na kuomba, tunaona kwamba nginx imeanza na inasikiliza anwani ya IP ya ndani:

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

Ili kuhakikisha kuwa mtandao kati ya maganda unafanya kazi kwa usahihi, tunaweza kukimbia curl kutoka kwa ganda lingine:

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

Inafurahisha sana kuchimba katika mazingira haya na kuona ni nini kinachofanya kazi na kisichofanya kazi. Niligundua kuwa ConfigMap na Siri hufanya kazi kama inavyotarajiwa, lakini Huduma na Upelekaji hazifanyi kazi.

Mafanikio!

Chapisho hili linakuwa refu, kwa hivyo nitatangaza ushindi na kusema kwamba huu ni usanidi unaowezekana ambao unaweza kuitwa "Kubernetes". Kwa muhtasari: jozi nne, vigezo vya mstari wa amri tano na "tu" mistari 45 ya YAML (sio kiasi hicho kwa viwango Kubernetes) na tuna mambo machache yanayofanya kazi:

  • Maganda yanadhibitiwa kwa kutumia Kubernetes API ya kawaida (iliyo na hacks chache)
  • Unaweza kupakia na kudhibiti picha za vyombo vya umma
  • Podi hubaki hai na zinawashwa upya kiotomatiki
  • Mtandao kati ya maganda ndani ya nodi sawa hufanya kazi vizuri
  • ConfigMap, Siri na kazi rahisi ya kuweka uhifadhi kama inavyotarajiwa

Lakini mengi ya kile kinachofanya Kubernetes kuwa muhimu bado hakipo, kama vile:

  • Mratibu wa Podi
  • Uthibitishaji/uidhinishaji
  • Nodi nyingi
  • Mtandao wa huduma
  • DNS ya ndani iliyounganishwa
  • Vidhibiti vya akaunti za huduma, usambazaji, ujumuishaji na watoa huduma za wingu na bidhaa zingine nyingi ambazo Kubernetes huleta.

Kwa hivyo tulipata nini hasa? API ya Kubernetes, inayoendesha yenyewe, ni jukwaa tu la otomatiki ya chombo. Haifanyi mengi - ni kazi kwa watawala na waendeshaji anuwai wanaotumia API - lakini hutoa mazingira thabiti ya uwekaji otomatiki.

Pata maelezo zaidi kuhusu kozi hiyo kwenye wavuti isiyolipishwa.

Soma zaidi:

Chanzo: mapenzi.com

Kuongeza maoni