Skip to main content

Deploying Gate Kubernetes with Ingress

In this example, we will deploy Gate in K8s as an ingress. In this scenario, all the services' traffic must go through Gate.

info

This is just an example of deployment. You should adjust it to your infrastructure.

Prerequisites

This tutorial uses Gate's Docker image.

In this example, we will use NGINX Ingress Controller. For more information on how to deploy NGINX Ingress Controller locally or on production, please check its documentation.

Architecture

orders service deploymentproducts service deploymentorders service pod 1products service pod 1orders service pod [n]...products service pod [n]...Gate sidecarGate sidecar orders service products serviceorders serviceproducts serviceGate sidecarGate sidecarUserYour Kubernetes clusternginx-ingressordersK8SserviceproductsK8Sservice

Example configuration

gate-ingress.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: products
spec:
replicas: 3
selector:
matchLabels:
app: products
template:
metadata:
labels:
app: products
spec:
containers:
- name: gate
image: slashid/gate
command: [gate, --env]
ports:
- containerPort: 8080
env:
- name: GATE_PORT
value: "8080"
# entire traffic will go to example service listening on port 80
- name: GATE_DEFAULT_TARGET
value: http://localhost:80
- name: example-service
image: slashid/example-service
env:
# this service is not exposed: it's only possible to access it through Gate
- name: PORT
value: "80"
- name: SERVICE_NAME
value: products
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders
spec:
replicas: 3
selector:
matchLabels:
app: orders
template:
metadata:
labels:
app: orders
spec:
containers:
- name: gate
image: slashid/gate
ports:
- containerPort: 8080
env:
- name: GATE_PORT
value: "8080"
# entire traffic will go to example service listening on port 80
- name: GATE_DEFAULT_TARGET
value: http://localhost:80
- name: orders
image: slashid/example-service
env:
# this service is not exposed: it's only possible to access it through Gate
- name: PORT
value: "80"
- name: SERVICE_NAME
value: orders
---
apiVersion: v1
kind: Service
metadata:
labels:
app: products
name: products
spec:
ports:
- port: 8080
targetPort: 8080
selector:
app: products
sessionAffinity: None
---
apiVersion: v1
kind: Service
metadata:
labels:
app: orders
name: orders
spec:
ports:
- port: 8080
targetPort: 8080
selector:
app: orders
sessionAffinity: None
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /orders
pathType: Exact
backend:
service:
name: orders
port:
number: 8080
- path: /products
pathType: Exact
backend:
service:
name: products
port:
number: 8080

Testing locally

You can test this setup locally (for example, with Docker Desktop Kubernetes).

kubectl apply -f gate-sidecar.yaml

Once the deployment is running, you can check if requests go through Gate.

curl -v http://localhost:80/products
> GET /products HTTP/1.1
> Host: localhost:80
> User-Agent: curl/7.79.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 81
< Content-Type: application/json
< Servicehostname: products-57c5667b6c-kg6qh
< Servicename: products
< Via: 1.0 gate
<
{
"service_hostname": "products-57c5667b6c-kg6qh",
"service_name": "products"
}
info

If curl cannot connect to the service, and you are using K8s from Docker Desktop, something else may be listening on port 80.

Ensure that example-ingress has an address assigned by calling kubectl get ingress.

> kubectl get ingress

NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> * 80 33m

If ingress works properly, you should see an localhost address assigned to it:

> kubectl get ingress

NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> * localhost 80 37m

If the Via: 1.0 gate header is present, it means that everything works properly and gate is up and running.

curl -v http://localhost:80/orders

> GET /orders HTTP/1.1
> Host: localhost:80
> User-Agent: curl/7.79.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 77
< Content-Type: application/json
< Servicehostname: orders-66cfb49594-mw6nf
< Servicename: orders
< Via: 1.0 gate
<
{
"service_hostname": "orders-66cfb49594-mw6nf",
"service_name": "orders"
}

Now you can configure Gate based on use cases.