diff --git a/incubator/fluentd/examples-elasticsearch-kibana/es.libsonnet b/incubator/fluentd/examples-elasticsearch-kibana/es.libsonnet new file mode 100644 index 0000000..5e0ab09 --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/es.libsonnet @@ -0,0 +1,155 @@ +local k = import "ksonnet.beta.2/k.libsonnet"; + +// Destructuring imports for base. +local container = k.core.v1.replicationController.mixin.spec.template.spec.containersType; +local containerPort = container.portsType; +local env = container.envType; +local rc = k.core.v1.replicationController; +local service = k.core.v1.service; +local servicePort = service.mixin.spec.portsType; +local volume = k.core.v1.replicationController.mixin.spec.template.spec.volumesType; +local volumeMount = container.volumeMountsType; + +// Destructuring RBAC imports. +local svcAccount = k.core.v1.serviceAccount; +local clRoleBinding = k.rbac.v1beta1.clusterRoleBinding; +local clRole = k.rbac.v1beta1.clusterRole; +local subject = clRoleBinding.subjectsType; +local rule = clRole.rulesType; + +{ + app:: { + new(config):: + local dbPortName = "db"; + local rbacObjs = $.parts.rbac(config.rbac.accountName, config.namespace); + rbacObjs + { + toArray():: + local objs = [self.service, self.controller]; + if "toArray" in super + then super.toArray() + objs + else objs, + service:: $.parts.service(dbPortName, config), + controller:: $.parts.controller(dbPortName, config), + }, + }, + + parts:: { + local boilerplate = { + appName:: "elasticsearch-logging", + + storageName:: "es-persistent-storage", + + controller:: { + selector:: { + "k8s-app": boilerplate.appName, + "version": "v1", + }, + + labels:: self.selector + { + "addonmanager.kubernetes.io/mode": "Reconcile", + "kubernetes.io/cluster-service": "true", + }, + + templateLabels:: self.selector + { + "kubernetes.io/cluster-service": "true", + }, + }, + + service:: { + labels:: { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": boilerplate.appName, + "kubernetes.io/cluster-service": "true", + "kubernetes.io/name": "Elasticsearch" + }, + + selector:: {"k8s-app": boilerplate.appName}, + }, + }, + + container(dbPortName, config):: + local dbPort = + containerPort.newNamed(dbPortName, 9200) + + containerPort.protocol("TCP"); + local transportPort = + containerPort.newNamed("transport", 9300) + + containerPort.protocol("TCP"); + local dataMount = volumeMount.new(boilerplate.storageName, "/data"); + local resources = + container.mixin.resources.limits({cpu: "1000m"}) + + container.mixin.resources.requests({cpu: "100m"}); + container.new( + boilerplate.appName, + "gcr.io/google_containers/elasticsearch:%s" % config.container.tag) + + container.env(env.fromFieldPath("NAMESPACE", "metadata.namespace")) + + container.ports([dbPort, transportPort]) + + container.volumeMounts(dataMount) + + resources, + + controller(dbPortName, config):: + local dataVol = volume.fromEmptyDir(boilerplate.storageName, {}); + rc.new() + + rc.mixin.metadata.name("elasticsearch-logging-v1") + + rc.mixin.metadata.namespace(config.namespace) + + rc.mixin.metadata.labels(boilerplate.controller.labels) + + rc.mixin.spec.replicas(2) + + rc.mixin.spec.selector(boilerplate.controller.selector) + + rc.mixin.spec.template.metadata.labels(boilerplate.controller.templateLabels) + + rc.mixin.spec.template.spec.containers($.parts.container(dbPortName, config)) + + rc.mixin.spec.template.spec.volumes(dataVol) + + rc.mixin.spec.template.spec.serviceAccountName(config.rbac.accountName), + + service(dbPortName, config):: + local port = + servicePort.new(9200, dbPortName) + + servicePort.protocol("TCP"); + service.new("elasticsearch-logging", boilerplate.service.selector, [port]) + + service.mixin.metadata.namespace(config.namespace) + + service.mixin.metadata.labels(boilerplate.service.labels) + + service.mixin.spec.type("LoadBalancer"), + + // Creates all top-level objects and mixins we need to add RBAC + // support to support the ElasticSearch logging infrastructure. + rbac(name, namespace):: + local metadata = svcAccount.mixin.metadata.name(name) + + svcAccount.mixin.metadata.namespace(namespace); + + local hcServiceAccount = svcAccount.new() + + metadata; + + local hcClusterRole = + clRole.new() + + metadata + + clRole.rules( + rule.new() + + rule.apiGroups("*") + + rule.resources(["namespaces", "services", "endpoints"]) + + rule.verbs(["get"]) + ); + + local hcClusterRoleBinding = + clRoleBinding.new() + + metadata + + clRoleBinding.mixin.roleRef.apiGroup("rbac.authorization.k8s.io") + + clRoleBinding.mixin.roleRef.name(name) + + clRoleBinding.mixin.roleRef.mixinInstance({kind: "ClusterRole"}) + + clRoleBinding.subjects( + subject.new() + + subject.name(name) + + subject.namespace(namespace) + {kind: "ServiceAccount"} + ); + + // Return. + {} + { + toArray():: + local objs = [self.account, self.clusterRole, self.roleBinding]; + if "toArray" in super + then super.toArray() + objs + else objs, + account:: hcServiceAccount, + clusterRole:: hcClusterRole, + roleBinding:: hcClusterRoleBinding, + }, + }, +} \ No newline at end of file diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/es.jsonnet b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/es.jsonnet new file mode 100644 index 0000000..2dc6a76 --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/es.jsonnet @@ -0,0 +1,30 @@ +local k = import "ksonnet.beta.2/k.libsonnet"; + +local es = import "../es.libsonnet"; + +// Configuration. Specifies how to set up the ElasticSearch app. +local config = { + namespace:: "elasticsearch", + rbac:: { + accountName:: "elasticsearch-serviceaccount", + }, + container:: { + tag:: "v2.4.1-2", + }, +}; + +// TODO: Move the rbac out here, too. +k.core.v1.list.new( + es.app.new(config).toArray() + + [ + { + "kind": "Namespace", + "apiVersion": "v1", + "metadata": { + "name": config.namespace, + "labels": { + "name": config.namespace + } + } + } + ]) diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/fluentd-es-ds.jsonnet b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/fluentd-es-ds.jsonnet new file mode 100644 index 0000000..28b30d0 --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/fluentd-es-ds.jsonnet @@ -0,0 +1,34 @@ +local k = import "ksonnet.beta.2/k.libsonnet"; + +local fluentd = import "incubator/fluentd/fluentd.libsonnet"; + +// Destructuring imports for base. +local container = k.core.v1.replicationController.mixin.spec.template.spec.containersType; +local ds = k.extensions.v1beta1.daemonSet; +local volume = k.core.v1.replicationController.mixin.spec.template.spec.volumesType; +local volumeMount = container.volumeMountsType; + +local config = { + namespace:: "elasticsearch", + container:: { + name:: "fluentd-es", + tag:: "1.22", + }, + daemonSet:: { + name:: "fluentd-es-v1.22", + }, + rbac:: { + accountName:: "fluentd-serviceaccount" + }, +}; + +local ds = + fluentd.app.daemonSetBuilder.new(config) + + fluentd.app.daemonSetBuilder.configureForPodLogs(config); + +local rbacObjs = fluentd.app.admin.rbacForPodLogs(config); + +k.core.v1.list.new( + ds.toArray() + + rbacObjs.toArray() +) diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/es.json b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/es.json new file mode 100644 index 0000000..be29c14 --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/es.json @@ -0,0 +1,176 @@ +{ + "apiVersion": "v1", + "items": [ + { + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": { + "name": "elasticsearch-serviceaccount", + "namespace": "elasticsearch" + } + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1beta1", + "kind": "ClusterRole", + "metadata": { + "name": "elasticsearch-serviceaccount", + "namespace": "elasticsearch" + }, + "rules": [ + { + "apiGroups": [ + "*" + ], + "resources": [ + "namespaces", + "services", + "endpoints" + ], + "verbs": [ + "get" + ] + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1beta1", + "kind": "ClusterRoleBinding", + "metadata": { + "name": "elasticsearch-serviceaccount", + "namespace": "elasticsearch" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "elasticsearch-serviceaccount" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "elasticsearch-serviceaccount", + "namespace": "elasticsearch" + } + ] + }, + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "labels": { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "elasticsearch-logging", + "kubernetes.io/cluster-service": "true", + "kubernetes.io/name": "Elasticsearch" + }, + "name": "elasticsearch-logging", + "namespace": "elasticsearch" + }, + "spec": { + "ports": [ + { + "port": 9200, + "protocol": "TCP", + "targetPort": "db" + } + ], + "selector": { + "k8s-app": "elasticsearch-logging" + }, + "type": "LoadBalancer" + } + }, + { + "apiVersion": "v1", + "kind": "ReplicationController", + "metadata": { + "labels": { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "elasticsearch-logging", + "kubernetes.io/cluster-service": "true", + "version": "v1" + }, + "name": "elasticsearch-logging-v1", + "namespace": "elasticsearch" + }, + "spec": { + "replicas": 2, + "selector": { + "k8s-app": "elasticsearch-logging", + "version": "v1" + }, + "template": { + "metadata": { + "labels": { + "k8s-app": "elasticsearch-logging", + "kubernetes.io/cluster-service": "true", + "version": "v1" + } + }, + "spec": { + "containers": [ + { + "env": [ + { + "name": "NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + } + ], + "image": "gcr.io/google_containers/elasticsearch:v2.4.1-2", + "name": "elasticsearch-logging", + "ports": [ + { + "containerPort": 9200, + "name": "db", + "protocol": "TCP" + }, + { + "containerPort": 9300, + "name": "transport", + "protocol": "TCP" + } + ], + "resources": { + "limits": { + "cpu": "1000m" + }, + "requests": { + "cpu": "100m" + } + }, + "volumeMounts": [ + { + "mountPath": "/data", + "name": "es-persistent-storage", + "readOnly": false + } + ] + } + ], + "serviceAccountName": "elasticsearch-serviceaccount", + "volumes": [ + { + "emptyDir": { }, + "name": "es-persistent-storage" + } + ] + } + } + } + }, + { + "apiVersion": "v1", + "kind": "Namespace", + "metadata": { + "labels": { + "name": "elasticsearch" + }, + "name": "elasticsearch" + } + } + ], + "kind": "List" +} diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/fluentd-es-ds.json b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/fluentd-es-ds.json new file mode 100644 index 0000000..01eea8f --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/fluentd-es-ds.json @@ -0,0 +1,138 @@ +{ + "apiVersion": "v1", + "items": [ + { + "apiVersion": "extensions/v1beta1", + "kind": "DaemonSet", + "metadata": { + "labels": { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "fluentd-es", + "kubernetes.io/cluster-service": "true", + "version": "v1.22" + }, + "name": "fluentd-es-v1.22", + "namespace": "elasticsearch" + }, + "spec": { + "template": { + "metadata": { + "annotations": { + "scheduler.alpha.kubernetes.io/critical-pod": "" + }, + "labels": { + "k8s-app": "fluentd-es", + "kubernetes.io/cluster-service": "true", + "version": "v1.22" + } + }, + "spec": { + "containers": [ + { + "command": [ + "/bin/sh", + "-c", + "/usr/sbin/td-agent 2>&1 >> /var/log/fluentd.log" + ], + "image": "gcr.io/google_containers/fluentd-elasticsearch:1.22", + "name": "fluentd-es", + "resources": { + "limits": { + "memory": "200Mi" + }, + "requests": { + "cpu": "100m", + "memory": "200Mi" + } + }, + "volumeMounts": [ + { + "mountPath": "/var/log", + "name": "varlog", + "readOnly": false + }, + { + "mountPath": "/var/lib/docker/containers", + "name": "varlibdockercontainers", + "readOnly": true + } + ] + } + ], + "nodeSelector": { + "beta.kubernetes.io/fluentd-ds-ready": "true" + }, + "serviceAccountName": "fluentd-serviceaccount", + "terminationGracePeriodSeconds": 30, + "volumes": [ + { + "hostPath": { + "path": "/var/log" + }, + "name": "varlog" + }, + { + "hostPath": { + "path": "/var/lib/docker/containers" + }, + "name": "varlibdockercontainers" + } + ] + } + } + } + }, + { + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": { + "name": "fluentd-serviceaccount", + "namespace": "elasticsearch" + } + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1beta1", + "kind": "ClusterRole", + "metadata": { + "name": "fluentd-serviceaccount", + "namespace": "elasticsearch" + }, + "rules": [ + { + "apiGroups": [ + "*" + ], + "resources": [ + "pods", + "nodes" + ], + "verbs": [ + "list", + "watch" + ] + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1beta1", + "kind": "ClusterRoleBinding", + "metadata": { + "name": "fluentd-serviceaccount", + "namespace": "elasticsearch" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "fluentd-serviceaccount" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "fluentd-serviceaccount", + "namespace": "elasticsearch" + } + ] + } + ], + "kind": "List" +} diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/kibana.json b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/kibana.json new file mode 100644 index 0000000..20c47e7 --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/generated/kibana.json @@ -0,0 +1,93 @@ +{ + "apiVersion": "v1", + "items": [ + { + "apiVersion": "extensions/v1beta1", + "kind": "Deployment", + "metadata": { + "labels": { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "kibana-logging", + "kubernetes.io/cluster-service": "true" + }, + "name": "kibana-logging", + "namespace": "kube-system" + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "k8s-app": "kibana-logging" + } + }, + "template": { + "metadata": { + "labels": { + "k8s-app": "kibana-logging" + } + }, + "spec": { + "containers": [ + { + "env": [ + { + "name": "ELASTICSEARCH_URL", + "value": "http://elasticsearch-logging:9200" + }, + { + "name": "KIBANA_BASE_URL", + "value": "/api/v1/proxy/namespaces/kube-system/services/kibana-logging" + } + ], + "image": "gcr.io/google_containers/kibana:v4.6.1-1", + "name": "kibana-logging", + "ports": [ + { + "containerPort": 5601, + "name": "ui", + "protocol": "TCP" + } + ], + "resources": { + "limits": { + "cpu": "100m" + }, + "requests": { + "cpu": "100m" + } + } + } + ] + } + } + } + }, + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "labels": { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "kibana-logging", + "kubernetes.io/cluster-service": "true", + "kubernetes.io/name": "Kibana" + }, + "name": "kibana-logging", + "namespace": "kube-system" + }, + "spec": { + "ports": [ + { + "port": 5601, + "protocol": "TCP", + "targetPort": "ui" + } + ], + "selector": { + "k8s-app": "kibana-logging" + } + } + } + ], + "kind": "List" +} diff --git a/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/kibana.jsonnet b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/kibana.jsonnet new file mode 100644 index 0000000..2c140ad --- /dev/null +++ b/incubator/fluentd/examples-elasticsearch-kibana/using-daemonset-builder/kibana.jsonnet @@ -0,0 +1,65 @@ +local k = import "ksonnet.beta.2/k.libsonnet"; + +// Destructuring imports for base. +local container = k.extensions.v1beta1.deployment.mixin.spec.template.spec.containersType; +local containerPort = container.portsType; +local deployment = k.extensions.v1beta1.deployment; +local env = container.envType; +local service = k.core.v1.service; +local servicePort = service.mixin.spec.portsType; + +local podLabels = { + "k8s-app": "kibana-logging" +}; + +local kibanaContainer = + local ports = + containerPort.newNamed("ui", 5601) + + containerPort.protocol("TCP"); + container.new("kibana-logging", "gcr.io/google_containers/kibana:v4.6.1-1") + + container.env([ + env.new("ELASTICSEARCH_URL", "http://elasticsearch-logging:9200"), + env.new("KIBANA_BASE_URL", "/api/v1/proxy/namespaces/kube-system/services/kibana-logging") + ]) + + container.ports(ports) { + "resources": { + "limits": { + "cpu": "100m" + }, + "requests": { + "cpu": "100m" + } + } + }; + +local kibanaDeployment = + deployment.new("kibana-logging", 1, kibanaContainer, podLabels) + + deployment.mixin.metadata.namespace("kube-system") + + deployment.mixin.metadata.labels({ + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "kibana-logging", + "kubernetes.io/cluster-service": "true" + }) + + deployment.mixin.spec.selector.matchLabels(podLabels); + +local serviceLabels = { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "kibana-logging", + "kubernetes.io/cluster-service": "true", + "kubernetes.io/name": "Kibana" +}; + +local selector = { + "k8s-app": "kibana-logging" +}; + +local port = + servicePort.new(5601, "ui") + + servicePort.protocol("TCP"); + +local kibanaService = + service.new("kibana-logging", selector, port) + + service.mixin.metadata.namespace("kube-system") + + service.mixin.metadata.labels(serviceLabels); + +k.core.v1.list.new([kibanaDeployment, kibanaService]) diff --git a/incubator/fluentd/fluentd.libsonnet b/incubator/fluentd/fluentd.libsonnet new file mode 100644 index 0000000..dc9da9f --- /dev/null +++ b/incubator/fluentd/fluentd.libsonnet @@ -0,0 +1,190 @@ +local k = import "ksonnet.beta.2/k.libsonnet"; + +// Destructuring imports for base. +local container = k.core.v1.replicationController.mixin.spec.template.spec.containersType; +local ds = k.extensions.v1beta1.daemonSet; +local volume = ds.mixin.spec.template.spec.volumesType; +local volumeMount = container.volumeMountsType; + +// Destructuring RBAC imports. +local svcAccount = k.core.v1.serviceAccount; +local clRoleBinding = k.rbac.v1beta1.clusterRoleBinding; +local clRole = k.rbac.v1beta1.clusterRole; +local subject = clRoleBinding.subjectsType; +local rule = clRole.rulesType; + +{ + util:: { + containerNameInSet(items):: + local itemSet = + if std.type(items) == "array" + then std.set(items) + else std.set([items]); + function(container) std.length(std.setInter(itemSet, std.set([container.name]))) > 0, + }, + + app:: { + admin:: { + rbacForPodLogs(config):: + $.parts.rbac(config.rbac.accountName, config.namespace), + }, + + daemonSetBuilder:: { + new(config):: { + toArray():: [self.daemonSet], + daemonSet:: $.parts.daemonSet(config.daemonSet.name, config.container.name, config.container.tag, config.namespace) + }, + + configureForPodLogs( + config, + varlogVolName="varlog", + podLogsVolName="varlibdockercontainers", + ):: + {} + { + daemonSet+:: + $.mixin.daemonSet.addHostMountedPodLogs( + varlogVolName, + podLogsVolName, + $.util.containerNameInSet(config.container.name)) + + ds.mixin.spec.template.spec.serviceAccountName(config.rbac.accountName) + }, + }, + }, + + parts:: { + local boilerplate = { + dsLabels:: { + "addonmanager.kubernetes.io/mode": "Reconcile", + "k8s-app": "fluentd-es", + "kubernetes.io/cluster-service": "true", + "version": "v1.22" + }, + + templateLabels:: { + "k8s-app": "fluentd-es", + "kubernetes.io/cluster-service": "true", + "version": "v1.22" + }, + + fluentdSelector:: { + "beta.kubernetes.io/fluentd-ds-ready": "true" + }, + }, + + container(name, tag):: + container.new(name, "gcr.io/google_containers/fluentd-elasticsearch:%s" % tag) + + container.command([ + "/bin/sh", + "-c", + "/usr/sbin/td-agent 2>&1 >> /var/log/fluentd.log" + ]) + + container.mixin.resources.limits({"memory": "200Mi"}) + + container.mixin.resources.requests({ + "cpu": "100m", + "memory": "200Mi" + }), + + daemonSet(dsName, containerName, conatinerTag, namespace):: + ds.new() + + ds.mixin.metadata.name(dsName) + + ds.mixin.metadata.namespace(namespace) + + ds.mixin.metadata.labels(boilerplate.dsLabels) + + ds.mixin.spec.template.metadata.annotations({ + "scheduler.alpha.kubernetes.io/critical-pod": "" + }) + + ds.mixin.spec.template.metadata.labels(boilerplate.templateLabels) + + ds.mixin.spec.template.spec.containers(self.container(containerName, conatinerTag)) + + ds.mixin.spec.template.spec.terminationGracePeriodSeconds(30) + + ds.mixin.spec.template.spec.nodeSelector(boilerplate.fluentdSelector), + + // Creates all top-level objects and mixins we need to add RBAC + // support to a Honeycomb agent DaemonSet. + rbac(name, namespace):: + local metadata = svcAccount.mixin.metadata.name(name) + + svcAccount.mixin.metadata.namespace(namespace); + + local hcServiceAccount = svcAccount.new() + + metadata; + + local hcClusterRole = + clRole.new() + + metadata + + clRole.rules( + rule.new() + + rule.apiGroups("*") + + rule.resources(["pods", "nodes"]) + + rule.verbs(["list", "watch"]) + ); + + local hcClusterRoleBinding = + clRoleBinding.new() + + metadata + + clRoleBinding.mixin.roleRef.apiGroup("rbac.authorization.k8s.io") + + clRoleBinding.mixin.roleRef.name(name) + + clRoleBinding.mixin.roleRef.mixinInstance({kind: "ClusterRole"}) + + clRoleBinding.subjects( + subject.new() + + subject.name(name) + + subject.namespace(namespace) + {kind: "ServiceAccount"} + ); + + // Return. + {} + { + toArray():: + local objs = [self.account, self.clusterRole, self.roleBinding]; + if "toArray" in super + then super.toArray() + objs + else objs, + account:: hcServiceAccount, + clusterRole:: hcClusterRole, + roleBinding:: hcClusterRoleBinding, + }, + + podLogs(varlogName, podlogsName):: + local varLogVol = volume.fromHostPath(varlogName, "/var/log"); + local podLogsVol = + // Pod logs are located on the host at well-known path. + // Define volumes and mounts for these paths, so the + // Honeytailer can access them. + volume.fromHostPath(podlogsName,"/var/lib/docker/containers"); + { + varLogVolume:: varLogVol, + varLogMount:: volumeMount.new(varLogVol.name, varLogVol.hostPath.path), + podLogVolume:: podLogsVol, + podLogMount:: + // podLogsVol is read-only because the directory is shared + // with other pods + volumeMount.new(podLogsVol.name, podLogsVol.hostPath.path, true), + }, + }, + + mixin:: { + daemonSet:: { + // addhostMountedPodLogs takes a two volume names and produces a + // mixin that will mount the Kubernetes pod logs into a set of + // containers specified by `containerSelector`. + addHostMountedPodLogs( + varlogName, podlogsName, containerSelector=function(c) true + ):: + local podLogs = $.parts.podLogs(varlogName, podlogsName); + + // Add volume to DaemonSet. + ds.mixin.spec.template.spec.volumes([ + podLogs.varLogVolume, + podLogs.podLogVolume, + ]) + + + // Add volume mount to selected containers in the DaemonSet. + ds.mapContainers( + function (c) + if containerSelector(c) + then + c + container.volumeMounts([ + podLogs.varLogMount, + podLogs.podLogMount, + ]) + else c), + }, + }, +} diff --git a/incubator/honeycomb-agent/honeycomb-agent.libsonnet b/incubator/honeycomb-agent/honeycomb-agent.libsonnet index a9a25e9..3ae1b72 100644 --- a/incubator/honeycomb-agent/honeycomb-agent.libsonnet +++ b/incubator/honeycomb-agent/honeycomb-agent.libsonnet @@ -140,7 +140,7 @@ local rule = clRole.rulesType; varlogVolName, podLogsVolName, $.util.containerNameInSet(config.agent.containerName)) + - ds.mixin.spec.template.spec.serviceAccountName(config.rbac.accountName) + deployment.mixin.spec.template.spec.serviceAccountName(config.rbac.accountName) }, }, },