Deploy to Google Kubernetes Engine
Deploy your agents to GKE with full control and customization using Kubernetes
Feature Coming Soon
GKE deployment commands are currently being developed for @iqai/adk
. The examples below show manual deployment methods you can use now.
GKE is Google Cloud's managed Kubernetes service. It allows you to deploy and manage containerized applications using Kubernetes with the highest degree of control and customization.
Manual Deployment (Available Now)
Prerequisites
Set your environment variables:
export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_LOCATION=us-central1
export GOOGLE_CLOUD_PROJECT_NUMBER=$(gcloud projects describe --format json $GOOGLE_CLOUD_PROJECT | jq -r ".projectNumber")
If you don't have jq
installed, run gcloud projects describe $GOOGLE_CLOUD_PROJECT
and copy the project number manually.
Install kubectl
following the GKE documentation.
Deployment Steps
Create GKE Cluster
Create an Autopilot cluster:
gcloud container clusters create-auto adk-cluster \
--location=$GOOGLE_CLOUD_LOCATION \
--project=$GOOGLE_CLOUD_PROJECT
Connect to the cluster:
gcloud container clusters get-credentials adk-cluster \
--location=$GOOGLE_CLOUD_LOCATION \
--project=$GOOGLE_CLOUD_PROJECT
Create Artifact Registry
Create a repository to store container images:
gcloud artifacts repositories create adk-repo \
--repository-format=docker \
--location=$GOOGLE_CLOUD_LOCATION \
--description="ADK repository"
Project Structure
Organize your project files:
your-project-directory/
├── src/
│ ├── agent/
│ │ └── index.ts # Your agent code
│ └── server.ts # Express server entry point
├── k8s/
│ └── deployment.yaml # Kubernetes manifests
├── package.json # Node.js dependencies
├── tsconfig.json # TypeScript configuration
└── Dockerfile # Container build instructions
Code Configuration
Express Server
import express from 'express';
import { LlmAgent, Runner, InMemorySessionService } from '@iqai/adk';
const app = express();
app.use(express.json());
// Create your agent
const agent = new LlmAgent({
name: "gke_agent",
description: "An agent running on GKE",
model: "gemini-2.5-flash",
instruction: "Be helpful and provide clear responses"
});
// Set up session service and runner
const sessionService = new InMemorySessionService();
const runner = new Runner({
appName: "gke-app",
agent,
sessionService
});
// Health check endpoint
app.get('/health', (req, res) => {
res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});
// Chat endpoint
app.post('/api/chat', async (req, res) => {
try {
const { message, userId = 'default-user' } = req.body;
if (!message) {
return res.status(400).json({ error: 'Message is required' });
}
// Create or get session
const sessions = await sessionService.listSessions('gke-app', userId);
let session;
if (sessions.sessions.length > 0) {
session = await sessionService.getSession('gke-app', userId, sessions.sessions[0].id);
} else {
session = await sessionService.createSession('gke-app', userId);
}
// Run agent
const events = [];
for await (const event of runner.runAsync({
userId,
sessionId: session.id,
newMessage: { parts: [{ text: message }] }
})) {
if (event.isFinalResponse()) {
events.push(event);
break;
}
}
res.json({
response: events[0]?.content?.parts?.[0]?.text || 'No response',
sessionId: session.id,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({
error: error.message,
timestamp: new Date().toISOString()
});
}
});
const PORT = parseInt(process.env.PORT || '8080', 10);
app.listen(PORT, () => {
console.log(`GKE Agent server running on port ${PORT}`);
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('Received SIGTERM, shutting down gracefully');
process.exit(0);
});
Package Configuration
{
"name": "@iqai/adk-gke-agent",
"version": "1.0.0",
"description": "ADK TypeScript Agent for GKE deployment",
"main": "dist/server.js",
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"dev": "ts-node src/server.ts"
},
"dependencies": {
"@iqai/adk": "^0.1.1",
"express": "^4.18.2"
},
"devDependencies": {
"@types/express": "^4.17.17",
"@types/node": "^22.0.0",
"ts-node": "^10.9.1",
"typescript": "^5.3.2"
},
"engines": {
"node": ">=22.0.0"
}
}
TypeScript Configuration
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"strict": true,
"outDir": "dist",
"rootDir": "src",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Dockerfile
FROM node:22-slim
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy source and build
COPY . .
RUN npm run build
# Expose port
EXPOSE 8080
# Start server
CMD ["npm", "start"]
Build and Deploy
Build Container Image
# Configure Docker for Artifact Registry
gcloud auth configure-docker $GOOGLE_CLOUD_LOCATION-docker.pkg.dev
# Build and push image
docker build -t $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/agent:latest .
docker push $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/agent:latest
Create Kubernetes Manifests
apiVersion: apps/v1
kind: Deployment
metadata:
name: adk-agent
labels:
app: adk-agent
spec:
replicas: 2
selector:
matchLabels:
app: adk-agent
template:
metadata:
labels:
app: adk-agent
spec:
containers:
- name: agent
image: us-central1-docker.pkg.dev/YOUR_PROJECT/adk-repo/agent:latest
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: adk-agent-service
labels:
app: adk-agent
spec:
selector:
app: adk-agent
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: LoadBalancer
Deploy to Kubernetes
# Update the image name in deployment.yaml with your project ID
sed -i "s/YOUR_PROJECT/$GOOGLE_CLOUD_PROJECT/g" k8s/deployment.yaml
# Apply the deployment
kubectl apply -f k8s/deployment.yaml
Get External IP
kubectl get service adk-agent-service
# Wait for external IP to be assigned
kubectl get service adk-agent-service --watch
Testing Your Deployment
Once the external IP is available, test your deployment:
# Replace EXTERNAL_IP with the actual IP from the previous command
curl -X POST http://EXTERNAL_IP/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello from GKE!", "userId": "test_user"}'
Monitoring and Scaling
View Logs
# Get pod logs
kubectl logs -l app=adk-agent --tail=100
# Follow logs
kubectl logs -l app=adk-agent -f
Scale Deployment
# Scale to 3 replicas
kubectl scale deployment adk-agent --replicas=3
# Check scaling status
kubectl get deployment adk-agent
Update Deployment
# Build new image with a tag
docker build -t $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/agent:v2 .
docker push $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/agent:v2
# Update deployment
kubectl set image deployment/adk-agent agent=$GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/agent:v2
What's Coming
The ADK CLI will provide:
- One-command deployment:
npx @iqai/adk deploy gke
- Automatic manifest generation: Generated Kubernetes configs
- Environment management: Easy config and secret management
- Monitoring setup: Built-in observability stack
- Auto-scaling configuration: Horizontal Pod Autoscaler setup
For production deployments, consider using ingress controllers, TLS certificates, and proper security configurations.