Môi trường thử nghiệm
Cài đặt môi trường cơ bản
Tạo các namespace và pod để kiểm tra:
[root@master01 networktest]# vi namespace-test-01.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-ns-01
labels:
environment: test-ns-01
[root@master01 networktest]# vi namespace-test-02.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-ns-02
labels:
environment: test-ns-02
[root@master01 networktest]# vi namespace-test-03.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-ns-03
labels:
environment: test-ns-03
[root@master01 networktest]# vi namespace-test-04.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-ns-04
labels:
environment: test-ns-04
[root@master01 networktest]# vi pod-alpha.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-alpha
namespace: test-ns-01
labels:
application: pod-alpha
spec:
containers:
- name: container-alpha
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# vi pod-beta.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-beta
namespace: test-ns-01
labels:
application: pod-beta
spec:
containers:
- name: container-beta
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# vi pod-gamma.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-gamma
namespace: test-ns-01
labels:
application: pod-gamma
spec:
containers:
- name: container-gamma
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# vi pod-delta.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-delta
namespace: test-ns-02
labels:
application: pod-delta
spec:
containers:
- name: container-delta
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# vi pod-epsilon.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-epsilon
namespace: test-ns-03
labels:
application: pod-epsilon
spec:
containers:
- name: container-epsilon
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# vi pod-zeta.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-zeta
namespace: test-ns-04
labels:
application: pod-zeta
spec:
containers:
- name: container-zeta
image: nginx:alpine
imagePullPolicy: IfNotPresent
restartPolicy: Always
[root@master01 networktest]# kubectl apply -f .
Kiểm tra trạng thái các pod đã được tạo:
[root@master01 networktest]# kubectl -n test-ns-01 get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-alpha 1/1 Running 0 30s 10.20.10.150 worker01 <none> <none>
pod-beta 1/1 Running 0 30s 10.20.30.200 worker02 <none> <none>
pod-gamma 1/1 Running 0 30s 10.20.30.201 worker02 <none> <none>
[root@master01 networktest]# kubectl -n test-ns-02 get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-delta 1/1 Running 0 25s 10.20.30.202 worker02 <none> <none>
[root@master01 networktest]# kubectl -n test-ns-03 get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-epsilon 1/1 Running 0 20s 10.20.10.151 worker01 <none> <none>
[root@master01 networktest]# kubectl -n test-ns-04 get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-zeta 1/1 Running 0 15s 10.20.30.203 worker02 <none> <none>
Kiểm tra kết nối mạng
[root@master01 networktest]# kubectl -n test-ns-01 exec -ti pod-alpha -- /bin/sh
# ping -c 1 10.20.30.200
PING 10.20.30.200 (10.20.30.200) 56(84) bytes of data.
64 bytes from 10.20.30.200: icmp_seq=1 ttl=62 time=0.450 ms
--- 10.20.30.200 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.450/0.450/0.450/0.000 ms
# ping -c 1 10.20.30.201
PING 10.20.30.201 (10.20.30.201) 56(84) bytes of data.
64 bytes from 10.20.30.201: icmp_seq=1 ttl=62 time=0.380 ms
--- 10.20.30.201 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.380/0.380/0.380/0.000 ms
# ping -c 1 10.20.30.202
PING 10.20.30.202 (10.20.30.202) 56(84) bytes of data.
64 bytes from 10.20.30.202: icmp_seq=1 ttl=63 time=0.120 ms
--- 10.20.30.202 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.120/0.120/0.120/0.000 ms
# ping -c 1 10.20.10.151
PING 10.20.10.151 (10.20.10.151) 56(84) bytes of data.
64 bytes from 10.20.10.151: icmp_seq=1 ttl=62 time=0.420 ms
--- 10.20.10.151 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.420/0.420/0.420/0.000 ms
# ping -c 1 10.20.30.203
PING 10.20.30.203 (10.20.30.203) 56(84) bytes of data.
64 bytes from 10.20.30.203: icmp_seq=1 ttl=63 time=0.090 ms
--- 10.20.30.203 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.090/0.090/0.090/0.000 ms
Chính sách bảo mật mạng
Cấu hình chính sách
[root@master01 networktest]# vi net-policy-example.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: net-policy-example
namespace: test-ns-01
spec:
podSelector:
matchLabels:
application: pod-alpha
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 10.20.0.0/16
except:
- 10.20.30.0/24
- namespaceSelector:
matchLabels:
environment: test-ns-03
- podSelector:
matchLabels:
application: pod-beta
ports:
- protocol: TCP
port: 80
egress:
- to:
- ipBlock:
cidr: 10.20.30.0/24
ports:
- protocol: TCP
port: 80
[root@master01 networktest]# kubectl apply -f net-policy-example.yaml
Giải thích chi tiết:
- Trường bắt buộc: Tương tự như các chính sách bảo mật khác trong Kubernetes, tài nguyên NetworkPolicy cần có các trường apiVersion, kind và metadata.
- spec: phần spec của NetworkPolicy chứa toàn bộ thông tin cần thiết để định nghĩa chính sách mạng cụ thể trong một namespace.
- podSelector: Mỗi NetworkPolicy bao gồm một podSelector để chọn nhóm Pod mà chiến lược này áp dụng. podSelector trống nghĩa là khớp với tất cả Pod trong namespace.
- policyTypes: Mỗi NetworkPolicy chứa danh sách policyTypes bao gồm Ingress hoặc Egress hoặc cả hai. Trường policyTypes biểu thị liệu chiến lược này được áp dụng cho lưu lượng vào Pod được chọn hay lưu lượng ra khỏi Pod được chọn, hoặc cả hai. Nếu không chỉ định policyTypes thì mặc định luôn đặt Ingress; nếu NetworkPolicy có bất kỳ quy tắc xuất nào thì phải cấu hình Egress.
- ingress: Mỗi NetworkPolicy có thể chứa danh sách các quy tắc ingress dưới dạng danh sách trắng. Mỗi quy tắc cho phép lưu lượng đồng thời khớp với phần from và ports.
- egress: Mỗi NetworkPolicy có thể chứa danh sách các quy tắc egress dưới dạng danh sách trắng. Mỗi quy tắc cho phép lưu lượng khớp với phần to và port.
Chính sách mạng trên có nghĩa:
- Cách ly Pod có nhãn
application=pod-alphatrong namespacetest-ns-01, tức là cách ly pod-alpha; - Quy tắc Ingress cho phép các Pod sau kết nối đến cổng TCP 80 của tất cả Pod có nhãn
application=pod-alphatrong namespacetest-ns-01:- Cho phép tất cả Pod có nhãn
application=pod-alphatrong namespacetest-ns-01vào; - Cho phép tất cả Pod trong namespace có nhãn
environment=test-ns-03vào; - Cho phép phạm vi địa chỉ IP ngoại trừ 10.20.30.0/24 trong toàn bộ 10.20.0.0/16 vào.
- Cho phép tất cả Pod có nhãn
- Quy tắc Egress cho phép kết nối từ bất kỳ Pod nào có nhãn
application=pod-alphatrong namespacetest-ns-01đến cổng TCP 80 trong dải CIDR 10.0.0.0/16.
Thử nghiệm chính sách
Thử nghiệm hướng Ingress
- Pod có IP 10.20.30.0/24 (ví dụ: pod-delta) truy cập pod-alpha (10.20.10.150):
[root@master01 ~]# kubectl -n test-ns-02 exec -ti pod-delta -- /bin/sh
/ # wget -O- -q http://10.20.10.150:80 # Theo chính sách nên bị chặn
- Pod có IP 10.20.0.0/16 (ví dụ: pod-gamma) truy cập pod-alpha (10.20.10.150):
[root@master01 ~]# kubectl -n test-ns-01 exec -ti pod-gamma -- /bin/sh
/ # wget -O- -q http://10.20.10.150:80 # Theo chính sách nên thành công
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
- Tất cả Pod trong namespace test-ns-03 (ví dụ: pod-epsilon) truy cập pod-alpha (10.20.10.150):
[root@master01 ~]# kubectl -n test-ns-03 exec -ti pod-epsilon -- /bin/sh
/ # wget -O- -q http://10.20.10.150:80 # Theo chính sách nên thành công
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
- Tất cả Pod có nhãn application=pod-beta (ví dụ: pod-beta) truy cập pod-alpha (10.20.10.150):
[root@master01 ~]# kubectl -n test-ns-01 exec -ti pod-beta -- /bin/sh
/ # wget -O- -q http://10.20.10.150:80 # Theo chính sách nên thành công
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Thử nghiệm hướng Egress
- pod-alpha truy cập Pod có IP 10.20.30.0/24 (ví dụ: pod-zeta):
[root@master01 ~]# kubectl -n test-ns-01 exec -ti pod-alpha -- /bin/sh
/ # wget -O- -q http://10.20.30.202:80 # Theo chính sách nên thành công
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
/ # wget -O- -q http://10.20.30.203:80 # Theo chính sách nên thành công
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
/ # wget -O- -q http://10.20.10.151:80 # Theo chính sách nên bị chặn
Hành vi của to và from
Có bốn loại selector có thể được chỉ định trong phần from của ingress hoặc phần to của egress:
- podSelector: Selector này sẽ chọn các Pod cụ thể trong cùng namespace với NetworkPolicy. Trong phần from của ingress, điều này biểu thị việc cho phép các Pod được chọn bởi selector này làm nguồn lưu lượng vào. Trong phần to của egress, điều này biểu thị việc cho phép lưu lượng ra đến các Pod được chọn bởi selector này (tức là Pod được chọn bởi podSelector là đích đến).
- namespaceSelector: Selector này sẽ chọn các namespace cụ thể, sử dụng tất cả các Pod như nguồn lưu lượng vào hoặc đích đến lưu lượng ra.
- namespaceSelector và podSelector: Một mục nhập to/from chỉ định cả namespaceSelector và podSelector chọn các Pod cụ thể trong namespace cụ thể.
- Ví dụ 1: Chỉ cho phép yêu cầu vào từ Pod cụ thể có nhãn role=client trong namespace có nhãn user=alice.
... ingress: - from: - namespaceSelector: matchLabels: user: alice podSelector: matchLabels: role: client ...- Ví dụ 2: Cho phép yêu cầu vào từ bất kỳ Pod nào trong namespace có nhãn user=xhyns hoặc từ Pod có nhãn role=xhyuser trong namespace nơi chiến lược này nằm.
... ingress: - from: - namespaceSelector: matchLabels: user: xhyns - podSelector: matchLabels: role: xhyuser ... - ipBlock: Selector này sẽ chọn dải IP CIDR cụ thể để làm nguồn lưu lượng vào hoặc đích đến lưu lượng ra. Thường là IP bên ngoài cluster, vì IP Pod thường được tạo ngẫu nhiên nên việc sử dụng đoạn IP Pod không thực sự có ý nghĩa.
Chính sách mặc định
Theo mặc định, nếu không có chính sách nào tồn tại trong namespace, tất cả lưu lượng vào và ra khỏi Pod trong namespace đó đều được cho phép. Có thể thay đổi hành vi mặc định trong namespace bằng các cách sau:
- Từ chối tất cả lưu lượng vào theo mặc định Vô hiệu hóa lưu lượng vào tất cả Pod trong namespace test-ns-01, tức là từ chối mặc định tất cả lưu lượng vào bất kỳ Pod nào trong namespace test-ns-01.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: test-ns-01
spec:
podSelector: {}
policyTypes:
- Ingress
Chiến lược này có thể được sử dụng như chiến lược khớp cuối cùng, đảm bảo rằng ngay cả khi container không khớp với bất kỳ NetworkPolicy nào khác, nó vẫn có thể được cách ly. Chiến lược này không thay đổi hành vi cách ly lưu lượng ra mặc định.
- Cho phép tất cả lưu lượng vào theo mặc định Cho phép lưu lượng vào tất cả Pod trong namespace test-ns-01, tức là cho phép mặc định tất cả lưu lượng vào bất kỳ Pod nào trong namespace test-ns-01.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: test-ns-01
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- {}
- Từ chối tất cả lưu lượng ra theo mặc định Vô hiệu hóa lưu lượng ra từ tất cả Pod trong namespace test-ns-01, tức là vô hiệu hóa mặc định lưu lượng ra từ bất kỳ Pod nào trong namespace test-ns-01.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: test-ns-01
spec:
podSelector: {}
policyTypes:
- Egress
- Cho phép tất cả lưu lượng ra theo mặc định Cho phép lưu lượng ra từ tất cả Pod trong namespace test-ns-01, tức là cho phép mặc định lưu lượng ra từ bất kỳ Pod nào trong namespace test-ns-01.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
namespace: test-ns-01
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
Sau khi khớp với chiến lược này, đảm bảo rằng ngay cả khi thêm các chiến lược khiến một số Pod được coi là "cách ly", vẫn có thể cho phép rõ ràng tất cả lưu lượng ra khỏi namespace này.
- Từ chối tất cả lưu lượng vào và ra theo mặc định Vô hiệu hóa tất cả lưu lượng vào và ra khỏi namespace test-ns-01.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Chiến lược này có thể được sử dụng như chiến lược khớp cuối cùng, đảm bảo rằng ngay cả những Pod không được chọn bởi bất kỳ NetworkPolicy nào khác cũng sẽ không được phép nhận lưu lượng vào hoặc ra.