# K8s NetworkPolicy 深入研討實戰 在 NetworkPolicy 規則裡針對一個 pod 如果有 deny 的規則,這時在新增一個 allow 的 NetworkPolicy 規則,則 allow 是會覆蓋掉 deny 的規則。 ## 題目一 Context You need to allow a pod to connect to each other over the network only with two other pods, but not with pods other than these two. Task Update Pod `ckad00018-newpod` in namespace ckad00018 to use a Networkpolicy that only allows this pod to send and receive traffic to and from pod `front` and `db`. * All necessary NetworkPolicy have been established. * Do not create, modify, or delete any NetworkPolicy while completing this project; you can only use existing NetworkPolicy. > 在 `ckad00018` namespace 下有 `ckad00018-newpod`、`front`、`db` 這三個 pod,允許 `ckad00018-newpod` pod 可以訪問 `front`、`db` 這兩個 pod,但 `front`、`db` 這兩個 pod 之間不允許互相訪問。 ### 環境準備 * 建立 pod ``` $ kubectl create ns ckad00018 namespace/ckad00018 created $ kubectl -n ckad00018 run front \ --image=quay.io/cloudwalker/nginx \ -l "app=front" pod/front created $ kubectl -n ckad00018 run db \ --image=quay.io/cloudwalker/nginx \ -l "app=db" pod/db created $ kubectl -n ckad00018 run ckad00018-newpod \ --image=quay.io/cloudwalker/nginx \ -l "app=ckad00018-newpod" pod/ckad00018-newpod created ``` * 建立 NetworkPolicy 規則 ``` $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: ckad00018 spec: podSelector: {} policyTypes: - Ingress EOF $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: all-access namespace: ckad00018 spec: podSelector: matchLabels: all-access: "true" ingress: - {} egress: - {} EOF $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-db namespace: ckad00018 spec: podSelector: matchLabels: app: db ingress: - from: - podSelector: matchLabels: db-access: "true" egress: - to: - podSelector: matchLabels: db-access: "true" EOF $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-front namespace: ckad00018 spec: podSelector: matchLabels: app: front ingress: - from: - podSelector: matchLabels: front-access: "true" egress: - to: - podSelector: matchLabels: front-access: "true" EOF ``` ``` $ kubectl -n ckad00018 get po -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ckad00018-newpod 1/1 Running 0 5m42s 10.244.41.12 tkdev-worker1 <none> <none> db 1/1 Running 0 5m46s 10.244.42.8 tkdev-worker2 <none> <none> front 1/1 Running 0 5m52s 10.244.41.11 tkdev-worker1 <none> <none> $ kubectl -n ckad00018 get netpol NAME POD-SELECTOR AGE access-db app=db 31s access-front app=front 11s all-access all-access=true 3m31s default-deny <none> 3m36s ``` ### 解答 * 在目前情況因為 `default-deny` NetworkPolicy 對每個 pod 都禁止 Ingress(進入) 的流量,因此目前這三個 pod 是互相都連不到的。 ``` $ kubectl -n ckad00018 exec ckad00018-newpod -- curl 10.244.42.8 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0 $ kubectl -n ckad00018 exec db -- curl 10.244.41.11 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0 ``` * 檢視 `access-db` networkpolicy,允需帶有 `app=db` label 的 pod ,可以接受帶有 `db-access=true` label 進入與出去的流量。 ``` $ kubectl -n ckad00018 describe networkpolicy access-db Name: access-db Namespace: ckad00018 Created on: 2024-11-16 23:24:37 +0800 CST Labels: <none> Annotations: <none> Spec: PodSelector: app=db Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From: PodSelector: db-access=true Allowing egress traffic: To Port: <any> (traffic allowed to all ports) To: PodSelector: db-access=true Policy Types: Ingress, Egress ``` * 檢視 `access-front` networkpolicy,允需帶有 `app=front` label 的 pod ,可以接受帶有 `front-access=true` label 進入與出去的流量。 ``` $ kubectl -n ckad00018 describe networkpolicy access-front Name: access-front Namespace: ckad00018 Created on: 2024-11-16 23:24:57 +0800 CST Labels: <none> Annotations: <none> Spec: PodSelector: app=front Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From: PodSelector: front-access=true Allowing egress traffic: To Port: <any> (traffic allowed to all ports) To: PodSelector: front-access=true Policy Types: Ingress, Egress ``` * 因此這題的作答,就是將 `ckad00018-newpod` pod 貼上 `front-access=true` 與 `db-access=true` label ``` $ tl -n ckad00018 get pods -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS ckad00018-newpod 1/1 Running 0 54m 10.244.41.12 tkdev-worker1 <none> <none> app=ckad00018-newpod db 1/1 Running 0 54m 10.244.42.8 tkdev-worker2 <none> <none> app=db front 1/1 Running 0 54m 10.244.41.11 tkdev-worker1 <none> <none> app=front $ kubectl -n ckad00018 label pod ckad00018-newpod front-access=true $ kubectl -n ckad00018 label pod ckad00018-newpod db-access=true ``` * 驗證 `ckad00018-newpod` 可以訪問 `db`、`front` 這兩個 pod,且 `db`、`front` 這兩個 pod 互相是不能溝通的。 ``` $ kubectl -n ckad00018 exec ckad00018-newpod -- curl 10.244.42.8 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 615 100 615 0 0 393k 0 --:--:-- --:--:-- --:--:-- 600k <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> $ kubectl -n ckad00018 exec ckad00018-newpod -- curl 10.244.41.11 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 615 100 615 0 0 337k 0 --:--:-- --:--:-- --:--:-- 600k <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> $ kubectl -n ckad00018 exec db -- curl 10.244.41.11 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0 ``` ### 題外 * 在這個情況下雖然 `ckad00018-newpod` 可以訪問 `db`、`front` 這兩個 pod,但 `db`、`front` 是不能訪問 `ckad00018-newpod` 的,原因是因為 `ckad00018-newpod` 的 Ingress(進入) 的流量被阻擋了。 ``` # 新增這個 NetworkPolicy 後,`front` 就可以訪問 `ckad00018-newpod` 了,`db` 以此類推。 $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test namespace: ckad00018 spec: podSelector: matchLabels: app: ckad00018-newpod ingress: - from: - podSelector: matchLabels: app: front EOF ``` ## 題目二 有兩個 namespace `demo1`、`demo2`,設計 NetworkPolicy 拒絕這兩個 namespace 之間所有網路流量,但只允 `demo1` namespace 下帶有 `app=demo1` 與 `demo2` namespace 下帶有 `app=demo2` 這兩個 label 的 pod 網路可以互通。 ### 環境準備 * 建立 pod ``` $ kubectl create ns demo1 $ kubectl create ns demo2 $ kubectl -n demo1 run demo1-front \ --image=quay.io/cloudwalker/nginx \ -l "app=demo1" $ kubectl -n demo2 run demo2-front \ --image=quay.io/cloudwalker/nginx \ -l "app=demo2" ``` * 還沒有 NetworkPolicy,所有流量都是互通的 ``` $ kubectl -n demo1 get pod -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS demo1-front 1/1 Running 0 118m 10.244.41.4 tkdev-worker1 <none> <none> app=demo1 $ kubectl -n demo2 get pod -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS demo2-front 1/1 Running 0 19s 10.244.41.3 tkdev-worker1 <none> <none> app=demo2 $ kubectl -n demo1 exec demo1-front -- curl http://10.244.41.3:80 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ``` ### 解答 * 設定拒絕 `demo1` namespace 下所有的 pod 出去與進來的流量 ``` $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: demo1 spec: podSelector: {} policyTypes: - Ingress - Egress EOF ``` * 設定拒絕 `demo2` namespace 下所有的 pod 出去與進來的流量 ``` $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: demo2 spec: podSelector: {} policyTypes: - Ingress - Egress EOF ``` ``` $ kubectl -n demo1 get netpol NAME POD-SELECTOR AGE deny-all <none> 58s $ kubectl -n demo2 get netpol NAME POD-SELECTOR AGE deny-all <none> 61s ``` * 在 `demo1` namespace 針對帶有 `app=demo1` label 的 pod 允許接受來自 `demo2` namespace 下帶有 `app=demo2` label 的 pod 過來與過去的流量。 ``` $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-front namespace: demo1 spec: podSelector: matchLabels: app: demo1 ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: demo2 podSelector: matchLabels: app: demo2 egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: demo2 podSelector: matchLabels: app: demo2 EOF ``` * 在 `demo2` namespace 允許帶有 `app=demo2` label 的 pod 接受來自 demo1 namespace 下帶有 `app=demo1` label 的 pod 過來與過去的流量。 ``` $ cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-front namespace: demo2 spec: podSelector: matchLabels: app: demo2 ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: demo1 podSelector: matchLabels: app: demo1 egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: demo1 podSelector: matchLabels: app: demo1 EOF ``` * 驗證兩個 namespace 之間只允許帶有 `app=demo1` 與 `app=demo2` 這兩個 label 的 pod 網路互通。 ``` $ kubectl -n demo1 exec demo1-front -- curl http://10.244.41.3:80 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> $ kubectl -n demo2 exec demo2-front -- curl http://10.244.41.4:80 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up