{"id":39203,"date":"2019-10-31T22:28:25","date_gmt":"2019-10-31T19:28:25","guid":{"rendered":"https:\/\/prohoster.info\/blog\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf\/"},"modified":"2019-10-31T22:28:25","modified_gmt":"2019-10-31T19:28:25","slug":"zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf","title":{"rendered":"Zatykamy dziury w klastrze Kubernetes. Prezentacja i transkrypcja z DevOpsConf","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Pawel Seliwanow, architekt rozwi\u0105za\u0144 w Southbridge i wyk\u0142adowca Slurm, wyst\u0105pi\u0142 z prezentacj\u0105 na DevOpsConf 2019. Ta prezentacja jest cz\u0119\u015bci\u0105 jednego z temat\u00f3w zaawansowanego kursu po Kubernetes \u201eSlurm Mega\u201d.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/slurm.io\/slurm?utm_source=habranons\">Slurm Podstawowy: wprowadzenie do Kubernetes<\/a><\/noindex> odbywa si\u0119 w Moskwie w dniach 18-20 listopada.<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/slurm.io\/mega?utm_source=habranons\">Slurm Mega: zagl\u0105damy pod mask\u0119 Kubernetes<\/a><\/noindex> \u2014 Moskwa, 22-24 listopada.<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/slurm.io\/online?utm_source=habranons\">Slurm Online: oba kursy po Kubernetes<\/a><\/noindex> dost\u0119pne zawsze.<\/p>\n<p>\n<center><div class=\"youtube-placeholder\" data-id=\"Gt4Q1du5FXk\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/Gt4Q1du5FXk\/hqdefault.jpg\" alt=\"Odtwarzaj wideo\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<p>Pod katem znajduje si\u0119 transkrypcja prezentacji.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Dzie\u0144 dobry, koledzy i sympatycy. Dzi\u015b b\u0119d\u0119 m\u00f3wi\u0107 o bezpiecze\u0144stwie.<\/p>\n<p><\/p>\n<p>Widz\u0119, \u017ce na sali jest dzi\u015b wielu specjalist\u00f3w ds. bezpiecze\u0144stwa. Z g\u00f3ry przepraszam, je\u015bli terminy z obszaru bezpiecze\u0144stwa b\u0119d\u0119 u\u017cywa\u0142 nieco inaczej ni\u017c to jest u was przyj\u0119te. <\/p>\n<p><\/p>\n<p>Tak si\u0119 z\u0142o\u017cy\u0142o, \u017ce gdzie\u015b p\u00f3\u0142 roku temu w moje r\u0119ce trafi\u0142 jeden publiczny klaster Kubernetes. Publiczny \u2014 oznacza to, \u017ce jest tam n-liczba namespaces, w tych namespaces s\u0105 u\u017cytkownicy, izolowani we w\u0142asnym namespaces. Wszyscy ci u\u017cytkownicy nale\u017c\u0105 do r\u00f3\u017cnych firm. C\u00f3\u017c, zak\u0142adano, \u017ce ten klaster ma by\u0107 u\u017cywany jako CDN. To znaczy, \u017ce daj\u0105 ci klaster, daj\u0105 tam u\u017cytkownika, przychodzisz do swojego namespace, deployujesz swoje fronty. <\/p>\n<p><\/p>\n<p>Mojej poprzedniej firmie pr\u00f3bowano sprzeda\u0107 tak\u0105 us\u0142ug\u0119. I poproszono mnie o przetestowanie klastra pod k\u0105tem tego, czy takie rozwi\u0105zanie odpowiada czy nie. <\/p>\n<p><\/p>\n<p>Wszed\u0142em do tego klastra. Dano mi ograniczone prawa, ograniczony namespace. Tam ch\u0142opaki rozumieli, czym jest bezpiecze\u0144stwo. Czytali, czym jest Role-based access control (RBAC) w Kubernetes \u2014 i skonfigurowali to tak, \u017ce nie mog\u0142em uruchamia\u0107 pod\u00f3w oddzielnie od deployment\u00f3w. Nie pami\u0119tam zadania, kt\u00f3re pr\u00f3bowa\u0142em rozwi\u0105za\u0107, uruchamiaj\u0105c pod bez deploymentu, ale bardzo chcia\u0142em po prostu uruchomi\u0107 pod. Postanowi\u0142em sprawdzi\u0107, jakie mam prawa w klastrze, co mog\u0119, czego nie mog\u0119, co tam pokr\u0119cili. Przy okazji opowiem, co maj\u0105 w RBAC skonfigurowane niepoprawnie. <\/p>\n<p><\/p>\n<p>Tak si\u0119 z\u0142o\u017cy\u0142o, \u017ce po dw\u00f3ch minutach uzyska\u0142em dost\u0119p administratora do ich klastra, zajrza\u0142em do wszystkich s\u0105siednich namespaces, zobaczy\u0142em tam uruchomione produkcyjne fronty firm, kt\u00f3re ju\u017c kupi\u0142y us\u0142ug\u0119 i zdeployowa\u0142y si\u0119. Ledwo powstrzyma\u0142em si\u0119, \u017ceby nie przyj\u015b\u0107 do kogo\u015b na front i nie umie\u015bci\u0107 na stronie g\u0142\u00f3wnej jakiego\u015b wulgaryzmu. <\/p>\n<p><\/p>\n<p>Opowiem na przyk\u0142adach, jak to zrobi\u0142em i jak nale\u017cy si\u0119 przed tym broni\u0107. <\/p>\n<p><\/p>\n<p>Na pocz\u0105tek pozw\u00f3lcie, \u017ce si\u0119 przedstawi\u0119. Nazywam si\u0119 Pawe\u0142 Seliwanow. Jestem architektem w firmie Southbridge. Znam si\u0119 na Kubernetesie, DevOps i innych modnych rzeczach. My z in\u017cynierami w Southbridge budujemy to wszystko, a ja doradzam. <\/p>\n<p><\/p>\n<p>Opr\u00f3cz dzia\u0142alno\u015bci g\u0142\u00f3wnej niedawno uruchomili\u015bmy projekty nazywane Slurmami. Staramy si\u0119 wprowadzi\u0107 nasze umiej\u0119tno\u015bci z pracy z Kubernetesem do szerszego grona, ucz\u0105c innych, jak r\u00f3wnie\u017c pracowa\u0107 z K8s. <\/p>\n<p><\/p>\n<p>O czym dzisiaj b\u0119d\u0119 m\u00f3wi\u0142. Temat mojego wyst\u0105pienia jest oczywisty \u2014 bezpiecze\u0144stwo klastra Kubernetes. Ale od razu chc\u0119 zaznaczy\u0107, \u017ce to bardzo obszerny temat \u2014 i dlatego chc\u0119 od razu wyja\u015bni\u0107, o czym na pewno nie b\u0119d\u0119 m\u00f3wi\u0107. Nie zamierzam omawia\u0107 wy\u015bwiechtanych termin\u00f3w, kt\u00f3re w internecie zosta\u0142y ju\u017c wielokrotnie przerobione, takich jak RBAC czy certyfikaty. <\/p>\n<p><\/p>\n<p>B\u0119d\u0119 m\u00f3wi\u0142 o tym, co moi koledzy i ja odczuwamy jako problemy zwi\u0105zane z bezpiecze\u0144stwem klastra Kubernetes. Widzimy te problemy zar\u00f3wno u dostawc\u00f3w, kt\u00f3rzy oferuj\u0105 klastry Kubernetes, jak i u klient\u00f3w, kt\u00f3rzy do nas przychodz\u0105. Nawet u klient\u00f3w, kt\u00f3rzy przychodz\u0105 do nas z innych firm konsultingowych. Tak wi\u0119c skala problemu jest w rzeczywisto\u015bci bardzo du\u017ca. <\/p>\n<p><\/p>\n<p>W\u0142a\u015bciwie trzy punkty, o kt\u00f3rych dzisiaj opowiem: <\/p>\n<p><\/p>\n<ol>\n<li>Uprawnienia u\u017cytkownik\u00f3w vs uprawnienia pod\u00f3w. Uprawnienia u\u017cytkownik\u00f3w i uprawnienia pod\u00f3w to nie to samo. <\/li>\n<li>Zbieranie informacji o klastrze. Poka\u017c\u0119, \u017ce mo\u017cna zbiera\u0107 wszystkie potrzebne informacje z klastra bez specjalnych uprawnie\u0144 w tym klastrze. <\/li>\n<li>Atak DoS na klaster. Je\u015bli nie b\u0119dziemy mogli zbiera\u0107 informacji, mimo wszystko b\u0119dziemy mogli zablokowa\u0107 klaster. Opowiem o atakach DoS na elementy zarz\u0105dzaj\u0105ce klastrem. <\/li>\n<\/ol>\n<p><\/p>\n<p>Jeszcze jedna og\u00f3lna rzecz, kt\u00f3r\u0105 wspomn\u0119 \u2014 na czym testowa\u0142em to wszystko, na czym mog\u0119 z ca\u0142\u0105 pewno\u015bci\u0105 powiedzie\u0107, \u017ce to dzia\u0142a.<\/p>\n<p><\/p>\n<p>Jako podstaw\u0119 bierzemy instalacj\u0119 klastra Kubernetes za pomoc\u0105 Kubespray. Je\u015bli kto\u015b nie wie, to jest to w\u0142a\u015bciwie zestaw r\u00f3l dla Ansible. Stosujemy go na co dzie\u0144 w pracy. Jest dobry, poniewa\u017c mo\u017cna go zainstalowa\u0107 wsz\u0119dzie \u2014 zar\u00f3wno na sprz\u0119cie, jak i w chmurze. Jeden spos\u00f3b instalacji w zasadzie pasuje do wszystkiego. <\/p>\n<p><\/p>\n<p>W tej klasie b\u0119dziemy mieli Kubernetes v1.14.5. Ca\u0142y klaster Kuby, kt\u00f3ry b\u0119dziemy omawia\u0107, jest podzielony na przestrzenie nazw, z kt\u00f3rych ka\u017cda nale\u017cy do innego zespo\u0142u, a cz\u0142onkowie tego zespo\u0142u maj\u0105 dost\u0119p tylko do swojej przestrzeni nazw. Nie mog\u0105 wchodzi\u0107 do innych przestrzeni. Istnieje jednak konto administracyjne, kt\u00f3re ma uprawnienia do ca\u0142ego klastra. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Zatykamy dziury w klastrze Kubernetes. Prezentacja i transkrypcja z DevOpsConf\" src=\"\/wp-content\/uploads\/2019\/10\/a50803499a402b7d90f8fe0738a3d029.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Obieca\u0142em, \u017ce pierwszym krokiem b\u0119dzie uzyskanie praw administratora do klastra. Potrzebujemy specjalnie przygotowanego poda, kt\u00f3ry b\u0119dzie prze\u0142amywa\u0142 klaster Kubernetes. Wszystko, co musimy zrobi\u0107, to zastosowa\u0107 go w klastrze Kubernetes. <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">kubectl apply -f pod.yaml<\/code><\/pre>\n<p><\/p>\n<p>Ten pod przyjedzie na jeden z master\u00f3w klastra Kubernetes. A klaster rado\u015bnie zwr\u00f3ci nam plik o nazwie admin.conf. W tym pliku Kuby zawarte s\u0105 wszystkie certyfikaty administratora, a tak\u017ce skonfigurowane jest API klastra. W ten spos\u00f3b mo\u017cna uzyska\u0107 dost\u0119p do administracji, my\u015bl\u0119, \u017ce do 98% klastr\u00f3w Kubernetes. <\/p>\n<p><\/p>\n<p>Powtarzam, ten pod stworzy\u0142 jeden programista w waszym klastrze, kt\u00f3ry ma dost\u0119p do wdra\u017cania swoich propozycji w ma\u0142ej przestrzeni nazw, jest on zupe\u0142nie zablokowany przez RBAC. Nie mia\u0142 \u017cadnych uprawnie\u0144. Niemniej jednak certyfikat zosta\u0142 zwr\u00f3cony. <\/p>\n<p><\/p>\n<p>A teraz o specjalnie przygotowanym podzie. Uruchamiamy na dowolnym obrazie. Dla przyk\u0142adu we\u017amy debian:jessie. <\/p>\n<p><\/p>\n<p>Mamy co\u015b takiego: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">tolerations:\n-   effect: NoSchedule \n    operator: Exists \nnodeSelector: \n    node-role.kubernetes.io\/master: \"\" <\/code><\/pre>\n<p><\/p>\n<p>Czym jest toleracja? Masterzy w klastrze Kubernetes s\u0105 zazwyczaj oznaczeni czym\u015b, co nazywa si\u0119 taint (\"zara\u017cenie\" po angielsku). Sens tego \"zara\u017cenia\" polega na tym, \u017ce nie mo\u017cna przypisywa\u0107 pod\u00f3w do w\u0119z\u0142\u00f3w master. Ale nikt nie zabrania w dowolnym podzie wskaza\u0107, \u017ce jest on tolerancyjny wobec \"zara\u017cenia\". Sekcja Toleration wskazuje, \u017ce je\u015bli na jakim\u015b w\u0119\u017ale ustalono NoSchedule, to nasz pod jest tolerancyjny wobec takiego zara\u017cenia \u2014 i nie ma z tym problem\u00f3w. <\/p>\n<p><\/p>\n<p>Nast\u0119pnie m\u00f3wimy, \u017ce nasz pod nie tylko jest tolerancyjny, ale r\u00f3wnie\u017c chce specjalnie trafi\u0107 do mastera. Poniewa\u017c na masterach znajduje si\u0119 to, co jest dla nas najwa\u017cniejsze \u2014 wszystkie certyfikaty. Dlatego m\u00f3wimy nodeSelector \u2014 i mamy standardow\u0105 etykiet\u0119 na masterach, kt\u00f3ra pozwala wybra\u0107 spo\u015br\u00f3d wszystkich w\u0119z\u0142\u00f3w klastra te, kt\u00f3re s\u0105 masterami. <\/p>\n<p><\/p>\n<p>Z takimi dwoma sekcjami pod z pewno\u015bci\u0105 trafi na mastera. I dostanie zezwolenie na \u017cycie tam. <\/p>\n<p><\/p>\n<p>Jednak samo przybycie na mastera to za ma\u0142o. To nam nic nie da. Dlatego p\u00f3\u017aniej mamy takie dwa elementy:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">hostNetwork: true \nhostPID: true <\/code><\/pre>\n<p><\/p>\n<p>Wskazujemy, \u017ce nasz pod, kt\u00f3ry uruchamiamy, b\u0119dzie dzia\u0142a\u0142 w przestrzeni nazw j\u0105dra, w przestrzeni nazw sieci i w przestrzeni nazw PID. Gdy tylko pod wystartuje na masterze, b\u0119dzie m\u00f3g\u0142 zobaczy\u0107 wszystkie prawdziwe, aktywne interfejsy tego w\u0119z\u0142a, nas\u0142uchiwa\u0107 ca\u0142y ruch i widzie\u0107 PID wszystkich proces\u00f3w.<\/p>\n<p><\/p>\n<p>Teraz pozostaje niewiele do zrobienia. Bierzemy etcd i odczytujemy, co chcemy. <\/p>\n<p><\/p>\n<p>Najciekawsze jest to, \u017ce ta funkcjonalno\u015b\u0107 Kubernetes jest dost\u0119pna domy\u015blnie. <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">volumeMounts:\n- mountPath: \/host \n  name: host \nvolumes:\n- hostPath: \n    path: \/ \n    type: Directory \n  name: host <\/code><\/pre>\n<p><\/p>\n<p>I istota tego polega na tym, \u017ce mo\u017cemy w podzie, kt\u00f3ry uruchamiamy, nawet bez praw do tego klastra, powiedzie\u0107, \u017ce chcemy stworzy\u0107 volume typu hostPath. Oznacza to, \u017ce we\u017amiemy \u015bcie\u017ck\u0119 z hosta, na kt\u00f3rym si\u0119 uruchomimy \u2014 i wykorzystamy j\u0105 jako volume. Nast\u0119pnie nazywamy go name: host. Ca\u0142y ten hostPath montujemy wewn\u0105trz podu. W tym przyk\u0142adzie w katalogu \/host. <\/p>\n<p><\/p>\n<p>Jeszcze raz powt\u00f3rz\u0119. Powiedzieli\u015bmy podowi przyby\u0107 na mastera, uzyska\u0107 hostNetwork i hostPID \u2014 i zamontowa\u0107 ca\u0142y root mastera wewn\u0105trz tego podu. <\/p>\n<p><\/p>\n<p>Rozumiesz, \u017ce na debianie uruchamiamy bash, a ten bash dzia\u0142a z uprawnieniami roota. Oznacza to, \u017ce w\u0142a\u015bnie uzyskali\u015bmy roota na masterze, nie posiadaj\u0105c przy tym \u017cadnych praw w klastrze Kubernetes.<\/p>\n<p><\/p>\n<p>Dalej ca\u0142a sprawa polega na tym, aby wej\u015b\u0107 do podu w katalogu \/host \/etc\/kubernetes\/pki, je\u015bli si\u0119 nie myl\u0119, zabra\u0107 tam wszystkie g\u0142\u00f3wne certyfikaty klastra i w ten spos\u00f3b sta\u0107 si\u0119 administratorem klastra. <\/p>\n<p><\/p>\n<p>Je\u015bli na to spojrze\u0107, to s\u0105 jedne z najniebezpieczniejszych uprawnie\u0144 w podach \u2014 niezale\u017cnie od tego, jakie prawa ma u\u017cytkownik:<br \/>\n<img decoding=\"async\" alt=\"Zatykamy dziury w klastrze Kubernetes. Prezentacja i transkrypcja z DevOpsConf\" src=\"\/wp-content\/uploads\/2019\/10\/53f0bb92dc86cde97193a8e4ddf94c6a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli mam prawo uruchomi\u0107 pod w jakiej\u015b przestrzeni nazw klastra, to ten pod ma te prawa domy\u015blnie. Mog\u0119 uruchamia\u0107 uprzywilejowane pody, a to praktycznie wszystkie prawa, prawie root na w\u0119\u017ale. <\/p>\n<p><\/p>\n<p>Moim ulubionym jest u\u017cytkownik Root. A Kubernetes ma tak\u0105 opcj\u0119 Uruchom jako nie-root. To jest rodzaj ochrony przed hakerami. Wiecie, co to jest \u201emo\u0142dawski wirus\u201d? Je\u015bli nagle jeste\u015bcie hakerem i weszli\u015bcie do mojego klastra Kubernetes, to my, biedni administratorzy, prosimy: \u00abProsz\u0119, okre\u015blcie, w waszych podach, kt\u00f3re zhackuj\u0105 m\u00f3j klaster, run as non-root. Bo mo\u017ce si\u0119 zdarzy\u0107, \u017ce uruchomicie proces w swoim podzie jako root, co bardzo u\u0142atwi mi w\u0142amanie. Prosz\u0119, chro\u0144cie si\u0119 sami\u00bb. <\/p>\n<p><\/p>\n<p>Volume host path \u2014 moim zdaniem, najszybszy spos\u00f3b na osi\u0105gni\u0119cie po\u017c\u0105danego wyniku w klastrze Kubernetes. <\/p>\n<p><\/p>\n<p>Ale co z tym wszystkim zrobi\u0107? <\/p>\n<p><\/p>\n<p>My\u015bli, kt\u00f3re powinny przychodzi\u0107 do g\u0142owy ka\u017cdemu normalnemu administratorowi, kt\u00f3ry ma do czynienia z Kubernetesem: \u201eAha, m\u00f3wi\u0142em, Kubernetes nie dzia\u0142a. Ma luki. Ca\u0142y Kubernetes to bzdura\u201d. W rzeczywisto\u015bci istnieje co\u015b takiego jak dokumentacja, a je\u015bli si\u0119 w ni\u0105 zagl\u0105dniesz, znajdziesz rozdzia\u0142 <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/policy\/pod-security-policy\/\">Pod Security Policy<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>To taki obiekt yaml \u2014 mo\u017cemy go tworzy\u0107 w klastrze Kubernetes \u2014 kt\u00f3ry kontroluje aspekty bezpiecze\u0144stwa w opisie pod\u00f3w. Oznacza to, \u017ce faktycznie kontroluje on prawa do u\u017cycia r\u00f3\u017cnych hostNetwork, hostPID, okre\u015blonych typ\u00f3w wolumen\u00f3w, kt\u00f3re s\u0105 dost\u0119pne w podach podczas uruchamiania. Dzi\u0119ki Pod Security Policy mo\u017cna to wszystko opisa\u0107. <\/p>\n<p><\/p>\n<p>Najnowsze w Pod Security Policy to, \u017ce w klastrze Kubernetes \u017caden z instalator\u00f3w PSP nie jest po prostu opisany, a domy\u015blnie s\u0105 one wy\u0142\u0105czone. Pod Security Policy w\u0142\u0105cza si\u0119 za pomoc\u0105 wtyczki admission.<\/p>\n<p><\/p>\n<p>OK, wdro\u017cymy Pod Security Policy w klastrze, powiedzmy, \u017ce mamy us\u0142u\u017cne pody w namespace, do kt\u00f3rego maj\u0105 dost\u0119p tylko administratorzy. Powiedzmy, \u017ce w innych podach prawa s\u0105 ograniczone. Poniewa\u017c prawdopodobnie deweloperzy nie musz\u0105 uruchamia\u0107 uprawnionych pod\u00f3w w Twoim klastrze. <\/p>\n<p><\/p>\n<p>I wszystko wydaje si\u0119 w porz\u0105dku. Nasz klaster Kubernetes nie mo\u017ce zosta\u0107 zhakowany w dwie minuty. <\/p>\n<p><\/p>\n<p>Jest problem. Prawdopodobnie, je\u015bli masz klaster Kubernetes, to masz w nim monitoring. Nawet odwa\u017cam si\u0119 przewidzie\u0107, \u017ce je\u015bli w twoim klastrze jest monitoring, to nazywa si\u0119 on Prometheus. <\/p>\n<p><\/p>\n<p>To, co teraz opowiem, b\u0119dzie wa\u017cne zar\u00f3wno dla operatora Prometheus, jak i dla Prometheus zainstalowanego w czystej wersji. Pytanie jest takie, \u017ce je\u015bli nie mog\u0119 tak szybko uzyska\u0107 administratora w klastrze, oznacza to, \u017ce musz\u0119 wi\u0119cej szuka\u0107. A mog\u0119 szuka\u0107 za pomoc\u0105 twojego monitoringu.<\/p>\n<p><\/p>\n<p>Prawdopodobnie wszyscy czytali te same artyku\u0142y na Habrze, a monitoring znajduje si\u0119 w namespace monitoring. Helm chart ma wszyscy nazywa na mniej wi\u0119cej tak samo. Zak\u0142adam, \u017ce je\u015bli zrobisz helm install stable\/prometheus, to otrzymasz mniej wi\u0119cej te same nazwy. A nawet prawdopodobnie nie b\u0119d\u0119 musia\u0142 zgadywa\u0107 nazwy DNS w twoim klastrze. Poniewa\u017c jest standardowa. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Zatykamy dziury w klastrze Kubernetes. Prezentacja i transkrypcja z DevOpsConf\" src=\"\/wp-content\/uploads\/2019\/10\/9df85cc12305a1ddaec933a6f838305e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dalej mamy jaki\u015b dev ns, w kt\u00f3rym mo\u017cna uruchomi\u0107 jaki\u015b pod. I dalej z tego poda bardzo \u0142atwo zrobi\u0107 to: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ curl http:\/\/prometheus-kube-state-metrics.monitoring <\/code><\/pre>\n<p><\/p>\n<p>prometheus-kube-state-metrics to jeden z eksporter\u00f3w Prometheusa, kt\u00f3ry zbiera metryki z API samego Kubernetes. Zawiera wiele danych o tym, co dzia\u0142a w Twoim klastrze, jakie jest, jakie masz z nim problemy. <\/p>\n<p><\/p>\n<p>Jako prosty przyk\u0142ad: <\/p>\n<p><\/p>\n<p>kube_pod_container_info{namespace=\u00abkube-system&#187;,pod=&#187;kube-apiserver-k8s- 1&#8243;,container=&#187;kube-apiserver&#187;,image= <\/p>\n<p><\/p>\n<p><strong>&#171;gcr.io\/google-containers\/kube-apiserver:v1.14.5&#187; <\/strong><\/p>\n<p><\/p>\n<p>,image_id=&#187;docker-pullable:\/\/gcr.io\/google-containers\/kube- apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989&#8243;,container_id=&#187;docker:\/\/7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b&#187;} 1 <\/p>\n<p><\/p>\n<p>Wykonuj\u0105c prosty \u017c\u0105danie curl z nieuprzywilejowanego poda, mo\u017cna uzyska\u0107 takie informacje. Je\u015bli nie wiesz, w kt\u00f3rej wersji Kubernetes jeste\u015b uruchomiony, to \u0142atwo Ci to powie. <\/p>\n<p><\/p>\n<p>A co ciekawe, obok tego, \u017ce zwracasz si\u0119 do kube-state-metrics, mo\u017cesz r\u00f3wnie dobrze zwr\u00f3ci\u0107 si\u0119 bezpo\u015brednio do samego Prometheusa. Mo\u017cesz zebra\u0107 metryki stamt\u0105d. Mo\u017cesz nawet zbudowa\u0107 metryki. Teoretycznie mo\u017cesz zbudowa\u0107 takie zapytanie z klastra do Prometheusa, kt\u00f3re go po prostu wy\u0142\u0105czy. I tw\u00f3j monitoring ca\u0142kowicie przestanie dzia\u0142a\u0107. <\/p>\n<p><\/p>\n<p>I tutaj pojawia si\u0119 pytanie, czy jaki\u015b zewn\u0119trzny monitoring monitoruje Tw\u00f3j monitoring. W\u0142a\u015bnie zyska\u0142em mo\u017cliwo\u015b\u0107 dzia\u0142ania w klastrze Kubernetes bez jakichkolwiek konsekwencji dla siebie. Nawet nie dowiesz si\u0119, \u017ce tam dzia\u0142am, poniewa\u017c monitoringu ju\u017c nie ma. <\/p>\n<p><\/p>\n<p>Dok\u0142adnie tak samo, jak z PSP, wra\u017cenie jest takie, \u017ce problem polega na tym, \u017ce wszystkie te modne technologie \u2014 Kubernetes, Prometheus \u2014 po prostu nie dzia\u0142aj\u0105 i s\u0105 pe\u0142ne luk. W rzeczywisto\u015bci tak nie jest. <\/p>\n<p><\/p>\n<p>Jest co\u015b takiego \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/network-policies\/\">Network Policy<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Je\u015bli jeste\u015b normalnym adminem, to prawdopodobnie wiesz, \u017ce Network Policy to kolejny yaml, kt\u00f3rych w klastrze jest ju\u017c mn\u00f3stwo. A jakie\u015b Network Policies z pewno\u015bci\u0105 nie s\u0105 potrzebne. A nawet je\u015bli przeczyta\u0142e\u015b, czym jest Network Policy, \u017ce jest to yamlowy firewalla Kubernetes, kt\u00f3ry pozwala ogranicza\u0107 uprawnienia dost\u0119pu mi\u0119dzy namespace'ami, mi\u0119dzy podami, to na pewno stwierdzi\u0142e\u015b, \u017ce firewall w formacie yaml w Kubernetes na kolejnych abstrakcjach\u2026 Nie, nie. To zdecydowanie nie jest potrzebne. <\/p>\n<p><\/p>\n<p>Nawet je\u015bli Twoi specjali\u015bci ds. bezpiecze\u0144stwa nie wiedz\u0105, \u017ce za pomoc\u0105 Kubernetes mo\u017cna bardzo \u0142atwo stworzy\u0107 granulatowy firewall. Je\u015bli jeszcze tego nie wiedz\u0105 i nie dopytuj\u0105: \u201eNo dajcie, dajcie\u2026\u201d To w ka\u017cdym razie potrzebujesz Network Policy, aby zablokowa\u0107 dost\u0119p do niekt\u00f3rych zasob\u00f3w systemowych, kt\u00f3re mo\u017cna pod\u0142\u0105czy\u0107 do klastra bez \u017cadnej autoryzacji. <\/p>\n<p><\/p>\n<p>Jak w przyk\u0142adzie, kt\u00f3ry poda\u0142em, mo\u017cna uzyska\u0107 kube state metrics z dowolnej przestrzeni nazw w klastrze Kubernetes, nie maj\u0105c do tego \u017cadnych uprawnie\u0144. Polityki sieciowe zablokowa\u0142y dost\u0119p z wszystkich innych przestrzeni nazw do przestrzeni nazw monitorowania i jakby wszystko: brak dost\u0119pu, brak problem\u00f3w. We wszystkich chartach, kt\u00f3re s\u0105, zar\u00f3wno standardowym Prometeuszu, jak i tym w operatorze, wystarczy w values Helma w\u0142\u0105czy\u0107 polityki sieciowe dla nich. Trzeba tylko w\u0142\u0105czy\u0107, a b\u0119d\u0105 dzia\u0142a\u0107. <\/p>\n<p><\/p>\n<p>Jest tu jednak jeden problem. B\u0119d\u0105c normalnym adminem, prawdopodobnie zdecydowa\u0142e\u015b, \u017ce polityki sieciowe s\u0105 niepotrzebne. Przeczytawszy r\u00f3\u017cne artyku\u0142y na stronach takich jak Habr, uzna\u0142e\u015b, \u017ce Flannel, zw\u0142aszcza w trybie host-gateway, to najlepsze, co mo\u017cesz wybra\u0107. <\/p>\n<p><\/p>\n<p>Co robi\u0107? <\/p>\n<p><\/p>\n<p>Mo\u017cesz spr\u00f3bowa\u0107 prze-deployowa\u0107 rozwi\u0105zanie sieciowe, kt\u00f3re masz w klastrze Kubernetes, i zast\u0105pi\u0107 je czym\u015b bardziej funkcjonalnym. Na przyk\u0142ad tym samym Calico. Ale od razu chc\u0119 powiedzie\u0107, \u017ce zmiana rozwi\u0105zania sieciowego w dzia\u0142aj\u0105cym klastrze Kubernetes to do\u015b\u0107 nietrywialne zadanie. Rozwi\u0105zywa\u0142em je dwa razy (oba razy teoretycznie), ale nawet na Slurmach pokazywali\u015bmy, jak to zrobi\u0107. Dla naszych uczni\u00f3w pokazywali\u015bmy, jak zmieni\u0107 rozwi\u0105zanie sieciowe w klastrze Kubernetes. W zasadzie mo\u017cesz spr\u00f3bowa\u0107 tak zrobi\u0107, aby w klastrze produkcyjnym nie by\u0142o przestoj\u00f3w. Ale prawdopodobnie nic z tego nie wyjdzie. <\/p>\n<p><\/p>\n<p>A problem w rzeczywisto\u015bci rozwi\u0105zuje si\u0119 bardzo prosto. W klastrze s\u0105 certyfikaty, a Ty wiesz, \u017ce certyfikaty za rok wygasn\u0105. C\u00f3\u017c, zwykle normalne rozwi\u0105zanie z certyfikatami w klastrze - po co mamy si\u0119 martwi\u0107, to obok wzniesiemy nowy klaster, a w starym niech wygasa i wszystko przenie\u015bmy. Prawda, kiedy on wyga\u015bnie, wszystkiego dnia le\u017cy, ale przynajmniej nowy klaster. <\/p>\n<p><\/p>\n<p>Kiedy b\u0119dziesz podnosi\u0107 nowy klaster, od razu wstaw Calico zamiast Flannela. <\/p>\n<p><\/p>\n<p>Co zrobi\u0107, je\u015bli masz certyfikaty wa\u017cne przez sto lat, a klastra nie zamierzasz przedeptywa\u0107? Istnieje takie narz\u0119dzie jak Kube-RBAC-Proxy. To bardzo fajny projekt, kt\u00f3ry pozwala wbudowa\u0107 si\u0119 jako kontener sidecar do dowolnego poda w klastrze Kubernetes. W rzeczywisto\u015bci dodaje ono do tego poda autoryzacj\u0119 przez RBAC samego Kubernetes. <\/p>\n<p><\/p>\n<p>Jest jeden problem. Kiedy\u015b w operatorze Prometheus to rozwi\u0105zanie Kube-RBAC-Proxy by\u0142o wbudowane. Ale potem zosta\u0142o usuni\u0119te. Aktualne wersje opieraj\u0105 si\u0119 na tym, \u017ce masz polityk\u0119 sieci (network policy) i zamykasz je za ich pomoc\u0105. Dlatego b\u0119dziesz musia\u0142 nieco przerobi\u0107 chart. Tak naprawd\u0119, je\u015bli wejdziesz w <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/brancz\/kube-rbac-proxy\">ten repozytorium<\/a><\/noindex>, znajdziesz przyk\u0142ady, jak to wykorzysta\u0107 jako sidecary, a chartery b\u0119d\u0105 musia\u0142y by\u0107 przerobione minimalnie. <\/p>\n<p><\/p>\n<p>Jest jeszcze jeden drobny problem. Nie tylko Prometheus udost\u0119pnia swoje metryki komukolwiek. Wszystkie komponenty klastra Kubernetes r\u00f3wnie\u017c potrafi\u0105 udost\u0119pnia\u0107 swoje metryki. <\/p>\n<p><\/p>\n<p>Ale jak ju\u017c m\u00f3wi\u0142em, je\u015bli nie mo\u017cesz uzyska\u0107 dost\u0119pu do klastra i zebra\u0107 informacje, to przynajmniej mo\u017cesz zaszkodzi\u0107. <\/p>\n<p><\/p>\n<p>Tak wi\u0119c szybko poka\u017c\u0119 dwa sposoby, jak mo\u017cna zaszkodzi\u0107 zdrowiu klastra Kubernetes. <\/p>\n<p><\/p>\n<p>B\u0119dziesz si\u0119 \u015bmia\u0142, kiedy to opowiem, to dwa przypadki z prawdziwego \u017cycia. <\/p>\n<p><\/p>\n<p>Spos\u00f3b pierwszy. Wyczerpanie zasob\u00f3w. <\/p>\n<p><\/p>\n<p>Uruchamiamy jeszcze jeden specjalny pod. B\u0119dzie mia\u0142 tak\u0105 sekcj\u0119. <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">resources: \n    requests: \n        cpu: 4 \n        memory: 4Gi <\/code><\/pre>\n<p><\/p>\n<p>Jak wiesz, requests to ilo\u015b\u0107 CPU i pami\u0119ci, kt\u00f3ra jest rezerwowana na ho\u015bcie dla konkretnych pod\u00f3w z requests. Je\u015bli mamy czterordzeniowy host w klastrze Kubernetes, a tam przyje\u017cd\u017ca pod z requestami na cztery CPU, to znaczy\u0107, \u017ce \u017caden inny pod z requests na ten host nie b\u0119dzie m\u00f3g\u0142 si\u0119 prze\u0142adowa\u0107. <\/p>\n<p><\/p>\n<p>Je\u015bli uruchomi\u0119 taki pod, potem wykonam polecenie: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ kubectl scale special-pod --replicas=...<\/code><\/pre>\n<p><\/p>\n<p>To nikt inny w klastrze Kubernetes nie b\u0119dzie m\u00f3g\u0142 si\u0119 wdro\u017cy\u0107. Poniewa\u017c na wszystkich w\u0119z\u0142ach sko\u0144cz\u0105 si\u0119 requests. W ten spos\u00f3b zatrzymam tw\u00f3j klaster Kubernetes. Je\u015bli zrobi\u0119 to wieczorem, wdro\u017cenia mog\u0119 wstrzyma\u0107 na do\u015b\u0107 d\u0142ugi czas. <\/p>\n<p><\/p>\n<p>Je\u015bli raz jeszcze spojrzymy na dokumentacj\u0119 Kubernetes, zobaczymy co\u015b, co nazywa si\u0119 Limit Range. Ustala on zasoby dla obiekt\u00f3w klastra. Mo\u017cesz napisa\u0107 obiekt Limit Range w formacie yaml, zastosowa\u0107 go w okre\u015blonych przestrzeniach nazw \u2014 a nast\u0119pnie w tej przestrzeni nazw mo\u017cesz okre\u015bli\u0107, \u017ce masz domy\u015blne, maksymalne i minimalne zasoby dla pod\u00f3w.<\/p>\n<p><\/p>\n<p>Dzi\u0119ki takiej funkcji mo\u017cemy ograniczy\u0107 u\u017cytkownik\u00f3w w okre\u015blonych przestrzeniach nazw produkt\u00f3w w mo\u017cliwo\u015bciach wskazywania w swoich podach na r\u00f3\u017cne niepo\u017c\u0105dane elementy. Ale niestety, nawet je\u015bli powiesz u\u017cytkownikowi, \u017ce nie mo\u017ce uruchamia\u0107 pod\u00f3w z \u017c\u0105daniami wi\u0119kszymi ni\u017c jeden CPU, istnieje taka wspania\u0142a komenda scale, lub przez dashboard mog\u0105 realizowa\u0107 skalowanie.<\/p>\n<p><\/p>\n<p>I st\u0105d pochodzi spos\u00f3b numer dwa. Uruchamiamy 11 111 111 111 111 pod\u00f3w. To jedena\u015bcie miliard\u00f3w. Nie dlatego, \u017ce wymy\u015bli\u0142em tak\u0105 liczb\u0119, ale dlatego, \u017ce sam to widzia\u0142em. <\/p>\n<p><\/p>\n<p>Prawdziwa historia. P\u00f3\u017anym wieczorem ju\u017c mia\u0142em zamiar wyj\u015b\u0107 z biura. Patrz\u0119, w rogu siedzi grupka programist\u00f3w i co\u015b gor\u0105czkowo robi z laptopami. Podchodz\u0119 do ch\u0142opak\u00f3w i pytam: \u201eCo si\u0119 sta\u0142o?\u201d<\/p>\n<p><\/p>\n<p>Troch\u0119 wcze\u015bniej, oko\u0142o dziewi\u0105tej wieczorem, jeden z programist\u00f3w szykowa\u0142 si\u0119 do powrotu do domu. I postanowi\u0142: \u201eTeraz skaluj\u0119 moj\u0105 aplikacj\u0119 do jedynki\u201d. Nacisn\u0105\u0142 jedynk\u0119, a internet troch\u0119 si\u0119 spowolni\u0142. Nacisn\u0105\u0142 jeszcze raz na jedynk\u0119, przycisn\u0105\u0142 jedynk\u0119, klikn\u0105\u0142 Enter. Pr\u00f3bowa\u0142 wszystkiego, co m\u00f3g\u0142. Wtedy internet o\u017cy\u0142 \u2014 i wszystko zacz\u0119\u0142o si\u0119 skalowa\u0107 do tej liczby. <\/p>\n<p><\/p>\n<p>Prawda jest taka, \u017ce ta historia mia\u0142a miejsce nie na Kubernetes, w tamtym czasie by\u0142 to Nomad. Zako\u0144czy\u0142o si\u0119 to tym, \u017ce po godzinie naszych pr\u00f3b zatrzymania Nomada przed uporczywymi pr\u00f3bami skalowania, Nomad odpowiedzia\u0142, \u017ce nie przestanie si\u0119 skalowa\u0107 i nie zajmie si\u0119 niczym innym. \u201eJestem zm\u0119czony, odchodz\u0119\u201d. I si\u0119 wy\u0142\u0105czy\u0142. <\/p>\n<p><\/p>\n<p>Oczywi\u015bcie pr\u00f3bowa\u0142em to samo zrobi\u0107 na Kubernetesie. Jedena\u015bcie miliard\u00f3w pod\u00f3w nie ucieszy\u0142o Kubernetesa, powiedzia\u0142: \u201eNie mog\u0119. Przekracza wewn\u0119trzne limity\u201d. Ale 1 000 000 000 pod\u00f3w uda\u0142o mu si\u0119 uruchomi\u0107. <\/p>\n<p><\/p>\n<p>W odpowiedzi na jeden miliard pod\u00f3w Kubernetes nie skala\u0142 si\u0119. On naprawd\u0119 zacz\u0105\u0142 si\u0119 skalowa\u0107. Im dalej post\u0119powa\u0142 proces, tym wi\u0119cej czasu zajmowa\u0142o mu tworzenie nowych pod\u00f3w. Ale i tak proces przebiega\u0142. Jedynym problemem jest to, \u017ce je\u015bli mog\u0119 w swoim namespace'ie uruchamia\u0107 nieograniczon\u0105 ilo\u015b\u0107 pod\u00f3w, to nawet bez request\u00f3w i limit\u00f3w mog\u0119 uruchomi\u0107 na przyk\u0142ad tak\u0105 ilo\u015b\u0107 pod\u00f3w, \u017ce w wyniku tych zada\u0144 w\u0119z\u0142y zaczn\u0105 prze\u0142adowywa\u0107 pami\u0119\u0107 i CPU. Kiedy uruchamiam tyle pod\u00f3w, informacje z nich musz\u0105 trafi\u0107 do magazynu, czyli etcd. A gdy za du\u017co informacji tam trafia, magazyn zaczyna zbyt wolno odpowiada\u0107 \u2014 i Kubernetes zaczyna si\u0119 zacina\u0107. <\/p>\n<p><\/p>\n<p>A jest jeszcze jeden problem\u2026 Jak wiecie, komponenty zarz\u0105dzaj\u0105ce Kubernetesem to nie jeden centralny element, lecz kilka komponent\u00f3w. W szczeg\u00f3lno\u015bci jest tam kontroler mened\u017cer, scheduler i tak dalej. Wszyscy ci go\u015bcie zaczynaj\u0105 jednocze\u015bnie wykonywa\u0107 niepotrzebn\u0105 i bezsensown\u0105 prac\u0119, kt\u00f3ra z czasem zaczyna zajmowa\u0107 coraz wi\u0119cej czasu. Kontroler mened\u017cer b\u0119dzie tworzy\u0142 nowe pody. Scheduler b\u0119dzie pr\u00f3bowa\u0142 znale\u017a\u0107 dla nich nowy w\u0119ze\u0142. Nowe w\u0119z\u0142y w klastrze prawdopodobnie wkr\u00f3tce si\u0119 sko\u0144cz\u0105. Klastrowi Kubernetes b\u0119dzie dzia\u0142a\u0107 coraz wolniej.<\/p>\n<p><\/p>\n<p>Ale postanowi\u0142em p\u00f3j\u015b\u0107 jeszcze dalej. Jak wiecie, w Kubernetesie jest co\u015b, co nazywa si\u0119 us\u0142ug\u0105. No i domy\u015blnie w waszych klastrach, prawdopodobnie, us\u0142uga dzia\u0142a za pomoc\u0105 iptables. <\/p>\n<p><\/p>\n<p>Je\u015bli uruchomi\u0107 miliard pod\u00f3w, na przyk\u0142ad, a potem za pomoc\u0105 skryptu zmusi\u0107 Kubernetes do tworzenia nowych us\u0142ug: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">for i in {1..1111111}; do\n    kubectl expose deployment test --port 80  \n        --overrides=\"{\"apiVersion\": \"v1\", \n           \"metadata\": {\"name\": \"nginx$i\"}}\"; \ndone <\/code><\/pre>\n<p><\/p>\n<p>Na wszystkich w\u0119z\u0142ach klastra w przybli\u017ceniu w tym samym czasie b\u0119d\u0105 generowane nowe regu\u0142y iptables. I dla ka\u017cdej us\u0142ugi b\u0119d\u0105 generowane po miliard regu\u0142 iptables. <\/p>\n<p><\/p>\n<p>Sprawdza\u0142em to na kilku tysi\u0105cach, do dziesi\u0105tki. I problem polega na tym, \u017ce ju\u017c na tym etapie SSH na w\u0119ze\u0142 staje si\u0119 do\u015b\u0107 problematyczne. Poniewa\u017c pakiety, przechodz\u0105c przez tak\u0105 ilo\u015b\u0107 \u0142a\u0144cuch\u00f3w, zaczynaj\u0105 \u017ale si\u0119 czu\u0107. <\/p>\n<p><\/p>\n<p>I to r\u00f3wnie\u017c mo\u017cna rozwi\u0105za\u0107 za pomoc\u0105 Kubernetesa. Istnieje taki obiekt jak Resource quota. Ustala on ilo\u015b\u0107 dost\u0119pnych zasob\u00f3w i obiekt\u00f3w dla namespace w klastrze. Mo\u017cemy stworzy\u0107 obiekt YAML w ka\u017cdym namespace klastra Kubernetesa. Dzi\u0119ki temu obiektowi mo\u017cemy powiedzie\u0107, \u017ce dla tego namespace przydzielono okre\u015blon\u0105 liczb\u0119 request\u00f3w, limit\u00f3w, a nast\u0119pnie mo\u017cemy okre\u015bli\u0107, \u017ce w tym namespace mo\u017cna stworzy\u0107 10 us\u0142ug i 10 pod\u00f3w. A programista mo\u017ce sobie spokojnie pracowa\u0107 wieczorami. Kubernetes powie mu: \u201eNie mo\u017cesz skalowa\u0107 swoich pod\u00f3w do takiej liczby, poniewa\u017c przekracza to limit zasob\u00f3w\u201d. I problem rozwi\u0105zany. <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/policy\/resource-quotas\/\">Dokumentacja tutaj<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Jednak pojawia si\u0119 jeden problem w zwi\u0105zku z tym. Czujesz, jak trudno sta\u0142o si\u0119 stworzy\u0107 namespace w Kubernetesa. Aby go stworzy\u0107, musimy wzi\u0105\u0107 pod uwag\u0119 wiele rzeczy.<\/p>\n<p><\/p>\n<p>Resource quota + Limit Range + RBAC<br \/>\n\u2022 Tworzymy namespace<br \/>\n\u2022 Tworzymy w \u015brodku limitrange<br \/>\n\u2022 Tworzymy wewn\u0105trz resourcequota<br \/>\n\u2022 Tworzymy serviceaccount dla CI<br \/>\n\u2022 Tworzymy rolebinding dla CI i u\u017cytkownik\u00f3w<br \/>\n\u2022 Opcjonalnie uruchamiamy potrzebne us\u0142ugi pod\u00f3w <\/p>\n<p><\/p>\n<p>Dlatego korzystaj\u0105c z okazji, chcia\u0142bym podzieli\u0107 si\u0119 moimi opracowaniami. Istnieje jedna rzecz, kt\u00f3ra nazywa si\u0119 operator SDK. To spos\u00f3b pisania operator\u00f3w dla klastra Kubernetesa. Mo\u017cesz pisa\u0107 operatorzy za pomoc\u0105 Ansible.<\/p>\n<p><\/p>\n<p>Najpierw napisali\u015bmy to w Ansible, a potem zobaczy\u0142em, \u017ce istnieje operator SDK i przepisa\u0142em rol\u0119 Ansible na operatora. Ten operator pozwala stworzy\u0107 w klastrze Kubernetesa obiekt, kt\u00f3ry nazywa si\u0119 komenda. Wewn\u0105trz komendy pozwala opisa\u0107 w YAML \u015brodowisko dla tej komendy. A wewn\u0105trz \u015brodowiska komendy pozwala okre\u015bla\u0107, ile zasob\u00f3w przydzielamy. <\/p>\n<p><\/p>\n<p>Ma\u0142y <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pauljamm\/team-operator\">u\u0142atwiacz ca\u0142ego tego trudnego procesu<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>I na zako\u0144czenie. Co z tym wszystkim zrobi\u0107?<br \/>\nPo pierwsze. Polityka bezpiecze\u0144stwa poda \u2014 to dobrze. I mimo \u017ce \u017caden z instalator\u00f3w Kubernetesa do tej pory ich nie u\u017cywa, to wci\u0105\u017c nale\u017cy je stosowa\u0107 w Twoich klastrach. <\/p>\n<p><\/p>\n<p>Polityka sieciowa \u2014 to nie jest jaka\u015b inna niepotrzebna funkcjonalno\u015b\u0107. To to, co jest naprawd\u0119 potrzebne w klastrze. <\/p>\n<p><\/p>\n<p>LimitRange\/ResourceQuota \u2014 czas, aby z nich korzysta\u0107. Od dawna ju\u017c zacz\u0119li\u015bmy z tego korzysta\u0107, a ja d\u0142ugo by\u0142em przekonany, \u017ce wszyscy to stosuj\u0105. Okaza\u0142o si\u0119, \u017ce to rzadko\u015b\u0107. <\/p>\n<p><\/p>\n<p>Opr\u00f3cz tego, co wspomnia\u0142em podczas prezentacji, istniej\u0105 nieudokumentowane funkcje, kt\u00f3re umo\u017cliwiaj\u0105 atak na klaster. Niedawno wyszed\u0142 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/community\/blob\/master\/wg-security-audit\/findings\/Kubernetes%20Final%20Report.pdf\">wszechstronny analiz\u0119 podatno\u015bci Kubernetes<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>Niekt\u00f3re rzeczy s\u0105 na tyle smutne i przykre. Na przyk\u0142ad, w pewnych warunkach kubelety w klastrze Kubernetes mog\u0105 ujawnia\u0107 zawarto\u015b\u0107 katalogu warlocks, i to u\u017cytkownikowi nieautoryzowanemu. <\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/centosadmin\/kube-security\">Tutaj<\/a><\/noindex> znajduj\u0105 si\u0119 instrukcje, jak odtworzy\u0107 wszystko, co m\u00f3wi\u0142em. S\u0105 tam pliki z produkcyjnymi przyk\u0142adami, jak wygl\u0105daj\u0105 ResourceQuota i Pod Security Policy. I to wszystko mo\u017cna sprawdzi\u0107. <\/p>\n<p><\/p>\n<p>Dzi\u0119kuj\u0119 wszystkim.<\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/472484\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0430\u0432\u0435\u043b \u0421\u0435\u043b\u0438\u0432\u0430\u043d\u043e\u0432, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 Southbridge \u0438 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u044c \u0421\u043b\u0451\u0440\u043c\u0430, \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043d\u0430 DevOpsConf 2019. \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u2014 \u0447\u0430\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0442\u0435\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430 \u043f\u043e Kubernetes \u00ab\u0421\u043b\u0451\u0440\u043c \u041c\u0435\u0433\u0430\u00bb. \u0421\u043b\u0451\u0440\u043c \u0411\u0430\u0437\u043e\u0432\u044b\u0439: \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Kubernetes \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435 18-20 \u043d\u043e\u044f\u0431\u0440\u044f. \u0421\u043b\u0451\u0440\u043c \u041c\u0435\u0433\u0430: \u0437\u0430\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442 Kubernetes \u2014 \u041c\u043e\u0441\u043a\u0432\u0430, 22-24 \u043d\u043e\u044f\u0431\u0440\u044f. \u0421\u043b\u0451\u0440\u043c \u041e\u043d\u043b\u0430\u0439\u043d: \u043e\u0431\u0430 \u043a\u0443\u0440\u0441\u0430 \u043f\u043e Kubernetes \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u0441\u0435\u0433\u0434\u0430. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":29423,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-39203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0430\u0432\u0435\u043b \u0421\u0435\u043b\u0438\u0432\u0430\u043d\u043e\u0432, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 Southbridge \u0438 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u044c \u0421\u043b\u0451\u0440\u043c\u0430, \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043d\u0430 DevOpsConf 2019.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0417\u0430\u0434\u0435\u043b\u044b\u0432\u0430\u0435\u043c \u0434\u044b\u0440\u044b \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Kubernetes. \u0414\u043e\u043a\u043b\u0430\u0434 \u0438 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0441 DevOpsConf | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0430\u0432\u0435\u043b \u0421\u0435\u043b\u0438\u0432\u0430\u043d\u043e\u0432, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 Southbridge \u0438 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u044c \u0421\u043b\u0451\u0440\u043c\u0430, \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043d\u0430 DevOpsConf 2019.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:28:25+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:28:25+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Zasypujemy dziury w klastrze Kubernetes. Prezentacja i transkrypcja z DevOpsConf | ProHoster","description":"Pawel Selivanov, architekt rozwi\u0105za\u0144 w Southbridge i wyk\u0142adowca w Slyerma, wyg\u0142osi\u0142 prezentacj\u0119 na DevOpsConf 2019.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0417\u0430\u0434\u0435\u043b\u044b\u0432\u0430\u0435\u043c \u0434\u044b\u0440\u044b \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Kubernetes. \u0414\u043e\u043a\u043b\u0430\u0434 \u0438 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0441 DevOpsConf | ProHoster","og:description":"\u041f\u0430\u0432\u0435\u043b \u0421\u0435\u043b\u0438\u0432\u0430\u043d\u043e\u0432, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 Southbridge \u0438 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u044c \u0421\u043b\u0451\u0440\u043c\u0430, \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043d\u0430 DevOpsConf 2019.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/zadelyvaem-dyry-v-klastere-kubernetes-doklad-i-rasshifrovka-s-devopsconf","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:28:25+00:00","article:modified_time":"2019-10-31T19:28:25+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"39203","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 01:15:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 00:54:43","updated":"2026-01-24 01:15:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/39203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=39203"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/39203\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/29423"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=39203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=39203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=39203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}