Giới thiệu
Bạn có biết rằng các Pod trong Kubernetes có thể được cấp một địa chỉ IP công khai và một nhóm bảo mật riêng biệt không? Điều này rất quan trọng khi triển khai các hệ thống truyền thông, đặc biệt là khi sử dụng AWS EKS. Trong bài viết này, chúng ta sẽ khám phá cách cấu hình một Pod với địa chỉ IP công khai và những lợi ích đi kèm.
Tóm tắt
Gần đây, tôi đã làm việc trên việc triển khai các hệ thống điện thoại trên AWS EKS. Trong quá trình này, tôi nhận ra rằng việc chạy các máy chủ truyền thông dựa trên RTP (Real-time Transport Protocol) đằng sau một NAT gateway không phải là một lựa chọn khả thi. Điều này chủ yếu là do NAT gateway của AWS không cho phép lưu lượng truy cập đến (ingress) vào, khiến cho việc xử lý truyền phát thời gian thực trong một subnet riêng tư không thể thực hiện được.
Vấn đề
Để RTP hoạt động, cả hai đầu cần phải có khả năng giao tiếp trực tiếp qua mạng (Internet/Intranet). NAT gateway không cho phép lưu lượng truy cập đến chảy vào, điều này gây khó khăn trong việc xử lý truyền phát thời gian thực trong một subnet riêng tư.
Giải pháp đơn giản:
Một giải pháp đơn giản là làm cho một node worker của EKS trở thành công khai, mở rộng các nhóm bảo mật, và mọi thứ sẽ bắt đầu hoạt động. Tuy nhiên, cách tiếp cận này có một lỗ hổng bảo mật đáng kể. RTP, theo bản chất, yêu cầu một dải lớn các cổng để cho phép truyền phát đồng thời. Để đạt được điều này, khoảng 10,000 cổng sẽ cần được đưa vào danh sách trắng trong nhóm bảo mật. Nếu cần nhiều đồng thời hơn, thậm chí còn cần nhiều cổng hơn.
Giải pháp lý tưởng:
- Pod có địa chỉ IP công khai tĩnh
- Pod có giao diện mạng riêng
- Pod có nhóm bảo mật riêng
Nếu các điều kiện trên được đáp ứng, nó sẽ làm cho môi trường trở nên đáng tin cậy và an toàn hơn.
Cách thực hiện điều này trong AWS EKS
Điều kiện tiên quyết
- Cụm AWS EKS với AWS VPC-CNI
- Elastic IP
- Nhóm bảo mật
Bước 1: Kích hoạt giao diện mạng dành riêng cho các Pod
Bước đầu tiên là cấu hình VPC-CNI để gán một giao diện mạng dành riêng cho một Pod. Để làm điều này, hãy thêm biến sau vào aws-node daemonset:
json
"ENABLE_POD_ENI": "true"
Nếu bạn đang sử dụng AWS Managed VPC-CNI, hãy thêm điều sau vào cấu hình nâng cao:
json
{
"env": {
"ENABLE_POD_ENI": "true"
}
}
Khi thay đổi này được thực hiện, CNI (VPC-CNI) sẽ sẵn sàng để gán các giao diện mạng cụ thể cho các Pod. Theo mặc định, không có gì thay đổi và tất cả các Pod hiện tại và mới sẽ hoạt động như mong đợi.
Bước 2: Gán Nhóm Bảo Mật cho Pod
AWS cung cấp một CRD (custom resource definition) vpcresources.k8s.aws/v1beta1. Sử dụng điều này, một SecurityGroupPolicy có thể được tạo như sau:
yaml
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: media-stream-sg-policy
namespace: myns
spec:
podSelector:
matchLabels:
app: media-servers
securityGroups:
groupIds:
- sg-e3edxxxxx
Nhóm bảo mật sg-e3edxxxxx được kỳ vọng sẽ tồn tại trong VPC.
Áp dụng manifest:
bash
kubectl apply -f securitygrouppolicy.yaml
Tạo một Pod với nhãn app: media-servers
yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: media-servers
name: media-servers-pod
namespace: myns
spec:
containers:
image: public.ecr.aws/docker/library/nginx:stable-alpine
Áp dụng manifest:
bash
kubectl apply -f pod.yaml
Khi Pod đang trong trạng thái chạy, hãy lấy địa chỉ IP của Pod:
bash
kubectl get pods -n myns -o wide
Sao chép địa chỉ IP và tìm kiếm trên AWS Console EC2 > Network & Security > Network interfaces. Địa chỉ IP này bây giờ sẽ được liên kết với một giao diện mạng riêng, mà cũng có nhóm bảo mật gán cho nó.
Bây giờ bạn đã có một Pod với giao diện mạng riêng và nhóm bảo mật gán cho nó.
- Lưu ý ID của giao diện.
Bước 3: Gán Elastic IP cho Pod
Theo mặc định, một địa chỉ IP công khai không được gán cho giao diện mạng và bạn cần một tập hợp địa chỉ IP tĩnh để bên ngoài có thể giao tiếp với bạn (giúp với việc đưa vào danh sách trắng).
Đi tới AWS Console EC2 > Elastic IP.
Cấp phát một IP mới hoặc sử dụng một IP hiện có.
Khi Elastic IP đã được cấp phát, hãy liên kết địa chỉ IP với giao diện mạng đã lấy được ở bước 2.
Để đơn giản hơn, hãy chạy lệnh sau để thực hiện việc liên kết một cách dễ dàng:
bash
ALLOCATION_ID="eipalloc-xxxx" # Lấy từ mô tả Elastic IP
POD_IP="110.46.35.231"
AWS_REGION="eu-west-1"
aws ec2 associate-address --allocation-id $ALLOCATION_ID --network-interface-id $(aws ec2 describe-network-interfaces --filters "Name=private-ip-address,Values=$POD_IP" --query "NetworkInterfaces[].NetworkInterfaceId" --output text --no-paginate) --private-ip-address $POD_IP --allow-reassociation
Lệnh trên có thể được chạy trong một init-container để đảm bảo rằng IP luôn được liên kết với Pod.
Tài liệu tham khảo
- Cấu hình plugin Amazon VPC CNI
- CRD - vpcresources.k8s.aws/v1beta1
- Cấp phát và liên kết địa chỉ IP Elastic
Thực tiễn tốt nhất
- Luôn kiểm tra nhóm bảo mật để đảm bảo rằng không có cổng không an toàn nào được mở.
- Sử dụng các công cụ giám sát để theo dõi lưu lượng truy cập đến và đi từ Pod.
Cạm bẫy phổ biến
- Không gán quá nhiều cổng vào nhóm bảo mật, điều này có thể dẫn đến rủi ro bảo mật.
- Không quên cập nhật Elastic IP khi thay đổi địa chỉ IP của Pod.
Mẹo hiệu suất
- Sử dụng các công cụ tối ưu hóa mạng để cải thiện tốc độ truyền tải.
Giải quyết sự cố
- Nếu Pod không nhận được địa chỉ IP như mong đợi, hãy kiểm tra lại cấu hình VPC-CNI và đảm bảo rằng các biến môi trường đã được thiết lập chính xác.
Kết luận
Việc cấu hình một Pod với địa chỉ IP công khai trong AWS EKS không chỉ giúp cải thiện khả năng truy cập mà còn đảm bảo tính bảo mật thông qua việc sử dụng nhóm bảo mật. Hãy áp dụng những hướng dẫn trên và bảo đảm rằng hệ thống của bạn luôn được bảo mật và hoạt động hiệu quả.
Câu hỏi thường gặp
1. Làm thế nào để tôi biết rằng Pod của tôi đã nhận được IP công khai?
- Bạn có thể sử dụng lệnh
kubectl get pods -o wideđể kiểm tra địa chỉ IP của Pod.
2. Có cần thiết phải sử dụng Elastic IP không?
- Có, Elastic IP giúp đảm bảo rằng địa chỉ IP của bạn không thay đổi ngay cả khi Pod khởi động lại.