Get an External IP for Kubernetes Services | On-Prem

External IP for Kubernetes Services

Learn how to get an external IP for Kubernetes services on premises or in your homelab environment with tools like MetalLB, NodePort, and NGINX Ingress controller. Discover straightforward methods to assign external IPs and manage external access to your Kubernetes cluster.

Table of Contents

Introduction

Setting up a Kubernetes cluster on-premises (on-prem) or in a homelab environment can be a great way to learn and experiment with Kubernetes. However, one of the common challenges is exposing your services to the outside world. While cloud providers offer built-in solutions for external IP addresses, doing this on-prem or in a homelab requires a different approach. In this guide, we will explore various methods to get an external IP for your Kubernetes services in an on-prem setup. These methods include using MetalLB, NodePort, and an Ingress controller.

Using MetalLB for External IPs

MetalLB is a popular choice for providing LoadBalancer services in on-premises Kubernetes clusters. It allows you to assign external IPs to your services, just like in cloud environments.

External IP for Kubernetes Services

Photo by admingeek from Infotechys

Installing MetalLB

First, you need to install MetalLB. Apply the following commands to deploy MetalLB in your cluster:

				
					kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml
				
			
				
					namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/addresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
...omitted for brevity...
				
			

Create a configuration map for MetalLB

You’ll need to specify a pool of IP addresses that MetalLB can use for services. Create a file named metallb-config.yaml with the following content:

				
					vim metallb-config.yaml
				
			

Copy and paste the following in the file:

				
					apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.240-192.168.1.250
				
			

Apply this configuration:

				
					kubectl apply -f metallb-config.yaml
				
			
				
					configmap/config created
				
			

Exposing a Service Using MetalLB

Now, you can expose a service using the LoadBalancer type. Create a service definition file named my-service.yaml:

				
					apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer
				
			

Apply the service definition:

				
					kubectl apply -f my-service.yaml
				
			
				
					service/my-service created
				
			

Check the service status to see the assigned external IP:

				
					kubectl get svc my-service
				
			
				
					NAME         TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)        AGE
my-service   LoadBalancer   10.111.84.63   192.168.1.242     80:31252/TCP   47m
				
			

Now, you will see that the EXTERNAL-IP status is 192.168.1.242, which can be accessed directly from outside the cluster without using NodePort or ClusterIP. Keep in mind that this IP, 192.168.1.242, is not assigned to any specific node. In this example, the service can be accessed via http://192.168.1.242.

Using NodePort for External Access

If you prefer not to use MetalLB, another option is to expose your service using the NodePort service type. This method will open a specific port on all nodes in your cluster, allowing external access.

Exposing a Service Using NodePort

Edit your service definition to use NodePort. Create a file named my-service-nodeport.yaml:

				
					apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30007
  type: NodePort

				
			

Apply service definition:

				
					kubectl apply -f my-service-nodeport.yaml
				
			
				
					service/my-service configured
				
			

Access the service via NodeIP and NodePort:

				
					kubectl get svc my-service
				
			
				
					NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-service   NodePort   10.111.84.63   <none>        80:30007/TCP   65m
				
			

Your service will be accessible at http://<NodeIP>:30007. For example, if a node’s IP is 192.168.1.100, you can access the service at http://192.168.1.100:30007.

Using Ingress for Advanced Routing

For more complex setups or when managing multiple services, using an Ingress controller can be very effective. NGINX Ingress controller is a popular choice for on-premises environments.

Installing NGINX Ingress Controller

Deploy the NGINX Ingress controller in your cluster:

				
					kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
				
			
				
					namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
...omitted for brevity...
				
			

Creating an Ingress Resource

Create an Ingress resource to route traffic to your service. Save the following content to a file named my-ingress.yaml:

				
					apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

				
			

Apply the Ingress resource:

				
					kubectl apply -f my-ingress.yaml
				
			

Configuring DNS

Update your DNS or /etc/hosts file to point to the IP of the Ingress controller. For example, add the following line to your /etc/hosts file:

				
					192.168.1.100 myapp.local
				
			

For on-premises or homelab Kubernetes clusters, using MetalLB to assign external IPs or using NodePort to expose services on node IPs and specific ports are common approaches. Additionally, setting up an Ingress controller provides more flexibility in managing external access to multiple services.

Conclusion

Exposing Kubernetes services in an on-prem or homelab environment can be challenging but manageable with the right tools. MetalLB offers a straightforward way to assign external IPs, while NodePort provides a simpler but less flexible method. Using an Ingress controller like NGINX can give you advanced routing capabilities and the ability to manage multiple services behind a single external IP.

By following these methods, you can effectively manage external access to your Kubernetes services in an on-premises or homelab setup. Each approach has its advantages, so choose the one that best fits your needs and infrastructure.

Did you find this article useful? Your feedback is invaluable to us! Please feel free to share your thoughts in the comments section below.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *