Нийтлэлийн орчуулгыг курс эхлэхийн өмнөх өдөр бэлтгэсэн
Хэрэв та үүнийг уншиж байгаа бол та Кубернетесийн талаар ямар нэг зүйл сонссон байх (мөн үгүй бол та энд яаж ирсэн бэ?) Гэхдээ Кубернетес гэж яг юу вэ? Энэ
Үнэнийг хэлэхэд би 100% итгэлтэй биш байна. Гэхдээ миний бодлоор дотоод сэтгэлгээг ухаж, олон давхар хийсвэрлэлийн дор Кубернетес хотод юу болж байгааг харах нь сонирхолтой юм. Зүгээр л хөгжилтэй байхын тулд хамгийн бага "Кубернетес кластер" ямар харагддагийг харцгаая. (Энэ нь хамаагүй хялбар байх болно
Таныг Кубернетес, Линукс, контейнерийн талаар анхан шатны мэдлэгтэй гэж бодож байна. Бидний энд ярьж байгаа бүх зүйл зөвхөн судалгаа/сургалтад зориулагдсан тул аль нэгийг нь үйлдвэрлэлд бүү оруулаарай!
тойм
Kubernetes нь олон бүрэлдэхүүн хэсгүүдийг агуулдаг. дагуу
Энд дор хаяж найман бүрэлдэхүүн хэсэг байгаа боловч бид тэдгээрийн ихэнхийг үл тоомсорлох болно. Кубернетес гэж нэрлэж болох хамгийн бага зүйл нь гурван үндсэн бүрэлдэхүүн хэсгээс бүрддэг гэдгийг би хэлмээр байна.
- кубелет
- kube-apiserver (энэ нь etcd - түүний мэдээллийн сангаас хамаарна)
- контейнер ажиллах хугацаа (энэ тохиолдолд Docker)
Баримт бичигт тус бүрийн талаар юу хэлснийг харцгаая (
Кластер дахь зангилаа бүр дээр ажиллаж буй агент. Энэ нь саванд савнууд ажиллаж байгаа эсэхийг баталгаажуулдаг.
Хангалттай энгийн сонсогдож байна. Яах вэ контейнер ажиллах хугацаа (контейнер ажиллах хугацаа)?
Контейнер ажиллуулах хугацаа нь контейнер ажиллуулах зориулалттай програм юм.
Маш мэдээлэл сайтай. Гэхдээ хэрэв та Docker-ийг мэддэг бол энэ нь юу хийдэг талаар ерөнхий ойлголттой байх ёстой. (Сантерийн ажиллах хугацаа болон кубелетийн хоорондох үүрэг хариуцлагыг салгах нарийн ширийн зүйл нь үнэндээ маш нарийн бөгөөд би энд ярихгүй.)
И API сервер?
API сервер нь Kubernetes API-г ил гаргадаг Kubernetes хяналтын самбарын бүрэлдэхүүн хэсэг юм. API сервер нь Kubernetes хяналтын самбарын клиент тал юм
Kubernetes-тэй ямар нэгэн зүйл хийж байсан хэн бүхэн API-тай шууд эсвэл kubectl-ээр дамжуулан харилцах шаардлагатай болдог. Энэ бол бидний мэддэг, хайрладаг YAML-ийн уулсыг (?) ажлын дэд бүтэц болгон хувиргадаг тархи болох Кубернетес Кубернетесийг юу болгож байгаагийн гол зүрх юм. API нь бидний хамгийн бага тохиргоонд байх ёстой нь ойлгомжтой юм шиг байна.
Урьдчилсан нөхцөл
- root хандалттай Линуксийн виртуал эсвэл физик машин (би виртуал машин дээр Ubuntu 18.04 ашиглаж байна).
- Энэ бүгд!
Уйтгартай суурилуулалт
Бид ашиглах машин дээрээ Docker суулгах хэрэгтэй. (Би Docker болон контейнер хэрхэн ажилладаг талаар дэлгэрэнгүй ярихгүй; хэрэв та сонирхож байвал apt
:
$ sudo apt install docker.io
$ sudo systemctl start docker
Үүний дараа бид Kubernetes хоёртын файлыг авах хэрэгтэй. Үнэн хэрэгтээ манай "кластер" -ийг анх эхлүүлэхийн тулд бидэнд хэрэгтэй kubelet
, учир нь бид бусад серверийн бүрэлдэхүүн хэсгүүдийг ажиллуулахын тулд ашиглаж болно kubelet
. Кластер ажиллаж дууссаны дараа түүнтэй харилцахын тулд бид бас ашиглах болно 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
Бид зүгээр л гүйгээд байвал яах вэ kubelet
?
$ ./kubelet
F0609 04:03:29.105194 4583 server.go:254] mkdir /var/lib/kubelet: permission denied
kubelet
root хэлбэрээр ажиллах ёстой. Тэр бүхэл бүтэн зангилааг удирдах шаардлагатай тул нэлээд логик юм. Түүний параметрүүдийг харцгаая:
$ ./kubelet -h
<слишком много строк, чтобы разместить здесь>
$ ./kubelet -h | wc -l
284
Хөөх, маш олон сонголт! Аз болоход бидэнд зөвхөн хоёр нь л хэрэгтэй. Бидний сонирхож буй параметрүүдийн нэг нь энд байна:
--pod-manifest-path string
Статик pods-д зориулсан файлуудыг агуулсан лавлах зам эсвэл статик подкуудыг дүрсэлсэн файлын зам. Цэгээр эхэлсэн файлуудыг үл тоомсорлодог. (ХУГАЦААГҮЙ: Энэ сонголтыг --config сонголтоор дамжуулан Kubelet-д дамжуулсан тохиргооны файлд тохируулах ёстой. Дэлгэрэнгүй мэдээллийг үзнэ үү.
Энэ сонголт нь биднийг ажиллуулах боломжийг олгодог
Эхлээд бид статик pods-д зориулсан лавлах үүсгээд ажиллуулна kubelet
:
$ mkdir pods
$ sudo ./kubelet --pod-manifest-path=pods
Дараа нь өөр терминал/tmux цонхонд/юунд ч бид 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
зарим анхааруулга бичиж эхэлдэг бөгөөд юу ч болоогүй юм шиг санагддаг. Гэхдээ энэ нь үнэн биш юм! Докерыг харцгаая:
$ 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
Би pod manifest-ийг уншаад Docker-д манай техникийн дагуу хэд хэдэн контейнер ажиллуулах тушаал өгсөн. (Хэрэв та "түр зогсоох" савны талаар гайхаж байгаа бол энэ нь Kubernetes-ийн хакердсан хэрэг - үзнэ үү. busybox
заасан командыг ашиглан статик подыг устгах хүртэл тодорхойгүй хугацаагаар дахин эхлүүлэх болно.
Өөртөө баяр хүргэе. Терминал руу текст гаргах хамгийн будлиантай аргуудын нэгийг бид дөнгөж сая бодож оллоо!
Эхлүүлэх гэх мэт
Бидний эцсийн зорилго бол Kubernetes API-г ажиллуулах явдал боловч үүнийг хийхийн тулд эхлээд ажиллуулах хэрэгтэй 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
Хэрэв та хэзээ нэгэн цагт Kubernetes-тэй ажиллаж байсан бол эдгээр YAML файлууд танд танил байх ёстой. Энд зөвхөн хоёр зүйлийг анхаарч үзэх хэрэгтэй.
Бид хост фолдерыг суулгасан /var/lib/etcd
Дахин ачаалсны дараа etcd өгөгдөл хадгалагдах тул pod-д суулгана (хэрэв үүнийг хийгээгүй бол подкликийг дахин эхлүүлэх бүрт кластерийн төлөв устах бөгөөд энэ нь Кубернетесийн хамгийн бага суулгалтад ч тохирохгүй).
Бид суулгасан hostNetwork: true
. Энэ тохиргоо нь etcd-г подын дотоод сүлжээний оронд хост сүлжээг ашиглахаар тохируулдаг нь гайхмаар зүйл биш юм (энэ нь API серверт etcd кластерийг олоход хялбар болгоно).
Энгийн шалгалт нь etcd нь үнэхээр localhost дээр ажиллаж, өгөгдлийг дискэнд хадгалж байгааг харуулж байна:
$ 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 серверийг эхлүүлж байна
Kubernetes API серверийг ажиллуулах нь бүр ч хялбар. Дамжуулах шаардлагатай цорын ганц параметр бол --etcd-servers
, таны хүлээж буй зүйлийг хийнэ:
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
Энэ YAML файлыг директорт байрлуул pods
, мөн API сервер эхлэх болно. -тай шалгаж байна curl
Kubernetes API нь бүрэн нээлттэй хандалттай 8080 портыг сонсож байгааг харуулж байна - баталгаажуулалт шаардлагагүй!
$ curl localhost:8080/healthz
ok
$ curl localhost:8080/api/v1/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "59"
},
"items": []
}
(Дахин хэлэхэд, үүнийг үйлдвэрлэлд бүү ажиллуул! Би анхдагч тохиргоо нь тийм найдвартай биш байгаад бага зэрэг гайхсан. Гэхдээ энэ нь хөгжүүлэлт, туршилтыг хөнгөвчлөх зорилготой гэж таамаглаж байна.)
Мөн тааламжтай гэнэтийн бэлэг, kubectl ямар ч нэмэлт тохиргоогүйгээр хайрцагнаас гарч ажилладаг!
$ ./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.
асуудал
Гэхдээ хэрэв та бага зэрэг гүн ухвал ямар нэг зүйл буруу болж байх шиг байна:
$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.
Бидний үүсгэсэн статик подкууд алга болсон! Үнэндээ бидний kubelet зангилаа огт нээгдээгүй байна:
$ ./kubectl get nodes
No resources found in default namespace.
Юу болсон бэ? Хэрэв та хэдэн догол мөрийн өмнө санаж байгаа бол бид kubelet-ийг командын мөрийн параметрүүдийн маш энгийн багцаар эхлүүлсэн тул kubelet API сервертэй хэрхэн холбогдож, төлөвийнх нь талаар мэдэгдэхээ мэдэхгүй байна. Баримт бичгийг судалсны дараа бид тохирох тугийг олно.
--kubeconfig string
Файлд хүрэх зам kubeconfig
, энэ нь API сервертэй хэрхэн холбогдохыг зааж өгдөг. Бэлэн байдал --kubeconfig
API серверийн горимыг идэвхжүүлдэг, үгүй --kubeconfig
офлайн горимыг идэвхжүүлдэг.
Энэ бүх хугацаанд бид өөрийн мэдэлгүй kubelet-ийг "офлайн горимд" ажиллуулж байсан. (Хэрэв бид педантик байсан бол бие даасан кубелетийг "хамгийн бага амьдрах чадвартай Кубернетес" гэж төсөөлж болох ч энэ нь маш уйтгартай байх болно). "Бодит" тохиргоог ажиллуулахын тулд бид kubeconfig файлыг kubelet рүү дамжуулах хэрэгтэй бөгөөд ингэснээр API сервертэй хэрхэн ярихаа мэддэг. Аз болоход энэ нь маш энгийн (бидэнд баталгаажуулалт эсвэл гэрчилгээний асуудал байхгүй тул):
apiVersion: v1
kind: Config
clusters:
- cluster:
server: http://127.0.0.1:8080
name: mink8s
contexts:
- context:
cluster: mink8s
name: mink8s
current-context: mink8s
Үүнийг дараах байдлаар хадгал kubeconfig.yaml
, үйл явцыг устгана kubelet
шаардлагатай параметрүүдээр дахин эхлүүлнэ үү:
$ sudo ./kubelet --pod-manifest-path=pods --kubeconfig=kubeconfig.yaml
(Дашрамд хэлэхэд, хэрэв та kubelet ажиллахгүй байхад curl-ээр API-д хандахыг оролдвол энэ нь одоо ч ажиллаж байгааг олж мэдэх болно! Kubelet нь Docker шиг подкуудын "эцэг эх" биш, харин "хяналт"-тай адил юм. дэмон." Кубелетийн удирддаг савнууд кубелет тэднийг зогсоох хүртэл ажиллана.)
Хэдхэн минутанд kubectl
Бидний бодож байгаагаар хонхорцог болон зангилаануудыг харуулах ёстой:
$ ./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
Энэ удаад үнэхээр баяр хүргэе (би аль хэдийн өөрсдөдөө баяр хүргэсэн гэдгээ мэдэж байна) - бидэнд бүрэн ажиллагаатай API бүхий хамгийн бага Kubernetes "кластер" байгаа!
Бид доор ажиллуулж байна
Одоо API ямар чадвартай болохыг харцгаая. Nginx pod-оос эхэлцгээе:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
Энд бид нэлээд сонирхолтой алдааг олж авах болно:
$ ./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.
Эндээс бид Kubernetes-ийн орчин хэчнээн бүрэн бус байгааг харж байна - бидэнд үйлчилгээний данс байхгүй. Үйлчилгээний бүртгэлийг гараар үүсгэн дахин оролдоод юу болохыг харцгаая:
$ 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
Үйлчилгээний бүртгэлийг гараар үүсгэсэн ч баталгаажуулалтын токен үүсдэггүй. Бид өөрсдийн минималист "кластер"-аа үргэлжлүүлэн туршиж үзэхэд ихэвчлэн автоматаар тохиолддог ихэнх ашигтай зүйлс алга болно гэдгийг олж мэдэх болно. Kubernetes API сервер нь нэлээд минималист бөгөөд хүнд даацын болон автомат тохиргооны ихэнх нь янз бүрийн хянагч болон хараахан ажиллаж амжаагүй суурь ажлуудад хийгддэг.
Бид сонголтыг тохируулснаар энэ асуудлыг шийдэж чадна automountServiceAccountToken
үйлчилгээний дансны хувьд (бид үүнийг ямар ч байсан ашиглах шаардлагагүй болно):
$ 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
Эцэст нь хонхорхой гарч ирэв! Гэвч үнэндээ манайд байхгүй учраас эхлэхгүй
Үнэн хэрэгтээ pod ажиллуулахын тулд төлөвлөгч хэрэггүй. Та параметрийн манифест руу гараар зангилаа нэмж болно nodeName
:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
nodeName: mink8s
(Солих mink8s
Зангилааны нэр.) Устгаж хэрэглэсний дараа бид nginx ажиллаж, дотоод IP хаягийг сонсож байгааг харж байна:
$ ./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>
Дотор хоорондын сүлжээ зөв ажиллаж байгаа эсэхийг шалгахын тулд бид өөр нэг подноос curl ажиллуулж болно:
$ 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>
Энэ орчныг ухаж, юу нь болж, юу нь болохгүй байгааг харах нь нэлээд сонирхолтой юм. ConfigMap болон Secret нь хүлээгдэж байгаа шиг ажиллаж байгааг би олж мэдсэн боловч Үйлчилгээ болон Байршлуулалт нь тэгдэггүй.
Амжилт!
Энэ нийтлэл удаан болж байгаа тул би ялалтаа зарлаж, энэ бол "Кубернетес" гэж нэрлэгдэх боломжтой тохиргоо юм гэж хэлэх болно. Дүгнэж хэлэхэд: дөрвөн хоёртын файл, таван тушаалын мөрийн параметр ба "зөвхөн" 45 мөр YAML (биш Kubernetes стандартын дагуу) мөн бидэнд маш олон зүйл ажиллаж байна:
- Pod-уудыг ердийн Kubernetes API ашиглан удирддаг (хэд хэдэн хакердсан)
- Та нийтийн контейнерийн зургийг байршуулж, удирдах боломжтой
- Подууд амьд хэвээр байх бөгөөд автоматаар дахин асаана
- Нэг зангилаа доторх pods хоорондын сүлжээ нь маш сайн ажилладаг
- ConfigMap, Нууц, хадгалах санг суурилуулах нь хүлээгдэж буй шигээ ажилладаг
Гэхдээ Кубернетесийг үнэхээр хэрэгтэй болгодог зүйлсийн ихэнх нь дутуу хэвээр байна, тухайлбал:
- Под хуваарьлагч
- Баталгаажуулалт/зөвшөөрөл
- Олон зангилаа
- Үйлчилгээний сүлжээ
- Кластерт дотоод DNS
- Үйлчилгээний дансны хянагч, байршуулалт, үүлэн үйлчилгээ үзүүлэгчтэй нэгтгэх болон Kubernetes-ийн авчирдаг бусад сайн зүйлс.
Тэгэхээр бид үнэндээ юу авсан бэ? Kubernetes API нь дангаараа ажилладаг бөгөөд энэ нь ердөө л платформ юм савны автоматжуулалт. Энэ нь тийм ч их зүйл хийдэггүй - энэ нь API ашигладаг янз бүрийн хянагч, операторуудад зориулсан ажил юм - гэхдээ энэ нь автоматжуулалтын тогтвортой орчинг бүрдүүлдэг.
Цааш унших:
Системийн администраторууд, хөгжүүлэгчид, тестерүүд яагаад DevOps практикт суралцах ёстой вэ? Thanos - Өргөтгөх боломжтой Прометей GitLab QA баг GitLab Performance Tool-ийг хэрхэн ашигладаг талаар Локи - Прометей аргыг ашиглан бүртгэл цуглуулах DevOps-ийн амьдралын нэг өдөр
Эх сурвалж: www.habr.com