Павел Селіванаў, архітэктар рашэнняў Southbridge і выкладчык Слёрма, выступіў з дакладам на DevOpsConf 2019. Гэты даклад - частка адной з тэм паглыбленага курсу па 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, і ў кліентаў, якія да нас прыходзяць. І нават у кліентаў, якія прыходзяць да нас ад іншых кансалтынгавых адмінскіх кампаній. Гэта значыць маштаб трагедыі вельмі вялікі насамрэч.
Літаральна тры пункты, пра якія я сёння раскажу:
- Правы карыстальнікаў vs правы pod'аў. Правы карыстальнікаў і правы подаў - гэта не адно і тое ж.
- Збор інфармацыі аб кластары. Пакажу, што з кластара можна збіраць усю інфармацыю, якая спатрэбіцца, не маючы асаблівых правоў у гэтым кластары.
- DoS-напад на кластар. Калі мы не зможам збіраць інфармацыю, мы зможам кластар пакласці ў любым выпадку. Я раскажу пра DoS-напады на кіравальныя элементы кластара.
Яшчэ адна агульная рэч, пра якую я згадаю - на чым я ўсё гэта тэставаў, на чым я сапраўды магу сказаць, што ўсё гэта працуе.
За аснову мы бярэм усталёўку кластара Kubernetes з дапамогай Kubespray. Калі нехта не ведае, гэта фактычна набор роляў для Ansible. Мы ў працы яго ўвесь час выкарыстоўваем. Добры тым, што можна накаціць куды заўгодна - і на жалязякі можна накаціць, і куды-небудзь у воблака. Адзін спосаб усталёўкі падыходзіць у прынцыпе для ўсяго.
У гэтым кластары ў мяне будзе Kubernetes v1.14.5. Увесь кластар Куба, які мы будзем разглядаць, падзелены на неймспейсы, кожны неймспейс належыць асобнай камандзе, у кожны неймспейс ёсць доступ у членаў гэтай каманды. У розныя неймспейсы яны хадзіць не могуць, толькі ў свой. Але ёсць нейкая адмінская ўлікоўка, у якой ёсць правы на ўвесь кластар.
Я абяцаў, што першае ў нас будзе - атрыманне адмінскіх правоў на кластар. Нам патрэбен спецыяльна падрыхтаваны 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, калі не памыляюся, забраць там усе майстравыя сертыфікаты кластара і, адпаведна, стаць адмінам кластара.
Калі так паглядзець, гэта адны з самых небяспечных правоў у падах - нягледзячы на тое, якія правы ёсць у карыстальніка:
Калі ў мяне ёсць правы запусціць пад у нейкім неймспейсе кластара, то ў гэтага пода гэтыя правы ёсць па змаўчанні. Я магу запускаць прывілеяваныя поды, а гэта ўвогуле ўсе правы, практычна рут на ноду.
Маё каханае – Root user. А ў Кубернэтэса ёсць такая опцыя Run As Non-Root. Гэта такая тыпу абарона ад хакера. Ведаеце, што такое "малдаўскі вірус"? Калі вы раптам хакер і дашлі ў мой кластар Кубернетэс, то мы, бедныя адміністратары, просім: «Пакажыце, калі ласка, у сваіх подах, якімі вы будзеце хакаць мой кластар, run as non-root. А то так атрымаецца, што вы запусціце працэс у сваім подзе пад рутам, і вам вельмі проста будзе мяне хакнуць. Абараніцеся, калі ласка, ад сябе самі».
Host path volume - на мой погляд, самы хуткі спосаб атрымаць жаданы вынік ад кластара Кубернэтэса.
Але што з усім гэтым рабіць?
Думкі, якая павінны прыходзіць любому нармальнаму адміністратару, які сутыкаецца з Кубернэтэсам: «Ага, я ж казаў, Кубернэтэс не працуе. У ім дзіркі. І ўвесь Куб бздура». Насамрэч, ёсць такая штука, як дакументацыя, а калі туды паглядзець, то там ёсць раздзел
Гэта такі 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-імя ў вашым кластары мне адгадваць не давядзецца. Бо яно стандартнае.
Далей у нас ёсць нейкі 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 вы ведаеце, што гэта чарговы 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у і зачыняеце з дапамогай іх. І таму давядзецца крыху перапісаць чартам. На самай справе калі вы зойдзеце ў
Ёсць яшчэ адна невялікая праблема. Не толькі 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 дырэкторыі, прычым неаўтарызаванаму карыстачу.
Усім дзякуй.
Крыніца: habr.com