ConfigMaps, Secrets and Ingress

ConfigMap and Secret

ConfigMap and Secret

Spring Boot relaxed binding turns SPRING_KAFKA_BOOTSTRAP_SERVERS into spring.kafka.bootstrap-servers, so these work through envFrom with no code changes:

k8s/order-service/config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
  namespace: shopease
data:
  SPRING_DATASOURCE_URL: jdbc:postgresql://orders-db.shopease:5432/order_db
  SPRING_KAFKA_BOOTSTRAP_SERVERS: kafka.shopease:9092
  MANAGEMENT_ZIPKIN_TRACING_ENDPOINT: http://zipkin.observability:9411/api/v2/spans
  SHOPEASE_PAYMENT_TIMEOUT: 3s
---
apiVersion: v1
kind: Secret
metadata:
  name: order-service-secrets
  namespace: shopease
type: Opaque
stringData:                        # written as plain text, stored base64-encoded
  SPRING_DATASOURCE_USERNAME: order_app
  SPRING_DATASOURCE_PASSWORD: change-me

Example output

$ kubectl create secret generic order-service-secrets -n shopease \
    --from-literal=SPRING_DATASOURCE_USERNAME=order_app \
    --from-literal=SPRING_DATASOURCE_PASSWORD="$DB_PASSWORD"
secret/order-service-secrets created

Note: Do not commit real Secret YAML to Git. Create them from CI with values from a secret store, or use External Secrets Operator / Sealed Secrets. Environment variables are read at startup; after changing a ConfigMap run kubectl rollout restart deploy/order-service.

Ingress: The Front Door

Ingress

Only the gateway is exposed. The Ingress controller (here ingress-nginx) terminates HTTPS and forwards to the api-gateway Service:

k8s/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shopease
  namespace: shopease
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod      # free TLS certificate
spec:
  ingressClassName: nginx
  tls:
    - hosts: ["api.shopease.in"]
      secretName: shopease-api-tls
  rules:
    - host: api.shopease.in
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-gateway
                port:
                  number: 80

Example output

$ kubectl get ingress -n shopease
NAME       CLASS   HOSTS             ADDRESS        PORTS     AGE
shopease   nginx   api.shopease.in   34.93.112.45   80, 443   6d

$ curl -s https://api.shopease.in/api/products/1
{"id":1,"name":"boAt Rockerz 450","price":1499.00,"stock":120,"category":"Electronics"}
internet --HTTPS--> Ingress (api.shopease.in, TLS) --> Service api-gateway --> gateway Pods
                                                                                 |
                       ClusterIP Services: product-service, order-service, payment-service

Exercise

Exercise: Write the Service and a minimal Deployment for payment-service (port 8084, 2 replicas, image ghcr.io/shopease/payment-service:2.0.1, readiness probe on /actuator/health/readiness).

Show answer
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-service
  namespace: shopease
spec:
  replicas: 2
  selector:
    matchLabels:
      app: payment-service
  template:
    metadata:
      labels:
        app: payment-service
    spec:
      containers:
        - name: payment-service
          image: ghcr.io/shopease/payment-service:2.0.1
          ports:
            - name: http
              containerPort: 8084
          readinessProbe:
            httpGet: { path: /actuator/health/readiness, port: http }
---
apiVersion: v1
kind: Service
metadata:
  name: payment-service
  namespace: shopease
spec:
  selector:
    app: payment-service
  ports:
    - port: 80
      targetPort: http