Kubeadm: gunakan sertifikat penyajian kubelet yang telah ditandatangani

Dibuat pada 9 Nov 2018  ·  38Komentar  ·  Sumber: kubernetes/kubeadm

Apakah ini LAPORAN BUG atau PERMINTAAN FITUR?

/ jenis bug

Membuka sisi kubeadm untuk masalah ini di server-metrik

Versi

$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.1", GitCommit:"4ed3216f3ec431b140b1d899130a69fc671678f4", GitTreeState:"clean", BuildDate:"2018-10-05T16:43:08Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}

Lingkungan :

  • Versi Kubernetes (gunakan kubectl version ):
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.1", GitCommit:"4ed3216f3ec431b140b1d899130a69fc671678f4", GitTreeState:"clean", BuildDate:"2018-10-05T16:46:06Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.1", GitCommit:"4ed3216f3ec431b140b1d899130a69fc671678f4", GitTreeState:"clean", BuildDate:"2018-10-05T16:36:14Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
  • Penyedia cloud atau konfigurasi perangkat keras :
    Apa saja
  • OS (misalnya dari / etc / os-release):
    Apa saja
  • Kernel (misalnya uname -a ):
$ uname -a
Linux ip-172-31-1-118 4.15.0-1023-aws #23-Ubuntu SMP Mon Sep 24 16:31:06 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Lainnya :

Apa yang terjadi?

kubeadm membuat sertifikat di bawah /var/lib/kubelet/pki/kubelet.* ditandatangani dengan CA berbeda dari yang di bawah /etc/kubernetes/pki/ca.pem

Apa yang Anda harapkan terjadi?

Akibatnya beberapa aplikasi seperti metrics-server tidak dapat mengumpulkan statistik dari kubelet yang diamankan karena kubelet memiliki sertifikat yang ditandatangani oleh ca yang berbeda dari master K8s

Contoh kesalahan:

E1108 23:49:32.090084       1 manager.go:102] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:ip-x-x-x-x: unable to fetch metrics from Kubelet ip-x-x-x-x (ip-x-x-x-x): Get https://ip-x-x-x-x:10250/stats/summary/: x509: certificate signed by unknown authority, unable to fully scrape metrics from source kubelet_summary:ip-x-x-x-x: unable to fetch metrics from Kubelet ip-x-x-x-x (ip-x-x-x-x): Get https://ip-x-x-x-x:10250/stats/summary/: x509: certificate is valid for x.x.x.x not ip-x-x-x-x]

Bagaimana cara memperbanyaknya (seminimal dan setepat mungkin)?

Instal server metrik saat dijalankan:

$ kubectl -n log kube-sistem

Ada hal lain yang perlu kami ketahui?

Beberapa latar belakang lagi di sini

Ada juga langkah-langkah di sana yang saya ikuti untuk memperbaiki masalah.


edit: neolit123

Masalahnya di sini adalah bahwa sertifikat pelayanan ditandatangani sendiri secara default:
lihat https://github.com/kubernetes/website/pull/27071 untuk pembaruan dokumentasi.

aresecurity help wanted kinbug kinfeature lifecyclfrozen prioritimportant-longterm

Komentar yang paling membantu

mari kita meringkas masalahnya:

sebagaimana diuraikan oleh @anitgandhi :
https://github.com/kubernetes/kubeadm/issues/1223#issuecomment -454572577

Masalah dengan kubeadm di sini adalah kita tidak mengirimkan beberapa flag ke kubelet:

--tls-cert-file=<some-path>/kubelet.crt
--tls-private-key-file=<some-path>/kubelet.key

tanpa tanda-tanda ini, kubelet secara default menandatangani sertifikat servisnya saat pertama kali dijalankan, yang dapat diverifikasi dengan:

sudo openssl verify -verbose -CAfile /var/lib/kubelet/pki/kubelet.crt /var/lib/kubelet/pki/kubelet.crt

dengan sertifikat yang ditandatangani sendiri dan bukan sertifikat yang ditandatangani oleh kluster CA ( /etc/kubernetes/ca.crt ), penerapan seperti server metrik tidak dapat mengikis kubelet, karena SAN cert yang ditandatangani sendiri hanya akan menyertakan DNS:hostname .

solusi yang memungkinkan:
A) menerapkan menyanyikan pasangan baru kubelet.crt/key , idealnya di bawah /var/lib/kubelet/pki dan mengatur tanda kubelet tambahan --tls-cert-file , --tls-private-key-file .

B) artinya mengaktifkan dokumen ini sesuai permintaan seperti yang dilakukan @ raravena80 di sini: https://stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
kecuali kemungkinan menggunakan perintah Kubernetes CSRs / kubeadm.

C) seperti yang dikomentari oleh @alexbrand

Jika memungkinkan, saya pikir kita harus menggunakan fasilitas bootstrap TLS yang dibangun di dalam kubelet untuk meminta / merotasi sertifikat pelayanan.

D)?

@ kubernetes / sig-cluster-lifycle
bagi saya ini tampak di ruang antara bug / fitur.

lihat juga:
https://github.com/kubernetes/community/pull/602/files

Semua 38 komentar

@ raravena80 Saya tidak mengetahui adanya sertifikat yang dibuat oleh kubeadm di bawah /var/lib/kubelet/pki/ .. dapatkah Anda memberikan info selengkapnya? misal file config kubeadm, langkah-langkah membuat cluster

@fabriziopandini Saya tidak sepenuhnya yakin apakah sertifikat dibuat oleh kubeadm, tetapi prosedur umum dijelaskan di sini .

Seperti inilah tampilan konten direktori:

root@ip-172-31-1-118:/var/lib/kubelet/pki# pwd
/var/lib/kubelet/pki
root@ip-172-31-1-118:/var/lib/kubelet/pki# ls -al
total 24
drwxr-xr-x 2 root root 4096 Jul 23 21:10 .
drwxr-xr-x 7 root root 4096 Nov 12 04:52 ..
-rw------- 1 root root 2810 Jul 23 21:09 kubelet-client-2018-07-23-21-09-53.pem
-rw------- 1 root root 1159 Jul 23 21:10 kubelet-client-2018-07-23-21-10-43.pem
lrwxrwxrwx 1 root root   59 Jul 23 21:10 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2018-07-23-21-10-43.pem
-rw-r--r-- 1 root root 1501 Nov  8 23:53 kubelet.crt
-rw------- 1 root root 1679 Nov  8 23:53 kubelet.key
root@ip-172-31-1-118:/var/lib/kubelet/pki#

Apakah file kubelet.crt dan kubelet.key dibuat oleh kubelet saat pertama kali dimuat?

@ raravena80 terima kasih atas klarifikasinya
Mungkin saya tidak memiliki konteks lengkap di sini jadi saya memberikan ruang kepada orang lain untuk menjawab.

Hanya satu catatan samping (mungkin itu bisa membantu)
Kubeadm sudah membuat sertifikat bernama apiserver-kubelet-client untuk membiarkan server api berbicara secara aman dengan kubelet; itu ditandatangani oleh ca dan terikat pada aturan RBAC yang diperlukan.

/ tetapkan @liztio

Saya rasa ini untuk membuat sertifikat server kubelet sebelumnya. Saya mencoba menggunakan flag Kubelet untuk bootstrap server TLS dan merotasi sertifikat server, sayangnya saya tidak bisa membuat Kubelet meminta sertifikat server untuk dirinya sendiri menggunakan token bootstrap. Kubelet akhirnya kembali ke perilaku default untuk sertifikat server, yaitu menghasilkan sertifikat yang ditandatangani sendiri.

Sepengetahuan saya, saat ini satu-satunya cara untuk melakukannya adalah dengan membuat sertifikat server Kubelet out-of-band dan menempatkannya pada jalur deterministik dan kubelet (dikonfigurasi oleh kubeadm) akan mengambilnya, dan mengatur beberapa flag kubelet yang sesuai. ; referensi: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/#client -and-serving-certificate

apiserver-kubelet-client adalah sertifikat klien yang akan disajikan oleh server API ke kubelet, tetapi kubelet dikonfigurasi untuk mempercayai klien yang ditandatangani oleh k8s CA:

# cat /var/lib/kubelet/config.yaml 
address: 0.0.0.0
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt

Ini adalah identitas kubelet sebagai server yang disajikan yang perlu ditandatangani oleh k8s CA, yang muncul di pertanyaan awal.

Ada juga beberapa diskusi yang relevan di akhir utas ini: https://github.com/kubernetes/kubeadm/issues/118

Saya pikir kubeadm mungkin harus menambahkan pemberi persetujuan CSR untuk permintaan sertifikat server dengan token bootstrap yang valid, seperti halnya untuk permintaan sertifikat klien?

Bagaimana dengan meminta kubelet mengunggah ca yang ditandatangani sendiri ke configmap di suatu tempat? plugin nodeadmission dapat membatasinya hanya untuk configmapnya sendiri. metrik-server dapat menggunakannya untuk menghubungi node.

Ada ide tentang itu?

Jika memungkinkan, saya pikir kita harus menggunakan fasilitas bootstrap TLS yang dibangun di dalam kubelet untuk meminta / merotasi sertifikat pelayanan.

@alexbrand Saya setuju itu

kubelet TLS bootstrap hanya menghasilkan sertifikat klien untuk alasan apa pun:
--bootstrap-kubeconfig string
Path to a kubeconfig file that will be used to get client certificate for kubelet. If the file specified by --kubeconfig does not exist, the bootstrap kubeconfig is used to request a client certificate from the API server. On success, a kubeconfig file referencing the generated client certificate and key is written to the path specified by --kubeconfig. The client certificate and key file will be stored in the directory pointed by --cert-dir.

Dan kubeadm sudah melakukan ini. Mungkin ini permintaan fitur kubelet?

mari kita meringkas masalahnya:

sebagaimana diuraikan oleh @anitgandhi :
https://github.com/kubernetes/kubeadm/issues/1223#issuecomment -454572577

Masalah dengan kubeadm di sini adalah kita tidak mengirimkan beberapa flag ke kubelet:

--tls-cert-file=<some-path>/kubelet.crt
--tls-private-key-file=<some-path>/kubelet.key

tanpa tanda-tanda ini, kubelet secara default menandatangani sertifikat servisnya saat pertama kali dijalankan, yang dapat diverifikasi dengan:

sudo openssl verify -verbose -CAfile /var/lib/kubelet/pki/kubelet.crt /var/lib/kubelet/pki/kubelet.crt

dengan sertifikat yang ditandatangani sendiri dan bukan sertifikat yang ditandatangani oleh kluster CA ( /etc/kubernetes/ca.crt ), penerapan seperti server metrik tidak dapat mengikis kubelet, karena SAN cert yang ditandatangani sendiri hanya akan menyertakan DNS:hostname .

solusi yang memungkinkan:
A) menerapkan menyanyikan pasangan baru kubelet.crt/key , idealnya di bawah /var/lib/kubelet/pki dan mengatur tanda kubelet tambahan --tls-cert-file , --tls-private-key-file .

B) artinya mengaktifkan dokumen ini sesuai permintaan seperti yang dilakukan @ raravena80 di sini: https://stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
kecuali kemungkinan menggunakan perintah Kubernetes CSRs / kubeadm.

C) seperti yang dikomentari oleh @alexbrand

Jika memungkinkan, saya pikir kita harus menggunakan fasilitas bootstrap TLS yang dibangun di dalam kubelet untuk meminta / merotasi sertifikat pelayanan.

D)?

@ kubernetes / sig-cluster-lifycle
bagi saya ini tampak di ruang antara bug / fitur.

lihat juga:
https://github.com/kubernetes/community/pull/602/files

Saya pikir sesuatu di antara opsi B + C harus dilakukan karena banyak sertifikat klien token bootstrap / logika CSR kubelet + kubeadm akan memiliki logika yang sama untuk ini.

mari kita meringkas masalahnya:

sebagaimana diuraikan oleh @anitgandhi :
# 1223 (komentar)

Masalah dengan kubeadm di sini adalah kita tidak mengirimkan beberapa flag ke kubelet:

--tls-cert-file=<some-path>/kubelet.crt
--tls-private-key-file=<some-path>/kubelet.key

tanpa tanda-tanda ini, kubelet secara default menandatangani sertifikat servisnya saat pertama kali dijalankan, yang dapat diverifikasi dengan:

sudo openssl verify -verbose -CAfile /var/lib/kubelet/pki/kubelet.crt /var/lib/kubelet/pki/kubelet.crt

dengan sertifikat yang ditandatangani sendiri dan bukan sertifikat yang ditandatangani oleh kluster CA ( /etc/kubernetes/ca.crt ), penerapan seperti server metrik tidak dapat mengikis kubelet, karena SAN cert yang ditandatangani sendiri hanya akan menyertakan DNS:hostname .

solusi yang memungkinkan:
A) menerapkan menyanyikan pasangan baru kubelet.crt/key , idealnya di bawah /var/lib/kubelet/pki dan mengatur tanda kubelet tambahan --tls-cert-file , --tls-private-key-file .

B) artinya mengaktifkan dokumen ini sesuai permintaan seperti yang dilakukan @ raravena80 di sini: https://stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
kecuali kemungkinan menggunakan perintah Kubernetes CSRs / kubeadm.

C) seperti yang dikomentari oleh @alexbrand

Jika memungkinkan, saya pikir kita harus menggunakan fasilitas bootstrap TLS yang dibangun di dalam kubelet untuk meminta / merotasi sertifikat pelayanan.

D)?

@ kubernetes / sig-cluster-lifycle
bagi saya ini tampak di ruang antara bug / fitur.

lihat juga:
https://github.com/kubernetes/community/pull/602/files

ringkasan bagus @ neolit123 . Apakah Anda tahu apakah ini akan tergelincir ke siklus berikutnya atau pekerjaan sedang berlangsung saat kita berbicara? Bertanya terutama karena server metrik yang diinginkan oleh setiap penerapan;)

@randomvariable menyebutkan bahwa ada solusi lain untuk itu.
dari diskusi sejauh ini, kami ragu-ragu untuk menandatangani sertifikat yang melayani kubelet dengan CA klaster. topik ini membutuhkan diskusi lebih lanjut.

/ hapus-bantuan

karena solusi untuk diterapkan belum dipilih.

Ada gerakan apa ini? Saya menentangnya untuk mendukung fitur penskalaan otomatis dalam cluster yang diterapkan kubeadm.

Solusi saat ini adalah menonaktifkan pemeriksaan CA dari sertifikat kubelet.

helm install --set 'args={--kubelet-insecure-tls}' --namespace kube-system metrics stable/metrics-serve

tidak juga, itu diblokir pada proposal desain.
ada sejumlah solusi, tetapi pekerjaan mendokumentasikannya terhenti:
https://github.com/kubernetes/kubeadm/issues/1602

--kubelet-insecure-tls

ini mungkin tidak ideal untuk semua pengguna.

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.

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

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

/ siklus hidup dibekukan

Mengalami masalah ini sebenarnya membuat cluster v1.18.2 dengan kubeadm.

Saat menyiapkan server metrik, ia tidak akan berfungsi tanpa menyetelnya kubelet-insecure-tls flag ATAU menerbitkan sertifikat untuk kublet "out of band", menandatanganinya dengan kubernetes CA.

Saya berpikir untuk menggunakan kembali sertifikat klien kubelet tetapi itu tentu saja dikeluarkan untuk CN = system:node:nodename dan tidak ada SAN. Dan saya mengujinya meskipun yang tentu saja mengubah kesalahan untuk menunjukkan hal itu. Sertifikat yang sama dapat digunakan sebagai server / klien jika memiliki nama noden sebagai nama alternatif subjek? Tapi saya rasa akan lebih tepat menggunakan sertifikat terpisah untuk server / klien?

/ hapus-siklus hidup dibekukan

/ siklus hidup dibekukan

itu dibekukan sehingga bot tidak menutup masalah.

Sertifikat yang sama dapat digunakan sebagai server / klien jika memiliki nama noden sebagai nama alternatif subjek?

dalam teori dan kecuali kubelet memvalidasinya - misalnya "sertifikat klien tidak boleh memiliki SAN".

Tapi saya rasa akan lebih tepat menggunakan sertifikat terpisah untuk server / klien?

itu adalah praktik umum untuk menggunakannya secara terpisah bahkan dalam kasus di mana tampaknya dapat dihindari. sepertinya pengelola kubelet / auth {z | n} tidak akan mengubah detail ini.

Hei. Melakukan sedikit lebih banyak diggin. Opsi konfigurasi Kubelet serverTLSBootstrap: true sebenarnya dapat membuat CSR untuk sertifikat pelayanan. Tapi itu membuatnya tidak disetujui. Mana yang mungkin baik-baik saja?

Menyetel rotateCertificates: true dan serverTLSBootsrap: true dan kemudian menyetujui CSR untuk sertifikat pelayanan sepertinya cara termudah untuk masuk ke sini. Sertifikat pelayanan yang diminta / diterbitkan adalah O = system:nodes, CN = system:node:<nodename> dengan Nama Alternatif Subjek untuk DNS: <nodename>, IP Address: <node IP address>

Haruskah kubeadm mengaktifkan opsi konfigurasi serverTLSBootstrap setidaknya jadi Menyetujui sertifikat server akan menjadi hal yang mudah untuk dilakukan? Atau bahkan kubeadm bisa melakukan persetujuan juga?

Hei. Melakukan sedikit lebih banyak diggin. Opsi konfigurasi Kubelet serverTLSBootstrap: true sebenarnya dapat membuat CSR untuk sertifikat pelayanan. Tapi itu membuatnya tidak disetujui. Mana yang mungkin baik-baik saja?

Menyetel rotateCertificates: true dan serverTLSBootsrap: true dan kemudian menyetujui CSR untuk sertifikat pelayanan sepertinya cara termudah untuk masuk ke sini. Sertifikat pelayanan yang diminta / diterbitkan adalah O = system:nodes, CN = system:node:<nodename> dengan Nama Alternatif Subjek untuk DNS: <nodename>, IP Address: <node IP address>

Haruskah kubeadm mengaktifkan opsi konfigurasi serverTLSBootstrap setidaknya jadi Menyetujui sertifikat server akan menjadi hal yang mudah untuk dilakukan? Atau bahkan kubeadm bisa melakukan persetujuan juga?

Tidak yakin dengan penerapan keamanannya tetapi Anda dapat menggabungkan serverTLSBootstrap dengan operator ini untuk menyetujui CSR secara otomatis https://github.com/kontena/kubelet-rubber-stamp

Haruskah kubeadm mengaktifkan opsi konfigurasi serverTLSBootstrap setidaknya jadi Menyetujui sertifikat server akan menjadi hal yang mudah untuk dilakukan? Atau bahkan kubeadm bisa melakukan persetujuan juga?

kubeadm tidak dapat melakukan persetujuan karena kubeadm bukan daemon. itu harus menerapkan pengontrol / operator yang mengaturnya untuk pengguna. mungkin di masa depan.

API sertifikat akan segera beralih ke GA dan semoga kami memiliki cara yang lebih baik untuk mengelola ini di k8s. tolong perhatikan:
https://github.com/kubernetes/enhancements/issues/267
(namun tidak jelas bagi saya apa yang akan berakhir dengan ...)

kami juga punya ide alternatif. tetapi jika semua ini mencoba untuk menyelesaikan masalah metrik-server, Anda sebaiknya menggunakan https://github.com/brancz/kube-rbac-proxy yang dapat melakukan SAR pada permintaan MS ke kubelet. sayangnya ini belum didokumentasikan di pihak kami:
https://github.com/kubernetes/kubeadm/issues/1602

@ neolit123 Saya setidaknya mulai melihat ke dalamnya ketika mencoba untuk berdiri server metrik di kubeadm dan cluster "cara yang sulit" untuk pengalaman belajar. Cara termudah tentu saja untuk menandai MS dengan --kubelet-insecure-tls , tetapi saya benar-benar ingin melihat cara memperbaikinya dengan cara yang aman dan kemudian tertarik dengan masalah tersebut. 🙂

Untuk saat ini cukup mudah bagi saya untuk menambahkan flag serverTLSbootstrap ke konfigurasi kubelet dan menyetujui sertifikat secara manual. Saya telah memperhatikan sisi negatifnya, yaitu Anda tidak dapat sepenuhnya berinteraksi dengan pod di node sampai Anda menyetujui sertifikat tersebut. (kubectl exec gagal menjalankan perintah pada pod yang berjalan pada node sebelum persetujuan misalnya)

Saya akan mengikuti masalah peningkatan juga. Terima kasih.

Sungguh menyedihkan bahwa dengan kubeadm yang tampaknya cukup matang, hasil out of the box untuk kubeletet cert harus ditandatangani sendiri & banyak orang memilih kubelet-insecure-tls untuk server metrik daripada melakukan sesuatu dengan benar & dll :(

itu masalah yang rumit.

silahkan coba:
https://github.com/kontena/kubelet-rubber-stamp
atau
https://github.com/brancz/kube-rbac-proxy
sebagai solusi

itu masalah yang rumit.

silahkan coba:
https://github.com/kontena/kubelet-rubber-stamp
atau
https://github.com/brancz/kube-rbac-proxy
sebagai solusi

Sebenarnya https://github.com/kontena/kubelet-rubber-stamp berfungsi cukup baik & imo tampaknya menjadi solusi yang lebih tepat daripada proxy.

Langkah 1:
Menambahkan
serverTLSBootstrap: true di akhir setiap /var/lib/kubelet/config.yaml untuk konfigurasi ulang kubelet & jangan lupa untuk menerapkan config (atau cukup reboot)

Langkah 2:
Terapkan kubelet-rubber-stamp

service_account.yaml
role.yaml
role_binding.yaml
operator.yaml

Langkah 3:
Edit penerapan metrik-server & hapus --kubelet-insecure-tls

Hasil:

kubectl get csr
NAME        AGE   SIGNERNAME                      REQUESTOR          CONDITION
csr-7dvsx   31m   kubernetes.io/kubelet-serving   system:node:u-02   Approved,Issued
csr-d6rvm   31m   kubernetes.io/kubelet-serving   system:node:u-03   Approved,Issued
csr-szblz   31m   kubernetes.io/kubelet-serving   system:node:u-01   Approved,Issued
csr-zjfgj   31m   kubernetes.io/kubelet-serving   system:node:u-04   Approved,Issued

Hei, tambahkan saja ke @vainkop itu
Selama kubeadm init untuk membuat cluster, Anda juga harus bisa meneruskan file objek KubeletConfiguration API untuk menyetel serverTLSBootstrap

`` kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
jenis: ClusterConfiguration

...

apiVersion: kubelet.config.k8s.io/v1beta1
jenis: KubeletConfiguration
serverTLSBootstrap: benar

`kubeadm init --config=kubeadm-config.yaml`

Then all kubelet's will automatically be set up using the `serverTLSBootstrap` flag.

To get the CSRs

kubectl mendapatkan csr
KONDISI PEMOHON NAMA UMUR NAMA SIGNERNAME
csr-2qkdw 2m1s kubernetes.io/kube-apiserver-client-kubelet system: bootstrap : fcufbo Disetujui, Diterbitkan
csr-9wvgt 114s kubernetes.io/kubelet-serving system: node : worker-1 Tertunda
csr-lz97v 4m58s kubernetes.io/kubelet-serving system: node : master-1 Tertunda
csr-rsdsp 4m59s kubernetes.io/kube-apiserver-client-kubelet system: node : master-1 Disetujui, Diterbitkan
csr-wgxqs 4m49s kubernetes.io/kubelet-serving system: node : master-1 Tertunda

Then either approve them manually or deploy https://github.com/kontena/kubelet-rubber-stamp which approves them automatically. I just tried it with kubelet-rubber-stamp and it works great.

Also I did not seem to need to restart the kubelet's this way, they picked up their certificates as soon as I approvde the CSR, but a caveat is that the kublet's have NO cert until the CSR is approved, it does not get a self signed certificate first.

kubectl certificate menyetujui csr-ab123 # ATAU gunakan stempel karet!

kubectl mendapatkan csr
KONDISI PEMOHON NAMA UMUR NAMA SIGNERNAME
csr-9wvgt 3m kubernetes.io/kubelet-serving system: node : worker-1 Disetujui, Diterbitkan
...
``

Hal aneh lainnya tampaknya terjadi di sini btw, yaitu node master tampaknya membuat CSR dua kali. (Setidaknya dua kali saya mencoba ini)

Tapi seperti yang dikatakan @nijave dalam komentar di atas, saya tidak yakin apa implikasi keamanan dari penggunaan stempel karet.

@allir , @vainkop sejauh yang saya bisa lihat kubelet-rubber-stamp hanya memverifikasi jika nama umum CSR cocok dengan nama pemohon tetapi tidak memverifikasi apakah nama host dan Alamat IP tambahan yang diminta oleh kubelet valid. Ini berarti penyerang yang memiliki akses ke sertifikat klien kubelet pada dasarnya dapat membuat sertifikat untuk semua nama domain atau alamat IP. Semua klien yang dikonfigurasi untuk mempercayai root CA kemudian akan menerima sertifikat ini.
Tentu saja sulit untuk memvalidasi nama host dan alamat IP yang valid untuk kubelet tertentu karena saat ini tidak ada otoritas yang dapat memastikan apa yang diizinkan untuk diminta oleh kubelet. Misalnya menggunakan objek node pada API server tidak cukup karena kubelet dapat mengupdate objek tersebut tanpa batasan.

Hei, tambahkan saja ke @vainkop itu
Selama kubeadm init untuk membuat cluster, Anda juga harus bisa meneruskan file objek KubeletConfiguration API untuk menyetel serverTLSBootstrap
kubeadm init --config=kubeadm-config.yaml
Kemudian semua kubelet akan secara otomatis diatur menggunakan flag serverTLSBootstrap .

Atau untuk penyiapan K8 yang ada menggunakan Ansible, ini bisa berupa:

  tasks:
    - name: Insert a line at the end of /var/lib/kubelet/config.yaml
      lineinfile:
        path: /var/lib/kubelet/config.yaml
        line: 'serverTLSBootstrap: true'

+ mulai ulang kubelet

Wow saya sangat senang saya menemukan masalah ini, dan saya tidak sendirian yang ingin membuat cara yang tepat ini. :)

Sekarang izinkan saya membagikan pemikiran saya tentang masalah ini (mohon koreksi saya jika saya salah) :

Pertama, visi saya tentang masalah aslinya:
Saat ini kubeadm mengaktifkan otentikasi webhook untuk semua kubelet secara default, jadi kubelet sedang memvalidasi sertifikat klien untuk koneksi masuk tanpa masalah bahkan jika opsi --kubelet-insecure-tls ditentukan.
Dari sisi lain, metrik-server tidak memiliki kesempatan untuk memverifikasi sertifikat kubelet tertentu karena ia ditandatangani sendiri pada node.

Kemungkinan resiko menggunakan --kubelet-insecure-tls untuk metrik-server:
Meskipun data kubelet agak aman dan tidak akan pernah diberikan ke server metrik tanpa otentikasi webhook yang berhasil.
Secara teori, seseorang dapat membahayakan IP server atau nama host dan memberikan statistik yang salah. Tetapi untuk membangun koneksi metrik server menggunakan alamat IP dan nama host yang ditentukan untuk node melalui kube-apiserver, jadi penyerang perlu meretas API-server, DNS atau alamat IP node terlebih dahulu.

Pengamatan kecil:
Metrics-server bukanlah layanan tunggal yang mengakses kubelet secara langsung. Kube-apiserver juga melakukan ini untuk membaca log kontainer atau menjalankan shell di atasnya. Pertanyaan baiknya adalah bagaimana kube-apiserver memastikan bahwa ia membangun koneksi dengan kubelet tertentu sementara ia tidak memiliki informasi tentang CA yang mengeluarkan sertifikatnya?
Bukankah itu berperilaku sama seperti server metrik dengan opsi --kubelet-insecure-tls dalam kasus ini?

Solusi yang mungkin:
Saat ini webhook dan agregasi API cukup populer di Kubernetes. Semuanya berperilaku serupa, dengan menghasilkan CA dan pasangan crt / kunci sendiri. Hash CA juga disimpan dalam resource tertentu untuk memberikan informasi kepada kube-apiserver tentang sertifikat mana yang dapat dipercaya.

Sebagai contoh:

  • Layanan APIS menyimpan hash CA terkait di sumber daya apiservices.apiregistration.k8s.io :

    spec:
    caBundle: <ca-hash>
    
  • Webhook menyimpan hash CA terkait di sumber daya validatingwebhookconfigurations.admissionregistration.k8s.io dan mutatingwebhookconfigurations.admissionregistration.k8s.io :

    webhooks:
    - clientConfig:
      caBundle: <ca-hash>
    

Bagi saya, cukup jelas bahwa setiap sumber daya node harus memiliki caBundle di spec , di mana kubelet dapat mendaftarkan CA mereka sendiri untuk melayani menggunakan sertifikat klien mereka:

spec:
  caBundle: <ca-hash>

Metris-server dan kube-apiserver harus menggunakan sertifikat ini untuk memverifikasi dan mempercayai koneksi ke kubelet.

terima kasih kepada @ kfox1111 yang mengungkapkan gagasan serupa sebelumnya https://github.com/kubernetes/kubeadm/issues/1223#issuecomment -460854312

Pertanyaan baiknya adalah bagaimana kube-apiserver memastikan bahwa ia membangun koneksi dengan kubelet tertentu sementara ia tidak memiliki informasi tentang CA yang mengeluarkan sertifikatnya?
Bukankah itu berperilaku sama seperti server metrik dengan opsi --kubelet-insecure-tls dalam kasus ini?

Untuk menjawab pertanyaan ini saya dapat mengutip @luxas di sini:

Benar, kami tidak dapat membuat koneksi dari server api ke server kubelet diverifikasi, karena setiap kubelet memiliki sertifikat yang ditandatangani sendiri. Kami mungkin mempertimbangkan alur persetujuan manual wrt kubelet melayani sertifikat di masa mendatang tetapi itu tidak diamankan secara default saat ini.

dari https://github.com/kubernetes/kubeadm/issues/118#issuecomment -407498529

berharap itu bisa diselesaikan suatu hari nanti

[root<strong i="6">@jenkins</strong> metrics-server]# kubectl -n kube-system logs -f metrics-server-6955d88db9-lftlz
I1120 08:23:09.094132       1 requestheader_controller.go:169] Starting RequestHeaderAuthRequestController
I1120 08:23:09.094234       1 shared_informer.go:240] Waiting for caches to sync for RequestHeaderAuthRequestController
I1120 08:23:09.094270       1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I1120 08:23:09.094279       1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I1120 08:23:09.094307       1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I1120 08:23:09.094315       1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I1120 08:23:09.095064       1 dynamic_serving_content.go:130] Starting serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key
I1120 08:23:09.095207       1 secure_serving.go:197] Serving securely on [::]:4443
I1120 08:23:09.095259       1 tlsconfig.go:240] Starting DynamicServingCertificateController
I1120 08:23:09.194453       1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file 
I1120 08:23:09.194660       1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::client-ca-file 
I1120 08:23:09.194455       1 shared_informer.go:247] Caches are synced for RequestHeaderAuthRequestController 
E1120 08:23:10.420643       1 server.go:132] unable to fully scrape metrics: [unable to fully scrape metrics from node k8s-master3: unable to fetch metrics from node k8s-master3: Get "https://10.39.140.250:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.39.140.250 because it doesn't contain any IP SANs, unable to fully scrape metrics from node k8s-master1: unable to fetch metrics from node k8s-master1: Get "https://10.39.140.248:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.39.140.248 because it doesn't contain any IP SANs, unable to fully scrape metrics from node k8s-master2: unable to fetch metrics from node k8s-master2: Get "https://10.39.140.249:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.39.140.249 because it doesn't contain any IP SANs, unable to fully scrape metrics from node k8s-node1: unable to fetch metrics from node k8s-node1: Get "https://10.39.140.251:10250/stats/summary?only_cpu_and_memory=true": x509: cannot validate certificate for 10.39.140.251 because it doesn't contain any IP SANs]
I1120 08:23:33.874949       1 requestheader_controller.go:183] Shutting down RequestHeaderAuthRequestController
I1120 08:23:33.874978       1 configmap_cafile_content.go:223] Shutting down client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I1120 08:23:33.874993       1 configmap_cafile_content.go:223] Shutting down client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I1120 08:23:33.875019       1 tlsconfig.go:255] Shutting down DynamicServingCertificateController
I1120 08:23:33.875026       1 dynamic_serving_content.go:145] Shutting down serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key
I1120 08:23:33.875041       1 secure_serving.go:241] Stopped listening on [::]:4443

Tidak ada berita dari masalah ini? Saya akan tertarik untuk memiliki solusi untuk ini juga.

kami mendokumentasikan solusi di sini:
https://github.com/kubernetes/website/pull/27071
https://github.com/kubernetes/kubeadm/issues/1602

kami dapat membiarkan masalah ini tetap terbuka, tetapi karena kompleksitas keharusan untuk menerapkan penanda tangan dengan kubeadm secara default, kecil kemungkinan kami akan membuat perubahan ini dalam waktu dekat.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat