diff --git a/deploy/kubernetes/Makefile b/deploy/kubernetes/Makefile index 722cac158d1..a97e9a986f4 100644 --- a/deploy/kubernetes/Makefile +++ b/deploy/kubernetes/Makefile @@ -1,4 +1,4 @@ -ALL=filebeat metricbeat auditbeat +ALL=filebeat metricbeat auditbeat heartbeat BEAT_VERSION=$(shell head -n 1 ../../libbeat/docs/version.asciidoc | cut -c 17- ) .PHONY: all $(ALL) diff --git a/deploy/kubernetes/README.md b/deploy/kubernetes/README.md index 65275dc4e45..b1ee4207d3e 100644 --- a/deploy/kubernetes/README.md +++ b/deploy/kubernetes/README.md @@ -9,3 +9,5 @@ Beat | Description ---- | ---- [filebeat](filebeat) | Tails and ships logs [metricbeat](metricbeat) | Fetches sets of metrics from the operating system and services +[auditbeat](auditbeat) | Collect Linux audit framework data and monitor files integrity +[heartbeat](heartbeat) | Monitor services for their availability with active probing diff --git a/deploy/kubernetes/heartbeat-kubernetes.yaml b/deploy/kubernetes/heartbeat-kubernetes.yaml new file mode 100644 index 00000000000..8938124bf17 --- /dev/null +++ b/deploy/kubernetes/heartbeat-kubernetes.yaml @@ -0,0 +1,159 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: heartbeat-deployment-config + namespace: kube-system + labels: + k8s-app: heartbeat +data: + heartbeat.yml: |- + #heartbeat.autodiscover: + # # Autodiscover pods + # providers: + # - type: kubernetes + # resource: pod + # scope: cluster + # node: ${NODE_NAME} + # hints.enabled: true + # + # # Autodiscover services + # providers: + # - type: kubernetes + # resource: service + # scope: cluster + # node: ${NODE_NAME} + # hints.enabled: true + # + # # Autodiscover nodes + # providers: + # - type: kubernetes + # resource: node + # node: ${NODE_NAME} + # scope: cluster + # templates: + # # Example, check SSH port of all cluster nodes: + # - condition: ~ + # config: + # - hosts: + # - ${data.host}:22 + # name: ${data.kubernetes.node.name} + # schedule: '@every 10s' + # timeout: 5s + # type: tcp + + processors: + - add_cloud_metadata: + + cloud.id: ${ELASTIC_CLOUD_ID} + cloud.auth: ${ELASTIC_CLOUD_AUTH} + + output.elasticsearch: + hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}'] + username: ${ELASTICSEARCH_USERNAME} + password: ${ELASTICSEARCH_PASSWORD} +--- +# Deploy singleton instance in the whole cluster for some unique data sources, like kube-state-metrics +apiVersion: apps/v1 +kind: Deployment +metadata: + name: heartbeat + namespace: kube-system + labels: + k8s-app: heartbeat +spec: + selector: + matchLabels: + k8s-app: heartbeat + template: + metadata: + labels: + k8s-app: heartbeat + spec: + serviceAccountName: heartbeat + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: heartbeat + image: docker.elastic.co/beats/heartbeat:7.9.0 + args: [ + "-c", "/etc/heartbeat.yml", + "-e", + ] + env: + - name: ELASTICSEARCH_HOST + value: elasticsearch + - name: ELASTICSEARCH_PORT + value: "9200" + - name: ELASTICSEARCH_USERNAME + value: elastic + - name: ELASTICSEARCH_PASSWORD + value: changeme + - name: ELASTIC_CLOUD_ID + value: + - name: ELASTIC_CLOUD_AUTH + value: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + securityContext: + runAsUser: 0 + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + volumeMounts: + - name: config + mountPath: /etc/heartbeat.yml + readOnly: true + subPath: heartbeat.yml + - name: data + mountPath: /usr/share/heartbeat/data + volumes: + - name: config + configMap: + defaultMode: 0600 + name: heartbeat-deployment-config + - name: data + hostPath: + path: /var/lib/heartbeat-data + type: DirectoryOrCreate + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: heartbeat +subjects: +- kind: ServiceAccount + name: heartbeat + namespace: kube-system +roleRef: + kind: ClusterRole + name: heartbeat + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: heartbeat + labels: + k8s-app: heartbeat +rules: +- apiGroups: [""] + resources: + - nodes + - namespaces + - pods + verbs: ["get", "list", "watch"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: heartbeat + namespace: kube-system + labels: + k8s-app: heartbeat +--- diff --git a/deploy/kubernetes/heartbeat/README.md b/deploy/kubernetes/heartbeat/README.md new file mode 100644 index 00000000000..a42be6a4a50 --- /dev/null +++ b/deploy/kubernetes/heartbeat/README.md @@ -0,0 +1,30 @@ +# Heartbeat + +## Monitor Kubernetes services uptime + +### Kubernetes Deployment + +Heartbeat can be deployed to monitor the whole cluster from a single pod. + +Everything is deployed under `kube-system` namespace, you can change that by +updating YAML manifests under this folder. + +### Settings + +We use official [Beats Docker images](https://github.com/elastic/beats-docker), +as they allow external files configuration, a [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) +is used for kubernetes specific settings. Check [heartbeat-configmap.yaml](heartbeat-configmap.yaml) +for details. + +Also, [heartbeat-deployment.yaml](heartbeat-deployment.yaml) uses a set of environment +variables to configure Elasticsearch output: + +Variable | Default | Description +-------- | ------- | ----------- +ELASTICSEARCH_HOST | elasticsearch | Elasticsearch host +ELASTICSEARCH_PORT | 9200 | Elasticsearch port +ELASTICSEARCH_USERNAME | elastic | Elasticsearch username for HTTP auth +ELASTICSEARCH_PASSWORD | changeme | Elasticsearch password + +If there is an existing `elasticsearch` service in the kubernetes cluster these +defaults will use it. diff --git a/deploy/kubernetes/heartbeat/heartbeat-configmap.yaml b/deploy/kubernetes/heartbeat/heartbeat-configmap.yaml new file mode 100644 index 00000000000..639ad28ae2b --- /dev/null +++ b/deploy/kubernetes/heartbeat/heartbeat-configmap.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: heartbeat-deployment-config + namespace: kube-system + labels: + k8s-app: heartbeat +data: + heartbeat.yml: |- + #heartbeat.autodiscover: + # # Autodiscover pods + # providers: + # - type: kubernetes + # resource: pod + # scope: cluster + # node: ${NODE_NAME} + # hints.enabled: true + # + # # Autodiscover services + # providers: + # - type: kubernetes + # resource: service + # scope: cluster + # node: ${NODE_NAME} + # hints.enabled: true + # + # # Autodiscover nodes + # providers: + # - type: kubernetes + # resource: node + # node: ${NODE_NAME} + # scope: cluster + # templates: + # # Example, check SSH port of all cluster nodes: + # - condition: ~ + # config: + # - hosts: + # - ${data.host}:22 + # name: ${data.kubernetes.node.name} + # schedule: '@every 10s' + # timeout: 5s + # type: tcp + + processors: + - add_cloud_metadata: + + cloud.id: ${ELASTIC_CLOUD_ID} + cloud.auth: ${ELASTIC_CLOUD_AUTH} + + output.elasticsearch: + hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}'] + username: ${ELASTICSEARCH_USERNAME} + password: ${ELASTICSEARCH_PASSWORD} diff --git a/deploy/kubernetes/heartbeat/heartbeat-deployment.yaml b/deploy/kubernetes/heartbeat/heartbeat-deployment.yaml new file mode 100644 index 00000000000..3f7a471b457 --- /dev/null +++ b/deploy/kubernetes/heartbeat/heartbeat-deployment.yaml @@ -0,0 +1,69 @@ +# Deploy singleton instance in the whole cluster for some unique data sources, like kube-state-metrics +apiVersion: apps/v1 +kind: Deployment +metadata: + name: heartbeat + namespace: kube-system + labels: + k8s-app: heartbeat +spec: + selector: + matchLabels: + k8s-app: heartbeat + template: + metadata: + labels: + k8s-app: heartbeat + spec: + serviceAccountName: heartbeat + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: heartbeat + image: docker.elastic.co/beats/heartbeat:%VERSION% + args: [ + "-c", "/etc/heartbeat.yml", + "-e", + ] + env: + - name: ELASTICSEARCH_HOST + value: elasticsearch + - name: ELASTICSEARCH_PORT + value: "9200" + - name: ELASTICSEARCH_USERNAME + value: elastic + - name: ELASTICSEARCH_PASSWORD + value: changeme + - name: ELASTIC_CLOUD_ID + value: + - name: ELASTIC_CLOUD_AUTH + value: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + securityContext: + runAsUser: 0 + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + volumeMounts: + - name: config + mountPath: /etc/heartbeat.yml + readOnly: true + subPath: heartbeat.yml + - name: data + mountPath: /usr/share/heartbeat/data + volumes: + - name: config + configMap: + defaultMode: 0600 + name: heartbeat-deployment-config + - name: data + hostPath: + path: /var/lib/heartbeat-data + type: DirectoryOrCreate + diff --git a/deploy/kubernetes/heartbeat/heartbeat-role-binding.yaml b/deploy/kubernetes/heartbeat/heartbeat-role-binding.yaml new file mode 100644 index 00000000000..5fe59dd56b8 --- /dev/null +++ b/deploy/kubernetes/heartbeat/heartbeat-role-binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: heartbeat +subjects: +- kind: ServiceAccount + name: heartbeat + namespace: kube-system +roleRef: + kind: ClusterRole + name: heartbeat + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/kubernetes/heartbeat/heartbeat-role.yaml b/deploy/kubernetes/heartbeat/heartbeat-role.yaml new file mode 100644 index 00000000000..50782d99aed --- /dev/null +++ b/deploy/kubernetes/heartbeat/heartbeat-role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: heartbeat + labels: + k8s-app: heartbeat +rules: +- apiGroups: [""] + resources: + - nodes + - namespaces + - pods + verbs: ["get", "list", "watch"] diff --git a/deploy/kubernetes/heartbeat/heartbeat-service-account.yaml b/deploy/kubernetes/heartbeat/heartbeat-service-account.yaml new file mode 100644 index 00000000000..461c335e176 --- /dev/null +++ b/deploy/kubernetes/heartbeat/heartbeat-service-account.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: heartbeat + namespace: kube-system + labels: + k8s-app: heartbeat diff --git a/heartbeat/docs/running-on-kubernetes.asciidoc b/heartbeat/docs/running-on-kubernetes.asciidoc new file mode 100644 index 00000000000..87b5c4bb395 --- /dev/null +++ b/heartbeat/docs/running-on-kubernetes.asciidoc @@ -0,0 +1,76 @@ +[[running-on-kubernetes]] +=== Running {beatname_uc} on Kubernetes + +{beatname_uc} <> can be used on Kubernetes to +check resources uptime. + +TIP: Running {ecloud} on Kubernetes? See {eck-ref}/k8s-beat.html[Run {beats} on ECK] + +ifeval::["{release-state}"=="unreleased"] + +However, version {version} of {beatname_uc} has not yet been +released, so no Docker image is currently available for this version. + +endif::[] + + +[float] +==== Kubernetes deploy manifests + +A single {beatname_uc} can check for uptime of the whole cluster. + +Everything is deployed under `kube-system` namespace, you can change that by +updating the YAML file. + +To get the manifests just run: + +["source", "sh", subs="attributes"] +------------------------------------------------ +curl -L -O https://raw.githubusercontent.com/elastic/beats/{branch}/deploy/kubernetes/{beatname_lc}-kubernetes.yaml +------------------------------------------------ + +[WARNING] +======================================= +If you are using Kubernetes 1.7 or earlier: {beatname_uc} uses a hostPath volume to persist internal data, it's located +under /var/lib/{beatname_lc}-data. The manifest uses folder autocreation (`DirectoryOrCreate`), which was introduced in +Kubernetes 1.8. You will need to remove `type: DirectoryOrCreate` from the manifest and create the host folder yourself. +======================================= + +[float] +==== Settings + +Some parameters are exposed in the manifest to configure logs destination, by +default they will use an existing Elasticsearch deploy if it's present, but you +may want to change that behavior, so just edit the YAML file and modify them: + +["source", "yaml", subs="attributes"] +------------------------------------------------ +- name: ELASTICSEARCH_HOST + value: elasticsearch +- name: ELASTICSEARCH_PORT + value: "9200" +- name: ELASTICSEARCH_USERNAME + value: elastic +- name: ELASTICSEARCH_PASSWORD + value: changeme +------------------------------------------------ + +[float] +==== Deploy + +To deploy {beatname_uc} to Kubernetes just run: + +["source", "sh", subs="attributes"] +------------------------------------------------ +kubectl create -f {beatname_lc}-kubernetes.yaml +------------------------------------------------ + +Then you should be able to check the status by running: + +["source", "sh", subs="attributes"] +------------------------------------------------ +$ kubectl --namespace=kube-system get deployment/{beatname_lc} + +NAME READY UP-TO-DATE AVAILABLE AGE +{beatname_lc} 1/1 1 1 1m +------------------------------------------------ diff --git a/heartbeat/docs/setting-up-running.asciidoc b/heartbeat/docs/setting-up-running.asciidoc index 4acaaa6ffea..9fbf90b7dc1 100644 --- a/heartbeat/docs/setting-up-running.asciidoc +++ b/heartbeat/docs/setting-up-running.asciidoc @@ -28,6 +28,8 @@ This section includes additional information on how to install, set up, and run * <> +* <> + * <> //MAINTAINERS: If you add a new file to this section, make sure you update the bulleted list ^^ too. @@ -42,6 +44,8 @@ include::{libbeat-dir}/repositories.asciidoc[] include::./running-on-docker.asciidoc[] +include::./running-on-kubernetes.asciidoc[] + include::{libbeat-dir}/shared-systemd.asciidoc[] include::{libbeat-dir}/shared/shutdown.asciidoc[]