Skip to content

Networking

This page describes how to expose Kannika Armory outside the cluster and configure network access between its components.

flowchart TD
    Client([External Client])
    Router[Ingress / Gateway API]

    Client --> Router

    subgraph system["kannika-system"]
        API["API :8080\nEvent Gateway :8082"]
        Console["Console :8080"]
    end

    subgraph data["kannika-data"]
        Pods["Backup / Restore Pods :9000"]
    end

    Router -- "/gql, /rest" --> API
    Router -- "/*" --> Console
    Pods -- "push events :8082" --> API
    API -- "scrape metrics :9000" --> Pods

By default, the API and Console are not exposed outside the cluster. The following Services are available in the system namespace (e.g. kannika-system):

ServicePortPurposeURL Paths
api8080REST and GraphQL API/gql, /rest
console8080Web-based user interface/
event-gateway8082Internal push metrics endpoint— (cluster-internal only)
Services
$ kubectl get svc -n kannika-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
api ClusterIP 10.96.124.99 <none> 8080/TCP 1m
console ClusterIP 10.96.46.216 <none> 8080/TCP 1m
...

For the Console to work properly, it must be able to access the /gql endpoint of the API. The API URL must be configured in the Console configuration of the Helm installation.

values.yaml
console:
config:
apiUrl: "http://localhost:8080" # Do not add /gql

In this example, the Console will access the GraphQL API at https://localhost:8080/gql.

If you want to expose the API and Console locally for testing purposes, you can use kubectl port-forward to forward the ports to your local machine.

Exposing the API on port 8080:

Port forwarding the API
$ kubectl port-forward -n kannika-system svc/api 8080
Forwarding from [127.0.0.1]:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

Exposing the Console on port 8081:

Port Forwarding the Console
$ kubectl port-forward -n kannika-system svc/console 8081:8080
Forwarding from [127.0.0.1]:8081 -> 8080
Forwarding from [::1]:8081 -> 8080

In this example:

  • Requests to http://localhost:8080/ will be routed to the api Service on port 8080.

  • Requests to http://localhost:8081/ will be routed to the console Service on port 8080.

  • The GraphQL API is available at http://localhost:8080/gql

  • The REST API is available at http://localhost:8080/rest

  • The Console is available at http://localhost:8081. Note that the API URL must be configured for the Console for it to work properly.

You can use a Kubernetes Ingress to expose the API and Console outside the cluster.

It is possible to host the API and Console on the same domain. This is the easiest approach, as it does not require any additional configuration regarding the API URL.

Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kannika-ingress
29 collapsed lines
namespace: kannika-system
spec:
tls:
- hosts:
- kannika.example.com
secretName: kannika-tls
defaultBackend:
service:
name: console
port:
number: 8080
rules:
- host: kannika.example.com
http:
paths:
- backend:
service:
name: api
port:
number: 8080
path: /gql
pathType: Prefix
- backend:
service:
name: api
port:
number: 8080
path: /rest
pathType: Prefix

In this example:

  • TLS is terminated at the Ingress using the kannika-tls Secret. The Secret must contain a valid certificate and key for the domain.

  • Requests to kannika.example.com under the paths /gql and /rest are routed to the api Service on port 8080.

  • The default backend is set to the console Service on port 8080, which means all other requests not matching the paths /gql and /rest under the domain kannika.example.com are routed to the console Service.

  • No additional configuration is needed for the Console to work properly as the API URL is the same as the Console URL.

It is possible to host the API and Console on different domains. This is useful if you want to separate the API and Console for security or organizational reasons.

If the API and Console are hosted on different domains, the API URL must be configured for the Console.

Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kannika-ingress
34 collapsed lines
namespace: kannika-system
spec:
tls:
- hosts:
- api.kannika.example.com
- console.kannika.example.com
secretName: kannika-tls
rules:
- host: api.kannika.example.com
http:
paths:
- backend:
service:
name: api
port:
number: 8080
path: /gql
pathType: Prefix
- backend:
service:
name: api
port:
number: 8080
path: /rest
pathType: Prefix
- host: console.kannika.example.com
http:
paths:
- backend:
service:
name: console
port:
number: 8080
pathType: Prefix

In this example:

  • Requests to api.kannika.example.com under the paths /gql and /rest are routed to the api Service on port 8080.

  • Requests to console.kannika.example.com are routed to the console Service on port 8080.

  • The Prefix path type is used to match all requests under the specified paths.

The Kubernetes Gateway API is the successor to Ingress and provides more expressive routing capabilities. You can use HTTPRoute resources to expose the API and Console.

flowchart TD
    GC[GatewayClass]
    GW[Gateway]
    HR[HTTPRoute]
    APISvc[api :8080]
    ConsoleSvc[console :8080]

    GC -. "managed by controller" .-> GW
    GW -- "parentRef" --- HR
    HR -- "/gql, /rest" --> APISvc
    HR -- "/*" --> ConsoleSvc

A Gateway API controller must be installed in the cluster (e.g. Envoy Gateway, Cilium, Istio, or Traefik). The controller manages the GatewayClass and Gateway resources.

The examples below assume a Gateway named my-gateway exists in the kannika-system namespace. Replace my-gateway with the name of your Gateway resource.

TLS termination is configured on the Gateway resource, not on HTTPRoute. The following example shows a Gateway with both an HTTP and HTTPS listener:

Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
22 collapsed lines
namespace: kannika-system
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
group: ""
name: kannika-tls
allowedRoutes:
namespaces:
from: Same

In this example:

  • The gatewayClassName references the GatewayClass provided by your controller.

  • The listener terminates TLS on port 443 using the kannika-tls Secret. The Secret must contain a valid TLS certificate and key for the domain.

  • allowedRoutes is set to from: Same, restricting HTTPRoute attachments to the same namespace as the Gateway. Other options are from: All and from: Selector.

HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: kannika-route
24 collapsed lines
namespace: kannika-system
spec:
parentRefs:
- name: my-gateway
hostnames:
- kannika.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /gql
backendRefs:
- name: api
port: 8080
- matches:
- path:
type: PathPrefix
value: /rest
backendRefs:
- name: api
port: 8080
- backendRefs:
- name: console
port: 8080

In this example:

  • The HTTPRoute references a Gateway named my-gateway via parentRefs.

  • Requests to kannika.example.com under the paths /gql and /rest are routed to the api Service on port 8080.

  • All other requests are routed to the console Service on port 8080.

  • No additional configuration is needed for the Console to work properly as the API URL is the same as the Console URL.

If the API and Console are hosted on different domains, the API URL must be configured for the Console.

HTTPRoute — API
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: kannika-api-route
21 collapsed lines
namespace: kannika-system
spec:
parentRefs:
- name: my-gateway
hostnames:
- api.kannika.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /gql
backendRefs:
- name: api
port: 8080
- matches:
- path:
type: PathPrefix
value: /rest
backendRefs:
- name: api
port: 8080
HTTPRoute — Console
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: kannika-console-route
10 collapsed lines
namespace: kannika-system
spec:
parentRefs:
- name: my-gateway
hostnames:
- console.kannika.example.com
rules:
- backendRefs:
- name: console
port: 8080

In this example:

  • Each HTTPRoute references the same Gateway named my-gateway via parentRefs.

  • Requests to api.kannika.example.com under the paths /gql and /rest are routed to the api Service on port 8080.

  • Requests to console.kannika.example.com are routed to the console Service on port 8080.

When the platform is installed in a different namespace than the resources (e.g. kannika-system and kannika-data), backup and restore pods need to communicate with the API server and vice versa.

If you are using Kubernetes NetworkPolicies or a service mesh that restricts cross-namespace traffic, the following ports must be open between the two namespaces.

PortDirectionSourceTargetPurpose
9000Resource → SystemBackup/Restore podsAPI serverPrometheus metrics scraping
8082Resource → SystemBackup/Restore podsAPI Event GatewayPush metrics and events

Every backup pod and restore job exposes a /metrics endpoint on port 9000 in the Prometheus format. The API server scrapes this endpoint to track progress.

When pods run in a separate resource namespace, the API server in the system namespace must be able to reach port 9000 on the pods.

See Metrics for more details.

Backup and restore pods push status events (started, stopped) to the API’s Event Gateway service on port 8082. The Armory console uses these events to display real-time progress.

When pods run in a separate resource namespace, they must be able to reach the event-gateway service in the system namespace on port 8082.

See Push metrics for more details on the Event Gateway configuration.

The following NetworkPolicy allows backup and restore pods in the resource namespace to communicate with the API server in the system namespace:

network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-armory-cross-namespace
namespace: kannika-data
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kannika-system
ports:
- protocol: TCP
port: 8082
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-armory-metrics-scraping
namespace: kannika-data
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kannika-system
ports:
- protocol: TCP
port: 9000

Security is enabled by default. For more details about the configuration, check out the Security section.