Kubernetes kümesindeki deliklerin düzeltilmesi. DevOpsConf'tan rapor ve transkript

Güney köprüsü çözüm mimarı ve Slurm öğretmeni Pavel Selivanov, DevOpsConf 2019'da bir sunum yaptı. Bu konuşma, Kubernetes "Slurm Mega" hakkındaki derinlemesine kursun konularından birinin bir parçasıdır.

Slurm Basic: Kubernetes'e Giriş 18-20 Kasım'da Moskova'da gerçekleşecek.
Slurm Mega: Kubernetes'in kapsamının altına bakmak — Moskova, 22-24 Kasım.
Slurm Online: her iki Kubernetes kursu her zaman müsait.

Kesimin altında raporun bir metni bulunmaktadır.

İyi günler meslektaşlarım ve onlara sempati duyanlar. Bugün güvenlikten bahsedeceğim.

Bugün salonda çok sayıda güvenlik görevlisinin olduğunu görüyorum. Güvenlik dünyasından terimleri tam olarak sizin için alışılagelmişin dışında kullanırsam sizden şimdiden özür dilerim.

Yaklaşık altı ay önce halka açık bir Kubernetes kümesiyle karşılaştım. Public, n'inci sayıda ad alanı olduğu anlamına gelir; bu ad alanlarında, ad alanlarında yalıtılmış kullanıcılar vardır. Bu kullanıcıların tümü farklı şirketlere aittir. Aslında bu kümenin CDN olarak kullanılması gerektiği varsayılmıştı. Yani size bir küme veriyorlar, orada size bir kullanıcı veriyorlar, oraya kendi ad alanınıza gidiyorsunuz, cephelerinizi konuşlandırıyorsunuz.

Önceki şirketim böyle bir hizmet satmaya çalıştı. Ve bu çözümün uygun olup olmadığını görmek için kümeyi dürtmem istendi.

Bu kümeye geldim. Bana sınırlı haklar ve sınırlı isim alanı verildi. Oradaki adamlar güvenliğin ne olduğunu anladılar. Kubernetes'te Rol tabanlı erişim denetimi (RBAC) hakkında bilgi edindiler ve bunu, dağıtımlardan ayrı olarak bölmeleri başlatamayacağım şekilde değiştirdiler. Bir pod'u konuşlandırmadan başlatarak çözmeye çalıştığım sorunu hatırlamıyorum ama gerçekten sadece bir pod başlatmak istedim. Şans olsun diye kümede hangi haklara sahip olduğumu, neler yapabileceğimi, neler yapamayacağımı ve orada neleri berbat ettiklerini görmeye karar verdim. Aynı zamanda RBAC'ta neyi yanlış yapılandırdıklarını da anlatacağım.

Öyle oldu ki, iki dakika içinde kümelerine bir yönetici getirdim, tüm komşu ad alanlarına baktım ve orada hizmeti zaten satın almış ve dağıtmış olan şirketlerin çalışan üretim cephelerini gördüm. Birinin önüne çıkıp ana sayfaya küfür koymaktan kendimi zar zor alıkoyabildim.

Bunu nasıl yaptığımı ve kendinizi bundan nasıl koruyacağınızı örneklerle anlatacağım.

Ama önce kendimi tanıtayım. Benim adım Pavel Selivanov. Southbridge'de mimarım. Kubernetes'i, DevOps'u ve her türlü süslü şeyi anlıyorum. Bütün bunları Güney Köprüsü mühendisleri ve ben inşa ediyoruz ve ben de danışmanlık yapıyorum.

Ana faaliyetlerimizin yanı sıra son dönemde Slurms isimli projelerimizi de hayata geçirdik. Kubernetes ile çalışma yeteneğimizi biraz da olsa kitlelere ulaştırmaya, diğer insanlara da K8'lerle çalışmayı öğretmeye çalışıyoruz.

Bugün ne hakkında konuşacağım? Raporun konusu açık: Kubernetes kümesinin güvenliği. Ancak bu konunun çok geniş olduğunu hemen söylemek istiyorum ve bu nedenle kesinlikle ne hakkında konuşmayacağımı hemen açıklığa kavuşturmak istiyorum. İnternette yüzlerce kez kullanılmış olan basmakalıp terimlerden bahsetmeyeceğim. Her türlü RBAC ve sertifika.

Kubernetes kümesinde güvenlik konusunda beni ve meslektaşlarımı rahatsız eden şeylerden bahsedeceğim. Bu sorunları hem Kubernetes kümesi sağlayan sağlayıcılarda hem de bize gelen müşterilerimizde görüyoruz. Ve hatta diğer danışmanlık yönetici şirketlerinden bize gelen müşterilerimizden bile. Yani trajedinin boyutu aslında çok büyük.

Bugün bahsedeceğim tam anlamıyla üç nokta var:

  1. Kullanıcı hakları ve kapsül hakları. Kullanıcı hakları ve pod hakları aynı şey değildir.
  2. Küme hakkında bilgi toplama. Bir kümeden ihtiyacınız olan tüm bilgileri, bu kümede özel haklara sahip olmadan toplayabildiğinizi göstereceğim.
  3. Kümeye DoS saldırısı. Eğer bilgi toplayamıyorsak her halükarda bir küme koyabileceğiz. Cluster kontrol elemanlarına yapılan DoS saldırılarından bahsedeceğim.

Bahsedeceğim bir diğer genel şey de tüm bunları test ettiğim şey ve bunun üzerinde her şeyin işe yaradığını kesinlikle söyleyebilirim.

Kubespray kullanarak Kubernetes kümesinin kurulumunu esas alıyoruz. Bilmeyen varsa, bu aslında Ansible için bir dizi roldür. İşimizde sürekli kullanıyoruz. İyi olan şey, onu herhangi bir yere yuvarlayabilmenizdir; onu demir parçalarının üzerine veya bir yerlerdeki bir bulutun içine yuvarlayabilirsiniz. Prensip olarak her şey için tek bir kurulum yöntemi işe yarar.

Bu kümede Kubernetes v1.14.5'e sahip olacağım. Ele alacağımız Cube kümesinin tamamı ad alanlarına bölünmüştür, her ad alanı ayrı bir ekibe aittir ve bu ekibin üyelerinin her ad alanına erişimi vardır. Farklı ad alanlarına gidemezler, yalnızca kendilerine ait ad alanlarına gidebilirler. Ancak tüm kümenin haklarına sahip olan belirli bir yönetici hesabı var.

Kubernetes kümesindeki deliklerin düzeltilmesi. DevOpsConf'tan rapor ve transkript

Yapacağımız ilk şeyin kümenin yönetici haklarını almak olacağına söz verdim. Kubernetes kümesini kıracak özel hazırlanmış bir pod'a ihtiyacımız var. Tek yapmamız gereken bunu Kubernetes kümesine uygulamak.

kubectl apply -f pod.yaml

Bu kapsül, Kubernetes kümesinin ustalarından birine ulaşacak. Ve bundan sonra küme bize admin.conf adlı bir dosyayı memnuniyetle geri verecektir. Cube'da bu dosya tüm yönetici sertifikalarını saklar ve aynı zamanda küme API'sini yapılandırır. Sanırım Kubernetes kümelerinin %98'ine yönetici erişimi sağlamak bu kadar kolay.

Tekrar ediyorum, bu bölme, kümenizdeki tekliflerini küçük bir ad alanına dağıtma erişimi olan bir geliştirici tarafından yapıldı, tamamı RBAC tarafından sınırlandırıldı. Hiçbir hakkı yoktu. Ancak yine de sertifika iade edildi.

Ve şimdi özel olarak hazırlanmış bir kapsül hakkında. Herhangi bir görüntü üzerinde çalıştırıyoruz. Örnek olarak debian:jessie'yi ele alalım.

Şu şeye sahibiz:

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

Hoşgörü nedir? Kubernetes kümesindeki ustalar genellikle kusur adı verilen bir şeyle işaretlenir. Ve bu "enfeksiyonun" özü, bölmelerin ana düğümlere atanamayacağını söylemesidir. Ancak hiç kimse herhangi bir kapsülde "enfeksiyona" toleranslı olduğunu belirtme zahmetine girmiyor. Tolerasyon bölümünde sadece, eğer bazı düğümlerde NoSchedule varsa, düğümümüzün bu tür bir enfeksiyona karşı toleranslı olduğu ve herhangi bir sorun olmadığı belirtiliyor.

Ayrıca altımızın sadece hoşgörülü olmadığını, aynı zamanda özellikle efendiyi hedef almak istediğini de söylüyoruz. Çünkü ustalarda ihtiyacımız olan en lezzetli şey var; tüm sertifikalar. Bu nedenle, nodeSelector diyoruz - ve ana düğümler üzerinde, kümedeki tüm düğümler arasından tam olarak ana düğüm olan düğümleri seçmenize olanak tanıyan standart bir etiketimiz var.

Bu iki bölümle mutlaka ustaya gelecektir. Ve orada yaşamasına izin verilecek.

Ama sadece ustanın yanına gelmek bizim için yeterli değil. Bu bize hiçbir şey kazandırmayacak. Şimdi elimizde şu iki şey var:

hostNetwork: true 
hostPID: true 

Başlattığımız podumuzun çekirdek ad alanında, ağ ad alanında ve PID ad alanında yaşayacağını belirtiyoruz. Pod, ana cihazda başlatıldığında, bu düğümün tüm gerçek, canlı arayüzlerini görebilecek, tüm trafiği dinleyebilecek ve tüm süreçlerin PID'sini görebilecek.

O zaman mesele küçük şeylerdir. Etcd'yi alın ve ne istediğinizi okuyun.

En ilginç şey, varsayılan olarak orada bulunan bu Kubernetes özelliğidir.

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

Ve bunun özü, başlattığımız bölmede, bu kümeye ilişkin haklara sahip olmasak bile, hostPath türünde bir birim oluşturmak istediğimizi söyleyebilmemizdir. Bu, başlatacağımız ana bilgisayardan yolu almak ve bunu hacim olarak almak anlamına gelir. Ve sonra buna isim diyoruz: host. Bu hostPath'in tamamını bölmenin içine monte ediyoruz. Bu örnekte /host dizinine.

Tekrar edeceğim. Pod'a ana sunucuya gelmesini, hostNetwork'ü ve hostPID'yi oradan almasını ve ana birimin tüm kökünü bu bölmenin içine yerleştirmesini söyledik.

Debian'da bash'ın çalıştığını ve bu bash'ın root altında çalıştığını anlıyorsunuz. Yani, Kubernetes kümesinde herhangi bir hakka sahip olmadan, ana makinede yeni kök aldık.

Daha sonra tüm görev /host /etc/kubernetes/pki alt dizinine gitmek, yanılmıyorsam kümenin tüm ana sertifikalarını oradan almak ve buna göre küme yöneticisi olmaktır.

Bu açıdan bakarsanız, kullanıcının hangi haklara sahip olduğuna bakılmaksızın pod'lardaki en tehlikeli haklardan bazıları şunlardır:
Kubernetes kümesindeki deliklerin düzeltilmesi. DevOpsConf'tan rapor ve transkript

Kümenin bazı ad alanlarında bir bölmeyi çalıştırma haklarına sahipsem, bu bölme varsayılan olarak bu haklara sahiptir. Ayrıcalıklı bölmeleri çalıştırabilirim ve bunların genel olarak tüm hakları vardır ve pratik olarak düğüm üzerinde kök oluşturur.

Benim favorim Root kullanıcısı. Ve Kubernetes'te bu Kök Olmayan Olarak Çalıştır seçeneği vardır. Bu, bilgisayar korsanına karşı bir tür korumadır. “Moldavya virüsü”nün ne olduğunu biliyor musunuz? Aniden bir bilgisayar korsanı olursanız ve Kubernetes kümeme gelirseniz, o zaman biz kötü yöneticiler olarak şunu sorarız: “Lütfen kümemi hangi yollarla hackleyeceğinizi, kök olmayan olarak çalıştıracağınızı bölmelerinizde belirtin. Aksi takdirde işlemi pod'unuzda root altında çalıştırırsınız ve beni hacklemeniz çok kolay olur. Lütfen kendinizi kendinizden koruyun."

Ana bilgisayar yolu hacmi, bana göre bir Kubernetes kümesinden istenen sonucu almanın en hızlı yoludur.

Peki tüm bunlarla ne yapmalı?

Kubernetes ile karşılaşan normal bir yöneticinin aklına gelmesi gereken düşünce şudur: “Evet, size söyledim, Kubernetes çalışmıyor. İçinde delikler var. Ve Küp'ün tamamı saçmalık." Aslında belgeleme diye bir şey var, oraya bakarsanız şöyle bir bölüm var Pod Güvenlik Politikası.

Bu, özellikle bölmelerin açıklamasındaki güvenlik hususlarını kontrol eden bir yaml nesnesidir (bunu Kubernetes kümesinde oluşturabiliriz). Yani aslında başlangıçta bölmelerde bulunan herhangi bir hostNetwork'ü, hostPID'yi ve belirli birim türlerini kullanma haklarını kontrol eder. Pod Güvenlik Politikası'nın yardımıyla tüm bunlar açıklanabilir.

Pod Güvenlik Politikası ile ilgili en ilginç şey, Kubernetes kümesinde tüm PSP yükleyicilerinin hiçbir şekilde tanımlanmaması, aynı zamanda varsayılan olarak devre dışı bırakılmış olmasıdır. Pod Güvenlik Politikası, giriş eklentisi kullanılarak etkinleştirilir.

Tamam, Pod Güvenlik Politikasını kümeye dağıtalım, ad alanında yalnızca yöneticilerin erişebildiği bazı hizmet podlarımız olduğunu varsayalım. Diğer tüm durumlarda kapsüllerin sınırlı haklara sahip olduğunu varsayalım. Çünkü büyük olasılıkla geliştiricilerin kümenizde ayrıcalıklı bölmeler çalıştırmasına gerek yoktur.

Ve bizde her şey yolunda görünüyor. Ve Kubernetes kümemiz iki dakika içinde hacklenemez.

Bir problem var. Büyük olasılıkla, bir Kubernetes kümeniz varsa, kümenize izleme yüklenir. Hatta kümenizin izleme özelliği varsa adının Prometheus olacağını tahmin edecek kadar ileri giderdim.

Anlatacaklarım hem Prometheus operatörü için hem de saf haliyle teslim edilen Prometheus için geçerli olacaktır. Sorun şu ki, eğer kümeye bu kadar çabuk bir yönetici alamıyorsam, bu daha fazla bakmam gerektiği anlamına gelir. Ve sizin izlemenizin yardımıyla arama yapabilirim.

Muhtemelen herkes Habré hakkında aynı makaleleri okuyordur ve izleme, izleme ad alanında yer almaktadır. Dümen haritası herkes için kabaca aynı olarak adlandırılır. Sanırım, eğer helm install stable/prometheus'u kurarsanız, kabaca aynı isimlerle karşılaşacaksınız. Ve büyük olasılıkla kümenizdeki DNS adını tahmin etmem bile gerekmeyecek. Çünkü standart.

Kubernetes kümesindeki deliklerin düzeltilmesi. DevOpsConf'tan rapor ve transkript

Daha sonra belirli bir bölmeyi çalıştırabileceğiniz belirli bir dev ns'imiz var. Ve bu bölmeden şunun gibi bir şey yapmak çok kolaydır:

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

prometheus-kube-state-metrics, Kubernetes API'nin kendisinden ölçümler toplayan Prometheus dışa aktarıcılarından biridir. Orada çok fazla veri var, kümenizde ne çalışıyor, ne var, onunla ne gibi sorunlar yaşıyorsunuz.

Basit bir örnek olarak:

kube_pod_container_info{namespace=“kube-system”,pod=”kube-apserver-k8s- 1″,container=”kube-apserver”,image=

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

,image_id=»docker-pullable://gcr.io/google-containers/kube- apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

Ayrıcalıksız bir pod'dan basit bir curl isteği yaparak aşağıdaki bilgileri alabilirsiniz. Hangi Kubernetes sürümünü çalıştırdığınızı bilmiyorsanız size kolayca söyleyecektir.

Ve en ilginç olanı, kube-durum-metriklerine erişmenin yanı sıra, Prometheus'un kendisine de doğrudan kolayca erişebilmenizdir. Metrikleri oradan toplayabilirsiniz. Hatta oradan metrikler bile oluşturabilirsiniz. Teorik olarak bile, Prometheus'taki bir kümeden böyle bir sorgu oluşturabilirsiniz, bu da onu basitçe kapatacaktır. Ve izlemeniz kümeden çalışmayı tamamen bırakacaktır.

Ve burada herhangi bir harici izlemenin izlemenizi izleyip izlemediği sorusu ortaya çıkıyor. Kendim için herhangi bir sonuç olmadan bir Kubernetes kümesinde çalışma fırsatını yeni yakaladım. Artık herhangi bir izleme yapılmadığı için orada çalıştığımı bile bilmeyeceksin.

Tıpkı PSP'de olduğu gibi, sorun tüm bu süslü teknolojilerin (Kubernetes, Prometheus) işe yaramaması ve boşluklarla dolu olması gibi geliyor. Tam olarak değil.

Böyle bir şey var - Ağ Politikası.

Normal bir yöneticiyseniz, büyük olasılıkla Ağ Politikası hakkında bunun başka bir yaml olduğunu biliyorsunuzdur ve kümede zaten çok sayıda bulunmaktadır. Ve bazı Ağ Politikalarına kesinlikle ihtiyaç duyulmaz. Ve Ağ Politikasının ne olduğunu, bunun Kubernetes'in yaml güvenlik duvarı olduğunu okusanız bile, ad alanları arasındaki, bölmeler arasındaki erişim haklarını sınırlamanıza izin verir, o zaman kesinlikle Kubernetes'teki yaml formatındaki güvenlik duvarının sonraki soyutlamalara dayandığına karar vermişsinizdir. ... Hayır, hayır. Bu kesinlikle gerekli değildir.

Güvenlik uzmanlarınıza Kubernetes'inizi kullanarak çok kolay, basit ve çok ayrıntılı bir güvenlik duvarı oluşturabileceğinizi söylememiş olsanız bile. Eğer henüz bunu bilmiyorlarsa ve sizi rahatsız etmiyorlarsa: “Peki, ver bana, ver...” O zaman her durumda, kümenizden alınabilecek bazı hizmet yerlerine erişimi engellemek için Ağ Politikasına ihtiyacınız var. herhangi bir yetki olmadan.

Verdiğim örnekte olduğu gibi Kubernetes kümesindeki herhangi bir ad alanından kube durum metriklerini hiçbir hakka sahip olmadan çekebilirsiniz. Ağ politikaları, diğer tüm ad alanlarından izleme ad alanına erişimi kapatmıştır ve işte bu kadar: erişim yok, sorun yok. Hem standart Prometheus hem de operatördeki Prometheus olmak üzere mevcut tüm çizelgelerde, dümen değerlerinde basitçe onlar için ağ politikalarını etkinleştirme seçeneği vardır. Sadece açmanız gerekiyor ve çalışacaklar.

Burada gerçekten bir sorun var. Normal sakallı bir yönetici olarak büyük olasılıkla ağ politikalarına gerek olmadığına karar verdiniz. Habr gibi kaynaklarla ilgili her türlü makaleyi okuduktan sonra, flanel'in, özellikle de ana bilgisayar ağ geçidi modunda seçebileceğiniz en iyi şey olduğuna karar verdiniz.

Ne yapmalı?

Kubernetes kümenizde bulunan ağ çözümünü yeniden konuşlandırmayı, daha işlevsel bir şeyle değiştirmeyi deneyebilirsiniz. Örneğin aynı Calico için. Ancak Kubernetes çalışma kümesindeki ağ çözümünü değiştirme görevinin oldukça önemsiz olmadığını hemen söylemek istiyorum. Bunu iki kez çözdüm (ancak her ikisinde de teorik olarak), ancak Slurms'ta nasıl yapılacağını bile gösterdik. Öğrencilerimize Kubernetes kümesindeki ağ çözümünün nasıl değiştirileceğini gösterdik. Prensip olarak üretim kümesinde kesinti olmadığından emin olmaya çalışabilirsiniz. Ama muhtemelen başaramayacaksınız.

Ve sorun aslında çok basit bir şekilde çözüldü. Kümede sertifikalar var ve sertifikalarınızın süresinin bir yıl sonra dolacağını biliyorsunuz. Peki ve genellikle kümedeki sertifikalarla normal bir çözüm - neden endişeleniyoruz, yakınlarda yeni bir küme oluşturacağız, eskisinin çürümesine izin vereceğiz ve her şeyi yeniden konuşlandıracağız. Doğru, çürüdüğünde bir gün oturmak zorunda kalacağız ama işte yeni bir küme.

Yeni bir salkım yetiştirdiğinizde aynı zamanda flanel yerine Calico'yu takın.

Sertifikalarınız yüz yıl süreyle veriliyorsa ve kümeyi yeniden dağıtmayacaksanız ne yapmalısınız? Kube-RBAC-Proxy diye bir şey var. Bu çok güzel bir gelişme; kendisini Kubernetes kümesindeki herhangi bir bölmeye sepet konteyneri olarak yerleştirmenize olanak tanıyor. Ve aslında Kubernetes'in RBAC'ı aracılığıyla bu bölmeye yetkilendirme ekliyor.

Bir sorun var. Daha önce bu Kube-RBAC-Proxy çözümü operatörün Prometheus'unda yerleşik olarak bulunuyordu. Ama sonra gitmişti. Artık modern sürümler, bir ağ politikanızın olduğu ve bunları kullanarak kapattığınız gerçeğine güveniyor. Bu nedenle grafiği biraz yeniden yazmamız gerekecek. Aslında eğer gidersen bu depo, bunun sepet olarak nasıl kullanılacağına dair örnekler var ve grafiklerin minimum düzeyde yeniden yazılması gerekecek.

Küçük bir sorun daha var. Ölçülerini herkese dağıtan tek kişi Prometheus değil. Tüm Kubernetes kümesi bileşenlerimiz aynı zamanda kendi metriklerini de döndürebilmektedir.

Ancak daha önce de söylediğim gibi kümeye erişip bilgi toplayamıyorsanız en azından bir miktar zarar verebilirsiniz.

Bu yüzden bir Kubernetes kümesinin nasıl mahvolabileceğinin iki yolunu hızlıca göstereceğim.

Bunu size söylediğimde güleceksiniz, bunlar gerçek hayattan iki örnek.

Birinci yöntem. Kaynak tükenmesi.

Başka bir özel kapsül başlatalım. Şöyle bir bölüm olacak.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Bildiğiniz gibi istekler, isteklerin bulunduğu belirli pod'lar için ana makinede ayrılan CPU ve bellek miktarıdır. Bir Kubernetes kümesinde dört çekirdekli bir ana makinemiz varsa ve isteklerle birlikte dört CPU pod'u oraya ulaşırsa, bu, bu ana makineye artık istek içeren pod'ların gelemeyeceği anlamına gelir.

Böyle bir bölmeyi çalıştırırsam şu komutu çalıştıracağım:

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

O zaman başka hiç kimse Kubernetes kümesine dağıtım yapamayacak. Çünkü tüm düğümlerin istekleri tükenecek. Böylece Kubernetes kümenizi durduracağım. Bunu akşam yaparsam dağıtımları oldukça uzun bir süre durdurabilirim.

Kubernetes belgelerine tekrar baktığımızda Limit Range denilen şeyi göreceğiz. Küme nesneleri için kaynakları ayarlar. Yaml'de bir Sınır Aralığı nesnesi yazabilir, bunu belirli ad alanlarına uygulayabilir ve ardından bu ad alanında bölmeler için varsayılan, maksimum ve minimum kaynaklara sahip olduğunuzu söyleyebilirsiniz.

Böyle bir şeyin yardımıyla, ekiplerin belirli ürün ad alanlarındaki kullanıcıların kapsüllerinde her türlü kötü şeyi belirtme yeteneğini sınırlayabiliriz. Ama ne yazık ki kullanıcıya birden fazla CPU isteği ile pod başlatamayacaklarını söyleseniz bile o kadar harika bir ölçeklendirme komutu var ki ya da kontrol paneli üzerinden ölçeklendirme yapabiliyorlar.

Ve iki numaralı yöntemin geldiği yer burasıdır. 11 kapsülü fırlatıyoruz. Bu on bir milyar eder. Bu, böyle bir sayı bulduğum için değil, bunu kendim gördüğüm için.

Gerçek hikaye. Akşam geç saatlerde ofisten çıkmak üzereydim. Köşede oturan bir grup geliştiricinin çılgınca dizüstü bilgisayarlarıyla bir şeyler yaptığını görüyorum. Adamların yanına gidip soruyorum: "Sana ne oldu?"

Biraz daha erken, akşam saat dokuz civarında geliştiricilerden biri eve gitmeye hazırlanıyordu. Ve karar verdim: "Şimdi başvurumu bire indireceğim." Birine bastım ama internet biraz yavaşladı. Birine tekrar bastı, birine bastı ve Enter'a bastı. Yapabildiğim her şeyi dürttüm. Sonra İnternet canlandı ve her şey bu sayıya küçülmeye başladı.

Doğru, bu hikaye Kubernetes'te geçmedi; o zamanlar Nomad'dı. Nomad'ın ısrarlı ölçeklendirme girişimlerini durdurmaya yönelik girişimlerimizden bir saat sonra, Nomad'ın ölçeklendirmeyi durdurmayacağını ve başka hiçbir şey yapmayacağını söylemesiyle sona erdi. "Yoruldum, gidiyorum." Ve kıvrıldı.

Doğal olarak aynısını Kubernetes'te de yapmaya çalıştım. Kubernetes on bir milyar kapsülden memnun değildi ve şunları söyledi: "Yapamam. Dahili ağız koruyucularını aşıyor." Ancak 1 kapsül bunu yapabilir.

Bir milyara karşılık Küp kendi içine çekilmedi. Gerçekten ölçeklenmeye başladı. Süreç ilerledikçe yeni kapsüller yaratması da daha fazla zaman aldı. Ama yine de süreç devam etti. Tek sorun şu ki, eğer kendi ad alanımda sınırsız sayıda pod başlatabilirsem, o zaman istekler ve sınırlamalar olmadan bile bazı görevlerle o kadar çok pod başlatabilirim ki, bu görevlerin yardımıyla düğümler bellekte, CPU'da birikmeye başlayacaktır. Bu kadar çok kapsülü başlattığımda, onlardan gelen bilgilerin depoya gitmesi gerekiyor, yani vb. Ve oraya çok fazla bilgi ulaştığında depolama çok yavaş geri dönmeye başlar ve Kubernetes donuklaşmaya başlar.

Ve bir sorun daha... Bildiğiniz gibi Kubernetes'in kontrol öğeleri tek bir merkezi öğe değil, birkaç bileşenden oluşur. Özellikle bir denetleyici yöneticisi, zamanlayıcı vb. Vardır. Bütün bu adamlar aynı anda gereksiz, aptalca işler yapmaya başlayacaklar ve bu da zamanla giderek daha fazla zaman almaya başlayacak. Denetleyici yöneticisi yeni bölmeler oluşturacaktır. Zamanlayıcı onlar için yeni bir düğüm bulmaya çalışacaktır. Büyük ihtimalle kümenizdeki yeni düğümler yakında tükenecek. Kubernetes kümesi giderek daha yavaş çalışmaya başlayacak.

Ama daha da ileri gitmeye karar verdim. Bildiğiniz gibi Kubernetes'te servis diye bir şey var. Kümelerinizde varsayılan olarak hizmet büyük olasılıkla IP tablolarını kullanarak çalışır.

Örneğin bir milyar kapsül çalıştırırsanız ve ardından Kubernetis'i yeni hizmetler oluşturmaya zorlamak için bir komut dosyası kullanırsanız:

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

Kümenin tüm düğümlerinde, yaklaşık olarak aynı anda giderek daha fazla yeni iptables kuralı oluşturulacaktır. Üstelik her hizmet için bir milyar iptables kuralı oluşturulacak.

Bütün bunları birkaç binden on taneye kadar kontrol ettim. Ve sorun şu ki, zaten bu eşikte düğüme ssh yapmanın oldukça sorunlu olması. Çünkü pek çok zincirden geçen paketler pek iyi hissetmemeye başlıyor.

Ve bu da Kubernetes'in yardımıyla çözüldü. Böyle bir Kaynak kotası nesnesi var. Kümedeki ad alanı için kullanılabilir kaynak ve nesnelerin sayısını ayarlar. Kubernetes kümesinin her ad alanında bir yaml nesnesi oluşturabiliriz. Bu nesneyi kullanarak bu namespace için belli sayıda request ve limit ayırmış olduğumuzu söyleyebiliriz ve sonrasında bu namespace içerisinde 10 adet servis ve 10 adet pod oluşturmanın mümkün olduğunu söyleyebiliriz. Ve tek bir geliştirici en azından akşamları kendini boğabilir. Kubernetes ona şunu söyleyecektir: "Kaynak kotayı aştığı için kapsüllerinizi bu miktara ölçeklendiremezsiniz." İşte bu, sorun çözüldü. Belgeler burada.

Bu konuda sorunlu bir nokta ortaya çıkıyor. Kubernetes'te bir ad alanı oluşturmanın ne kadar zorlaştığını hissediyorsunuz. Bunu oluşturmak için birçok şeyi hesaba katmamız gerekiyor.

Kaynak kotası + Sınır Aralığı + RBAC
• Ad alanı oluşturun
• İçeride bir sınır aralığı oluşturun
• Kaynak kotası içinde oluşturun
• CI için bir hizmet hesabı oluşturun
• CI ve kullanıcılar için rol bağlama oluşturma
• İsteğe bağlı olarak gerekli servis bölmelerini başlatın

Bu nedenle bu fırsatı gelişmeleri paylaşmak için kullanmak istiyorum. SDK operatörü diye bir şey var. Bu, Kubernetes kümesinin kendisi için operatörler yazmasının bir yoludur. Ansible'ı kullanarak ifadeler yazabilirsiniz.

İlk başta Ansible'da yazılmıştı, sonra bir SDK operatörü olduğunu gördüm ve Ansible rolünü bir operatöre yeniden yazdım. Bu ifade, Kubernetes kümesinde komut adı verilen bir nesne oluşturmanıza olanak tanır. Bir komutun içinde, bu komutun ortamını yaml'de tanımlamanıza olanak tanır. Ve ekip ortamında bu kadar çok kaynak ayırdığımızı açıklamamıza olanak tanıyor.

Minyon tüm bu karmaşık süreci kolaylaştırmak.

Ve sonuç olarak. Bütün bunlarla ne yapmalı?
Birinci. Pod Güvenlik Politikası iyidir. Ve bugüne kadar hiçbir Kubernetes yükleyicisinin bunları kullanmamasına rağmen, bunları hâlâ kümelerinizde kullanmanız gerekiyor.

Ağ Politikası yalnızca gereksiz bir özellik değildir. Bir kümede gerçekten ihtiyaç duyulan şey budur.

LimitRange/ResourceQuota - onu kullanmanın zamanı geldi. Bunu uzun zaman önce kullanmaya başladık ve uzun süre herkesin kullandığından emindim. Bunun nadir olduğu ortaya çıktı.

Raporda bahsettiklerime ek olarak, kümeye saldırmanızı sağlayan belgelenmemiş özellikler de var. Yakın zamanda yayınlandı Kubernetes güvenlik açıklarının kapsamlı analizi.

Bazı şeyler çok üzücü ve acı verici. Örneğin, belirli koşullar altında bir Kubernetes kümesindeki küpler, warlocks dizininin içeriğini yetkisiz bir kullanıcıya verebilir.

Burada Size söylediğim her şeyi nasıl çoğaltacağınıza dair talimatlar var. ResourceQuota ve Pod Güvenlik Politikasının neye benzediğine ilişkin üretim örnekleri içeren dosyalar vardır. Ve tüm bunlara dokunabilirsiniz.

Hepinize teşekkürler.

Kaynak: habr.com

Yorum ekle