Let's define a simple Service:
$ vi hello-nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-nginx
spec:
type: ClusterIP # this's default if the field type is skipped
ports:
- port: 80
targetPort: 80 # this defaults to the Port's value if the field targetPort is skipped
protocol: TCP # this's the default if the field protocol is skipped
selector: # the Service's selector verifies Pods that define all its labels
app: hello-nginx
The Service defines a Selector (spec.
selector): "app=hello-nginx"
Pods that have all the labels defined in the Service's Selector will be selected.
Let's apply now the Service:
$ kubectl apply -f hello-nginx-service.yaml
service/hello-nginx created
Check the Service:
$ kubectl get service hello-nginx -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
hello-nginx ClusterIP 10.109.87.124 <none> 80/TCP 11m app=hello-nginx
In the bellow Deployment example, the Pods will be selected because they define (spec.template.metadata.
labels) the label "app=hello-nginx".
The other labels of the Pods ("product=mtitek", "stage=dev") are not considered.
Let's define a simple deployment:
$ vi hello-nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-nginx
spec:
replicas: 2
selector:
matchLabels:
app: hello-nginx
template:
metadata:
labels: # a subset of the Pod's labels must match the Service's selector
app: hello-nginx
product: mtitek
stage: dev
spec:
containers:
- name: hello-nginx
image: nginx:latest
ports:
- containerPort: 80
Let's apply the Deployment:
$ kubectl apply -f hello-nginx-deployment.yaml
deployment.apps/hello-nginx created
Verify that Pods are running and ready (note the IP addresses of each Pod):
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hello-nginx-5d77cc88f4-gj6k2 1/1 Running 0 13m 10.1.0.157 docker-desktop <none> <none>
hello-nginx-5d77cc88f4-pz9dj 1/1 Running 0 13m 10.1.0.156 docker-desktop <none> <none>
Let's validate the Service (note that the Endpoints field contains the Pods' IP addresses):
$ kubectl describe service hello-nginx
Name: hello-nginx
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=hello-nginx # list of labels that Pods must define so they can bed added to the Service's Endpoints
Type: ClusterIP
IP: 10.109.87.124 # clusterIP address (internal) of the Service
Port: <unset> 80/TCP # the port that the Service listens on inside the cluster
TargetPort: 80/TCP # the port that the Pods are listening on
Endpoints: 10.1.0.156:80,10.1.0.157:80 # list of Pods (IP addresses) that are healthy and their labels match the service's label selector
Session Affinity: None
Events: <none>
Check the Endpoints object of the Service (note the ENDPOINTS column):
$ kubectl get endpoints hello-nginx
NAME ENDPOINTS AGE
hello-nginx 10.1.0.156:80,10.1.0.157:80 23m
Describe the Endpoints object of the Service (note the Addresses field):
$ kubectl describe endpoints hello-nginx
Name: hello-nginx
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-06-06T10:31:11Z
Subsets:
Addresses: 10.1.0.156,10.1.0.157
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 80 TCP
Events: <none>
To access the service from inside the cluster:
$ kubectl exec -ti hello-nginx-5d77cc88f4-gj6k2 -- bash
root@hello-nginx-5d77cc88f4-gj6k2:/# curl -I -X GET 10.109.87.124:80
HTTP/1.1 200 OK
Server: nginx/1.21.0
Date: Wed, 06 Jun 2021 02:52:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 25 May 2021 12:28:56 GMT
Connection: keep-alive
ETag: "60aced88-264"
Accept-Ranges: bytes
root@hello-nginx-5d77cc88f4-gj6k2:/#