A, Headless Service

Sometimes load balancing and a separate Service IP are not required or desired. In this case, you can create a Headless Service by specifying the Cluster IP (spec.clusterIP) value to “None”. Headless services do not assign Cluster IP, Kube-proxy does not process them, and the platform does not load balance and route them.

How DNS is automatically configured depends on whether the Service defines a selection operator. (1) For A headless Service with A selection operator defined for A Service with A selection operator, the Endpoint controller creates Endpoints records in the API and modifiers the DNS configuration to return A record (address), which directly reaches the back-end Pod of the Service. 1) For headless services that do not have a selection operator defined, the Endpoint controller does not create Endpoints records. However, the DNS system will look up and configure whether: for a service of type ExternalName, look up its CNAME record.

2) For all other types of services, find records for any Endpoints with the same name as the Service.

Headless services (with no cluster IP) can also be assigned A DNS A or AAAA record in the form of A name like my-svc.my-namespace.svc.cluster-domain-example. Unlike normal services, this record is resolved to the IP of the Pod collection selected by the corresponding service. Clients need to be able to use this set of IP addresses or choose from this set using a standard rotation policy.

Next, two Headless services will guide readers to understand its features.

(1) In example 1, we will implement a Headless service with a selection operator to verify its characteristics.

(2) In example 2, we will implement a Headless service with no selection operator to verify its characteristics.

In example 1, we create a service nginx-service-headless with a label selector.

The first step is to edit a yamL file for a headless Service. The only difference between the Service definition and the previous one is that a property clusterIP: None has been added. The definition of Deployment is the same as the previous one.

apiVersion: v1 kind: Service metadata: name: nginx-service-headless spec: ports: - port: 80 protocol: TCP targetPort: 80 clusterIP: None # Selector: app: nginx # Selector: app: nginx ClusterIP # ClusterIP -- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: Nginx replicas: 3 # tells Deployment how many Pod instances are running. # Pod template metadata: labels: app: nginx # Pod tag spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80Copy the code

The second step is to apply the YAML file and create the corresponding Service and Pod resources.

kubectl apply -f 2-service-headless.yaml

The CLUSTER IP of Service nginx-service-headless is None, as shown in the figure.

[root@kubernetes-master01 service]# kubectl get all NAME READY STATUS RESTARTS AGE pod/nginx-deployment-6b474476c4-27gqr  1/1 Running 0 4m29s pod/nginx-deployment-6b474476c4-6w5zl 1/1 Running 0 4m29s pod/nginx-deployment-6b474476c4-ww74l 1/1  Running 0 4m29s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx-service-headless ClusterIP None <none> 80/TCP 4m29s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 3/3 3 3 4m29s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-6b474476c4 3 3 3 4m29sCopy the code

Service nginx-service-headless = nginx-service-headless = nginx-service-headless = nginx-service-headless = nginx-service-headless

[root@kubernetes-master01 service]# kubectl describe service nginx-service-headless Name: nginx-service-headless Namespace: default Labels: <none> Annotations: Selector: app=nginx Type: ClusterIP IP: None Port: < the unset > 80 / TCP and TargetPort: 80 / TCP Endpoints: 10.244.1.51:80,10.244. 1.52:80,10.244. 2.20:80 Session Affinity: None Events: <none> [root@kubernetes-master01 service]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE Nginx-deployment-6b474476c4-27gqr 1/1 Running 0 7m47s 10.244.2.20 Nginx-deployment-6b474476C4-6w5zl 1/1 Running 0 7m47s Nginx-deployment-6b474476c4-ww74l 1/1 Running 0 7m47s 10.244.1.51Copy the code

Step 5: Randomly log in to a Pod and check the DNS records. The result is shown in the figure, which shows the IP of all associated pods behind. Users need to select the specific Pod to access according to the situation.

Sh-4.4 # nslookup nginx-service-headless Server: 10.96.0.10 Address: 10.96.0.10#53 Name: Nginx - service - headless. Default. SVC. Cluster. The local Address: 10.244.1.51 Name: Nginx - service - headless. Default. SVC. Cluster. The local Address: 10.244.2.20 Name: Nginx - service - headless. Default. SVC. Cluster. The local Address: 10.244.1.52Copy the code

For the second example, create a Headless service with no label selectors.

Services most commonly abstract access to Kubernetes Pods, but they can also abstract other kinds of backends. Example: (1) You want to use an external database cluster in your production environment, but your test environment uses your own database. (2) You want the service to point to a service in another Namespace or another cluster. (3) You are migrating your workload to Kubernetes. When evaluating this method, you only run part of the back end in Kubernetes. In any of these scenarios, it is possible to define a Service without a selection operator. Example:

apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - port: 80 protocol: TCP targetPort: 80 clusterIP: None # Headless Service type: ClusterIP # The Service type is ClusterIPCopy the code

Because this service does not select an operator, the corresponding Endpoint object is not automatically created. We can manually add an Endpoint object to map the service to the network address and port where the service runs. The metadata. Name field in Endpoints of the resource object must be the name of the service we define.

ApiVersion: v1 kind: Endpoints Metadata: name: my-service subsets: -addresses: -ip: 10.20.40.150 ports: -port: 80Copy the code

Note: (1) Endpoint IPs must not be: Local loop (127.0.0.0/8 for IPv4, ::1/128 for IPv6) or local link (169.254.0.0/16 and 224.0.0.0/24 for IPv6, FE80 ::/64 for IPv6). (2) The endpoint IP address cannot be the cluster IP of another Kubernetes service, because Kube-Proxy does not support virtual IP as the target. (3) Accessing a Service without a selector operator is the same as accessing a Service with a selector operator. Requests are routed to the user-defined Endpoint, which in YAML is 10.20.40.150:80 (TCP).

The Endpoints of the headless Service are already mounted to the 10.20.40.150:80 Service.

[root@kubernetes-master01 service]# kubectl describe service my-service Name: my-service Namespace: default Labels: <none> Annotations: Selector: <none> Type: ClusterIP IP: None Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.20.40.150:80 Session Affinity: None Events: < None >Copy the code

Two, guess you like

If you are interested in learning more about containerization, you can read the Kubernetes column on Beautiful Containerization

Features of this column:

  • Combining theory with practice
  • The explanation is simple and simple