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
.