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ẽ tạo một ứng dụng minh hoạ cơ bản cho thấy cách tích hợp nhiều dịch vụ của Google Cloud cho một dịch vụ nằm trong dự án có các quy định hạn chế về việc tuân thủ. Dự án này sử dụng các chức năng bảo mật sau:

Lớp học lập trình này dành cho 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 kiến thức 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ằng chứng đơn giản về khái niệm, không phải là một ứng dụng phát hành chính thức. Á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 đã 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

Khởi động 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 Cloud Console:

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 của bạn 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 dự án đúng như mong đợi, 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 bạn 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ó những quyền này để tạo các tài nguyên cần thiết trên 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):

  • 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 được 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 kiểm soát. 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 Assured Workloads API trong dự án hạn mức của bạn. Bạn cần 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 Workloads

Lệnh sau đây sẽ tạo một "vùng tiếp đất" an toàn cho bản minh hoạ của bạn. Thao tác này sẽ tạo 2 dự án Google Cloud mới 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 và ứng dụng GKE của bạn.
  • Dự án khác quản lý Khoá mã hoá do khách hàng quản lý (CMEK).

Dịch vụ này 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 chúng được tạo.

Chạy lệnh sau để tạo môi trường tải.

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 tạo, hãy bật các API bắt buộc cho những dịch vụ cần thiết.

Lệnh bên dưới sẽ 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 chuyên dụ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 tách biệt như dự kiến.

Chạy các lệnh sau để tạo mạng VPC và một mạng con trong khu vực mà 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 tính năng mã hoá bằng Cloud KMS

Để đáp ứng các yêu cầu nghiêm ngặt về việc tuân thủ đối với dữ liệu không hoạt động, hãy sử dụng Khoá mã hoá do khách hàng quản lý (CMEK). Nhờ đó, bạn có thể 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á nằm trong một dự án KMS riêng biệt 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 tải 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 tải để sử dụng khoá này. Lệnh bên dưới sẽ 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 sẽ cung cấp một cụm GKE có bật một số tính năng bảo mật.

Quá trình này mất vài phút để hoàn tất vì Google Cloud sẽ cấp phát 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 đăng nhập 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. 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 một Tài khoản dịch vụ Kubernetes (KSA) chuyên dụng 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ó một danh tính trong Google Cloud. Tạo một tài khoản dịch vụ Cloud IAM trong Google Cloud 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 mối liên kết giữa hai tài khoản đó. Đây là 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 của bạn.

# 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 của bạn.

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 nhóm chạy trong cụm của bạn bằng tài khoản dịch vụ Kubernetes hiện có thể truy cập vào Vertex API.

Lưu ý: Bạn có thể loại bỏ việc 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 hạn chế.

7. Tạo và triển khai ứng dụng

Đã đến lúc đóng gói ứng dụng, lưu trữ 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 đó trong một kho lưu trữ Artifact Registry. Hãy 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"

Tạo và đẩy hình ảnh Docker

Tạo 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à tạo hình ảnh vùng chứa. Sau đó, gắn thẻ bằng đường dẫn đầy đủ của Artifact Registry và đẩy nó 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

Với 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à chạy 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 sẽ 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 truy xuất IP ngoài được chỉ định cho dịch vụ và tương tác với địa chỉ đó 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ộ

Trong 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 quy trình triển khai GKE. Công cụ 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 nên được phân phát từ 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 đã 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 đó, 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ả tài nguyên liên quan đến Assured Workloads.

# 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

Đã hoàn thành nhiệm vụ! 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ộ lao động.

Những gì bạn đã đạt được:

  • 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 chế độ kiểm soát việc 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