Configuring MetalLB and NGINX for Federal Frontier API Services
Understanding the Networking in Kubernetes with MetalLB and NGINX Ingress
Last updated: October 10, 2022 by Jeremy Estrada
Setup Environment
Kubernetes Configuration
To get started, ensure that Kubernetes has been config into your local machine. An example would be:
export KUBECONFIG=~/.kube/bamboo-config.yaml
Application Service Port Setup
Once you have configured Kubernetes in your local machine, you would want to start choosing which application you would like to implement an ingress controller on. For this example, I will be utilizing Federal Frontier API Services. Therefore, within Kubernetes, you would want to make sure the application is able to serve ports. For Federal Frontier at the time of this documentation, it is built to serve on port 8080.
Create Namespaces
You will want to create two namespaces within Kubernetes. One will be for MetalLB and the other will be for Ingress-NGINX.
kubectl create namespace metallb-system
kubectl create namespace ingress-nginx
With these creations, we will install each of the two within their respective namespaces.
Install Metallb
You can install MetalLB through a couple commands. We will be doing this installation through Helm3. If Helm3 is not installed, be sure to visit their installation page from their documentation website.
Step 1: Begin by navigating into the metallb-system Kubernetes namespace. Be sure kubectx into your local machine.
kubens metallb-system
Step 2: Once you’re in the metallb-system namespace, add MetalLB into your Helm repository.
helm repo add metallb https://metallb.github.io/metallb
Step 3: After the download is complete, install MetalLB into Kubernetes.
helm install metallb metallb/metallb
Install Ingress-NGINX
For Ingress-NGINX installation, we will be using Helm3 similarily utilized when installing MetalLB.
Step 1: Begin by now navigating into the ingress-nginx Kubernetes namespace.
kubens ingress-nginx
Step 2: Once you’re in the ingress-nginx namespace, add Ingress-NGINX into your Helm repository.
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Step 3: Update the chart repo.
helm repo update
Step 4: After all downloads and updates are complete, install Ingress-NGINX into Kubernetes.
helm install ingress-controller ingress-nginx/ingress-nginx
NOTE: If you wish to use a different helm release name other than ingress-controller from the command above, you must mirror this change to all other locations where the helm release name resides throughout this tutorial.
Configure MetalLB and Ingress-NGINX for Services
The figure above demonstrates a diagram over the implemenation of MetalLB and Ingress-NGINX for back-end services (for this example: Federal Frontier API Services). Configuration for Ingress-NGINX depends on MetalLB Load Balancer when you are configuring ingress on-premise. All of these components rely on IPAddressPool. In order to advertise the IP coming from an IPAddressPool, an L2Advertisement instance must be associated to the IPAddressPool. In these next steps, we will establish the IPAddressPool for communication between MetalLB and Ingress-NGINX.
Step 1: Navigate to the metallb-system namespace within Kubernetes.
kubens metallb-system
Step 2: Within your local machine, create a ipaddpool-config.yaml and paste this manifest. Note: You can name the .yaml file to your preference.
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2-ip
namespace: metallb-system
spec:
ipAddressPools:
- single-ip
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: single-ip
namespace: metallb-system
spec:
addresses:
- 192.168.1.254/32
Step 3: Apply this manifest into Kubernetes within your metallb-system namespace.
kubectl apply -f idaddpool-config.yaml
Step 4: Get ipaddresspool within your metallb-system Kubernetes namespace to confirm the address pool configuration.
kubectl get ipaddresspool -n metallb-system
Step 5: Navigate to your ingress-nginx Kubernetes namespace to begin configuration for Ingress-NGINX with MetalLB Load Balancer.
kubens ingress-nginx
Step 6: Within your local machine, create a nginx-service.yaml and paste this manifest. Note: You can name the .yaml file to your preference.
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: ingress-controller
meta.helm.sh/release-namespace: ingress-nginx
metallb.universe.tf/address-pool: single-ip
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-controller
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.3.0
helm.sh/chart: ingress-nginx-4.2.1
name: ingress-controller-ingress-nginx-controller
namespace: ingress-nginx
spec:
externalTrafficPolicy: Local
ports:
- name: http
port: 8080
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-controller
app.kubernetes.io/name: ingress-nginx
sessionAffinity: None
type: LoadBalancer
Step 7: Apply this manifest into Kubernetes within your ingress-nginx namespace.
kubectl apply -f nginx-service.yaml
Step 8: Confirm changes by getting your service in your ingress-controller in a yaml format to find metallb.universe.tf/address-pool: single-ip within metadata annotations. You can run the following command below to view the yaml of the service.
kubectl get svc ingress-controller-ingress-nginx-controller -o yaml
Step 9: By this step, when you get the services within your ingress-nginx Kubernetes namespace, you should receive an output such as this response below.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-controller-ingress-nginx-controller LoadBalancer 10.107.123.3 <pending> 8080:32402/TCP,443:32702/TCP 2d
Notice EXTERNAL-IP is still in a pending state. To allow the service to find and connect to an external IP, you will need to configure ingress to your application within Kubernetes. Start by navigating to your application’s namespace. For this example, we will navigate to Federal Frontier API Services’ Kubernetes namespace.
kubens frontier
Step 10: Within your local machine, create a ingress-app-config.yaml and paste these contents inside of your manifest. Note: You can name the .yaml file to your preference.
NOTE: Keep in mind, you will need to have a host domain available in order to apply this manifest to utilize Ingress-NGINX.
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"creationTimestamp":"2022-08-05T21:08:12Z","generation":1,"name":"federal-frontier-api-service","namespace":"frontier","resourceVersion":"35503249","uid":"2a599a8c-f831-4298-9267-914d8cf42814"},"spec":{"rules":[{"host":"fas.eupraxialabs.com","http":{"paths":[{"backend":{"service":{"name":"frontier-api","port":{"number":8080}}},"path":"/","pathType":"ImplementationSpecific"}]}}]}}
kubernetes.io/ingress.class: nginx
creationTimestamp: "2022-08-05T21:08:12Z"
generation: 8
name: federal-frontier-api-service
namespace: frontier
resourceVersion: "36083984"
uid: 2a599a8c-f831-4298-9267-914d8cf42814
spec:
rules:
- host: fas.eupraxialabs.com
http:
paths:
- backend:
service:
name: frontier-api
port:
number: 8080
path: /
pathType: ImplementationSpecific
status:
loadBalancer:
ingress:
- ip: 192.168.1.254
kind: List
metadata:
resourceVersion: ""
Step 11: Apply this manifest into Kubernetes within your application’s namespace.
kubectl apply -f ingress-app-config.yaml
Step 12: Confirm these changes by inputting this command within your application’s Kubernetes namespace.
kubectl get ingress
Step 13: With all the configurations you made within Kubernetes throughout these steps, you should now possess and external IP for your ingress controller service within your ingress-nginx Kubernetes namespace. Confirm by inputting the command below. You should be able to see a similar response such as that provided in this example.
kubectl get svc ingress-controller-ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-controller-ingress-nginx-controller LoadBalancer 10.107.123.3 192.168.1.254 8080:32402/TCP,443:32702/TCP 2d
If you no longer see your external IP in a pending state and your service has been configured to your desired address, then congratulations! You are now finished with configuring MetalLB and Ingress-NGINX to your application in Kubernetes!