#
Create a service with an external IP
This tutorial explains how we can expose a service in Kubernetes using a specific IP.
#
Services - introduction
The pods don't have stable IPs and this is a problem for an external service to call the services inside pods.
A Kubernetes service group the pods (by using labels and selectors) and give them a fix
- IP
- DNS name
- port
We can access the services inside these pods through this service, which acts as a load balancer as well. Each Service that is created, automatically gets an associated Endpoint object. This Endpoint object is a dynamic list of all the healthy Pods on the cluster that match the Service’s label selector.
The services could be of several types:
- ClusterIP
- NodePort
- LoadBalancer
ClusterIP service type
(the default service type)
All the services inside cluster can communicate by using the Cluster IP (or the name of the cluster which is resolved to the Cluster IP). This IP address is accessible only inside Kubernetes cluster.
#
NodePort Service - introduction
NodePort service type
The NodePort Service type add a new layer over the ClusterIP Service type. This layer let you access the service on each node on a particular port (defined during the NodePort service definition).
With this type of service, you can access the services we have in pods by using node_ip:nodePort, where node_ip is the IP of any node, and nodePort is a port defined during the service definition. If there are multiple nodes, then multiple IP addresses with the same port will be exposed.
Info
The request to the node_ip:nodePort will be redirected to ClusterIP:clusterPort of the service and the service will decide which pod will serv your request.
#
Create a NodePort service
The following example is has a prerequisite the Deployment from Create, View and Destroy a Deployment
Now we can create the yaml file for creating the new service:
kind: Service
apiVersion: v1
metadata:
name: http-server-service2
spec:
# This service works only with pods labeled as below
selector:
app: app1
ports:
- name: http
protocol: TCP
port: 8081 # On the clusterIP level (for inter-pods communication) & for external IP
targetPort: 80 #On the pod level
externalIPs:
- 192.168.72.3
The following command will create the new service:
kubectl apply -f my-first-service-with-external-ip.yml
We can run the following command in order to see if the new service is created:
kubectl get services
Here is the result:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
http-server-service2 ClusterIP 10.105.247.113 192.168.72.3 8081/TCP 4s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d4h
If you want to get more information on "http-server-service" service you can run:
kubectl describe service http-server-service2
Here is the result:
Name: http-server-service2
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=app1
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.105.247.113
IPs: 10.105.247.113
External IPs: 192.168.72.3
Port: http 8081/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.26:80,10.244.0.27:80,10.244.0.30:80 + 1 more...
Session Affinity: None
Events: <none>
If you want to test that the service is accessible, you can on a machine which
has access to 192.168.72.3 virtual IP and run the command curl 192.168.72.3:8081
:
curl 192.168.72.3:8081
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
IF you want to see the nodes IPs, you can run the following command:
kubectl get nodes -o wide
Here is the result in my case:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
minikube Ready control-plane 4d4h v1.26.1 192.168.49.2 <none> Ubuntu 20.04.5 LTS 5.10.16.3-microsoft-standard-WSL2 docker://20.10.23
#
Delete a Service in Kubernetes
Delete the service created above:
kubectl delete service http-server-service2