# PodNodeSelector admission webhook 實作 * 透過 PodNodeSelector admission webhook 限制 namespace 所產生的 workload 只能跑在指定節點上。 ## 實作 * 在 RKE2 apiserver 啟用 `enable-admission-plugins=PodNodeSelector` 參數,預設 `PodNodeSelector` 這個功能是沒有開啟的。 ![image](https://hackmd.io/_uploads/rky7tIl51e.png) ### 驗證 * 我的環境有三個節點 ``` $ kubectl get node NAME STATUS ROLES AGE VERSION demo-1 Ready control-plane,etcd,master,worker 59d v1.29.11+rke2r1 demo-2 Ready control-plane,etcd,master,worker 59d v1.29.11+rke2r1 demo-3 Ready control-plane,etcd,master,worker 59d v1.29.11+rke2r1 ``` * 建立 test namespace,並指定在這個 namespace 產生的 pod 都只能跑在 demo-3 這個節點上。 ``` $ echo 'apiVersion: v1 kind: Namespace metadata: annotations: scheduler.alpha.kubernetes.io/node-selector: kubernetes.io/hostname=demo-3 name: test' | kubectl apply -f - ``` * 在沒有宣告 nodeSelector 情況下,預設 pod 都只會跑在 demo-3 這個節點上。 ``` $ kubectl -n test create deploy test --image=quay.io/cooloo9871/nginx $ kubectl -n test get po -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-58f589487f-vzhv2 1/1 Running 0 38s 10.42.29.13 demo-3 <none> <none> $ kubectl -n test scale deploy test --replicas=5 $ kubectl -n test get po -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-58f589487f-5hr49 1/1 Running 0 7s 10.42.29.29 demo-3 <none> <none> test-58f589487f-8t67s 1/1 Running 0 7s 10.42.29.33 demo-3 <none> <none> test-58f589487f-9p2cg 1/1 Running 0 7s 10.42.29.17 demo-3 <none> <none> test-58f589487f-sccfx 1/1 Running 0 7s 10.42.29.22 demo-3 <none> <none> test-58f589487f-vzhv2 1/1 Running 0 62s 10.42.29.13 demo-3 <none> <none> ``` * 如果指定了 nodeSelector ,就會出現 pod 指定的 node label selector 與 namespace 指定的不符合,並且拒絕產生 pod。 ``` $ echo 'apiVersion: v1 kind: Pod metadata: name: nginx namespace: test spec: containers: - image: quay.io/cooloo9871/nginx name: nginx nodeSelector: kubernetes.io/hostname: demo-1' | kubectl apply -f - Error from server (Forbidden): error when creating "STDIN": pods "nginx" is forbidden: pod node label selector conflicts with its namespace node label selector ``` ![image](https://hackmd.io/_uploads/By0D5Ulq1x.png) * 但如果是透過 nodeName 宣告,會顯示 created,但實際上 pod 是不會 running 的。 ``` $ echo 'apiVersion: v1 kind: Pod metadata: name: nginx namespace: test spec: containers: - image: quay.io/cooloo9871/nginx name: nginx nodeName: demo-1' | kubectl apply -f - pod/nginx created ``` ![image](https://hackmd.io/_uploads/SJThqLx9kl.png) ## 參考 https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#podnodeselector