A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them.
Overview
At the end of the module, you will :
Learn how to expose a Pod internally
Learn how the domain name resolution works on a Kubernetes cluster
Learn how to expose a Pod externally
Prerequisites
Create the directory data/services in your home folder to manage the YAML file needed in this module.
mkdir~/data/services
Create
Kubernetes Pods are mortal. They are born and when they die, they are not resurrected. ReplicaSets in particular create and destroy Pods dynamically. While each Pod gets its own IP address, even those IP addresses cannot be relied upon to be stable over time. This leads to a problem.
A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them. The set of Pods targeted by a Service is determined by a label selector.
Kubernetes manage four kinds of services depending on the exposition needed for the Pods attached :
Type
Description
ClusterIP
Only accessed within the Kubernetes cluster
NodePort
Host exposition accessible from the local network
LoadBalancer
External exposition, Internet access
Endpoint
External endpoint definition to easily use it in the cluster
The create command can directly ask the API resource to create a Service in command line or create a Service object based on a yaml file definition.
Exercise n°1
Create an Nginx Deployement and expose the Nginx Deployemnt to be able to access it from the local network on HTTP (80) port in command line.
# Create an Nginx Podskubectlrunnginx--image=nginx--port=80# Expose the Nginx Pods on port 80kubectlexposedeploymentnginx--port=80--type=NodePort
Exercise n°2
Update the Nginx Pod in the namespace app-demo to be able to access it on HTTP (80) and HTTPS (443) port thanks to a YAML file.
Update the service with the new yaml file definition.
kubectlapply-f~/data/services/01_service.yaml
Get
The get command list the object asked. It could be a single object or a list of multiple objects comma separated. This command is useful to get the status of each object. The output can be formatted to only display some information based on some json search or external tools like tr, sort, uniq.
The default output display some useful information about each services :
Name : the name of the newly created resource
Type : the type of exposition defined at service creation (see previous table).
Cluster-IP : the internal cluster IP of the resources
External-IP : the external resources IP of the resources, field configured when LoadBalancer type is used
Port(s) : a list of ports opened in the pods managed by the service
Age : the age since his creation
Exercise n°1
Get the list of existing service in the default namespace.
Once an object is running, it is inevitably a need to debug problems or check the configuration deployed.
The describe command display a lot of configuration information about the Service(s) (labels, resource requirements, etc.) or any other Kubernetes objects, as well as status information about the Service(s) and Pod (state, readiness, restart count, events, etc.).
This command is really useful to introspect and debug an object deployed in a cluster.
Exercise n°1
Describe one of the existing service in the default namespace.
Kubernetes come with a lot of documentation about his objects and the available options in each one. Those information can be fin easily in command line or in the official Kubernetes documentation.
The explain command allows to directly ask the API resource via the command line tools to display information about each Kubernetes objects and their architecture.
Exercise n°1
Get the documentation of a specific field of a resource.
kubectlexplainservice.spec
KIND:ServiceVERSION:v1RESOURCE:spec<Object>DESCRIPTION:Specdefinesthebehaviorofaservice.https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-statusServiceSpecdescribestheattributesthatausercreatesonaservice.FIELDS:clusterIP<string>clusterIPistheIPaddressoftheserviceandisusuallyassignedrandomlybythemaster.Ifanaddressisspecifiedmanuallyandisnotinusebyothers,itwillbeallocatedtotheservice; otherwise,creationoftheservicewillfail.Thisfieldcannotbechangedthroughupdates.Validvaluesare"None",emptystring (""), or a valid IP address. "None" can bespecifiedforheadlessserviceswhenproxyingisnotrequired.OnlyappliestotypesClusterIP,NodePort,andLoadBalancer.IgnorediftypeisExternalName.Moreinfo:https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxiesexternalIPs<[]string>externalIPsisalistofIPaddressesforwhichnodesintheclusterwillalsoaccepttrafficforthisservice.TheseIPsarenotmanagedbyKubernetes.TheuserisresponsibleforensuringthattrafficarrivesatanodewiththisIP.Acommonexampleisexternalload-balancersthatarenotpartoftheKubernetessystem.externalName<string>externalNameistheexternalreferencethatkubednsorequivalentwillreturnasaCNAMErecordforthisservice.Noproxyingwillbeinvolved.MustbeavalidRFC-1123hostname (https://tools.ietf.org/html/rfc1123) andrequiresTypetobeExternalName.externalTrafficPolicy<string>externalTrafficPolicydenotesifthisServicedesirestorouteexternaltraffictonode-localorcluster-wideendpoints."Local"preservestheclientsourceIPandavoidsasecondhopforLoadBalancerandNodeporttypeservices,butriskspotentiallyimbalancedtrafficspreading."Cluster"obscurestheclientsourceIPandmaycauseasecondhoptoanothernode,butshouldhavegoodoverallload-spreading.healthCheckNodePort<integer>healthCheckNodePortspecifiesthehealthchecknodePortfortheservice.Ifnotspecified,HealthCheckNodePortiscreatedbytheserviceapibackendwiththeallocatednodePort.Willuseuser-specifiednodePortvalueifspecifiedbytheclient.OnlyeffectswhenTypeissettoLoadBalancerandExternalTrafficPolicyissettoLocal.loadBalancerIP<string>OnlyappliestoServiceType:LoadBalancerLoadBalancerwillgetcreatedwiththeIPspecifiedinthisfield.Thisfeaturedependsonwhethertheunderlyingcloud-providersupportsspecifyingtheloadBalancerIPwhenaloadbalanceriscreated.Thisfieldwillbeignoredifthecloud-providerdoesnotsupportthefeature.loadBalancerSourceRanges<[]string>Ifspecifiedandsupportedbytheplatform,thiswillrestricttrafficthroughthecloud-providerload-balancerwillberestrictedtothespecifiedclientIPs.Thisfieldwillbeignoredifthecloud-providerdoesnotsupportthefeature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/ ports <[]Object> The list of ports that are exposed by this service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies publishNotReadyAddresses <boolean> publishNotReadyAddresses, when set to true, indicates that DNS implementations must publish the notReadyAddresses of subsets for the Endpoints associated with the Service. The default value is false. The primary use case for setting this field is to use a StatefulSet's Headless Service to propagate SRV records for its Pods without respect to their readiness for purpose of peer discovery. selector <map[string]string> Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/ sessionAffinity <string> Supports "ClientIP" and "None". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies sessionAffinityConfig <Object> sessionAffinityConfig contains the configurations of session affinity. type <string> type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. "ExternalName" maps to the specified externalName. "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP. "NodePort" builds on ClusterIP and allocates a port on every node which routes to the clusterIP. "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
Add the --recursive flag to display all of the fields at once without descriptions.
Delete
The delete command delete resources by filenames, stdin, resources and names, or by resources and label selector.
Deleting a Service will have no effect on the Pod state. It only delete the access to each resources managed by the service.
Note that the delete command does NOT do resource version checks, so if someone submits an update to a resource right when you submit a delete, their update will be lost along with the rest of the resource.
Exercise n°1
Delete the service and the deployment created previously in the default namespace.
# Delete the service previously createdkubectldeleteservicenginx# Delete the previous deployment createdkubectldeletedeploymentnginx
Module exercise
The purpose of this section is to manage each steps of the lifecycle of an application to better understand each concepts of the Kubernetes course.
The main objective in this module is to understand how to expose a service depending on the security level needed.
For more information about the application used all along the course, please refer to the Exercise App > Voting App link in the left panel.
Based on the principles explain in this module, try by your own to handle this steps. The development of a yaml file is recommended.
The file developed has to be stored in this directory : ~/data/votingapp/04_services
Manage the access of each part of the Voting App based on those conditions :
The PostgreSQL database Deployment must only be access from the Kubernetes cluster on port 5432.
The Redis queue Deployment must only be access from the Kubernetes cluster on port 6379.
The vote and result Deployment must be publicly access on port 8080.
The worker Pods must not be exposed.
Try to access the vote web site
Try to access the result web site
An example of yaml definition file to manage the Pods access with Services resources.