Rostini aytsam, men 100% ishonchim komil emas. Ammo, menimcha, ichki qismlarni o'rganish va Kubernetesda uning ko'plab mavhum qatlamlari ostida nima sodir bo'layotganini ko'rish qiziq. Keling, o'yin-kulgi uchun minimal "Kubernetes klasteri" aslida qanday ko'rinishini ko'rib chiqaylik. (Bu ancha oson bo'ladi Kubernetes qiyin yo'l.)
O'ylaymanki, siz Kubernetes, Linux va konteynerlar haqida asosiy bilimga egasiz. Bu yerda biz gaplashadigan hamma narsa faqat tadqiqot/taʼlim maqsadlari uchun, ulardan hech birini ishlab chiqarishga qoʻymang!
haqida umumiy ma'lumot
Kubernetes ko'plab komponentlarni o'z ichiga oladi. Ga binoan Vikipediya, arxitektura quyidagicha ko'rinadi:
Bu erda kamida sakkizta komponent ko'rsatilgan, ammo biz ularning aksariyatiga e'tibor bermaymiz. Shuni ta'kidlashni istardimki, Kubernetes deb nomlanishi mumkin bo'lgan minimal narsa uchta asosiy komponentdan iborat:
kublet
kube-apiserver (bu etcd ga bog'liq - uning ma'lumotlar bazasi)
konteyner ish vaqti (bu holda Docker)
Keling, hujjatlarda ularning har biri haqida nima deyilganini ko'rib chiqaylik (rus., Ingliz.). Boshida kublet:
Klasterdagi har bir tugun ustida ishlaydigan agent. Bu konteynerlar podda ishlayotganiga ishonch hosil qiladi.
Etarlicha oddiy eshitiladi. Nima haqida konteyner ishlash vaqtlari (konteyner ish vaqti)?
Konteynerning ishlash vaqti - bu konteynerlarni ishga tushirish uchun mo'ljallangan dastur.
Juda ma'lumotli. Ammo agar siz Docker bilan tanish bo'lsangiz, u nima qilishi haqida umumiy tasavvurga ega bo'lishingiz kerak. (Konteynerning ishlash vaqti va kubelet o'rtasidagi mas'uliyatni ajratish tafsilotlari aslida juda nozik va men bu erda ularga kirmayman.)
И API serveri?
API serveri Kubernetes boshqaruv paneli komponenti boʻlib, u Kubernetes API-ni ochib beradi. API serveri Kubernetes boshqaruv panelining mijoz tomonidir
Kubernetes bilan biror narsa qilgan har bir kishi to'g'ridan-to'g'ri yoki kubectl orqali API bilan o'zaro aloqada bo'lishi kerak edi. Bu Kubernetes Kubernetesni - biz hammamiz biladigan va sevadigan YAML tog'larini (?) ishlaydigan infratuzilmaga aylantiradigan miyaning yuragi. API bizning minimal konfiguratsiyamizda bo'lishi kerakligi aniq.
Old shartlar
Ildizga kirish huquqiga ega Linux virtual yoki jismoniy mashinasi (men virtual mashinada Ubuntu 18.04 dan foydalanmoqdaman).
Va bu hammasi!
Zerikarli o'rnatish
Biz foydalanadigan mashinaga Docker-ni o'rnatishimiz kerak. (Men Docker va konteynerlar qanday ishlashi haqida batafsil ma'lumot bermayman; agar qiziqsangiz, u erda ajoyib maqolalar). Keling, uni faqat bilan o'rnatamiz apt:
Shundan so'ng biz Kubernetes ikkiliklarini olishimiz kerak. Aslida, bizning "klasterimiz" ni dastlabki ishga tushirish uchun bizga faqat kerak kubelet, chunki boshqa server komponentlarini ishga tushirish uchun biz foydalanishimiz mumkin kubelet. Klasterimiz ishlagandan so'ng u bilan o'zaro ishlash uchun biz ham foydalanamiz kubectl.
kubelet root sifatida ishlashi kerak. Juda mantiqiy, chunki u butun tugunni boshqarishi kerak. Keling, uning parametrlarini ko'rib chiqaylik:
$ ./kubelet -h
<слишком много строк, чтобы разместить здесь>
$ ./kubelet -h | wc -l
284
Voy, juda ko'p variantlar! Yaxshiyamki, bizga ulardan faqat ikkitasi kerak. Mana bizni qiziqtirgan parametrlardan biri:
--pod-manifest-path string
Statik pods uchun fayllarni o'z ichiga olgan katalogga yo'l yoki statik podlarni tavsiflovchi faylga yo'l. Nuqtalar bilan boshlangan fayllar e'tiborga olinmaydi. (QO'SHILGAN: Bu parametr --config opsiyasi orqali Kubeletga uzatiladigan konfiguratsiya faylida o'rnatilishi kerak. Qo'shimcha ma'lumot uchun qarang. kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file .)
Ushbu parametr bizni ishga tushirishga imkon beradi statik podalar — Kubernetes API orqali boshqarilmaydigan pods. Statik podalar kamdan-kam qo'llaniladi, lekin ular klasterni tezda ko'tarish uchun juda qulaydir va bu bizga kerak bo'lgan narsadir. Biz bu katta ogohlantirishni e'tiborsiz qoldiramiz (yana buni ishlab chiqarishda ishlatmang!) va podni ishga tushirishimiz mumkinligini bilib olamiz.
Avval biz statik pods uchun katalog yaratamiz va ishga tushiramiz kubelet:
kubelet ba'zi ogohlantirishlarni yozishni boshlaydi va hech narsa sodir bo'lmaganga o'xshaydi. Ammo bu unday emas! Keling, Dockerni ko'rib chiqaylik:
$ 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 Men pod manifestini o'qib chiqdim va Dockerga bizning spetsifikatsiyalarimizga muvofiq bir nechta konteynerlarni ishga tushirish buyrug'ini berdim. (Agar siz "pauza" konteyneri haqida qiziqayotgan bo'lsangiz, bu Kubernetes xackidir - qarang. bu blog.) Kubelet bizning konteynerimizni ishga tushiradi busybox belgilangan buyruq bilan va statik pod o'chirilgunga qadar uni cheksiz muddatga qayta ishga tushiradi.
O'zingizni tabriklang. Biz faqat terminalga matn chiqarishning eng chalkash usullaridan birini topdik!
Ishga tushirish va boshqalar
Bizning yakuniy maqsadimiz Kubernetes API-ni ishga tushirishdir, lekin buning uchun avval ishga tushirishimiz kerak va boshqalar. Minimal etcd klasterini uning sozlamalarini pods katalogiga joylashtirish orqali boshlaylik (masalan, pods/etcd.yaml):
Agar siz hech qachon Kubernetes bilan ishlagan bo'lsangiz, ushbu YAML fayllari sizga tanish bo'lishi kerak. Bu erda faqat ikkita fikrni ta'kidlash kerak:
Biz xost papkasini o'rnatdik /var/lib/etcd qayta ishga tushirilgandan so'ng etcd ma'lumotlari saqlanib qolishi uchun podkada (agar bu bajarilmasa, pod har safar qayta ishga tushirilganda klaster holati o'chiriladi, bu hatto minimal Kubernetes o'rnatilishi uchun ham yaxshi bo'lmaydi).
Biz o'rnatdik hostNetwork: true. Bu sozlama, ajablanarli emas, etcd ni podning ichki tarmog'i o'rniga xost tarmog'idan foydalanish uchun sozlaydi (bu API serveriga etcd klasterini topishni osonlashtiradi).
Oddiy tekshirish shuni ko'rsatadiki, etcd haqiqatan ham localhost-da ishlaydi va ma'lumotlarni diskda saqlaydi:
$ 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 server ishga tushirilmoqda
Kubernetes API serverini ishga tushirish yanada oson. O'tish kerak bo'lgan yagona parametr --etcd-servers, siz kutgan narsani qiladi:
Ushbu YAML faylini katalogga joylashtiring pods, va API server ishga tushadi. bilan tekshirish curl Kubernetes API 8080 portni butunlay ochiq kirish bilan tinglayotganini ko'rsatadi - autentifikatsiya talab qilinmaydi!
(Yana, buni ishlab chiqarishda ishlatmang! Standart sozlama juda xavfli ekanligi meni hayratda qoldirdi. Lekin men buni ishlab chiqish va sinovdan o‘tkazishni osonlashtirish uchun qilingan deb o‘ylayman.)
Va yoqimli ajablanib, kubectl hech qanday qo'shimcha sozlamalarsiz ishlaydi!
$ ./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.
muammo
Ammo agar siz biroz chuqurroq qazsangiz, biror narsa noto'g'ri ketayotganga o'xshaydi:
$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.
Biz yaratgan statik podlar yo'qoldi! Aslida, bizning kubelet tugunimiz umuman topilmagan:
$ ./kubectl get nodes
No resources found in default namespace.
Nima bo'ldi? Agar bir necha paragraflar oldin esingizda bo'lsa, biz kubeletni juda oddiy buyruq qatori parametrlari to'plami bilan boshladik, shuning uchun kubelet API serveri bilan qanday bog'lanishni va uning holati haqida uni xabardor qilishni bilmaydi. Hujjatlarni o'rganib chiqqandan so'ng biz tegishli bayroqni topamiz:
--kubeconfig string
Faylga yo'l kubeconfig, bu API serveriga qanday ulanishni belgilaydi. Mavjudligi --kubeconfig API server rejimini yoqadi, yo'q --kubeconfig oflayn rejimini yoqadi.
Bu vaqt davomida biz bilmagan holda kubeletni "oflayn rejimda" ishga tushirdik. (Agar biz pedantik bo'lganimizda, biz mustaqil kubeletni "minimal hayotiy Kubernetes" deb o'ylashimiz mumkin edi, lekin bu juda zerikarli bo'lar edi). "Haqiqiy" konfiguratsiya ishlashi uchun biz kubeconfig faylini kubeletga o'tkazishimiz kerak, shunda u API serveri bilan qanday gaplashishni biladi. Yaxshiyamki, bu juda oddiy (chunki bizda autentifikatsiya yoki sertifikat bilan bog'liq muammolar yo'q):
(Aytgancha, agar siz kubelet ishlamayotgan vaqtda API-ga curl orqali kirishga harakat qilsangiz, u hali ham ishlayotganini ko'rasiz! Kubelet Docker kabi podslarining "ota-onasi" emas, u ko'proq "boshqaruv" ga o'xshaydi. daemon." Kubelet tomonidan boshqariladigan konteynerlar kubelet ularni to'xtatmaguncha ishlashda davom etadi.)
Bir necha daqiqadan so'ng kubectl Biz kutganimizdek, bizga podalar va tugunlarni ko'rsatishi kerak:
$ ./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
Keling, bu safar o'zimizni chin dildan tabriklaylik (men allaqachon o'zimizni tabriklaganimni bilaman) - bizda to'liq ishlaydigan API bilan ishlaydigan minimal Kubernetes "klasteri" bor!
Biz ostida ishga tushiramiz
Endi API nimaga qodirligini ko'rib chiqamiz. Nginx podidan boshlaylik:
$ ./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.
Bu erda biz Kubernetes muhitimiz qanchalik to'liq emasligini ko'ramiz - bizda xizmatlar uchun hisoblar yo'q. Xizmat hisobini qo'lda yaratish orqali qayta urinib ko'raylik va nima sodir bo'lishini ko'ramiz:
$ 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
Xizmat hisobini qo'lda yaratganimizda ham, autentifikatsiya belgisi yaratilmaydi. Minimalistik "klasterimiz" bilan tajriba o'tkazishda davom etar ekanmiz, odatda avtomatik ravishda sodir bo'ladigan foydali narsalarning ko'pchiligi yo'qolishini topamiz. Kubernetes API serveri juda minimalist bo'lib, og'ir yuklarni ko'tarish va avtomatik sozlashning aksariyati hali ishlamayotgan turli kontrollerlar va fon ishlarida sodir bo'ladi.
Variantni o'rnatish orqali bu muammoni hal qilishimiz mumkin automountServiceAccountToken xizmat hisobi uchun (chunki biz undan foydalanishimiz shart emas):
$ 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
Nihoyat, pod paydo bo'ldi! Lekin aslida u boshlamaydi, chunki bizda yo'q rejalashtiruvchi (rejalashtiruvchi) Kubernetesning yana bir muhim komponentidir. Shunga qaramay, biz Kubernetes API hayratlanarli darajada "soqov" ekanligini ko'ramiz - APIda Pod yaratganingizda, u uni ro'yxatdan o'tkazadi, lekin uni qaysi tugunda ishga tushirishni aniqlashga urinmaydi.
Aslida, podkastni ishga tushirish uchun rejalashtiruvchi kerak emas. Parametrdagi manifestga tugunni qo'lda qo'shishingiz mumkin nodeName:
(Almashtirish mink8s tugun nomiga.) Oʻchirish va qoʻllashdan soʻng biz nginx ishga tushganini va ichki IP manzilni tinglayotganini koʻramiz:
$ ./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>
Qopqoqlar orasidagi tarmoq to'g'ri ishlayotganiga ishonch hosil qilish uchun biz boshqa poddan curl ishga tushirishimiz mumkin:
$ 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 muhitni qazish va nima ishlayotganini va nima bo'lmasligini ko'rish juda qiziq. Men ConfigMap va Secret kutilganidek ishlayotganini topdim, lekin Xizmat va Deployment ishlamayapti.
Uspex!
Bu post uzoq davom etmoqda, shuning uchun men g'alabani e'lon qilmoqchiman va bu "Kubernetes" deb nomlanishi mumkin bo'lgan hayotiy konfiguratsiya ekanligini aytmoqchiman. Xulosa qilish uchun: to'rtta ikkilik, beshta buyruq qatori parametrlari va "faqat" 45 qator YAML (emas) Kubernetes standartlari bo'yicha) va bizda juda ko'p narsa ishlaydi:
Podlar oddiy Kubernetes API yordamida boshqariladi (bir nechta xakerlar bilan)
Siz ommaviy konteyner rasmlarini yuklashingiz va boshqarishingiz mumkin
Podlar tirik qoladi va avtomatik ravishda qayta ishga tushadi
Xuddi shu tugun ichidagi podlar o'rtasidagi tarmoq juda yaxshi ishlaydi
ConfigMap, maxfiy va oddiy saqlashni o'rnatish kutilganidek ishlaydi
Ammo Kubernetes-ni haqiqatan ham foydali qiladigan ko'p narsalar hali ham etishmayapti, masalan:
Pod Scheduler
Autentifikatsiya/avtorizatsiya
Bir nechta tugunlar
Xizmatlar tarmog'i
Klasterli ichki DNS
Xizmat hisoblari uchun kontrollerlar, joylashtirishlar, bulutli provayderlar bilan integratsiya va Kubernetes keltiradigan ko'pgina boshqa yaxshiliklar
Xo'sh, biz aslida nimani oldik? O'z-o'zidan ishlaydigan Kubernetes API haqiqatan ham shunchaki platformadir konteynerni avtomatlashtirish. Bu ko'p narsa qilmaydi - bu API-dan foydalanadigan turli kontrollerlar va operatorlar uchun ishdir - lekin u avtomatlashtirish uchun izchil muhitni ta'minlaydi.