It’s been a little while since I last published anything on my personal website but I have been creating quite a lot of content over on isovalent.com and posting a lot of Cilium updates on LinkedIn.
Most of the content over there is long-form and there is a little feature I discovered this morning that I thought I should share here for posterity.
I have been working on Gateway API for the past few months: previously at my last gig with HashiCorp (Consul was one of the first platforms to support it) and now at Isovalent, where Gateway API is officially released with Cilium 1.13. To help folks understanding Gateway API generally (and how it works on Cilium), I have created with an online lab which has been well-received. Check it out here.
I had been wondering what the migration path would be for Kubernetes Ingress users. Officially the line seems to be that Gateway API will not replace Ingress API but in the long-run, I imagine that it will (it doesn’t make sense for operators to run in parallel two means to route traffic into their clusters).
I was browsing the Gateway API website when I came across some details about a tool to migrate Ingress to Gateway API resources: it’s originally called Ingress to Gateway.
Written in Go, the tool checks out your Kubernetes Cluster (based on your current Kube Config), reads the Ingress API resources and outputs equivalent Gateway API resources to the terminal.
The project is still experimental as I write this blog post so obviously double-check the results and test before deploying.
The only requirement is to have Go installed and run go run .
to compile and execute the tool. It worked straight-away for me.
I actually used the Isovalent Service Mesh lab to test it out as we use Ingress resources in the lab.
The Ingress Resouces deployed is the following:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
namespace: default
spec:
ingressClassName: cilium
rules:
- http:
paths:
- backend:
service:
name: details
port:
number: 9080
path: /details
pathType: Prefix
- backend:
service:
name: productpage
port:
number: 9080
path: /
pathType: Prefix
One of the problems with Ingress is that Ingress definitions are specified in one big YAML file and managing it can be challenging when you have multiple teams looking at applying various routing configurations.
That’s addressed by Gateway API by separating the definition of an Gateway in one resource and the actual routes in separate resources (for example, HTTPRoute).
And that’s what you get when you use Ingress2Gateway:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: cilium
namespace: default
spec:
gatewayClassName: cilium
listeners:
- name: http
port: 80
protocol: HTTP
status: {}
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: all-hosts
namespace: default
spec:
parentRefs:
- name: cilium
rules:
- backendRefs:
- name: details
port: 9080
matches:
- path:
type: PathPrefix
value: /details
- backendRefs:
- name: productpage
port: 9080
matches:
- path:
type: PathPrefix
value: /
status:
parents: []
This is pretty good. There are some fields that are not required (like creationTimestamp
) but regardless, it works. When I saved this output into a yaml file called ingress2gateway.yaml
and apply it, access to the Service behind the Gateway was successful:
root@server:~# vi ingress2gateway.yaml
root@server:~# kubectl apply -f ingress2gateway.yaml
gateway.gateway.networking.k8s.io/cilium created
httproute.gateway.networking.k8s.io/all-hosts created
root@server:~#
root@server:~#
root@server:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-cilium LoadBalancer 10.96.251.20 172.18.255.201 80:31478/TCP 7s
details ClusterIP 10.96.130.54 <none> 9080/TCP 49s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m
productpage ClusterIP 10.96.7.88 <none> 9080/TCP 49s
ratings ClusterIP 10.96.179.111 <none> 9080/TCP 49s
reviews ClusterIP 10.96.176.21 <none> 9080/TCP 49s
root@server:~# kubectl get gateway
NAME CLASS ADDRESS READY AGE
cilium cilium 172.18.255.201 True 68s
root@server:~# GATEWAY=$(kubectl get gateway cilium -o jsonpath='{.status.addresses[0].value}')
root@server:~# echo $GATEWAY
172.18.255.201
root@server:~#
root@server:~# curl --fail -s http://$GATEWAY/details/1 | jq
{
"id": 1,
"author": "William Shakespeare",
"year": 1595,
"type": "paperback",
"pages": 200,
"publisher": "PublisherA",
"language": "English",
"ISBN-10": "1234567890",
"ISBN-13": "123-1234567890"
}
That’s it for today. Thanks for reading.