OpenShift Service Concepts: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(38 intermediate revisions by the same user not shown)
Line 8: Line 8:
* [[OpenShift Concepts#Service|OpenShift Concepts]]
* [[OpenShift Concepts#Service|OpenShift Concepts]]
* [[OpenShift Service Operations]]
* [[OpenShift Service Operations]]
* [[OpenShift Service Definition]]


=Overview=
=Overview=


A ''service'' represents functionality provided by the OpenShift cluster and that is exposed as a permanent IP, hostname and port, for other applications to use. There is no actual process running on a node that can be identified as a service; a service is rather state in the API server. In the vast majority of the cases, the functionality is provided by a group of pods managed by OpenShift. The pods provide equivalent, replicated functionality, and they may individually come and go. This situation provides the main use case for services, as described in the "[[#Need_for_Services|Need for Services]]" section. The relationship between a pod and the service is defined by a label selector declared by the service:
A ''service'' is a Kubernetes primitive representing functionality provided by the Kubernetes cluster, exposed at a permanent IP, hostname and port, for other applications to use. There is no actual process running on any node that can be identified as a service; a service is rather state in the API server. In the vast majority of the cases, the functionality is provided by a group of pods managed by the Kubernetes environment. The pods provide equivalent, replicated functionality, and they may individually, and arbitrarily, come and go. This situation provides the main use case for services, as described in the "[[#Need_for_Services|Need for Services]]" section. The relationship between a service and a pod it represents is defined by a label selector declared by the service:


  apiVersion: v1
  apiVersion: v1
Line 21: Line 22:
     key2: value2
     key2: value2


A pod will be identified as being part of the service "cluster" if the label selector declared by the service matches the pod.
A pod will be identified as being part of the service "cluster" if the label selector declared by the service matches the pod. More details are available in the [[OpenShift_Service_Definition#selector|Service defintion]]. A service may expose [[#Ports|one or more ports]].


There are cases when pods represent functionality that is not provided by pods, but by external processes; these are [[#External_Service|external services]].
In some special cases, the service can represent a set of pods running outside the current project, or processes running outside OpenShift altogether. This is known as an [[#External_Service|external service]].  


The services constitute the [[OpenShift Concepts#Service_Layer|service layer]].
The services constitute the [[OpenShift Concepts#Service_Layer|service layer]], which is how how applications communicate with one another. All pods that are part of a projects [[OpenShift_Environment_Variables#Environment_Variables_Corresponding_to_Other_Services|get injected]] with the address of all other services available in the project as <''SVCNAME''>_SERVICE_HOST, <''SVCNAME''>_SERVICE_PORT pairs of environment variables, which facilitates consumption of those services at the published addresses.
 
Services of a project can be displayed with:
 
[[oc get#all|oc get all]]
[[Oc_get#services.2C_svc|oc get svc]]
 
=Service Definition=
 
{{Internal|OpenShift Service Definition|Service Definition}}


=Need for Services=
=Need for Services=


Pods are transient, they may be started, and more importantly, die at any time, and the IP addresses their endpoints are accessible at are dynamically allocated from the [[OpenShift_Concepts#The_Cluster_Network|cluster network]]. This dynamic behavior is hidden behind the ''service abstraction'', that provides the appearance of a stable, consistent service backed by a [[#Service_Address|permanent IP address]]. A client that needs the functionality provided by the service will contact the well-known address - the service's address - and the service will proxy the call, via a [[#Service_Proxy|service proxy]], to one of the actual pods providing the service. From this perspective, the service acts as a load balancer.
Pods are transient, they may be started, and more importantly, die at any time, and the IP addresses their endpoints are accessible at are dynamically allocated from the [[OpenShift_Concepts#The_Cluster_Network|cluster network]]. This dynamic behavior is hidden behind the ''service abstraction'', that provides the appearance of a stable, consistent service backed by a [[#Service_Address|permanent IP address]]. A client that needs the functionality provided by the service will contact the well-known address - the service's address - and the service will proxy the call, via a [[#Service_Proxy|service proxy]], to one of the actual pods providing the service. From this perspective, the service acts as an ''internal load balancer'': it identifies a set of replicated pods and then proxies the connections it receives to those pods.


=Service Address=
=Service Address=
Line 45: Line 55:
     protocol: TCP
     protocol: TCP
     targetPort: 80
     targetPort: 80
This is somewhat confusing, as the pod IPs, which belong to a completely different category of addresses, are said to allocated from the [[OpenShift_Concepts#The_Cluster_Network|cluster network]]. The service IP is only available internally in the cluster and it is not routable (in the IP sense) externally. The service can be exposed externally via a [[OpenShift Concepts#Route|route]].


=Service Endpoints=
=Service Endpoints=


The API server evaluates its services' selectors continuously, and the information about pods that match those selectors are published as part of the state of an API primitive named Endpoints.  The name of the Endpoints object is the same as the name of the corresponding Service:
The [[#EndpointsController|EndpointsController]] component of the API server evaluates its services' selectors continuously, and the information about pods that match those selectors are published as part of the state of an API primitive named Endpoints.  The name of the Endpoints object is the same as the name of the corresponding Service:


  oc get -o yaml endpoints
  oc get -o yaml endpoints/serviceA


  apiVersion: v1
  apiVersion: v1
  kind: List
  '''kind''': '''Endpoints'''
items:
metadata:
- apiVersion: v1
  '''name''': serviceA
  '''kind''': '''Endpoints'''
subsets:
  metadata:
- '''addresses''':
    '''name''': serviceA
  - '''ip''': 10.130.1.0
  subsets:
    nodeName: node1
  - '''addresses''':
    targetRef:
    - '''ip''': 10.130.1.0
      kind: Pod
      nodeName: node1
      name: serviceA-1-gr7rh
      targetRef:
  '''ports''':
        kind: Pod
  - name: 80-tcp
        name: serviceA-1-gr7rh
    '''port''': 80
    '''ports''':
    protocol: TCP
    - name: 80-tcp
      '''port''': 80
      protocol: TCP


==EndpointsController==
The <[[OpenShift Concepts#Pod_IP_Address|pod IP address]]>:<port> pairs correspond to processes running inside of a container, on a pod, on a node. The same information can be obtained from the service:


The [[#EndpointsController|EndpointsController]] system component associates a service with the endpoints of pods that match the selector. Once the association is done, the actual physical network streaming is performed by a [[#Service_Proxy|service proxy]]. More about endpoints is available here: [[#Service_Endpoints|service endpoints]].
  oc describe service <''service-name''>


Name: logging-kibana
...
Endpoints: 10.129.2.17:3000
...


==EndpointsController==


The [[#EndpointsController|EndpointsController]] system component  associates a service with the endpoints of pods that match the selector. Once the association is done, the actual physical network streaming is performed by a [[#Service_Proxy|service proxy]]. More about endpoints is available here: [[#Service_Endpoints|service endpoints]].


=Service Proxy=


{{External|https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies}}


The ''service proxy'' is a simple network proxy that represents the services defined in the API on the node. Each node runs a service proxy instance. The service proxy does simple TCP and UDP stream forwarding across a set of backends.


==SessionAffinity==


=Ports=


In some special cases, the service can represent a set of pods running outside the current project, or an instance running outside OpenShift altogether.  This is known as an [[#External_Service|external service]].
{{Internal|OpenShift_Service_Definition#ports|Service Definition - ports}}


The service IP is available internally in the cluster. It is not routable (in the IP sense) externally. The service can be exposed externally via a [[#Route|route]].
==Multi-Port Service==


A ''service resource'' is an abstraction that defines a logical set of pods and a policy that is used to access the pods. The ''service layer'' is how applications communicate with one another. The service is a [[Kubernetes Concepts#Service|Kubernetes concept]]. The service serves as an ''internal'' load balancer: it identifies a set of replicated pods and then proxies the connections it receives to those pods ([[OpenShift_Concepts#Router|routers]] provide external load balancing). The service is not a "thing", but an entry in the configuration. Backing pods can be added or removed to or from the service arbitrarily. This way, anything that depends on the service can refer to it as a consistent IP:port pair. The services uses a label selector to find all the running containers associated with it.
{{External|https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services}}


Services can be consumed from other pods using the values of the <SERVICE>_HOST environment variables that are injected by the cluster.
=External Service=


{{Internal|OpenShift Service Definition|Service Definition}}
In some special cases, the service can represent a set of pods running outside the current project, or an instance running outside OpenShift altogether. Services representing external resources do not require associated pods, hence do not need a selector. They are called ''external services''. If the selector is not set, the [[#EndpointsController|EndpointsController]] ignores the services, and endpoints can be specified manually. The procedure to declare services from another projects or external service is available here: {{Internal|OpenShift_Service_Operations#Integrate_an_External_Service|Integrating External Services}}


Services of a project can be displayed with:
=Service Dependencies=


[[oc get#all|oc get all]]
<font color=red>
[[Oc_get#services.2C_svc|oc get svc]]
TO PROCESS: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/
 
</font>
=Service Endpoint=
 
An <[[#Pod_IP_Address|pod IP address]]>:<port> pair that corresponds to a process running inside of a container, on a pod, on a node. The process that associates services and endpoints is performed by the EndpointController and it is described [[#EndpointsController|above]]. The service endpoint coordinate can be obtained by executing:
 
oc describe service <''service-name''>


Name: logging-kibana
Note that "service.alpha.openshift.io/dependencies", sometimes present in Service declarations, do not refer to service dependencies, but rather to GUI details:
...
Endpoints: 10.129.2.17:3000
...
 
=Service Proxy=
 
The ''service proxy'' is a simple network proxy that represents the services defined in the API on the node. Each node runs a service proxy instance. The service proxy does simple TCP and UDP stream forwarding across a set of backends.
 
=Service Dependencies=
 
<font color=red>'''TODO''': It seems there's a way to express dependencies between services:


  apiVersion: v1
  apiVersion: v1
Line 122: Line 126:
   name: jenkins
   name: jenkins
   annotations:
   annotations:
     service.alpha.openshift.io/dependencies: '[{"name": "jenkins-jnlp", "namespace": "", "kind": "Service"}]'
     '''service.alpha.openshift.io/dependencies''': '[{"name": "jenkins-jnlp", "namespace": "", "kind": "Service"}]'
    ...
spec:
     ...
     ...


Clarify this.
See: https://github.com/openshift/origin-web-console/issues/2319
 
TO PROCESS: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/
</font>
 
=Relationship between Services and the Pods providing the Service=
 
=External Service=
 
In some special cases, the service can represent a set of pods running outside the current project, or an instance running outside OpenShift altogether. Services representing external resources do not require associated pods, hence do not need a selector. They are called ''external services''. If the selector is not set, the [[#EndpointsController|EndpointsController]] ignores the services, and endpoints can be specified manually. The procedure to declare services from another projects or external service is available here: {{Internal|OpenShift_Service_Operations#Integrate_an_External_Service|Integrating External Services}}

Latest revision as of 23:48, 26 February 2018

External

Internal

Overview

A service is a Kubernetes primitive representing functionality provided by the Kubernetes cluster, exposed at a permanent IP, hostname and port, for other applications to use. There is no actual process running on any node that can be identified as a service; a service is rather state in the API server. In the vast majority of the cases, the functionality is provided by a group of pods managed by the Kubernetes environment. The pods provide equivalent, replicated functionality, and they may individually, and arbitrarily, come and go. This situation provides the main use case for services, as described in the "Need for Services" section. The relationship between a service and a pod it represents is defined by a label selector declared by the service:

apiVersion: v1
kind: Service
spec:
  [...]
  selector:
    key1: value1
    key2: value2

A pod will be identified as being part of the service "cluster" if the label selector declared by the service matches the pod. More details are available in the Service defintion. A service may expose one or more ports.

In some special cases, the service can represent a set of pods running outside the current project, or processes running outside OpenShift altogether. This is known as an external service.

The services constitute the service layer, which is how how applications communicate with one another. All pods that are part of a projects get injected with the address of all other services available in the project as <SVCNAME>_SERVICE_HOST, <SVCNAME>_SERVICE_PORT pairs of environment variables, which facilitates consumption of those services at the published addresses.

Services of a project can be displayed with:

oc get all
oc get svc

Service Definition

Service Definition

Need for Services

Pods are transient, they may be started, and more importantly, die at any time, and the IP addresses their endpoints are accessible at are dynamically allocated from the cluster network. This dynamic behavior is hidden behind the service abstraction, that provides the appearance of a stable, consistent service backed by a permanent IP address. A client that needs the functionality provided by the service will contact the well-known address - the service's address - and the service will proxy the call, via a service proxy, to one of the actual pods providing the service. From this perspective, the service acts as an internal load balancer: it identifies a set of replicated pods and then proxies the connections it receives to those pods.

Service Address

Each service has a service IP address and a port, which is allocated from the services subnet. The service IP address is sometimes referred to as the "Cluster IP", which is consistent with the abstraction provided by the service: a cluster of OpenShift-managed pods providing the service:

apiVersion: v1
kind: Service
spec:
 [...]
 clusterIP: 172.30.73.18
 ports:
 - name: 80-tcp
   port: 80
   protocol: TCP
   targetPort: 80

This is somewhat confusing, as the pod IPs, which belong to a completely different category of addresses, are said to allocated from the cluster network. The service IP is only available internally in the cluster and it is not routable (in the IP sense) externally. The service can be exposed externally via a route.

Service Endpoints

The EndpointsController component of the API server evaluates its services' selectors continuously, and the information about pods that match those selectors are published as part of the state of an API primitive named Endpoints. The name of the Endpoints object is the same as the name of the corresponding Service:

oc get -o yaml endpoints/serviceA
apiVersion: v1
kind: Endpoints
metadata:
  name: serviceA
subsets:
- addresses:
  - ip: 10.130.1.0
    nodeName: node1
    targetRef:
      kind: Pod
      name: serviceA-1-gr7rh
  ports:
  - name: 80-tcp
    port: 80
    protocol: TCP

The <pod IP address>:<port> pairs correspond to processes running inside of a container, on a pod, on a node. The same information can be obtained from the service:

oc describe service <service-name>
Name:			logging-kibana
...
Endpoints:		10.129.2.17:3000
...

EndpointsController

The EndpointsController system component associates a service with the endpoints of pods that match the selector. Once the association is done, the actual physical network streaming is performed by a service proxy. More about endpoints is available here: service endpoints.

Service Proxy

https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

The service proxy is a simple network proxy that represents the services defined in the API on the node. Each node runs a service proxy instance. The service proxy does simple TCP and UDP stream forwarding across a set of backends.

SessionAffinity

Ports

Service Definition - ports

Multi-Port Service

https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services

External Service

In some special cases, the service can represent a set of pods running outside the current project, or an instance running outside OpenShift altogether. Services representing external resources do not require associated pods, hence do not need a selector. They are called external services. If the selector is not set, the EndpointsController ignores the services, and endpoints can be specified manually. The procedure to declare services from another projects or external service is available here:

Integrating External Services

Service Dependencies

TO PROCESS: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/

Note that "service.alpha.openshift.io/dependencies", sometimes present in Service declarations, do not refer to service dependencies, but rather to GUI details:

apiVersion: v1
kind: Service
metadata:
  name: jenkins
  annotations:
    service.alpha.openshift.io/dependencies: '[{"name": "jenkins-jnlp", "namespace": "", "kind": "Service"}]'
    ...

See: https://github.com/openshift/origin-web-console/issues/2319