Латаем дзюры ў кластары Kubernetes. Даклад і расшыфроўка з DevOpsConf

Павел Селіванаў, архітэктар рашэнняў Southbridge і выкладчык Слёрма, выступіў з дакладам на DevOpsConf 2019. Гэты даклад - частка адной з тэм паглыбленага курсу па Kubernetes "Слёрм Мега".

Слёрм Базавы: увядзенне ў Kubernetes праходзіць у Маскве 18-20 лістапада.
Слёрм Мега: зазіраем пад капот Kubernetes - Масква, 22-24 лістапада.
Слёрм Анлайн: абодва курса па Kubernetes даступны заўсёды.

Пад катом - расшыфроўка даклада.

Добры дзень, калегі і ім спачуваюць. Сёння я буду расказваць пра бяспеку.

Я бачу, што ў залі сёння шмат бяспечнікаў. Я загадзя перад вамі прашу прабачэння, калі тэрміны са свету бяспекі я буду выкарыстоўваць не зусім так, як у вас прынята.

Так атрымалася, што недзе паўгода таму мне ў рукі патрапіў адзін публічны кластар Kubernetes. Публічны - азначае, што там ёсць n-ная колькасць namespaces, у гэтых неймспейсах ёсць users, ізаляваныя ў сваім неймспейсе. Усе гэтыя карыстачы прыналежаць розным кампаніям. Ну, і меркавалася, што гэты кластар трэба выкарыстоўваць як CDN. Гэта значыць, вам даюць кластар, даюць туды карыстальніка, вы туды прыходзьце ў свой namespace, дэплоіце свае франты.

Маёй папярэдняй кампаніі паспрабавалі такую ​​паслугу прадаць. І мяне папрасілі патыкаць кластар на прадмет - падыходзіць ці не падыходзіць такое рашэнне.

Прыйшоў я ў гэты кластар. Мне далечы абмежаваныя правы, абмежаваны namespace. Там хлопцы разумелі, што такое бяспека. Яны чыталі, што такое Role-based access control (RBAC) у Кубернэтэса — і яны яго закруцілі так, што я не мог запускаць поды асобна ад дэплайментаў. Не памятаю задачу, якую я спрабаваў рашыць, запускаючы пад без дэплойменту, але мне вельмі хацелася запусціць проста пад. Я вырашыў на поспех паглядзець, якія правы ў мяне ў кластары ёсць, што я магу, што не магу, што яны там панакруцілі. Заадно раскажу, што ў іх у RBAC наладжана няправільна.

Так атрымалася, што праз дзве хвіліны я атрымаў адміна да іх кластара, паглядзеў ва ўсе суседнія namespaces, убачыў там запушчаныя прадакшн франты кампаній, якія ўжо купілі паслугу і задэплаіраліся. Я ледзьве спыніў сябе, каб не прыйсці да каго-небудзь у фронт і на галоўную старонку не змясціць якое-небудзь мацюкальнае слова.

Я раскажу на прыкладах, як я гэта зрабіў і як ад гэтага трэба абараняцца.

Але для пачатку прадстаўлюся. Мяне клічуць Павел Селіванаў. Я архітэктар кампаніі Southbridge. Я разбіраюся ў Kubernetes, DevOps і ўсякіх модных штуках. Мы з інжынерамі Southbridge усё гэта які будуецца, а я кансультую.

Апроч асноўнай дзейнасці мы яшчэ нядаўна запусцілі праекты, якія называюцца Слёрмы. Мы наша ўменне працаваць з Kubernetes спрабуем крыху прыўнесці ў масы, навучыць іншых людзей таксама працаваць з К8s.

Пра што я буду сёння расказваць. Тэма дакладу відавочная – пра бяспеку кластара Kubernetes. Але адразу хачу сказаць, што гэтая тэма вельмі вялікая — і таму я адразу хачу абгаварыць, пра што я дакладна расказваць не буду. Я не буду расказваць пра заезджаныя тэрміны, якія ў інтэрнэце ўжо сто разоў перамусоленыя. Усякія RBAC і сертыфікаты.

Я буду расказваць пра тое, што ў мяне і ў маіх калег баліць ад бяспекі ў кластары Kubernetes. Мы гэтыя праблемы бачым і ў правайдэраў, якія падаюць кластара Kubernetes, і ў кліентаў, якія да нас прыходзяць. І нават у кліентаў, якія прыходзяць да нас ад іншых кансалтынгавых адмінскіх кампаній. Гэта значыць маштаб трагедыі вельмі вялікі насамрэч.

Літаральна тры пункты, пра якія я сёння раскажу:

  1. Правы карыстальнікаў vs правы pod'аў. Правы карыстальнікаў і правы подаў - гэта не адно і тое ж.
  2. Збор інфармацыі аб кластары. Пакажу, што з кластара можна збіраць усю інфармацыю, якая спатрэбіцца, не маючы асаблівых правоў у гэтым кластары.
  3. DoS-напад на кластар. Калі мы не зможам збіраць інфармацыю, мы зможам кластар пакласці ў любым выпадку. Я раскажу пра DoS-напады на кіравальныя элементы кластара.

Яшчэ адна агульная рэч, пра якую я згадаю - на чым я ўсё гэта тэставаў, на чым я сапраўды магу сказаць, што ўсё гэта працуе.

За аснову мы бярэм усталёўку кластара Kubernetes з дапамогай Kubespray. Калі нехта не ведае, гэта фактычна набор роляў для Ansible. Мы ў працы яго ўвесь час выкарыстоўваем. Добры тым, што можна накаціць куды заўгодна - і на жалязякі можна накаціць, і куды-небудзь у воблака. Адзін спосаб усталёўкі падыходзіць у прынцыпе для ўсяго.

У гэтым кластары ў мяне будзе Kubernetes v1.14.5. Увесь кластар Куба, які мы будзем разглядаць, падзелены на неймспейсы, кожны неймспейс належыць асобнай камандзе, у кожны неймспейс ёсць доступ у членаў гэтай каманды. У розныя неймспейсы яны хадзіць не могуць, толькі ў свой. Але ёсць нейкая адмінская ўлікоўка, у якой ёсць правы на ўвесь кластар.

Латаем дзюры ў кластары Kubernetes. Даклад і расшыфроўка з DevOpsConf

Я абяцаў, што першае ў нас будзе - атрыманне адмінскіх правоў на кластар. Нам патрэбен спецыяльна падрыхтаваны pod, які будзе ламаць кластар Kubernetes. Усё, што нам трэба зрабіць, гэта прымяніць яго ў кластар Кубернетэс.

kubectl apply -f pod.yaml

Гэты pod у нас прыедзе на адзін з майстроў кластара Kubernetes. І кластар нам пасля гэтага радасна верне файлік, які завецца admin.conf. У Кубе ў гэтым файле захоўваюцца ўсе сертыфікаты адміна, а заадно наладжаны API кластара. Вось так проста можна атрымаць адмінскі доступ, думаю, да 98% кластараў Kubernetes.

Паўтаруся, гэты pod зрабіў адзін распрацоўшчык у вашым кластары, у якога есць доступ дэплоіць свае прапановы ў адзін маленькі namespace, ён увесь заціснуты RBAC. Мае рацыю ў яго ніякіх не было. Але тым не менш сертыфікат вярнуўся.

А зараз аб спецыяльна падрыхтаваным подзе. Запускаем на любой выяве. Для прыкладу возьмем debian: jessie.

У нас ёсць такая штука:

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

Што такое toleration? Майстры ў кластары Кубернэтэса звычайна пазначаныя штукай, якая называецца taint («зараза» па-ангельску). І сутнасць гэтай «заразы» - яна кажа, што на майстаравыя ноды нельга прызначаць поды. Але ніхто не мяшае ў любым подзе паказаць, што ён талерантны да «заразы». Секцыя Toleration як раз і кажа, што калі на нейкай нодзе стаіць NoSchedule, то наш пад да такой заразы талерантны – і ніякіх праблем.

Далей, мы гаворым, што наш пад не проста талерантны, але і хоча спецыяльна трапляць на майстра. Таму што на майстрах знаходзіцца самае смачнае, што нам трэба - усе сертыфікаты. Таму мы гаворым nodeSelector — і ў нас ёсць стандартны лэйбл на майстрах, які дазваляе выбраць з усіх нод кластара менавіта тыя ноды, якія з'яўляюцца майстрамі.

Вось з такімі двума секцыямі пад сапраўды прыедзе на майстар. І яму дазволяць там жыць.

Але проста прыехаць на майстар нам нядосыць. Гэта нам нічога не дасць. Таму далей у нас ёсць такія дзве рэчы:

hostNetwork: true 
hostPID: true 

Мы паказваем, што наш пад, які мы запускаем, будзе жыць у неймспейсе ядра, у network неймспейсе і ў PID неймспейсе. Як толькі пад запусціцца на майстру, ён зможа бачыць усе сапраўдныя, жывыя інтэрфейсы гэтай ноды, праслухоўваць увесь трафік і бачыць PID усіх працэсаў.

Далей справа за малым. Бераце etcd і чытаеце, што хочаце.

Самае цікавае - гэта магчымасць Kubernetes, якая там па змаўчанні прысутнічае.

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

І сутнасць яе ў тым, што мы можам у подзе, які мы запускаем, нават без правоў на гэты кластар, сказаць, што мы жадаем стварыць volume тыпу hostPath. Значыць узяць шлях з хаста, на якім мы запусцімся - і ўзяць яго як volume. І далей яго абзываем name: host. Увесь гэты hostPath мы мантуем ўнутр пода. У дадзеным прыкладзе ў дырэкторыю /host.

Яшчэ раз паўтаруся. Мы сказалі поду прыязджаць на майстар, атрымліваць туды hostNetwork і hostPID - і ўвесь root майстра замантаваць унутр гэтага пода.

Вы разумееце, што ў дэбіяне ў нас запушчаны bash, і гэты bash у нас працуе пад рутам. Гэта значыць, мы толькі што атрымалі рута на майстар, пры гэтым не валодаючы нейкімі правамі ў кластары Kubernetes.

Далей уся задача - зайсці ў пад у дырэкторыю /host /etc/kubernetes/pki, калі не памыляюся, забраць там усе майстравыя сертыфікаты кластара і, адпаведна, стаць адмінам кластара.

Калі так паглядзець, гэта адны з самых небяспечных правоў у падах - нягледзячы на ​​тое, якія правы ёсць у карыстальніка:
Латаем дзюры ў кластары Kubernetes. Даклад і расшыфроўка з DevOpsConf

Калі ў мяне ёсць правы запусціць пад у нейкім неймспейсе кластара, то ў гэтага пода гэтыя правы ёсць па змаўчанні. Я магу запускаць прывілеяваныя поды, а гэта ўвогуле ўсе правы, практычна рут на ноду.

Маё каханае – Root user. А ў Кубернэтэса ёсць такая опцыя Run As Non-Root. Гэта такая тыпу абарона ад хакера. Ведаеце, што такое "малдаўскі вірус"? Калі вы раптам хакер і дашлі ў мой кластар Кубернетэс, то мы, бедныя адміністратары, просім: «Пакажыце, калі ласка, у сваіх подах, якімі вы будзеце хакаць мой кластар, run as non-root. А то так атрымаецца, што вы запусціце працэс у сваім подзе пад рутам, і вам вельмі проста будзе мяне хакнуць. Абараніцеся, калі ласка, ад сябе самі».

Host path volume - на мой погляд, самы хуткі спосаб атрымаць жаданы вынік ад кластара Кубернэтэса.

Але што з усім гэтым рабіць?

Думкі, якая павінны прыходзіць любому нармальнаму адміністратару, які сутыкаецца з Кубернэтэсам: «Ага, я ж казаў, Кубернэтэс не працуе. У ім дзіркі. І ўвесь Куб бздура». Насамрэч, ёсць такая штука, як дакументацыя, а калі туды паглядзець, то там ёсць раздзел Pod Security Policy.

Гэта такі yaml-аб'ект - мы яго можам ствараць у кластары Кубернетэс - які кантралюе аспекты бяспекі менавіта ў апісанні подаў. Гэта значыць фактычна ён кантралюе тыя правы на выкарыстанне ўсякіх hostNetwork, hostPID, вызначаных тыпаў volume, якія ёсць у падах пры запуску. З дапамогай Pod Security Policy усё гэта можна апісаць.

Самае цікавае ў Pod Security Policy, што ў кластары Кубернэтэса ва ўсіх усталёўшчыкаў PSP не проста ніяк не апісаны, яны проста па змаўчанні выключаны. Pod Security Policy уключаецца з дапамогай admission plugin.

Окей, у кластар задэплоім Pod Security Policy, скажам, што ў нас ёсць службовыя нейкія поды ў неймспейсе, да якога маюць доступ толькі адміны. Скажам, ва ўсіх астатніх поды маюць абмежаваныя правы. Таму што хутчэй за ўсё распрацоўнікам не трэба запускаць у вашым кластары прывілеяваныя поды.

І ў нас быццам усё добра. І наш кластар Кубернетэс нельга ўзламаць за дзве хвіліны.

Ёсць праблема. Хутчэй за ўсё, калі ў вас ёсць кластар Кубернетэс, то ў вашым кластары ўсталяваны маніторынг. Я нават бяруся прадказаць, што калі ў вашым кластары ёсць маніторынг, то ён называецца Prometheus.

Тое, што я зараз раскажу, будзе валідна і для Prometheus-аператара, і для Prometheus, пастаўленага ў чыстым выглядзе. Пытанне ў тым, што калі я ў кластар не магу так хутка адміна атрымаць, то гэта азначае, што мне трэба больш шукаць. А шукаць я магу з дапамогай вашага маніторынгу.

Верагодна, усё чыталі адны і тыя ж артыкулы на Хабре, і маніторынг знаходзіцца ў неймспейсе monitoring. Helm chart ва ўсіх завецца прыкладна аднолькава. Я мяркую, што калі вы зробіце helm install stable/prometheus, то ў вас атрымлівацца прыкладна аднолькавыя назовы. І нават хутчэй за ўсё DNS-імя ў вашым кластары мне адгадваць не давядзецца. Бо яно стандартнае.

Латаем дзюры ў кластары Kubernetes. Даклад і расшыфроўка з DevOpsConf

Далей у нас ёсць нейкі dev ns, у ім можна запусціць нейкі пад. І далей з гэтага пода вельмі лёгка зрабіць вось так:

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

prometheus-kube-state-metrics - гэта адзін з экспарцёраў праметэуса, які збірае метрыкі з API самога Kubernetes. Там вельмі шмат дадзеных, што запушчана ў вас у кластары, якое яно, якія ў вас з ім ёсць праблемы.

Як просты прыклад:

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:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

Зрабіўшы просты запыт curl з непрывілеяванага пода, можна атрымаць такую ​​вось інфармацыю. Калі вы не ведаеце, у якой версіі Кубернетэс вы запушчаны, то ён лёгка вам раскажа.

А самае цікавае, што акрамя таго, што вы звяртаецеся да kube-state-metrics, вы можаце з тым жа поспехам звярнуцца і ў сам Prometheus напрамую. Вы можаце сабраць адтуль метрыкі. Вы нават можаце пабудаваць адтуль метрыкі. Нават тэарэтычна вы можаце пабудаваць такі запыт з кластара ў Prometheus, які яго проста выключыць. І ў вас маніторынг увогуле перастане ад кластара працаваць.

І тут ужо ўзнікае пытанне, ці маніторыць які-небудзь знешні маніторынг ваш маніторынг. Толькі што я атрымаў магчымасць дзейнічаць у кластары Кубернетэс наогул без наступстваў для сябе. Вы нават не даведаецеся, што я там дзейнічаю, бо маніторынгу ўжо няма.

Сапраўды гэтак жа, як з PSP, узнікае адчуванне, быццам бы праблема ў тым, што ўсе гэтыя модныя тэхналогіі – Kubernetes, Prometheus – яны проста не працуюць і поўныя дзірак. Насамрэч няма.

Ёсць такая штука - Network Policy.

Калі вы нармальны адмін, то хутчэй за ўсё пра Network Policy вы ведаеце, што гэта чарговы yaml, якіх у кластары і так дафіга. І Network Policies нейкія сапраўды не патрэбныя. А калі нават вы і прачыталі, што такое Network Policy, што гэта yaml-фаервол Кубернэтэса, ён дазваляе абмяжоўваць правы доступу паміж неймспейсамі, паміж подамі, то вы ўжо сапраўды вырашылі, што фаервол у фармаце yaml у Кубернэтэсе на чарговых абстракцыях… Не-не . Гэта сапраўды не трэба.

Нават калі ў вас спецыялістам па бяспецы не распавялі, што з дапамогай вашага Кубернэтэса можна будаваць вельмі лёгка і проста фаервол, прычым вельмі грануляваны. Калі яны ў вас яшчэ гэтага не ведаюць і вас не торгаюць: «Ну дайце, дайце…» То ў любым выпадку Network Policy вам трэба, каб зачыняць доступ да некаторых службовых месцаў, якія можна з вашага кластара паторгаць, не маючы ніякай аўтарызацыі.

Як у прыкладзе, які я прыводзіў, можна паторгваць kube state metrics з любога неймспейса ў кластары Кубернетэс, не маючы на ​​гэта ніякіх правоў. Network policies закрылі доступ з усіх астатніх неймспейсаў у неймспейс маніторынгу і як бы ўсё: няма доступу, няма праблем. Ва ўсіх чартах, якія ёсць, і стандартнага праметэуса, і таго праметэуса, які ў аператары, там проста ў values ​​хелма ёсць опцыя проста ўключыць network policies для іх. Трэба проста ўключыць і яны будуць працаваць.

Ёсць тут праўда адна праблема. Будучы нармальным барадатым адмінам, вы хутчэй за ўсё вырашылі, што network policies не патрэбны. І пачытаўшы ўсякія артыкулы на рэсурсах тыпу Хабра, вы вырашылі, што flannel асабліва з рэжымам host-gateway - гэта самае лепшае, што вы можаце абраць.

Што рабіць?

Вы можаце паспрабаваць перадэплоіць сеткавае рашэнне, якое стаіць у вас у кластары Кубернетэс, паспрабаваць замяніць на нешта больш функцыянальнае. На тое ж самае Calico, напрыклад. Але адразу ж хачу сказаць, задача памяняць сеткавае рашэнне ў працоўным кластары Кубернетэс – даволі нетрывіяльная. Я яе два разы вырашаў (абодва разы, праўда, тэарэтычна), але мы нават на Слёрмах паказвалі, як гэта зрабіць. Для нашых навучэнцаў мы паказвалі, як памяняць сеткавае рашэнне ў кластары Кубернетэс. У прынцыпе можаце паспрабаваць зрабіць так, каб на прадакшн-кластары даунтайма не было. Але, верагодна, у вас нічога не атрымаецца.

І праблема насамрэч вырашаецца вельмі проста. У кластары ёсць сертыфікаты, і вы ведаеце, што сертыфікаты ў вас праз год пратухнуць. Ну, і звычайна нармальнае рашэнне з сертыфікатамі ў кластары - а чаго мы будзем парыцца, мы побач новы кластар падымем, у старым няхай пратухне, і ўсё перацяплім. Праўда, калі яно пратухне, у нас дзень усё паляжыць, але вось затое новы кластар.

Калі будзеце новы кластар паднімаць, заадно Calico устаўце замест flannel.

Што рабіць калі ў вас сертыфікаты выпісаны на сто гадоў і кластар вы перадаплаўваць не збіраецеся? Ёсць такая штука Kube-RBAC-Proxy. Гэта вельмі класная распрацоўка, яна дазваляе ўбудаваць сябе, як sidecar container да любога поду ў кластары Кубернетэс. І яна фактычна дадае да гэтага поду аўтарызацыю праз RBAC самога Kubernetes.

Адна праблема ёсць. Раней у праметэус аператара гэтае рашэнне Kube-RBAC-Proxy было ўбудавана. Але яго потым не стала. Цяпер сучасныя версіі абапіраюцца на тое, што ў вас ёсць network policу і зачыняеце з дапамогай іх. І таму давядзецца крыху перапісаць чартам. На самай справе калі вы зойдзеце ў гэты рэпазітар, там ёсць прыклады, як гэта выкарыстоўваць як sidecars, і чарты давядзецца перапісаць мінімальна.

Ёсць яшчэ адна невялікая праблема. Не толькі Prometheus аддае свае метрыкі каму ні патрапячы. У нас усе кампаненты кластар Кубернетэс таксама свае метрыкі ўмеюць аддаваць.

Але як я ўжо казаў, калі не можаш атрымаць доступ да кластара і сабраць інфармацыю, то можна хаця б нашкодзіць.

Так што я хуценька пакажу два спосабу, як можна кластару Kubernetes сапсаваць здароўе.

Вы будзеце смяяцца, калі я гэта раскажу, гэта два выпадкі з рэальнага жыцця.

Спосаб першы. Вычарпанне рэсурсаў.

Запускаем яшчэ адзін спецыяльны пад. У яго будзе вось такая секцыя.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Як вы ведаеце, requests - гэта тая колькасць ЦПУ і памяці, якое на хасце рэзервуецца для канкрэтных падоў з рэквестамі. Калі ў нас ёсць чатырох'ядравы хост у кластары Кубернетэс, і туды прыязджае пад з рэквестамі чатыры па ЦПУ, то значыць ніводнага больш пода з рэквестамі на гэты хост прыехаць не зможа.

Калі я запушчу такі пад, потым зраблю каманду:

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

То больш ніхто ў кластар Кубернэтэс дэплаіцца не зможа. Таму што ва ўсіх нодах скончацца рэквесты. І такім чынам я ваш кластар Kubernetes спыню. Калі я ўвечары такое зраблю, то дэплоі магу спыніць даволі надоўга.

Калі мы паглядзім у чарговы раз у дакументацыю Kubernetes, то мы ўбачым такую ​​штуку, якая завецца Limit Range. Ён устанаўлівае рэсурсы для аб'ектаў кластара. Вы можаце напісаць у yaml аб'ект Limit Range, прымяніць яго ў пэўныя нэймспейсы - і далей у гэтым нэймспейсе вы можаце сказаць, што ў вас ёсць рэсурсы для падоў дэфолтныя, максімальныя і мінімальныя.

З дапамогай такой штукі мы можам абмежаваць карыстачоў у пэўных прадуктовых неймспейсах каманд у магчымасцях паказваць на сваіх подах усякую гадасць. Але нажаль, нават калі вы скажаце карыстачу, што нельга запускаць поды з рэквестамі больш аднаго ЦПУ, ёсць такая выдатная каманда scale, ну ці праз dashboard яны могуць рабіць scale.

І адсюль вынікае спосаб нумар два. Запускаем 11 подаў. Гэта адзінаццаць мільярдаў. Гэта не таму, што я прыдумаў такую ​​колькасць, а таму што я сам гэта бачыў.

Рэальная гісторыя. Позна ўвечары я ўжо збіраўся сыходзіць з офіса. Гляджу, у кутку сядзіць групка распрацоўшчыкаў і нешта сутаргава з наўтбукамі робіць. Я падыходжу да хлопцаў і пытаю: "Што ў вас здарылася?"

Ледзь крыху раней, гадзін у дзевяць вечара адзін з распрацоўшчыкаў збіраўся дадому. І вырашыў: «Я зараз сваё з дадаткам заскейлю да адзінкі». Націснуў адзінку, а інтэрнэт крыху затупіў. Ён яшчэ раз націснуў на адзінку, ён націснуў на адзінку, клікнуў па Enter. Патыкаў на ўсё, што мог. Тут інтэрнэт ажыў - і ўсё пачало скейліцца да гэтага чысла.

Праўда, гэтая гісторыя адбывалася не на Kubernetes, у той час гэта быў Nomad. Скончылася гэта тым, што праз гадзіну нашых спробаў спыніць Nomad ад упартых спробаў скейліцца, Nomad адказаў, што скейліцца не перастане і нічым іншым займацца не будзе. "Я стаміўся, я сыходжу". І скруціўся.

Я натуральна паспрабаваў зрабіць тое ж самае на Kubernetes. Адзінаццаць мільярдаў падоў Кубернэтэс не ўзрадавалі, ён сказаў: «Не магу. Перавышае ўнутраныя капы». А вось 1 000 000 000 падоў здолеў.

У адказ на адзін мільярд Куб у сябе не сышоў. Ён сапраўды пачаў скейліць. Чым далей працэс заходзіў, тым больш часу ў яго сыходзіла на стварэнне новых подаў. Але ўсё роўна працэс ішоў. Адзіная праблема ў тым, што калі я магу ў сваім неймспейсе неабмежавана запускаць поды, то нават без рэквестаў і лімітаў я магу пазапускаць з нейкімі задачамі такую ​​колькасць подаў, што з дапамогай гэтых задач ноды пачнуць складацца па памяці, па ЦПУ. Калі я запускаю гэтулькі подаў, інфармацыя з іх павінна патрапіць у сховішча, то бок etcd. А калі туды паступае занадта шмат інфармацыі, сховішча пачынае занадта павольна аддаваць - і ў Кубернэтэса пачынаюцца затупы.

А яшчэ адна праблема ... Як ведаеце, кіраўнікі элементы Кубернетэс – гэта не адна нейкая цэнтральная штуковіна, а некалькі кампанентаў. Там у прыватнасці ёсць кантролер менеджэр, scheduler і гэтак далей. Усе гэтыя хлопцы пачнуць выконваць адначасова непатрэбную бязглуздую працу, якая з часам пачне займаць усё больш і больш часу. Кантролер менеджэр будзе новыя поды ствараць. Scheduler будзе спрабаваць знайсці ім новую наду. Новыя ноды ў вас у кластары, хутчэй за ўсё, хутка скончацца. Кластар Кубернетэс пачне працаваць усё павольней і павольней.

Але я вырашыў пайсці яшчэ далей. Як вы ведаеце, у Кубернетэс ёсць такая штука, якая называецца сэрвіс. Ну, і па змаўчанні ў вашых кластарах, хутчэй за ўсё, сэрвіс працуе з дапамогай IP tables.

Калі запусціць адзін мільярдаў падоў, да прыкладу, а потым з дапамогай скрыптыка прымусіць Кубернеціс ствараць новыя сэрвісы:

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

На ўсіх нодах кластара прыблізна адначасова будзе генеравацца ўсё новыя і новыя правілы iptables. Прычым на кожны сэрвіс будуць генеравацца па адным мільярдзе правіл iptables.

Я гэтую ўсю справу правяраў на некалькі тысячах, да дзясятка. І праблема ў тым, што ўжо на гэтым парозе ssh на ноду зрабіць даволі праблематычна. Таму што пакеты, праходзячы такую ​​колькасць ланцужкоў, пачынаюць не вельмі добрае сябе адчуваць.

І гэта таксама ўсё вырашаецца з дапамогай Кубернэтэса. Ёсць такі аб'ект Resource quota. Устанаўлівае колькасць даступных рэсурсаў і аб'ектаў для неймспейса ў кластары. Мы можам стварыць yaml аб'ект у кожным неймспейсе кластара Кубернетэс. З дапамогай гэтага аб'екта мы можам сказаць, што ў нас для гэтага неймспейса выдзелена пэўную колькасць рэквестаў, лімітаў, і далей мы можам сказаць, што ў гэтым нейспейсе магчыма стварыць 10 сэрвісаў і 10 падоў. І распрацоўшчык адзінкай можа хоць абдавіцца па вечарах. Кубернэтэс яму скажа: "Нельга заскейліць вашыя поды да такой колькасці, таму што перавышае рэсурс квоту". Усё, праблема вырашана. Дакументацыя тут.

Адзін праблемны момант у сувязі з гэтым узнікае. Вы адчуваеце, як складана становіцца стварыць у Кубернэтэсе неймспейс. Каб яго стварыць, нам неабходна кучу ўсяго ўлічыць.

Resource quota + Limit Range + RBAC
• Ствараем namespace
• Ствараем ўнутры limitrange
• Ствараем ўнутры resourcequota
• Ствараем serviceaccount для CI
• Ствараем rolebinding для CI і карыстальнікаў
• Апцыянальна запускаем патрэбныя службовыя поды

Таму, карыстаючыся выпадкам, я хацеў бы падзяліцца сваімі распрацоўкамі. Ёсць такая штука, называецца аператар SDK. Гэта спосаб у кластары Кубернетэс пісаць для яго аператары. Вы можаце пісаць аператары з дапамогай Ansible.

Спачатку ў нас было напісана на Ansible, а потым я паглядзеў, што ёсць аператар SDK і перапісаў Ansible-ролю ў аператар. Гэты аператар дазваляе стварыць у кластары Кубернетэс аб'ект, які называецца каманда. Усярэдзіне каманд ён дазваляе апісваць у yaml асяроддзе для гэтай каманды. І ўнутры атачэння каманды ён дазваляе апісваць, што мы вылучаем столькі рэсурсаў.

маленькая аблегчалка ўсяго гэтага складанага працэсу.

І ў зняволенні. Што з усім гэтым рабіць?
Першае. Pod Security Policy – ​​гэта добра. І не гледзячы на ​​тое, што ніводны з усталёўшчыкаў Кубернетэс дагэтуль іх не выкарыстоўвае, усёткі ў вашых кластарах іх выкарыстоўваць трэба.

Network Policy – ​​гэта не нейкая яшчэ адна непатрэбная фіча. Гэта тое, што ў кластары рэальна патрэбна.

LimitRange/ResourceQuota – пара б выкарыстоўваць. Мы даўно пачалі гэтым карыстацца, і я доўга быў упэўнены, што ўсё пагалоўна гэта прымяняюць. Аказалася, што гэта рэдкасць.

Апроч таго, што я згадваў падчас дакладу, ёсць незадакументаваныя фічы, якія дазваляюць атакаваць кластар. Выйшаў нядаўна вялікі аналіз уразлівасцяў Кубернетэс.

Некаторыя рэчы настолькі сумныя і крыўдныя. Як напрыклад, пры некаторых умовах кублеты ў кластары Кубернетэс могуць аддаваць змесціва warlocks дырэкторыі, прычым неаўтарызаванаму карыстачу.

Тут ляжаць інструкцыі, як прайграць усё, што я расказваў. Там ляжаць файлікі з прадакшн прыкладамі, як ResourceQuota, Pod Security Policy выглядаюць. І ўсё гэта можна памацаць.

Усім дзякуй.

Крыніца: habr.com

Дадаць каментар