Skip to content

Commit b0dac87

Browse files
committed
feat: Migrate cloud deployment example from Minikube to Kind
- Replace Minikube with Kind for simpler, more reliable Kubernetes testing - Implement Kind local registry pattern (localhost:5001) - Remove complex Minikube registry addon and port-forwarding logic - Simplify deployment script - no OS-specific workarounds needed - Update cleanup to remove Kind cluster and registry container - Benefits: Faster startup, better CI support, no rootless Podman issues
1 parent c1b63e1 commit b0dac87

File tree

4 files changed

+124
-113
lines changed

4 files changed

+124
-113
lines changed

examples/cloud-deployment/k8s/04-agent-deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
spec:
1818
containers:
1919
- name: a2a-agent
20-
image: localhost:5000/a2a-cloud-deployment:latest
20+
image: localhost:5001/a2a-cloud-deployment:latest
2121
imagePullPolicy: IfNotPresent
2222
ports:
2323
- containerPort: 8080
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Kind cluster configuration for A2A Cloud Deployment Example
2+
# This config enables:
3+
# - Local registry integration
4+
# - LoadBalancer service support via MetalLB
5+
# - Sufficient resources for PostgreSQL, Kafka, and 2 agent pods
6+
7+
kind: Cluster
8+
apiVersion: kind.x-k8s.io/v1alpha4
9+
10+
# Enable local registry support
11+
containerdConfigPatches:
12+
- |-
13+
[plugins."io.containerd.grpc.v1.cri".registry]
14+
config_path = "/etc/containerd/certs.d"
15+
16+
nodes:
17+
# Single control-plane node is sufficient for this demo
18+
- role: control-plane
19+
# Expose port 80 for potential ingress testing
20+
extraPortMappings:
21+
- containerPort: 80
22+
hostPort: 80
23+
protocol: TCP
24+
- containerPort: 443
25+
hostPort: 443
26+
protocol: TCP

examples/cloud-deployment/scripts/cleanup.sh

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ RED='\033[0;31m'
1111
YELLOW='\033[1;33m'
1212
NC='\033[0m' # No Color
1313

14-
echo -e "${YELLOW}This will delete all resources in the a2a-demo namespace${NC}"
14+
echo -e "${YELLOW}This will delete all resources in the a2a-demo namespace and the Kind cluster${NC}"
1515
read -p "Are you sure you want to continue? (y/N) " -n 1 -r
1616
echo ""
1717

@@ -45,25 +45,23 @@ echo "Deleting namespace..."
4545
kubectl delete -f ../k8s/00-namespace.yaml --ignore-not-found=true
4646

4747
echo ""
48-
echo "Stopping registry port forwarding..."
49-
# Kill any port-forward processes
50-
pkill -f "kubectl.*port-forward.*registry" > /dev/null 2>&1 || true
48+
echo "Deleting Kind cluster..."
49+
kind delete cluster
5150

52-
# Determine container tool for stopping socat container on macOS
51+
echo ""
52+
echo "Stopping and removing registry container..."
53+
# Determine container tool
5354
CONTAINER_TOOL="docker"
54-
if command -v podman &> /dev/null; then
55+
if command -v podman &> /dev/null && ! command -v docker &> /dev/null; then
5556
CONTAINER_TOOL="podman"
5657
fi
5758

58-
# Stop socat container if running (macOS)
59-
$CONTAINER_TOOL stop socat-registry > /dev/null 2>&1 || true
60-
$CONTAINER_TOOL rm socat-registry > /dev/null 2>&1 || true
59+
$CONTAINER_TOOL stop kind-registry > /dev/null 2>&1 || true
60+
$CONTAINER_TOOL rm kind-registry > /dev/null 2>&1 || true
6161

6262
echo ""
6363
echo -e "${GREEN}Cleanup completed${NC}"
6464
echo ""
65-
echo -e "${YELLOW}Note: Minikube registry addon and Strimzi operator were not removed${NC}"
66-
echo "To disable the registry addon, run:"
67-
echo " minikube addons disable registry"
65+
echo -e "${YELLOW}Note: Strimzi operator was not removed${NC}"
6866
echo "To remove Strimzi operator, run:"
6967
echo " kubectl delete namespace kafka"

examples/cloud-deployment/scripts/deploy.sh

Lines changed: 87 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -31,96 +31,100 @@ done
3131
echo "Container tool: $CONTAINER_TOOL"
3232
echo ""
3333

34-
# Check if Minikube is running
35-
if ! minikube status > /dev/null 2>&1; then
36-
echo -e "${RED}Error: Minikube is not running${NC}"
37-
echo "Please start Minikube first:"
38-
echo ""
39-
echo "With Docker:"
40-
echo " minikube start --cpus=4 --memory=8192"
41-
echo ""
42-
echo "With Podman:"
43-
echo " minikube start --cpus=4 --memory=8192 --driver=podman"
44-
echo ""
45-
echo "With Podman (rootless):"
46-
echo " minikube start --cpus=4 --memory=8192 --driver=podman --container-runtime=containerd"
34+
# Check if Kind is installed
35+
if ! command -v kind &> /dev/null; then
36+
echo -e "${RED}Error: Kind is not installed${NC}"
37+
echo "Please install Kind first: https://kind.sigs.k8s.io/docs/user/quick-start/#installation"
4738
exit 1
4839
fi
4940

50-
echo -e "${GREEN}✓ Minikube is running${NC}"
41+
# Check if kubectl is installed
42+
if ! command -v kubectl &> /dev/null; then
43+
echo -e "${RED}Error: kubectl is not installed${NC}"
44+
echo "Please install kubectl first: https://kubernetes.io/docs/tasks/tools/"
45+
exit 1
46+
fi
5147

52-
# Enable Minikube registry addon if not already enabled
53-
echo ""
54-
echo "Checking Minikube registry addon..."
55-
if ! minikube addons list | grep -q "registry.*enabled"; then
56-
echo "Enabling Minikube registry addon..."
57-
minikube addons enable registry
58-
# Wait a bit for registry to start
59-
sleep 5
60-
echo -e "${GREEN}✓ Registry addon enabled${NC}"
48+
# Setup local registry
49+
echo "Setting up local registry..."
50+
REG_NAME='kind-registry'
51+
REG_PORT='5001'
52+
53+
# Create registry container if it doesn't exist
54+
if [ "$($CONTAINER_TOOL inspect -f '{{.State.Running}}' "${REG_NAME}" 2>/dev/null || true)" != 'true' ]; then
55+
echo "Creating registry container..."
56+
$CONTAINER_TOOL run \
57+
-d --restart=always -p "127.0.0.1:${REG_PORT}:5000" --network bridge --name "${REG_NAME}" \
58+
registry:2
59+
echo -e "${GREEN}✓ Registry container created${NC}"
6160
else
62-
echo -e "${GREEN}✓ Registry addon already enabled${NC}"
61+
echo -e "${GREEN}✓ Registry container already running${NC}"
6362
fi
6463

65-
# Detect registry port (5000 for standard, 34741 for rootless podman)
66-
echo ""
67-
echo "Detecting registry configuration..."
68-
REGISTRY_PORT=5000
69-
70-
# Check if using rootless podman (registry uses different port)
71-
if [ "$CONTAINER_TOOL" = "podman" ] && [ "$(minikube config get rootless 2>/dev/null)" = "true" ]; then
72-
REGISTRY_PORT=34741
73-
echo "Rootless Podman detected, using registry port $REGISTRY_PORT"
64+
# Create Kind cluster if it doesn't exist
65+
if ! kind get clusters 2>/dev/null | grep -q '^kind$'; then
66+
echo ""
67+
echo "Creating Kind cluster..."
68+
cat <<EOF | kind create cluster --config=-
69+
kind: Cluster
70+
apiVersion: kind.x-k8s.io/v1alpha4
71+
containerdConfigPatches:
72+
- |-
73+
[plugins."io.containerd.grpc.v1.cri".registry]
74+
config_path = "/etc/containerd/certs.d"
75+
EOF
76+
echo -e "${GREEN}✓ Kind cluster created${NC}"
77+
else
78+
echo -e "${GREEN}✓ Kind cluster already exists${NC}"
7479
fi
7580

76-
# Set up port forwarding to registry
81+
# Configure registry on cluster nodes
7782
echo ""
78-
echo "Setting up registry port forwarding..."
79-
80-
# Detect OS
81-
if echo "$OSTYPE" | grep -q "^darwin"; then
82-
# macOS - use socat in container for port forwarding
83-
echo "macOS detected, using socat for port forwarding..."
84-
85-
# Stop any existing port forwarder
86-
$CONTAINER_TOOL stop socat-registry 2>/dev/null || true
87-
$CONTAINER_TOOL rm socat-registry 2>/dev/null || true
88-
89-
# Pull alpine if needed
90-
$CONTAINER_TOOL pull alpine 2>/dev/null || true
91-
92-
# Start socat container for port forwarding
93-
$CONTAINER_TOOL run -d --name socat-registry --rm --network=host alpine \
94-
ash -c "apk add socat && socat TCP-LISTEN:$REGISTRY_PORT,reuseaddr,fork TCP:$(minikube ip):$REGISTRY_PORT" \
95-
> /dev/null 2>&1 &
83+
echo "Configuring registry on cluster nodes..."
84+
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${REG_PORT}"
85+
for node in $(kind get nodes); do
86+
$CONTAINER_TOOL exec "${node}" mkdir -p "${REGISTRY_DIR}"
87+
cat <<EOF | $CONTAINER_TOOL exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
88+
[host."http://${REG_NAME}:5000"]
89+
EOF
90+
done
91+
echo -e "${GREEN}✓ Registry configured on nodes${NC}"
9692

97-
echo -e "${GREEN}✓ Port forward started (socat container)${NC}"
93+
# Connect registry to cluster network
94+
echo ""
95+
echo "Connecting registry to cluster network..."
96+
if [ "$($CONTAINER_TOOL inspect -f='{{json .NetworkSettings.Networks.kind}}' "${REG_NAME}")" = 'null' ]; then
97+
$CONTAINER_TOOL network connect "kind" "${REG_NAME}"
98+
echo -e "${GREEN}✓ Registry connected to cluster network${NC}"
9899
else
99-
# Linux - use kubectl port-forward
100-
echo "Linux detected, using kubectl port-forward..."
101-
102-
# Kill any existing port-forward processes
103-
pkill -f "kubectl.*port-forward.*registry" || true
104-
105-
# Start port forward in background
106-
kubectl port-forward --namespace kube-system service/registry $REGISTRY_PORT:80 > /dev/null 2>&1 &
107-
108-
echo -e "${GREEN}✓ Port forward started (kubectl)${NC}"
100+
echo -e "${GREEN}✓ Registry already connected${NC}"
109101
fi
110102

111-
# Wait for registry to be accessible
112-
echo "Waiting for registry to be accessible at localhost:$REGISTRY_PORT..."
113-
for i in {1..30}; do
114-
if curl -s http://localhost:$REGISTRY_PORT/v2/ > /dev/null 2>&1; then
115-
echo -e "${GREEN}✓ Registry accessible at localhost:$REGISTRY_PORT${NC}"
116-
break
117-
fi
118-
if [ $i -eq 30 ]; then
119-
echo -e "${RED}ERROR: Registry not accessible after 30 attempts${NC}"
120-
exit 1
121-
fi
122-
sleep 1
123-
done
103+
# Create ConfigMap to document local registry
104+
echo ""
105+
echo "Creating registry ConfigMap..."
106+
cat <<EOF | kubectl apply -f -
107+
apiVersion: v1
108+
kind: ConfigMap
109+
metadata:
110+
name: local-registry-hosting
111+
namespace: kube-public
112+
data:
113+
localRegistryHosting.v1: |
114+
host: "localhost:${REG_PORT}"
115+
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
116+
EOF
117+
echo -e "${GREEN}✓ Registry ConfigMap created${NC}"
118+
119+
# Verify registry is accessible
120+
echo ""
121+
echo "Verifying registry is accessible..."
122+
if curl -s http://localhost:${REG_PORT}/v2/ > /dev/null 2>&1; then
123+
echo -e "${GREEN}✓ Registry accessible at localhost:${REG_PORT}${NC}"
124+
else
125+
echo -e "${RED}ERROR: Registry not accessible${NC}"
126+
exit 1
127+
fi
124128

125129
# Build the project
126130
echo ""
@@ -129,31 +133,16 @@ cd ../server
129133
mvn clean package -DskipTests
130134
echo -e "${GREEN}✓ Project built successfully${NC}"
131135

132-
# Build and push container image to Minikube registry
133-
REGISTRY="localhost:$REGISTRY_PORT"
136+
# Build and push container image to local registry
137+
REGISTRY="localhost:${REG_PORT}"
134138
echo ""
135139
echo "Building container image..."
136140
$CONTAINER_TOOL build -t ${REGISTRY}/a2a-cloud-deployment:latest .
137141
echo -e "${GREEN}✓ Container image built${NC}"
138142

139-
echo "Pushing image to Minikube registry..."
140-
# Retry push a few times as port-forward can be flaky
141-
MAX_RETRIES=3
142-
for attempt in $(seq 1 $MAX_RETRIES); do
143-
echo "Push attempt $attempt/$MAX_RETRIES..."
144-
if $CONTAINER_TOOL push ${REGISTRY}/a2a-cloud-deployment:latest 2>&1 | tee /tmp/push.log; then
145-
echo -e "${GREEN}✓ Image pushed to registry${NC}"
146-
break
147-
else
148-
if [ $attempt -eq $MAX_RETRIES ]; then
149-
echo -e "${RED}ERROR: Failed to push image after $MAX_RETRIES attempts${NC}"
150-
cat /tmp/push.log
151-
exit 1
152-
fi
153-
echo -e "${YELLOW}Push failed, retrying in 2 seconds...${NC}"
154-
sleep 2
155-
fi
156-
done
143+
echo "Pushing image to local registry..."
144+
$CONTAINER_TOOL push ${REGISTRY}/a2a-cloud-deployment:latest
145+
echo -e "${GREEN}✓ Image pushed to registry${NC}"
157146

158147
# Go back to scripts directory
159148
cd ../scripts
@@ -250,9 +239,7 @@ echo -e "${GREEN}✓ ConfigMap deployed${NC}"
250239
if [ "${SKIP_AGENT_DEPLOY}" != "true" ]; then
251240
echo ""
252241
echo "Deploying A2A Agent..."
253-
254-
# Update the deployment YAML with the correct registry port
255-
sed "s|localhost:5000|localhost:$REGISTRY_PORT|g" ../k8s/04-agent-deployment.yaml | kubectl apply -f -
242+
kubectl apply -f ../k8s/04-agent-deployment.yaml
256243

257244
echo "Waiting for Agent pods to be ready..."
258245
kubectl wait --for=condition=Ready pod -l app=a2a-agent -n a2a-demo --timeout=120s
@@ -261,7 +248,7 @@ else
261248
echo ""
262249
echo -e "${YELLOW}⚠ Skipping agent deployment (SKIP_AGENT_DEPLOY=true)${NC}"
263250
echo " ConfigMap has been deployed, you can manually deploy the agent with:"
264-
echo " sed 's|localhost:5000|localhost:$REGISTRY_PORT|g' ../k8s/04-agent-deployment.yaml | kubectl apply -f -"
251+
echo " kubectl apply -f ../k8s/04-agent-deployment.yaml"
265252
fi
266253

267254
echo ""

0 commit comments

Comments
 (0)