Kubeadm: Mendokumentasikan penggunaan kubeadm dengan SELinux

Dibuat pada 29 Mei 2017  ·  77Komentar  ·  Sumber: kubernetes/kubeadm

Apakah ini LAPORAN BUG atau PERMINTAAN FITUR?

Pilih salah satu: LAPORAN BUG atau PERMINTAAN FITUR

PERMINTAAN KOMUNITAS

Versi

Semua

Kami memerlukan pengujian e2e yang memastikan kubeadm berfungsi dengan SELinux di CentOS / Fedora (https://github.com/kubernetes/kubeadm/issues/215) dan CoreOS (https://github.com/kubernetes/kubeadm/issues/269)

Kami mungkin bisa menambahkan pekerjaan untuk itu di kubernetes- everywhere @pipejakob ?

Kubeadm IIUC rusak dengan SELinux diaktifkan sekarang. Masalahnya adalah kami tidak memiliki satu (AFAIK) yang sangat berpengalaman dengan SELinux di tim kubeadm (setidaknya belum ada yang punya waktu untuk memeriksanya)

AFAIK, masalahnya sering kali saat memasang volume hostPath ...

Untuk lebih mendekati kesiapan produksi, kita harus memperbaiki ini dan menambahkan rangkaian pengujian untuknya.
Kami juga harus bekerja dengan penyedia jaringan CNI untuk memastikan mereka juga mengadopsi kebijakan SELinux yang benar.

Ada yang mau mengambil alih kepemilikan di sini? Saya tidak terlalu berpengalaman dengan SELinux, jadi saya mungkin akan fokus pada hal-hal lain.

@dgoodwin @aaronlevy @coeki @rhatdan @philips @bboreham @mikedanese @pipejakob

areecosystem help wanted kindocumentation lifecyclfrozen prioritbacklog

Komentar yang paling membantu

Saya tidak bekerja dengan kubadmin tetapi akan sangat bersedia membantu siapa pun yang melakukan ini.

Semua 77 komentar

@pipejakob Saya menambahkan label kind/postmortem karena bertema sama, kami merusak pengguna SELinux lagi tanpa menyadarinya ...

Saya tidak bekerja dengan kubadmin tetapi akan sangat bersedia membantu siapa pun yang melakukan ini.

@rhatdan Hebat! Yang saya cari adalah orang-orang yang akrab dengan SELinux dan bersedia membantu.
Saya mungkin bisa mengoordinasikan pekerjaan itu.

Daftar rencana kasar akan terlihat seperti ini:

  • Jadikan kubeadm berfungsi dengan SELinux diaktifkan di v1.7
  • Buat suite e2e dari node CentOS / Fedora yang akan memberi tahu kami jika ada regresi.
  • Pelajari masalah CoreOS dan perbedaan penyiapan SELinux antara CentOS dan CoreOS.

@rhatdan Mari pertama mencoba dan membuatnya bekerja di v1.7, bisa dilakukan di # 215

@tokopedia

Saya akan mengambilnya untuk saat ini, karena saya membesarkannya. Saya akan segera memiliki beberapa pembaruan, @rhatdan , mohon beri tahu saya;)

@luxas , @jasonbrooks - apakah ini masih ada di fedora?

Saya pikir orang-orang telah menambal kebijakan di saluran lain.

/ cc @eparis

@timothysc Saya belum mencoba w / 1.7, tetapi w / 1.6, CentOS bekerja dengan selinux tetapi Fedora 25 tidak. Saya akan menguji w / 1.7

untuk referensi, saya baru saja menjalankan kubeadm 1.7 di f26 dalam mode permisif, dan ini adalah penolakan yang saya dapatkan:

[root@fedora-1 ~]# ausearch -m avc -ts recent
----
time->Tue Jul 11 13:03:50 2017
type=AVC msg=audit(1499792630.959:321): avc:  denied  { read } for  pid=2885 comm="kube-apiserver" name="apiserver.crt" dev="dm-0" ino=16820634 scontext=system_u:system_r:container_t:s0:c171,c581 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file permissive=1
----
time->Tue Jul 11 13:03:50 2017
type=AVC msg=audit(1499792630.959:322): avc:  denied  { open } for  pid=2885 comm="kube-apiserver" path="/etc/kubernetes/pki/apiserver.crt" dev="dm-0" ino=16820634 scontext=system_u:system_r:container_t:s0:c171,c581 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file permissive=1
----
time->Tue Jul 11 13:04:18 2017
type=AVC msg=audit(1499792658.917:331): avc:  denied  { read } for  pid=2945 comm="kube-controller" name="sa.key" dev="dm-0" ino=16820637 scontext=system_u:system_r:container_t:s0:c755,c834 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file permissive=1
----
time->Tue Jul 11 13:04:18 2017
type=AVC msg=audit(1499792658.917:332): avc:  denied  { open } for  pid=2945 comm="kube-controller" path="/etc/kubernetes/pki/sa.key" dev="dm-0" ino=16820637 scontext=system_u:system_r:container_t:s0:c755,c834 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file permissive=1

Di CentOS 7, hal yang sama, tidak ada penyangkalan.

Anda meningkatkan volume konten dari host ke dalam wadah. Jika Anda ingin proses terbatas SELinux di dalam container untuk dapat membaca konten, itu harus memiliki label SELinux yang diizinkan untuk dibaca oleh container tersebut.

Memasang objek dengan: Z atau: z akan menyelesaikan masalah. Perhatikan salah satu dari ini akan memungkinkan wadah untuk menulis objek ini. Jika Anda ingin mengizinkan penampung untuk membaca tanpa menulis, Anda dapat mengubah konten pada host menjadi sesuatu seperti container_share_t.

https://github.com/kubernetes/kubernetes/pull/48607 juga akan membantu di sini karena mulai membuat semua mount kecuali etcd read-only ...

@luxas @jasonbrooks - seseorang ingin bermain-main dengan menyesuaikan manifes (https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)?

Bagi saya, tidak jelas kebijakan mana yang harus ditambahkan oleh kubeadm:

  • hanya baca tunggangan
  • baca tulis tunggangan

yang bekerja di CentOS, Fedora _and_ CoreOS

Pada 12 Juli 2017, pada 16:57, Timothy St. Clair [email protected] menulis:

@luxas @jasonbrooks - seseorang ingin bermain-main dengan menyesuaikan manifes (https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)?

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub, atau nonaktifkan utasnya.

@rhatdan Sepertinya: Z hanya digunakan jika pod menyediakan label selinux. Dalam pengujian awal saya, container_runtime_t tampaknya berfungsi - apakah itu label yang sesuai? Dan kemudian, saya berasumsi dalam sistem tanpa selinux, ini akan diabaikan begitu saja?

Ya itu akan diabaikan oleh sistem non SELinux. Menjalankan aplikasi sebagai container_runtime_t, pada dasarnya tidak menyediakan kurungan SELinux, karena ini seharusnya menjadi label runtime container seperti buruh pelabuhan dan CRI-O. Jika Anda menjalankan kublet seperti ini, itu mungkin cukup akurat.

Saat ini, kami menjalankan container etcd sebagai spc_t - apakah lebih baik menjalankan container tersebut sebagai container_runtime_t juga?

Sepertinya ini yang melakukannya:

diff --git a/cmd/kubeadm/app/master/manifests.go b/cmd/kubeadm/app/master/manifests.go
index 55fe560c46..228f935cdd 100644
--- a/cmd/kubeadm/app/master/manifests.go
+++ b/cmd/kubeadm/app/master/manifests.go
@@ -96,6 +96,7 @@ func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
                        LivenessProbe: componentProbe(int(cfg.API.BindPort), "/healthz", api.URISchemeHTTPS),
                        Resources:     componentResources("250m"),
                        Env:           getProxyEnvVars(),
+                        SecurityContext: &api.SecurityContext{SELinuxOptions: &api.SELinuxOptions{Type: "container_runtime_t",}},
                }, volumes...),
                kubeControllerManager: componentPod(api.Container{
                        Name:          kubeControllerManager,
@@ -105,6 +106,7 @@ func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
                        LivenessProbe: componentProbe(10252, "/healthz", api.URISchemeHTTP),
                        Resources:     componentResources("200m"),
                        Env:           getProxyEnvVars(),
+                        SecurityContext: &api.SecurityContext{SELinuxOptions: &api.SELinuxOptions{Type: "container_runtime_t",}},
                }, volumes...),
                kubeScheduler: componentPod(api.Container{
                        Name:          kubeScheduler,

Apakah ini sesuatu untuk diserahkan sebagai PR ke cabang 1.7 dan untuk dikuasai, atau hanya untuk dikuasai? Sumbernya berpindah-pindah sedikit di master, tambalan di atas adalah ke cabang 1.7.

Saya sebenarnya lebih suka menjalankannya sebagai spc_t, atau sebagai domain terbatas (container_t). etcd harus dapat dengan mudah dibatasi oleh SELinux.

Saya pikir spc_t seharusnya berfungsi. Saya mencoba w / container_t dan tidak berhasil. audit2allow mengatakan itu membutuhkan:

allow container_t cert_t:file { open read };

Bisakah kita memberi label ulang direktori certs dengan container_file_t atau container_share_t. maka itu akan berhasil.

kubeadm membuat /etc/kubernetes/pki dir ketika Anda menjalankan kubeadm init , tetapi ketika Anda kubeadm reset , itu hanya mengosongkan direktori itu. Jika kita membuat dir pki saat rpm diinstal, kita dapat melakukan pelabelan pada saat itu, dengan memodifikasi file spesifikasi.

Untuk etcd, penampung akan membutuhkan allow container_t container_var_lib_t:file { create lock open read unlink write }; untuk /var/lib/etcd pada host.

Saya mencoba mencari tahu apakah sah menggunakan direktori chcon di file spesifikasi rpm - Saya melihat banyak contoh di github (https://github.com/search?l=&p=1&q=chcon+extension%3Aspec ) tetapi saya tidak tahu apakah itu dianggap praktik pengemasan yang baik atau tidak. Kita bisa mengubah kubeam untuk menjalankan komponen sebagai spc_t, tidak dibatasi, atau kita bisa membiarkan kubeadm dan chcon dir pki.

Saya tidak begitu paham dengan Arsitektur Kubernetes, sebagaimana seharusnya. Tetapi apakah kita berbicara tentang wadah yang berbeda atau wadah yang sama. wadah kubeadmin versus wadah etcd? Penampung pengelolaan yang dapat meluncurkan penampung lain sebagai "hak istimewa" harus berjalan sebagai spc_t, karena membatasinya tidak memberi kita apa-apa. Layanan yang hanya mendengarkan di jaringan dan membagikan data di sisi lain, dapat dijalankan dengan lebih banyak batasan.

kubeadm didistribusikan sebagai paket deb atau rpm, dan bergantung pada kubelet dan paket cni (dan pada buruh pelabuhan). Anda memulai kubelet, dan kemudian Anda menjalankan kubeadm, yang membuat manifes untuk etcd, apiserver, controller manager, scheduler dan proxy, dan semuanya dijalankan sebagai kontainer. Itulah cara utama menjalankan kubeadm, seperti yang dijelaskan di sini: https://kubernetes.io/docs/setup/independent/install-kubeadm/

Saya telah bereksperimen dengan menjalankan kubeadm sebagai wadah sistem, juga: http://www.projectatomic.io/blog/2017/05/testing-system-containerized-kubeadm/

Ok Itulah yang saya pikirkan. Jika kita membagi semua layanan ini ke dalam wadah sistem yang berbeda atau wadah yang diatur, beberapa mungkin dapat berjalan terbatas dan beberapa perlu dijalankan dengan ull privs. kubeadmin sebagai alat untuk administrator harus dijalankan dengan privs penuh. spc_t, jika dijalankan di dalam container, jika dijalankan di luar, ia akan dijalankan sebagai label administrator.

Jika semua layanan ini berjalan dalam wadah yang sama, maka mereka mungkin harus berjalan sebagai hak istimewa.

Semuanya berjalan dalam wadah terpisah. Mereka dapat dijalankan sebagai container_t, tetapi apiserver dan manajer pengontrol perlu membuka dan membaca cert_t, dan etcd membutuhkan akses ke container_var_lib_t.

Kita dapat membuat dirs / etc / kubernetes / pki dan / var / lib / etcd dan mengatur konteksnya ke container_share_t di file spesifikasi untuk kubeadm rpm, atau kita dapat membuat wadah apiserver dan controller manager dijalankan sebagai spc_t (seperti etcd container tidak sekarang), dan membuatnya berfungsi, tetapi tanpa batasan, atau mungkin membuat semacam kebijakan kustom atau semacamnya.

Bagaimana menurut Anda, @rhatdan

Seperti yang dijelaskan oleh @jasonbrooks, kami memiliki beberapa opsi di sini. Tapi itu bukan yang utama.

Yang utama adalah, di mana kita menyimpan rahasia ... Saya pikir konsensusnya adalah menyimpan CA dan hal-hal dalam rahasia kubernetes, jadi hanya spc_t yang diperlukan untuk etcd

@luxas @timothysc @jbeda

Masalah menjadi basi setelah 90 hari tidak aktif.
Tandai terbitan sebagai baru dengan /remove-lifecycle stale .
Masalah basi membusuk setelah 30 hari tambahan tidak aktif dan akhirnya ditutup.

Cegah masalah dari penutupan otomatis dengan komentar /lifecycle frozen .

Jika masalah ini aman untuk ditutup sekarang, lakukan dengan /close .

Kirim umpan balik ke sig-testing, kubernetes / test-infra dan / atau @fejta .
/ siklus hidup basi

/ siklus hidup dibekukan

/cc @detiber

Hai, saya masih punya masalah dengan SELinux ketika saya menjalankan kubeadm init

audit2allow -a -w
type=AVC msg=audit(1522929610.297:136): avc:  denied  { write } for  pid=2817 comm="etcd" name="etcd" dev="dm-0" ino=67228425 scontext=system_u:system_r:svirt_lxc_net_t:s0:c430,c632 tcontext=system_u:object_r:var_lib_t:s0 tclass=dir

Versons:

  • kubeadm 1.9.3
  • CentOS 7.4

Sepertinya direktori di / var / lib / etcd? Apakah volume dipasang ke dalam wadah tanpa label SELinux yang benar di atasnya.
Memasang ini dengan ekuivalen: Z akan memperbaikinya atau
chcon -R -v svirt_sandbox_file_t / var / lib / etcd

Dan kemudian itu harus berhasil.

/ tetapkan @detiber

Saya menduga kami dapat menangani ini dengan menyetel konteks keamanan pada definisi pod statis jika diperlukan (dan hanya secara bersyarat berdasarkan apakah selinux diaktifkan pada host).

Saya yakin runtime kontainer akan mengabaikan konteks keamanan jika host tidak diaktifkan.

ref # 1026 # 1082

Ketika mencoba untuk mereproduksi masalah dengan CentOS terbaru saya melihat bahwa server API tidak dapat memuat sertifikatnya jika SELinux diatur dalam mode pemberlakuan.

Ini komentar saya:
https://github.com/kubernetes/kubeadm/issues/1082#issuecomment -416991032

Pesan AVC?

ausearch -m avc -ts baru-baru ini

@hhhhhhhhhhhh

time->Fri Aug 31 11:47:18 2018
type=PROCTITLE msg=audit(1535705238.732:281): proctitle=6B7562652D617069736572766572002D2D617574686F72697A6174696F6E2D6D6F64653D4E6F64652C52424143002D2D6164766572746973652D616464726573733D3139322E3136382E3231372E313333002D2D616C6C6F772D70726976696C656765643D74727565002D2D636C69656E742D63612D66696C653D2F6574632F
type=SYSCALL msg=audit(1535705238.732:281): arch=c000003e syscall=257 success=no exit=-13 a0=ffffffffffffff9c a1=c420427a10 a2=80000 a3=0 items=0 ppid=4525 pid=4541 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="kube-apiserver" exe="/usr/local/bin/kube-apiserver" subj=system_u:system_r:container_t:s0:c224,c932 key=(null)
type=AVC msg=audit(1535705238.732:281): avc:  denied  { read } for  pid=4541 comm="kube-apiserver" name="apiserver.crt" dev="dm-0" ino=604382 scontext=system_u:system_r:container_t:s0:c224,c932 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file
----
time->Fri Aug 31 11:47:26 2018
type=PROCTITLE msg=audit(1535705246.653:285): proctitle=65746364002D2D6164766572746973652D636C69656E742D75726C733D68747470733A2F2F3132372E302E302E313A32333739002D2D636572742D66696C653D2F6574632F6B756265726E657465732F706B692F657463642F7365727665722E637274002D2D636C69656E742D636572742D617574683D74727565002D2D6461
type=SYSCALL msg=audit(1535705246.653:285): arch=c000003e syscall=257 success=no exit=-13 a0=ffffffffffffff9c a1=c420195d70 a2=80000 a3=0 items=0 ppid=4594 pid=4609 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="etcd" exe="/usr/local/bin/etcd" subj=system_u:system_r:container_t:s0:c315,c1002 key=(null)
type=AVC msg=audit(1535705246.653:285): avc:  denied  { read } for  pid=4609 comm="etcd" name="peer.crt" dev="dm-0" ino=102172270 scontext=system_u:system_r:container_t:s0:c315,c1002 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file
----
time->Fri Aug 31 11:52:29 2018
type=PROCTITLE msg=audit(1535705549.708:291): proctitle=6B7562652D617069736572766572002D2D617574686F72697A6174696F6E2D6D6F64653D4E6F64652C52424143002D2D6164766572746973652D616464726573733D3139322E3136382E3231372E313333002D2D616C6C6F772D70726976696C656765643D74727565002D2D636C69656E742D63612D66696C653D2F6574632F
type=SYSCALL msg=audit(1535705549.708:291): arch=c000003e syscall=257 success=no exit=-13 a0=ffffffffffffff9c a1=c4205c5800 a2=80000 a3=0 items=0 ppid=4839 pid=4855 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="kube-apiserver" exe="/usr/local/bin/kube-apiserver" subj=system_u:system_r:container_t:s0:c224,c932 key=(null)
type=AVC msg=audit(1535705549.708:291): avc:  denied  { read } for  pid=4855 comm="kube-apiserver" name="apiserver.crt" dev="dm-0" ino=604382 scontext=system_u:system_r:container_t:s0:c224,c932 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file
----
time->Fri Aug 31 11:52:36 2018
type=PROCTITLE msg=audit(1535705556.661:295): proctitle=65746364002D2D6164766572746973652D636C69656E742D75726C733D68747470733A2F2F3132372E302E302E313A32333739002D2D636572742D66696C653D2F6574632F6B756265726E657465732F706B692F657463642F7365727665722E637274002D2D636C69656E742D636572742D617574683D74727565002D2D6461
type=SYSCALL msg=audit(1535705556.661:295): arch=c000003e syscall=257 success=no exit=-13 a0=ffffffffffffff9c a1=c420195d70 a2=80000 a3=0 items=0 ppid=4907 pid=4922 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="etcd" exe="/usr/local/bin/etcd" subj=system_u:system_r:container_t:s0:c315,c1002 key=(null)
type=AVC msg=audit(1535705556.661:295): avc:  denied  { read } for  pid=4922 comm="etcd" name="peer.crt" dev="dm-0" ino=102172270 scontext=system_u:system_r:container_t:s0:c315,c1002 tcontext=unconfined_u:object_r:cert_t:s0 tclass=file

Anda menaikkan volume beberapa konten di / etc / pki ke dalam container?

Ya, di /etc/kubernetes/pki . Begitulah cara kerja kubeadm.

Jika tidak ada proses terbatas lain yang membaca file-file ini selain kontainer, maka Anda dapat me-mountnya menggunakan: z, atau chcon -t container_share_t -R / etc / kubernetes / pki

Terima kasih @rhatdan Saya akan mencobanya minggu depan.

Kami juga memiliki kubelet yang membaca sertifikat, yang tidak dimasukkan ke dalam container. Ada lagi yang dibutuhkan untuk @rhatdan itu?

Label apa yang dijalankan oleh sublet?

ps -eZ | grep kublet

system_u:system_r:unconfined_service_t:s0 31110 ? 00:00:01 kubelet

Ah, oke ini masuk akal sekarang. Juga menghubungkan https://bugzilla.redhat.com/show_bug.cgi?id=1546160 untuk wisatawan lain.

Terima kasih.

Karena ini berjalan sebagai layanan yang tidak dibatasi, maka tidak akan ada masalah membaca label pada konten jika diberi label container_file_t.

Terima kasih Dan.

Jadi, https://github.com/kubernetes/kubernetes/pull/68448 mendapatkan node yang diinisialisasi kubeadm yang bekerja di Fedora 28 dengan Docker + SELinux dengan container yang dibatasi setidaknya container_t , dengan satu perintah manual tambahan.

Saya memiliki sejumlah pertanyaan tentang apa yang harus kami lakukan (yang harus ditunda hingga setelah 1.12):

  • Haruskah kita mendapatkan perubahan yang dilakukan pada hulu kontainer-selinux atau kebijakan kapal dalam paket kubeadm kita

    • Kami memiliki peringatan seputar fakta bahwa direktori data etcd dan direktori sertifikat dapat dikonfigurasi pada saat run-time.

  • PR menggunakan opencontainers/selinux hanya untuk menulis atribut yang diperluas pada sertifikat dan dir data etcd.

    • Haruskah ini benar-benar diterapkan dengan semanage fcontext + restorecon ?

  • Haruskah kita menerapkan PodSecurityPolicies, khususnya ke direktori sertifikat, sehingga setiap komponen inti memiliki share privat.

    • Akan membutuhkan pemisahan lebih lanjut dari sertifikat menjadi direktori per komponen, setidaknya untuk kunci privat.

  • Saya harus menerapkan secara manual container_file_t menjadi /opt/cni/bin karena praktik sebagian besar plugin CNI saat ini adalah memasangnya dan kemudian menulis plugin mereka ke direktori host tersebut.

    • /opt/cni/bin bukan masalah kubeadm, jadi belum menyentuhnya di sini.

    • Lingkungan yang tertarik dengan SELinux mungkin tidak menginginkan /opt/cni/bin memiliki hal-hal yang tidak berasal dari RPM.

  • Kami membutuhkan e2e
Should we get changes made to container-selinux upstream or ship policies in our kubeadm package

Mungkin akan lebih baik untuk memasukkannya ke dalam container-selinux, setidaknya meminta saya memeriksanya.

    We have caveats around the fact that both the etcd data directory and certificate directory are configurable at run-time.

The PR uses opencontainers/selinux to just write the extended attributes on certs and the etcd data dir.

    Should this actually be applied with semanage fcontext + restorecon ?

Ya, itu yang terbaik, meskipun jika semua orang setuju tentang ini, kami dapat memasukkan mereka ke dalam paket upstream. Haruskah file-file ini dibagikan hanya baca atau Baca / tulis?

Should we apply PodSecurityPolicies, particularly to the certificates directory, such that each of the core components then have private shares.

    Would require further split out of certificates into directories per component, at least for the private key.

Saya tidak punya ide.

I had to manually apply container_file_t to /opt/cni/bin as the current practice of most CNI plugins is to mount it and then write their plugins into that host directory.

Proses container_t harus dapat membaca / menjalankan label default pada file / direktori ini, Apakah Anda ingin mengizinkan container untuk menulis ke direktori ini?

$ matchpathcon /opt/cni/bin
/opt/cni/bin    system_u:object_r:bin_t:s0
$ sesearch -A -s container_t -t bin_t -c file
allow domain base_ro_file_type:file { getattr ioctl lock open read };
allow svirt_sandbox_domain exec_type:file { entrypoint execute execute_no_trans getattr ioctl lock map open read };

Terima kasih. Saya akan melihat apa yang harus dilakukan untuk container-selinux minggu depan.

Proses container_t harus dapat membaca / menjalankan label default pada file / direktori ini, Apakah Anda ingin mengizinkan container untuk menulis ke direktori ini?

Sayangnya ya. Cara kerja sebagian besar plugin CNI sekarang dalam manifes defaultnya, mereka menggunakan wadah init untuk mengunduh plugin CNI mereka dan menyimpannya di /opt/cni/bin untuk digunakan kubelet, meskipun RPM CNI kami mungkin sudah memilikinya sehingga mereka dapat mencocokkan versi plugin CNI yang digunakan dengan bidang kontrol lainnya.

Di sisi lain, saya rasa saya dapat mempersempit akses tulis ke hanya etcd untuk direktori data, dan kubelet yang tersisa tanpa batasan dapat melakukan rotasi sertifikatnya seperti biasa.

Fakta bahwa CNI RPM memasukkan barang ke /opt tetap bermasalah untuk Atomic Host , jadi mungkin kita perlu menangani dukungan CentOS / Fedora secara lebih luas?

@timothysc tahukah Anda jika pekerjaan ini telah / dijadwalkan untuk siklus 1,15?

@ DanyC97 bukan

@rcythr membuat beberapa penemuan terbaru WRT ke dukungan selinux di sini:
https://github.com/kubernetes/kubeadm/issues/1654

kami cenderung mendokumentasikan cara-cara mengaktifkan selinux di dokumen penyiapan kami.

Ringkasan singkat masalah:

Pada sistem selinux semua file dan proses ditandai dengan label selinux, dan kebijakan dipasang untuk menentukan jenis label mana yang dapat berinteraksi satu sama lain. Docker dan runtime lain yang mendukung selinux menjalankan containernya dengan konteks seperti system_u: system_r: container_t: s0: ... Ada aturan tertentu tentang apa yang dapat dilakukan proses container_t, dan ada dua aturan bermasalah yang saya sadari saat ini:

  1. itu tidak dapat berinteraksi dengan file jenis cert_t (yaitu sertifikat dan kunci)
  2. itu tidak bisa menulis ke / var / lib / direktori

Biasanya, saat bekerja secara langsung dengan buruh pelabuhan Anda bisa memasang volume dengan flag: z atau: Z, yang secara otomatis akan memberi label ulang pada file sebelum dipasang sehingga kontainer dapat membacanya. Dalam kasus ini, saya tidak dapat berasumsi bahwa buruh pelabuhan sedang digunakan karena runtime lain harus didukung.

Solusi awal saya
Saya memberi label ulang pada direktori _ / etc / kubernetes_ dan direktori _ / var / lib / etcd / _ dengan tipe yang dapat dibaca dan ditulis oleh semua container dengan tipe container_t (svirt_sandbox_file_t). Ini sebagian besar berfungsi, tetapi tidak semua direktori yang dipasang dapat diberi label ulang seperti ini tanpa merusak sistem (misalnya _ / etc / pki_).

Solusi terbaik yang saya miliki saat ini
Saya perhatikan bahwa karena kubelet tidak dalam container, ia berjalan dengan tipe system_u: system_r: unconfined_service_t: s0 , jadi saya memutuskan untuk mencari container-selinux yang setara (yang ternyata spc_t ). Saya menambahkan yang berikut ini ke file manifes untuk semua 4 pod:

securityContext:
  seLinuxOptions:
    user: "system_u"
    role: "system_r"
    type: "spc_t"
    level: "s0"

Solusi ini sangat bagus karena cukup melemaskan selinux untuk memungkinkan sistem ini bekerja, tetapi tidak memengaruhi sistem non-selinux sama sekali. Solusi serupa (tapi lebih buruk) akan menetapkan "privileged: true", yang akan bekerja untuk alasan yang sama persis, tetapi akan mengurangi keamanan untuk semua pengguna (termasuk yang selinux karena peningkatan kemampuan yang diberikan ke wadah yang diistimewakan).

Namun, solusi ini bukan _perfect_ karena sedikit banyak memperbaiki masalah dengan menonaktifkan manfaat selinux untuk wadah layanan ini. Ini pada dasarnya setara dengan memanggil setenforce 0 hanya untuk

terima kasih atas investigasi mendetail @rcythr

Namun, solusi ini tidak sempurna karena sedikit banyak memperbaiki masalah dengan menonaktifkan manfaat selinux untuk wadah layanan ini. Ini pada dasarnya setara dengan memanggil setenforce 0 hanya untuk 4 kontainer ini.

itu masih jauh lebih baik daripada mematikan selinux untuk node sepenuhnya.
solusi ini memungkinkan kita untuk mengizinkan control-plane dan etcd untuk menyebarkan selinux tanpa mengganggu operasi mereka, namun bagaimana dengan beban kerja pengguna?

saya kira kita masih perlu mendokumentasikan penambahan securityContext .

@detiber @tips_indonesia

PS. Saya juga bertanya-tanya apakah masih ada sisa gotcha di sini.

Beban kerja pengguna akan mendapatkan tipe biasa system_u: system_r: container_t: s0: .... Catatan: ... diperlukan karena MCS.

Gotcha paling terkenal yang saya sadari saat ini adalah bahwa menurut pengalaman saya, beberapa plugin jaringan pod akan langsung hilang saat mereka mencoba memulai dengan selinux diaktifkan. Saya memiliki masalah serupa yang terbuka dengan calico untuk mengatasi masalah ini. Ini perbaikan yang agak kasar, tetapi seharusnya berhasil. https://github.com/projectcalico/calico/issues/2704

Demikian pula, aplikasi pengguna mungkin dibuat tanpa memikirkan selinux, dan akan rusak. Cara mudah untuk mengujinya adalah dengan menjalankan sementara pod / container yang melanggar "privledged: true" dan melihat apakah pod tiba-tiba mulai berfungsi dengan baik. Kemudian mereka dapat mengangkat masalah / PR dengan pengembang penampung yang rusak untuk meminta mereka, dengan baik, untuk mendukung selinux.

Plugin CNI yang gagal bisa menjadi masalah. Yang paling populer yang kami dapat dari survey adalah Flanel, Calico, Weave dan sisanya lumayan menyebar.

Sudahkah Anda mencoba menenun atau flanel dengan selinux?

tetapi bagaimanapun, kami harus mendokumentasikan kasus selinux untuk beban kerja pengguna dan CNI.

kembali ke proposal untuk manifestasi kubeadm.
saya lupa menyebutkan bahwa kami memiliki rencana untuk menjalankan kontainer ini sebagai non-root, sangat mungkin dalam jangka waktu 1,16, apakah itu akan mengubah perilaku selinux?

cc @randomvariable

Plugin CNI yang gagal bisa menjadi masalah. Yang paling populer yang kami dapat dari survey adalah Flanel, Calico, Weave dan sisanya lumayan menyebar.

Sudahkah Anda mencoba menenun atau flanel dengan selinux?

Tidak, tapi saya akan mencobanya dan melihat apakah itu berhasil atau tidak.

tetapi bagaimanapun, kami harus mendokumentasikan kasus selinux untuk beban kerja pengguna dan CNI.

Sepakat. Peringatan tentang apa yang mungkin terjadi jika dibiarkan dalam penegakan tentu sangat membantu. Pengguna yang ingin tetap menerapkannya mungkin tidak akan peduli jika beberapa aplikasi userspace gagal - kemungkinan besar ini adalah grup yang sama yang akan memerlukan wadah non-root (termasuk saya sendiri). CNI lebih bermasalah, tetapi saya menduga sebagian besar plugin CNI akan sangat senang menerima patch selinux;)

kembali ke proposal untuk manifestasi kubeadm.
saya lupa menyebutkan bahwa kami memiliki rencana untuk menjalankan kontainer ini sebagai non-root, sangat mungkin dalam jangka waktu 1,16, apakah itu akan mengubah perilaku selinux?

Saya baru saja melakukan tes cepat menggunakan bitnami / nginx yang saya tahu berjalan sebagai non-root.

system_u:system_r:container_t:s0:c615,c897 1001 18714 0.5  0.0 26860 3280 ?    Ss   18:47   0:00 nginx: master process /opt/bitnami/nginx/sbin/nginx -c /opt/bitnami/nginx/conf/nginx.conf -g daemon off;

Konteks selinux sama seperti jika dijalankan sebagai root; Namun, kita harus berhati-hati karena saya menduga hal ini dapat berubah di masa mendatang. Saat ini satu-satunya perbedaan adalah pid 1001, bukan 0. Akibatnya, mengubah container ini untuk dijalankan sebagai non-root seharusnya tidak merusak perbaikan ini karena hak istimewa spc_t adalah superset dari hak istimewa container_t.

tetapi saya curiga sebagian besar plugin CNI akan sangat senang menerima patch selinux;)

ya, semoga.

Konteks selinux sama seperti jika dijalankan sebagai root; Namun, kita harus berhati-hati karena saya menduga hal ini dapat berubah di masa mendatang. Saat ini satu-satunya perbedaan adalah pid 1001, bukan 0. Akibatnya, mengubah container ini untuk dijalankan sebagai non-root seharusnya tidak merusak perbaikan ini karena hak istimewa spc_t adalah superset dari hak istimewa container_t.

Ok terima kasih. itu menyenangkan untuk diketahui.

Ini tambalan yang saya masak sejauh ini. Tampaknya menghasilkan manifestasi yang benar. https://github.com/rcythr/kubernetes/commit/fb6c0248488af2b3a54ceb638e29db84ae0530bf

Saya akan membuat PR setelah saya menguji beberapa hal lain dan setelah menandatangani CLA - saya saat ini memiliki tiket dukungan dengan CNCF karena masalah email.

Tiga hal yang saat ini ingin saya uji:

  1. Saya ingin mempertimbangkan untuk menggabungkan beberapa perubahan oleh @randomvariable untuk lebih membatasi beberapa wadah, jika memungkinkan. Saya yakin perubahannya akan memungkinkan kita untuk membatasi kube-scheduler dan etcd dengan ketat; akan tetapi, karena kita tidak dapat melabel ulang / etc / ssl / certs atau / etc / pki tanpa merusak sistem, kita tidak dapat membatasi kube-apiserver atau kube-controller-manager lebih ketat dari spc_t. Kita perlu membuat tipe khusus untuk mereka, berhenti menggunakan dua direktori sistem ini, atau hanya menggunakan tipe spc_t .
  2. Melihat sejarah tiket ini, saya melihat beberapa obrolan tentang masalah dengan spc_t di CoreOS. Saya ingin melakukan beberapa pengujian untuk melihat apakah itu masih menjadi masalah, atau apa yang terjadi di sana.
  3. Meskipun saya yakin ini hanya terkait secara tangensial dengan PR, saya ingin menguji flanel dan menenun jaring di bawah penerapan selinux.

Terima kasih telah menangani ini di @rcythr .

Mungkin saja salah, tetapi saya rasa saya tidak mengalami masalah dengan CNI setelah mereka mengaktifkan panji istimewa.

Sama seperti dump hal-hal yang harus saya lakukan setidaknya untuk Fedora 28, jadi mungkin ini sekarang dimasukkan ke dalam container-selinux:

Buat modul berikut:

Memungkinkan Cilium dan Weave Scope bekerja

module container_bpf 1.0;

require {
  type spc_t;
  type container_runtime_t;
  class bpf { map_create prog_load prog_run map_write map_read };
}

#============= spc_t ==============
allow container_runtime_t self:bpf { map_create prog_load prog_run map_write map_read };
allow container_runtime_t self:bpf map_create;
allow container_runtime_t spc_t:bpf { map_read map_write };
allow spc_t container_runtime_t:bpf { map_create prog_load prog_run map_write map_read };
allow spc_t self:bpf { map_create prog_load prog_run map_write map_read };

Izinkan penampung memuat sertifikat

module container_cert 1.0;

require {
  type container_t;
  type cert_t;
  class file { open read };
  class dir { read };
  class lnk_file { read };
}

allow container_t cert_t:file { open read };
allow container_t cert_t:lnk_file { read };
allow container_t cert_t:dir { read };

Hal yang paling saya khawatirkan adalah situasi pengujian di sini. Saat ini kami tidak memiliki cara untuk secara otomatis melakukan uji asap dukungan SELinux dengan kubeadm dan k8s secara keseluruhan. kind / kinder mendasarkan gambar node mereka pada ubuntu 19.04. Ini, tentu saja, tidak mengaktifkan SELinux di dalamnya secara default.
Kita perlu memiliki kemampuan untuk menjalankan cluster pengujian dengan kinder pada gambar node dasar Fedora / CentOS dengan SELinux diaktifkan. Setelah kami dapat melakukannya, kami dapat mempertahankan status kerja dukungan SELinux melalui kisi uji k8s.

Jika kita tidak menangani situasi pengujian dengan benar, kita mungkin berakhir pada situasi "berfungsi hari ini, tetapi mungkin tidak berfungsi besok" dan pengguna yang marah atas klaim dukungan SELinux dalam dokumentasi kita.

100% setuju.

Saya tergoda untuk mengatakan kami menunda sampai CentOS 8 menjadi GA sehingga kami memiliki baseline yang konsisten untuk versi kernel di seluruh distro.

Jika kita tidak menangani situasi pengujian dengan benar, kita mungkin berakhir pada situasi "berfungsi hari ini, tetapi mungkin tidak berfungsi besok" dan pengguna yang marah atas klaim dukungan SELinux dalam dokumentasi kita.

jika selinux adalah sesuatu yang sangat membutuhkan tes e2e, kami tidak dapat mendukungnya hari ini.

Masalahnya adalah bahwa ekosistem memiliki banyak distro dan rasa yang tidak dapat kami uji semuanya.
jika kita tidak ingin mempertahankan kode untuk selinux di kubeadm, kita masih dapat memiliki panduan dalam penyiapan kita dengan penafian "mungkin tidak berfungsi" dan ini adalah proposal awal saya.

Jika kita menyelesaikan # 1379, ini akan membawa kita jauh untuk memungkinkan pengguna yang ingin memiliki pengaturan SELinux yang lebih ketat.

Saya akan mengumpulkan instruksi tentang bagaimana Anda dapat melakukan SELinux dengan cara yang tidak didukung hari ini - baik sebagai blogpost atau dokumen yang dapat masuk ke docs.k8s.io.

Selain itu, @TheFoxAtWork memang meningkatkan SELinux di CNCF SIG Security minggu ini, jadi bertanya-tanya apakah ada minat yang lebih luas untuk membuatnya berfungsi.

Masalahnya adalah bahwa ekosistem memiliki banyak distro dan rasa yang tidak dapat kami uji semuanya.

Satu hal yang membantu di sini adalah bahwa paket container-selinux dibagikan di semua distro, jadi mungkin cukup menambahkan satu saja. Saran adalah menambahkan CentOS 8 karena akan ada di Linux 4.18, yang sedikit lebih maju dari Ubuntu 18.04 tetapi tidak cukup masif untuk mulai menunjukkan bug lain. Amazon Linux 2 juga merupakan opsi jika kami mengujinya di tempat lain.

Masalahnya adalah bahwa ekosistem memiliki banyak distro dan rasa yang tidak dapat kami uji semuanya.

Satu hal yang membantu di sini adalah bahwa paket container-selinux dibagikan di semua distro, jadi mungkin cukup menambahkan satu saja. Saran adalah menambahkan CentOS 8 karena akan ada di Linux 4.18, yang sedikit lebih maju dari Ubuntu 18.04 tetapi tidak cukup masif untuk mulai menunjukkan bug lain. Amazon Linux 2 juga merupakan opsi jika kami mengujinya di tempat lain.

Saya kira maksud saya lebih banyak tentang fakta bahwa selinux bukanlah sesuatu yang benar-benar didukung di Ubuntu dan AppArmor adalah alternatif untuk itu.

https://security.stackexchange.com/a/141716

Sekarang secara praktis SElinux bekerja lebih baik dengan Fedora dan RHEL karena sudah tersedia sebelumnya sementara AA bekerja lebih baik di Ubuntu dan SUSE yang berarti akan lebih baik untuk mempelajari cara menggunakan SElinux pada distro sebelumnya daripada melalui hassel untuk membuat AA bekerja pada mereka dan sebaliknya sebaliknya.

ini adalah kekacauan rasa distro yang saya tidak ingin masuki kubeadm.

survei kubeadm memberi tahu kami bahwa 65% pengguna kami menggunakan Ubuntu, jadi secara teknis kami harus memprioritaskan apparmor. adakah yang mencoba kubeadm dengan apparmor?
xref https://kubernetes.io/docs/tutorials/clusters/apparmor/

Jika kita menyelesaikan # 1379, ini akan membawa kita jauh untuk memungkinkan pengguna yang ingin memiliki pengaturan SELinux yang lebih ketat.

ya, menurut saya kita harus mendokumentasikan beberapa detail dasar dan memasukkan sisanya ke # 1379.
tetapi saya juga melihat permintaan untuk peningkatan konfigurasi pod statis di v1betaX berikutnya, karena RN kami tidak dapat mempertahankan modifikasi konteks keamanan setelah peningkatan.

adakah yang mencoba kubeadm dengan apparmor?

AppArmor jauh lebih ringan daripada SELinux dan memiliki model keamanan yang berbeda. Ini cukup banyak secara default hari ini untuk Docker di Ubuntu.

ini adalah kekacauan rasa distro yang saya tidak ingin masuki kubeadm.

Mengingat AppArmor tidak dapat digunakan pada CentOS dan yang setara (selain AL2 yang mendukung keduanya), kami sudah ada di sana untuk mengatakan beberapa persentase pengguna tidak dapat menggunakan Modul Keamanan Linux dengan cara yang didukung.

ini adalah kekacauan rasa distro yang saya tidak ingin masuki kubeadm.

Saya benar-benar memahami keinginan untuk tidak terlibat dalam kekacauan distro dan opsi - ini adalah ledakan kombinatorial dari konfigurasi pengujian. Secara pribadi, saya percaya jika kubeadm setidaknya _compatible_ dengan selinux, itu akan memiliki bagian yang lebih besar dari pengguna non-ubuntu, tetapi saya tidak memiliki bukti selain fakta bahwa saya adalah salah satu dari orang-orang itu. Namun, jika satu-satunya kombinasi distro / cri yang diuji adalah ubuntu dengan docker, maka itulah satu-satunya distro / cri yang didukung.

Jika Anda tidak ingin mendukung konfigurasi lain yang menjadi pilihan Anda, tetapi setidaknya jelaskan tentang itu di dokumentasi dan tutup masalah ini sekarang. Memberi tahu pengguna centos / rhel / fedora untuk menonaktifkan selinux untuk seluruh sistem mereka karena mencari tahu (dan menguji) kebijakan untuk aplikasi mengganggu sama dengan memberi tahu mereka untuk menonaktifkan firewall mereka karena mencari tahu (dan menguji) aturan itu mengganggu.

@variabel acak

AppArmor jauh lebih ringan daripada SELinux dan memiliki model keamanan yang berbeda. Ini cukup banyak secara default hari ini untuk Docker di Ubuntu.

sebenarnya, saya pikir itu sudah berjalan di gambar prow / kubekins.

@bayu_joo

Jika satu-satunya kombinasi distro / cri yang diuji adalah ubuntu dengan docker, maka itulah satu-satunya distro / cri yang didukung.

Saat ini kami menguji containerd dan docker di Ubuntu.

Memberi tahu pengguna centos / rhel / fedora untuk menonaktifkan selinux untuk seluruh sistem mereka karena mencari tahu (dan menguji) kebijakan untuk aplikasi mengganggu sama dengan memberi tahu mereka untuk menonaktifkan firewall mereka karena mencari tahu (dan menguji) aturan itu mengganggu.

kami membutuhkan bantuan dengan detail selinux. kami sudah memberi tahu pengguna "CentOS, RHEL atau Fedora" untuk menonaktifkan selinux sepenuhnya:
https://github.com/kubernetes/website/blob/master/content/en/docs/setup/production-environment/tools/kubeadm/install-kubeadm.md#installing -kubeadm-kubelet-and-kubectl

ini tidak diinginkan dan saya masih berpikir kita harus memiliki dokumen atau paragraf dengan beberapa langkah panduan.

Mengajukan https://github.com/containerd/cri/issues/1195 untuk mencatat fakta bahwa masih ada pekerjaan yang harus dilakukan untuk menyelesaikan dukungan SELinux di ContainerD.

  1. Saya ingin mempertimbangkan untuk memasukkan beberapa perubahan oleh @randomvariable menjadi lebih banyak
    batasi dengan rapat beberapa wadah, jika memungkinkan. Saya yakin perubahannya akan memungkinkan kita
    untuk membatasi kube-scheduler dan etcd dengan ketat; namun, karena kami tidak dapat memberi label ulang
    / etc / ssl / certs atau / etc / pki tanpa merusak sistem, kami tidak dapat membatasi kube-apiserver
    atau kube-controller-manager lebih ketat dari spc_t. Kami juga perlu membuat tipe khusus
    untuk mereka, berhenti menggunakan dua direktori sistem ini, atau hidupkan saja dengan tipe

Tidak menggunakan direktori sistem atau membuat tipe kustom untuk komponen yang membutuhkan akses ke direktori sistem ini akan memungkinkan kita untuk lebih memperketat berbagai komponen dan menghindari penggunaan jenis spc_t sepenuhnya. Ini jelas IMHO solusi terbaik.

  1. Saya ingin mempertimbangkan untuk memasukkan beberapa perubahan oleh @randomvariable menjadi lebih banyak
    batasi dengan rapat beberapa wadah, jika memungkinkan. Saya yakin perubahannya akan memungkinkan kita
    untuk membatasi kube-scheduler dan etcd dengan ketat; namun, karena kami tidak dapat memberi label ulang
    / etc / ssl / certs atau / etc / pki tanpa merusak sistem, kami tidak dapat membatasi kube-apiserver
    atau kube-controller-manager lebih ketat dari spc_t. Kami juga perlu membuat tipe khusus
    untuk mereka, berhenti menggunakan dua direktori sistem ini, atau hidupkan saja dengan tipe

Tidak menggunakan direktori sistem atau membuat tipe kustom untuk komponen yang membutuhkan akses ke direktori sistem ini akan memungkinkan kita untuk lebih memperketat berbagai komponen dan menghindari penggunaan jenis spc_t sepenuhnya. Ini jelas IMHO solusi terbaik.

Saya setuju. Itulah mengapa saya ingin mengujinya dan membuatnya berfungsi.

Berdasarkan umpan balik dari @ neolit123 , saya ragu kita akan melihat perubahan

Di halaman itu saya akan menyajikan tiga opsi:

  1. Nonaktifkan selinux: Ini adalah opsi yang paling tidak terbatas, tetapi paling didukung. Mungkin diperlukan untuk beberapa plugin CNI atau beban kerja pengguna.
  2. Tetap gunakan direktori sistem / etc / pki dan / etc / ssl / certs dan gunakan spt_t untuk menghindari masalah.
  3. Direktori kustom, dan pelabelan ulang chcon dan pembatasan yang cukup ketat.

Hai, hanya ingin berkomentar bahwa kami telah menjalankan selinux selama hampir satu tahun bersama dengan kubeadm dan kubernetes + docker + calico di Centos7. Sebagian besar beban kerja tidak memiliki masalah, hanya memiliki beberapa masalah dengan concourse yang dapat saya ingat.

Namun kami ingin melakukan penegakan yang lebih baik meskipun pada titik tertentu, saat ini kami menjalankannya
'chcon -Rt container_file_t' pada direktori di bawah ini dan pastikan sudah dibuat sebelum menjalankan kubeadm init (termasuk / etc / kubernetes / pki / etcd)

/ var / lib / etcd (etcd datadir)
/ etc / kubernetes / pki (`certificateDir 'di kubeadm.conf)
/etc/cni/net.d
/ opt / cni / bin /

@qpehedm Jika Anda dapat menerapkan JSONPatch ke manifes pod statis, dan juga memastikan kubeadm menjalankan restorecon untuk setiap file / direktori yang ditulisnya, apakah itu cukup untuk memungkinkan Anda menyetel pengurungan yang lebih ketat?

@randomvariable Ya untuk menambahkan

Saya akan menutup tiket ini dan inilah alasan saya, dijelaskan dengan poin-poin:

/Menutup

@ neolit123 : Menutup masalah ini.

Menanggapi ini :

Saya akan menutup tiket ini dan inilah alasan saya, dijelaskan dengan poin-poin:

/Menutup

Instruksi untuk berinteraksi dengan saya menggunakan komentar PR tersedia di sini . Jika Anda memiliki pertanyaan atau saran terkait dengan perilaku saya, harap ajukan masalah ke kubernetes / test-infra repository.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat