---
# System prepended metadata

title: PodNodeSelector admission webhook 實作
tags: [K8S]

---

# 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



