Ingress for tunnels¶
Info
Inlets Uplink is designed to connect customer services to a remote Kubernetes cluster for command and control as part of a SaaS product.
Any tunnelled service can be accessed directly from within the cluster and does not need to be exposed to the public Internet for access.
Beware: by following these instructions, you are exposing one or more of those tunnels to the public Internet.
Make inlets uplink HTTP tunnels publicly accessible by setting up ingress for the data plane.
The instructions assume that you want to expose two HTTP tunnels. We will configure ingress for the first tunnel, called grafana
, on the domain grafana.example.com
. The second tunnel, called openfaas
, will use the domain openfaas.example.com
.
Both tunnels can be created with kubectl
or the inlets-pro
cli. See create tunnels for more info:
$ cat <<EOF | kubectl apply -f -
apiVersion: uplink.inlets.dev/v1alpha1
kind: Tunnel
metadata:
name: grafana
namespace: tunnels
spec:
licenseRef:
name: inlets-uplink-license
namespace: tunnels
---
apiVersion: uplink.inlets.dev/v1alpha1
kind: Tunnel
metadata:
name: openfaas
namespace: tunnels
spec:
licenseRef:
name: inlets-uplink-license
namespace: tunnels
EOF
$ inlets-pro tunnel create grafana
Created tunnel openfaas. OK.
$ inlets-pro tunnel create openfaas
Created tunnel openfaas. OK.
Follow the instruction for Kubernetes Ingress or Istio depending on how you deployed inlets uplink.
Setup tunnel ingress¶
-
Create a new certificate Issuer for tunnels:
export EMAIL="you@example.com" cat > tunnel-issuer-prod.yaml <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: tunnels-letsencrypt-prod namespace: inlets spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: $EMAIL privateKeySecretRef: name: tunnels-letsencrypt-prod solvers: - http01: ingress: class: "nginx" EOF
-
Create an ingress resource for the tunnel:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana-tunnel-ingress namespace: inlets annotations: kubernetes.io/ingress.class: nginx cert-manager.io/issuer: tunnels-letsencrypt-prod spec: rules: - host: grafana.example.com http: paths: - path: / pathType: Prefix backend: service: name: grafana.tunnels port: number: 8000 tls: - hosts: - grafana.example.com secretName: grafana-cert
Note that the annotation
cert-manager.io/issuer
is used to reference the certificate issuer created in the first step.
To setup ingress for multiple tunnels simply define multiple ingress resources. For example apply a second ingress resource for the openfaas tunnel:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: openfaas-tunnel-ingress
namespace: inlets
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/issuer: tunnels-letsencrypt-prod
spec:
rules:
- host: openfaas.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: openfaas.tunnels
port:
number: 8000
tls:
- hosts:
- openfaas.example.com
secretName: openfaas-cert
Setup tunnel ingress with an Istio Ingress gateway¶
-
Create a new certificate Issuer for tunnels:
export EMAIL="you@example.com" cat > tunnel-issuer-prod.yaml <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: tunnels-letsencrypt-prod namespace: istio-system spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: $EMAIL privateKeySecretRef: name: tunnels-letsencrypt-prod solvers: - http01: ingress: class: "istio" EOF
We are using the Let's Encrypt production server which has strict limits on the API. A staging server is also available at https://acme-staging-v02.api.letsencrypt.org/directory. If you are creating a lot of certificates while testing it would be better to use the staging server.
-
Create a new certificate resource. In this case we want to expose two tunnels on their own domain,
grafana.example.com
andopenfaas.example.com
. This will require two certificates, one for each domain:apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: grafana-cert namespace: istio-system spec: secretName: grafana-cert commonName: grafana.example.com dnsNames: - grafana.example.com issuerRef: name: tunnels-letsencrypt-prod kind: Issuer --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: openfaas-cert namespace: istio-system spec: secretName: openfaas-cert commonName: openfaas.example.com dnsNames: - openfaas.example.com issuerRef: name: tunnels-letsencrypt-prod kind: Issuer
Note that both the certificates and issuer are created in the
istio-system
namespace. -
Configure the ingress gateway for both tunnels. In this case we create a single resource for both hosts but you could also split the configuration into multiple Gateway resources.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: tunnel-gateway namespace: inlets spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: grafana-cert hosts: - grafana.example.com - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: openfaas-cert hosts: - openfaas.example.com
Note that the
credentialsName
references the secrets for the certificates created in the previous step. -
Configure the gateway's traffic routes by defining corresponding virtual services:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grafana namespace: inlets spec: hosts: - grafana.example.com gateways: - tunnel-gateway http: - match: - uri: prefix: / route: - destination: host: grafana.tunnels.svc.cluster.local port: number: 8000 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: openfaas namespace: inlets spec: hosts: - openfaas.example.com gateways: - tunnel-gateway http: - match: - uri: prefix: / route: - destination: host: openfaas.tunnels.svc.cluster.local port: number: 8000
After applying these resources you should be able to access the data plane for both tunnels on their custom domain.