Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Kubernetes Deployment

Deploy Radar Collector in Kubernetes using Deployments, ConfigMaps, and Secrets for scalable monitoring.

Prerequisites

  • Kubernetes cluster (1.19+)
  • kubectl configured to access your cluster
  • Container image of Radar Collector

Quick Start

1. Create Namespace

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: radar-collector
  labels:
    name: radar-collector
kubectl apply -f namespace.yaml

2. Create Secrets

Store sensitive configuration in Kubernetes Secrets:

# secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: radar-collector-secrets
  namespace: radar-collector
type: Opaque
stringData:
  api-key: "your-radar-api-key"
  redis-password: "your-redis-password"
kubectl apply -f secrets.yaml

3. Create ConfigMap

Store the collector configuration:

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: radar-collector-config
  namespace: radar-collector
data:
  config.yml: |
    collector:
      id: "radar-collector-k8s-${HOSTNAME}"
      hostname: "${HOSTNAME}"
      collection_interval: "30s"

    server:
      grpc_url: "https://api.radar.com:443"
      api_key: "${RADAR_API_KEY}"

    deployments:
      - id: "redis-production"
        name: "Production Redis"
        deployment_type: "standalone"
        redis_url: "redis://radar-collector:${REDIS_PASSWORD}@redis.production.svc.cluster.local:6379"
        collection:
          interval: "30s"
          retry_on_failure: true
          max_retries: 3
kubectl apply -f configmap.yaml

4. Create Deployment

Deploy the Radar Collector:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: radar-collector
  namespace: radar-collector
  labels:
    app: radar-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: radar-collector
  template:
    metadata:
      labels:
        app: radar-collector
    spec:
      serviceAccountName: radar-collector
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      containers:
        - name: radar-collector
          image: radar-collector:latest # Replace with your image
          imagePullPolicy: Always

          # Command and arguments
          command: ["/app/radar-collector"]
          args: ["--config", "/etc/radar-collector/config.yml"]

          # Environment variables
          env:
            - name: HOSTNAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: RADAR_API_KEY
              valueFrom:
                secretKeyRef:
                  name: radar-collector-secrets
                  key: api-key
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: radar-collector-secrets
                  key: redis-password
            - name: RUST_LOG
              value: "info"

          # Volume mounts
          volumeMounts:
            - name: config
              mountPath: /etc/radar-collector
              readOnly: true

          # Resource limits
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"

          # Health checks
          livenessProbe:
            exec:
              command:
                - /app/radar-collector
                - validate
                - --config
                - /etc/radar-collector/config.yml
            initialDelaySeconds: 30
            periodSeconds: 60
            timeoutSeconds: 10

          readinessProbe:
            exec:
              command:
                - /app/radar-collector
                - validate
                - --config
                - /etc/radar-collector/config.yml
                - --test-connections
            initialDelaySeconds: 10
            periodSeconds: 30
            timeoutSeconds: 15

      volumes:
        - name: config
          configMap:
            name: radar-collector-config

      # Restart policy
      restartPolicy: Always

      # Node selection (optional)
      nodeSelector:
        kubernetes.io/os: linux

5. Create ServiceAccount and RBAC

Create service account with minimal permissions:

# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: radar-collector
  namespace: radar-collector

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: radar-collector
  namespace: radar-collector
rules:
  - apiGroups: [""]
    resources: ["configmaps", "secrets"]
    verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: radar-collector
  namespace: radar-collector
subjects:
  - kind: ServiceAccount
    name: radar-collector
    namespace: radar-collector
roleRef:
  kind: Role
  name: radar-collector
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac.yaml
kubectl apply -f deployment.yaml

Advanced Configuration

Multi-Environment Setup

Deploy different collectors for different environments:

# production-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: radar-collector-production
  namespace: radar-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: radar-collector
      environment: production
  template:
    metadata:
      labels:
        app: radar-collector
        environment: production
    spec:
      containers:
        - name: radar-collector
          image: radar-collector:latest
          env:
            - name: ENVIRONMENT
              value: "production"
          volumeMounts:
            - name: config
              mountPath: /etc/radar-collector
      volumes:
        - name: config
          configMap:
            name: radar-collector-config-production

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: radar-collector-staging
  namespace: radar-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: radar-collector
      environment: staging
  template:
    metadata:
      labels:
        app: radar-collector
        environment: staging
    spec:
      containers:
        - name: radar-collector
          image: radar-collector:latest
          env:
            - name: ENVIRONMENT
              value: "staging"
          volumeMounts:
            - name: config
              mountPath: /etc/radar-collector
      volumes:
        - name: config
          configMap:
            name: radar-collector-config-staging

Horizontal Pod Autoscaler

Auto-scale based on CPU usage:

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: radar-collector-hpa
  namespace: radar-collector
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: radar-collector
  minReplicas: 1
  maxReplicas: 3
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

Network Policies

Restrict network access:

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: radar-collector-netpol
  namespace: radar-collector
spec:
  podSelector:
    matchLabels:
      app: radar-collector
  policyTypes:
    - Egress
  egress:
    # Allow DNS resolution
    - to: []
      ports:
        - protocol: UDP
          port: 53
    # Allow HTTPS to Radar server
    - to: []
      ports:
        - protocol: TCP
          port: 443
    # Allow Redis connections
    - to: []
      ports:
        - protocol: TCP
          port: 6379
        - protocol: TCP
          port: 6380

Container Image

Dockerfile

Create a secure container image:

# Dockerfile
FROM rust:1.88-slim as builder

WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim

# Install CA certificates and create user
RUN apt-get update && \
    apt-get install -y ca-certificates && \
    rm -rf /var/lib/apt/lists/* && \
    groupadd -r radar-collector && \
    useradd -r -g radar-collector radar-collector

# Copy binary
COPY --from=builder /app/target/release/radar-collector /app/radar-collector

# Set ownership and permissions
RUN chown radar-collector:radar-collector /app/radar-collector

# Switch to non-root user
USER radar-collector

# Expose metrics port (if implemented)
EXPOSE 8080

ENTRYPOINT ["/app/radar-collector"]

Build and Push

# Build image
docker build -t radar-collector:latest .

# Tag for registry
docker tag radar-collector:latest your-registry.com/radar-collector:latest

# Push to registry
docker push your-registry.com/radar-collector:latest

Management and Operations

View Logs

# View logs from all radar-collector pods
kubectl logs -n radar-collector -l app=radar-collector -f

# View logs from specific pod
kubectl logs -n radar-collector <pod-name> -f

# View previous container logs (after restart)
kubectl logs -n radar-collector <pod-name> --previous

Update Configuration

# Update ConfigMap
kubectl apply -f configmap.yaml

# Restart deployment to pick up changes
kubectl rollout restart deployment/radar-collector -n radar-collector

# Check rollout status
kubectl rollout status deployment/radar-collector -n radar-collector

Scale Deployment

# Scale to 3 replicas
kubectl scale deployment/radar-collector --replicas=3 -n radar-collector

# Auto-scale based on CPU
kubectl autoscale deployment/radar-collector --cpu-percent=70 --min=1 --max=5 -n radar-collector

Monitoring and Alerting

Pod Monitoring

# servicemonitor.yaml (for Prometheus Operator)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: radar-collector
  namespace: radar-collector
spec:
  selector:
    matchLabels:
      app: radar-collector
  endpoints:
    - port: metrics
      interval: 30s
      path: /metrics

Alerting Rules

# alerts.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: radar-collector-alerts
  namespace: radar-collector
spec:
  groups:
    - name: radar-collector
      rules:
        - alert: RadarCollectorDown
          expr: up{job="radar-collector"} == 0
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Radar Collector is down"
            description: "Radar Collector has been down for more than 5 minutes"

Troubleshooting

Common Issues

Pod won't start:

# Check pod status
kubectl get pods -n radar-collector

# Describe pod for events
kubectl describe pod <pod-name> -n radar-collector

# Check logs
kubectl logs <pod-name> -n radar-collector

Configuration issues:

# Validate ConfigMap
kubectl get configmap radar-collector-config -n radar-collector -o yaml

# Test configuration in pod
kubectl exec -it <pod-name> -n radar-collector -- /app/radar-collector validate --config /etc/radar-collector/config.yml

Network connectivity:

# Test from within pod
kubectl exec -it <pod-name> -n radar-collector -- /bin/sh

# Inside pod:
curl -v https://api.radar.com
redis-cli -u redis://user:pass@redis.example.com:6379 ping

Health Checks

Monitor deployment health:

# Check deployment status
kubectl get deployment radar-collector -n radar-collector

# Check pod health
kubectl get pods -n radar-collector -l app=radar-collector

# Check recent events
kubectl get events -n radar-collector --sort-by='.lastTimestamp'