Kubernetes klasterindəki boşluqları aradan qaldırırıq. DevOpsConf-dan təqdimat və transkript.

Pavel Selivanov, Southbridge solution architect and Slerma instructor, delivered a presentation at DevOpsConf 2019. This presentation is part of one of the advanced course topics on Kubernetes 'Slerma Mega'.

Slerma Basic: Introduction to Kubernetes takes place in Moscow from November 18-20.
Slerma Mega: Peeking under the hood of Kubernetes — Moscow, November 22-24.
Slerma Online: both courses on Kubernetes are always available.

Videonu izləyin

Below the cut is a transcript of the lecture.

Good day, colleagues and sympathizers. Today I will talk about security.

I see that there are many security professionals in the audience today. I apologize in advance if I use security terminology somewhat differently than you are used to.

It just so happened that about six months ago, I got my hands on a public Kubernetes cluster. Public means there are a number of namespaces, in which there are users isolated in their namespace. All these users belong to different companies. Well, it was assumed that this cluster needs to be used as a CDN. That is, you are given a cluster, provided with a user, and you come to your namespace to deploy your front ends.

My previous company tried to sell such a service. And I was asked to poke around the cluster to see if such a solution was suitable or not.

I came into this cluster. I was given limited rights and a restricted namespace. The guys there understood what security meant. They read about Role-based access control (RBAC) in Kubernetes—and they configured it so that I could not run pods separately from deployments. I don’t remember the task I was trying to solve by running a pod without a deployment, but I really wanted to just run a pod. By chance, I decided to see what rights I had in the cluster, what I could and could not do, and what they had configured. Along the way, I will tell you what they configured incorrectly in RBAC.

It just so happened that within two minutes I got admin access to their cluster, looked into all neighboring namespaces, and saw production front ends of companies that had already bought the service and deployed. I barely stopped myself from going to someone’s front end and posting some inappropriate word on the main page.

I will illustrate with examples how I did this and how to protect against it.

Amma əvvəlcə özümü təqdim edim. Mənim adım Pavel Selivanov. Mən Southbridge şirkətinin memarıyam. Kubernetes, DevOps və digər müasir texnologiyalarla tanışam. Biz Southbridge mühəndisləri ilə birlikdə bu sistemləri qururuq və mən məsləhət verirəm.

Əsas fəaliyyətimizdən əlavə, biz yaxınlarda Slërm adlı layihələri də işə saldıq. Kubernetes ilə işləmə bacarığımızı kütlə arasında yaymağa çalışırıq, başqalarını da K8s-də işləməyə öyrətmək istəyirik.

Bu gün mən nədən danışacağam. Müzakirə mövzusu aydındır - Kubernetes klasterinin təhlükəsizliyi. Lakin dərhal qeyd etməliyəm ki, bu mövzu çox genişdir və bu səbəbdən hansı mövzudan danışmayacağımı da qeyd etmək istəyirəm. İnternetdə artıq dəfələrlə müzakirə edilmiş, sıradan mövzulara, məsələn, RBAC və sertifikatlara toxunmayacağam.

Mən Kubernetes klasterində təhlükəsizliklə bağlı problemlərimizi və həmkarlarımın narahatlıqlarını müzakirə edəcəyəm. Bu problemləri həm Kubernetes klasterlərini təmin edən provayderlərdə, həm də bizə gələn müştərilərdə görürük. Hətta bizə digər konsaltinq şirkətlərindən gələn müştərilərdə də bu problemləri müşahidə edirik. Yəni məsələ gerçəkdən çox genişdir.

Bu gün müzakirə edəcəyim üç əsas nöqtə var:

  1. İstifadəçi hüquqları vs pod hüquqları. İstifadəçi hüquqları və pod hüquqları eyni deyil.
  2. Klaster haqqında məlumatların toplanması. Klasterdən xüsusi hüquqlara malik olmadan toplana biləcək bütün məlumatları göstərəcəyəm.
  3. Klasterə DoS hücumu. Əgər məlumat toplaya bilməsək, klasteri hər halda mühasirəyə ala bilərik. Klasterin idarəedici elementlərinə DoS hücumları haqqında danışacağam.

Bir başqa ümumi məsələ isə odur ki, bunları hansı mühitdə test etdiyimdir, yəni bunların işlədiyini dəqiq şəkildə deyə bilirəm.

Biz Kubernetes klasterini Kubespray vasitəsilə quraşdırmağı əsas götürürük. Kim bilir, bu faktiki olaraq Ansible üçün rol dəstidir. Biz onu işdə daima istifadə edirik. Yaxşıdır, çünki onu harada olursa olsun tətbiq etmək olur - həm avadanlıqlara, həm də buluda. Bir quraşdırma metodu prinsip etibarilə hər şey üçün uyğundur.

Bu klasterde mənim Kubernetes v1.14.5-ə sahib olacağım. Müxtəlif komandalara aid olan hər bir namespace-yə bölünmüş bir kub klasteri nəzərdən keçirəcəyik. Hər bir namespace-ə yalnız bu komandanın üzvlərinin daxil olma hüququ var. Ancaq bütün klasterə giriş imkanı olan bir admin hesabı var.

Kubernetes klasterindəki boşluqları aradan qaldırırıq. DevOpsConf-dan təqdimat və transkript.

Mən vəd etmişdim ki, bizim ilk addımımız klasterdə admin hüquqları əldə etmək olacaq. Bizə Kubernetes klasterini pozacaq xüsusi hazırlanmış bir pod lazımdır. Bunu klaster Kubernetes-ə tətbiq etmək kifayətdir.

kubectl apply -f pod.yaml

Bu pod klaster Kubernetes-in bir master-nə gələcək. Bunun ardınca klaster bizə admin.conf adlanan bir fayl qaytaracaq. Bu faylda admin-in bütün sertifikatları saxlanır, eyni zamanda klasterin API-si qurulub. Beləliklə, admin girişini əldə etmək çox asandır, düşünürəm ki, Kubernetes klasterlərinin 98%-nə giriş edilir.

Təkrarlayıram, bu pod sizin klasterdə olan bir inkişaf etdirici tərəfindən yaradılıb ki, o, öz təkliflərini kiçik bir namespace-ə yerləşdirmək hüququna malikdir, RBAC ilə tamamilə sıxışdırılıb. Onun heç bir hüququ yox idi. Lakin buna baxmayaraq, sertifikat geri qaytarıldı.

İndi isə xüsusi hazırlanmış pod haqqında. Hər hansı bir imicdə işə salırıq. Nümunə üçün debian:jessie-i götürək.

Bizdə belə bir şey var:

tolerations:
-   effect: NoSchedule 
    operator: Exists 
nodeSelector: 
    node-role.kubernetes.io/master: "" 

Toleration nədir? Kubernetes klasterindəki master-lər adətən taint (ingiliscə "zəhərlilik") adlı bir şeylə işarələnir. Bu "zəhərlilik" deməkdir ki, master nodlara pod-lar yerləşdirilə bilməz. Amma heç kim bir pod-da göstərməyə mane olmur ki, o, "zəhərlilik"-ə tolerantdır. Toleration bölməsi, əgər bir nodda NoSchedule varsa, bizim pod-un belə bir zəhərliliyə tolerant olduğunu bildirir - və heç bir problem yoxdur.

Daha sonra, biz deyirik ki, bizim pod yalnız tolerant deyil, həm də xüsusi olaraq master-a düşmək istəyir. Çünki master-lərdə bizim lazım olan ən iri məlumatlar - bütün sertifikatlar var. Buna görə biz nodeSelector deyirik - və master-lərdə seçmək üçün standart bir etiketimiz var, bu da klasterin bütün nodları arasında yalnız master-nodu seçməyə imkan verir.

Belə iki bölmə ilə pod mütləq master-a gələcək. Və ona orada qalmaq icazəsi veriləcək.

Lakin sadəcə olaraq master-a gəlmək kifayət deyil. Bu, bizə heç bir şey verməyəcək. Buna görə də bizdə belə iki şey var:

hostNetwork: true 
hostPID: true 

Biz, bizim işə saldığımız podun kernel ad boşluğunda, şəbəkə ad boşluğunda və PID ad boşluğunda yaşayacağını bildiririk. Pod masterdə işə salındıqda, bu nodun bütün real, aktiv interfeyslərini görə biləcək, bütün trafiki dinləyə biləcək və bütün proseslərin PID-lərini görə biləcək.

Sonra iş az qalıb. etcd götürürsünüz və istədiyinizi oxuyursunuz.

Ən maraqlısı - bu, Kubernetes-in varsayılan olaraq mövcud olan bu xüsusiyyətidir.

volumeMounts:
- mountPath: /host 
  name: host 
volumes:
- hostPath: 
    path: / 
    type: Directory 
  name: host 

Və bunun mahiyyəti ondadır ki, biz, işə saldığımız podda, bu klasterdə hər hansı bir hüququmız olmadan belə, hostPath tipində bir volume yaratmaq istədiyimizi bildirə bilərik. Yəni, işə saldığımız hostdan yolu götürüb, onu volume kimi istifadə edirik. Və sonra ona name: host deyirik. Bütün bu hostPath-i podun içinə montaj edirik. Bu nümunədə /host direktoryasına.

Bir daha təkrar edirəm. Podumuzu masterə gəlməyi, orada hostNetwork və hostPID almasını söylədik və masterin kökünü bu podun içində montaj etmək.

Anlayırsınız ki, Debian-da bizim bash açılır və bu bash root altında işləyir. Yəni, biz az əvvəl masterə root əldə etdik, buna baxmayaraq Kubernetes klasterində heç bir hüququmız yoxdur.

Sonra bütün iş, podda /host /etc/kubernetes/pki direktoryasına daxil olub, əgər səhv etmirəmsə, oradan bütün master sertifikatlarını götürmək və müvafiq olaraq klasterin administratoru olmaqdır.

Əgər belə baxsanız, bu podlarda ən təhlükəli hüquqlardan biridir - istifadəçinin hüquqlarına baxmayaraq:
Kubernetes klasterindəki boşluqları aradan qaldırırıq. DevOpsConf-dan təqdimat və transkript.

Əgər mənim klasterin hansısa ad boşluğunda pod işə salmaq hüququm varsa, bu podun da varsayılan olaraq bu hüquqları var. Mən imtiyazlı podlar işə sala bilərəm və bu, demək olar ki, nodda root hüquqlarıdır.

Mənim sevdiyim - Root user. Və Kubernetes-in Run As Non-Root kimi bir seçimi var. Bu, hackerlardan qorunma üçün bir cürdür. Məlumatınız olsun, "moldovan virusu" nədir? Əgər siz təsadüfən hacker olsanız və mənim Kubernetes klasterimə girmisinizsə, biz, kasıb administratorlar acizik: "Zəhmət olmasa, bizim klasterimizi hack edəcəyiniz podlarda run as non-root deyin. Əks halda, sizin podunuzda prosesi root altında işə salacaqsınız və məni hack etmək çox asan olacaq. Özünüzdən qorunun, zəhmət olmasa."

Host path volume - mənim fikrimcə, Kubernetes klasterindən istədiyinizi əldə etməyin ən sürətli yoludur.

Amma bununla nə edək?

Hər bir normal administratorun Kubernetes ilə qarşılaşdığında düşünməli olduğu şeylərdən biri: "Aha, dedim ki, Kubernetes işləmir. Onun içində çatlar var. Bütün Kubernetes gərəksizdir". Əslində, sənədləşmə var və ora baxsan, orada bir bölmə var. Pod Security Policy.

Bu, Kubernetes klasterində yarada bildiyimiz yaml-obyektidir - o, podların təhlükəsizlik aspektlərini idarə edir. Yəni, əslində hostNetwork, hostPID, podların işə salınması zamanı olan müəyyən tipli volume-lərə istifadə hüquqlarını idarə edir. Pod Security Policy vasitəsi ilə bunları hamısını təsvir edə bilərik.

Pod Security Policy ilə bağlı ən maraqlı şey, Kubernetes klasterində PSP-lərin heç bir şəkildə təsvir edilməməsidir; onlar sadəcə olaraq standart olaraq deaktivdir. Pod Security Policy, admission plugin vasitəsi ilə aktivləşdirilir.

Yaxşı, klasterə Pod Security Policy yerləşdirəcəyik, deyək ki, bizim administrasiyaya yalnız giriş imkanı olan bir namespace-də bəzi xidmət podlarımız var. Deyək ki, qalan bütün podların məhdud hüquqları var. Çünki inkişaf etdiricilərin, ehtimal ki, sizin klasterdə imtiyazlı podlar işə salmağa ehtiyacı olmayacaq.

Və bizdə hər şey yaxşı görünür. Və klasterimiz Kubernetes iki dəqiqə içində sındırıla bilməz.

Bir problem var. Sizin Kubernetes klasteriniz varsa, ehtimal ki, klasterdə monitorinq sistemi quraşdırılıb. Hatta deyə bilərəm ki, əgər sizin klasterinizdə monitorinq varsa, o, Prometheus adlanır.

İndi danışacağım şey həm Prometheus operatoru, həm də təkcə Prometheus üçün keçərlidir. Məsələ budur ki, əgər klasterdə admin almaq üçün bu qədər tez bir yol tapa bilmirəmsə, bu, daha çox axtarmalı olduğum deməkdir. Və axtarışı sizin monitorinq sisteminiz vasitəsilə edə bilərəm.

Ehtimal ki, hər kəs eyni Habr məqalələrini oxuyub və monitorinq 'monitoring' namespace-dədir. Helm chart-ları demək olar ki, hamısının adı eynidir. Mən düşünürəm ki, əgər 'helm install stable/prometheus' etsəniz, sizdə eyni adlar əldə ediləcək. Hətta ehtimal ki, mən sizin klasterdə DNS adını tapmaqda çətinlik çəkməyəcəyəm. Çünki standartdır.

Kubernetes klasterindəki boşluqları aradan qaldırırıq. DevOpsConf-dan təqdimat və transkript.

İndi bizim bir dev ns var, orada müəyyən bir pod işə sala bilərik. Və daha sonra bu poddan belə bir şey etmək çox asandır:

$ curl http://prometheus-kube-state-metrics.monitoring 

prometheus-kube-state-metrics — Kubernetes API-dan metrikləri toplayan Prometheus eksporterlərindən biridir. Klasterinizdə nə başlandığı, necə olduğu və onunla bağlı problemləriniz haqqında çox sayda məlumat var.

Sadə bir nümunə:

kube_pod_container_info{namespace="kube-system", pod="kube-apiserver-k8s-1", container="kube-apiserver", image=

"gcr.io/google-containers/kube-apiserver:v1.14.5"

, image_id="docker-pullable://gcr.io/google-containers/kube-apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a9638ee634989", container_id="docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2853397d7daf08e72c22d3cf8b"} 1

İcazəsiz poddan sadə bir curl sorğusu edərək belə bir məlumat ala bilərsiniz. Kubernetes-in hansı versiyasında olduğunuzu bilmirsinizsə, o, asanlıqla sizə deyəcək.

Ən maraqlısı isə odur ki, kube-state-metrics-ə müraciət etdiyinizdən əlavə, birbaşa Prometheusa da müraciət edə bilərsiniz. Oradan metrikləri toplaya bilərsiniz. Hətta oradan metrikləri qurmağı belə bacarırsınız. Hətta nəzəri cəhətdən Prometheus-a klasterdən elə bir sorğu göndərə bilərsiniz ki, bu onu sadəcə söndürsün. Və monitorinqiniz klasterdən tamamilə işləməkdən dayanacaq.

Burada artıq sual ortaya çıxır: hər hansı bir xarici monitorinq sizin monitorinqinizi izləyirmi? Mən, heç bir nəticə olmadan, Kubernetes klasterində fəaliyyət göstərmək imkanı əldə etdim. Mən orada fəaliyyət göstərdiyimi heç bilməyəcəksiniz, çünki artıq monitorinq yoxdur.

PSP ilə olduğu kimi, bütün bu dəbdəbəli texnologiyaların — Kubernetes, Prometheus — sadəcə işləmədiyinə və tam boşluqlarla dolu olduğuna dair bir hiss var. Əslində, belə deyil.

Belə bir şey var — Şəbəkə Siyasəti.

Əgər normal bir adminisinizsə, şəbəkə siyasətinin klasterdəki əlavə yaml-dan biri olduğunu bilirsiniz. Və bəzən şəbəkə siyasəti tamamilə lazım olmaya bilər. Hətta şəbəkə siyasətinin nə olduğunu da oxumaş olsanız, yəni Kubernetes-in yaml-dan ibarət firewall olduğunu, namespace-lər arasında, pod-lar arasında giriş hüquqlarını məhdudlaşdırdığını bilirsinizsə, siz əmin oldunuz ki, Kubernetes-də yaml formatında firewall — sadəcə başqa abstraksiyalar... Yox, yox. Bu, mütləq lazım deyil.

Hətta təhlükəsizlik mütəxəssislərinizə sizin Kubernetes vasitəsilə asanlıqla və sadəcə firewall yaratmağı söyləməsələr də, əgər onlar bunu hələ bilmir və sizdən "Bəs verin, verin..." demirlərsə: hər halda Network Policy sizə lazımdır ki, bəzi xidmət yerlərinə girişinizi bağlayasınız ki, bunları klasterinizdən heç bir icazə olmadan əldə etmək mümkün olmasın.

Mənim verdiyim nümunələrdə olduğu kimi, siz kube state metrics-i Kubernetes klasterinin istənilən namespace-indən icazə almadan əldə edə bilərsiniz. Network policies bütün digər namespace-lərdən monitorinq namespace-ə ərizə göndərən girişləri bağlayıb. Ümumilikdə, giriş yoxdur, problem də yoxdur. Var olan bütün chart-larda, həm standart Prometheus-da, həm də operatorun Prometheus-da sadəcə values-də network policies-i aktivləşdirmək imkanı var. Sadəcə aktivləşdirmək lazımdır ki, onlar işləsin.

Burada əslində bir problem var. Normal bir administrator olaraq, siz çox güman ki, network policies-in lazım olmadığını düşünmüsünüz. Həmçinin Habr kimi resurslarda müxtəlif məqalələr oxuyaraq flannel-in xüsusən host-gateway rejimi ilə ən yaxşı seçiminiz olduğunu düşündünüz.

What to do?

Kubernetes klasterinizdə olan şəbəkə həllini yenidən yerləşdirmək üçün çalışa bilərsiniz, daha funksional bir şeylə əvəz etməyə çalışa bilərsiniz. Məsələn, Calico ilə. Amma əvvəlcədən demək istəyirəm ki, işləyən Kubernetes klasterində şəbəkə həllini dəyişmək tapşırığı olduqca çətindir. Mən bu tapşırığı iki dəfə həll etmişəm (hər iki dəfə nəzəri olaraq, lakin biz Slurm-də bunu necə etmək lazım olduğunu göstərmişik). Təlimçilərimizə Kubernetes klasterində şəbəkə həllini necə dəyişmək lazım olduğunu göstərmişik. İstəyirsinizsə, istehsal klasterində dayanmadan bunu etməyə çalışa bilərsiniz. Ancaq sizdə bunun heç alınmaması ehtimalı yüksəkdir.

Və problem əslində çox sadə bir şəkildə həll edilir. Klasterdə sertifikatlar var və siz bilirsiniz ki, sertifikatlarınız bir ildən sonra keçərsiz olacaq. Ümumiyyətlə, klasterdə sertifikatlar üçün normallaşmış həll odur ki, yeni bir klaster quraq, köhnə klasteri keçsin və hər şeyi yenidən yerləşdirmək. Düzdür, köhnə klaster keçəndə, bir gün hər şey tutulacaq, amma yenə də yeni klasteriniz əldə olunmuş olacaq.

Yeni klasterinizi quran zaman Calico-nu flannel-in yerinə qoymağı unutmayın.

Nə etməliyik, əgər sertifikatlarınız yüz illiyə tərtib edilibsə və klasteri yenidən yerləşdirmək istəmiriksə? Belə bir şey var: Kube-RBAC-Proxy. Bu, çox mükəmməl bir inkişafdır, o, özünü Kubernetes klasterindəki hər hansı bir pod-a sidecar konteyneri kimi yerləşdirməyə imkan verir. Və bu pod-a faktiki olaraq Kubernetes-in RBAC-i vasitəsilə avtorizasiya əlavə edir.

Bir problem var. Əvvəllər Prometheus operatorunda bu Kube-RBAC-Proxy həlli yer alırdı. Ancaq sonradan onu çıxardılar. İndi müasir versiyalar sizdə network policy-nin olduğunu və onların köməyi ilə bağlandığını əsas götürür. Buna görə bir az chartı yenidən yazmaq lazım gələcək. Həqiqətən, əgər siz daxil olsanız bu repozitoriya PR etməlisiniz, orada sidecar-lar kimi istifadə etməyə dair nümunələr var, və chartları minimum dərəcədə yenidən yazmaq lazım olacaq.

Başqa bir kiçik problem də var. Sadəcə Prometheus öz metriklərini kiməsə göndərmir. Bizim Kubernetes klasterinin bütün komponentləri də öz metriklərini təqdim etməyi bacarır.

Amma dediyim kimi, əgər klasterə daxil ola bilmirsinizsə və məlumat toplaya bilmirsinizsə, ən azından ziyan vermək olar.

Beləliklə, mən Kubernetes klasterinin sağlamlığını necə pozmağın iki yolunu tez göstərəcəyəm.

Siz güldüreceksiniz, bunu izah edəndə, bu, reallıqdan iki vəziyyətdir.

Birinci yol. Resursların tükənməsi.

Başqa bir xüsusi podu işə salırıq. Onun aşağıdakı kimi bir bölməsi olacaq.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Bildiyiniz kimi, requests — bu, xüsusi podlar üçün hostda rezerv edilmiş CPU və yaddaş miqdarını bildirir. Əgər bizim Kubernetes klasterimizdə dörd nüvəli bir host varsa və ora dörd CPU tələbi olan bir pod daxil olursa, deməli, bu hosta tələbi olan heç bir pod daha daxil ola bilməz.

Əgər belə bir pod işə salsam, sonra belə bir əmr verəcəyəm:

$ kubectl scale special-pod --replicas=...

O zaman daha heç kəs Kubernetes klasterinə yerləşdirilə bilməyəcək. Çünki bütün nodlarda tələblər başa çatacaq. Bu şəkildə mən sizin Kubernetes klasterinizi dayandıracağam. Əgər bunu axşam etdim, yerləşdirmələri olduqca uzun müddət dayandıra bilərəm.

Kubernetes sənədinə bir daha baxsaq, Limit Range adlanan bir anlayışın olduğunu görəcəyik. Bu, klaster obyektləri üçün resursları müəyyən edir. Siz YAML formatında Limit Range obyekti yaza bilər, onu müəyyən ad məkanlarına tətbiq edə bilərsiniz — sonra isə həmin ad məkanında siz podlar üçün standart, maksimum və minimum resursların olduğunu deyə bilərsiniz.

Bu cür bir anlayışdan istifadə edərək, biz müəyyən məhsul ad məkanlarında komandaları istifadəçini podlarının içində istənilən şeylər təqdim etməyə məhdudlaşdıra bilərik. Lakin, təəssüf ki, siz istifadəçiyə bir CPU-dan daha yüksək tələb etməyi qadağan etsəniz belə, bu, əla faktordur — komanda scale ilə və ya dashboard vasitəsilə ölçməni həyata keçirə bilərlər.

İkincisi, 11 111 111 111 111 podu işə salırıq. Bu, on bir milyarddır. Bu, yadımda saxladığım bir rəqəm deyil, öz gözümlə gördüyümə görədir.

Gerçek bir hekayə. Gecənin qaranlığında ofisdən çıxmağa hazırlaşırdım. Baxıram ki, küncdə bir neçə inkişaf etdirici oturub, nəsə tələsik laptopları ilə edir. Mən yaxınlaşıb onlara soruşuram: "Nə baş verib?"

Bir az əvvəldə, saat doqquzda, inkişaf etdiricilərdən biri evə getməyə hazırlaşırdı. Və düşündü: "İndi öz tətbiqimi birə qədər ölçəcəm." Bir düyməyə basdı, internet bir az zəiflədi. Yenidən düyməyə basdı, bir daha basdı, Enter düyməsinə tıkladı. Hər şeyi basmağa çalışdı. Burda internet canlandı — və hər şey bu rəqəmə qədər ölçməyə başladı.

Amma bu hekayə Kubernetesdə baş vermirdi, o anda bu Nomad idi. Bu, bir saatımızı Nomadı ölçmələrdən dayandırmaq cəhdlərimizlə başa çatdı; Nomad cavab verdi ki, ölçməni dayandırmayacaq və başqa heç nə ilə məşğul olmayacaq. "Yoruldum, gedirəm". Və bağlandı.

Təbii ki, mən Kubernetesdə eyni şeyi etməyə çalışdım. On bir milyard podu Kubernetes sevindirmədi, "Olmaz. İrimiqyaslı daxili limitləri aşır" dedi. Amma 1 000 000 000 podu qura bildim.

Bir milyarda kub daxil olmaq mümkün olmadı. O, həqiqətən genişlənməyə başladı. Proses irəlilədikcə, yeni podlar yaratmaq üçün daha çox vaxt sərf etdi. Ancaq procesos hələ də davam edirdi. Yeganə problem odur ki, mənim ad boşluğumda məhdudiyyətsiz podlar işə sala bilsəm də, hətta tələblər və limitlər olmadan, bəzi vəzifələrlə o qədər pod işə sala bilərəm ki, bu vəzifələrlə nodlar yaddaş və CPU üzrə çökə bilər. O qədər pod işə salanda, onlardan əldə edilən məlumatlar saxlanmağa, yəni etcd-yə çatmalıdır. Və oraya çox məlumat daxil olduqda, saxlama sisteminin nəticə verməsi çox yavaşlaşır - və Kubernetes-də problemler başlayır.

Və bir problem daha var... Bildiyiniz kimi, Kubernetes-in idarəetmə komponentləri tək bir mərkəzi cihaza deyil, bir neçə komponentə bölünür. Orada xüsusilə kontroller meneceri, scheduler və s. var. Bu bütün şəxslər eyni anda lazımsız mənasız işləri yerinə yetirməyə başlayacaq, bu da zamanla daha çox vaxt istəyəcək. Kontroller meneceri yeni podlar yaradacaq. Scheduler onlara yeni bir nod tapmağa çalışacaq. Klasterinizdəki yeni nodlar, çox güman ki, tezliklə tükənəcək. Kubernetes klasteri daha yavaş işləməyə başlayacaq.

Amma mən daha irəliləməyə qərar verdim. Bildiyiniz kimi, Kubernetes-də xidmət adlandırılan bir şey var. Və standart olaraq klasterlərinizdə, çox güman ki, xidmət IP tabloları vasitəsilə işləyir.

Məsələn, bir milyard podu işə salanda və sonra skriptlə Kubernetes-i yeni xidmətlər yaratmağa məcbur edəndə:

for i in {1..1111111}; do
    kubectl expose deployment test --port 80  
        --overrides="{"apiVersion": "v1", 
           "metadata": {"name": "nginx$i"}}"; 
done 

Klasterdəki bütün nodlarda eyni vaxtda yeni və yeni iptables qaydaları yaradılacaq. Hər xidmət üçün bir milyard iptables qaydası yaradılacaq.

Bütün bunları bir neçə minə, on təşviqə qədər yoxladım. Problemin odur ki, artıq bu həddə ssh noduna keçmək olduqca çətinləşir. Çünki paketlər bu qədər zəncirlərdən keçdikcə, özlərini yaxşı hiss etmir.

Və bu da Kubernetes vasitəsilə həll olunur. Resource quota adlı bir obyekt var. O, klasterdəki namespace üçün əlçatan resursların və obyektlərin sayını müəyyənləşdirir. Kubernetes klasterində hər bir namespace-də bir yaml obyekti yarada bilərik. Bu obyekt vasitəsilə biz bu namespace üçün müəyyən bir sayda resurs tələbini, limitlərini ayırdığımızı bildirə bilərik və daha sonra bu namespace-də 10 xidmət və 10 pod yarada biləcəyimizi deyə bilərik. Və inkişaf etdirici gecələri istədiyi kimi işləyə bilər. Kubernetes ona deyəcək: "Podlarınızı bu sayda artırmaq olmaz, çünki resurs kvotasını aşır." Hər şey, problem həll olundu. Dokumentasiya burada.

Bu əlaqədar bir problem yaranır. Kubernetesdə namespace yaratmaq nə qədər çətin olduğunu hiss edirsiniz. Onu yaratmaq üçün bir çox şeyi nəzərə almalıyıq.

Resource quota + Limit Range + RBAC
• Namespace yaradırıq
• İçəridə limitrange yaradırıq
• İçəridə resourcequota yaradırıq
• CI üçün serviceaccount yaradırıq
• CI və istifadəçilər üçün rolebinding yaradırıq
• İstədiyimiz xidmət podlarını opsional olaraq işə salırıq

Bu səbəbdən, bu fürsətdən istifadə edərək, öz tərtibatlarımı bölüşmək istəyirəm. Kubernetes klasterində operatorlar yazmaq üçün bir yol var ki, buna operator SDK deyilir. Siz Ansible ilə operatorlar yaza bilərsiniz.

Başlanğıcda bu Ansible-da yazılmışdı, sonra operator SDK-nın olduğunu gördüm və Ansible rolunu operatora yenidən yazdım. Bu operator Kubernetes klasterində komanda adlı bir obyekti yaratmağa imkan verir. Komanda daxilində, bu komandanın yaml mühitini təsvir etməyə imkan verir. Komanda mühitinin içində isə biz bu komandaya lazım olan resursların ayrılmasını təsvir edə bilirik.

Kiçik bu mürəkkəb prosesi asanlaşdıran şey.

Və yekun olaraq. Bununla nə etməliyik?
Birincisi. Pod Security Policy - bu yaxşıdır. Və hərçənd ki, bu günə qədər Kubernetesin heç bir quraşdırıcısı bunu istifadə etmir, klasterlərinizdə bunu istifadə etmək lazımdır.

Network Policy - bu bir növ əlavə lazım olmayan funksiya deyil. Bu klasterdə gerçəkdən lazım olan bir şeydir.

LimitRange/ResourceQuota - bunu istifadə etməyin vaxtıdır. Biz bunu uzun müddətdir ki, istifadə edirik və mən uzun müddət əmin idim ki, hamı bunu tətbiq edir. Məlum oldu ki, bu nadir hallardandır.

Yazılı təqdimatımda qeyd etdiyimdən əlavə, klasteri hədəf almağa imkan verən sənədləşdirilməmiş xüsusiyyətlər var. Yaxın zamanda Kubernetes üzrə geniş zəiflik analizi.

Bəzi ehtimallar kədərlidir və acınacaqlıdır. Məsələn, bəzi şərtlər altında Kubernetes klasterindəki kubelet-lər, qeyri-autorizə olunmuş istifadəçiyə warlocks direktoryasının məzmununu təqdim edə bilir.

Bunlar Bütün dediklərimi təkrar etməyə aid təlimatlar var. Orada ResourceQuota, Pod Security Policy kimi bizim real nümunələrlə faylılar var. Bütün bunları sınaqdan keçirə bilərsiniz.

Hamınıza təşəkkür edirəm.

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster