Kubeadm: 署名されたkubeletサービング証明書を使用する

作成日 2018年11月09日  ·  38コメント  ·  ソース: kubernetes/kubeadm

これはバグレポートですか、それとも機能リクエストですか?

/種類のバグ

メトリックサーバーでこの問題kubeadm側を開く

バージョン

$ 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"}

環境

  • Kubernetesバージョン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"}
  • クラウドプロバイダーまたはハードウェア構成
    どれか
  • OS (例:/ etc / os-releaseから):
    どれか
  • カーネル(例: 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は、 /etc/kubernetes/pki/ca.pem下のCAとは異なるCAで署名された/var/lib/kubelet/pki/kubelet.*下の証明書を作成します

あなたは何が起こると思っていましたか?

その結果、metrics-serverなどの一部のアプリは、K8sマスターとは異なるcaによって署名された証明書がkubeletにあるため、セキュリティで保護されたkubeletから統計を収集できません。

エラーサンプル:

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]

それを(可能な限り最小限かつ正確に)再現する方法は?

実行時にmetrics-serverをインストールし

$ kubectl -nkube-システムログ

他に知っておくべきことはありますか?

ここにもう少し背景

問題を修正するために私が従った手順もそこにあります。


編集:neolit123

ここでの問題は、サービング証明書がデフォルトで自己署名されていることです。
ドキュメントの更新については、 https://github.com/kubernetes/website/pull/27071を参照して

aresecurity help wanted kinbug kinfeature lifecyclfrozen prioritimportant-longterm

最も参考になるコメント

問題を要約しましょう:

@anitgandhiによって概説されている
https://github.com/kubernetes/kubeadm/issues/1223#issuecomment -454572577

ここでのkubeadmの問題は、いくつかのフラグをkubeletに渡していないことです。

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

これらのフラグがないと、kubeletはデフォルトで、最初に実行されたときにサービング証明書に自己署名します。これは次の方法で確認できます。

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

クラスタCAによって署名された証明書( /etc/kubernetes/ca.crt )の代わりに自己署名証明書を使用すると、自己署名証明書SANにはDNS:hostnameしか含まれないため、メトリックサーバーのような展開ではkubeletをスクレイピングできません。

可能な解決策:
A)新しいkubelet.crt/keyペアの歌を実装します。理想的には/var/lib/kubelet/pki下で、追加のkubeletフラグ--tls-cert-file--tls-private-key-fileます。

B)ドキュメントとは、 @ raravena80がここで行ったのと同様に、オンデマンドでこれを有効にすることを意味します: https//stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
おそらくKubernetesCSR / kubeadmコマンドを使用する場合を除きます。

C) @alexbrandによるコメント

可能であれば、サービング証明書を要求/ローテーションするために、kubeletに組み込まれているTLSブートストラップ機能を使用する必要があると思います。

D)?

@ kubernetes / sig-cluster-lifecycle
私には、これはバグ/機能の間のスペースにあるように思われます。

参照:
https://github.com/kubernetes/community/pull/602/files

全てのコメント38件

@ raravena80 /var/lib/kubelet/pki/下でkubeadmによって作成された証明書を知りません..詳細を教えていただけますか? 例:kubeadm構成ファイル、クラスターを作成する手順

@fabriziopandini証明書がkubeadmによって作成されているかどうかは完全にはここで説明されてい

ディレクトリの内容は次のようになります。

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#

それらkubelet.crt 、kubeletが最初にロードされたときに作成されたkubelet.keyファイルと

@ raravena80説明してくれてありがとう
おそらく私はここで完全な文脈を持っていないので、私は他の人に答える余地を残します。

片方のメモだけ(それが役立つかもしれません)
Kubeadmは、APIサーバーがkubeletsと安全に通信できるようにするために、 apiserver-kubelet-clientという名前の証明書をすでに作成しています。 caによって署名され、必要なRBACルールにバインドされます。

/ assign @liztio

これは、kubeletのサーバー証明書を事前に生成するためだと思い

私の知る限り、現時点での唯一の回避策は、Kubeletのサーバー証明書を帯域外で生成し、それらを決定論的なパスに配置することです。kubelet(kubeadmによって構成されます)がそれを取得し、それに応じていくつかのkubeletフラグを設定します。 ; 参照: https ://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/#client -and-serving-certificates

apiserver-kubelet-clientは、APIサーバーがkubeletに提示するクライアント証明書ですが、kubeletは、k8sCAによって署名されたクライアントを信頼するように構成されています。

# 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

k8s CAによって署名される必要があるのは、提示されているサーバーとしてのkubeletのIDであり、元の質問に出くわします。

このスレッドの最後にいくつかの関連する議論もあります: https

kubeadmは、クライアント証明書要求の場合と同様に、有効なブートストラップトークンを使用してサーバー証明書要求のCSR承認者を追加する必要があると思いますか?

kubeletに自己署名CAをどこかのconfigmapにアップロードさせるのはどうですか? nodeadmissionプラグインは、それを独自のconfigmapだけに制限することができます。 メトリックサーバーはそれを使用してノードに接続できます。

それについて何かアイデアはありますか?

可能であれば、サービング証明書を要求/ローテーションするために、kubeletに組み込まれているTLSブートストラップ機能を使用する必要があると思います。

@alexbrand私はそれに同意します

kubelet TLSブートストラップは、何らかの理由でクライアント証明書のみを生成します。
--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.

そして、kubeadmはすでにこれを行っています。 おそらくこれはkubelet機能のリクエストですか?

問題を要約しましょう:

@anitgandhiによって概説されている
https://github.com/kubernetes/kubeadm/issues/1223#issuecomment -454572577

ここでのkubeadmの問題は、いくつかのフラグをkubeletに渡していないことです。

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

これらのフラグがないと、kubeletはデフォルトで、最初に実行されたときにサービング証明書に自己署名します。これは次の方法で確認できます。

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

クラスタCAによって署名された証明書( /etc/kubernetes/ca.crt )の代わりに自己署名証明書を使用すると、自己署名証明書SANにはDNS:hostnameしか含まれないため、メトリックサーバーのような展開ではkubeletをスクレイピングできません。

可能な解決策:
A)新しいkubelet.crt/keyペアの歌を実装します。理想的には/var/lib/kubelet/pki下で、追加のkubeletフラグ--tls-cert-file--tls-private-key-fileます。

B)ドキュメントとは、 @ raravena80がここで行ったのと同様に、オンデマンドでこれを有効にすることを意味します: https//stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
おそらくKubernetesCSR / kubeadmコマンドを使用する場合を除きます。

C) @alexbrandによるコメント

可能であれば、サービング証明書を要求/ローテーションするために、kubeletに組み込まれているTLSブートストラップ機能を使用する必要があると思います。

D)?

@ kubernetes / sig-cluster-lifecycle
私には、これはバグ/機能の間のスペースにあるように思われます。

参照:
https://github.com/kubernetes/community/pull/602/files

ブートストラップトークンクライアント証明書/ CSRロジックkubelet + kubeadmの多くはこれに共通のロジックを持っているため、オプションB + Cの間で何かを行う必要があると思います。

問題を要約しましょう:

@anitgandhiによって概説されている
#1223(コメント)

ここでのkubeadmの問題は、いくつかのフラグをkubeletに渡していないことです。

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

これらのフラグがないと、kubeletはデフォルトで、最初に実行されたときにサービング証明書に自己署名します。これは次の方法で確認できます。

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

クラスタCAによって署名された証明書( /etc/kubernetes/ca.crt )の代わりに自己署名証明書を使用すると、自己署名証明書SANにはDNS:hostnameしか含まれないため、メトリックサーバーのような展開ではkubeletをスクレイピングできません。

可能な解決策:
A)新しいkubelet.crt/keyペアの歌を実装します。理想的には/var/lib/kubelet/pki下で、追加のkubeletフラグ--tls-cert-file--tls-private-key-fileます。

B)ドキュメントとは、 @ raravena80がここで行ったのと同様に、オンデマンドでこれを有効にすることを意味します: https//stackoverflow.com/questions/53212149/x509-certificate-signed-by-unknown-authority-kubeadm/53218524#53218524
おそらくKubernetesCSR / kubeadmコマンドを使用する場合を除きます。

C)@alexbrandによるコメント

可能であれば、サービング証明書を要求/ローテーションするために、kubeletに組み込まれているTLSブートストラップ機能を使用する必要があると思います。

D)?

@ kubernetes / sig-cluster-lifecycle
私には、これはバグ/機能の間のスペースにあるように思われます。

参照:
https://github.com/kubernetes/community/pull/602/files

素晴らしい要約@ neolit123 。 これが次のサイクルに進むのか、それとも私たちが話すときに進行中の作業になるのか知っていますか? 主に、すべてのデプロイメントでどのimoが必要なメトリックサーバーであるかを尋ねます;)

@randomvariableは、そのための別の回避策があると述べました。
これまでの議論から、クラスターCAを使用してkubelet-serving証明書に署名することを躊躇しています。 このトピックについては、さらに議論する必要があります。

/ remove-help

実装するソリューションがまだ選択されていないためです。

これに関する動きはありますか? kubeadmでデプロイされたクラスター内の自動スケーリング機能をサポートするためにこれに直面しています。

現在の回避策は、kubelet証明書のCAチェックをオフにすることです。

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

実際には、それは設計提案でブロックされています。
いくつかの回避策がありますが、それらを文書化する作業は行き詰まりました。
https://github.com/kubernetes/kubeadm/issues/1602

--kubelet-insecure-tls

これは、すべてのユーザーにとって理想的ではない場合があります。

90日間操作がないと、問題は古くなります。
/remove-lifecycle staleして、問題を新規としてマークします。
古い問題は、さらに30日間操作がないと腐敗し、最終的には閉じます。

この問題を今すぐ解決できる場合は、 /close

SIG-テスト、kubernetes /テスト・インフラおよび/またはへのフィードバックを送信fejta
/ lifecycle stale

/ライフサイクル凍結

kubeadmを使用してv1.18.2クラスターを作成すると、この正確な問題が発生します。

メトリックサーバーを設定する場合、 kubelet-insecure-tlsフラグを設定するか、「帯域外」のkubletの証明書を発行して、kubernetesCAで署名しないと機能しません。

kubeletクライアント証明書を再利用することを考えましたが、それはもちろんCN = system:node:nodename発行され、SANは発行されません。 そして、もちろんそれを示すためにエラーを変更しますが、私はそれをテストしました。 サブジェクト代替名としてノード名が含まれている場合、同じ証明書をサーバー/クライアントの両方として使用できますか? しかし、サーバー/クライアントに別々の証明書を使用する方が適切だと思いますか?

/ remove-ライフサイクルが凍結されました

/ライフサイクル凍結

ボットが問題を解決しないように凍結されています。

サブジェクト代替名としてノード名が含まれている場合、同じ証明書をサーバー/クライアントの両方として使用できますか?

理論的には、kubeletがそれらを検証しない限り、たとえば「クライアント証明書にはSANが含まれていてはなりません」。

しかし、サーバー/クライアントに別々の証明書を使用する方が適切だと思いますか?

回避できると思われる場合でも、別々に使用するのが一般的な方法です。 kubelet / auth {z | n}メンテナがこの詳細を変更する可能性はほとんどありません。

ねえ。 もう少し掘りました。 Kubelet構成オプションserverTLSBootstrap: trueは、実際にサービング証明書のCSRを作成できます。 しかし、それは未承認のままです。 どちらでも大丈夫ですか?

rotateCertificates: trueserverTLSBootsrap: true両方を設定してから、サービング証明書のCSRを承認するのが、ここに行く最も簡単な方法のようです。 要求/発行されるサービング証明書はO = system:nodes, CN = system:node:<nodename> 、サブジェクト代替名はDNS: <nodename>, IP Address: <node IP address>

kubeadmは少なくともserverTLSBootstrap構成オプションを有効にする必要があるので、サーバー証明書の承認は簡単です。 または、kubeadmでさえ承認を行うことができますか?

ねえ。 もう少し掘りました。 Kubelet構成オプションserverTLSBootstrap: trueは、実際にサービング証明書のCSRを作成できます。 しかし、それは未承認のままです。 どちらでも大丈夫ですか?

rotateCertificates: trueserverTLSBootsrap: true両方を設定してから、サービング証明書のCSRを承認するのが、ここに行く最も簡単な方法のようです。 要求/発行されるサービング証明書はO = system:nodes, CN = system:node:<nodename> 、サブジェクト代替名はDNS: <nodename>, IP Address: <node IP address>

kubeadmは少なくともserverTLSBootstrap構成オプションを有効にする必要があるので、サーバー証明書の承認は簡単です。 または、kubeadmでさえ承認を行うことができますか?

セキュリティの実装はわかりませんが、 serverTLSBootstrapをこの演算子と組み合わせて、CSRを自動承認することができますhttps://github.com/kontena/kubelet-rubber-stamp

kubeadmは少なくともserverTLSBootstrap構成オプションを有効にする必要があるので、サーバー証明書の承認は簡単です。 または、kubeadmでさえ承認を行うことができますか?

kubeadmはデーモンではないため、kubeadmは承認を行うことができません。 ユーザーのためにそれを管理するコントローラー/オペレーターをデプロイする必要があります。 多分将来的に。

証明書APIはまもなくGAに移行するはずであり、k8sでこれを管理するためのより良い方法があることを願っています。 見てください:
https://github.com/kubernetes/enhancements/issues/267
(私には、私たちが最終的に何をするのかはまだわかりません...)

代替案もあります。 しかし、これがすべてメトリックサーバーの問題を解決しようとしている場合は、kubeletへのMSリクエストでSARを実行できるhttps://github.com/brancz/kube-rbac-proxyを使用することもできます。 悲しいことに、これはまだ私たちの側で文書化されていません:
https://github.com/kubernetes/kubeadm/issues/1602

@ neolit123少なくとも、kubeadmでメトリクスサーバーを立ち上げて、学習体験のための「難しい方法」のクラスターを構築しようとしたときに、--kubelet-insecure-tlsフラグを立てるのが最も簡単な方法でしたが、安全な方法で修正する方法を本当に知りたかったので、問題に興味を持ちました。 🙂

今のところ、 serverTLSbootstrapフラグをkubelet構成に追加して、証明書を手動で承認するのは簡単です。 ただし、証明書を承認するまでノード上のポッドと完全に対話できないという欠点に気づきました。 (たとえば、kubectl execは、承認前にノードで実行されているポッドでコマンドを実行できません)

拡張機能の問題についても説明します。 ありがとう。

十分に成熟しているように見えるkubeadmを使用すると、kubeletet証明書の結果が自己署名され、多くの人が適切に処理する代わりにメトリックサーバーにkubelet-insecure-tlsを選択するのは本当に悲しいことです:(

それは複雑な問題です。

してみてください:
https://github.com/kontena/kubelet-rubber-stamp
または
https://github.com/brancz/kube-rbac-proxy
回避策として

それは複雑な問題です。

してみてください:
https://github.com/kontena/kubelet-rubber-stamp
または
https://github.com/brancz/kube-rbac-proxy
回避策として

実際、 https://github.com/kontena/kubelet-rubber-stampはかなりうまく機能し、プロキシではなくimoの方が正しい解決策のようです。

ステップ1:
追加
serverTLSBootstrap: trueは、kubeletsの再構成のためにすべての/var/lib/kubelet/config.yamlの最後にあり、構成を適用することを忘れないでください(または単に再起動してください)

ステップ2:
kubelet-rubber-stampをデプロイし

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

ステップ3:
メトリックの編集-サーバーの展開と--kubelet-insecure-tls削除

結果:

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

ねえ、@ vainkopに追加するだけ
クラスターを作成するための最初のkubeadm init中に、KubeletConfiguration APIオブジェクトファイルを渡してserverTLSBootstrapを設定することもできるはずです。

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

..。

apiVersion:kubelet.config.k8s.io/v1beta1
種類:KubeletConfiguration
serverTLSBootstrap:true

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

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

To get the CSRs

kubectl get csr
NAME AGE SIGNERNAME REQUESTORCONDITION
csr-2qkdw 2m1s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap :fcufbo承認済み、発行済み
csr-9wvgt 114s kubernetes.io/kubelet-serving system:node :worker-1保留中
csr-lz97v 4m58s kubernetes.io/kubelet-serving system:node :master-1保留中
csr-rsdsp 4m59s kubernetes.io/kube-apiserver-client-kubelet system:node :master-1承認済み、発行済み
csr-wgxqs 4m49s kubernetes.io/kubelet-serving system:node :master-1保留中

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証明書はcsr-ab123を承認します#またはラバースタンプを展開します!

kubectl get csr
NAME AGE SIGNERNAME REQUESTORCONDITION
csr-9wvgt 3m kubernetes.io/kubelet-serving system:node :worker-1承認済み、発行済み
..。
`` `

ここでもう1つの奇妙なことが起こっているようです。それは、マスターノードがCSRを2回作成しているように見えることです。 (少なくとも2回はこれを試しました)

しかし、 @ nijaveが上記のコメントで述べているように、ラバースタンパーを使用することのセキュリティへの影響が何であるかは

@ allir@ vainkopは、kubelet-rubber-stampが、CSRの共通名がリクエスター名と一致するかどうかのみを確認し、kubeletによって要求された追加のホスト名とIPアドレスが有効かどうかを確認しないことを確認できます。 つまり、kubeletクライアント証明書にアクセスできる攻撃者は、基本的に任意のドメイン名またはIPアドレスの証明書を作成できます。 ルートCAを信頼するように構成されているすべてのクライアントは、この証明書を受け入れます。
もちろん、特定のkubeletに有効なホスト名とIPアドレスを検証することは困難です。これは、現在、kubeletが何を要求できるかを確認できる権限がないためです。 たとえば、kubeletsは制限なしでオブジェクトを更新できるため、APIサーバーでノードオブジェクトを使用するだけでは不十分です。

ねえ、@ vainkopに追加するだけ
クラスターを作成するための最初のkubeadm init中に、KubeletConfiguration APIオブジェクトファイルを渡してserverTLSBootstrapを設定することもできるはずです。
kubeadm init --config=kubeadm-config.yaml
次に、すべてのkubeletがserverTLSBootstrapフラグを使用して自動的に設定されます。

または、Ansibleを使用した既存のK8sセットアップの場合、次のようになります。

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

+ kubeletsを再起動します

うわー、私はこの問題を見つけてとてもうれしいです、そしてこれを適切な方法で作りたいと思っているのは私だけではありません。 :)

今、私はこの問題についての私の考えを共有させて

最初に、元の問題に対する私のビジョン:
現在、kubeadmはデフォルトですべてのkubeletのWebhook認証を有効にしているため、 --kubelet-insecure-tlsオプションが指定されていても、kubeletは着信接続のクライアント証明書を問題なく検証しています。
反対側のメトリックから-サーバーはノード上で自己署名されているため、特定のkubelet証明書を検証する機会がありません。

メトリックサーバーに--kubelet-insecure-tlsを使用することで発生する可能性のあるリスク:
kubeletデータはある程度保護されており、Webhook認証が成功しないとmetrics-serverに提供されることはありません。
理論的には、誰かがサーバーのIPまたはホスト名を危険にさらし、間違った統計を提供する可能性があります。 ただし、接続を確立するために、metricserverはkube-apiserverを介してノードに指定されたIPアドレスとホスト名を使用しているため、攻撃者は最初にAPIサーバー、DNS、またはノードのIPアドレスをハッキングする必要があります。

少しの観察:
メトリックサーバーは、kubeletsに直接アクセスする単一のサービスではありません。 Kube-apiserverは、コンテナログを読み取ったり、それらに対してシェルを実行したりするためにもこれを実行します。 良い質問は、kube-apiserverが、証明書を発行したCAに関する情報がないときに、特定のkubeletとの接続を確立することをどのように確認するかです。
この場合、 --kubelet-insecure-tlsオプションを使用したメトリックサーバーと同じように動作しませんか?

考えられる解決策:
現在、WebhookとAPIアグリゲーションはKubernetesで非常に人気があります。 それらはすべて、独自のCAとcrt / keyペアを生成することにより、同じように動作します。 CAハッシュも特定のリソースに格納され、kube-apiserverに信頼できる証明書に関する情報を提供します。

例えば:

  • APIServicesは、関連するCAハッシュをapiservices.apiregistration.k8s.ioリソースに格納しています。

    spec:
    caBundle: <ca-hash>
    
  • Webhookは、関連するCAハッシュをvalidatingwebhookconfigurations.admissionregistration.k8s.ioおよびmutatingwebhookconfigurations.admissionregistration.k8s.ioリソースに格納しています。

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

私には、各ノードリソースのspecに同様のcaBundleが必要であることは明らかです。ここで、kubeletsは、クライアント証明書を使用してサービスを提供するために独自のCAを登録できます。

spec:
  caBundle: <ca-hash>

metris-serverとkube-apiserverはどちらも、これらの証明書を使用して、kubeletsへの接続を確認および信頼する必要があります。

以前に同様のアイデアを表明してくれた@ kfox1111に感謝しますhttps://github.com/kubernetes/kubeadm/issues/1223#issuecomment-460854312

良い質問は、kube-apiserverが、証明書を発行したCAに関する情報がないときに、特定のkubeletとの接続を確立することをどのように確認するかです。
この場合、 --kubelet-insecure-tlsオプションを使用したメトリックサーバーと同じように動作しませんか?

この質問に答えるために、私はここで@luxasを引用することができます:

そうです、各kubeletには独自の自己署名証明書があるため、APIサーバーからkubeletサーバーへの接続を検証することはできません。 将来、kubeletサービング証明書のフローを手動で承認することを検討する可能性がありますが、現時点ではデフォルトで保護されていません。

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

いつか解決できることを願っています

[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

この問題からのニュースはありませんか? 私もこれに対する解決策を持っていることに興味があります。

ここで回避策を文書化しています:
https://github.com/kubernetes/website/pull/27071
https://github.com/kubernetes/kubeadm/issues/1602

この問題は未解決のままにしておくことができますが、デフォルトでkubeadmを使用して署名者をデプロイする必要があるという複雑さのため、この変更をすぐに行うことはほとんどありません。

このページは役に立ちましたか?
0 / 5 - 0 評価