Exposing Kubernetes workloads
Kubernetes offers several types of Services to expose workloads:
ClusterIP (Default): Exposes the Service only within the cluster. It’s not accessible from the outside.
NodePort: Exposes the Service on each Node’s IP at a static port. It’s accessible from outside the cluster using
<NodeIP>:<NodePort>
.LoadBalancer: Exposes the Service externally using a cloud provider's load balancer. It’s accessible via the load balancer’s external IP.
ExternalName: Maps the Service to the contents of the
externalName
field (e.g., a DNS name).
Using NodePort service
Note that the NodePort Service has a lot of downsides:
you can only have one service per port
you can only use ports 30000–32767,
if your Node/VM IP address changes, you need to deal with that.
Running nginx application using deployment.
Deploy a simple Nginx application,
Create POD using
deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- Apply
deployment.yml
file,
kubectl apply -f deployment.yml
- Create service for the application using
service.yml
file,
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30001
- Apply
services.yml
file,
kubectl apply -f service.yml
- Verify service status,
kubectl get svc -o wide
- Expose port to access application on browser,
kubectl port-forward svc/nginx-service 8081:80 --address=0.0.0.0 &
- Now try to access,
Discover Services and Pods within a Kubernetes cluster using DNS
Service Discovery Using DNS
Let’s start by deploying a simple Service,
- Create deployment and service and apply both of them,
# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: hashicorp/http-echo:0.2.3
args:
- "-text=Hello, Kubernetes!"
ports:
- containerPort: 5678
# service.yml
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
namespace: default
spec:
selector:
app: hello-world
ports:
- protocol: TCP
port: 80
targetPort: 5678
- Apply both files,
kubectl apply -f deployment.yml
kubectl apply -f service.yml
- Test deployment and service at once,
kubectl get all
Discover the Service Using DNS,
You can resolve the Service DNS name from within any Pod in the same namespace. Deploy a test Pod,
kubectl run -it --rm --image=busybox dns-test -- /bin/sh
- Within this Pod, you can use the
nslookup
ordig
command to resolve the Service name,
nslookup hello-world-service.default.svc.cluster.local
Pod Discovery Using DNS
- Step 1 : Enable Headless Service
To discover individual Pods, you should create a Headless Service by setting clusterIP: None
,
apiVersion: v1
kind: Service
metadata:
name: hello-world-headless
namespace: default
spec:
clusterIP: None
selector:
app: hello-world
ports:
- protocol: TCP
port: 80
targetPort: 5678
- Apply file,
kubectl apply -f dns-headless.yml
- Step 2 : Discover Pods Using DNS
Test DNS Resolution Inside a Pod,
Use a test Pod to check DNS resolution. Let’s use a busybox
Pod for this,
kubectl run -it --rm --image=busybox dns-test -- /bin/sh
Inside the shell of the dns-test
Pod, use the nslookup
command to try to resolve the Headless Service and Pods,
nslookup hello-world-headless.default.svc.cluster.local
This will return a list of IP addresses, each corresponding to a Pod running under the hello-world
deployment.
Connect With Me
Thank you for reading. I hope you were able to understand and learn something new from my blog.
Happy Learning!