github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/production/ksonnet/enterprise-logs/main.libsonnet (about)

     1  // TODO(jdb): Use cluster_dns_suffix to configure absolute domain names so as to avoid excessive lookups.
     2  // TODO(jdb): Introduce utility functions for mapping over all containers, all microservices (modules), all apps, etc..
     3  local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet',
     4        clusterRole = k.rbac.v1.clusterRole,
     5        clusterRoleBinding = k.rbac.v1.clusterRoleBinding,
     6        container = k.core.v1.container,
     7        configMap = k.core.v1.configMap,
     8        deployment = k.apps.v1.deployment,
     9        job = k.batch.v1.job,
    10        policyRule = k.rbac.v1.policyRule,
    11        pvc = k.core.v1.persistentVolumeClaim,
    12        service = k.core.v1.service,
    13        serviceAccount = k.core.v1.serviceAccount,
    14        subject = k.rbac.v1.subject,
    15        statefulSet = k.apps.v1.statefulSet;
    16  local loki = import 'github.com/grafana/loki/production/ksonnet/loki/loki.libsonnet';
    17  local util = (import 'github.com/grafana/jsonnet-libs/ksonnet-util/util.libsonnet').withK(k) {
    18    withNonRootSecurityContext(uid, fsGroup=null)::
    19      { spec+: { template+: { spec+: { securityContext: {
    20        fsGroup: if fsGroup == null then uid else fsGroup,
    21        runAsNonRoot: true,
    22        runAsUser: uid,
    23      } } } } },
    24  };
    25  
    26  loki {
    27    _config+:: {
    28      commonArgs+:: {
    29        'auth.enabled': 'true',
    30        'auth.type': 'enterprise',
    31        'cluster-name':
    32          if self['auth.type'] == 'enterprise' then
    33            error 'must set _config.commonArgs.cluster-name'
    34          else null,
    35      },
    36  
    37      loki+: {
    38        distributor+: {
    39          ring: {
    40            kvstore: {
    41              store: 'memberlist',
    42            },
    43          },
    44        },
    45        ingester+: {
    46          lifecycler+: {
    47            ring: {
    48              kvstore: {
    49                store: 'memberlist',
    50              },
    51            },
    52          },
    53        },
    54        memberlist: {
    55          retransmit_factor: 2,
    56          gossip_interval: '5s',
    57          stream_timeout: '5s',
    58          abort_if_cluster_join_fails: false,
    59          bind_port: 7946,
    60          join_members: ['gossip-ring'],
    61        },
    62      },
    63  
    64      ingester_pvc_size: '50Gi',
    65      stateful_ingesters: true,
    66  
    67      querier_pvc_size: '50Gi',
    68      stateful_queriers: true,
    69  
    70      compactor_pvc_size: '50Gi',
    71    },
    72  
    73    _images+:: {
    74      loki: 'grafana/enterprise-logs:v1.1.0',
    75      kubectl: 'bitnami/kubectl',
    76    },
    77  
    78    admin_api_args:: self._config.commonArgs {
    79      'license.path': '/etc/gel-license/license.jwt',
    80      target: 'admin-api',
    81    },
    82    admin_api_container::
    83      container.new(name='admin-api', image=self._images.loki)
    84      + container.withArgs(util.mapToFlags(self.admin_api_args))
    85      + container.withPorts(loki.util.defaultPorts)
    86      + container.resources.withLimits({ cpu: '2', memory: '4Gi' })
    87      + container.resources.withRequests({ cpu: '500m', memory: '1Gi' })
    88      + loki.util.readinessProbe,
    89    admin_api_deployment:
    90      deployment.new(name='admin-api', replicas=3, containers=[self.admin_api_container])
    91      + deployment.spec.selector.withMatchLabelsMixin({ name: 'admin-api' })
    92      + deployment.spec.template.metadata.withLabelsMixin({ name: 'admin-api', gossip_ring_member: 'true' })
    93      + deployment.spec.template.spec.withTerminationGracePeriodSeconds(15)
    94      + util.configVolumeMount('loki', '/etc/loki/config')
    95      + util.secretVolumeMount('gel-license', '/etc/gel-license/')
    96      + util.withNonRootSecurityContext(uid=10001),
    97    admin_api_service:
    98      util.serviceFor(self.admin_api_deployment),
    99  
   100    compactor_data_pvc+: { spec+: { storageClassName:: null } },
   101    compactor_statefulset+: util.withNonRootSecurityContext(10001),
   102  
   103    // Remove consul in favor of memberlist.
   104    consul_config_map:: {},
   105    consul_deployment:: null,
   106    consul_service:: null,
   107  
   108    distributor_deployment+:
   109      deployment.spec.template.metadata.withLabelsMixin({ gossip_ring_member: 'true' })
   110      + util.withNonRootSecurityContext(uid=10001),
   111  
   112    gateway_args:: self._config.commonArgs {
   113      'license.path': '/etc/gel-license/license.jwt',
   114      'gateway.proxy.admin-api.url': 'http://admin-api:%s' % $._config.http_listen_port,
   115      'gateway.proxy.compactor.url': 'http://compactor:%s' % $._config.http_listen_port,
   116      'gateway.proxy.distributor.url': 'dns:///distributor:9095',
   117      'gateway.proxy.ingester.url': 'http://ingester:%s' % $._config.http_listen_port,
   118      'gateway.proxy.query-frontend.url': 'http://query-frontend:%s' % $._config.http_listen_port,
   119      'gateway.proxy.ruler.url': 'http://ruler:%s' % $._config.http_listen_port,
   120      target: 'gateway',
   121    },
   122    gateway_container::
   123      container.new(name='gateway', image=self._images.loki)
   124      + container.withArgs(util.mapToFlags(self.gateway_args))
   125      + container.withPorts(loki.util.defaultPorts)
   126      + container.resources.withLimits({ cpu: '2', memory: '4Gi' })
   127      + container.resources.withRequests({ cpu: '500m', memory: '1Gi' })
   128      + loki.util.readinessProbe,
   129    gateway_deployment:
   130      deployment.new(name='gateway', replicas=3, containers=[self.gateway_container])
   131      + deployment.spec.template.spec.withTerminationGracePeriodSeconds(15)
   132      + deployment.spec.template.spec.securityContext.withFsGroup(10001)
   133      + deployment.spec.template.spec.securityContext.withRunAsNonRoot(true)
   134      + deployment.spec.template.spec.securityContext.withRunAsUser(10001)
   135      + util.configVolumeMount('loki', '/etc/loki/config')
   136      + util.withNonRootSecurityContext(uid=10001),
   137    // Remove the htpasswd Secret used by the OSS Loki NGINX gateway.
   138    gateway_secret:: null,
   139    gateway_service:
   140      util.serviceFor(self.gateway_deployment),
   141  
   142    ingester_data_pvc+: { spec+: { storageClassName:: null } },
   143    ingester_statefulset+:
   144      statefulSet.spec.template.metadata.withLabelsMixin({ gossip_ring_member: 'true' })
   145      + util.withNonRootSecurityContext(uid=10001),
   146  
   147    querier_data_pvc+: { spec+: { storageClassName:: null } },
   148    querier_statefulset+:
   149      statefulSet.spec.template.metadata.withLabelsMixin({ gossip_ring_member: 'true' })
   150      + util.withNonRootSecurityContext(uid=10001),
   151  
   152    table_manager_deployment+: util.withNonRootSecurityContext(uid=10001),
   153  
   154    tokengen_args:: self._config.commonArgs {
   155      target: 'tokengen',
   156      'tokengen.token-file': '/shared/admin-token',
   157    },
   158    tokengen_container::
   159      container.new('tokengen', self._images.loki)
   160      + container.withPorts(loki.util.defaultPorts)
   161      + container.withArgs(util.mapToFlags(self.tokengen_args))
   162      + container.withVolumeMounts([
   163        { mountPath: '/etc/loki/config', name: 'config' },
   164        { mountPath: '/shared', name: 'shared' },
   165      ])
   166      + container.resources.withLimits({ memory: '4Gi' })
   167      + container.resources.withRequests({ cpu: '500m', memory: '500Mi' }),
   168    tokengen_create_secret_container::
   169      container.new('create-secret', self._images.kubectl)
   170      + container.withCommand([
   171        '/bin/bash',
   172        '-euc',
   173        'kubectl create secret generic gel-admin-token --from-file=token=/shared/admin-token --from-literal=grafana-token="$(base64 <(echo :$(cat /shared/admin-token)))"',
   174      ])
   175      + container.withVolumeMounts([{ mountPath: '/shared', name: 'shared' }]),
   176    tokengen_job::
   177      job.new('tokengen')
   178      + job.spec.withCompletions(1)
   179      + job.spec.withParallelism(1)
   180      + job.spec.template.spec.withContainers([self.tokengen_create_secret_container])
   181      + job.spec.template.spec.withInitContainers([self.tokengen_container])
   182      + job.spec.template.spec.withRestartPolicy('Never')
   183      + job.spec.template.spec.withServiceAccount('tokengen')
   184      + job.spec.template.spec.withServiceAccountName('tokengen')
   185      + job.spec.template.spec.withVolumes([
   186        { name: 'config', configMap: { name: 'loki' } },
   187        { name: 'shared', emptyDir: {} },
   188      ])
   189      + util.withNonRootSecurityContext(uid=10001),
   190    tokengen_service_account:
   191      serviceAccount.new('tokengen'),
   192    tokengen_cluster_role:
   193      clusterRole.new('tokengen')
   194      + clusterRole.withRules([
   195        policyRule.withApiGroups([''])
   196        + policyRule.withResources(['secrets'])
   197        + policyRule.withVerbs(['create']),
   198      ]),
   199    tokengen_cluster_role_binding:
   200      clusterRoleBinding.new()
   201      + clusterRoleBinding.metadata.withName('tokengen')
   202      + clusterRoleBinding.roleRef.withApiGroup('rbac.authorization.k8s.io')
   203      + clusterRoleBinding.roleRef.withKind('ClusterRole')
   204      + clusterRoleBinding.roleRef.withName('tokengen')
   205      + clusterRoleBinding.withSubjects([
   206        subject.new()
   207        + subject.withName('tokengen')
   208        + subject.withKind('ServiceAccount')
   209        + { namespace: $._config.namespace },
   210      ]),
   211  
   212    gossip_ring_service:
   213      service.new(
   214        name='gossip-ring',
   215        selector={ gossip_ring_member: 'true' },
   216        ports=[{ name: 'gossip-ring', port: 7946, protocol: 'TCP', targetPort: 7946 }],
   217      )
   218      + service.spec.withClusterIp('None')
   219      + service.spec.withPublishNotReadyAddresses(true),
   220  }