====== Services ====== Un service est un moyen de découvrir les pods qui réalise une tâche particulière. Attention à ne pas confondre avec [[ingress]] qui est un composant gérant les connexions externes de type HTTP. Les connexions HTTP peuvent aussi être géré par des services, mais il est recommander d'utiliser [[ingress]]. ===== Définition ===== apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 Ce service s'appelle ''my-service'', et pointe sur tous les pods avec l'étiquette ''app=MyApp'' sur le port ''9376''. Kubernetes assigne une IP (appelé le ClusterIP) au service. Cette IP est utilisée comme IP proxy pour load-balancer les requêtes entre les différents pods pointés par le sélecteur. ===== Découverte des services ===== Les services peuvent être découverts par différents moyens. ==== Variable d'environnement ==== Chaque pods créé dans le même espace de nom qu'un service va avoir des variables défini sous les formes suivantes : ^ Variable ^ Description ^ Exemple ^ | {svc_name}_SERVICE_HOST | ClusterIP (IP du service) | 10.0.0.11 | | {svc_name}_SERVICE_PORT | Port du serice | 6379 | | {svc_name}_PORT | Adresse du service | tcp://10.0.0.11:6379 | | {svc_name}_PORT_{svc_port}_{protocol} | Adresse du service | tcp://10.0.0.11:6379 | | {svc_name}_PORT_{svc_port}_{protocol}_PROTO | Protocole du port | tcp | | {svc_name}_PORT_{svc_port}_{protocol}_PORT | Port | 6379 | | {svc_name}_PORT_{svc_port}_{protocol}_ADDR | Adresse IP du service | 10.0.0.11 | ==== DNS A record ==== Chaque service va avoir un enregistrement A sur le DNS du système sous la forme ''{svc-name}.{namespace}.svc.cluster.local''. À savoir que dans un namespace, il y a un DNS search avec le nom du domaine. Les adresses suivantes sont donc valides : * {svc-name} * {svc-name}.{namespace} * {svc-name}.{namespace}.svc.cluster.local Cette méthode ne permet pas de connaitre le port du service. ==== DNS SRV record ==== Les services ont aussi un enregistrement SRV. Cet enregistrement permet aussi la découverte du port. L'enregistrement SRV est sous la forme ''_{port-name}._{port-protocol}.{svc-name}.svc.cluster.local''. ===== Spec ===== ==== Selector ==== Le selector permet de découvrir la liste des pods vers lesquelles doit pointer le service. Si un sélecteur est défini, un objet [[..:endpoints]] sera automatiquement créé dynamiquement pour pointer vers ces pods. Il est aussi possible de faire des services sans sélecteur. Dans ce cas particulier, les [[..:endpoints]] doivent être créé manuellement sur le service. ==== Type ==== Le champs ''spec.type'' est le type de service. Le type de service par défaut est ''ClusterIP''. === ClusterIP === Type de service par défaut. Le service se comportera comme un LoadBalancer entre les différentes cibles. Le service aura une IP virtuelle appelé le ClusterIP (IP du loadbalancer) sur laquelle attaqueront les programmes ayant besoin du service. Ce type de service est accessible uniquement à l'intérieur du Cluster. === NodePort === Les services de type node port ouvre le port ''nodePort'' sur les noeuds du cluster sur lesquelles s'exécute les pods. === LoadBalancer === Les services LoadBalancer sont semblables aux services de type NodePort, mais utilisent un loadbalancer externe pour créer les routes vers les bons noeuds. === ExternalName === Ce type de service est permet de faire référence à un autre service. Il peut être dans le même namespace, un autre namespace mais aussi peut être un service externe au cluster. ==== ClusterIP ==== Le champs ''spec.clusterIP'' est rempli par défaut par une IP disponible dans le système. Il est possible de forcer cette IP. Dans le cas où il n'y a pas besoin de load-balancing, le champs ''spec.ClusterIP'' peut être défini à ''None''. Il s'agit alors d'un service dit Headless, sans proxy en amont. S'il y a un sélecteur, les enregistrements DNS du service renverront directement l'IP du pod. S'il n'y en a pas, les enregistrement pointeront vers l'IP défini dans l'objet [[..:endpoints]] ayant le même nom que le service. Si le service est de type externalName, l'enregistrement DNS sera transformé en CNAME. ==== Ports ==== Le champs ''spec.ports'' est un tableau d'objets avec les éléments suivants : ^ Variable ^ Valeur par défaut ^ Description ^ | .spec.ports[*].port | | Port du service (accès à l'interieur du cluster. | | .spec.ports[*].name | None | Nom du port. | | .spec.ports[*].protocol | TCP | Type de protocole. | | .spec.ports[*].targetPort | = ''port'' | Port du pod vers lequel rediriger les connexions. | | .spec.ports[*].nodePort | None | Port publique ouvert sur le noeud du pod. | Attention, le ''nodePort'' doit être compris entre 30000 et 32767. Les protocoles supportés sont : * TCP (par défaut) * UDP * HTTP * Proxy protocol * SCTP (nécessite une activation) Le service écoute sur le ''spec.ports[*].port'' et redirige le trafic vers le ''spec.ports[].targetPort''. Par défaut, le ''targetPort'' est le même que le ''port''. ==== ExternalName ==== Champs requis pour les services de type ''externalName''. C'est le FQDN vers lequel doit pointer le service. ==== ExternalIP ==== Liste d'adresse IP de destination sur lesquelles le service sera accessible de l'extérieur. ==== SessionAffinity ==== Le champs ''spec.sessionAffinity'' est par défaut None. Il s'agit de savoir si le loadBalancer du service doit toujours rediriger un client donné vers le même pod. Les valeurs possibles sont les suivantes : ^ Valeur ^ Description ^ | None | Pas de persistance des sessions. Toute connexion est renvoyé vers un pod aléatoire. | | ClientIP | Une IP source sera toujours envoyé vers un même pod. | Si le champs est défini à ''ClientIP'', un client est redirigé par défaut vers un seul pod donné durant 3h. Ce temps d'expiration de la session peut être modifié par le paramètre ''service.spec.sessionAffinityConfig.clientIP.timeoutSeconds''.