Use namespace-scoped Kong Mesh policies

Uses: Kong Mesh
Incompatible with
konnect
Related Documentation
Related Resources
Minimum Version
Kong Mesh - 2.9
TL;DR

Create a deploy a consumer namespace with sidecar injection enabled, then create your policy within that consumer namespace.

Prerequisites

You will need Helm, a package manager for Kubernetes.

This guide requires a running Kubernetes cluster. If you already have a Kubernetes cluster running, you can skip this step. It can be a cluster running locally, like Docker, or in a public cloud like AWS EKS, GCP GKE, etc.

For example, if you are using minikube:

minikube start -p mesh-zone
  1. Install Kong Mesh:

    helm upgrade \
      --install \
      --create-namespace \
      --namespace kong-mesh-system \
      kong-mesh kong-mesh/kong-mesh
    kubectl wait -n kong-mesh-system --for=condition=ready pod --selector=app=kong-mesh-control-plane --timeout=90s
    
  2. Apply the demo configuration:

    echo "
    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        kuma.io/sidecar-injection: enabled
      name: kong-mesh-demo
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-app
      namespace: kong-mesh-demo
    spec:
      ports:
      - appProtocol: http
        port: 5050
        protocol: TCP
        targetPort: 5050
      selector:
        app: demo-app
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-app-v1
      namespace: kong-mesh-demo
    spec:
      ports:
      - appProtocol: http
        port: 5050
        protocol: TCP
        targetPort: 5050
      selector:
        app: demo-app
        version: v1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-app-v2
      namespace: kong-mesh-demo
    spec:
      ports:
      - appProtocol: http
        port: 5050
        protocol: TCP
        targetPort: 5050
      selector:
        app: demo-app
        version: v2
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: kv
      namespace: kong-mesh-demo
    spec:
      ports:
      - appProtocol: http
        port: 5050
        protocol: TCP
        targetPort: 5050
      selector:
        app: kv
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: demo-app
        version: v1
      name: demo-app
      namespace: kong-mesh-demo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: demo-app
          version: v1
      template:
        metadata:
          labels:
            app: demo-app
            version: v1
        spec:
          containers:
          - env:
            - name: OTEL_SERVICE_NAME
              value: demo-app
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: http://opentelemetry-collector.mesh-observability:4317
            - name: KV_URL
              value: http://kv.kong-mesh-demo.svc.cluster.local:5050
            - name: APP_VERSION
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['version']
            image: ghcr.io/kumahq/kuma-counter-demo:latest@sha256:daf8f5cffa10b576ff845be84e4e3bd5a8a6470c7e66293c5e03a148f08ac148
            name: app
            ports:
            - containerPort: 5050
              name: http
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: demo-app
        version: v2
      name: demo-app-v2
      namespace: kong-mesh-demo
    spec:
      replicas: 0
      selector:
        matchLabels:
          app: demo-app
          version: v2
      template:
        metadata:
          labels:
            app: demo-app
            version: v2
        spec:
          containers:
          - env:
            - name: OTEL_SERVICE_NAME
              value: demo-app
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: http://opentelemetry-collector.mesh-observability:4317
            - name: KV_URL
              value: http://kv.kong-mesh-demo.svc.cluster.local:5050
            - name: APP_VERSION
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['version']
            image: ghcr.io/kumahq/kuma-counter-demo:latest@sha256:daf8f5cffa10b576ff845be84e4e3bd5a8a6470c7e66293c5e03a148f08ac148
            name: demo-app
            ports:
            - containerPort: 5050
              name: http
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: kv
      namespace: kong-mesh-demo
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kv
      template:
        metadata:
          labels:
            app: kv
        spec:
          containers:
          - env:
            - name: OTEL_SERVICE_NAME
              value: kv
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: http://opentelemetry-collector.mesh-observability:4317
            - name: APP_VERSION
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['version']
            image: ghcr.io/kumahq/kuma-counter-demo:latest@sha256:daf8f5cffa10b576ff845be84e4e3bd5a8a6470c7e66293c5e03a148f08ac148
            name: app
            ports:
            - containerPort: 5050
              name: http
    ---
    apiVersion: kuma.io/v1alpha1
    kind: Mesh
    metadata:
      name: default
    spec:
      meshServices:
        mode: Exclusive
      mtls:
        backends:
        - name: ca-1
          type: builtin
        enabledBackend: ca-1
    ---
    apiVersion: kuma.io/v1alpha1
    kind: MeshTrafficPermission
    metadata:
      name: kv
      namespace: kong-mesh-demo
    spec:
      from:
      - default:
          action: Allow
        targetRef:
          kind: MeshSubset
          tags:
            app: demo-app
            k8s.kuma.io/namespace: kong-mesh-demo
      targetRef:
        kind: Dataplane
        labels:
          app: kv" | kubectl apply -f -
    

Add MeshTrafficPermission

Add a MeshTrafficPermission policy to allow access to the mesh we created in the prerequisites:

echo "apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
  namespace: kong-mesh-demo
  name: mtp
spec:
  targetRef:
    kind: Mesh
  from:
    - targetRef:
        kind: Mesh
      default:
        action: Allow" | kubectl apply -f -

Create consumer namespaces

In this example, we’ll create two different consumer namespaces, and apply different policies to them.

  1. Create the first consumer namespace:

    echo "apiVersion: v1
    kind: Namespace
    metadata:
      name: first-consumer
      labels:
        kuma.io/sidecar-injection: enabled" | kubectl apply -f -
    
  2. Deploy the first namespace:

    kubectl run consumer --image nicolaka/netshoot -n first-consumer --command -- /bin/bash -c "ping -i 60 localhost"
    
  3. Create the second consumer namespace:
    echo "apiVersion: v1
    kind: Namespace
    metadata:
      name: second-consumer
      labels:
        kuma.io/sidecar-injection: enabled" | kubectl apply -f -
    
  4. Deploy the second namespace:

     kubectl run consumer --image nicolaka/netshoot -n second-consumer --command -- /bin/bash -c "ping -i 60 localhost"
    
  5. Send a request to the first consumer to validate that it’s working:

    kubectl exec -n first-consumer consumer -- curl -s -XPOST demo-app.kong-mesh-demo:5050/api/counter
    

    You should get the following response:

    {
        "counter": 1,
        "zone": ""
    }
    

    If you get a container not found error, it may be because the consumer pod takes a few seconds to initialize. Wait a few seconds and try again.

Add a MeshTimeout producer policy

  1. Add a MeshTimeout producer policy with a one second timeout:

    echo "apiVersion: kuma.io/v1alpha1
    kind: MeshTimeout
    metadata:
      name: producer-timeout
      namespace: kong-mesh-demo
      labels:
        kuma.io/mesh: default
        kuma.io/origin: zone
    spec:
      to:
        - targetRef:
            kind: MeshService
            name: demo-app
          default:
            http:
              requestTimeout: 1s" | kubectl apply -f -
    
  2. Run the following command to inspect the policy labels:

    kubectl get meshtimeout -n kong-mesh-demo producer-timeout -o jsonpath='{.metadata.labels}'
    

    You should get the following result:

    {
        "k8s.kuma.io/namespace": "kong-mesh-demo",
        "kuma.io/env": "kubernetes",
        "kuma.io/mesh": "default",
        "kuma.io/origin": "zone",
        "kuma.io/policy-role": "producer",
        "kuma.io/zone": "default"
    }
    

    Kong Mesh adds custom labels to the policy. The kuma.io/policy-role label set to producer indicates that the policy applies to the same namespace as the MeshService it targets in spec.to. In this example the targeted MeshService is demo-app, which is associated with the kong-mesh-demo namespace.

Validate the MeshTimeout policy

Send requests to the demo app using both consumer namespaces with the x-set-response-delay-ms header to simulate delays:

kubectl exec -n first-consumer consumer -- curl -s -XPOST demo-app.kong-mesh-demo:5050/api/counter -H "x-set-response-delay-ms: 2000"
kubectl exec -n second-consumer consumer -- curl -s -XPOST demo-app.kong-mesh-demo:5050/api/counter -H "x-set-response-delay-ms: 2000"

You should get the following response for both:

upstream request timeout

Add a MeshTimeout consumer policy

  1. Add a MeshTimeout consumer policy with a three second timeout, scoped to the first consumer:

    echo "apiVersion: kuma.io/v1alpha1
    kind: MeshTimeout
    metadata:
     name: consumer-timeout
     namespace: first-consumer
     labels:
         kuma.io/mesh: default
         kuma.io/origin: zone
    spec:
      to:
        - targetRef:
            kind: MeshService
            labels:
              k8s.kuma.io/service-name: demo-app
          default:
            http:
              requestTimeout: 3s" | kubectl apply -f -
    
  2. Run the following command to inspect the policy labels:

    kubectl get meshtimeout -n first-consumer consumer-timeout -o jsonpath='{.metadata.labels}'
    

    You should get the following result:

    {
        "k8s.kuma.io/namespace": "first-consumer",
        "kuma.io/env": "kubernetes",
        "kuma.io/mesh": "default",
        "kuma.io/origin": "zone",
        "kuma.io/policy-role": "consumer",
        "kuma.io/zone": "default"
    }
    

    The kuma.io/policy-role label set to consumer indicates the policy applies to the consumer namespace, first-consumer in this example. This overrides the producer policy.

  3. Send a request to the demo app using the first consumer namespace:

    kubectl exec -n first-consumer consumer -- curl -s -XPOST demo-app.kong-mesh-demo:5050/api/counter -H "x-set-response-delay-ms: 2000"
    

    Since we’ve increased the timeout for the first consumer, you should get this response:

    {
        "counter": 2,
        "zone": ""
    }
    

    If you send a request to the second consumer, you should still get a timeout:

    kubectl exec -n second-consumer consumer -- curl -s -XPOST demo-app.kong-mesh-demo:5050/api/counter -H "x-set-response-delay-ms: 2000"
    

Cleanup

To clean up your environment, remove the Docker containers, network, temporary directory, and the control plane configuration. Run the following command:

kubectl config delete-context mesh-zone
Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!