GCP for DevOps — GKE Workloads
GKE Workloads
This page covers deploying production workloads on GKE — Deployments, Services, Ingress, ConfigMaps, Secrets, and health checks.
Deployment with Health Checks
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
labels:
app: api-server
spec:
replicas: 3
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
serviceAccountName: app-ksa
containers:
- name: api
image: us-central1-docker.pkg.dev/my-project/my-repo/api:v1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
Services
# ClusterIP (internal only)
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
type: ClusterIP
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
---
# LoadBalancer (external)
apiVersion: v1
kind: Service
metadata:
name: api-server-external
spec:
type: LoadBalancer
selector:
app: api-server
ports:
- port: 443
targetPort: 8080
---
# NodePort
apiVersion: v1
kind: Service
metadata:
name: api-server-nodeport
spec:
type: NodePort
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
nodePort: 30080
GKE Ingress (HTTP/S Load Balancer)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.global-static-ip-name: "api-ip"
networking.gke.io/managed-certificates: "api-cert"
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-server
port:
number: 80
---
# Managed SSL Certificate
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: api-cert
spec:
domains:
- api.example.com
# Reserve a static IP for the Ingress
$ gcloud compute addresses create api-ip --global
# Get the IP
$ gcloud compute addresses describe api-ip --global \
--format="value(address)"
ConfigMaps
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "10.0.1.5"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"
config.yaml: |
server:
port: 8080
timeout: 30s
features:
cache: true
# Use ConfigMap in a Deployment
containers:
- name: api
image: my-api:v1.0.0
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: config.yaml
path: config.yaml
Kubernetes Secrets
# Create a secret from literal values
$ kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=s3cur3p@ss
# Create from file
$ kubectl create secret generic tls-secret \
--from-file=tls.crt=server.crt \
--from-file=tls.key=server.key
# Use secrets in a Deployment
containers:
- name: api
image: my-api:v1.0.0
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Network Policies
Restrict pod-to-pod communication.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-frontend
spec:
podSelector:
matchLabels:
app: api-server
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Pod Disruption Budgets
Ensure availability during voluntary disruptions (node upgrades, scaling).
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api-server
Common Mistakes
| Mistake | Why It’s Wrong | Fix |
|---|---|---|
| No readiness probe | Traffic sent to unready pods | Always configure readiness probes |
| No resource requests/limits | OOM kills, noisy neighbors | Set appropriate resources |
| Secrets in ConfigMaps | Not encrypted | Use K8s Secrets or Secret Manager |
| No PodDisruptionBudget | All pods evicted during upgrade | Set PDB with minAvailable |
| Single replica in production | No availability if pod crashes | Use at least 3 replicas with PDB |
Quick Reference
| Resource | Purpose |
|---|---|
| Deployment | Manage replica sets, rolling updates |
| Service (ClusterIP) | Internal load balancing |
| Service (LoadBalancer) | External L4 load balancer |
| Ingress | External L7 HTTP/S load balancer |
| ConfigMap | Non-sensitive configuration |
| Secret | Sensitive data (base64 encoded) |
| NetworkPolicy | Pod-to-pod firewall rules |
| PodDisruptionBudget | Availability during disruptions |
Next → Container CI/CD