GCP Deployment
DeepIntShield Enterprise images for GCP customers are distributed through GCP Artifact Registry, enabling native Workload Identity for secure, keyless authentication.
Architecture
Section titled “Architecture”flowchart LR subgraph GCP[GCP Project] subgraph GKE[GKE Cluster] Pod[DeepIntShield Pod] KSA[K8s ServiceAccount] end GSA[GCP Service Account] AR[Artifact Registry<br/>DeepIntShield Images] end
KSA -->|Workload Identity| GSA Pod -->|Impersonates| GSA GSA -->|Pull Permission| AR AR -->|Image| PodPrerequisites
Section titled “Prerequisites”- GKE cluster (v1.24+) with Workload Identity enabled
gcloudCLI configured with appropriate permissionskubectlconfigured for your GKE cluster- Your GCP project allowlisted by DeepIntShield team
Workload Identity (Recommended)
Section titled “Workload Identity (Recommended)”Workload Identity provides the most secure authentication method for GKE deployments by eliminating the need for service account keys.
Step 1: Enable Workload Identity on GKE
Section titled “Step 1: Enable Workload Identity on GKE”If not already enabled, enable Workload Identity on your cluster:
# For existing clustergcloud container clusters update YOUR_CLUSTER_NAME \ --region=YOUR_REGION \ --workload-pool=YOUR_PROJECT_ID.svc.id.goog
# Verify Workload Identity is enabledgcloud container clusters describe YOUR_CLUSTER_NAME \ --region=YOUR_REGION \ --format="value(workloadIdentityConfig.workloadPool)"Step 2: Create GCP Service Account
Section titled “Step 2: Create GCP Service Account”Create a service account that will be used to pull images:
# Create service accountgcloud iam service-accounts create deepintshield-pull-sa \ --display-name="DeepIntShield Image Pull SA" \ --project=YOUR_PROJECT_IDStep 3: Request Access from DeepIntShield Team
Section titled “Step 3: Request Access from DeepIntShield Team”Provide the following to the DeepIntShield team:
- Your GCP project ID
- Service account email:
deepintshield-pull-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com
The DeepIntShield team will grant the necessary permissions to pull images from the registry.
Step 4: Create Namespace and ServiceAccount
Section titled “Step 4: Create Namespace and ServiceAccount”kubectl create namespace deepintshieldapiVersion: v1kind: ServiceAccountmetadata: name: deepintshield-sa namespace: deepintshield annotations: iam.gke.io/gcp-service-account: deepintshield-pull-sa@YOUR_PROJECT_ID.iam.gserviceaccount.comStep 5: Bind Kubernetes SA to GCP SA
Section titled “Step 5: Bind Kubernetes SA to GCP SA”Allow the Kubernetes ServiceAccount to impersonate the GCP Service Account:
gcloud iam service-accounts add-iam-policy-binding \ deepintshield-pull-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com \ --role=roles/iam.workloadIdentityUser \ --member="serviceAccount:YOUR_PROJECT_ID.svc.id.goog[deepintshield/deepintshield-sa]"Step 6: Create Image Pull Secret with Token Refresh
Section titled “Step 6: Create Image Pull Secret with Token Refresh”Artifact Registry tokens expire after 60 minutes. Use a CronJob to refresh the imagePullSecret:
apiVersion: batch/v1kind: CronJobmetadata: name: refresh-ar-secret namespace: deepintshieldspec: schedule: "*/30 * * * *" # Every 30 minutes successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 3 jobTemplate: spec: template: spec: serviceAccountName: deepintshield-sa containers: - name: token-refresh image: google/cloud-sdk:slim command: ["/bin/bash", "-c"] args: - | set -e
# Get access token using Workload Identity TOKEN=$(gcloud auth print-access-token)
# Delete existing secret if it exists kubectl delete secret ar-pull-secret --ignore-not-found -n deepintshield
# Create new imagePullSecret kubectl create secret docker-registry ar-pull-secret \ --docker-server=REGION-docker.pkg.dev \ --docker-username=oauth2accesstoken \ --docker-password="$TOKEN" \ -n deepintshield
echo "Secret refreshed at $(date)" restartPolicy: OnFailure---apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: secret-manager namespace: deepintshieldrules:- apiGroups: [""] resources: ["secrets"] verbs: ["get", "create", "delete"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: secret-manager-binding namespace: deepintshieldsubjects:- kind: ServiceAccount name: deepintshield-sa namespace: deepintshieldroleRef: kind: Role name: secret-manager apiGroup: rbac.authorization.k8s.ioStep 7: Deploy DeepIntShield
Section titled “Step 7: Deploy DeepIntShield”apiVersion: apps/v1kind: Deploymentmetadata: name: deepintshield namespace: deepintshieldspec: replicas: 2 selector: matchLabels: app: deepintshield template: metadata: labels: app: deepintshield spec: serviceAccountName: deepintshield-sa imagePullSecrets: - name: ar-pull-secret containers: - name: deepintshield image: REGION-docker.pkg.dev/DEEPINTSHIELD_PROJECT/YOUR_HUB_SLUG/deepintshield:latest ports: - containerPort: 8080 name: http resources: requests: cpu: "250m" memory: "512Mi" limits: cpu: "1000m" memory: "2Gi" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 5 volumeMounts: - name: config mountPath: /app/data/config.json subPath: config.json volumes: - name: config secret: secretName: deepintshield-config---apiVersion: v1kind: Servicemetadata: name: deepintshield namespace: deepintshieldspec: selector: app: deepintshield ports: - port: 80 targetPort: 8080 protocol: TCP type: ClusterIPBootstrap: Initial Secret Creation
Section titled “Bootstrap: Initial Secret Creation”Before the first deployment, manually create the initial imagePullSecret:
# Authenticate gcloudgcloud auth login
# Create initial secretkubectl create secret docker-registry ar-pull-secret \ --docker-server=REGION-docker.pkg.dev \ --docker-username=oauth2accesstoken \ --docker-password="$(gcloud auth print-access-token)" \ -n deepintshieldService Account Impersonation
Section titled “Service Account Impersonation”For cross-project deployments or when you need to use an existing service account:
Configure Impersonation
Section titled “Configure Impersonation”# Grant impersonation permissiongcloud iam service-accounts add-iam-policy-binding \ DEEPINTSHIELD_PROVIDED_SA@DEEPINTSHIELD_PROJECT.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountTokenCreator \ --member="serviceAccount:deepintshield-pull-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com"Token Refresh with Impersonation
Section titled “Token Refresh with Impersonation”Update the CronJob to use impersonation:
args:- | set -e
# Get access token by impersonating the DeepIntShield SA TOKEN=$(gcloud auth print-access-token \ --impersonate-service-account=DEEPINTSHIELD_PROVIDED_SA@DEEPINTSHIELD_PROJECT.iam.gserviceaccount.com)
kubectl delete secret ar-pull-secret --ignore-not-found -n deepintshield kubectl create secret docker-registry ar-pull-secret \ --docker-server=REGION-docker.pkg.dev \ --docker-username=oauth2accesstoken \ --docker-password="$TOKEN" \ -n deepintshieldService Account Key (Legacy)
Section titled “Service Account Key (Legacy)”For environments that cannot use Workload Identity:
# Create key (provided by DeepIntShield team)# Store key securely
# Create imagePullSecretkubectl create secret docker-registry ar-pull-secret \ --docker-server=REGION-docker.pkg.dev \ --docker-username=_json_key \ --docker-password="$(cat sa-key.json)" \ -n deepintshieldVerifying Access
Section titled “Verifying Access”Test Artifact Registry Authentication
Section titled “Test Artifact Registry Authentication”# Configure docker for Artifact Registrygcloud auth configure-docker REGION-docker.pkg.dev
# Pull test (requires impersonation or direct access)docker pull REGION-docker.pkg.dev/DEEPINTSHIELD_PROJECT/YOUR_HUB_SLUG/deepintshield:latestVerify Workload Identity Configuration
Section titled “Verify Workload Identity Configuration”# Check ServiceAccount annotationkubectl get sa deepintshield-sa -n deepintshield -o yaml
# Verify pod can authenticatekubectl exec -it deployment/deepintshield -n deepintshield -- \ gcloud auth print-access-token
# Check token refresh CronJobkubectl get cronjob refresh-ar-secret -n deepintshieldkubectl get jobs -n deepintshieldTroubleshooting
Section titled “Troubleshooting”ImagePullBackOff Errors
Section titled “ImagePullBackOff Errors”- Check imagePullSecret exists:
kubectl get secret ar-pull-secret -n deepintshield - Verify token is valid: Check if CronJob ran successfully
- Check Workload Identity binding: Ensure GCP SA is bound to K8s SA
# Check pod eventskubectl describe pod -l app=deepintshield -n deepintshield
# Manually refresh tokenkubectl create job --from=cronjob/refresh-ar-secret manual-refresh -n deepintshieldWorkload Identity Issues
Section titled “Workload Identity Issues”# Verify Workload Identity poolgcloud container clusters describe YOUR_CLUSTER_NAME \ --region=YOUR_REGION \ --format="value(workloadIdentityConfig.workloadPool)"
# Check IAM bindinggcloud iam service-accounts get-iam-policy \ deepintshield-pull-sa@YOUR_PROJECT_ID.iam.gserviceaccount.comToken Expiration
Section titled “Token Expiration”If pods fail to pull images after 60 minutes:
- Verify CronJob is running:
kubectl get cronjob -n deepintshield - Check CronJob logs:
kubectl logs -l job-name=refresh-ar-secret -n deepintshield - Manually trigger refresh:
kubectl create job --from=cronjob/refresh-ar-secret manual-refresh -n deepintshield
Next Steps
Section titled “Next Steps”- Configure DeepIntShield settings for your use case
- Set up observability for monitoring
- Enable clustering for high availability