Ingress and Service are both fundamental concepts in Kubernetes, but they serve different purposes and operate at different layers within the networking stack.
A Service in Kubernetes is primarily used for exposing a set of pods as a network service.
Types:
Sample manifest:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 8080
An Ingress in Kubernetes is used for external access to services within the cluster.
Sample manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
An Ingress Controller is responsible for implementing the Ingress resource specifications and managing the external access to services within the cluster.
Below is a basic example of the manifest files required for deploying the NGINX Ingress Controller along with a default backend. This example uses namespace ingress-nginx.
# ingress-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress-controller
template:
metadata:
labels:
app: nginx-ingress-controller
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:latest
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
In addition to this, you will need to deploy the Service for the NGINX Ingress Controller:
# ingress-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
spec:
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app: nginx-ingress-controller
If you’ve worked with NGINX before, you’ll know that it also sues a set of configuration options. This can be deployed separately on a ConfigMap:
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
data:
proxy-connect-timeout: "5"
proxy-send-timeout: "600"
proxy-read-timeout: "600"
use-proxy-protocol: "false"
Apply the files:
kubectl apply -f ingress-controller.yaml
kubectl apply -f ingress-service.yaml
kubectl apply -f nginx-configmap.yaml
Next, you will need to create the Ingress Resource.
An Ingress resource in Kubernetes is an API object that defines how external HTTP and HTTPS traffic should be processed and directed to services within the cluster.
Sample manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
tls:
- hosts:
- myapp.example.com
secretName: my-tls-secret
Starting Kubernetes version 1.20, we can create an Ingress resource from the imperative way like this:
kubectl create ingress <ingress-name> --rule="host/path=service:port"
kubectl create ingress ingress-test --rule="wear.my-online-store.com/wear*=wear-service:80"
We can split traffic via URLs or via prefixes.
Different ingress controllers have different options that can be used to customise the way it works. NGINX Ingress controller has many options that can be seen here.
Below is an example that uses rewrite annotation.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
ingressClassName: nginx
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: http-svc
port:
number: 80
In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.
For example, the ingress definition above will result in the following rewrites:
To learn more, check out Rewrite.