Skip to content

Read Kubernetes Services

The kubernetes sourceWhere a service reads its endpoints, one of dns, file, url or kubernetes. See Services and sources. serves the ready endpointsOne IP address and port that a service gives, with its load balancing weight. See HTTP API. of a Kubernetes Service, read from its EndpointSlicesThe Kubernetes object that lists the pods behind a Kubernetes Service, read by the kubernetes source. See Read Kubernetes Services.. A client outside the cluster, such as a load balancer in front of it, then reaches the pods directly, without a NodePort or a LoadBalancer Service in between. The pod addresses must be routable from that client.

You need:

  • A Service with a selector, so that Kubernetes keeps its EndpointSlices.
  • Either Vigie running in the cluster with a service account, or a kubeconfig on the host that runs Vigie.

Vigie reads the Service, then lists its EndpointSlices. In the namespace of the Service, give its identity these two rights:

vigie-rbac.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: vigie
namespace: shop
rules:
- apiGroups: [""]
resources: [services]
verbs: [get]
- apiGroups: [discovery.k8s.io]
resources: [endpointslices]
verbs: [list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vigie
namespace: shop
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: vigie
subjects:
- kind: ServiceAccount
name: vigie
namespace: vigie

This binds the service account vigie of the namespace vigie, the one of Run in a Kubernetes cluster. From outside the cluster, bind the user of the kubeconfig instead. Repeat the Role and the RoleBinding in each namespace Vigie reads.

config.yml
services

services

Type list · Required yes · Default none

Services the server answers for, at least one.

:
- name

services[].name

Type string · Required yes · Default none

Name clients ask for. A request without a name gets the service named default.

: web
default_port

services[].default_port

Type integer · Required no · Default 80

Port of the endpoints that don’t give their own.

: 8080
kubernetes

services[].kubernetes

Type object · Required one source · Default none

Reads the endpoints from a Kubernetes Service.

:
namespace

services[].kubernetes.namespace

Type string · Required no · Default default

Namespace of the Service.

: shop
service

services[].kubernetes.service

Type string · Required yes · Default none

Name of the Kubernetes Service.

: web
port_name

services[].kubernetes.port_name

Type string · Required no · Default empty

Name of the port to use, among the ports of the Service.

: http
  • The port of the endpoints is the one named port_name among the ports of the Service. Without port_name, it’s the port of the Service when it has only one, else the default_port of the service.
  • The weight is always 0, Kubernetes has no weight per endpoint.
  • An endpoint that isn’t ready, a terminating pod for instance, is left out. An endpoint without a ready condition counts as ready, as in Kubernetes.
  • A dual-stack Service gives each pod once per address family.

A Service without any ready pod answers 200 with [].

Set kubeconfig, and context to pick another context than the current one:

config.yml
services

services

Type list · Required yes · Default none

Services the server answers for, at least one.

:
- name

services[].name

Type string · Required yes · Default none

Name clients ask for. A request without a name gets the service named default.

: web
default_port

services[].default_port

Type integer · Required no · Default 80

Port of the endpoints that don’t give their own.

: 8080
kubernetes

services[].kubernetes

Type object · Required one source · Default none

Reads the endpoints from a Kubernetes Service.

:
namespace

services[].kubernetes.namespace

Type string · Required no · Default default

Namespace of the Service.

: shop
service

services[].kubernetes.service

Type string · Required yes · Default none

Name of the Kubernetes Service.

: web
port_name

services[].kubernetes.port_name

Type string · Required no · Default empty

Name of the port to use, among the ports of the Service.

: http
kubeconfig

services[].kubernetes.kubeconfig

Type path · Required no · Default empty

Kubeconfig to connect with. A leading ~/ is the home directory.

: ~/.kube/config
context

services[].kubernetes.context

Type string · Required no · Default empty

Context of the kubeconfig. Empty means its current context.

: prod

Without kubeconfig, Vigie looks for $KUBECONFIG, then ~/.kube/config, then the service account of the pod it runs in. A leading ~/ is the home directory of the user that runs Vigie, which is a dynamic user with the systemd unit of the repository, so give an absolute path there.

Two services can read two clusters, each with its own kubeconfig or context.

Vigie loads the kubeconfig when it loads the services, at start and on each reloadReading the configuration file again to replace the services, on SIGHUP or POST /reload. See Reload the services.. It reads the cluster each time the cache of the service expires, every 5 seconds by default while clients poll, with two requests, one for the Service and one for its EndpointSlices. Vigie doesn’t rate-limit them, so raise cache_ttl for a busy API server.

A kubeconfig that can’t be loaded stops Vigie at start, and makes a reload keep the previous services. vigie check-config doesn’t load it, so it can’t catch that.

Terminal window
kubectl -n shop get endpointslices -l kubernetes.io/service-name=web
curl -s 'http://localhost:8080/services?service_name=web'
Error in the answerCause
get service shop/web: <err>The Service doesn’t exist, or the cluster can’t be reached or refuses Vigie. A forbidden error means the Role is missing.
list endpointslices of service shop/web: <err>Vigie can read the Service but not list its EndpointSlices, usually the second rule of the Role is missing.
port http not found in service shop/webThe Service has no port named port_name.

Configuration lists every key of the source.