1. Thiết lập NetworkPolicy để cô lập Pod
Trong môi trường Edge, việc hạn chế truy cập giữa các Pod là bắt buộc để ngăn chặn sự lan rộng của lỗ hổng bảo mật nếu một cảm biến bị xâm nhập.
Tạo file cấu hình NetworkPolicy để chỉ cho phép Pod IoT Gateway truy cập vào Pod Database, chặn mọi lưu lượng khác.
Đường dẫn: ~/config/network-policy-iot.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-iot
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-iot-to-db
namespace: default
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: iot-gateway
ports:
- protocol: TCP
port: 5432
Áp dụng cấu hình vào cluster K3s:
kubectl apply -f ~/config/network-policy-iot.yaml
Kết quả mong đợi: Pod "db" chỉ nhận kết nối từ Pod có label "app: iot-gateway" trên port 5432. Mọi Pod khác không thể ping hoặc telnet đến Pod db.
Verify bằng cách chạy lệnh từ Pod không được phép:
kubectl run test-pod --image=busybox --rm -it --restart=Never -- wget -q -O- http://db-service:5432 || echo "Connection blocked as expected"
2. Định tuyến lưu lượng qua Tunnel WireGuard
Để đảm bảo dữ liệu IoT không đi qua mạng công cộng, ta buộc lưu lượng giữa Cloud và Edge phải đi qua tunnel WireGuard đã thiết lập ở phần 4.
Cấu hình CNI (Container Network Interface) của K3s/KubeEdge để định tuyến subnet Pod qua interface WireGuard.
Đường dẫn: /etc/systemd/system/k3s.service.d/override.conf (trên Node Master) hoặc cấu hình tương tự trên Edge Node tùy phiên bản CNI.
Giả sử subnet Pod là 10.42.0.0/16 và subnet WireGuard là 172.16.0.0/12.
[Service]
ExecStartPre=-/usr/bin/ip route add 10.42.0.0/16 dev wg0
ExecStartPre=-/usr/bin/ip route add 192.168.100.0/24 dev wg0
Tải lại systemd và khởi động lại K3s để áp dụng route:
systemctl daemon-reload
systemctl restart k3s
Kết quả mong đợi: Traffic từ Pod Cloud (10.42.x.x) sang Pod Edge (192.168.100.x) sẽ đi qua interface wg0 thay vì eth0.
Verify bằng cách kiểm tra bảng định tuyến:
ip route show | grep wg0
3. Thiết lập chứng chỉ mTLS cho dịch vụ
Sử dụng Cert-Manager để tự động cấp phát chứng chỉ mTLS cho các dịch vụ, đảm bảo xác thực hai chiều giữa các thành phần trong cluster.
Tạo ClusterIssuer để kết nối với CA nội bộ hoặc Let's Encrypt (tùy chọn), ở đây ta dùng self-signed cho môi trường Edge offline.
Đường dẫn: ~/config/issuer-self-signed.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
Áp dụng Issuer:
kubectl apply -f ~/config/issuer-self-signed.yaml
Tiếp theo, tạo Certificate cho dịch vụ IoT Gateway để client (cảm biến) có thể xác thực server và ngược lại.
Đường dẫn: ~/config/iot-mtls-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: iot-gateway-mtls
namespace: default
spec:
secretName: iot-gateway-tls
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
dnsNames:
- iot-gateway.default.svc.cluster.local
- iot-gateway.edge.local
usages:
- server auth
- client auth
Áp dụng Certificate:
kubectl apply -f ~/config/iot-mtls-cert.yaml
Kết quả mong đợi: Secret "iot-gateway-tls" được tạo tự động chứa tls.crt và tls.key. Pod IoT Gateway mount secret này vào container để bật HTTPS với mTLS.
Verify bằng cách kiểm tra secret:
kubectl get secret iot-gateway-tls -o yaml | grep -A 5 data
4. Quản lý Secret cho dữ liệu nhạy cảm IoT
Dữ liệu như API Key, Token cảm biến, hoặc mật khẩu DB không được lưu dưới dạng plain text trong ConfigMap hoặc Code.
Sử dụng Sealed Secrets (Bitnami) hoặc Kubernetes Secrets mã hóa để lưu trữ thông tin nhạy cảm.
Ở đây ta dùng Kubernetes Secrets cơ bản với mã hóa tại nghỉ (Encryption at Rest) nếu K3s hỗ trợ, hoặc đơn giản là tạo Secret từ file an toàn.
Đường dẫn: ~/config/iot-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
name: iot-sensor-credentials
namespace: default
type: Opaque
stringData:
db-password: "SecureP@ssw0rd!2024"
sensor-api-key: "sk_live_8x9y0z1a2b3c4d5e"
mqtt-token: "token_abc123xyz"
Áp dụng Secret:
kubectl apply -f ~/config/iot-credentials.yaml
Trong Deployment của ứng dụng IoT, mount secret này vào biến môi trường (Environment Variable) hoặc volume.
Đoạn code trong Deployment file:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: iot-sensor-credentials
key: db-password
- name: API_KEY
valueFrom:
secretKeyRef:
name: iot-sensor-credentials
key: sensor-api-key
Kết quả mong đợi: Khi chạy `kubectl describe pod `, bạn thấy các biến môi trường nhưng giá trị không hiển thị (ẩn). Không ai có thể đọc giá trị qua `kubectl get secret` nếu không có quyền RBAC.
Verify bằng cách vào container và kiểm tra biến môi trường:
kubectl exec -it -- env | grep DB_PASSWORD
5. Kiểm tra tính toàn vẹn đường truyền
Khẳng định lại rằng lưu lượng đang đi đúng đường qua WireGuard và không bị rò rỉ ra mạng công cộng.
Thực hiện ping và traceroute từ Pod Cloud sang Pod Edge.
Trước tiên, cần đảm bảo Pod Cloud và Pod Edge đều có thể ping nhau qua IP nội bộ.
kubectl run traceroute-pod --image=nicolaka/netshoot --rm -it --restart=Never -- bash
Trong shell của pod, thực hiện ping đến IP của Pod Edge (giả sử IP Edge là 192.168.100.50):
ping 192.168.100.50 -c 4
Sau đó, thực hiện traceroute để xem đường đi của gói tin:
traceroute 192.168.100.50
Kết quả mong đợi:
1. Ping thành công (100% packet loss = 0%).
2. Traceroute hiển thị bước đầu tiên là IP của interface WireGuard (172.16.0.x) hoặc IP Gateway của tunnel, không hiển thị IP Public của ISP.
3. Nếu thấy IP Public trong traceroute, cấu hình route ở mục 2 chưa đúng, cần kiểm tra lại bảng route trên Node.
Ra khỏi container:
exit
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Edge Computing an toàn với K3s, KubeEdge và WireGuard cho IoT
« Phần 4: Xây dựng mạng riêng ảo an toàn với WireGuard
Phần 6: Triển khai ứng dụng IoT mẫu và thu thập dữ liệu cảm biến »