The AaC Runtime manages the execution of agent containers. It provides a comprehensive container orchestration system with support for different execution strategies and resource management.
The runtime system handles:
- Container Orchestration: Docker-based container management
- Runtime Configuration: Dynamic configuration and environment setup
- Monitoring and Logging: Real-time container monitoring and log streaming
- Resource Management: CPU, memory, and network resource allocation
- Scaling Strategies: Horizontal and vertical scaling capabilities
The runtime integrates with:
- Docker Engine: For container lifecycle management
- Parser: For configuration validation
- Builder: For image availability verification
type Runtime struct {
dockerClient *client.Client
}type RunOptions struct {
Image string // Container image name
Ports []string // Port mappings (host:container)
Environment []string // Environment variables
Detach bool // Run in background
Name string // Container name
Volumes []string // Volume mounts
Interactive bool // Interactive mode
}type ContainerInfo struct {
ID string // Container ID
Name string // Container name
Ports []PortMapping // Port mappings
}type PortMapping struct {
Host string // Host port
Container string // Container port
Protocol string // Protocol (tcp/udp)
}- Container Engine: Docker Engine
- Orchestration: Native Docker API
- Networking: Docker bridge network
- Storage: Docker volumes and bind mounts
- Orchestration: Kubernetes API
- Scaling: Horizontal Pod Autoscaler
- Networking: Service mesh integration
- Storage: Persistent volumes
- Execution: Direct process execution
- Isolation: Process-level isolation
- Networking: Local port binding
- Storage: File system access
package main
import (
"fmt"
"github.com/pxkundu/agent-as-code/internal/runtime"
)
func main() {
// Create runtime instance
r := runtime.New()
// Run options
options := &runtime.RunOptions{
Image: "my-agent:latest",
Ports: []string{"8080:8080", "9090:9090"},
Environment: []string{
"OPENAI_API_KEY=your-key",
"LOG_LEVEL=INFO",
},
Name: "my-agent-instance",
Volumes: []string{"./data:/app/data"},
Interactive: false,
}
// Start container
container, err := r.Run(options)
if err != nil {
fmt.Printf("Failed to start container: %v\n", err)
return
}
fmt.Printf("Container started: %s\n", container.ID)
fmt.Printf("Container name: %s\n", container.Name)
}- Validation: Verify image exists locally
- Creation: Create container with configuration
- Startup: Start container and wait for readiness
- Monitoring: Track container status and health
- Cleanup: Handle container termination
# Basic port mapping
8080:8080
# Host port different from container
80:8080
# Protocol specification
8080:8080/tcp
8080:8080/udp
# Multiple ports
8080:8080,9090:9090# agent.yaml
spec:
ports:
- container: 8080
host: 8080
protocol: tcp
- container: 9090
host: 9090
protocol: tcp- Port numbers: 1-65535
- Protocol support: TCP, UDP
- Host port availability check
- Container port exposure
# agent.yaml
spec:
environment:
- name: OPENAI_API_KEY
value: "your-api-key"
- name: LOG_LEVEL
value: "INFO"
- name: MODEL_NAME
from: "config"# Set environment variables
export OPENAI_API_KEY="your-key"
export LOG_LEVEL="DEBUG"
# Run with environment
agent run -e OPENAI_API_KEY=${OPENAI_API_KEY} my-agent:latest# agent.yaml
spec:
environment:
- name: DATABASE_PASSWORD
from: "secret"
secretName: "db-secret"
secretKey: "password"# agent.yaml
spec:
volumes:
- source: ./data
target: /app/data
type: bind
- source: model-cache
target: /app/models
type: volume- Bind Mounts: Host directory to container
- Named Volumes: Docker-managed volumes
- Temporary Volumes: Ephemeral storage
- Config Maps: Configuration data
# Bind mount
agent run -v $(pwd)/data:/app/data my-agent:latest
# Named volume
agent run -v model-cache:/app/models my-agent:latest
# Multiple volumes
agent run -v ./data:/app/data -v ./config:/app/config my-agent:latest# agent.yaml
spec:
healthCheck:
command: ["curl", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
startPeriod: 5s- HTTP: HTTP endpoint health checks
- Command: Custom command execution
- TCP: Port availability checks
- File: File existence checks
# Python health check example
from flask import Flask
app = Flask(__name__)
@app.route('/health')
def health_check():
return {"status": "healthy", "timestamp": time.time()}
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)# agent.yaml
spec:
resources:
limits:
cpu: "2"
memory: "2Gi"
requests:
cpu: "500m"
memory: "512Mi"// Monitor container resources
func monitorResources(containerID string) {
// Get container stats
stats, err := dockerClient.ContainerStats(context.Background(), containerID, false)
if err != nil {
return
}
// Parse resource usage
var resourceUsage struct {
CPU float64
Memory int64
}
// Process stats...
}# Basic start
agent run my-agent:latest
# With port mapping
agent run -p 8080:8080 my-agent:latest
# With environment
agent run -e API_KEY=value my-agent:latest
# With volumes
agent run -v ./data:/app/data my-agent:latest
# Interactive mode
agent run -i -t my-agent:latest// Stop container
err := r.Stop(containerID)
if err != nil {
fmt.Printf("Failed to stop container: %v\n", err)
return
}// Stream container logs
err := r.StreamLogs(containerID)
if err != nil {
fmt.Printf("Failed to stream logs: %v\n", err)
return
}// List running containers
containers, err := r.List()
if err != nil {
fmt.Printf("Failed to list containers: %v\n", err)
return
}
for _, container := range containers {
fmt.Printf("ID: %s, Name: %s\n", container.ID, container.Name)
}# agent.yaml
spec:
network:
mode: bridge
ports:
- 8080:8080
dns:
- 8.8.8.8
- 8.8.4.4- Bridge: Default Docker networking
- Host: Host network namespace
- None: No networking
- Custom: User-defined networks
# agent.yaml
spec:
services:
- name: database
port: 5432
protocol: tcp
- name: cache
port: 6379
protocol: tcp- CPU Usage: Per-container CPU consumption
- Memory Usage: Memory allocation and usage
- Network I/O: Network traffic statistics
- Disk I/O: Storage access patterns
// Configure logging
logOptions := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Follow: true,
Timestamps: true,
Tail: "100",
}
// Get logs
reader, err := dockerClient.ContainerLogs(ctx, containerID, logOptions)// Health check loop
func healthMonitor(containerID string) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for range ticker.C {
// Check container health
if !isHealthy(containerID) {
// Handle unhealthy container
handleUnhealthyContainer(containerID)
}
}
}# agent.yaml
spec:
scaling:
replicas: 3
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70# agent.yaml
spec:
resources:
limits:
cpu: "4"
memory: "8Gi"
requests:
cpu: "1"
memory: "2Gi"# agent.yaml
spec:
autoscaling:
enabled: true
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
scaleDownDelay: 300s
scaleUpDelay: 60s# agent.yaml
spec:
security:
runAsUser: 1000
runAsGroup: 1000
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE# agent.yaml
spec:
network:
security:
allowExternalConnections: false
allowedHosts:
- "api.openai.com"
- "api.anthropic.com"# agent.yaml
spec:
secrets:
- name: api-key
from: "kubernetes-secret"
secretName: "agent-secrets"
secretKey: "openai-api-key"- Image Not Found: "image 'my-agent:latest' not found locally"
- Port Conflicts: "port 8080 is already in use"
- Resource Limits: "insufficient memory"
- Network Issues: "failed to create network"
// Retry logic for container operations
func runWithRetry(options *RunOptions, maxRetries int) (*ContainerInfo, error) {
var lastErr error
for i := 0; i < maxRetries; i++ {
container, err := r.Run(options)
if err == nil {
return container, nil
}
lastErr = err
time.Sleep(time.Duration(i+1) * time.Second)
}
return nil, fmt.Errorf("failed after %d retries: %v", maxRetries, lastErr)
}- Image Size: Use minimal base images
- Layer Caching: Optimize Docker layers
- Resource Allocation: Right-size resource limits
- Network Optimization: Use appropriate network modes
- Metrics Collection: Efficient metrics gathering
- Log Rotation: Implement log rotation
- Resource Tracking: Monitor resource usage
- Performance Profiling: Profile container performance
- Use minimal base images
- Implement proper health checks
- Handle graceful shutdowns
- Optimize layer caching
- Set appropriate resource limits
- Monitor resource usage
- Implement auto-scaling
- Use resource quotas
- Run containers as non-root
- Implement network policies
- Use secrets for sensitive data
- Regular security updates
- Implement comprehensive logging
- Monitor container health
- Track performance metrics
- Set up alerting
-
Container Won't Start
- Check image availability
- Verify port availability
- Check resource limits
- Review container logs
-
Performance Issues
- Monitor resource usage
- Check network performance
- Review storage I/O
- Analyze container metrics
-
Network Issues
- Verify port mappings
- Check firewall rules
- Test network connectivity
- Review DNS configuration
# Check container status
docker ps -a
# View container logs
docker logs <container-id>
# Inspect container
docker inspect <container-id>
# Check resource usage
docker stats <container-id>
# Execute in container
docker exec -it <container-id> /bin/bash- Parser - Configuration parsing
- Builder - Container building
- Registry - Image distribution
- CLI Overview - Command-line usage
- Agent Configuration - Configuration reference