Memperbaiki lubang di cluster Kubernetes. Laporan dan transkrip dari DevOpsConf

Pavel Selivanov, arsitek solusi Southbridge dan guru Slurm, memberikan presentasi di DevOpsConf 2019. Pembicaraan ini merupakan bagian dari salah satu topik kursus mendalam tentang Kubernetes “Slurm Mega”.

Slurm Basic: Pengantar Kubernetes berlangsung di Moskow pada 18-20 November.
Slurm Mega: mencari di balik terpal Kubernetes — Moskow, 22-24 November.
Slurm Online: kedua kursus Kubernetes selalu tersedia.

Di bawah potongan tersebut terdapat transkrip laporan.

Selamat siang rekan-rekan dan pihak-pihak yang bersimpati kepada mereka. Hari ini saya akan berbicara tentang keselamatan.

Saya melihat banyak penjaga keamanan di aula hari ini. Saya mohon maaf sebelumnya jika saya menggunakan istilah-istilah dari dunia keamanan yang tidak persis seperti kebiasaan Anda.

Kebetulan sekitar enam bulan yang lalu saya menemukan satu cluster Kubernetes publik. Publik berarti terdapat jumlah namespace ke-n; dalam namespace ini terdapat pengguna yang diisolasi dalam namespace mereka. Semua pengguna ini berasal dari perusahaan yang berbeda. Nah, cluster ini diasumsikan harus digunakan sebagai CDN. Artinya, mereka memberi Anda sebuah cluster, mereka memberi Anda pengguna di sana, Anda pergi ke sana ke namespace Anda, menyebarkan front Anda.

Perusahaan saya sebelumnya mencoba menjual layanan seperti itu. Dan saya diminta untuk menyodok cluster tersebut untuk melihat apakah solusi ini cocok atau tidak.

Saya datang ke cluster ini. Saya diberi hak terbatas, namespace terbatas. Orang-orang di sana mengerti apa itu keselamatan. Mereka membaca tentang kontrol akses berbasis peran (RBAC) di Kubernetes - dan mereka memutarbalikkannya sehingga saya tidak dapat meluncurkan pod secara terpisah dari penerapan. Saya tidak ingat masalah yang saya coba selesaikan dengan meluncurkan sebuah pod tanpa penerapan, tetapi saya benar-benar ingin meluncurkan sebuah pod saja. Semoga beruntung, saya memutuskan untuk melihat hak apa yang saya miliki di cluster, apa yang bisa saya lakukan, apa yang tidak bisa saya lakukan, dan apa yang telah mereka lakukan di sana. Pada saat yang sama, saya akan memberi tahu Anda apa yang salah dikonfigurasi di RBAC.

Kebetulan dalam dua menit saya menerima admin cluster mereka, melihat semua namespace tetangga, melihat di sana bagian produksi yang sedang berjalan dari perusahaan yang telah membeli layanan dan menerapkannya. Saya hampir tidak bisa menahan diri untuk tidak tampil di depan seseorang dan melontarkan kata-kata makian di halaman utama.

Saya akan memberi tahu Anda dengan contoh bagaimana saya melakukan ini dan bagaimana melindungi diri Anda dari ini.

Tapi pertama-tama, izinkan saya memperkenalkan diri. Nama saya Pavel Selivanov. Saya seorang arsitek di Southbridge. Saya memahami Kubernetes, DevOps, dan segala hal mewah lainnya. Para insinyur Southbridge dan saya sedang membangun semua ini, dan saya berkonsultasi.

Selain aktivitas utama kami, kami baru-baru ini meluncurkan proyek yang disebut Slurm. Kami mencoba untuk sedikit memperkenalkan kemampuan kami untuk bekerja dengan Kubernetes, untuk mengajari orang lain untuk juga bekerja dengan K8.

Apa yang akan saya bicarakan hari ini? Topik laporannya jelas - tentang keamanan cluster Kubernetes. Tetapi saya ingin segera mengatakan bahwa topik ini sangat besar - dan oleh karena itu saya ingin segera mengklarifikasi apa yang pasti tidak akan saya bicarakan. Saya tidak akan berbicara tentang istilah-istilah usang yang telah digunakan ratusan kali di Internet. Segala macam RBAC dan sertifikat.

Saya akan berbicara tentang apa yang menyusahkan saya dan rekan-rekan saya tentang keamanan di cluster Kubernetes. Kami melihat masalah ini baik di antara penyedia yang menyediakan cluster Kubernetes maupun di antara klien yang datang kepada kami. Dan bahkan dari klien yang datang kepada kami dari perusahaan admin konsultan lain. Artinya, skala tragedi tersebut sebenarnya sangat besar.

Ada tiga poin yang akan saya bicarakan hari ini:

  1. Hak pengguna vs hak pod. Hak pengguna dan hak pod bukanlah hal yang sama.
  2. Mengumpulkan informasi tentang cluster. Saya akan menunjukkan bahwa Anda dapat mengumpulkan semua informasi yang Anda perlukan dari sebuah cluster tanpa memiliki hak khusus dalam cluster ini.
  3. Serangan DoS pada cluster. Jika kami tidak dapat mengumpulkan informasi, kami tetap dapat membuat cluster. Saya akan berbicara tentang serangan DoS pada elemen kontrol cluster.

Hal umum lainnya yang akan saya sebutkan adalah pada apa saya menguji semua ini, yang mana saya dapat dengan pasti mengatakan bahwa semuanya berfungsi.

Kami mengambil dasar instalasi cluster Kubernetes menggunakan Kubespray. Jika ada yang belum tahu, ini sebenarnya adalah kumpulan peran Ansible. Kami menggunakannya terus-menerus dalam pekerjaan kami. Hal baiknya adalah Anda bisa menggulungnya di mana saja - Anda bisa menggulungnya menjadi potongan besi atau menjadi awan di suatu tempat. Satu metode instalasi pada prinsipnya berfungsi untuk semuanya.

Di cluster ini saya akan memiliki Kubernetes v1.14.5. Seluruh cluster Cube, yang akan kita pertimbangkan, dibagi menjadi beberapa namespace, setiap namespace milik tim yang terpisah, dan anggota tim ini memiliki akses ke setiap namespace. Mereka tidak bisa pergi ke namespace yang berbeda, hanya ke namespace mereka sendiri. Namun ada akun admin tertentu yang memiliki hak atas seluruh cluster.

Memperbaiki lubang di cluster Kubernetes. Laporan dan transkrip dari DevOpsConf

Saya berjanji bahwa hal pertama yang akan kami lakukan adalah mendapatkan hak admin atas cluster tersebut. Kami memerlukan pod yang disiapkan secara khusus yang akan memecah cluster Kubernetes. Yang perlu kita lakukan hanyalah menerapkannya pada cluster Kubernetes.

kubectl apply -f pod.yaml

Pod ini akan sampai ke salah satu master cluster Kubernetes. Dan setelah ini cluster akan dengan senang hati mengembalikan kepada kita sebuah file bernama admin.conf. Di Cube, file ini menyimpan semua sertifikat administrator, dan pada saat yang sama mengkonfigurasi API cluster. Menurut saya, begitulah mudahnya mendapatkan akses admin ke 98% cluster Kubernetes.

Saya ulangi, pod ini dibuat oleh salah satu pengembang di cluster Anda yang memiliki akses untuk menyebarkan proposalnya ke dalam satu namespace kecil, semuanya dijepit oleh RBAC. Dia tidak punya hak. Tapi tetap saja sertifikat itu dikembalikan.

Dan sekarang tentang pod yang disiapkan khusus. Kami menjalankannya pada gambar apa pun. Mari kita ambil debian:jessie sebagai contoh.

Kami memiliki hal ini:

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

Apa itu toleransi? Master di cluster Kubernetes biasanya ditandai dengan sesuatu yang disebut taint. Dan inti dari “infeksi” ini adalah dikatakan bahwa pod tidak dapat ditugaskan ke node master. Tapi tidak ada seorangpun yang mau menunjukkan bahwa pod tersebut toleran terhadap “infeksi”. Bagian Toleransi hanya mengatakan bahwa jika beberapa node memiliki NoSchedule, maka node kami toleran terhadap infeksi tersebut - dan tidak ada masalah.

Lebih lanjut, kami katakan bahwa bawahan kami tidak hanya toleran, tetapi juga ingin secara khusus menyasar sang majikan. Karena para master memiliki hal terlezat yang kami butuhkan - semua sertifikat. Oleh karena itu, kami mengatakan nodeSelector - dan kami memiliki label standar pada master, yang memungkinkan Anda memilih dari semua node di cluster yang merupakan node master.

Dengan dua bagian ini dia pasti akan sampai pada masternya. Dan dia akan diizinkan untuk tinggal di sana.

Namun datang kepada sang master saja tidaklah cukup bagi kami. Ini tidak akan memberi kita apa pun. Jadi selanjutnya kita memiliki dua hal ini:

hostNetwork: true 
hostPID: true 

Kami menentukan bahwa pod kami, yang kami luncurkan, akan berada di namespace kernel, di namespace jaringan, dan di namespace PID. Setelah pod diluncurkan pada master, pod akan dapat melihat semua antarmuka nyata dan langsung dari node ini, mendengarkan semua lalu lintas, dan melihat PID dari semua proses.

Maka ini masalah hal-hal kecil. Ambil etcd dan baca apa yang Anda inginkan.

Yang paling menarik adalah fitur Kubernetes ini, yang hadir disana secara default.

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

Dan intinya adalah kita dapat mengatakan di pod yang kita luncurkan, bahkan tanpa hak atas cluster ini, bahwa kita ingin membuat volume bertipe hostPath. Ini berarti mengambil jalur dari host tempat kita akan meluncurkannya - dan menganggapnya sebagai volume. Dan kemudian kami menyebutnya nama: tuan rumah. Kami memasang seluruh hostPath ini di dalam pod. Dalam contoh ini, ke direktori /host.

Saya akan mengulanginya lagi. Kami menyuruh pod untuk datang ke master, mendapatkan hostNetwork dan hostPID di sana - dan memasang seluruh root master di dalam pod ini.

Anda memahami bahwa di Debian kami menjalankan bash, dan bash ini berjalan di bawah root. Artinya, kami baru saja menerima root pada master, tanpa memiliki hak apa pun di cluster Kubernetes.

Kemudian seluruh tugasnya adalah pergi ke subdirektori /host /etc/kubernetes/pki, jika saya tidak salah, ambil semua sertifikat master cluster di sana dan, karenanya, jadilah administrator cluster.

Jika Anda melihatnya seperti ini, berikut adalah beberapa hak paling berbahaya di pod - apa pun hak yang dimiliki pengguna:
Memperbaiki lubang di cluster Kubernetes. Laporan dan transkrip dari DevOpsConf

Jika saya memiliki hak untuk menjalankan sebuah pod di beberapa namespace cluster, maka pod ini memiliki hak tersebut secara default. Saya dapat menjalankan pod yang memiliki hak istimewa, dan ini umumnya merupakan hak, praktis melakukan root pada node.

Favorit saya adalah pengguna Root. Dan Kubernetes memiliki opsi Jalankan Sebagai Non-Root. Ini adalah jenis perlindungan dari peretas. Tahukah Anda apa itu “virus Moldova”? Jika Anda tiba-tiba menjadi seorang hacker dan datang ke cluster Kubernetes saya, maka kami, administrator yang malang, bertanya: “Tolong tunjukkan di pod Anda yang akan Anda gunakan untuk meretas cluster saya, jalankan sebagai non-root. Jika tidak, Anda akan menjalankan proses di pod Anda di bawah root, dan akan sangat mudah bagi Anda untuk meretas saya. Tolong lindungi dirimu dari dirimu sendiri."

Volume jalur host, menurut saya, adalah cara tercepat untuk mendapatkan hasil yang diinginkan dari cluster Kubernetes.

Tapi apa yang harus dilakukan dengan semua ini?

Pemikiran yang harus muncul di benak setiap administrator normal yang mengenal Kubernetes adalah: “Ya, sudah saya katakan, Kubernetes tidak berfungsi. Ada lubang di dalamnya. Dan keseluruhan Cube adalah omong kosong.” Sebenarnya ada yang namanya dokumentasi, dan kalau dilihat-lihat, ada bagiannya Kebijakan Keamanan Pod.

Ini adalah objek yaml - kita dapat membuatnya di cluster Kubernetes - yang mengontrol aspek keamanan khususnya dalam deskripsi pod. Faktanya, ia mengontrol hak untuk menggunakan hostNetwork, hostPID, jenis volume tertentu yang ada di pod saat startup. Dengan bantuan Kebijakan Keamanan Pod, semua ini dapat dijelaskan.

Hal yang paling menarik tentang Kebijakan Keamanan Pod adalah bahwa di cluster Kubernetes, semua installer PSP tidak dijelaskan dengan cara apa pun, tetapi juga dinonaktifkan secara default. Kebijakan Keamanan Pod diaktifkan menggunakan plugin penerimaan.

Oke, mari kita terapkan Kebijakan Keamanan Pod ke dalam cluster, misalkan kita memiliki beberapa pod layanan di namespace, yang hanya dapat diakses oleh admin. Katakanlah, dalam semua kasus lainnya, pod memiliki hak terbatas. Karena kemungkinan besar pengembang tidak perlu menjalankan pod dengan hak istimewa di cluster Anda.

Dan semuanya tampak baik-baik saja bagi kami. Dan cluster Kubernetes kami tidak dapat diretas dalam dua menit.

Ada masalah. Kemungkinan besar, jika Anda memiliki cluster Kubernetes, maka pemantauan diinstal pada cluster Anda. Saya bahkan memperkirakan bahwa jika cluster Anda memiliki pemantauan, itu akan disebut Prometheus.

Apa yang akan saya sampaikan kepada Anda akan berlaku untuk operator Prometheus dan Prometheus yang dikirimkan dalam bentuk murni. Pertanyaannya adalah jika saya tidak bisa memasukkan admin ke dalam cluster secepat itu, maka ini berarti saya perlu mencari lebih jauh. Dan saya dapat mencari dengan bantuan pemantauan Anda.

Mungkin semua orang membaca artikel yang sama di Habré, dan pemantauannya terletak di namespace pemantauan. Bagan helm disebut kurang lebih sama untuk semua orang. Saya menduga jika Anda melakukan helm install stable/prometheus, Anda akan mendapatkan nama yang kira-kira sama. Dan kemungkinan besar saya bahkan tidak perlu menebak nama DNS di cluster Anda. Karena itu standar.

Memperbaiki lubang di cluster Kubernetes. Laporan dan transkrip dari DevOpsConf

Selanjutnya kita memiliki dev ns tertentu, di mana Anda dapat menjalankan pod tertentu. Dan dari pod ini sangat mudah untuk melakukan sesuatu seperti ini:

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

prometheus-kube-state-metrics adalah salah satu eksportir Prometheus yang mengumpulkan metrik dari Kubernetes API itu sendiri. Ada banyak data di sana, apa yang berjalan di cluster Anda, apa itu, apa masalah yang Anda hadapi.

Sebagai contoh sederhana:

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

Dengan membuat permintaan curl sederhana dari pod yang tidak memiliki hak istimewa, Anda bisa mendapatkan informasi berikut. Jika Anda tidak mengetahui versi Kubernetes yang Anda jalankan, Kubernetes akan dengan mudah memberi tahu Anda.

Dan yang paling menarik adalah selain mengakses kube-state-metrics, Anda juga dapat dengan mudah mengakses Prometheus sendiri secara langsung. Anda dapat mengumpulkan metrik dari sana. Anda bahkan dapat membuat metrik dari sana. Bahkan secara teoritis, Anda dapat membuat kueri seperti itu dari sebuah cluster di Prometheus, yang hanya akan mematikannya. Dan pemantauan Anda akan berhenti bekerja dari cluster sama sekali.

Dan di sini muncul pertanyaan apakah ada pemantauan eksternal yang memantau pemantauan Anda. Saya baru saja mendapat kesempatan untuk beroperasi di cluster Kubernetes tanpa konsekuensi apa pun bagi diri saya sendiri. Anda bahkan tidak akan tahu bahwa saya beroperasi di sana, karena tidak ada lagi pengawasan.

Sama seperti PSP, sepertinya masalahnya adalah semua teknologi mewah ini - Kubernetes, Prometheus - tidak berfungsi dan penuh lubang. Tidak terlalu.

Ada hal seperti itu - Kebijakan Jaringan.

Jika Anda seorang admin biasa, kemungkinan besar Anda tahu tentang Kebijakan Jaringan bahwa ini hanyalah yaml lain, yang sudah ada banyak di cluster. Dan beberapa Kebijakan Jaringan jelas tidak diperlukan. Dan bahkan jika Anda membaca apa itu Kebijakan Jaringan, bahwa itu adalah firewall yaml di Kubernetes, yang memungkinkan Anda membatasi hak akses antar namespace, antar pod, maka Anda pasti memutuskan bahwa firewall dalam format yaml di Kubernetes didasarkan pada abstraksi berikutnya … Tidak, tidak. Ini jelas tidak diperlukan.

Meskipun Anda tidak memberi tahu pakar keamanan bahwa dengan menggunakan Kubernetes, Anda dapat membangun firewall yang sangat mudah dan sederhana, dan sangat terperinci. Jika mereka belum mengetahui hal ini dan tidak mengganggu Anda: "Baiklah, beri saya, beri saya..." Maka bagaimanapun juga, Anda memerlukan Kebijakan Jaringan untuk memblokir akses ke beberapa tempat layanan yang dapat ditarik dari cluster Anda tanpa izin apa pun.

Seperti pada contoh yang saya berikan, Anda dapat mengambil metrik status kube dari namespace mana pun di cluster Kubernetes tanpa memiliki hak apa pun untuk melakukannya. Kebijakan jaringan telah menutup akses dari semua namespace lain ke namespace pemantauan dan hanya itu: tidak ada akses, tidak ada masalah. Di semua chart yang ada, baik Prometheus standar maupun Prometheus yang ada di operator, hanya ada opsi di nilai helm untuk mengaktifkan kebijakan jaringan bagi mereka. Anda hanya perlu menyalakannya dan semuanya akan berfungsi.

Sebenarnya ada satu masalah di sini. Sebagai admin berjanggut biasa, kemungkinan besar Anda memutuskan bahwa kebijakan jaringan tidak diperlukan. Dan setelah membaca berbagai artikel di sumber seperti Habr, Anda memutuskan bahwa kain flanel, terutama dengan mode host-gateway, adalah pilihan terbaik.

Apa yang harus dilakukan?

Anda dapat mencoba menerapkan kembali solusi jaringan yang Anda miliki di cluster Kubernetes Anda, coba ganti dengan sesuatu yang lebih fungsional. Untuk Calico yang sama, misalnya. Namun saya ingin segera mengatakan bahwa tugas mengubah solusi jaringan di cluster kerja Kubernetes bukanlah hal yang sepele. Saya menyelesaikannya dua kali (keduanya, secara teoritis), tetapi kami bahkan menunjukkan cara melakukannya di Slurms. Untuk siswa kami, kami menunjukkan cara mengubah solusi jaringan di cluster Kubernetes. Pada prinsipnya, Anda dapat mencoba memastikan tidak ada downtime pada cluster produksi. Tapi Anda mungkin tidak akan berhasil.

Dan masalahnya sebenarnya diselesaikan dengan sangat sederhana. Ada sertifikat di cluster, dan Anda tahu bahwa sertifikat Anda akan kedaluwarsa dalam satu tahun. Ya, dan biasanya solusi normal dengan sertifikat di cluster - mengapa kita khawatir, kita akan membuat cluster baru di dekatnya, membiarkan yang lama membusuk, dan memindahkan semuanya. Benar, kalau sudah busuk, kita harus duduk seharian, tapi ini cluster baru.

Saat Anda membesarkan cluster baru, sekaligus masukkan Calico sebagai pengganti kain flanel.

Apa yang harus dilakukan jika sertifikat Anda diterbitkan selama seratus tahun dan Anda tidak akan menerapkan ulang cluster? Ada yang namanya Kube-RBAC-Proxy. Ini adalah pengembangan yang sangat keren, memungkinkan Anda untuk menyematkan dirinya sebagai container sidecar ke pod mana pun di cluster Kubernetes. Dan ia sebenarnya menambahkan otorisasi ke pod ini melalui RBAC Kubernetes itu sendiri.

Ada satu masalah. Sebelumnya, solusi Kube-RBAC-Proxy ini dibangun di Prometheus milik operator. Tapi kemudian dia pergi. Sekarang versi modern mengandalkan fakta bahwa Anda memiliki kebijakan jaringan dan menutupnya menggunakan kebijakan tersebut. Dan oleh karena itu kita harus menulis ulang grafiknya sedikit. Faktanya, jika Anda pergi ke repositori ini, ada contoh bagaimana menggunakan ini sebagai sidecars, dan grafiknya harus ditulis ulang secara minimal.

Ada satu masalah kecil lagi. Prometheus bukan satu-satunya yang membagikan metriknya kepada sembarang orang. Semua komponen cluster Kubernetes kami juga dapat menampilkan metriknya sendiri.

Namun seperti yang sudah saya katakan, jika Anda tidak dapat mengakses cluster dan mengumpulkan informasi, setidaknya Anda dapat menimbulkan kerugian.

Jadi saya akan segera menunjukkan dua cara bagaimana cluster Kubernetes dapat dirusak.

Anda akan tertawa ketika saya memberi tahu Anda hal ini, ini adalah dua kasus kehidupan nyata.

Metode satu. Penipisan sumber daya.

Mari luncurkan pod khusus lainnya. Ini akan memiliki bagian seperti ini.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Seperti yang Anda ketahui, permintaan adalah jumlah CPU dan memori yang dicadangkan pada host untuk pod tertentu yang memiliki permintaan. Jika kita memiliki host empat inti di cluster Kubernetes, dan empat pod CPU tiba di sana dengan permintaan, itu berarti tidak ada lagi pod dengan permintaan yang dapat masuk ke host ini.

Jika saya menjalankan pod seperti itu, saya akan menjalankan perintah:

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

Maka tidak ada orang lain yang dapat menerapkannya ke cluster Kubernetes. Karena semua node akan kehabisan permintaan. Dan dengan demikian saya akan menghentikan cluster Kubernetes Anda. Jika saya melakukan ini di malam hari, saya dapat menghentikan penerapan untuk waktu yang cukup lama.

Jika kita melihat kembali dokumentasi Kubernetes, kita akan melihat hal yang disebut Limit Range. Ini menetapkan sumber daya untuk objek cluster. Anda dapat menulis objek Batas Rentang di yaml, menerapkannya ke namespace tertentu - dan kemudian di namespace ini Anda dapat mengatakan bahwa Anda memiliki sumber daya default, maksimum dan minimum untuk pod.

Dengan bantuan hal seperti itu, kami dapat membatasi pengguna di ruang nama produk tertentu dari tim dalam kemampuan untuk menunjukkan segala macam hal buruk di pod mereka. Namun sayangnya, meskipun Anda memberi tahu pengguna bahwa mereka tidak dapat meluncurkan pod dengan permintaan lebih dari satu CPU, ada perintah skala yang sangat bagus, atau mereka dapat melakukan penskalaan melalui dasbor.

Dan dari sinilah metode nomor dua berasal. Kami meluncurkan 11 pod. Itu sebelas miliar. Ini bukan karena saya mendapatkan nomor seperti itu, tetapi karena saya melihatnya sendiri.

Kisah nyata. Menjelang sore saya hendak meninggalkan kantor. Saya melihat sekelompok pengembang duduk di sudut, dengan panik melakukan sesuatu dengan laptop mereka. Saya mendatangi mereka dan bertanya: “Apa yang terjadi padamu?”

Beberapa saat sebelumnya, sekitar jam sembilan malam, salah satu pengembang bersiap-siap untuk pulang. Dan saya memutuskan: “Sekarang saya akan memperkecil lamaran saya menjadi satu.” Saya menekan satu, tetapi Internet sedikit melambat. Dia menekan yang satu lagi, dia menekan yang satu lagi, dan mengklik Enter. Aku menyodok semua yang aku bisa. Kemudian Internet menjadi hidup - dan segalanya mulai berkurang hingga angka ini.

Benar, cerita ini tidak terjadi di Kubernetes; pada saat itu adalah Nomad. Itu berakhir dengan fakta bahwa setelah satu jam upaya kami untuk menghentikan upaya terus-menerus dari Nomad untuk melakukan penskalaan, Nomad menjawab bahwa dia tidak akan berhenti melakukan penskalaan dan tidak akan melakukan apa pun lagi. "Aku lelah, aku pergi." Dan dia meringkuk.

Tentu saja, saya mencoba melakukan hal yang sama di Kubernetes. Kubernetes tidak senang dengan sebelas miliar pod, dia berkata: “Saya tidak bisa. Melebihi pelindung mulut bagian dalam." Tapi 1 pod bisa.

Menanggapi satu miliar, Cube tidak menarik diri. Dia benar-benar mulai melakukan penskalaan. Semakin jauh prosesnya, semakin banyak waktu yang dibutuhkannya untuk membuat pod baru. Namun prosesnya tetap berjalan. Satu-satunya masalah adalah jika saya dapat meluncurkan pod tanpa batas di namespace saya, bahkan tanpa permintaan dan batasan saya dapat meluncurkan begitu banyak pod dengan beberapa tugas sehingga dengan bantuan tugas ini node akan mulai bertambah di memori, di CPU. Ketika saya meluncurkan begitu banyak pod, informasi dari pod tersebut harus disimpan, yaitu, dll. Dan ketika terlalu banyak informasi yang masuk ke sana, penyimpanan mulai kembali terlalu lambat - dan Kubernetes mulai menjadi membosankan.

Dan satu masalah lagi... Seperti yang Anda ketahui, elemen kontrol Kubernetes bukanlah satu hal utama, melainkan beberapa komponen. Secara khusus, ada manajer pengontrol, penjadwal, dan sebagainya. Semua orang ini akan mulai melakukan pekerjaan yang tidak perlu dan bodoh pada saat yang bersamaan, yang seiring waktu akan memakan lebih banyak waktu. Manajer pengontrol akan membuat pod baru. Penjadwal akan mencoba mencari node baru untuk mereka. Kemungkinan besar Anda akan segera kehabisan node baru di cluster Anda. Cluster Kubernetes akan mulai bekerja semakin lambat.

Tapi saya memutuskan untuk melangkah lebih jauh. Seperti yang kalian ketahui, di Kubernetes ada yang namanya layanan. Secara default, di cluster Anda, kemungkinan besar, layanan bekerja menggunakan tabel IP.

Misalnya, jika Anda menjalankan satu miliar pod, lalu menggunakan skrip untuk memaksa Kubernetis membuat layanan baru:

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

Di semua node cluster, semakin banyak aturan iptables baru yang akan dihasilkan secara bersamaan. Selain itu, satu miliar aturan iptables akan dihasilkan untuk setiap layanan.

Saya memeriksa semuanya pada beberapa ribu, hingga sepuluh. Dan masalahnya sudah pada ambang batas ini cukup bermasalah untuk melakukan ssh ke node. Karena paket-paket, yang melewati begitu banyak rantai, mulai terasa tidak enak.

Dan semua ini diselesaikan dengan bantuan Kubernetes. Ada objek kuota Sumber Daya. Menetapkan jumlah sumber daya dan objek yang tersedia untuk namespace di klaster. Kita dapat membuat objek yaml di setiap namespace cluster Kubernetes. Dengan menggunakan objek ini, kita dapat mengatakan bahwa kita memiliki sejumlah permintaan dan batasan yang dialokasikan untuk namespace ini, dan kemudian kita dapat mengatakan bahwa dalam namespace ini dimungkinkan untuk membuat 10 layanan dan 10 pod. Dan satu pengembang setidaknya bisa tersedak di malam hari. Kubernetes akan memberitahunya: “Anda tidak dapat menskalakan pod Anda ke jumlah tersebut, karena sumber dayanya melebihi kuota.” Itu saja, masalah terpecahkan. Dokumentasi di sini.

Ada satu permasalahan yang muncul dalam hal ini. Anda merasakan betapa sulitnya membuat namespace di Kubernetes. Untuk membuatnya, kita perlu mempertimbangkan banyak hal.

Kuota sumber daya + Rentang Batas + RBAC
• Buat ruang nama
• Buat batasan di dalamnya
• Buat kuota sumber daya di dalam
• Buat akun layanan untuk CI
• Membuat pengikatan peran untuk CI dan pengguna
• Secara opsional, luncurkan pod layanan yang diperlukan

Oleh karena itu, saya ingin menggunakan kesempatan ini untuk berbagi perkembangan saya. Ada yang disebut operator SDK. Ini adalah cara cluster Kubernetes menulis operator untuknya. Anda dapat menulis pernyataan menggunakan Ansible.

Awalnya ditulis di Ansible, lalu saya melihat ada operator SDK dan menulis ulang peran Ansible menjadi operator. Pernyataan ini memungkinkan Anda membuat objek di cluster Kubernetes yang disebut perintah. Di dalam sebuah perintah, ini memungkinkan Anda untuk mendeskripsikan lingkungan untuk perintah ini di yaml. Dan dalam lingkungan tim, hal ini memungkinkan kami untuk menggambarkan bahwa kami mengalokasikan begitu banyak sumber daya.

Sedikit membuat seluruh proses rumit ini menjadi lebih mudah.

Dan sebagai kesimpulan. Apa yang harus dilakukan dengan semua ini?
Pertama. Kebijakan Keamanan Pod bagus. Meskipun faktanya hingga saat ini belum ada penginstal Kubernetes yang menggunakannya, Anda masih perlu menggunakannya di cluster Anda.

Kebijakan Jaringan bukan sekadar fitur yang tidak diperlukan. Hal inilah yang sangat dibutuhkan dalam sebuah cluster.

LimitRange/ResourceQuota - saatnya menggunakannya. Kami mulai menggunakan ini sejak lama, dan untuk waktu yang lama saya yakin semua orang menggunakannya. Ternyata hal ini jarang terjadi.

Selain apa yang saya sebutkan dalam laporan, ada fitur tidak berdokumen yang memungkinkan Anda menyerang cluster. Dirilis baru-baru ini analisis ekstensif terhadap kerentanan Kubernetes.

Beberapa hal sangat menyedihkan dan menyakitkan. Misalnya, dalam kondisi tertentu, cubelet di cluster Kubernetes dapat memberikan konten direktori warlocks kepada pengguna yang tidak berwenang.

Di sini Ada instruksi tentang cara mereproduksi semua yang saya katakan. Terdapat file dengan contoh produksi seperti apa ResourceQuota dan Kebijakan Keamanan Pod. Dan Anda bisa menyentuh semua ini.

Terimakasih untuk semua.

Sumber: www.habr.com

Tambah komentar