A Service profile

1.1 the Service concept

Service is the core concept of Kubernetes. By creating a Service, you can provide a unified entry address for a group of container applications with the same function, and distribute the request load to each container application at the back end.

1.2 Service Definition

1 apiVersion: v1 # mandatory, API version 2 Kind: Service # mandatory, type: Service 3 Metadata: # mandatory, name: string # mandatory, Service name 5 Namespace: Annotations: string # Mandatory, namespaces, default = default 6 labels: # Tags = 0 annotations: 11 Selector: [] # selector: [] # selector: [] # selector: [] # selector: [] String # Virtual service IP address. If type=ClusterIP is selected, the system automatically allocates the virtual service IP address. 14 ports: #Service Specifies the list of ports to be exposed when type=LoadBalancer. 15 - name: string Port: int # port number that the service listens to 18 targetPort: 8080 # port number that needs to be forwarded to the back-end Pod 19 nodePort: Int # if spec.type=NodePort, specify the port number to be mapped to the physical machine 20 status: Ingress 23 IP: string # IP address of the external load balancer 24 hostname: string # hostname of the external load balancerCopy the code

Spec. type: Specifies the Service type. The default value is ClusterIP.

  • ClusterIP: virtual service IP address. This IP address is used for Pod access within the Kubernetes cluster. Kube-proxy forwards nodes using the iptables rules.
  • NodePort: Uses the host port to enable external clients that can access each Node to access services using the IP address and port number of the Node.
  • LoadBalancer: specifies the IP address of the external LoadBalancer in the spec.status. LoadBalancer field and defines nodePort and clusterIP for the public cloud.

Service Basic usage

2.1 Basic Usage of Service

Generally speaking, external service applications need to be implemented through some mechanism. The easiest way for containers is through TCP/IP mechanism and listening IP and port number.

Example: Define an RC that provides a Web service, consisting of two copies of Tomcat containers, each with port number 8080 set to provide the service through containerPort.

[root@k8smaster01 study]# cat webapp-rc.yaml
Copy the code
  1 apiVersion: v1
  2 kind: ReplicationController
  3 metadata:
  4   name: webapp
  5 spec:
  6   replicas: 2
  7   template:
  8     metadata:
  9       name: webapp
 10       labels:
 11         app: webapp
 12     spec:
 13       containers:
 14       - name: webapp
 15         image: tomcat
 16         ports:
 17         - containerPort: 8080
Copy the code

[root@k8smaster01 study]# kubectl create -f webapp-rc.yaml

[root@k8smaster01 study]# kubectl get pods -l app=webapp -o yaml | grep podIP

PodIP: 172.24.9.88

PodIP: 172.24.9.199

[root @ k8smaster01 study] # curl 172.24.9.88:8080

Directly through the Pod IP address and port number can access the container application services, but the Pod IP address is not reliable, for example, when the Pod Node failure, Pod will be Kubernetes reschedule to another Node, Pod IP address will change.

If the container application itself is distributed and provides services through multiple instances, a load balancer needs to be set up at the front of these instances to distribute requests. Service in Kubernetes is the core component used to solve these problems.

Service example: To give the client application access to two Instances of Tomcat Pod, you can create a Service to provide the Service. Kubernetes provides a quick way to create a Service through the Kubectl expose command.

[root@k8smaster01 study]# kubectl expose rc webapp

[root@k8smaster01 study]# kubectl get svc | grep -E ‘NAME|webapp’

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

Webapp ClusterIP 10.10.10.51 < None > 8080/TCP 45s

[root@k8smaster01 study]# curl 10.10.10.51:8080 #

Tip: The above access to Service address 10.10.10.51:8080 is automatically loaded to the two back-end pods.

Service Example 2: Expose the Service through the Service configuration file.

[root@k8smaster01 study]# vi webappsvc.yaml

  1 apiVersion: v1
  2 kind: Service
  3 metadata:
  4   name: webappservice
  5 spec:
  6   ports:
  7   - port: 8081
  8     targetPort: 8080
  9   selector:
 10     app: webapp
Copy the code

[root@k8smaster01 study]# kubectl create -f webappsvc.yaml

[root@k8smaster01 study]# kubectl get svc | grep -E ‘NAME|webappser’

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

Webappservice ClusterIP 10.10.10.83 < None > 8081/TCP 22s

Tip: The key fields in the Service definition above are ports and selector. In this example, the ports definition part specifies the virtual port number required by the Service as 8081. Because the port number is different from the Pod container port number 8080, the port number of the back-end Pod needs to be specified through the targetPort. Part of the Selector definition sets the label: app= webApp owned by the backend Pod.

[root@k8smaster01 study]# curl 10.10.10.83:8081

  • Service load distribution policies: RoundRobin and SessionAffinity
    • RoundRobin: indicates the RoundRobin mode, which forwards requests to each Pod at the back end.
    • SessionAffinity: Indicates the session retention mode based on the client IP address. That is, the first request from a client is forwarded to a Pod at the backend, and subsequent requests from the same client are forwarded to the same Pod at the backend.

By default, Kubernetes client requests the RoundRobin pattern on the load distribution, at the same time can be set by the service. The spec. SessionAffinity = ClientIP to enable sessionAffinity strategy. In this way, requests from the same client IP are forwarded to a Pod fixed on the back end.

Through the definition of Service, Kubernetes implements a unified gateway definition and load balancing mechanism for distributed applications. A Service can also be configured with other types of Settings, such as multiple port numbers, external Service, or Headless Service mode.

2.2 Multi-port Service

Sometimes a container application can also provide multiple port services, so the definition of Service can be set to have multiple ports corresponding to multiple application services.

Example 1: Below, the Service sets two port numbers and names each port number.

[root@k8smaster01 study]# vi twoportservice.yaml

  1 apiVersion: v1
  2 kind: Service
  3 metadata:
  4   name: webapp
  5 spec:
  6   ports:
  7   - port: 8080
  8     targetPort: 8080
  9     name: web
 10   - port: 8005
 11     targetPort: 8005
 12     name: management
 13   selector:
 14     app: webapp
Copy the code

[root@k8smaster01 study]# vi kubednsservice.yaml

1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: kube-dns 5 namespace: kube-system 6 labels: 7 k8s-app: kube-dns 8 kubernetes.io/cluster-service: "true" 9 kubernetes.io/name: "KubeDNS" 10 spec: 11 selector: 12 k8s-app: Kube-dns 13 clusterIP: 169.169.0.100 14 Ports: 15-name: DNS 16 port: 53 17 protocol: UDP 18 19-name: clusterIP: 169.169.0.100 14 Ports: 15-name: DNS 16 port: 53 17 protocol: UDP 18 19-name: dns-tcp 20 port: 53 21 protocol: TCPCopy the code

2.3 External Services Service

In some environments, the application system needs to use an external database, another cluster, or a Service in a Namespace as the back end of the Service. This can be achieved by creating a Service without Label Selector.

[root@k8smaster01 study]# vi noselectorservice.yaml

  1 apiVersion: v1
  2 kind: Service
  3 metadata:
  4   name: my-service
  5 spec:
  6   ports:
  7   - protocol: TCP
  8     port: 80
  9     targetPort: 80
Copy the code

[root@k8smaster01 study]# kubectl create -f noselectorservice.yaml

As defined above, a Service without a label selector is created, that is, the Pod at the back end cannot be selected. The system does not automatically create an Endpoint. Therefore, you need to manually create an Endpoint corresponding to the Service to point to the actual back-end address.

The Endpoint definition file looks like this:

[root@k8smaster01 study]# vi noselectorendpoint.yaml

1 apiVersion: v1 2 kind: Endpoints 3 metadata: 4 name: my-service 5 subsets: 6 - addresses: 7 - IP: 8 Ports: 9-Port: 80Copy the code

[root@k8smaster01 study]# kubectl create -f noselectorendpoint.yaml

[root@k8smaster01 study]# kubectl get svc | grep -E ‘NAME|my-service’

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

My-service ClusterIP 10.10.10.211 < None > 80/TCP 3s

[root @ k8smaster01 study] # curl 10.10.10.211

Tip: As shown above, accessing a Service without a label selector is the same as accessing a Service with a label selector. The request will be routed to a manually defined back-end Endpoint.

Three Headless Service

3.1 Introduction to headless Service

In some application scenarios, the default load balancer provided by Service is not used if the load balancer needs to be manually specified, or the application wants to know other instances of services belonging to the same group. Kubernetes provides a Headless Service to do this, which does not set a ClusterIP (inbound IP address) for the Service, but only returns a list of back end pods to the calling client via Label Selector.

In this scenario, the Service no longer has a specific ClusterIP address. Accessing it will get the entire Pod list with Label “app=nginx”, and the client program will then decide what to do with the Pod list.

For example, StatefulSet uses Headless Service to return multiple Service addresses for clients.

For “decentralized” application clusters, Headless Service is ideal.

3.2 Nginx scenario experiment

By setting up Nginx cluster for Headless Service, the application cluster can be automatically created.

[root@k8smaster01 study]# vi nginx-service.yaml # create service

1 apiVersion: v1 2 kind: Service 3 metadata: 4 labels: 5 name: nginx-svc 6 name: nginx-svc 7 spec: 8 ports: 9 -protocol: TCP 10 port: 80 11 targetPort: 80 12 selector: 13 Name: nginx-demo # define selector 14 clusterIP: NoneCopy the code

[root@k8smaster01 study]# kubectl create -f nginx-service.yaml

[root@k8smaster01 study]# vi nginx-deployment.yaml

1 apiVersion: apps/v1 2 kind: Deployment 3 metadata: 4 labels: 5 name: nginx-demo 6 name: nginx-demo 7 spec: 8 replicas: 2 9 selector: 10 matchLabels: 11 name: nginx-demo 12 template: 13 metadata: 14 labels: 15 name: Nginx-demo 16 spec: 17 containers: 18-name: nginx 19 Image: nginx:1.7.9 20 ports: 21-containerport: 80 22 Name: webCopy the code

[root@k8smaster01 study]# kubectl create -f nginx-deployment.yaml

[root@k8smaster01 study]# kubectl create -f nginx-service.yaml

[root@k8smaster01 study]# kubectl get svc -o wide

[root@k8smaster01 study]# kubectl get pods -o wide

[root @ k8smaster01 study] # nslookup nginx – SVC. Default. SVC. Cluster. The local 10.10.190.170

The IP address of the Pod can be directly resolved.