Sicherheit eines Systems zur Erkennung von Arbeitssicherheitsrisiken

1. Einführung

In diesem Codelab erstellen Sie eine einfache Demoanwendung, die zeigt, wie Sie verschiedene Google Cloud-Dienste für einen Dienst in einem Projekt mit Compliance-Einschränkungen einbinden. In diesem Projekt werden die folgenden Sicherheitsfunktionen verwendet:

Dieses Codelab richtet sich an Entwickler aller Erfahrungsstufen, auch an Anfänger. Sie verwenden die Befehlszeile in der Google Cloud Shell und Python-Code. Sie müssen kein Python-Experte sein, aber ein grundlegendes Verständnis des Lesens von Code hilft Ihnen, die Konzepte zu verstehen.

Hinweis:Dies ist ein vereinfachter Proof of Concept und keine Produktionsanwendung. Wenden Sie in einem realen Szenario zusätzliche Vorsichtsmaßnahmen an, z. B. authentifizierten und sicheren externen Zugriff auf diesen Dienst.

2. Hinweis

Projekteinrichtung

../shared/_project-setup.md

Cloud Shell starten

Die Cloud Shell ist eine Befehlszeilenumgebung, die in Google Cloud ausgeführt wird und in der die erforderlichen Tools vorinstalliert sind.

  1. Klicken Sie oben in der Google Cloud Console auf Cloud Shell aktivieren:

404e4cce0f23e5c5.png

  1. Führen Sie nach der Verbindung mit der Cloud Shell den folgenden Befehl aus, um Ihre Authentifizierung in der Cloud Shell zu überprüfen:
gcloud auth list
  1. Führen Sie den folgenden Befehl aus, um zu bestätigen, dass Ihr Projekt für die Verwendung mit gcloud konfiguriert ist:
gcloud config get project
  1. Bestätigen Sie, dass das Projekt wie erwartet ist, und führen Sie dann den folgenden Befehl aus, um Ihre Projekt-ID festzulegen:
export PROJECT_ID=$(gcloud config get project)

Erforderliche IAM-Berechtigungen

Das Konto, das Sie für dieses Codelab verwenden, muss die folgenden IAM-Rollen haben. Diese Berechtigungen sind erforderlich, um die erforderlichen Google Cloud-Ressourcen (Projekte, Ordner, GKE-Cluster, KMS-Schlüssel, Dienstkonten usw.) zu erstellen und die Assured Workload zu konfigurieren.

Auf Organisationsebene:

  • roles/assuredworkloads.admin (Assured Workloads-Administrator) : Zum Erstellen und Verwalten der Assured Workloads-Ressource selbst und zum Sicherstellen der Compliance-Konfiguration.

Auf Abrechnungskontoebene (für Ihr Abrechnungskonto):

  • roles/billing.accountUser (Billing Account User): Zum Verknüpfen des angegebenen Rechnungskontos.

Codelab-Variablen konfigurieren

Um die erforderliche Infrastruktur zu erstellen, müssen Sie die folgenden Umgebungsvariablen angeben:

# 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. Grundlagen für Assured Workloads erstellen

Sie können jetzt die Grundlagen für Ihre Anwendung in einer regulierten Umgebung schaffen. Mit Assured Workloads können Sie Complianceanforderungen durchsetzen, indem Sie eine kontrollierte Umgebung für Ihre Ressourcen erstellen.

Kontingentprojekt konfigurieren

Aktivieren Sie die Assured Workloads API in Ihrem Kontingentprojekt. Diese API ist erforderlich, um Assured Workloads zu erstellen und zu verwalten.

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

Assured Workload-Umgebung erstellen

Mit dem folgenden Befehl wird eine sichere „Landing Zone“ für Ihre Demo erstellt. Dabei werden zwei neue Google Cloud-Projekte unter dem angegebenen Ordner und Abrechnungskonto erstellt.

  • In einem Projekt werden Ihr GKE-Cluster und Ihre Anwendung gehostet.
  • Im anderen Projekt werden Ihre kundenverwalteten Verschlüsselungsschlüssel (Customer-Managed Encryption Keys, CMEK) verwaltet.

Die angegebenen IL5-Compliancekontrollen werden ab dem Erstellungszeitpunkt automatisch auf beide Projekte angewendet.

Führen Sie den folgenden Befehl aus, um die Arbeitslastumgebung zu erstellen.

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)")

Erforderliche Google Cloud APIs aktivieren

Aktivieren Sie vor dem Erstellen die erforderlichen APIs für die benötigten Dienste.

Mit dem folgenden Befehl werden alle erforderlichen Dienste für dieses Codelab in Ihrem primären Arbeitslastprojekt aktiviert.

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. GKE-Infrastruktur einrichten

Erstellen Sie die Kerninfrastruktur, die Ihren GKE-Cluster unterstützt. Dazu müssen Sie ein dediziertes Netzwerk für Ihren Cluster einrichten und Ihre eigenen Verschlüsselungsschlüssel konfigurieren, um die Daten auf Ihren Knoten zu schützen.

VPC-Netzwerk konfigurieren

Erstellen Sie eine benutzerdefinierte Virtual Private Cloud (VPC) und ein Subnetz. Mit diesem Ansatz haben Sie die vollständige Kontrolle über den IP-Adressbereich und stellen sicher, dass Ihr Cluster wie vorgesehen isoliert ist.

Führen Sie die folgenden Befehle aus, um das VPC-Netzwerk und ein Subnetz in der angegebenen Region zu erstellen.

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}"

Verschlüsselung mit Cloud KMS konfigurieren

Um strenge Complianceanforderungen für ruhende Daten zu erfüllen, verwenden Sie kundenverwaltete Verschlüsselungsschlüssel (Customer-Managed Encryption Keys, CMEK). So haben Sie die direkte Kontrolle über die Schlüssel, mit denen die Boot-Volumes Ihrer GKE-Knoten verschlüsselt werden.

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}"

Da sich der Verschlüsselungsschlüssel in einem separaten KMS-Projekt befindet als der Dienst, der ihn verwenden muss, benötigt der Google Compute Engine-Dienst-Agent im Arbeitslastprojekt Zugriff auf den Schlüssel.

Sie müssen dem GCE-Dienst-Agenten aus dem Arbeitslastprojekt explizit die Berechtigung zur Verwendung dieses Schlüssels gewähren. Mit dem folgenden Befehl wird dem Schlüssel eine IAM-Richtlinienbindung hinzugefügt, wodurch dem Dienst-Agenten die erforderliche Rolle zugewiesen wird.

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}"

GKE-Knotendienstkonto konfigurieren

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. GKE-Cluster erstellen und konfigurieren

Jetzt können Sie den GKE-Cluster erstellen. Mit dem folgenden Befehl wird ein GKE-Cluster mit mehreren aktivierten Sicherheitsfunktionen bereitgestellt.

Dieser Vorgang dauert einige Minuten, da Google Cloud die Knoten und die Steuerungsebene bereitstellt.

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

Verbindung zum neuen Cluster herstellen

Konfigurieren Sie das lokale kubectl-Befehlszeilentool, um mit dem neuen Cluster zu interagieren.

Mit diesem Befehl werden die Anmeldedaten und der Endpunkt des Clusters abgerufen und die lokale kubeconfig-Datei automatisch konfiguriert. Nach dem Ausführen dieses Befehls werden alle kubectl-Befehle an Ihren neuen GKE-Cluster weitergeleitet.

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

6. Anwendungsidentität konfigurieren

Konfigurieren Sie Workload Identity, um ein Kubernetes-Dienstkonto mit einem Google Cloud IAM-Dienstkonto zu verbinden.

Dienstkonten erstellen

Erstellen Sie ein dediziertes Kubernetes-Dienstkonto (Kubernetes Service Account, KSA) in Ihrem Cluster.

export GKE_NAMESPACE=default
export GKE_SA=ppe-sa

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

Als Nächstes benötigt Ihre Anwendung eine Identität in Google Cloud. Erstellen Sie ein Google Cloud IAM-Dienstkonto für die Anwendung. Nachdem Sie das Dienstkonto erstellt haben, weisen Sie ihm die erforderlichen Rollen zu.

# 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"

Kubernetes-Dienstkonto erlauben, die Identität des IAM-Dienstkontos zu übernehmen

Nachdem beide Dienstkonten erstellt wurden, müssen Sie sie noch verknüpfen. Dieser Vorgang besteht aus zwei Teilen. Fügen Sie zuerst Ihrem Google Cloud-Dienstkonto eine IAM-Richtlinie hinzu.

# 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}]"

Annotieren Sie dann Ihr Kubernetes-Dienstkonto.

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

Danach kann jeder Pod, der in Ihrem Cluster mit dem Kubernetes-Dienstkonto ausgeführt wird, auf die Vertex API zugreifen.

Hinweis: Sie können die Identitätsübernahme des Dienstkontos vermeiden, um diese Konfiguration zu vereinfachen. Weitere Informationen und Einschränkungen finden Sie hier.

7. Anwendung erstellen und bereitstellen

Jetzt können Sie Ihre Anwendung verpacken, speichern und in Ihrem GKE-Cluster bereitstellen.

Artifact Registry-Repository erstellen

Bevor Sie die Anwendung ausführen können, müssen Sie sie als Docker-Container verpacken und in einem Artifact Registry-Repository speichern. Verwenden Sie den folgenden Befehl, um dieses Repository zu erstellen.

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"

Sie müssen dem Dienstkonto, das von den GKE-Knoten verwendet wird, explizit die Berechtigung zum Lesen aus Ihrem neuen Repository gewähren.

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"

Docker-Image erstellen und übertragen

Erstellen Sie das Docker-Image und übertragen Sie es in das Repository. Klonen Sie zuerst den Quellcode und erstellen Sie das Container-Image. Taggen Sie es dann mit dem vollständigen Artifact Registry-Pfad und übertragen Sie es in das zuvor erstellte Repository.

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}"

In GKE bereitstellen

Nachdem das Container-Image in Artifact Registry verfügbar ist, müssen Sie GKE anweisen, es abzurufen und auszuführen. Dazu definieren Sie die Ressourcen Ihrer Anwendung in einer Kubernetes-Manifestdatei und wenden sie auf den Cluster an. Mit diesem Befehl werden die in der Datei definierten Deployment- und Dienstobjekte erstellt.

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. Anwendung testen

Im letzten Schritt greifen Sie auf die Demoanwendung zu und testen sie. Dazu müssen Sie die externe IP-Adresse abrufen, die dem Dienst zugewiesen ist, und über ein einfaches Frontend mit ihm interagieren.

Externe IP-Adresse des Dienstes abrufen

Rufen Sie die externe IP-Adresse des bereitgestellten Dienstes ab. Die Bereitstellung dauert etwa 30 Sekunden.

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

Frontend lokal ausführen

Für diese Demo ist das Frontend eine einfache HTML-/JavaScript-Seite, die nicht Teil der GKE-Bereitstellung ist. Es ist für die Ausführung auf Ihrem lokalen Computer konzipiert.

Bei einer Produktionsanwendung sollte das Frontend von GCP bereitgestellt werden. Auf dem lokalen Computer:

# 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

Öffnen Sie in Chrome http://localhost:8001/index.html.

9. Bereinigen

Löschen Sie die in diesem Codelab erstellten Ressourcen, um laufende Kosten zu vermeiden.

GKE-Cluster löschen

Wenn Sie die gesamte Anwendung löschen möchten, müssen Sie nur den GKE-Cluster löschen. Führen Sie dazu den folgenden Befehl aus:

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

Assured Workloads löschen

Führen Sie die folgenden Befehle aus, um alle Ressourcen im Zusammenhang mit Assured Workloads zu löschen.

# 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. Glückwunsch

Aufgabe abgeschlossen! Sie haben ein System zur Erkennung von Arbeitsplatzsicherheit für regulierte Branchen erstellt, das mit Gemini Schutzhelme erkennen kann.

Das haben Sie erreicht:

  • Datenschutz und ‐sicherheit:Sie haben einen Confidential GKE-Knoten mit CMEK bereitgestellt.
  • Datenbegrenzungen:Sie haben Plattform-Compliancekontrollen für eine regulierte Umgebung aktiviert.

Referenzdokumente