From b22bef5cfba085f4de24ab3c5c969a39222d4ffc Mon Sep 17 00:00:00 2001 From: Seungkyu Ahn Date: Thu, 10 Aug 2017 06:48:53 +0000 Subject: [PATCH] Apply RBAC to efk and create fluentd.conf Making fluentd.conf as configmap to change configuration. Change elasticsearch rc to deployment. Having installed previous elastaicsearch as rc, first should delete that. --- .../efk/elasticsearch/tasks/main.yml | 43 ++- .../templates/efk-clusterrolebinding.yml | 13 + .../efk/elasticsearch/templates/efk-sa.yml | 7 + .../templates/elasticsearch-deployment.yml.j2 | 13 +- .../efk/fluentd/defaults/main.yml | 2 + .../efk/fluentd/tasks/main.yml | 33 +- .../fluentd/templates/fluentd-config.yml.j2 | 328 ++++++++++++++++++ .../efk/fluentd/templates/fluentd-ds.yml.j2 | 11 +- .../kibana/templates/kibana-deployment.yml.j2 | 4 + 9 files changed, 412 insertions(+), 42 deletions(-) create mode 100644 roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml create mode 100644 roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml create mode 100644 roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2 diff --git a/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml b/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml index df27ec701..7e3626571 100644 --- a/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml +++ b/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml @@ -1,34 +1,41 @@ --- +- name: "ElasticSearch | Write efk manifests (RBAC)" + template: + src: "{{ item }}" + dest: "{{ kube_config_dir }}/{{ item }}" + with_items: + - "efk-sa.yml" + - "efk-clusterrolebinding.yml" + run_once: true + when: rbac_enabled + +- name: "ElasticSearch | Create Serviceaccount and Clusterrolebinding (RBAC)" + command: "kubectl apply -f {{ kube_config_dir }}/{{ item }} -n {{ system_namespace }}" + with_items: + - "efk-sa.yml" + - "efk-clusterrolebinding.yml" + run_once: true + when: rbac_enabled + - name: "ElasticSearch | Write ES deployment" - template: + template: src: elasticsearch-deployment.yml.j2 dest: "{{ kube_config_dir }}/elasticsearch-deployment.yaml" register: es_deployment_manifest - name: "ElasticSearch | Create ES deployment" - kube: - filename: "{{kube_config_dir}}/elasticsearch-deployment.yaml" - kubectl: "{{bin_dir}}/kubectl" - name: "elasticsearch-logging-v1" - namespace: "{{system_namespace}}" - resource: "rc" - state: "{{ item | ternary('latest','present') }}" - with_items: "{{ es_deployment_manifest.changed }}" + command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-deployment.yaml -n {{ system_namespace }}" run_once: true + when: es_deployment_manifest.changed - name: "ElasticSearch | Write ES service " - template: + template: src: elasticsearch-service.yml.j2 dest: "{{ kube_config_dir }}/elasticsearch-service.yaml" register: es_service_manifest - name: "ElasticSearch | Create ES service" - kube: - filename: "{{kube_config_dir}}/elasticsearch-service.yaml" - kubectl: "{{bin_dir}}/kubectl" - name: "elasticsearch-logging" - namespace: "{{system_namespace}}" - resource: "svc" - state: "{{ item | ternary('latest','present') }}" - with_items: "{{ es_service_manifest.changed }}" + command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-service.yaml -n {{ system_namespace }}" run_once: true + when: es_service_manifest.changed + diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml new file mode 100644 index 000000000..2c11e566b --- /dev/null +++ b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml @@ -0,0 +1,13 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: efk + namespace: {{ system_namespace }} +subjects: + - kind: ServiceAccount + name: efk + namespace: {{ system_namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml new file mode 100644 index 000000000..b73c2a49d --- /dev/null +++ b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: efk + namespace: {{ system_namespace }} + labels: + kubernetes.io/cluster-service: "true" diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2 b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2 index 98d26675d..6d5382e09 100644 --- a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2 +++ b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2 @@ -1,7 +1,7 @@ --- # https://raw.githubusercontent.com/kubernetes/kubernetes/v1.5.2/cluster/addons/fluentd-elasticsearch/es-controller.yaml -apiVersion: v1 -kind: ReplicationController +apiVersion: extensions/v1beta1 +kind: Deployment metadata: name: elasticsearch-logging-v1 namespace: "{{ system_namespace }}" @@ -12,8 +12,9 @@ metadata: spec: replicas: 2 selector: - k8s-app: elasticsearch-logging - version: "{{ elasticsearch_image_tag }}" + matchLabels: + k8s-app: elasticsearch-logging + version: "{{ elasticsearch_image_tag }}" template: metadata: labels: @@ -49,3 +50,7 @@ spec: volumes: - name: es-persistent-storage emptyDir: {} +{% if rbac_enabled %} + serviceAccountName: efk +{% endif %} + diff --git a/roles/kubernetes-apps/efk/fluentd/defaults/main.yml b/roles/kubernetes-apps/efk/fluentd/defaults/main.yml index dfb2c98a2..eeb95b71a 100644 --- a/roles/kubernetes-apps/efk/fluentd/defaults/main.yml +++ b/roles/kubernetes-apps/efk/fluentd/defaults/main.yml @@ -3,3 +3,5 @@ fluentd_cpu_limit: 0m fluentd_mem_limit: 200Mi fluentd_cpu_requests: 100m fluentd_mem_requests: 200Mi +fluentd_config_dir: /etc/kubernetes/fluentd +fluentd_config_file: fluentd.conf diff --git a/roles/kubernetes-apps/efk/fluentd/tasks/main.yml b/roles/kubernetes-apps/efk/fluentd/tasks/main.yml index 728bf156d..31b41412e 100644 --- a/roles/kubernetes-apps/efk/fluentd/tasks/main.yml +++ b/roles/kubernetes-apps/efk/fluentd/tasks/main.yml @@ -1,28 +1,23 @@ --- +- name: "Fluentd | copy config file" + template: + src: fluentd-config.yml.j2 + dest: "{{ kube_config_dir }}/fluentd-config.yaml" + register: fluentd_config + +- name: "Fluentd | create configMap" + command: "{{bin_dir}}/kubectl apply -f {{ kube_config_dir }}/fluentd-config.yaml" + run_once: true + when: fluentd_config.changed + - name: "Fluentd | Write fluentd daemonset" template: src: fluentd-ds.yml.j2 dest: "{{ kube_config_dir }}/fluentd-ds.yaml" register: fluentd_ds_manifest -#FIXME: remove if kubernetes/features#124 is implemented -- name: "Fluentd | Purge old fluentd daemonset" - kube: - filename: "{{kube_config_dir}}/fluentd-ds.yaml" - kubectl: "{{bin_dir}}/kubectl" - name: "fluentd-es-v{{ fluentd_version }}" - namespace: "{{system_namespace}}" - resource: "ds" - state: absent - when: inventory_hostname == groups['kube-master'][0] and fluentd_ds_manifest.changed - - name: "Fluentd | Create fluentd daemonset" - kube: - filename: "{{kube_config_dir}}/fluentd-ds.yaml" - kubectl: "{{bin_dir}}/kubectl" - name: "fluentd-es-v{{ fluentd_version }}" - namespace: "{{system_namespace}}" - resource: "ds" - state: "{{ item | ternary('latest','present') }}" - with_items: "{{ fluentd_ds_manifest.changed }}" + command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/fluentd-ds.yaml -n {{ system_namespace }}" run_once: true + when: fluentd_ds_manifest.changed + diff --git a/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2 b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2 new file mode 100644 index 000000000..8a8ebbcec --- /dev/null +++ b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2 @@ -0,0 +1,328 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluentd-config + namespace: "{{ system_namespace }}" +data: + {{ fluentd_config_file }}: | + # This configuration file for Fluentd / td-agent is used + # to watch changes to Docker log files. The kubelet creates symlinks that + # capture the pod name, namespace, container name & Docker container ID + # to the docker logs for pods in the /var/log/containers directory on the host. + # If running this fluentd configuration in a Docker container, the /var/log + # directory should be mounted in the container. + # + # These logs are then submitted to Elasticsearch which assumes the + # installation of the fluent-plugin-elasticsearch & the + # fluent-plugin-kubernetes_metadata_filter plugins. + # See https://github.com/uken/fluent-plugin-elasticsearch & + # https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter for + # more information about the plugins. + # Maintainer: Jimmi Dyson + # + # Example + # ======= + # A line in the Docker log file might look like this JSON: + # + # {"log":"2014/09/25 21:15:03 Got request with path wombat\n", + # "stream":"stderr", + # "time":"2014-09-25T21:15:03.499185026Z"} + # + # The time_format specification below makes sure we properly + # parse the time format produced by Docker. This will be + # submitted to Elasticsearch and should appear like: + # $ curl 'http://elasticsearch-logging:9200/_search?pretty' + # ... + # { + # "_index" : "logstash-2014.09.25", + # "_type" : "fluentd", + # "_id" : "VBrbor2QTuGpsQyTCdfzqA", + # "_score" : 1.0, + # "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n", + # "stream":"stderr","tag":"docker.container.all", + # "@timestamp":"2014-09-25T22:45:50+00:00"} + # }, + # ... + # + # The Kubernetes fluentd plugin is used to write the Kubernetes metadata to the log + # record & add labels to the log record if properly configured. This enables users + # to filter & search logs on any metadata. + # For example a Docker container's logs might be in the directory: + # + # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b + # + # and in the file: + # + # 997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log + # + # where 997599971ee6... is the Docker ID of the running container. + # The Kubernetes kubelet makes a symbolic link to this file on the host machine + # in the /var/log/containers directory which includes the pod name and the Kubernetes + # container name: + # + # synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # -> + # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log + # + # The /var/log directory on the host is mapped to the /var/log directory in the container + # running this instance of Fluentd and we end up collecting the file: + # + # /var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # This results in the tag: + # + # var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # The Kubernetes fluentd plugin is used to extract the namespace, pod name & container name + # which are added to the log message as a kubernetes field object & the Docker container ID + # is also added under the docker field object. + # The final tag is: + # + # kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log + # + # And the final log record look like: + # + # { + # "log":"2014/09/25 21:15:03 Got request with path wombat\n", + # "stream":"stderr", + # "time":"2014-09-25T21:15:03.499185026Z", + # "kubernetes": { + # "namespace": "default", + # "pod_name": "synthetic-logger-0.25lps-pod", + # "container_name": "synth-lgr" + # }, + # "docker": { + # "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b" + # } + # } + # + # This makes it easier for users to search for logs by pod name or by + # the name of the Kubernetes container regardless of how many times the + # Kubernetes pod has been restarted (resulting in a several Docker container IDs). + # + # TODO: Propagate the labels associated with a container along with its logs + # so users can query logs using labels as well as or instead of the pod name + # and container name. This is simply done via configuration of the Kubernetes + # fluentd plugin but requires secrets to be enabled in the fluent pod. This is a + # problem yet to be solved as secrets are not usable in static pods which the fluentd + # pod must be until a per-node controller is available in Kubernetes. + # Prevent fluentd from handling records containing its own logs. Otherwise + # it can lead to an infinite loop, when error in sending one message generates + # another message which also fails to be sent and so on. + + type null + + # Example: + # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"} + + type tail + path /var/log/containers/*.log + pos_file /var/log/es-containers.log.pos + time_format %Y-%m-%dT%H:%M:%S.%NZ + tag kubernetes.* + format json + read_from_head true + + # Example: + # 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081 + + type tail + format /^(?