diff --git a/helpers/bumper.py b/helpers/bumper.py index 41a5500c9..1956ff65e 100755 --- a/helpers/bumper.py +++ b/helpers/bumper.py @@ -13,7 +13,7 @@ } file_patterns = [ - '*/examples/*/test/goss.y*ml', + '*/examples/*/test/goss*.y*ml', '*/examples/*/*.y*ml', '*/README.md', '*/values.y*ml', diff --git a/helpers/common.mk b/helpers/common.mk index 7f38e2d41..3afe2bfd1 100644 --- a/helpers/common.mk +++ b/helpers/common.mk @@ -3,6 +3,7 @@ default: test .ONESHELL: lint: + grep 'charts/' ./.helmignore || echo 'charts/' >> ./.helmignore helm lint --strict ./ template: @@ -15,7 +16,11 @@ build: pytest: pytest -sv --color=yes -test-all: template lint pytest +deps: + sed --in-place '/charts\//d' ./.helmignore + helm dependency update + +test-all: lint deps template pytest test: build docker run --rm -i --user "$$(id -u):$$(id -g)" -v $$(pwd)/../:/app -w /app/$$(basename $$(pwd)) helm-tester make test-all diff --git a/helpers/examples.mk b/helpers/examples.mk index 8319c1014..b0ce2e6e3 100644 --- a/helpers/examples.mk +++ b/helpers/examples.mk @@ -1,8 +1,10 @@ GOSS_VERSION := v0.3.6 +GOSS_FILE ?= goss.yaml +GOSS_SELECTOR ?= release=$(RELEASE) goss: - GOSS_CONTAINER=$$(kubectl get pods -l release=$(RELEASE) -o name | awk -F'/' 'NR==1{ print $$NF }') && \ + GOSS_CONTAINER=$$(kubectl get --no-headers=true pods -l $(GOSS_SELECTOR) -o custom-columns=:metadata.name | sed -n 1p ) && \ echo Testing with pod: $$GOSS_CONTAINER && \ - kubectl cp test/*.yaml $$GOSS_CONTAINER:/tmp/goss.yaml && \ - kubectl exec $$GOSS_CONTAINER -- sh -c "cd /tmp/ && curl -s -L https://github.com/aelsabbahy/goss/releases/download/$(GOSS_VERSION)/goss-linux-amd64 -o goss && chmod +rx ./goss && ./goss validate --retry-timeout 30s --sleep 5s --color --format documentation" + kubectl cp test/$(GOSS_FILE) $$GOSS_CONTAINER:/tmp/$(GOSS_FILE) && \ + kubectl exec $$GOSS_CONTAINER -- sh -c "cd /tmp/ && curl -s -L https://github.com/aelsabbahy/goss/releases/download/$(GOSS_VERSION)/goss-linux-amd64 -o goss && chmod +rx ./goss && ./goss --gossfile $(GOSS_FILE) validate --retry-timeout 30s --sleep 5s --color --format documentation" diff --git a/helpers/helm-tester/Dockerfile b/helpers/helm-tester/Dockerfile index b197fcc39..8843743ee 100644 --- a/helpers/helm-tester/Dockerfile +++ b/helpers/helm-tester/Dockerfile @@ -5,4 +5,6 @@ ENV HELM_VERSION=2.14.0 RUN wget https://storage.googleapis.com/kubernetes-helm/helm-v${HELM_VERSION}-linux-amd64.tar.gz && \ tar xfv helm-v${HELM_VERSION}-linux-amd64.tar.gz && \ mv linux-amd64/helm /usr/local/bin/ && \ - rm -rf linux-amd64 + rm -rf linux-amd64 && \ + HOME=/ helm init --client-only && \ + chmod 777 -R /.helm diff --git a/helpers/matrix.yml b/helpers/matrix.yml index fbe55177d..d8dbf5396 100644 --- a/helpers/matrix.yml +++ b/helpers/matrix.yml @@ -2,6 +2,7 @@ CHART: - elasticsearch - kibana - filebeat + - metricbeat ES_SUITE: - default - multi @@ -19,6 +20,11 @@ FILEBEAT_SUITE: - oss - security - 6.x +METRICBEAT_SUITE: + - default + - oss + - security + - 6.x KUBERNETES_VERSION: - '1.11' - '1.12' diff --git a/helpers/terraform/Makefile b/helpers/terraform/Makefile index afdf700ca..0052a6c2e 100644 --- a/helpers/terraform/Makefile +++ b/helpers/terraform/Makefile @@ -62,7 +62,10 @@ up: k8s for i in 1 2 3 4 5; do helm init --wait --upgrade && break || sleep 5; done integration: creds - cd ../../$(CHART)/examples/$(SUITE) && \ + cd ../../$(CHART)/ && \ + helm init --client-only && \ + helm dependency update && \ + cd ./examples/$(SUITE) && \ make build: diff --git a/metricbeat/.helmignore b/metricbeat/.helmignore new file mode 100644 index 000000000..e12c0b4b9 --- /dev/null +++ b/metricbeat/.helmignore @@ -0,0 +1,2 @@ +tests/ +.pytest_cache/ diff --git a/metricbeat/Chart.yaml b/metricbeat/Chart.yaml new file mode 100755 index 000000000..debbbe01c --- /dev/null +++ b/metricbeat/Chart.yaml @@ -0,0 +1,11 @@ +description: Official Elastic helm chart for Metricbeat +home: https://github.com/elastic/helm-charts +maintainers: +- email: helm-charts@elastic.co + name: Elastic +name: metricbeat +version: 7.2.0 +appVersion: 7.2.0 +sources: + - https://github.com/elastic/beats +icon: https://helm.elastic.co/icons/metricbeat.png diff --git a/metricbeat/Makefile b/metricbeat/Makefile new file mode 100644 index 000000000..22218a1f6 --- /dev/null +++ b/metricbeat/Makefile @@ -0,0 +1 @@ +include ../helpers/common.mk diff --git a/metricbeat/README.md b/metricbeat/README.md new file mode 100644 index 000000000..9c728ad8b --- /dev/null +++ b/metricbeat/README.md @@ -0,0 +1,112 @@ +# Metricbeat Helm Chart + +This functionality is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features. + +This helm chart is a lightweight way to configure and run our official [Metricbeat docker image](https://www.elastic.co/guide/en/beats/metricbeat/current/running-on-docker.html). + +## Requirements + +* Kubernetes >= 1.8 +* [Helm](https://helm.sh/) >= 2.8.0 + +## Installing + +* Add the elastic helm charts repo + ``` + helm repo add elastic https://helm.elastic.co + ``` +* Install it + ``` + helm install --name metricbeat elastic/metricbeat --version 7.2.0 + ``` + +## Compatibility + +This chart is tested with the latest supported versions. The currently tested versions are: + +| 6.x | 7.x | +| ----- | ----- | +| 6.8.1 | 7.2.0 | + +Examples of installing older major versions can be found in the [examples](./examples) directory. + +While only the latest releases are tested, it is possible to easily install old or new releases by overriding the `imageTag`. To install version `7.2.0` of metricbeat it would look like this: + +``` +helm install --name metricbeat elastic/metricbeat --version 7.2.0 --set imageTag=7.2.0 +``` + + +## Configuration +| Parameter | Description | Default | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `metricbeatConfig` | Allows you to add any config files in `/usr/share/metricbeat` such as `metricbeat.yml`. See [values.yaml](./values.yaml) for an example of the formatting with the default configuration. | see [values.yaml](./values.yaml) | +| `extraEnvs` | Extra [environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#using-environment-variables-inside-of-your-config) which will be appended to the `env:` definition for the container | `[]` | +| `extraVolumeMounts` | Any extra volumes mounts to define for the Metricbeat container | `[]` | +| `extraVolumes` | Any extra volumes to define for the pod | `[]` | +| `hostPathRoot` | Fully-qualified [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) that will be used to persist Metricbeat registry data | `/var/lib` | +| `image` | The Metricbeat docker image | `docker.elastic.co/beats/metricbeat` | +| `imageTag` | The Metricbeat docker image tag | `7.2.0` | +| `imagePullPolicy` | The Kubernetes [imagePullPolicy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) value | `IfNotPresent` | +| `imagePullSecrets` | Configuration for [imagePullSecrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret) so that you can use a private registry for your image | `[]` | +| `managedServiceAccount` | Whether the `serviceAccount` should be managed by this helm chart. Set this to `false` in order to manage your own service account and related roles. | `true` | +| `podAnnotations` | Configurable [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) applied to all Metricbeat pods | `{}` | +| `podSecurityContext` | Configurable [podSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for Metricbeat pod execution environment | `runAsUser: 0`
`privileged: false` | +| `livenessProbe` | Parameters to pass to [liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) checks for values such as timeouts and thresholds. | `failureThreshold: 3`
`initialDelaySeconds: 10`
`periodSeconds: 10`
`successThreshold: 3`
`timeoutSeconds: 5` | +| `readinessProbe` | Parameters to pass to [readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) checks for values such as timeouts and thresholds. | `failureThreshold: 3`
`initialDelaySeconds: 10`
`periodSeconds: 10`
`successThreshold: 3`
`timeoutSeconds: 5` | +| `resources` | Allows you to set the [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) for the `DaemonSet` | `requests.cpu: 100m`
`requests.memory: 100Mi`
`limits.cpu: 1000m`
`limits.memory: 200Mi` | +| `serviceAccount` | Custom [serviceAccount](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) that Metricbeat will use during execution. By default will use the service account created by this chart. | `""` | +| `secretMounts` | Allows you easily mount a secret as a file inside the `DaemonSet`. Useful for mounting certificates and other secrets. See [values.yaml](./values.yaml) for an example | `[]` | +| `terminationGracePeriod` | Termination period (in seconds) to wait before killing Metricbeat pod process on pod shutdown | `30` | +| `tolerations` | Configurable [tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) | `[]` | +| `updateStrategy` | The [updateStrategy](https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy) for the `DaemonSet`. By default Kubernetes will kill and recreate pods on updates. Setting this to `OnDelete` will require that pods be deleted manually. | `RollingUpdate` | +| `replicas` | The replica count for the metricbeat deployment talking to kube-state-metrics | `1` | + +## Examples + +In [examples/](./examples) you will find some example configurations. These examples are used for the automated testing of this helm chart. + +### Default + +* Deploy the [default Elasticsearch helm chart](../elasticsearch/README.md#default) +* Deploy Metricbeat with the default values + ``` + cd examples/default + make + ``` +* You can now setup a port forward for Elasticsearch to observe Metricbeat indices + ``` + kubectl port-forward svc/elasticsearch-master 9200 + curl localhost:9200/_cat/indices + ``` + +## Testing + +This chart uses [pytest](https://docs.pytest.org/en/latest/) to test the templating logic. The dependencies for testing can be installed from the [`requirements.txt`](../requirements.txt) in the parent directory. + +``` +pip install -r ../requirements.txt +make pytest +``` + +You can also use `helm template` to look at the YAML being generated + +``` +make template +``` + +It is possible to run all of the tests and linting inside of a docker container + +``` +make test +``` + +## Integration Testing + +Integration tests are run using [goss](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md) which is a serverspec like tool written in golang. See [goss.yaml](examples/default/test/goss.yaml) for an example of what the tests look like. + +To run the goss tests against the default example: +``` +cd examples/default +make goss +``` diff --git a/metricbeat/examples/6.x/Makefile b/metricbeat/examples/6.x/Makefile new file mode 100644 index 000000000..05a66d2bc --- /dev/null +++ b/metricbeat/examples/6.x/Makefile @@ -0,0 +1,17 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-metricbeat-six +GOSS_SELECTOR = release=$(RELEASE),app=helm-metricbeat-six-metricbeat + +install: + helm upgrade --wait --timeout=600 --install $(RELEASE) --values values.yaml ../../ + +purge: + helm del --purge $(RELEASE) + +test-metrics: + GOSS_FILE=goss-metrics.yaml make goss GOSS_SELECTOR=release=$(RELEASE),app=helm-metricbeat-six-metricbeat-metrics + +test: install goss test-metrics diff --git a/metricbeat/examples/6.x/test/goss-metrics.yaml b/metricbeat/examples/6.x/test/goss-metrics.yaml new file mode 100644 index 000000000..fd776f6ad --- /dev/null +++ b/metricbeat/examples/6.x/test/goss-metrics.yaml @@ -0,0 +1,43 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/kube-state-metrics-metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://six-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-6.8.1' + http://six-master:9200/_search?q=metricset.name:state_deployment: + status: 200 + timeout: 2000 + body: + - 'metricbeat-6.8.1' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://six-master:9200' + - 'version: 6.8.1' diff --git a/metricbeat/examples/6.x/test/goss.yaml b/metricbeat/examples/6.x/test/goss.yaml new file mode 100644 index 000000000..ba21aab47 --- /dev/null +++ b/metricbeat/examples/6.x/test/goss.yaml @@ -0,0 +1,51 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/metricbeat/metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://six-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-6.8.1' + http://six-master:9200/_search?q=metricset.name:container: + status: 200 + timeout: 2000 + body: + - 'metricbeat-6.8.1' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://six-master:9200' + - 'version: 6.8.1' diff --git a/metricbeat/examples/6.x/values.yaml b/metricbeat/examples/6.x/values.yaml new file mode 100644 index 000000000..d0eeea620 --- /dev/null +++ b/metricbeat/examples/6.x/values.yaml @@ -0,0 +1,5 @@ +imageTag: 6.8.1 + +extraEnvs: + - name: ELASTICSEARCH_HOSTS + value: six-master:9200 diff --git a/metricbeat/examples/default/Makefile b/metricbeat/examples/default/Makefile new file mode 100644 index 000000000..833f62973 --- /dev/null +++ b/metricbeat/examples/default/Makefile @@ -0,0 +1,17 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE = helm-metricbeat-default +GOSS_SELECTOR = release=$(RELEASE),app=helm-metricbeat-default-metricbeat + +install: + helm upgrade --wait --timeout=600 --install $(RELEASE) ../../ + +test-metrics: + GOSS_FILE=goss-metrics.yaml make goss GOSS_SELECTOR=release=$(RELEASE),app=helm-metricbeat-default-metricbeat-metrics + +test: install goss test-metrics + +purge: + helm del --purge $(RELEASE) diff --git a/metricbeat/examples/default/test/goss-metrics.yaml b/metricbeat/examples/default/test/goss-metrics.yaml new file mode 100644 index 000000000..ec57e8bee --- /dev/null +++ b/metricbeat/examples/default/test/goss-metrics.yaml @@ -0,0 +1,44 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/kube-state-metrics-metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + http://elasticsearch-master:9200/_search?q=metricset.name:state_deployment: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + - 'elasticsearch-master:9200' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://elasticsearch-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/default/test/goss.yaml b/metricbeat/examples/default/test/goss.yaml new file mode 100644 index 000000000..edc9fdd2f --- /dev/null +++ b/metricbeat/examples/default/test/goss.yaml @@ -0,0 +1,52 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/metricbeat/metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + http://elasticsearch-master:9200/_search?q=metricset.name:container: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + - 'elasticsearch-master:9200' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://elasticsearch-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/oss/Makefile b/metricbeat/examples/oss/Makefile new file mode 100644 index 000000000..0e4828ed0 --- /dev/null +++ b/metricbeat/examples/oss/Makefile @@ -0,0 +1,17 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-metricbeat-oss +GOSS_SELECTOR = release=$(RELEASE),app=helm-metricbeat-oss-metricbeat + +install: + helm upgrade --wait --timeout=600 --install $(RELEASE) --values values.yaml ../../ + +purge: + helm del --purge $(RELEASE) + +test-metrics: + GOSS_FILE=goss-metrics.yaml make goss GOSS_SELECTOR=release=$(RELEASE),app=helm-metricbeat-oss-metricbeat-metrics + +test: install goss test-metrics diff --git a/metricbeat/examples/oss/test/goss-metrics.yaml b/metricbeat/examples/oss/test/goss-metrics.yaml new file mode 100644 index 000000000..4b115200d --- /dev/null +++ b/metricbeat/examples/oss/test/goss-metrics.yaml @@ -0,0 +1,43 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/kube-state-metrics-metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://oss-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + http://oss-master:9200/_search?q=metricset.name:state_deployment: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://oss-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/oss/test/goss.yaml b/metricbeat/examples/oss/test/goss.yaml new file mode 100644 index 000000000..e7788dd04 --- /dev/null +++ b/metricbeat/examples/oss/test/goss.yaml @@ -0,0 +1,51 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/metricbeat/metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://oss-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + http://oss-master:9200/_search?q=metricset.name:container: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: http://oss-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/oss/values.yaml b/metricbeat/examples/oss/values.yaml new file mode 100644 index 000000000..89f2d453c --- /dev/null +++ b/metricbeat/examples/oss/values.yaml @@ -0,0 +1,5 @@ +image: docker.elastic.co/beats/metricbeat-oss + +extraEnvs: + - name: ELASTICSEARCH_HOSTS + value: oss-master:9200 diff --git a/metricbeat/examples/security/Makefile b/metricbeat/examples/security/Makefile new file mode 100644 index 000000000..3f92e7fe2 --- /dev/null +++ b/metricbeat/examples/security/Makefile @@ -0,0 +1,17 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-metricbeat-security +GOSS_SELECTOR = release=$(RELEASE),app=helm-metricbeat-security-metricbeat + +install: + helm upgrade --wait --timeout=600 --install $(RELEASE) --values values.yaml ../../ + +purge: + helm del --purge $(RELEASE) + +test-metrics: + GOSS_FILE=goss-metrics.yaml make goss GOSS_SELECTOR=release=$(RELEASE),app=helm-metricbeat-security-metricbeat-metrics + +test: install goss test-metrics diff --git a/metricbeat/examples/security/test/goss-metrics.yaml b/metricbeat/examples/security/test/goss-metrics.yaml new file mode 100644 index 000000000..86434f43a --- /dev/null +++ b/metricbeat/examples/security/test/goss-metrics.yaml @@ -0,0 +1,49 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/kube-state-metrics-metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + https://security-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + allow-insecure: true + username: '{{ .Env.ELASTICSEARCH_USERNAME }}' + password: '{{ .Env.ELASTICSEARCH_PASSWORD }}' + https://security-master:9200/_search?q=metricset.name:state_deployment: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + allow-insecure: true + username: '{{ .Env.ELASTICSEARCH_USERNAME }}' + password: '{{ .Env.ELASTICSEARCH_PASSWORD }}' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: https://security-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/security/test/goss.yaml b/metricbeat/examples/security/test/goss.yaml new file mode 100644 index 000000000..05d6d0a87 --- /dev/null +++ b/metricbeat/examples/security/test/goss.yaml @@ -0,0 +1,57 @@ +port: + tcp:5066: + listening: true + ip: + - '127.0.0.1' + +mount: + /usr/share/metricbeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/metricbeat/metricbeat.yml: + exists: true + opts: + - ro + +user: + metricbeat: + exists: true + uid: 1000 + gid: 1000 + +http: + https://security-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + allow-insecure: true + username: '{{ .Env.ELASTICSEARCH_USERNAME }}' + password: '{{ .Env.ELASTICSEARCH_PASSWORD }}' + https://security-master:9200/_search?q=metricset.name:container: + status: 200 + timeout: 2000 + body: + - 'metricbeat-7.2.0' + allow-insecure: true + username: '{{ .Env.ELASTICSEARCH_USERNAME }}' + password: '{{ .Env.ELASTICSEARCH_PASSWORD }}' + +file: + /usr/share/metricbeat/metricbeat.yml: + exists: true + contains: + - 'add_kubernetes_metadata' + - 'output.elasticsearch' + +command: + cd /usr/share/metricbeat && metricbeat test output: + exit-status: 0 + stdout: + - 'elasticsearch: https://security-master:9200' + - 'version: 7.2.0' diff --git a/metricbeat/examples/security/values.yaml b/metricbeat/examples/security/values.yaml new file mode 100644 index 000000000..5d3f92501 --- /dev/null +++ b/metricbeat/examples/security/values.yaml @@ -0,0 +1,87 @@ +metricbeatConfig: + metricbeat.yml: | + system: + hostfs: /hostfs + metricbeat.modules: + - module: kubernetes + metricsets: + - container + - node + - pod + - system + - volume + period: 10s + hosts: ["localhost:10255"] + processors: + - add_kubernetes_metadata: + in_cluster: true + - module: kubernetes + enabled: true + metricsets: + - event + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + processes: ['.*'] + process.include_top_n: + by_cpu: 5 + by_memory: 5 + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: '^/(sys|cgroup|proc|dev|etc|host|lib)($|/)' + + output.elasticsearch: + username: '${ELASTICSEARCH_USERNAME}' + password: '${ELASTICSEARCH_PASSWORD}' + protocol: https + hosts: ["security-master:9200"] + ssl.certificate_authorities: + - /usr/share/metricbeat/config/certs/elastic-certificate.pem + + kube-state-metrics-metricbeat.yml: | + metricbeat.modules: + - module: kubernetes + enabled: true + metricsets: + - state_node + - state_deployment + - state_replicaset + - state_pod + - state_container + period: 10s + hosts: ["${KUBE_STATE_METRICS_HOSTS:kube-state-metrics:8080}"] + output.elasticsearch: + username: '${ELASTICSEARCH_USERNAME}' + password: '${ELASTICSEARCH_PASSWORD}' + protocol: https + hosts: ["security-master:9200"] + ssl.certificate_authorities: + - /usr/share/metricbeat/config/certs/elastic-certificate.pem + +secretMounts: + - name: elastic-certificate-pem + secretName: elastic-certificate-pem + path: /usr/share/metricbeat/config/certs + +extraEnvs: + - name: 'ELASTICSEARCH_USERNAME' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: username + - name: 'ELASTICSEARCH_PASSWORD' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: password diff --git a/metricbeat/requirements.lock b/metricbeat/requirements.lock new file mode 100644 index 000000000..213c4e3a4 --- /dev/null +++ b/metricbeat/requirements.lock @@ -0,0 +1,6 @@ +dependencies: +- name: kube-state-metrics + repository: https://kubernetes-charts.storage.googleapis.com + version: 1.6.0 +digest: sha256:111c5be854f72db1996a198a473a3e69bd50b7c5f046cf03ee4733d62a612874 +generated: 2019-06-11T09:46:07.710748+02:00 diff --git a/metricbeat/requirements.yaml b/metricbeat/requirements.yaml new file mode 100644 index 000000000..37d378f9c --- /dev/null +++ b/metricbeat/requirements.yaml @@ -0,0 +1,4 @@ +dependencies: + - name: 'kube-state-metrics' + version: '1.6.0' + repository: '@stable' diff --git a/metricbeat/templates/NOTES.txt b/metricbeat/templates/NOTES.txt new file mode 100755 index 000000000..24cdde2e5 --- /dev/null +++ b/metricbeat/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Watch all containers come up. + $ kubectl get pods --namespace={{ .Release.Namespace }} -l app={{ template "fullname" . }} -w diff --git a/metricbeat/templates/_helpers.tpl b/metricbeat/templates/_helpers.tpl new file mode 100755 index 000000000..769546335 --- /dev/null +++ b/metricbeat/templates/_helpers.tpl @@ -0,0 +1,28 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Use the fullname if the serviceAccount value is not set +*/}} +{{- define "serviceAccount" -}} +{{- if .Values.serviceAccount }} +{{- .Values.serviceAccount -}} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/metricbeat/templates/clusterrole.yaml b/metricbeat/templates/clusterrole.yaml new file mode 100644 index 000000000..52d7e5e98 --- /dev/null +++ b/metricbeat/templates/clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "serviceAccount" . }}-cluster-role + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +rules: +- apiGroups: + - "" + resources: + - namespaces + - pods + verbs: + - get + - list + - watch +{{- end -}} diff --git a/metricbeat/templates/clusterrolebinding.yaml b/metricbeat/templates/clusterrolebinding.yaml new file mode 100644 index 000000000..b901e2387 --- /dev/null +++ b/metricbeat/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "serviceAccount" . }}-cluster-role-binding + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +roleRef: + kind: ClusterRole + name: {{ template "serviceAccount" . }}-cluster-role + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "serviceAccount" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/metricbeat/templates/configmap.yaml b/metricbeat/templates/configmap.yaml new file mode 100644 index 000000000..655173b52 --- /dev/null +++ b/metricbeat/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.metricbeatConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "fullname" . }}-config + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.metricbeatConfig }} + {{ $path }}: | +{{ $config | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/metricbeat/templates/daemonset.yaml b/metricbeat/templates/daemonset.yaml new file mode 100644 index 000000000..fd1b12f10 --- /dev/null +++ b/metricbeat/templates/daemonset.yaml @@ -0,0 +1,136 @@ +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "fullname" . }} + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +spec: + selector: + matchLabels: + app: "{{ template "fullname" . }}" + release: {{ .Release.Name | quote }} + updateStrategy: + type: {{ .Values.updateStrategy }} + template: + metadata: + annotations: + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{/* This forces a restart if the configmap has changed */}} + {{- if .Values.metricbeatConfig }} + configChecksum: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + name: "{{ template "fullname" . }}" + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + spec: + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + serviceAccountName: {{ template "serviceAccount" . }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} + volumes: + {{- range .Values.secretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- if .Values.metricbeatConfig }} + - name: metricbeat-config + configMap: + defaultMode: 0600 + name: {{ template "fullname" . }}-config + {{- end }} + - name: data + hostPath: + path: {{ .Values.hostPathRoot }}/{{ template "fullname" . }}-{{ .Release.Namespace }}-data + type: DirectoryOrCreate + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: varrundockersock + hostPath: + path: /var/run/docker.sock + {{- if .Values.extraVolumes }} +{{ tpl .Values.extraVolumes . | indent 6 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: "metricbeat" + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + args: + - "-e" + - "-E" + - "http.enabled=true" + livenessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + curl --fail 127.0.0.1:5066 +{{ toYaml .Values.livenessProbe | indent 10 }} + readinessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + metricbeat test output +{{ toYaml .Values.readinessProbe | indent 10 }} + resources: +{{ toYaml .Values.resources | indent 10 }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace +{{- if .Values.extraEnvs }} +{{ toYaml .Values.extraEnvs | indent 8 }} +{{- end }} +{{- if .Values.podSecurityContext }} + securityContext: +{{ toYaml .Values.podSecurityContext | indent 10 }} +{{- end }} + volumeMounts: + {{- range .Values.secretMounts }} + - name: {{ .name }} + mountPath: {{ .path }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.metricbeatConfig }} + - name: metricbeat-config + mountPath: /usr/share/metricbeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{- end }} + - name: data + mountPath: /usr/share/metricbeat/data + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + # Necessary when using autodiscovery; avoid mounting it otherwise + # See: https://www.elastic.co/guide/en/beats/metricbeat/master/configuration-autodiscover.html + - name: varrundockersock + mountPath: /var/run/docker.sock + readOnly: true + {{- if .Values.extraVolumeMounts }} +{{ tpl .Values.extraVolumeMounts . | indent 8 }} + {{- end }} diff --git a/metricbeat/templates/deployment.yaml b/metricbeat/templates/deployment.yaml new file mode 100644 index 000000000..96cce2ea6 --- /dev/null +++ b/metricbeat/templates/deployment.yaml @@ -0,0 +1,119 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: '{{ template "fullname" . }}-metrics' + labels: + app: '{{ template "fullname" . }}-metrics' + chart: '{{ .Chart.Name }}-{{ .Chart.Version }}' + heritage: '{{ .Release.Service }}' + release: '{{ .Release.Name }}' +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: '{{ template "fullname" . }}-metrics' + chart: '{{ .Chart.Name }}-{{ .Chart.Version }}' + heritage: '{{ .Release.Service }}' + release: '{{ .Release.Name }}' + template: + metadata: + annotations: + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{/* This forces a restart if the configmap has changed */}} + {{- if .Values.metricbeatConfig }} + configChecksum: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + labels: + app: '{{ template "fullname" . }}-metrics' + chart: '{{ .Chart.Name }}-{{ .Chart.Version }}' + heritage: '{{ .Release.Service }}' + release: '{{ .Release.Name }}' + spec: + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + serviceAccountName: {{ template "serviceAccount" . }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} + volumes: + {{- range .Values.secretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- if .Values.metricbeatConfig }} + - name: metricbeat-config + configMap: + defaultMode: 0600 + name: {{ template "fullname" . }}-config + {{- end }} + {{- if .Values.extraVolumes }} +{{ tpl .Values.extraVolumes . | indent 6 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: "metricbeat" + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + args: + - "-c" + - "/usr/share/metricbeat/kube-state-metrics-metricbeat.yml" + - "-e" + - "-E" + - "http.enabled=true" + livenessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + curl --fail 127.0.0.1:5066 + readinessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + metricbeat test output +{{ toYaml .Values.readinessProbe | indent 10 }} + resources: +{{ toYaml .Values.resources | indent 10 }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KUBE_STATE_METRICS_HOSTS + value: "$({{ .Release.Name | replace "-" "_" | upper }}_KUBE_STATE_METRICS_SERVICE_HOST):$({{ .Release.Name | replace "-" "_" | upper }}_KUBE_STATE_METRICS_SERVICE_PORT_HTTP)" +{{- if .Values.extraEnvs }} +{{ toYaml .Values.extraEnvs | indent 8 }} +{{- end }} +{{- if .Values.podSecurityContext }} + securityContext: +{{ toYaml .Values.podSecurityContext | indent 10 }} +{{- end }} + volumeMounts: + {{- range .Values.secretMounts }} + - name: {{ .name }} + mountPath: {{ .path }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.metricbeatConfig }} + - name: metricbeat-config + mountPath: /usr/share/metricbeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{- end }} + {{- if .Values.extraVolumeMounts }} +{{ tpl .Values.extraVolumeMounts . | indent 8 }} + {{- end }} diff --git a/metricbeat/templates/serviceaccount.yaml b/metricbeat/templates/serviceaccount.yaml new file mode 100644 index 000000000..70a7a049b --- /dev/null +++ b/metricbeat/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "serviceAccount" . }} + labels: + app: "{{ template "fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +{{- end -}} diff --git a/metricbeat/tests/metricbeat_test.py b/metricbeat/tests/metricbeat_test.py new file mode 100644 index 000000000..d578fef6b --- /dev/null +++ b/metricbeat/tests/metricbeat_test.py @@ -0,0 +1,181 @@ +import os +import sys +sys.path.insert(1, os.path.join(sys.path[0], '../../helpers')) +from helpers import helm_template +import yaml + +project = 'metricbeat' +name = 'release-name-' + project + +def test_defaults(): + config = ''' + ''' + + r = helm_template(config) + + assert name in r['daemonset'] + + c = r['daemonset'][name]['spec']['template']['spec']['containers'][0] + assert c['name'] == project + assert c['image'].startswith('docker.elastic.co/beats/' + project + ':') + + assert c['env'][0]['name'] == 'POD_NAMESPACE' + assert c['env'][0]['valueFrom']['fieldRef']['fieldPath'] == 'metadata.namespace' + + assert 'curl --fail 127.0.0.1:5066' in c['livenessProbe']['exec']['command'][-1] + + assert 'metricbeat test output' in c['readinessProbe']['exec']['command'][-1] + + # Empty customizable defaults + assert 'imagePullSecrets' not in r['daemonset'][name]['spec']['template']['spec'] + assert 'tolerations' not in r['daemonset'][name]['spec']['template']['spec'] + + assert r['daemonset'][name]['spec']['updateStrategy']['type'] == 'RollingUpdate' + + assert r['daemonset'][name]['spec']['template']['spec']['serviceAccountName'] == name + + volumes = r['daemonset'][name]['spec']['template']['spec']['volumes'] + assert { + 'name': 'data', + 'hostPath': { + 'path': '/var/lib/' + name + '-default-data', + 'type': 'DirectoryOrCreate' + } + } in volumes + + +def test_adding_envs(): + config = ''' +extraEnvs: +- name: LOG_LEVEL + value: DEBUG +''' + r = helm_template(config) + envs = r['daemonset'][name]['spec']['template']['spec']['containers'][0]['env'] + assert {'name': 'LOG_LEVEL', 'value': 'DEBUG'} in envs + + +def test_adding_image_pull_secrets(): + config = ''' +imagePullSecrets: + - name: test-registry +''' + r = helm_template(config) + assert r['daemonset'][name]['spec']['template']['spec']['imagePullSecrets'][0]['name'] == 'test-registry' + + +def test_adding_tolerations(): + config = ''' +tolerations: +- key: "key1" + operator: "Equal" + value: "value1" + effect: "NoExecute" + tolerationSeconds: 3600 +''' + r = helm_template(config) + assert r['daemonset'][name]['spec']['template']['spec']['tolerations'][0]['key'] == 'key1' + + +def test_override_the_default_update_strategy(): + config = ''' +updateStrategy: OnDelete +''' + + r = helm_template(config) + assert r['daemonset'][name]['spec']['updateStrategy']['type'] == 'OnDelete' + +def test_setting_a_custom_service_account(): + config = ''' +serviceAccount: notdefault +''' + r = helm_template(config) + assert r['daemonset'][name]['spec']['template']['spec']['serviceAccountName'] == 'notdefault' + +def test_self_managing_rbac_resources(): + config = ''' +managedServiceAccount: false +''' + r = helm_template(config) + assert name not in r['serviceaccount'] + assert name not in r['clusterrole'] + assert name not in r['clusterrolebinding'] + +def test_setting_pod_security_context(): + config = ''' +podSecurityContext: + runAsUser: 1001 + privileged: false +''' + r = helm_template(config) + c = r['daemonset'][name]['spec']['template']['spec']['containers'][0] + assert c['securityContext']['runAsUser'] == 1001 + assert c['securityContext']['privileged'] == False + +def test_adding_in_metricbeat_config(): + config = ''' +metricbeatConfig: + metricbeat.yml: | + key: + nestedkey: value + dot.notation: test + + other-config.yml: | + hello = world +''' + r = helm_template(config) + c = r['configmap'][name + '-config']['data'] + + assert 'metricbeat.yml' in c + assert 'other-config.yml' in c + + assert 'nestedkey: value' in c['metricbeat.yml'] + assert 'dot.notation: test' in c['metricbeat.yml'] + + assert 'hello = world' in c['other-config.yml'] + + d = r['daemonset'][name]['spec']['template']['spec'] + + assert {'configMap': {'name': name + '-config', 'defaultMode': 0600}, 'name': project + '-config'} in d['volumes'] + assert {'mountPath': '/usr/share/metricbeat/metricbeat.yml', 'name': project + '-config', 'subPath': 'metricbeat.yml', 'readOnly': True} in d['containers'][0]['volumeMounts'] + assert {'mountPath': '/usr/share/metricbeat/other-config.yml', 'name': project + '-config', 'subPath': 'other-config.yml', 'readOnly': True} in d['containers'][0]['volumeMounts'] + + assert 'configChecksum' in r['daemonset'][name]['spec']['template']['metadata']['annotations'] + + +def test_adding_a_secret_mount(): + config = ''' +secretMounts: + - name: elastic-certificates + secretName: elastic-certificates-name + path: /usr/share/metricbeat/config/certs +''' + r = helm_template(config) + s = r['daemonset'][name]['spec']['template']['spec'] + assert s['containers'][0]['volumeMounts'][0] == { + 'mountPath': '/usr/share/metricbeat/config/certs', + 'name': 'elastic-certificates' + } + assert s['volumes'][0] == { + 'name': 'elastic-certificates', + 'secret': { + 'secretName': 'elastic-certificates-name' + } + } + + +def test_adding_a_extra_volume_with_volume_mount(): + config = ''' +extraVolumes: | + - name: extras + emptyDir: {} +extraVolumeMounts: | + - name: extras + mountPath: /usr/share/extras + readOnly: true +''' + r = helm_template(config) + extraVolume = r['daemonset'][name]['spec']['template']['spec']['volumes'] + assert {'name': 'extras', 'emptyDir': {}} in extraVolume + extraVolumeMounts = r['daemonset'][name]['spec']['template']['spec']['containers'][0]['volumeMounts'] + assert {'name': 'extras', 'mountPath': '/usr/share/extras', 'readOnly': True} in extraVolumeMounts diff --git a/metricbeat/values.yaml b/metricbeat/values.yaml new file mode 100755 index 000000000..7cae07ef4 --- /dev/null +++ b/metricbeat/values.yaml @@ -0,0 +1,147 @@ +--- +# Allows you to add any config files in /usr/share/metricbeat +# such as metricbeat.yml +metricbeatConfig: + metricbeat.yml: | + system: + hostfs: /hostfs + metricbeat.modules: + - module: kubernetes + metricsets: + - container + - node + - pod + - system + - volume + period: 10s + hosts: ["localhost:10255"] + processors: + - add_kubernetes_metadata: + in_cluster: true + - module: kubernetes + enabled: true + metricsets: + - event + - module: system + period: 10s + metricsets: + - cpu + - load + - memory + - network + - process + - process_summary + processes: ['.*'] + process.include_top_n: + by_cpu: 5 + by_memory: 5 + - module: system + period: 1m + metricsets: + - filesystem + - fsstat + processors: + - drop_event.when.regexp: + system.filesystem.mount_point: '^/(sys|cgroup|proc|dev|etc|host|lib)($|/)' + output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}' + + kube-state-metrics-metricbeat.yml: | + metricbeat.modules: + - module: kubernetes + enabled: true + metricsets: + - state_node + - state_deployment + - state_replicaset + - state_pod + - state_container + period: 10s + hosts: ["${KUBE_STATE_METRICS_HOSTS:kube-state-metrics:8080}"] + output.elasticsearch: + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}' + +# Replicas being used for the kube-state-metrics metricbeat deployment + +replicas: 1 + +# Extra environment variables to append to the DaemonSet pod spec. +# This will be appended to the current 'env:' key. You can use any of the kubernetes env +# syntax here +extraEnvs: [] +# - name: MY_ENVIRONMENT_VAR +# value: the_value_goes_here + +extraVolumeMounts: [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + +extraVolumes: [] + # - name: extras + # emptyDir: {} + +# Root directory where metricbeat will write data to in order to persist registry data across pod restarts (file position and other metadata). +hostPathRoot: /var/lib + +image: "docker.elastic.co/beats/metricbeat" +imageTag: "7.2.0" +imagePullPolicy: "IfNotPresent" +imagePullSecrets: [] + +livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + +readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + +# Whether this chart should self-manage its service account, role, and associated role binding. +managedServiceAccount: true + +podAnnotations: {} + # iam.amazonaws.com/role: es-cluster + +# Various pod security context settings. Bear in mind that many of these have an impact on metricbeat functioning properly. +# +# - Filesystem group for the metricbeat user. The official elastic docker images always have an id of 1000. +# - User that the container will execute as. Typically necessary to run as root (0) in order to properly collect host container logs. +# - Whether to execute the metricbeat containers as privileged containers. Typically not necessarily unless running within environments such as OpenShift. +podSecurityContext: + runAsUser: 0 + privileged: false + +resources: + requests: + cpu: "100m" + memory: "100Mi" + limits: + cpu: "1000m" + memory: "200Mi" + +# Custom service account override that the pod will use +serviceAccount: "" + +# A list of secrets and their paths to mount inside the pod +# This is useful for mounting certificates for security other sensitive values +secretMounts: [] +# - name: metricbeat-certificates +# secretName: metricbeat-certificates +# path: /usr/share/metricbeat/certs + +# How long to wait for metricbeat pods to stop gracefully +terminationGracePeriod: 30 + +tolerations: [] + +updateStrategy: RollingUpdate + +# Override various naming aspects of this chart +# Only edit these if you know what you're doing +nameOverride: "" +fullnameOverride: ""