0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Hướng Dẫn Cấu Hình Amazon EBS Với Amazon EKS Bằng Terraform

Đăng vào 8 tháng trước

• 8 phút đọc

Giới thiệu

Trong bài viết này, chúng ta sẽ tìm hiểu cách tích hợp Amazon Elastic Block Store (EBS) với Amazon Elastic Kubernetes Service (EKS). Chúng ta sẽ cấu hình một cluster EKS bằng Terraform, thiết lập driver EBS CSI, và chạy một container Nginx sử dụng EBS để lưu trữ các tệp website.

Bài viết này là hướng dẫn thực tiễn cho bất kỳ ai xây dựng các workload có trạng thái trên EKS.

Hiểu về Amazon EBS cho Kubernetes

Amazon EBS là gì?

Amazon Elastic Block Store (EBS) cung cấp các volume lưu trữ block bền vững có thể được gắn vào các instance Amazon EC2. Trong Kubernetes, các volume EBS có thể được truy xuất bởi các Pods thông qua driver EBS CSI (Container Storage Interface), cho phép các workload duy trì dữ liệu vượt qua vòng đời của pod.

Sơ đồ Kiến trúc

Khi bạn sử dụng Amazon EBS với Amazon EKS, ứng dụng của bạn yêu cầu lưu trữ thông qua một PersistentVolumeClaim (PVC). Kubernetes sau đó sẽ kết nối yêu cầu này với một EBS volume hiện có (cung cấp tĩnh) hoặc tự động tạo mới một volume (cung cấp động) với sự trợ giúp của StorageClass và driver EBS CSI.

Driver CSI sẽ giao tiếp với AWS để tạo và gắn volume vào nút worker mà Pod của bạn đang chạy, và volume sẽ được gắn vào bên trong container tại đường dẫn chỉ định (như /usr/share/nginx/html). Một điều quan trọng cần nhớ là các volume EBS chỉ hoạt động trong một Availability Zone (AZ) duy nhất. Điều này có nghĩa là Pod của bạn và volume EBS phải nằm trong cùng một AZ. Cung cấp động thường sẽ xử lý điều này một cách tự động, nhưng đối với cung cấp tĩnh, bạn cần đảm bảo volume được tạo trong AZ đúng.

Lợi ích chính cho EKS

  • Độ bền: Dữ liệu tồn tại qua các lần khởi động lại pod.
  • Hiệu suất: Nhiều loại volume (gp3, io2, st1, v.v.) cho thông lượng hoặc IOPS tối ưu.
  • Tính linh hoạt: Các volume có thể được thay đổi kích thước mà không cần dừng hoạt động.
  • Chi phí hợp lý: Chỉ trả tiền cho lưu trữ đã được cấp phát.

Những lưu ý quan trọng khi sử dụng EKS

  • Các volume EBS có phạm vi theo AZ – một Pod sử dụng EBS phải chạy trong cùng một Availability Zone với volume.
  • Cần có Kubernetes v1.17+ với hỗ trợ driver CSI.
  • Các Pod cần EBS phải sử dụng StatefulSets hoặc các Deployments được lên lịch cẩn thận.
  • Cần theo dõi hạn mức tài nguyên để tránh cạn kiệt lưu trữ hoặc vượt quá giới hạn API.

Bước 1: Cấp phát Cluster EKS với Terraform trong VPC

Bước đầu tiên trong việc tích hợp Amazon EBS với EKS là cấp phát một cluster Kubernetes chạy an toàn bên trong một VPC riêng biệt. Chúng tôi sẽ sử dụng các mô-đun Terraform cộng đồng AWS phổ biến cho cả việc thiết lập VPC và EKS. Vui lòng tham khảo mô-đun chính trong repo GitHub.

Bước 2: Tạo Hệ Thống Tệp EFS

EBS Storage: Lưu trữ EBS được mã hóa với tùy chọn mã hóa

hcl Copy
resource "aws_ebs_volume" "static_volume" {
  count = var.create_static_volume ? 1 : 0

  availability_zone = var.availability_zones[0]
  size              = var.static_volume_size
  type              = var.ebs_volume_type
  encrypted         = var.ebs_encrypted
  kms_key_id        = var.ebs_kms_key_id

  # Cấu hình IOPS cho các volume gp3, io1, io2
  iops = var.ebs_volume_type == "gp3" || var.ebs_volume_type == "io1" || var.ebs_volume_type == "io2" ? var.ebs_volume_iops : null

  # Cấu hình throughput cho các volume gp3
  throughput = var.ebs_volume_type == "gp3" ? var.ebs_volume_throughput : null

  tags = {
    Name        = "${var.cluster_name}-static-ebs-volume"
    Environment = var.environment
    Terraform   = "true"
    Purpose     = "Static EBS volume for Kubernetes testing"
  }
}

IAM Role: Đối với EFS CSI driver với danh tính pod

hcl Copy
resource "aws_iam_role" "ebs_csi_driver_role" {
  name = "${var.cluster_name}-ebs-csi-driver-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "pods.eks.amazonaws.com"
        }
        Action = [
          "sts:AssumeRole",
          "sts:TagSession"
        ]
      }
    ]
  })

  tags = {
    Name        = "${var.cluster_name}-ebs-csi-driver-role"
    Environment = var.environment
    Terraform   = "true"
  }
}

Bước 3: Triển Khai Các Mẫu Lưu Trữ EBS

Cung cấp tĩnh

Trong cung cấp tĩnh, PersistentVolume (PV) được tạo thủ công bởi quản trị viên. PV sẽ chỉ rõ ID volume EBS hiện có và thư mục.

Cách hoạt động:

  1. Bạn đầu tiên cấp phát một EBS Volume bằng Terraform/CLI.
  2. Sau đó, bạn định nghĩa một tài nguyên PersistentVolume (PV) của Kubernetes tham chiếu đến ID volume EBS.
  3. Tiếp theo, bạn tạo một PersistentVolumeClaim (PVC) yêu cầu lưu trữ phù hợp với các thông số của PV.
  4. Triển khai Pod của bạn (ví dụ: Nginx) và gắn PVC như một volume để lưu trữ tệp.
yaml Copy
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-static-sc
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
yaml Copy
apiVersion: v1
kind: PersistentVolume
metadata:
  name: ebs-static-pv
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ebs-static-sc
  csi:
    driver: ebs.csi.aws.com
    volumeHandle: ${EBS_VOLUME_ID}
    fsType: ext4
yaml Copy
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-static-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-static-sc
  volumeName: ebs-static-pv
  resources:
    requests:
      storage: 10Gi
yaml Copy
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ebs-static-pod
  namespace: default
  labels:
    app: nginx-ebs-static
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: ebs-storage
      mountPath: /usr/share/nginx/html
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    command: ["/bin/sh"]
    args: ["-c", "echo '<h1>Hello from EBS Static Volume!</h1><p><b>Pod:</b> '$POD_NAME'</p>' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]
  volumes:
  - name: ebs-storage
    persistentVolumeClaim:
      claimName: ebs-static-pvc
yaml Copy
apiVersion: v1
kind: Service
metadata:
  name: nginx-ebs-static-service
  namespace: default
  labels:
    app: nginx-ebs-static
spec:
  selector:
    app: nginx-ebs-static
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

Bước 4: Triển Khai cho Cung Cấp Tĩnh

  1. Lấy giá trị EBS từ Terraform:
Copy
cd infrastructure
EBS_VOLUME_ID=$(terraform output -raw ebs_volume_id 2>/dev/null || echo "")
  1. Cập nhật các manifest với giá trị EFS:
Copy
sed "s/\${EBS_VOLUME_ID}/$EBS_VOLUME_ID/g" static-persistent-volume.yaml > static-persistent-volume-final.yaml
  1. Áp dụng các manifest tĩnh:
Copy
kubectl apply -f static-storage-class.yaml
kubectl apply -f static-persistent-volume-final.yaml
kubectl apply -f static-persistent-volume-claim.yaml
kubectl apply -f static-nginx-pod.yaml
kubectl apply -f static-nginx-service.yaml

Cung cấp động (Khuyến nghị)

Trong cung cấp động, Kubernetes tự động tạo EBS volumes theo yêu cầu bằng driver EBS CSI và một StorageClass.

Cách hoạt động:

  1. Định nghĩa một StorageClass chỉ định volume EBS (ví dụ: loại gp3, chính sách giữ lại, chế độ gắn kết).
  2. Khi một ứng dụng yêu cầu lưu trữ thông qua PVC, Kubernetes sẽ tạo động:
    • Một PV mới được hỗ trợ bởi một EBS volume mới.
    • Các Pod gắn PV được cấp phát động thông qua PVC.
yaml Copy
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-dynamic-sc
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
  encrypted: "true"
  iops: "3000"
  throughput: "125"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
yaml Copy
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-dynamic-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-dynamic-sc
  resources:
    requests:
      storage: 10Gi
yaml Copy
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ebs-dynamic-pod
  namespace: default
  labels:
    app: nginx-ebs-dynamic
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: ebs-storage
      mountPath: /usr/share/nginx/html
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo '<h1>Hello from EBS Dynamic Volume!</h1><p><b>Pod:</b> '$POD_NAME'</p>' > /usr/share/nginx/html/index.html"]
  volumes:
  - name: ebs-storage
    persistentVolumeClaim:
      claimName: ebs-dynamic-pvc
yaml Copy
apiVersion: v1
kind: Service
metadata:
  name: nginx-ebs-dynamic-service
  namespace: default
  labels:
    app: nginx-ebs-dynamic
spec:
  selector:
    app: nginx-ebs-dynamic
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

Bước 5: Triển Khai cho Cung Cấp Động

  1. Áp dụng các manifest tĩnh:
Copy
kubectl apply -f dynamic-storage-class.yaml
kubectl apply -f dynamic-persistent-volume-claim.yaml
kubectl apply -f dynamic-nginx-pod.yaml
kubectl apply -f dynamic-nginx-service.yaml

Kiểm tra

Kiểm tra rằng mọi thứ đang hoạt động:

Copy
# Kiểm tra pods EFS CSI driver
kubectl get pods -n kube-system -l app=efs-csi-controller

# Kiểm tra các lớp lưu trữ
kubectl get storageclass ebs-sc

# Đối với Cung cấp Tĩnh:
kubectl get pv ebs-static-pv
kubectl get pvc ebs-static-pvc
kubectl get pod nginx-ebs-static
kubectl get service nginx-ebs-static-service

# Đối với Cung cấp Động:
kubectl get pvc ebs-dynamic-pvc
kubectl get pod nginx-ebs-dynamic
kubectl get service nginx-ebs-dynamic-service

Dọn dẹp

Dọn dẹp Cung cấp Tĩnh

Copy
kubectl delete -f static-storage-class.yaml
kubectl delete -f static-persistent-volume-final.yaml
kubectl delete -f static-persistent-volume-claim.yaml
kubectl delete -f static-nginx-pod.yaml
kubectl delete -f static-nginx-service.yaml

Dọn dẹp Cung cấp Động

Copy
kubectl delete -f dynamic-nginx-service.yaml
kubectl delete -f dynamic-nginx-pod.yaml
kubectl delete -f dynamic-persistent-volume-claim.yaml
kubectl delete -f dynamic-storage-class.yaml

Và sau đó terraform destroy hạ tầng EKS nếu bạn không sử dụng để tiết kiệm chi phí.

Kết luận

Amazon EBS cung cấp lưu trữ block đáng tin cậy cho các workload có trạng thái trên Amazon EKS. Việc sử dụng Terraform để cấp phát cơ sở hạ tầng và các manifest Kubernetes cho cấu hình lưu trữ mang lại cho bạn cả tự động hóa và tính linh hoạt. Với việc thiết lập đúng các vai trò IAM, driver CSI và các thực tiễn tốt nhất, bạn có thể tự tin chạy các workload như Nginx với lưu trữ bền vững trên EKS.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào