Skip to content

Commit

Permalink
mixins: Normalize headless service name for query-frontend/scheduler (#…
Browse files Browse the repository at this point in the history
…8880)

**What this PR does / why we need it**:
Mixins in general are rather complex pieces of code to consume. When
trying to use the loki mixins it wasn't apparent at first that I could
use a headless service for DNS SRV discovery for both query_frontend and
query_scheduler, especially because for frontend the service is named
`query_frontend_headless_service` and for the scheduler, it's named
`query_scheduler_service_discovery`. Furthermore, the query_frontend
mixin provides a non-headless version of the service while
query_scheduler doesn't. This PR aims at normalizing this for end users,
both headless services are now named `query_frontend_headless_service`
and `query_scheduler_headless_service` and both also provide a
non-headless version of the service.
  • Loading branch information
JoaoBraveCoding authored Mar 23, 2023
1 parent 93a1c21 commit 1549fec
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@

* [7923](https://github.com/grafana/loki/pull/7923) **manohar-koukuntla**: Add zone aware ingesters in jsonnet deployment
* [8855](https://github.com/grafana/loki/pull/8855) **JoaoBraveCoding**: Add gRPC port to loki compactor mixin
* [8880](https://github.com/grafana/loki/pull/8880) **JoaoBraveCoding**: Normalize headless service name for query-frontend/scheduler

##### Fixes

Expand Down
6 changes: 6 additions & 0 deletions production/ksonnet/loki/common.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ local k = import 'ksonnet-util/kausal.libsonnet';
// This helps ensure we create SRV records starting with _grpclb
grpclbServiceFor(deployment):: k.util.serviceFor(deployment, $._config.service_ignored_labels, nameFormat='%(port)s'),

// Headless service for discovering IPs of pods instead of the service IP.
headlessService(deployment, name)::
$.util.grpclbServiceFor(deployment) +
k.core.v1.service.mixin.spec.withClusterIp('None') +
k.core.v1.service.mixin.spec.withPublishNotReadyAddresses(true) +
k.core.v1.service.mixin.metadata.withName(name),

readinessProbe::
container.mixin.readinessProbe.httpGet.withPath('/ready') +
Expand Down
22 changes: 11 additions & 11 deletions production/ksonnet/loki/query-frontend.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ local k = import 'ksonnet-util/kausal.libsonnet';
// so if the intention is to use the k8s service for load balancing,
// it is advised to use the below `query-frontend` service instead.
query_frontend_headless_service:
$.util.grpclbServiceFor($.query_frontend_deployment) +
// Make sure that query frontend worker, running in the querier, do resolve
// each query-frontend pod IP and NOT the service IP. To make it, we do NOT
// use the service cluster IP so that when the service DNS is resolved it
// returns the set of query-frontend IPs.
service.mixin.spec.withClusterIp('None') +
// Query frontend will not become ready until at least one querier connects
// which creates a chicken and egg scenario if we don't publish the
// query-frontend address before it's ready.
service.mixin.spec.withPublishNotReadyAddresses(true) +
service.mixin.metadata.withName('query-frontend-headless'),
// headlessService will make ensure two things:
// 1. Set clusterIP to "None": this makes it so that query frontend worker,
// running in the querier, resolve each query-frontend pod IP instead
// of the service IP. clusterIP set to "None" allow this by making it
// so that when the service DNS is resolved it returns the set of
// query-frontend IPs.
// 2. Set withPublishNotReadyAddresses to true: query frontend will not
// become ready until at least one querier connects which creates a
// chicken and egg scenario if we don't publish the query-frontend
// address before it's ready.
$.util.headlessService($.query_frontend_deployment, 'query-frontend-headless'),

query_frontend_service:
$.util.grpclbServiceFor($.query_frontend_deployment),
Expand Down
31 changes: 25 additions & 6 deletions production/ksonnet/loki/query-scheduler.libsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,29 @@ local k = import 'ksonnet-util/kausal.libsonnet';

local service = k.core.v1.service,

// Headless to make sure resolution gets IP address of target pods, and not service IP.
query_scheduler_discovery_service: if !$._config.query_scheduler_enabled then {} else
$.util.grpclbServiceFor($.query_scheduler_deployment) +
service.mixin.spec.withPublishNotReadyAddresses(true) +
service.mixin.spec.withClusterIp('None') +
service.mixin.metadata.withName('query-scheduler-discovery'),
// When this module was created the headless service was named
// 'query-scheduler-discovery' which diverges from the naming convention in
// query-frontend, this hidden attribute provides backward compatibility while
// allowing users to solve themselves this inconsistency
query_scheduler_headless_service_name:: 'query-scheduler-discovery',

// A headless service for discovering IPs of each query-scheduler pod.
// It leaves it up to the client to do any load-balancing of requests,
// so if the intention is to use the k8s service for load balancing,
// it is advised to use the below `query-scheduler` service instead.
query_scheduler_headless_service: if !$._config.query_scheduler_enabled then {} else
// headlessService will make ensure two things:
// 1. Set clusterIP to "None": this makes it so that query scheduler worker,
// running in the querier, resolve each query-scheduler pod IP instead
// of the service IP. clusterIP set to "None" allow this by making it
// so that when the service DNS is resolved it returns the set of
// query-scheduler IPs.
// 2. Set withPublishNotReadyAddresses to true: query scheduler will not
// become ready until at least one querier connects which creates a
// chicken and egg scenario if we don't publish the query-scheduler
// address before it's ready.
$.util.headlessService($.query_scheduler_deployment, $.query_scheduler_headless_service_name),

query_scheduler_service: if !$._config.query_scheduler_enabled then {} else
$.util.grpclbServiceFor($.query_scheduler_deployment),
}

0 comments on commit 1549fec

Please sign in to comment.