ECK是官方推出的在Kubernetes集群中的部署方式,其采用operator的方式进行部署。
部署operator
kubectl apply -f https://download.elastic.co/downloads/eck/1.1.2/all-in-one.yaml
然后通过一下命令查看日志输出
kubectl -n elastic-system logs -f statefulset.apps/elastic-operator
可以通过一下命令查看部署情况
# kubectl get pod -n elastic-systemNAME READY STATUS RESTARTS AGEelastic-operator-0 1/1 Running 0 19m# kubectl get svc -n elastic-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEelastic-webhook-server ClusterIP 10.102.3.82 <none> 443/TCP 19m
部署ElasticSearch
编写YAML文件,如下
apiVersion: elasticsearch.k8s.elastic.co/v1beta1kind: Elasticsearchmetadata:name: esnamespace: elastic-systemspec:version: 7.4.1http:service:metadata:creationTimestamp: nullspec: {}tls:certificate: {}selfSignedCertificate:disabled: truenodeSets:- config:node.data: truenode.ingest: truenode.master: truenode.store.allow_mmap: truexpack.security.authc.realms:native:native1:order: 1count: 1name: masterpodTemplate:spec:containers:- env:- name: ES_JAVA_OPTSvalue: -Xms1g -Xmx1gname: elasticsearchresources:limits:cpu: 2memory: 2Girequests:cpu: 2memory: 2GivolumeClaimTemplates:- metadata:name: elasticsearch-dataspec:accessModes:- ReadWriteManyresources:requests:storage: 10GistorageClassName: managed-nfs-storage
通过NFS做的持久化
可以通过如下命令查看状态
# kubectl get elasticsearches.elasticsearch.k8s.elastic.co -n elastic-systemNAME HEALTH NODES VERSION PHASE AGEes green 1 7.4.1 Ready 48m# kubectl get pod -n elastic-systemNAME READY STATUS RESTARTS AGEelastic-operator-0 1/1 Running 1 56mes-es-master-0 1/1 Running 0 47m
查看svc的信息
# kubectl get svc -n elastic-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEelastic-webhook-server ClusterIP 10.111.204.184 <none> 443/TCP 57mes-es-http ClusterIP 10.100.200.193 <none> 9200/TCP 48mes-es-master ClusterIP None <none> <none> 47mes-es-transport ClusterIP None <none> 9300/TCP 48m
同时是会生成一些secrets,如下:
# kubectl get secrets -n elastic-systemNAME TYPE DATA AGEdefault-token-xjqxq kubernetes.io/service-account-token 3 57melastic-operator-token-ttckk kubernetes.io/service-account-token 3 57melastic-system-es-kibana-kibana-user Opaque 3 23melastic-webhook-server-cert Opaque 2 57mes-es-elastic-user Opaque 1 48mes-es-http-ca-internal Opaque 2 48mes-es-http-certs-internal Opaque 3 48mes-es-http-certs-public Opaque 2 48mes-es-internal-users Opaque 2 48mes-es-master-es-config Opaque 1 47mes-es-remote-ca Opaque 1 48mes-es-transport-ca-internal Opaque 2 48mes-es-transport-certificates Opaque 3 48mes-es-transport-certs-public Opaque 1 48mes-es-xpack-file-realm Opaque 3 48m
其中quickstart-es-elastic-user就是存放的登录es的密码,我们可以通过以下命令获取明文信息
kubectl get secret -n elastic-system es-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode
然后访问查看ES是否正常(集群内部访问)
curl -k https://elastic:nf963Smr0To2u6AA1dS0u93f@es-es-http:9200
部署kibana
kibana的yaml文件如下:
apiVersion: kibana.k8s.elastic.co/v1beta1kind: Kibanametadata:name: es-kibananamespace: elastic-systemspec:count: 1elasticsearchRef:name: eshttp:service:metadata:creationTimestamp: nullspec: {}tls:certificate: {}selfSignedCertificate:disabled: truepodTemplate:metadata:creationTimestamp: nullspec:containers:- name: kibanaresources:limits:cpu: 1memory: 2Girequests:cpu: 0.5memory: 1Giversion: 7.4.1
部署后查看pod状态。
# kubectl get pod -n elastic-systemNAME READY STATUS RESTARTS AGEelastic-operator-0 1/1 Running 1 58mes-es-master-0 1/1 Running 0 48mes-kibana-kb-5c4468f8bf-msql2 1/1 Running 0 23m
查看svc。
# kubectl get svc -n elastic-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEelastic-webhook-server ClusterIP 10.111.204.184 <none> 443/TCP 64mes-es-http ClusterIP 10.100.200.193 <none> 9200/TCP 55mes-es-master ClusterIP None <none> <none> 55mes-es-transport ClusterIP None <none> 9300/TCP 55mes-kibana-kb-http NodePort 10.105.148.116 <none> 5601:30696/TCP 30m
然后我们用kubectl edit将es-kibana-kb-http 的type类型改为NodePort。
登录kibana,创建index template
PUT /_template/app-template{"index_patterns" : ["app-*"],"settings" : {"index" : {"lifecycle" : {"name" : "slm-history-ilm-policy"},"number_of_shards" : "2","number_of_replicas" : "0","highlight.max_analyzed_offset": 10000000}},"mappings" : {"dynamic_templates" : [{"message_field" : {"path_match" : "message","mapping" : {"norms" : false,"type" : "text"},"match_mapping_type" : "string"}},{"string_fields" : {"mapping" : {"norms" : false,"type" : "keyword"},"match_mapping_type" : "string","match" : "*"}}]},"aliases" : { }}
部署filebeat
配置filebeat的configMap.
apiVersion: v1data:filebeat.yml: |-filebeat.inputs:- type: logfields: {host: '${NODE_NAME}'}enabled: truepaths:- /var/logs/webapps/*/*/*-info-*.logtail_files: truemultiline.match: aftermultiline.negate: truemultiline.pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}processors:- dissect:tokenizer: "/%{key1}/%{key2}/%{key3}/%{appName}/%{podName}/"field: "log.file.path"target_prefix: ""- type: logfields: {host: '${NODE_NAME}'}enabled: truepaths:- /var/logs/webapps/*/*.logtail_files: truemultiline.match: aftermultiline.negate: truemultiline.pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}processors:- dissect:tokenizer: "/%{key1}/%{key2}/%{key3}/%{appName}/"field: "log.file.path"target_prefix: ""setup.ilm.enabled: falsesetup.template.pattern: "app-*"setup.template.name: "app-template"output.elasticsearch:pipeline: timestamp-pipelinehosts: ["es-es-http:9200"]username: elasticpassword: nf963Smr0To2u6AA1dS0u93findex: "app-%{[appName]}-%{+yyyy.MM.dd}"bulk_max_size: 100processors:- rename:fields:- from: "log.file.path"to: "source"- from: "fields.host"to: "node"ignore_missing: true- drop_fields:when:has_fields: ['key1','key2','key3','agent','@metadata','ecs','input','host','log','fields']fields: ['key1','key2','key3','agent','@metadata','ecs','input','host','log','fields']logging.level: errorkind: ConfigMapmetadata:labels:k8s-app: filebeatname: filebeat-confignamespace: elastic-system
filebeat的yaml如下。
apiVersion: apps/v1kind: DaemonSetmetadata:labels:k8s-app: filebeatname: filebeatnamespace: elastic-systemspec:revisionHistoryLimit: 10selector:matchLabels:k8s-app: filebeattemplate:metadata:labels:k8s-app: filebeatspec:containers:- args:- '-c'- /etc/filebeat.yml- '-e'env:- name: NODE_NAMEvalueFrom:fieldRef:apiVersion: v1fieldPath: spec.nodeNameimage: docker.elastic.co/beats/filebeat:7.4.0imagePullPolicy: IfNotPresentname: filebeatresources:limits:cpu: 300mmemory: 300Mirequests:cpu: 300mmemory: 300MisecurityContext:runAsUser: 0terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /etc/filebeat.ymlname: configreadOnly: truesubPath: filebeat.yml- mountPath: /usr/share/filebeat/dataname: data- mountPath: /var/logs/webappsname: logpathreadOnly: true- mountPath: /var/logname: varlogreadOnly: truednsPolicy: ClusterFirstWithHostNethostNetwork: truerestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30volumes:- configMap:defaultMode: 384name: filebeat-configname: config- hostPath:path: /var/lib/filebeat-datatype: DirectoryOrCreatename: data- hostPath:path: /home/logstype: ''name: logpath- hostPath:path: /var/logtype: ''name: varlog
创建模板文件:
PUT /_template/app-template{"index_patterns" : ["app-*"],"settings" : {"index" : {"lifecycle" : {"name" : "slm-history-ilm-policy"},"number_of_shards" : "2","number_of_replicas" : "0","highlight.max_analyzed_offset": 10000000}},"mappings" : {"dynamic_templates" : [{"message_field" : {"path_match" : "message","mapping" : {"norms" : false,"type" : "text"},"match_mapping_type" : "string"}},{"string_fields" : {"mapping" : {"norms" : false,"type" : "keyword"},"match_mapping_type" : "string","match" : "*"}}]},"aliases" : { }}
创建pipeline:
PUT /_ingest/pipeline/timestamp-pipeline{"description" : "fix timestamp","processors" : [{"grok" : {"if" : "! ctx.appName.contains('weipeiapp')","field" : "message","patterns" : ["%{TIMESTAMP_ISO8601:timestamp} "]},"remove" : {"if" : "! ctx.appName.contains('weipeiapp')","field" : "@timestamp"}},{"date" : {"if" : "! ctx.appName.contains('weipeiapp')","field" : "timestamp","timezone" : "Asia/Shanghai","formats" : ["yyyy-MM-dd HH:mm:ss.SSS"]},"remove" : {"if" : "! ctx.appName.contains('weipeiapp')","field" : "timestamp"}}],"on_failure" : [{"set" : {"field" : "_index","value" : "{{ _index }}"}}]}
