/ jenis bug
Membuka sisi kubeadm
untuk masalah ini di server-metrik
$ 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 :
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"}
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
kubeadm membuat sertifikat di bawah /var/lib/kubelet/pki/kubelet.*
ditandatangani dengan CA berbeda dari yang di bawah /etc/kubernetes/pki/ca.pem
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]
Instal server metrik saat dijalankan:
$ kubectl -n log kube-sistem
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.
@ 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 menyertakanDNS:hostname
.solusi yang memungkinkan:
A) menerapkan menyanyikan pasangan barukubelet.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
danserverTLSBootsrap: true
dan kemudian menyetujui CSR untuk sertifikat pelayanan sepertinya cara termudah untuk masuk ke sini. Sertifikat pelayanan yang diminta / diterbitkan adalahO = system:nodes, CN = system:node:<nodename>
dengan Nama Alternatif Subjek untukDNS: <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
Selamakubeadm init
untuk membuat cluster, Anda juga harus bisa meneruskan file objek KubeletConfiguration API untuk menyetelserverTLSBootstrap
kubeadm init --config=kubeadm-config.yaml
Kemudian semua kubelet akan secara otomatis diatur menggunakan flagserverTLSBootstrap
.
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.
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:
tanpa tanda-tanda ini, kubelet secara default menandatangani sertifikat servisnya saat pertama kali dijalankan, yang dapat diverifikasi dengan:
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 menyertakanDNS: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
D)?
@ kubernetes / sig-cluster-lifycle
bagi saya ini tampak di ruang antara bug / fitur.
lihat juga:
https://github.com/kubernetes/community/pull/602/files