ClusterIP

ClusterIP is the default Service type. It exposes the Service on a cluster-internal IP. Pods in the cluster could reach the Service via the IP address, environment variables, or DNS. In the following example, we'll learn how to use both native Service environment variables and DNS to access the pods behind Services in the cluster.

Before starting a Service, we'd like to create two sets of RS with different version labels, as follows:

// create RS 1 with nginx 1.12.0 version
# cat 3-2-3_rs1.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-1.12
spec:
replicas: 2
selector:
matchLabels:
project: chapter3
service: web
version: "0.1"
template:
metadata:
name: nginx
labels:
project: chapter3
service: web
version: "0.1"
spec:
containers:
- name: nginx
image: nginx:1.12.0
ports:
- containerPort: 80

// create RS 2 with nginx 1.13.1 version
# cat 3-2-3_rs2.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-1.13
spec:
replicas: 2
selector:
matchLabels:
project: chapter3
service: web
version: "0.2"
template:
metadata:
name: nginx
labels:
project: chapter3
service: web
version: "0.2"
spec:
containers:
- name: nginx
image: nginx:1.13.1
ports:
- containerPort: 80

Then, we could make our pod selector, targeting project and service labels:

// simple nginx service 
# cat 3-2-3_service.yaml
kind: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
selector:
project: chapter3
service: web
ports:
- protocol: TCP
port: 80
targetPort: 80
name: http

// create the RSs
# kubectl create -f 3-2-3_rs1.yaml
replicaset.apps/nginx-1.12 created
# kubectl create -f 3-2-3_rs2.yaml
replicaset.apps/nginx-1.13 created
// create the service
# kubectl create -f 3-2-3_service.yaml
service "nginx-service" created
Since a Service object might create a DNS label, the service name must be a combination of alphanumeric characters and hyphens. A hyphen at the beginning or end of a label isn't allowed.

We can then use kubectl describe service <service_name> to check the Service information:

// check nginx-service information
# kubectl describe service nginx-service
Name: nginx-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: project=chapter3,service=web
Type: ClusterIP
IP: 10.0.0.188
Port: http 80/TCP
Endpoints:    172.17.0.5:80,172.17.0.6:80,172.17.0.7:80 + 1 more...
Session Affinity: None
Events: <none>
One Service could expose multiple ports. Just extend the .spec.ports list in the service spec.

We can see that it's a ClusterIP type Service and its assigned internal IP is 10.0.0.188. The endpoints show that we have four IPs behind the Service. The pod IPs can be found by the kubectl describe pods <pod_name> command. Kubernetes creates an endpoints object along with a service object to route the traffic to the matching pods.

When the Service is created with selectors, Kubernetes will create corresponding endpoint entries and keep updating, which will indicate the destination that the Service routes to:

// list current endpoints. Nginx-service endpoints are created and pointing to the ip of our 4 nginx pods.
# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 10.0.2.15:8443 2d nginx-service 172.17.0.5:80,172.17.0.6:80,172.17.0.7:80 + 1 more... 10s
The ClusterIP could be defined within your cluster, though most of the time we don't explicitly use the IP address to access clusters. Using .spec.clusterIP can do this for us.

By default, Kubernetes will expose seven environment variables for each Service. In most cases, the first two allow us to use the kube-dns add-on to carry out service discovery for us:

  • ${SVCNAME}_SERVICE_HOST
  • ${SVCNAME}_SERVICE_PORT
  • ${SVCNAME}_PORT
  • ${SVCNAME}_PORT_${PORT}_${PROTOCAL}
  • ${SVCNAME}_PORT_${PORT}_${PROTOCAL}_PROTO
  • ${SVCNAME}_PORT_${PORT}_${PROTOCAL}_PORT
  • ${SVCNAME}_PORT_${PORT}_${PROTOCAL}_ADDR

In the following example, we'll use ${SVCNAME}_SERVICE_HOST in another pod to check whether we can access our nginx pods:

Accessing ClusterIP via environment variables and DNS names

We'll then create a pod called clusterip-chk to access nginx containers via nginx-service:

// access nginx service via ${NGINX_SERVICE_SERVICE_HOST}
# cat 3-2-3_clusterip_chk.yaml
apiVersion: v1
kind: Pod
metadata:
name: clusterip-chk
spec:
containers:
- name: centos
image: centos
command: ["/bin/sh", "-c", "while : ;do curl

http://${NGINX_SERVICE_SERVICE_HOST}:80/; sleep 10; done"]

We can check stdout of the cluserip-chk pod via the kubectl logs command:

// check stdout, see if we can access nginx pod successfully
# kubectl logs -f clusterip-chk
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed
100 612 100 612 0 0 156k 0 --:--:-- --:--:-- --:--:-- 199k ... <title>Welcome to nginx!</title> ...

This abstraction level decouples the communication between pods. Pods are mortal. With RS and Services, we can build robust services without worrying about whether one pod will influence all microservices.

With the DNS server enabled, the pods in the same cluster and the same namespace as the Services can access Services via their DNS records.

CoreDNS GA was introduced in Kubernetes 1.11 and is now the default option in Kubernetes. Before this, the kube-dns add-on was in charge of DNS-based service discovery

The DNS server creates DNS records for newly created services by watching the Kubernetes API. The DNS format for the cluster IP is $servicename.$namespace and the port is _$portname_$protocal.$servicename.$namespace. The spec of the clusterip_chk pod will be similar to the environment variables one. Change the URL to http://nginx-service.default:_http_tcp.nginx-service.default/ in our previous example, and they should work exactly the same.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset