We can solve this problem by implementing single Kubernetes Ingress resource with multiple service mapping.
K8 Ingress works based on URL based HTTP routing. So, we can map multiple services to multiple HTTP URLs. When a client sends an HTTP request to the Ingress, the URL host and path in the request determine which service the request is supposed to navigate.
1. Ingress Resource: It is YAML manifest file which contain set of HTTP routing rules mapped to services
2. Ingress Controller: It is K8 Pod running inside the cluster. It is responsible to process Ingress Resource YAML file and route the request to appropriate service. Ingress controller Pods are not started automatically with a cluster. Different K8 environments use different implementations of the controller.
Note: DNS name should resolve to the IP address of Ingress controller to access K8 service from the ingress controller.
As per diagram,
1. run the following kubectl command to enable Nginx Ingress controller on Docker Desktop
run the following command if you are using minikube
2. run the following kubectl command to check the “ingress-nginx-controller” Pod running status
Create Kubernetes Deployment
Create an Ingress YAML manifest to expose multiple services on single host
As per diagram,
- when you initiate a http call from the browser (i.e. shop.com/cart), it performs DNS lookup and returns a IP address of the Ingress controller. So, make sure that DNS name should map to IP address of the Ingress controller.
- Browser sends HTTP request to the Ingress controller, it determines the service which is mapped to the given http URL based on HTTP headers
- Ingress controller find the Pod IPs through Endpoints associated with the service
- HTTP request will be forwarded to one of the Pod.
- Ingress controller uses the service to find Pod IPs, then the controller will process the request.
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/cloud/deploy.yaml
$ minikube addons enable ingress
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-84dcb9867d-dqc9h 1/1 Running 0 11h
Before creating an Ingress, first create two different versions of helloworld app using K8 Deployment and service
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-v1-deployment
spec:
replicas: 1
selector:
matchLabels:
app: v1-web
template:
metadata:
labels:
app: v1-web
spec:
containers:
- name: hello-v1
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello-v1-service
spec:
type: ClusterIP
selector:
app: v1-web
ports:
- protocol: TCP
port: 8080
targetPort: 8080
// save above yaml manifest as hello-v1.yaml and run below command
$ kubectl apply -f hello-v1.yaml
deployment.apps/hello-v1-deployment created
service/hello-v1-service created
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-v2-deployment
spec:
replicas: 1
selector:
matchLabels:
app: v2-web
template:
metadata:
labels:
app: v2-web
spec:
containers:
- name: hello-v2
image: gcr.io/google-samples/hello-app:2.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello-v2-service
spec:
type: ClusterIP
selector:
app: v2-web
ports:
- protocol: TCP
port: 8080
targetPort: 8080
// save above yaml manifest as hello-v2.yaml and run below command
$ kubectl apply -f hello-v2.yaml
deployment.apps/hello-v2-deployment created
service/hello-v2-service created
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-ingress
spec:
rules:
- host: shop.com
http:
paths:
- path: /product
backend:
serviceName: hello-v1-service
servicePort: 8080
- path: /order
backend:
serviceName: hello-v2-service
servicePort: 8080
// create an ingress resource
$ kubectl apply -f hello-ingress.yaml
ingress.extensions/hello-ingress created
// get an ingress details
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-ingress <none> shop.com localhost 80 73s
// open windows host file (C:\Windows\System32\drivers\etc) and map shop.com to localhost
127.0.0.1 shop.com
// make curl command to shop.com/product to get hello-v1 app details
$ curl shop.com/product
Hello, world!
Version: 1.0.0
Hostname: hello-v1-deployment-855c95579b-d99pp
// make curl command to shop.com/order to get hello-v2 app details
$ curl shop.com/order
Hello, world!
Version: 2.0.0
Hostname: hello-v2-deployment-5fc58f68df-hwgxx
Create an Ingress YAML manifest to expose multiple services on sub domains
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-ingress
spec:
rules:
- host: product.shop.com
http:
paths:
- path: /
backend:
serviceName: hello-v1-service
servicePort: 8080
- host: order.shop.com
http:
paths:
- path: /
backend:
serviceName: hello-v2-service
servicePort: 8080
// create an ingress resource to map multiple sub domains
$ kubectl apply -f hello-multi-domain-ingress.yaml
ingress.extensions/hello-ingress created
// get an ingress details
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-ingress <none> product.shop.com,order.shop.com 80 6s
// open windows host file (C:\Windows\System32\drivers\etc) and map shop.com to localhost
127.0.0.1 product.shop.com
127.0.0.1 order.shop.com
// make curl command to product.shop.com to get hello-v1 app details
$ curl product.shop.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1-deployment-855c95579b-d99pp
// make curl command to order.shop.com to get hello-v2 app details
$ curl order.shop.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2-deployment-5fc58f68df-hwgxx
Kubernetes for Developers Journey.
- Kubernetes for Developers #25: PersistentVolume and PersistentVolumeClaim in-detail
- Kubernetes for Developers #24: Kubernetes Volume hostPath in-detail
- Kubernetes for Developers #23: Kubernetes Volume emptyDir in-detail
- Kubernetes for Developers #22: Access to Multiple Clusters or Namespaces using kubectl and kubeconfig
- Kubernetes for Developers #21: Kubernetes Namespace in-detail
- Kubernetes for Developers #20: Create Automated Tasks using Jobs and CronJobs
- Kubernetes for Developers #19: Manage app credentials using Kubernetes Secrets
- Kubernetes for Developers #18: Manage app settings using Kubernetes ConfigMap
- Kubernetes for Developers #17: Expose service using Kubernetes Ingress
- Kubernetes for Developers #16: Kubernetes Service Types - ClusterIP, NodePort, LoadBalancer and ExternalName
- Kubernetes for Developers #15: Kubernetes Service YAML manifest in-detail
- Kubernetes for Developers #14: Kubernetes Deployment YAML manifest in-detail
- Kubernetes for Developers #13: Effective way of using K8 Readiness Probe
- Kubernetes for Developers #12: Effective way of using K8 Liveness Probe
- Kubernetes for Developers #11: Pod Organization using Labels
- Kubernetes for Developers #10: Kubernetes Pod YAML manifest in-detail
- Kubernetes for Developers #9: Kubernetes Pod Lifecycle
- Kubernetes for Developers #8: Kubernetes Object Name, Labels, Selectors and Namespace
- Kubernetes for Developers #7: Imperative vs. Declarative Kubernetes Objects
- Kubernetes for Developers #6: Kubernetes Objects
- Kubernetes for Developers #5: Kubernetes Web UI Dashboard
- Kubernetes for Developers #4: Enable kubectl bash autocompletion
- Kubernetes for Developers #3: kubectl CLI
- Kubernetes for Developers #2: Kubernetes for Local Development
- Kubernetes for Developers #1: Kubernetes Architecture and Features
Happy Coding :)