Bảo mật hệ thống phát hiện an toàn tại nơi làm việc

1. Giới thiệu

Trong lớp học lập trình này, bạn sẽ xây dựng một ứng dụng minh hoạ cơ bản để minh hoạ cách tích hợp nhiều dịch vụ của Google Cloud cho một dịch vụ nằm trong một dự án có các hạn chế về việc tuân thủ. Dự án này sử dụng các tính năng bảo mật sau:

Lớp học lập trình này dành cho các nhà phát triển ở mọi cấp độ, kể cả người mới bắt đầu. Bạn sẽ sử dụng giao diện dòng lệnh trong Google Cloud Shell và mã Python. Bạn không cần phải là chuyên gia về Python, nhưng việc hiểu biết cơ bản về cách đọc mã sẽ giúp bạn hiểu các khái niệm.

Lưu ý: Đây là một bản minh chứng khái niệm đơn giản hoá, không phải là một ứng dụng phát hành chính thức. Hãy áp dụng các biện pháp phòng ngừa bổ sung, chẳng hạn như quyền truy cập bên ngoài được xác thực và bảo mật vào dịch vụ này trong một tình huống thực tế.

2. Trước khi bắt đầu

Thiết lập dự án

../shared/_project-setup.md

Bắt đầu Cloud Shell

Cloud Shell là một môi trường dòng lệnh chạy trong Google Cloud và được tải sẵn các công cụ cần thiết.

  1. Nhấp vào Kích hoạt Cloud Shell ở đầu bảng điều khiển Cloud:

404e4cce0f23e5c5.png

  1. Sau khi kết nối với Cloud Shell, hãy chạy lệnh này để xác minh quá trình xác thực trong Cloud Shell:
gcloud auth list
  1. Chạy lệnh sau để xác nhận rằng dự án của bạn được định cấu hình để sử dụng với gcloud:
gcloud config get project
  1. Xác nhận rằng dự án đúng như dự kiến, sau đó chạy lệnh bên dưới để đặt mã dự án:
export PROJECT_ID=$(gcloud config get project)

Các quyền IAM bắt buộc

Tài khoản mà bạn sử dụng cho lớp học lập trình này phải có các vai trò IAM sau. Bạn cần có các quyền này để tạo các tài nguyên cần thiết của Google Cloud (dự án, thư mục, cụm GKE, khoá KMS, tài khoản dịch vụ, v.v.) và định cấu hình Assured Workload.

Ở cấp tổ chức:

  • roles/assuredworkloads.admin (Quản trị viên Assured Workloads): Để tạo và quản lý chính tài nguyên Assured Workloads, đảm bảo cấu hình tuân thủ.

Ở cấp tài khoản thanh toán (trên Tài khoản thanh toán của bạn):

  • roles/billing.accountUser (Người dùng tài khoản thanh toán): Để liên kết tài khoản thanh toán đã chỉ định.

Định cấu hình các biến của lớp học lập trình

Để tạo cơ sở hạ tầng cần thiết, bạn cần cung cấp các biến môi trường sau:

# The ID of the Billing Account in the format (XXXXXX-XXXXXX-XXXXXX).
# This value will be used to attach in the projects created using Assured Workloads
export BILLING_ACCOUNT=

# The ID of a Google Cloud Platform organization
# Run `gcloud organizations list` to check all your available organizations
export GCP_ORGANIZATION=

# The numeric ID of a folder where the Assured Workloads will create the resources.
export FOLDER_ID=

# Region where the application will be deployed.
# Since you are using Assured Workloads, you MUST use one of the valid locations as described here: <https://docs.cloud.google.com/assured-workloads/docs/locations>
export REGION="us-central1"

# The ID of an existing Google Cloud project to be used for API quota and billing purposes.
# This project will only be used to enable the Assured Workloads API and create an Assured Workload.
export QUOTA_PROJECT_ID=

# Random suffix used to avoid naming collisions when creating the GCP projects.
export RANDOM_SUFFIX=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 5 ; echo)

# The ID of the projects that will be created using Assured Workloads.
# You can modify this value if you want a custom id.
export PROJECT_ID="il5-gemini-vision-aw-${RANDOM_SUFFIX}"
export KMS_PROJECT_ID="il5-gemini-vision-kms-${RANDOM_SUFFIX}"

3. Tạo nền tảng Assured Workloads

Giờ đây, bạn có thể đặt nền tảng cho ứng dụng của mình trong một môi trường được quản lý. Sử dụng Assured Workloads để giúp thực thi các yêu cầu tuân thủ bằng cách tạo một môi trường được kiểm soát cho các tài nguyên của bạn.

Định cấu hình dự án hạn mức

Bật API Assured Workloads trong dự án hạn mức. Bạn phải có API này để tạo và quản lý Assured Workloads.

gcloud services enable assuredworkloads.googleapis.com \
  --project="${QUOTA_PROJECT_ID}"

Tạo môi trường Assured Workload

Lệnh sau đây tạo một "vùng đích" an toàn cho bản minh hoạ của bạn. Lệnh này tạo 2 dự án mới của Google Cloud trong thư mục và tài khoản thanh toán mà bạn đã chỉ định.

  • Một dự án lưu trữ cụm GKE và ứng dụng của bạn.
  • Dự án còn lại quản lý Khoá mã hoá do khách hàng quản lý (CMEK).

Hệ thống sẽ tự động áp dụng các biện pháp kiểm soát tuân thủ IL5 đã chỉ định cho cả hai dự án ngay từ thời điểm tạo.

Chạy lệnh sau để tạo môi trường khối lượng công việc.

export ASSURED_WORKLOAD_ID=$(gcloud assured workloads create \
    --project="${QUOTA_PROJECT_ID}" \
    --display-name="DoD IL5 Gemini Vision Demo" \
    --compliance-regime="IL5" \
    --billing-account="billingAccounts/${BILLING_ACCOUNT}" \
    --location="${REGION}" \
    --organization="${GCP_ORGANIZATION}" \
    --provisioned-resources-parent="folders/${FOLDER_ID}" \
    --resource-settings="consumer-project-id=${PROJECT_ID},consumer-project-name=DoD IL5 Workloads,encryption-keys-project-id=${KMS_PROJECT_ID},encryption-keys-project-name=DoD IL5 KMS" \
    --labels="codelab=gemini-vision-demo" \
    --format="value(name)")

echo "Assured Workload created: ${ASSURED_WORKLOAD_ID}"

export WORKLOAD_FOLDER_ID=$(gcloud assured workloads describe ${ASSURED_WORKLOAD_ID} \
    --location="${REGION}" \
    --project="${QUOTA_PROJECT_ID}" \
    --format="json" | grep -B 1 "CONSUMER_FOLDER" | grep -oE "[0-9]{10,}")

echo "Assured Workload folder created: ${WORKLOAD_FOLDER_ID}"

gcloud projects create "${PROJECT_ID}" \
    --folder="${WORKLOAD_FOLDER_ID}" \
    --name="DoD IL5 Workloads"

gcloud billing projects link "${PROJECT_ID}" \
    --billing-account="${BILLING_ACCOUNT}"

export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")

Bật các API bắt buộc của Google Cloud

Trước khi xây dựng, hãy bật các API bắt buộc cho các dịch vụ cần thiết.

Lệnh bên dưới kích hoạt tất cả các dịch vụ cần thiết cho lớp học lập trình này trong dự án khối lượng công việc chính của bạn.

gcloud services enable \
    aiplatform.googleapis.com \
    artifactregistry.googleapis.com \
    cloudkms.googleapis.com \
    compute.googleapis.com \
    container.googleapis.com \
    iam.googleapis.com \
    logging.googleapis.com \
    monitoring.googleapis.com \
    --project="${PROJECT_ID}"

4. Thiết lập cơ sở hạ tầng GKE

Xây dựng cơ sở hạ tầng cốt lõi hỗ trợ cụm GKE của bạn. Việc này bao gồm thiết lập một mạng riêng cho cụm và định cấu hình khoá mã hoá của riêng bạn để bảo vệ dữ liệu trên các nút.

Định cấu hình mạng VPC

Tạo một Virtual Private Cloud (VPC) và mạng con tuỳ chỉnh. Phương pháp này giúp bạn có toàn quyền kiểm soát dải địa chỉ IP và đảm bảo cụm của bạn được cách ly như dự kiến.

Chạy các lệnh sau để tạo mạng VPC và mạng con trong khu vực bạn đã chỉ định.

export GKE_NETWORK_NAME="il5-gke-network"
export GKE_SUBNETWORK_NAME="il5-gke-subnet"

gcloud compute networks create "${GKE_NETWORK_NAME}" \
    --description="VPC network for GKE cluster in DoD IL5 Assured Workload" \
    --subnet-mode="custom" \
    --project="${PROJECT_ID}"

gcloud compute networks subnets create "${GKE_SUBNETWORK_NAME}" \
    --network="${GKE_NETWORK_NAME}" \
    --range="10.10.0.0/20" \
    --region="${REGION}" \
    --description="Subnet for GKE cluster nodes in DoD IL5 Assured Workload" \
    --project="${PROJECT_ID}"

Định cấu hình mã hoá bằng Cloud KMS

Để đáp ứng các yêu cầu tuân thủ nghiêm ngặt đối với dữ liệu tĩnh, hãy sử dụng Khoá mã hoá do khách hàng quản lý (CMEK). Điều này giúp bạn có quyền kiểm soát trực tiếp các khoá dùng để mã hoá đĩa khởi động của các nút GKE.

export KMS_KEYRING_NAME="il5_gke_key_ring"
export KMS_KEY_NAME="il5_gke_key"

gcloud kms keyrings create "${KMS_KEYRING_NAME}" \
    --location="$REGION" \
    --project="${KMS_PROJECT_ID}"

gcloud kms keys create "${KMS_KEY_NAME}" \
    --keyring="${KMS_KEYRING_NAME}" \
    --location="${REGION}" \
    --purpose="encryption" \
    --project="${KMS_PROJECT_ID}"

Vì khoá mã hoá tồn tại trong một dự án KMS riêng biệt so với dịch vụ cần sử dụng khoá đó, nên tác nhân dịch vụ Google Compute Engine trong dự án khối lượng công việc cần có quyền truy cập vào khoá.

Bạn phải cấp quyền rõ ràng cho tác nhân dịch vụ GCE từ dự án khối lượng công việc để sử dụng khoá này. Lệnh bên dưới thêm một liên kết chính sách IAM vào khoá, cấp vai trò cần thiết cho tác nhân dịch vụ.

gcloud kms keys add-iam-policy-binding "${KMS_KEY_NAME}" \
    --location="${REGION}" \
    --keyring="${KMS_KEYRING_NAME}" \
    --member="serviceAccount:service-${PROJECT_NUMBER}@compute-system.iam.gserviceaccount.com" \
    --role="roles/cloudkms.cryptoKeyEncrypterDecrypter" \
    --project="${KMS_PROJECT_ID}"

Định cấu hình tài khoản dịch vụ nút GKE

export GKE_NODE_SA=gke-node-sa

gcloud iam service-accounts create "${GKE_NODE_SA}" \
    --display-name="GKE Node Service Account" \
    --project="${PROJECT_ID}"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/monitoring.metricWriter"

5. Tạo và định cấu hình cụm GKE

Giờ đây, bạn có thể tạo cụm GKE. Lệnh sau đây cung cấp một cụm GKE có một số tính năng bảo mật được bật.

Quá trình này mất vài phút để hoàn tất khi Google Cloud cung cấp các nút và mặt phẳng điều khiển.

export GKE_CLUSTER=ppe-app

gcloud beta container clusters create "${GKE_CLUSTER}" \
    --project="$PROJECT_ID" \
    --region="$REGION" \
    --service-account="${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --release-channel="regular" \
    --machine-type="n2d-standard-4" \
    --image-type="COS_CONTAINERD" \
    --disk-type="pd-ssd" \
    --disk-size="50" \
    --boot-disk-kms-key="projects/${KMS_PROJECT_ID}/locations/${REGION}/keyRings/${KMS_KEYRING_NAME}/cryptoKeys/${KMS_KEY_NAME}" \
    --metadata disable-legacy-endpoints=true \
    --num-nodes="1" \
    --network="projects/${PROJECT_ID}/global/networks/${GKE_NETWORK_NAME}" \
    --subnetwork="projects/${PROJECT_ID}/regions/${REGION}/subnetworks/${GKE_SUBNETWORK_NAME}" \
    --security-posture="standard" \
    --workload-vulnerability-scanning="disabled" \
    --workload-pool="${PROJECT_ID}.svc.id.goog" \
    --workload-metadata=GKE_METADATA \
    --addons="HorizontalPodAutoscaling,HttpLoadBalancing,NodeLocalDNS,GcePersistentDiskCsiDriver" \
    --max-surge-upgrade=1 \
    --max-unavailable-upgrade=0 \
    --binauthz-evaluation-mode="DISABLED" \
    --no-enable-basic-auth \
    --enable-autoupgrade \
    --enable-autorepair \
    --enable-confidential-nodes \
    --confidential-node-type=sev \
    --enable-ip-access \
    --enable-ip-alias \
    --enable-managed-prometheus \
    --enable-dns-access \
    --enable-shielded-nodes \
    --shielded-integrity-monitoring \
    --shielded-secure-boot

Kết nối với cụm mới

Để tương tác với cụm mới, hãy định cấu hình công cụ dòng lệnh kubectl cục bộ.

Lệnh này tìm nạp thông tin xác thực và điểm cuối của cụm, đồng thời tự động định cấu hình tệp kubeconfig cục bộ. Sau khi chạy lệnh này, mọi lệnh kubectl mà bạn chạy sẽ được chuyển đến cụm GKE mới.

gcloud container clusters get-credentials "${GKE_CLUSTER}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --dns-endpoint

6. Định cấu hình danh tính ứng dụng

Để kết nối tài khoản dịch vụ Kubernetes với tài khoản dịch vụ Cloud IAM của Google Cloud, hãy định cấu hình Workload Identity.

Tạo tài khoản dịch vụ

Tạo Tài khoản dịch vụ Kubernetes (KSA) chuyên dụng bên trong cụm của bạn.

export GKE_NAMESPACE=default
export GKE_SA=ppe-sa

kubectl create sa "${GKE_SA}" --namespace="${GKE_NAMESPACE}"

Tiếp theo, ứng dụng của bạn cần có danh tính trong Google Cloud. Tạo một tài khoản dịch vụ Cloud IAM của Google cho ứng dụng. Sau khi tạo tài khoản dịch vụ, hãy cấp cho tài khoản đó các vai trò cần thiết.

# Create GCP service account
gcloud iam service-accounts create "${GKE_SA}" \
    --project="${PROJECT_ID}"
# Grant necessary roles
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/aiplatform.user"

Cho phép Tài khoản dịch vụ Kubernetes mạo danh tài khoản IAM

Sau khi tạo cả hai tài khoản dịch vụ, bước cuối cùng là tạo liên kết giữa chúng. Đây là một quy trình gồm 2 phần. Trước tiên, hãy thêm một chính sách IAM vào Tài khoản dịch vụ Google Cloud.

# Allow the Kubernetes service account to act as GCP service account by using Workload Identity
gcloud iam service-accounts add-iam-policy-binding "${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --project="${PROJECT_ID}" \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:${PROJECT_ID}.svc.id.goog[${GKE_NAMESPACE}/${GKE_SA}]"

Thứ hai, chú thích Tài khoản dịch vụ Kubernetes.

kubectl annotate --namespace="${GKE_NAMESPACE}" serviceaccount "$GKE_SA" \
    iam.gke.io/gcp-service-account="${GKE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"

Sau khi hoàn tất, mọi pod chạy trong cụm của bạn bằng tài khoản dịch vụ Kubernetes đều có thể truy cập vào API Vertex.

Lưu ý: Bạn có thể loại bỏ tính năng mạo danh tài khoản dịch vụ để đơn giản hoá cấu hình này. Xem tại đây để biết thông tin chi tiết và các giới hạn.

7. Xây dựng và triển khai ứng dụng

Đã đến lúc đóng gói ứng dụng, lưu trữ ứng dụng và triển khai ứng dụng đó vào cụm GKE.

Tạo kho lưu trữ Artifact Registry

Trước khi có thể chạy ứng dụng, hãy đóng gói ứng dụng đó dưới dạng một vùng chứa Docker và lưu trữ ứng dụng đó bên trong kho lưu trữ Artifact Registry. Sử dụng lệnh bên dưới để tạo kho lưu trữ này.

export REPOSITORY_ID=ppe-repo

gcloud artifacts repositories create "${REPOSITORY_ID}" \
  --repository-format=docker \
  --location="${REGION}" \
  --project="${PROJECT_ID}" \
  --description="Regional Docker repo for PPE App"

Bạn phải cấp quyền rõ ràng cho tài khoản dịch vụ mà các nút GKE sử dụng để đọc từ kho lưu trữ mới.

gcloud artifacts repositories add-iam-policy-binding "${REPOSITORY_ID}" \
    --location="${REGION}" \
    --role="roles/artifactregistry.reader" \
    --project="${PROJECT_ID}" \
    --member="serviceAccount:${GKE_NODE_SA}@${PROJECT_ID}.iam.gserviceaccount.com"

Xây dựng và đẩy hình ảnh Docker

Xây dựng và đẩy hình ảnh Docker vào kho lưu trữ. Trước tiên, hãy sao chép mã nguồn và xây dựng hình ảnh vùng chứa. Sau đó, gắn thẻ hình ảnh đó bằng đường dẫn đầy đủ của Artifact Registry và đẩy hình ảnh đó vào kho lưu trữ mà bạn đã tạo trước đó.

git clone https://github.com/GoogleCloudPlatform/next-26-sessions.git

cd BRK3-034-workplace-safety

cd ppe

export IMAGE_TAG="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_ID}/ppe-app:v15"
docker build -t "${IMAGE_TAG}" .
docker push "${IMAGE_TAG}"

Triển khai vào GKE

Khi hình ảnh vùng chứa có trong Artifact Registry, bước cuối cùng là hướng dẫn GKE kéo và kích hoạt hình ảnh đó. Bạn có thể thực hiện việc này bằng cách xác định tài nguyên của ứng dụng trong tệp kê khai Kubernetes và áp dụng tệp đó cho cụm. Lệnh này tạo các đối tượng Triển khai và Dịch vụ được xác định trong tệp.

export GKE_DEPLOY=ppe-detector

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${GKE_DEPLOY}
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ${GKE_DEPLOY}
  template:
    metadata:
      labels:
        app: ${GKE_DEPLOY}
    spec:
      serviceAccountName: ${GKE_SA}
      containers:
      - name: ${GKE_DEPLOY}
        image: ${IMAGE_TAG}
        env:
        - name: PROJECT_ID
          value: ${PROJECT_ID}
        - name: LOCATION
          value: ${REGION}
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
  name: ${GKE_DEPLOY}
spec:
  type: LoadBalancer
  selector:
    app: ${GKE_DEPLOY}
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
EOF

8. Kiểm thử ứng dụng

Bước cuối cùng là truy cập và kiểm thử ứng dụng minh hoạ. Việc này bao gồm việc truy xuất địa chỉ IP ngoài được gán cho dịch vụ và tương tác với dịch vụ đó thông qua một giao diện người dùng đơn giản.

Truy xuất IP ngoài của dịch vụ

Nhận IP ngoài của dịch vụ được hiển thị (mất khoảng 30 giây để cung cấp)

export IP_ADDRESS=$(kubectl get service "${GKE_DEPLOY}" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $IP_ADDRESS

Chạy giao diện người dùng cục bộ

Đối với bản minh hoạ này, giao diện người dùng là một trang HTML/JavaScript đơn giản, không thuộc quá trình triển khai GKE. Giao diện này được thiết kế để chạy trên máy cục bộ của bạn.

Giao diện người dùng phải được phân phát từ Google Cloud Platform (GCP) trong một ứng dụng phát hành chính thức. Trên máy cục bộ:

# Update the index.html file with the server IP address
cd frontend

# For Linux
sed -i "s#\(const BACKEND_URL = \"http://\)[^/]\+\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"

# For MacOS
#sed -i '' "s#\(const BACKEND_URL = #\"http://\)[^/]*\(\/analyze\";\)#\1${IP_ADDRESS}\2#g" "index.html"

python3 -m http.server 8001

Mở http://localhost:8001/index.html trong Chrome.

9. Dọn dẹp

Để tránh bị tính phí liên tục, hãy xoá các tài nguyên được tạo trong lớp học lập trình này.

Huỷ cụm GKE

Để xoá toàn bộ ứng dụng, bạn chỉ cần xoá cụm GKE. Để thực hiện việc này, hãy chạy:

gcloud container clusters delete "${GKE_CLUSTER}" \
    --region="$REGION" \
    --project="${PROJECT_ID}"

Xoá Assured Workloads

Chạy các lệnh sau để xoá tất cả các tài nguyên liên quan đến Assured Workload.

# Workload project deletion
gcloud billing projects unlink "${PROJECT_ID}"
gcloud projects delete "${PROJECT_ID}"

# KMS project deletion
gcloud billing projects unlink "${KMS_PROJECT_ID}"
gcloud projects delete "${KMS_PROJECT_ID}"

# Assured Workload folder deletion
gcloud resource-manager folders delete ${WORKLOAD_FOLDER_ID} --quiet

# Assured Workload deletion
gcloud assured workloads delete "${ASSURED_WORKLOAD_ID}" \
    --location="${REGION}" \
    --organization="${GCP_ORGANIZATION}" \
    --project="${QUOTA_PROJECT_ID}"

10. Xin chúc mừng

Nhiệm vụ đã hoàn tất! Bạn đã xây dựng thành công một hệ thống phát hiện an toàn tại nơi làm việc cho các ngành được quản lý, sử dụng Gemini để phát hiện mũ bảo hộ.

Những gì bạn đã hoàn thành:

  • Bảo vệ dữ liệu và quyền riêng tư: Bạn đã cung cấp một nút GKE bảo mật bằng CMEK
  • Ranh giới dữ liệu: Bạn đã bật các biện pháp kiểm soát tuân thủ nền tảng cho một môi trường được quản lý

Tài liệu tham khảo