Kubernetes集群使用ECK部署elasticsearch和kibana

说明

  • 仅记录操作过程和部署过程
  • 请考虑再三之后再决定是否上生产环境!
  • 操作系统使用的CentOS-7.6.1810 x86_64
  • Kubernetes集群版本v1.14.4
  • elastic-operator版本为0.9.0
  • elasticsearch和kibana版本为7.2.0
  • elasticsearch和kibana默认提供HTTPS,其中elasticsearch无法关闭HTTPS

参考文档

Elastic Cloud on Kubernetes Quickstart

Elastic Cloud on k8s design

项目地址

cloud-on-k8s

准备环境

Kubernetes集群

  • kubectl版本v1.11+
  • kubectl当前content拥有cluster-admin权限

准备存储

  • 出于测试目的,本文使用emptyDir
  • 另外还可以使用volumeClaimTemplates作为持久化数据存储

部署ECK

部署elastic-operator、CRD资源、RBAC

1
kubectl apply -f https://download.elastic.co/downloads/eck/0.9.0/all-in-one.yaml

检查部署情况

1
kubectl -n elastic-system get pod

输出示例

1
2
NAME                 READY   STATUS    RESTARTS   AGE
elastic-operator-0 1/1 Running 1 50m

部署elasticsearch

编辑YAML文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
apiVersion: elasticsearch.k8s.elastic.co/v1alpha1
kind: Elasticsearch
metadata:
name: elasticsearc-demo
namespace: default
spec:
version: 7.2.0
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
updateStrategy:
changeBudget:
maxSurge: 1
maxUnavailable: 1
# groups:
# - selector:
# matchLabels:
# nodesGroup: group-a
# - selector:
# matchLabels:
# nodesGroup: group-b
http:
service:
spec:
type: ClusterIP
tls:
# certificate:
# secretName: my-cert
selfSignedCertificate:
# subjectAltNames:
# - ip: 160.46.176.15
# - dns: hulk.example.com
disabled: false
nodes:
# - nodeCount: 10
# config:
# node.master: false
# node.data: true
# node.ingest: true
# node.ml: true
# cluster.remote.connect: false
- nodeCount: 2
config:
node.master: true
node.data: true
node.ingest: true
setVmMaxMapCount: true
# volumeClaimTemplates:
# - metadata:
# name: elasticsearch-data
# spec:
# accessModes:
# - ReadWriteOnce
# storageClassName: cephfs
# resources:
# requests:
# storage: 10Gi
podTemplate:
spec:
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: failure-domain.beta.kubernetes.io/zone
# operator: In
# values:
# - abc
# initContainers:
# 使用initContainers安装elasticsearch插件
# - name: install-plugins
# command:
# - "sh"
# - "-c"
# - |
# bin/elasticsearch-plugin install --batch analysis-icu
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: -Xms2G -Xmx2G
resources:
requests:
memory: 4Gi
limits:
memory: 4Gi
volumeMounts:
- name: timezone-volume
mountPath: /etc/localtime
readOnly: true
volumes:
- name: timezone-volume
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- name: elasticsearch-data
emptyDir: {}

部署YAML

1
kubectl apply -f elasticsearch.yaml

部署kibana

编辑YAML文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
apiVersion: kibana.k8s.elastic.co/v1alpha1
kind: Kibana
metadata:
name: kibana-demo
namespace: default
spec:
version: 7.2.0
image: docker.elastic.co/kibana/kibana:7.2.0
updateStrategy:
changeBudget:
maxSurge: 1
maxUnavailable: 1
# groups:
# - selector:
# matchLabels:
# nodesGroup: group-a
# - selector:
# matchLabels:
# nodesGroup: group-b
nodeCount: 1
http:
service:
spec:
type: ClusterIP
tls:
# certificate:
# secretName: my-cert
selfSignedCertificate:
# subjectAltNames:
# - ip: 160.46.176.15
# - dns: hulk.example.com
disabled: false
elasticsearchRef:
name: elasticsearc-demo
namespace: default
podTemplate:
spec:
containers:
- name: kibana
env:
- name: I18N_LOCALE
value: zh-CN
resources:
requests:
memory: 1Gi
limits:
memory: 2Gi
volumeMounts:
- name: timezone-volume
mountPath: /etc/localtime
readOnly: true
volumes:
- name: timezone-volume
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai

部署YAML

1
kubectl apply -f kibana.yaml

验证和访问服务

查看elasticsearch

查看Pod

1
kubectl get pod -l common.k8s.elastic.co/type=elasticsearch

输出示例

1
2
3
NAME                              READY   STATUS    RESTARTS   AGE
elasticsearc-demo-es-6vpj7k9qxk 1/1 Running 1 38m
elasticsearc-demo-es-x8nzjksw84 1/1 Running 1 38m

查看集群状态

1
kubectl get elasticsearch

输出示例

1
2
NAME                HEALTH   NODES   VERSION   PHASE         AGE
elasticsearc-demo green 2 7.2.0 Operational 34m

查看secret

1
kubectl get secret -l common.k8s.elastic.co/type=elasticsearch

输出示例

1
2
3
4
5
6
7
8
NAME                                          TYPE     DATA   AGE
elasticsearc-demo-es-elastic-user Opaque 1 38m
elasticsearc-demo-es-http-ca-internal Opaque 2 38m
elasticsearc-demo-es-http-certs-internal Opaque 2 38m
elasticsearc-demo-es-internal-users Opaque 3 38m
elasticsearc-demo-es-transport-ca-internal Opaque 2 38m
elasticsearc-demo-es-transport-certs-public Opaque 1 38m
elasticsearc-demo-es-xpack-file-realm Opaque 3 38m

查看kibana

查看Pod

1
kubectl get pod -l common.k8s.elastic.co/type=kibana

输出示例

1
2
NAME                              READY   STATUS    RESTARTS   AGE
kibana-demo-kb-77cc75688f-lwqnk 1/1 Running 0 37m

查看集群状态

1
kubectl get kibana

输出示例

1
2
NAME          HEALTH   NODES   VERSION   AGE
kibana-demo green 1 7.2.0 35m

查看secret

1
kubectl get secret -l common.k8s.elastic.co/type=kibana

输出示例

1
2
3
4
5
NAME                                 TYPE     DATA   AGE
kibana-demo-kb-es-ca Opaque 1 40m
kibana-demo-kb-http-ca-internal Opaque 2 37m
kibana-demo-kb-http-certs-internal Opaque 2 37m
kibana-demo-kibana-user Opaque 1 40m

获取用户名密码

默认用户名是elastic

访问elasticsearch和kibana的密码存放在elasticsearc-demo-es-elastic-user可以通过以下方式获取

1
2
ELASTIC_PASSWORD=$(kubectl get secrets elasticsearc-demo-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode)
echo $ELASTIC_PASSWORD

访问服务

获取svc

elasticsearch

1
kubectl get svc -l common.k8s.elastic.co/type=elasticsearch

输出示例

1
2
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
elasticsearc-demo-es-http ClusterIP 10.96.217.252 <none> 9200/TCP 43m

kibana

1
kubectl get svc -l common.k8s.elastic.co/type=kibana

输出示例

1
2
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kibana-demo-kb-http ClusterIP 10.96.102.185 <none> 5601/TCP 44m

访问elasticsearch

1
curl -k -u "elastic:${ELASTIC_PASSWORD}" "http://10.96.217.252:9200"

输出示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "elasticsearc-demo-es-x8nzjksw84",
"cluster_name" : "elasticsearc-demo",
"cluster_uuid" : "U8xgFU1NSB6o8qmKYgYyxw",
"version" : {
"number" : "7.2.0",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "508c38a",
"build_date" : "2019-06-20T15:54:18.811730Z",
"build_snapshot" : false,
"lucene_version" : "8.0.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

访问kibana

修改svc为NodePort

这种做法比较low,建议走Ingress Controller

1
kubectl patch svc kibana-demo-kb-http -p '{"spec":{"type":"NodePort"}}'

获取端口

1
kubectl get svc -l common.k8s.elastic.co/type=kibana

示例输出

1
2
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kibana-demo-kb-http NodePort 10.96.102.185 <none> 5601:31364/TCP 47m

浏览器访问

https://k8s-master:31364

登录

  • 用户名:elastic
  • 密码:上面访问elasticsearch时的密码

创建ingress规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: elasticsearch-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
rules:
- host: elasticsearch.default.cluster.local
http:
paths:
- path: /
backend:
serviceName: elasticsearch-demo-es-http
servicePort: 9200
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kibana-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
rules:
- host: kibana.default.cluster.local
http:
paths:
- path: /
backend:
serviceName: kibana-demo-kb-http
servicePort: 5601