Sử dụng Namespace của Host cho Pod
Trong một số trường hợp đặc biệt, Pod cần truy cập trực tiếp vào các tài nguyên hệ thống của Node (máy chủ vật lý hoặc máy ảo). Kubernetes cung cấp các tùy chọn để chia sẻ không gian tên (namespace) của máy chủ với container.
Sử dụng Network Namespace của Node
Khi kích hoạt hostNetwork: true, Pod sẽ không nhận được địa chỉ IP riêng từ mạng của cụm (cluster network) mà sử dụng trực tiếp giao diện mạng của Node. Điều này thường được dùng cho các thành phần quản trị hệ thống hoặc monitoring.
apiVersion: v1
kind: Pod
metadata:
name: k8s-node-net-pod
spec:
hostNetwork: true
containers:
- name: inspector
image: busybox
command: ["sh", "-c", "sleep 1h"]
Ràng buộc cổng trực tiếp trên Host (hostPort)
Khác với hostNetwork, hostPort cho phép container giữ Network Namespace riêng nhưng ánh xạ một cổng cụ thể từ Node vào container. Lưu ý rằng mỗi cổng trên Node chỉ có thể được sử dụng bởi một Pod tại một thời điểm.
apiVersion: v1
kind: Pod
metadata:
name: web-direct-port
spec:
containers:
- name: nginx-server
image: nginx:alpine
ports:
- containerPort: 80
hostPort: 8888
Chia sẻ không gian tên PID và IPC
Sử dụng hostPID cho phép container nhìn thấy tất cả các tiến trình đang chạy trên Node. Trong khi đó, hostIPC cho phép container giao tiếp với các tiến trình trên Node thông qua cơ chế Inter-Process Communication.
apiVersion: v1
kind: Pod
metadata:
name: system-monitor-pod
spec:
hostPID: true
hostIPC: true
containers:
- name: monitor
image: alpine
command: ["sleep", "3600"]
Cấu hình Security Context cho Container
Security Context xác định các đặc quyền và quyền hạn truy cập cho một Pod hoặc Container, giúp giảm thiểu rủi ro nếu container bị tấn công.
Chạy với User ID cụ thể
Thay vì chạy dưới quyền root (UID 0), bạn có thể chỉ định một User ID cụ thể để hạn chế quyền truy cập vào file hệ thống.
apiVersion: v1
kind: Pod
metadata:
name: uid-restricted-pod
spec:
containers:
- name: app-worker
image: alpine
command: ["sleep", "1h"]
securityContext:
runAsUser: 1001
Ngăn chặn chạy dưới quyền Root
Thiết lập runAsNonRoot: true sẽ khiến Pod thất bại khi khởi tạo nếu image được build để chạy mặc định bằng quyền root.
spec:
containers:
- name: secure-app
image: alpine
securityContext:
runAsNonRoot: true
Chế độ đặc quyền (Privileged Mode)
Khi một container chạy ở chế độ privileged, nó có quyền truy cập gần như tương đương với các tiến trình chạy trực tiếp trên host, bao gồm cả việc can thiệp vào kernel.
securityContext:
privileged: true
Quản lý Kernel Capabilities
Thay vì cấp toàn bộ đặc quyền, bạn có thể thêm hoặc bớt các quyền cụ thể của kernel (capabilities) để tối ưu hóa bảo mật theo nguyên tắc đặc quyền tối thiểu.
securityContext:
capabilities:
add: ["SYS_TIME"]
drop: ["CHOWN"]
Sử dụng File System chỉ đọc
Để ngăn chặn việc ghi mã độc vào container, bạn có thể chuyển root filesystem sang chế độ chỉ đọc và chỉ cho phép ghi vào các Volume được chỉ định.
spec:
containers:
- name: static-app
image: alpine
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: data-storage
mountPath: /data
volumes:
- name: data-storage
emptyDir: {}
Chính sách bảo mật Pod (PodSecurityPolicy)
PodSecurityPolicy (PSP) là một tài nguyên cấp Cluster dùng để kiểm soát các khía cạnh bảo mật mà Pod phải tuân thủ trước khi được khởi tạo.
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restrictive-policy
spec:
privileged: false
hostNetwork: false
allowPrivilegeEscalation: false
runAsUser:
rule: MustRunAsNonRoot
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- 'configMap'
- 'secret'
- 'persistentVolumeClaim'
Để áp dụng chính sách này cho người dùng cụ thể, cần sử dụng RBAC để liên kết (bind) quyền use đối với tài nguyên PSP này thông qua ClusterRole và ClusterRoleBinding.
Cô lập lưu lượng mạng với NetworkPolicy
Mặc định trong Kubernetes, mọi Pod đều có thể giao tiếp với nhau. NetworkPolicy cho phép bạn thiết lập các quy tắc tường lửa để kiểm soát luồng dữ liệu.
Chặn toàn bộ lưu lượng vào (Default Deny)
Chính sách này thường được dùng làm nền tảng để khóa chặt một Namespace, sau đó mới mở dần các cổng cần thiết.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
Cho phép truy cập dựa trên Label và Port
Ví dụ dưới đây chỉ cho phép các Pod có nhãn role: frontend truy cập vào cổng 3306 của các Pod có nhãn role: db.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-access
spec:
podSelector:
matchLabels:
role: db
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 3306
Giới hạn truy cập theo dải IP (CIDR)
Có thể giới hạn truy cập từ các dải mạng bên ngoài hoặc các phân vùng mạng cụ thể.
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/16
except:
- 10.0.1.0/24
Kiểm soát lưu lượng ra (Egress)
Để ngăn chặn việc rò rỉ dữ liệu hoặc kết nối đến các máy chủ điều khiển độc hại, bạn có thể cấu hình Egress để chỉ cho phép Pod kết nối đến các dịch vụ hợp lệ.
spec:
podSelector:
matchLabels:
app: my-service
egress:
- to:
- podSelector:
matchLabels:
app: internal-api
policyTypes:
- Egress