Gateway API implementation for Oracle Kubernetes (OKE).
Project status: Beta
Install Gateway API CRDs. Choose one path:
# Standard CRDs are enough for HTTPRoute / ALB usage.
kubectl apply --server-side=true \
-f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml
# Or use experimental CRDs when enabling TCPRoute / UDPRoute / NLB usage.
kubectl apply --server-side=true \
-f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/experimental-install.yamlThe controller can run with only the standard CRDs. The experimental channel is required only for TCPRoute and UDPRoute support.
TLSRoute is available from the standard Gateway API CRDs.
Prepare API key and config file (use actual values):
[DEFAULT]
user=<user_ocid>
fingerprint=<key_fingerprint>
tenancy=<tenancy_ocid>
region=<oci_region>
key_file=/etc/oci/key.pemNote: key_file corresponds to the location on pod that will be mounted as a secret, so leave it as is.
Create a secret with the API key and config file:
# Ensure namespace exists first
kubectl create namespace oke-gw
# config should point to the locally prepared config file as per above example
# key.pem should point to the locally prepared private key file
kubectl create secret generic oci-api-key \
--from-file=config=/path/to/created/config \
--from-file=key.pem=/path/to/actual/privatekey.pem \
-n oke-gwInstall the OKE Gateway API controller using Helm:
helm upgrade oke-gateway-api-controller \
oci://ghcr.io/gemyago/helm-charts/oke-gateway-api-controller \
--install \
-n oke-gwGive it few minutes to start.
Create a GatewayClass resource:
cat <<EOF | kubectl -n oke-gw apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: oke-gateway-api
spec:
controllerName: oke-gateway-api.gemyago.github.io/oke-alb-gateway-controller
EOFThe controller will not automatically create the load balancer. Please create it first. Prepare a GatewayConfig resource. You will need to specify the OCID of the created OCI Load Balancer.
cat <<EOF | kubectl -n oke-gw apply -f -
apiVersion: oke-gateway-api.gemyago.github.io/v1
kind: GatewayConfig
metadata:
name: oke-gateway-config
spec:
# Replace with your Load Balancer OCID
loadBalancerId: ocid1.loadbalancer.oc1..exampleuniqueID
EOFCreate Gateway resource:
cat <<EOF | kubectl -n oke-gw apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: oke-gateway
spec:
gatewayClassName: oke-gateway-api
infrastructure:
parametersRef:
group: oke-gateway-api.gemyago.github.io
kind: GatewayConfig
name: oke-gateway-config
listeners:
- name: http
port: 80
protocol: HTTP
EOFAssuming you have a deployment and service similar to the following:
cat <<EOF | kubectl -n oke-gw apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: oke-gateway-example-server
labels:
app: oke-gateway-example-server
spec:
replicas: 1
selector:
matchLabels:
app: oke-gateway-example-server
template:
metadata:
labels:
app: oke-gateway-example-server
spec:
containers:
- name: echo
# This is simple echo server that can be used to test the gateway
image: ghcr.io/gemyago/oke-gateway-api-server:main
args:
- start
- --json-logs
ports:
- containerPort: 8080
name: http
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: oke-gateway-example-server
labels:
app: oke-gateway-example-server
spec:
ports:
- port: 8080
name: http
targetPort: http
selector:
app: oke-gateway-example-server
EOFYou can now attach the HTTP route to the gateway to route traffic to the deployment:
cat <<EOF | kubectl -n oke-gw apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: oke-gateway-example-server
spec:
parentRefs:
- name: oke-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /echo
backendRefs:
- name: oke-gateway-example-server
port: 8080
EOFUninstall example resources:
kubectl -n oke-gw delete gateway oke-gateway
kubectl -n oke-gw delete gatewayclass oke-gateway-api
kubectl -n oke-gw delete gatewayconfig oke-gateway-config
kubectl -n oke-gw delete deployment oke-gateway-example-server
kubectl -n oke-gw delete httproute oke-gateway-example-serverFollowing match types are supported:
- path:
PathPrefixandExact - header:
ExactandRegularExpression
OCI doesn't support regexp matching, instead start with (sw) or end with (ew) matching are possible. Due to this limitations, the below patterns only are supported, they will be mapped to corresponding OCI conditions:
^foo->sw 'foo'^foo.*->sw 'foo'^foo\\..*->sw 'foo.'foo$->ew 'foo'.*foo$->ew 'foo'
Other patterns will result in an error.
Please refer to https for more details.
GRPCRoute uses the standard Gateway API CRDs and is reconciled on OCI Load Balancer with the other layer 7 routes. It is not implemented on OCI Network Load Balancer. Use TCPRoute if you only need gRPC passthrough to pods.
The controller supports gRPC host, service, method, and exact header matching. HTTPRoute and GRPCRoute can share the same HTTPS listener and hostname; GRPCRoute rules require a native gRPC content-type and are ordered before broad HTTPRoute matches.
See deploy/manifests/examples/grpcroute.yaml for a minimal route example.
BackendTLSPolicy configures TLS from OCI Load Balancer backend sets to backend Pods for ALB-backed HTTPRoute, GRPCRoute, and TLSRoute with tls.mode: Terminate. It is not supported for OCI Network Load Balancer routes.
OCI backend SSL validates the backend certificate chain but does not enforce hostname/SAN identity. Policies must explicitly set oci.oraclecloud.com/backend-hostname-validation: Disabled, and unsupported standard fields such as subjectAltNames are rejected. CA trust can come from validation.caCertificateRefs, from pre-managed OCI CA bundle OCIDs in oci.oraclecloud.com/trusted-ca-bundle-ocids, or both.
See deploy/manifests/examples/backendtlspolicy.yaml for a complete example with a Gateway, HTTPRoute, Service, CA ConfigMap, and BackendTLSPolicy.
Layer 4 support uses an existing OCI Network Load Balancer. The controller reconciles listeners, backend sets, and backends on the referenced NLB, but does not create or delete the NLB resource itself.
Apply the NLB GatewayClass:
kubectl apply -f deploy/manifests/examples/gatewayclass-nlb.yamlCreate a GatewayConfig that points to the existing NLB:
apiVersion: oke-gateway-api.gemyago.github.io/v1
kind: GatewayConfig
metadata:
name: oke-nlb-gateway-config
spec:
loadBalancerId: ocid1.networkloadbalancer.oc1..exampleuniqueIDCreate a Gateway with TCP and UDP listeners, then attach matching routes:
kubectl apply -n <namespace> -f deploy/manifests/examples/gatewayconfig-nlb.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/gateway-nlb.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/l4serverdeployment-nlb.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/tcproute-nlb.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/udproute-nlb.yamlOCI Network Load Balancer backend sets require health checks. For UDPRoute,
set oke-gateway-api.gemyago.github.io/nlb-udp-health-check-port on each route
to the TCP port the backend Pods expose for health checking. UDP health checks
are not configured by this controller.
GatewayConfig.spec.loadBalancerId is shared with ALB usage. The GatewayClass determines whether the OCID is resolved through the OCI Load Balancer API or the OCI Network Load Balancer API.
TLSRoute supports two OCI-backed modes:
- OCI Load Balancer with
tls.mode: Terminate: terminates TLS at the ALB and forwards to the backend Service port. UseBackendTLSPolicywhen the backend connection should also use TLS. - OCI Network Load Balancer with
tls.mode: Passthrough: forwards encrypted TCP bytes to a backend that terminates TLS itself.
Unsupported combinations are rejected: ALB passthrough and NLB termination. OCI does not support SNI fanout for ALB TCP+SSL listeners or NLB TCP passthrough listeners, so only one effective TLSRoute can own a TLS listener. TLSRoute health checks use TCP on the resolved backend Service port.
Apply the ALB terminate example:
kubectl apply -n <namespace> -f deploy/manifests/examples/gatewayconfig.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/gatewayclass.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/tlsroute-alb.yamlApply the NLB passthrough example:
kubectl apply -n <namespace> -f deploy/manifests/examples/gatewayconfig-nlb.yaml
kubectl apply -f deploy/manifests/examples/gatewayclass-nlb.yaml
kubectl apply -n <namespace> -f deploy/manifests/examples/tlsroute-nlb.yamlUse this section to setup the development environment.
We optionally use OpenSpec, we don't yet commit it to the repo.
npm install -g @fission-ai/openspec@latest
openspec initPlease have the following tools installed:
Install/Update dependencies:
direnv allow
# Install go dependencies
go mod download
go install tool
# or update:
go get -u ./... && go mod tidy
# Install required python version
pyenv install -s
# Setup python environment
python -m venv .venv
# Reload env
direnv reload
# Install python dependencies
pip install -r requirements.txtIf updating python dependencies, please lock them:
pip freeze > requirements.txtRun all lint and tests:
make lint
make testFor local development purposes you can run the controller fully locally pointing on OKE cluster and provision the resources in an actual OCI tenancy.
Please follow OCI SDK CLI Setup to setup the OCI CLI.
You may want to use alternative SDK config location. In this case please create .envrc.local file with the contents similar to below:
# Point to the OCI CLI config file
export OCI_CLI_CONFIG_FILE=${PWD}/../.oci-cloud-cli/config
export OCI_CONFIG_FILE=${PWD}/../.oci-cloud-cli/config
# Point to the OCI CLI profile
export OCI_CLI_PROFILE=DEFAULT
# Point to the OCI CLI config profile
export OCI_CLI_CONFIG_PROFILE=eu-frankfurt-1Reload the environment and check if all good:
direnv reload
# Check if the oci sdk is properly configured
oci iam user listMake sure to kubectl configured to point to a target OKE cluster.
Run the controller locally:
go run ./cmd/controller/ start