Kubernetes 101 (2-р хэсэг)

Энэ удаагийн нийтлэлээр kubernetes api object-уудын талаар дэлгэрэнгүй тайлбарлах болно. Тэгэхээр k8s api object гэж юу вэ?

k8s-н бүхий л бүрдэл хэсгүүд нь өөр өөрсдийн api group-т багтах бөгөөд тэдгээр нь api object-оор тодорхойлогдоно. Хамгийн түгээмэл хэрэглэгддэг object-ууд бол Pod, Deployment, Service, Ingress, StatefulSet зэрэг юм. Эдгээрийг ерөнхий том зургаар харуулсан нээх гоё зураг олсонгүй тул тус тусад нь тайлбарлая.


k8s-н хамгийн жижиг нэгж бол Pod юм. Pod нь нэг болон нилээн хэдэн container-уудаас бүрдэнэ. Container нь энгийндээ docker run .. гээд ажиллуулдаг шиг ажиллаж буй 1ш container instance-г хэлнэ. Docker-оос онцлогтой нь 1 Pod дотор олон container-ууд зэрэгцэн оршиж болох бөгөөд 1 Pod нь 1ш unique IP-тай байна. Ингэснээр 1 pod дотор орших container-ууд хоорондоо localhost-оор буюу 1 сүлжээгээр харьцана. Өөрөөр хэлбэл 1 pod дотор 2ш 80 порт дээр ажиллах апп зэрэгцэн ажиллах боломжгүй юм. Харин FileSystem-н хувьд өөр байна. Pod-г ихэвчлэн шууд үүсгэхгүй хөндлөнгийн object-оос удирддаг.

ReplicaSet нь Pod-н дээд талын нэгж бөгөөд 1pod-г 1 replicaset удирдана. 1 Pod дотор хичнээн container байх вэ, энэхүү pod-г тус бүр хэд хувилах вэ зэрэг хуваарилах үүргийг replicaset гүйцэтгэнэ. Гэхдээ бид ReplicaSet-тэй хэзээ ч (бараг л) шууд харьцахгүй бөгөөд бидний хамгийн их ашиглах object бол RS-н дээд талын нэгж болох Deployment юм. (ReplicaSet-н өмнө ReplicationController гэж байсан бөгөөд одоо ReplicaSet болон Deployment болж задарсан юм.) Deployment нь RS-уудыг удирдах бөгөөд энд хичнээн pod үүсгэх, хичнээн container-ууд хоорондоо хэрхэн холбогдож ажиллах зэргийг тодорхойлно. Deployment нь яагаад RS-ээ удирддаг вэ гэхээр RS нь Pod-той 1:1 хамааралтай. Жишээлбэл application v1-дээ шинэчлэлт хийгээд v2-ийг ажиллуулах болох үед deployment нь шинээр v2-т зориулсан RS үүсгэнэ. v2-н RS нь v2-т зориулсан Pod-оо үүсгэх гэх мэт хоорондоо уялдаатай ажиллана.


Ингээд бид ямар ч байсан deployment ашиглан pod-оо ажиллуулчихлаа. Одоо гаднаас эсвэл cluster доторх бусад апп-ууд хэрхэн уг апп-тай маань харьцах вэ? Энэхүү асуудлыг шийдэхийн тулд k8s service object-г ашиглана. Service нь kube-dns (одоо core-dns-ээр солигдсон) буюу k8s cluster доторх dns серверийг ашиглан deployment-уудад FQDN (Fully Qualified Domain name) буюу IP-г domain нэр болгон ашиглах боломж олгоно. Жишээлбэл би http://10.3.0.16 гэсэн IP хаягаар сервислүүгээ хандахын оронд http://my-service.default-subdomain.my-namespace.svc.cluster-domain.example гэх мэт тогтмол нэрээр хандах боломжтой болох юм. Мөн kubernetes-н pod бүр дахин давтагдашгүй IP хаяг авах бөгөөд шинэ pod үүсэх болгонд энэхүү IP хаяг автоматаар өөрчлөгдөж байдаг тул байнга мэдээд байх боломжгүй юм. Service-тэй болсноор уг апп-руугаа cluster дотроосоо тогтмол хаягаар хандаж чаддаг боллоо. Гэхдээ гаднаас бусад хэрэглэгчид хэрхэн хандах вэ?

Энэхүү асуудлыг шийдэхийн тулд k8s ingress object-г ашиглана. Ingress нь OSI model-н Transport layer L4 болон Application layer L7 дээр ажиллах боломжтой ч хүмүүс ихэвчлэн L7 дээр ашигладаг. L7 нь бидний сайн мэдэх https://google.com/keep гэх мэт domain name + path гэсэн хослол юм. Нэг зүйлийг онцлон дурдахад Ingress нь зөвхөн L7 дүрмүүдийн тодорхойлолт бөгөөд дангаараа юу ч хийдэггүйг анхаарна уу. L7 тохиргоонуудыг яг ажиллуулах програмыг та өөрөө сонгох ёстой. Бидний хамгийн түгээмэл хэрэглэдэг нь ingress-nginx юм. Энэхүү програмыг ingress controller гэх бөгөөд бидний тодорхойлсон ingress object-уудыг удирдан ажиллуулах үүрэгтэй. Ingress-nginx controller нь nginx-н open source хувилбар дээр анх суурилж эхэлсэн ч 0.25.0 хувилбараас эхлэн nginx-н fork болох openresty-г ашиглах болсон.


Энэ хүртэл явсан бол та k8s дээр хэрхэн өөрийн deployment-г үүсгэх мөн хэрхэн домэйнд холбон интернэтэд холбох зэрэг талаар ерөнхий ойлголттой боллоо. Container-ууд нь ихэвчлэн байнгын хөдөлгөөнд оршиж байнга шинээр үүсч, хуучин нь устаж байдаг тул container-уудыг stateless буюу дээр нь өгөгдөл хадгалах зорилгоор ашиглахгүй байх нь тохиромжтой. Гэвч бүх апп тийм зорилгоор ашиглагдах боломжгүй. Жишээлбэл database бол заавал ч гүй өгөгдлөө дискэн дээрээ хадгалах л ёстой. Үүнийг шийдэхийн тулд StatefulSet гэсэн api object гарч ирсэн бөгөөд statefulset нь deployment/replicaset-н адил шууд pod-уудыг үүсгэнэ. Гэхдээ STS-ээр үүссэн pod-ууд нь тогтмол нэртэй байх бөгөөд жишээлбэл pod-0.service.namespace… , pod-1.service.namespace …гэх мэт нэртэй байна. STS нь мөн PVC (Persistent Volume Claim) буюу k8s-н хатуу дискийг төлөөлсөн object-той харьцаж өөрийн pod-ууддаа тэрхүү дискийг холбож ажиллуулснаар бид k8s дотор stateful app буюу database-үүдийг ажиллуулах боломжтой. k8s-н PV, PVC нь тайлбарлахад том ойлголт тул дараа нь тусад нь сэдэв зориулан бичье.