kubestronautへの道 ~CKS編 その4 killer coda「Apiserver NodeRestriction」~

tech article

今日覚えて帰ること

その1

NodeRestrictionは、各ノードに存在するkubeletが、

  • 自分以外のnodeに対してlabelの設定変更をできないようにする
  • 自分のnodeに対してnode-restriction.kubernetes.io/というプレフィックスが付いたlabelの設定変更をできないようにする

admission policyであるということ

その2

あるノードにおいて環境変数KUBECONFIGを設定すると、当該ノードのkubectlはKUBECONFIGに設定されているconfigファイルを参照してkube-apiserverと通信すること

の2点です!

Apiserver NodeRestriction

今回のシナリオは「Apiserver NodeRestriction」です。

Verify the issue

The Kubelet on node01 shouldn’t be able to set Node labels

  • starting with node-restriction.kubernetes.io/*
  • on other Nodes than itself

Verify this is not restricted atm by performing the following actions as the Kubelet from node01 :

  1. add label killercoda/one=123 to Node controlplane
  2. add label node-restriction.kubernetes.io/one=123 to Node node01

node01のkubeletがラベルをセットすることをまだ禁止できていないことを確認していきます。

controlplane $ ssh node01
Last login: Sun Nov 13 17:27:09 2022 from 10.48.0.33

node01 $ cd /etc/kubernetes/
node01 $ ll
total 20
drwxrwxr-x   4 root root 4096 Jul  3 18:51 ./
drwxr-xr-x 107 root root 4096 Jul 28 14:12 ../
-rw-------   1 root root 1959 Jul  3 18:51 kubelet.conf
drwxrwxr-x   2 root root 4096 Jul  3 18:49 manifests/
drwxr-xr-x   2 root root 4096 Jul  3 18:51 pki/

node01 $ export KUBECONFIG=/etc/kubernetes/kubelet.conf 

node01 $ k label node controlplane killercoda/one=123
node/controlplane labeled

node01 $ k label node node01  node-restriction.kubernetes.io/one=123
node/node01 labeled
node01 $ 

まずsshでnode01にログインします。

controlplane $ ssh node01
Last login: Sun Nov 13 17:27:09 2022 from 10.48.0.33

次に、 /etc/kubernetes/kubelet.conf が存在することを確認し、kubectlが認証情報としてkubeletを参照してkube-apiserverに接続するように設定します。

node01 $ cd /etc/kubernetes/
node01 $ ll
total 20
drwxrwxr-x   4 root root 4096 Jul  3 18:51 ./
drwxr-xr-x 107 root root 4096 Jul 28 14:12 ../
-rw-------   1 root root 1959 Jul  3 18:51 kubelet.conf
drwxrwxr-x   2 root root 4096 Jul  3 18:49 manifests/
drwxr-xr-x   2 root root 4096 Jul  3 18:51 pki/

node01 $ export KUBECONFIG=/etc/kubernetes/kubelet.conf 

/etc/kubernetes/kubelet.conf の中身はConfigリソースのマニフェストファイルです。

node01 $ cat /etc/kubernetes/kubelet.conf 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJUU1GblRQeUtYTVl3RFFZSktvWklod
///(省略)
3Yjcyc25HRlJIdFhOUkR3QlZPMHcKS3ZJVTBzN3A5SGJiCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://172.30.1.2:6443
  name: default-cluster
contexts:
- context:
    cluster: default-cluster
    namespace: default
    user: default-auth
  name: default-context
current-context: default-context
kind: Config
preferences: {}
users:
- name: default-auth
  user:
    client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
    client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
node01 $ 

そして環境変数KUBECONFIGを設定することで、kubectlコマンド実行時には設定したConfigファイルを用いてkube-apiserverにアクセスするようになります。(kubectlはそのように実装されています。)

kubeconfigファイルを使用してクラスターアクセスを組織する
kubeconfigを使用すると、クラスターに、ユーザー、名前空間、認証の仕組みに関する情報を組織できます。kubectlコマンドラインツールはkubeconfigファイルを使用してクラスターを選択するために必要な情報を見つけ、クラスターのAPIサーバーと通信します。 備考:クラスターへのアクセスを設定するために使われ...

以下の記事ではより詳細に説明されています。

ラベルがつけられることを確認します。

node01 $ k label node controlplane killercoda/one=123
node/controlplane labeled

node01 $ k label node node01  node-restriction.kubernetes.io/one=123
node/node01 labeled
node01 $ 

Enable the NodeRestriction Admission Controller

Enable the NodeRestriction Admission Controller and verify the issue is gone by trying to

  1. add label killercoda/two=123 to Node controlplane
  2. add label node-restriction.kubernetes.io/two=123 to Node node01

Notice that existing restricted labels won’t be removed once the NodeRestriction is enabled.

NodeRestriction Admission Controllerを使用して、kubeletにラベル付けする権限を与えないようにします。
NodeRestrictionアドミッションプラグインの役割は、kubeletがNodeに対してnode-restriction.kubernetes.io/というプレフィックスを持つラベルを設定したり、また既に存在するそのようなラベルを変更や削除することを禁止することです。

ノード上へのPodのスケジューリング
Podを特定のノードで実行するように 制限 したり、特定のノードで実行することを 優先 させたりといった制約をかけることができます。 これを実現するためにはいくつかの方法がありますが、推奨されている方法は、すべてラベルセレクターを使用して選択を容易にすることです。 多くの場合、このような制約を設定する必要はなく、スケジ...

以下のように、/etc/kubernetes/manifest/kube-apiserver.yamlを修正していきます。

Connection to node01 closed.
controlplane $ cd /etc/kubernetes/manifests/
controlplane $ cp kube-apiserver.yaml kube-apiserver.yaml~
controlplane $ vi kube-apiserver.yaml
controlplane $ diff kube-apiserver.yaml kube-apiserver.yaml~
21d20
<     - --enable-admission-plugins=NodeRestriction

kube-apiserverが再起動されていることを確認します。

Every 2.0s: crictl ps                                                                                                                                controlplane: Sun Jul 28 14:24:02 2024

CONTAINER           IMAGE               CREATED             STATE               NAME                      ATTEMPT             POD ID              POD
97abe89891dcd       c42f13656d0b2       6 seconds ago       Running             kube-apiserver            1                   d4d3ec5e9100d       kube-apiserver-controlplane
d8072dca74165       f9c3c1813269c       20 seconds ago      Running             calico-kube-controllers   3                   24efce1347958       calico-kube-controllers-75bdb5b75d-2b6mr
1541d826afecd       c7aad43836fa5       40 seconds ago      Running             kube-controller-manager   4                   78cc50e25f02b       kube-controller-manager-controlplane
25d583b3ffdc1       259c8277fcbbc       44 seconds ago      Running             kube-scheduler            4                   e7f7d9f48433f       kube-scheduler-controlplane
e944e91735629       13ebff5b37ba8       10 minutes ago      Running             local-path-provisioner    2                   d7cd6372d3cb7       local-path-provisioner-75655fcf79-xw9b6
5e4e5853cf91d       e6ea68648f0cd       11 minutes ago      Running             kube-flannel              1                   299a78041b23f       canal-wzjz6
a444f2c6990b6       75392e3500e36       11 minutes ago      Running             calico-node               1                   299a78041b23f       canal-wzjz6
98fcc8f6d1c1c       a0bf559e280cf       11 minutes ago      Running             kube-proxy                2                   5fc168afadb11       kube-proxy-dp5fn
79fdb9d4e649d       3861cfcd7c04c       11 minutes ago      Running             etcd                      2                   13a530f45a05a       etcd-controlplane

kube-apiserverのログから、NodeRestrictionが有効化されていることを確認します。

controlplane $ k logs -n kube-system kube-apiserver-controlplane | grep noderestriction -i
I0728 14:33:31.234385       1 plugins.go:157] Loaded 12 mutating admission controller(s) successfully in the following order: NamespaceLifecycle,LimitRanger,ServiceAccount,NodeRestriction,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,RuntimeClass,DefaultIngressClass,MutatingAdmissionWebhook.
controlplane $ 

sshでnode01にログインします。
NodeRestrictionを有効化すると、

  • kubeletが自分のノード以外に対して操作(ラベルづけのみ?)ができない
  • node-restriction.kubernetes.ioという内容が含まれるノードを追加や修正ができない

状態になります。
それを検証しているのが以下です。

controlplane $ ssh node01
Last login: Sun Jul 28 14:18:58 2024 from 10.244.7.5


node01 $ export KUBECONFIG=/etc/kubernetes/kubelet.conf
node01 $  k label node controlplane killercoda/two=123 # restricted
Error from server (Forbidden): nodes "controlplane" is forbidden: node "node01" is not allowed to modify node "controlplane"

node01 $ k label node node01 node-restriction.kubernetes.io/two=123 # restricted
Error from server (Forbidden): nodes "node01" is forbidden: is not allowed to modify labels: node-restriction.kubernetes.io/two

node01 $  k label node node01 test/two=123 # works
node/node01 labeled
タイトルとURLをコピーしました