Kubernetes Ingress
Kubernetes Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
An Ingress can be configured to give Kubernetes services externally reachable URLs, load balance traffic, terminate SSL/TLS, and offer name-based virtual hosting.
It is important to note that to satisfy an Ingress, you must have an Ingress controller (in the example above, FortiWeb Ingress Controller is used). Only creating an Ingress resource would have no effect.
FortiWeb Ingress Controller version 1.0.0 only supports services of type NodePort. |
Ingress class
Ingresses can be implemented by different controllers, often with different configurations. Each Ingress should specify an IngressClass name, which is a reference to an IngressClass resource that contains additional configuration including the name of the controller that should implement the class.
For an Ingress that would be implemented by FortiWeb Ingress Controller, please specify the ingressClassName
to fwb-ingress-controller
in the ingress specification. Upon installation, FortiWeb Ingress Controller is set as the default Ingress controller in the Helm chart value.yaml.
controller: ingressClassResource: name: "fwb-ingress-controller" enabled: true default: true controllerValue: "fortinet.com/fwb-ingress-controller"
Mapping of the Ingress related resources with the FortiWeb objects
Kubernetes Objects |
FortiWeb Objects |
---|---|
Ingress |
Virtual server Content Routing Scripting |
Service |
Real Server Pool Real Server |
Node | Real Server |
Secret |
Local Certificate Local Certificate Group Client-SSL |
Naming rule
For FortiWeb objects created by FortiWeb Ingress Controller, the name of the object is composed of the namespace and the name of the Kubernetes objects. The naming rule is shown below:
FortiWeb Objects |
Naming Rule |
---|---|
Virtual server Real Server Pool Scripting Local Certificate Local Certificate Group Client-SSL |
[namespace of Kubernetes objects]_[name of Kubernetes objects] |
Content Routing | [namespace of Kubernetes objects]_[name of Kubernetes ingress]_[name of Kubernetes service] |
Real Server | Name of the Kubernetes node |
Ingress types
FortiWeb supports all 5 types of Ingress:
For details on each Ingress type, see https://kubernetes.io/docs/concepts/services-networking/ingress/.
For an example Ingress file, see https://github.com/fortinet/fortiweb-ingress/tree/main/service_examples/.
Ensure the service used in the Ingress is already deployed with NodePort type. Kubernetes does not verify whether the service defined in the Ingress exists or not when deploying an Ingress. So, if you remove the service used in the deployed Ingress, you will not be warned or blocked from this action. |
Default backend
An Ingress with no rules sends all traffic to a single default backend. If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is routed to your default backend. Therefore, if Rules are not specified, defaultBackend
must be specified in the Ingress.
Note: FortiWeb Ingress Controller only supports Service
backend. A Resource
backend is not supported.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-with-default-backend annotations: { "fortiweb-ip" : "172.23.133.148", "fortiweb-login" : "fwb-login1", "fortiweb-port": "443", "fortiweb-ctrl-log" : "enable", "virtual-server-ip" : "192.23.133.6", "virtual-server-addr-type" : "ipv4", "virtual-server-interface" : "port2", "server-policy-web-protection-profile" : "Inline Standard Protection", "server-policy-https-service" : "HTTPS", "server-policy-http-service" : "HTTP", "server-policy-syn-cookie" : "enable", "server-policy-http-to-https" : "disable" } spec: ingressClassName: fwb-ingress-controller defaultBackend: service: name: service1 port: number: 1241
You can add defaultBackend in any particular Ingress. You can check the example here:
https://github.com/fortinet/fortiweb-ingress/blob/main/service_examples/default-http-backend.yaml
Minimal-Ingress
A minimal-Ingress has at least one rule defined in the Ingress with no specified default backend. The following is an example of a minimal-Ingress.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: { "fortiweb-ip" : "172.23.133.148", "fortiweb-login" : "fwb-login1", "fortiweb-ctrl-log" : "disable", "virtual-server-ip" : "192.23.133.6", "virtual-server-addr-type" : "ipv4", "virtual-server-interface" : "port2", "server-policy-web-protection-profile" : "Inline Standard Protection", "server-policy-https-service" : "HTTPS", "server-policy-http-service" : "HTTP", "server-policy-syn-cookie" : "enable", "server-policy-http-to-https" : "disable" } spec: ingressClassName: fwb-ingress-controller rules: - host: test.com http: paths: - path: /info pathType: Prefix backend: service: name: service1 port: number: 1241
Name-based virtual hosting
Name-based virtual hosts support the routing of HTTP/HTTPS traffic to multiple host names at the same IP address.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: simple-fanout-example annotations: { "fortiweb-ip" : "172.23.133.148", "fortiweb-login" : "fwb-login1", "fortiweb-ctrl-log" : "disable", "virtual-server-ip" : "192.23.133.6", "virtual-server-addr-type" : "ipv4", "virtual-server-interface" : "port2", "server-policy-web-protection-profile" : "Inline Standard Protection", "server-policy-https-service" : "HTTPS", "server-policy-http-service" : "HTTP", "server-policy-syn-cookie" : "enable", "server-policy-http-to-https" : "disable" } spec: ingressClassName: fwb-ingress-controller rules: - host: test.com http: paths: - path: /info pathType: Prefix backend: service: name: service1 port: number: 1241 - path: /hello pathType: Prefix backend: service: name: service2 port: number: 1242
Hostname wildcards
The hostname can be a precise match or a wildcard. Precise matches require the HTTP host header to match the host field (e.g., foo.bar.com
). Wildcard matches require the HTTP host header to be equal to the suffix of the wildcard rule (e.g., *.foo.com
).
Refer to the examples below to determine whether an HTTP host header is a wildcard match or not.
Host |
Host header |
Does it match? |
---|---|---|
*.foo.com
|
bar.foo.com
|
Yes, it matches based on shared suffix. |
*.foo.com
|
baz.bar.foo.com
|
No, it does not match. Wildcard only covers a single DNS label. |
*.foo.com
|
foo.com
|
No, it does not match. Wildcard only covers a single DNS label. |
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wildcard-host annotations: { "fortiweb-ip" : "172.23.133.148", "fortiweb-login" : "fwb-login1", "fortiweb-ctrl-log" : "disable", "virtual-server-ip" : "192.23.133.6", "virtual-server-addr-type" : "ipv4", "virtual-server-interface" : "port2", "server-policy-web-protection-profile" : "Inline Standard Protection", "server-policy-https-service" : "HTTPS", "server-policy-http-service" : "HTTP", "server-policy-syn-cookie" : "enable", "server-policy-http-to-https" : "disable" } spec: ingressClassName: fwb-ingress-controller rules: - host: "test.com" http: paths: - path: /info pathType: Prefix backend: service: name: service1 port: number: 1241 - host: "*.test1.com" http: paths: - path: /info pathType: Prefix backend: service: name: service2 port: number: 1242
TLS
You can secure an Ingress by specifying a Secret that contains a TLS private key and certificate. The Ingress resource only supports a single TLS port, 443, and assumes TLS termination at the Ingress point (traffic to the Service and its Pods is in plain text). If the TLS configuration section in an Ingress specifies different hosts, they are multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret must contain keys named tls.crt
and tls.key
that contain the certificate and private key to use for TLS.
For example:
apiVersion: v1 kind: Secret metadata: name: testsecret-tls namespace: default data: tls.crt: base64 encoded cert tls.key: base64 encoded key type: kubernetes.io/tls
You can create the TLS secret by using the kubectl command, for example:
kubectl create secret tls tls-example --cert=/etc/ssl/tls.crt --key=/etc/ssl/tls.key
Referencing this secret in an Ingress tells the Ingress controller to secure the channel from the client to the load balancer using TLS. You need to ensure the TLS secret you created came from a certificate that contains a Common Name (CN), also known as a Fully Qualified Domain Name (FQDN) for https-example.foo.com
.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-example-ingress annotations: { "fortiweb-ip" : "172.23.133.148", "fortiweb-login" : "fwb-login1", "fortiweb-ctrl-log" : "disable", "virtual-server-ip" : "192.23.133.6", "virtual-server-addr-type" : "ipv4", "virtual-server-interface" : "port2", "server-policy-web-protection-profile" : "Inline Standard Protection", "server-policy-https-service" : "HTTPS", "server-policy-http-service" : "HTTP", "server-policy-syn-cookie" : "enable", "server-policy-http-to-https" : "disable" } spec: ingressClassName: fwb-ingress-controller tls: - hosts: - test.com secretName: tls-example rules: - host: test.com http: paths: - path: /info pathType: Prefix backend: service: name: service1 port: number: 1241 - path: /hello pathType: Prefix backend: service: name: service2 port: number: 1242