以3节点为例,存储使用local pv使用最大io性能,所有节点即是master节点也是data节点。完整内容可参考文档:
https://www.cuiliangblog.cn/detail/section/162609409
系统参数调整
---
修改文件描述符数目
---
设置环境变量
1 2 3 4 5 # 修改环境变量文件 vim /etc/profile ulimit -n 65535 # 使配置生效 source /etc/profile
修改limits.conf配置文件
1 2 3 4 # 修改limits.conf配置 vim /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535
验证
修改虚拟内存数大小
---
内核设置可以直接在主机上设置,也可以通过具有特权的初始化容器中设置,通常情况下直接在主机上设置。
临时设置
1 2 # sysctl -w vm.max_map_count=262144 vm.max_map_count = 262144
永久设置
1 2 3 4 5 cat >> /etc/sysctl.conf << EOF vm.max_map_count=262144 EOF # sysctl -p vm.max_map_count = 262144
创建local pv资源
---
创建StorageClass
---
provisioner 字段定义为 no-provisioner,这是因为 Local Persistent Volume 目前尚不支持 Dynamic Provisioning 动态生成 PV,所以我们需要提前手动创建 PV。 volumeBindingMode 字段定义为 WaitForFirstConsumer,它是 Local Persistent Volume 里一个非常重要的特性,即:延迟绑定。延迟绑定就是在我们提交 PVC 文件时,StorageClass 为我们延迟绑定 PV 与 PVC 的对应关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@tiaoban eck]# cat > storageClass.yaml << EOF apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer EOF [root@tiaoban eck]# kubectl apply -f storageClass.yaml storageclass.storage.k8s.io/local-storage created [root@tiaoban eck]# kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-storage kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 19s
创建pv
---
pv资源分布如下:
pv名称
主机
路径
容量
es-data-pv0
k8s-test1
/data/es-data
50G
es-data-pv1
k8s-test2
/data/es-data
50G
es-data-pv2
k8s-test3
/data/es-data
50G
我们需要提前在各个节点下创建对应的数据存储目录。
创建pv资源:
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 [root@tiaoban eck]# cat > pv.yaml << EOF apiVersion: v1 kind: PersistentVolume metadata: name: es-data-pv0 labels: app: es-pv0 spec: capacity: storage: 50Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain # 删除策略 storageClassName: local-storage # storageClass名称,与前面创建的storageClass保持一致 local: path: /data/es-data # 本地存储路径 nodeAffinity: # 调度至k8s-test1节点 required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-test1 --- apiVersion: v1 kind: PersistentVolume metadata: name: es-data-pv1 labels: app: es-pv1 spec: capacity: storage: 50Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain # 删除策略 storageClassName: local-storage # storageClass名称,与前面创建的storageClass保持一致 local: path: /data/es-data # 本地存储路径 nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-test2 --- apiVersion: v1 kind: PersistentVolume metadata: name: es-data-pv2 labels: app: es-pv2 spec: capacity: storage: 50Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain # 删除策略 storageClassName: local-storage # storageClass名称,与前面创建的storageClass保持一致 local: path: /data/es-data # 本地存储路径 nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-test3 EOF [root@tiaoban eck]# kubectl apply -f pv.yaml persistentvolume/es-data-pv0 created persistentvolume/es-data-pv1 created persistentvolume/es-data-pv2 created [root@tiaoban eck]# kubectl get pv | grep es es-data-pv0 50Gi RWO Retain Available local-storage <unset> 43s es-data-pv1 50Gi RWO Retain Available local-storage <unset> 43s es-data-pv2 50Gi RWO Retain Available local-storage <unset> 43s
创建pvc
---
创建的时候注意pvc的名字的构成:pvc的名字 = volume_name-statefulset_name-序号,然后通过selector标签选择,强制将pvc与pv绑定。
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 [root@tiaoban eck]# cat > pvc.yaml << EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: elasticsearch-data-elasticsearch-es-all-0 namespace: elk spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: local-storage selector: matchLabels: app: es-pv0 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: elasticsearch-data-elasticsearch-es-all-1 namespace: elk spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: local-storage selector: matchLabels: app: es-pv1 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: elasticsearch-data-elasticsearch-es-all-2 namespace: elk spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi storageClassName: local-storage selector: matchLabels: app: es-pv2 EOF [root@tiaoban eck]# kubectl create ns elk namespace/elk created [root@tiaoban eck]# kubectl apply -f pvc.yaml persistentvolumeclaim/elasticsearch-data-elasticsearch-es-all-0 created persistentvolumeclaim/elasticsearch-data-elasticsearch-es-all-1 created persistentvolumeclaim/elasticsearch-data-elasticsearch-es-all-2 created [root@tiaoban eck]# kubectl get pvc -n elk NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE elasticsearch-data-elasticsearch-es-all-0 Pending local-storage <unset> 53s elasticsearch-data-elasticsearch-es-all-1 Pending local-storage <unset> 53s elasticsearch-data-elasticsearch-es-all-2 Pending local-storage <unset> 53s
ECK部署
---
部署CRD资源
---
1 2 3 4 5 6 7 8 9 10 11 12 [root@tiaoban eck]# wget https://download.elastic.co/downloads/eck/2.14.0/crds.yaml [root@tiaoban eck]# kubectl apply -f crds.yaml customresourcedefinition.apiextensions.k8s.io/agents.agent.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/apmservers.apm.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/beats.beat.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/elasticmapsservers.maps.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/elasticsearchautoscalers.autoscaling.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/elasticsearches.elasticsearch.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/enterprisesearches.enterprisesearch.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/kibanas.kibana.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/logstashes.logstash.k8s.elastic.co created customresourcedefinition.apiextensions.k8s.io/stackconfigpolicies.stackconfigpolicy.k8s.elastic.co created
部署Operator
---
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@tiaoban eck]# wget https://download.elastic.co/downloads/eck/2.14.0/operator.yaml [root@tiaoban eck]# kubectl apply -f operator.yaml namespace/elastic-system created serviceaccount/elastic-operator created secret/elastic-webhook-server-cert created configmap/elastic-operator created clusterrole.rbac.authorization.k8s.io/elastic-operator created clusterrole.rbac.authorization.k8s.io/elastic-operator-view created clusterrole.rbac.authorization.k8s.io/elastic-operator-edit created clusterrolebinding.rbac.authorization.k8s.io/elastic-operator created service/elastic-webhook-server created statefulset.apps/elastic-operator created validatingwebhookconfiguration.admissionregistration.k8s.io/elastic-webhook.k8s.elastic.co created
验证
---
1 2 3 4 5 6 [root@tiaoban eck]# kubectl get pod -n elastic-system NAME READY STATUS RESTARTS AGE elastic-operator-0 1/1 Running 0 2s [root@tiaoban eck]# kubectl get svc -n elastic-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elastic-webhook-server ClusterIP 10.103.185.159 <none> 443/TCP 5m55s
当看到elastic-operator-0状态为Running时,表示eck已成功部署并运行在k8s集群上。
Elasticsearch部署
---
创建elasticsearch集群
---
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 [root@tiaoban eck]# cat > es.yaml << EOF apiVersion: elasticsearch.k8s.elastic.co/v1 kind: Elasticsearch metadata: namespace: elk name: elasticsearch spec: version: 8.15.3 image: harbor.local.com/elk/elasticsearch:8.15.3 # 自定义镜像地址,如果不指定则从elastic官方镜像仓库拉取 nodeSets: - name: all # 节点名称 count: 3 # 节点数量 volumeClaimTemplates: - metadata: name: elasticsearch-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 50Gi # 指定master节点存储容量,与pvc容量保持一致。 storageClassName: local-storage podTemplate: spec: containers: - name: elasticsearch env: - name: ES_JAVA_OPTS # 指定节点JVM大小 value: "-Xms1g -Xmx1g" resources: limits: # 资源限制值,通常为JVM的2倍 cpu: 1 memory: 2Gi requests: # 资源请求值,通常与JVM保持一致 cpu: 500m memory: 1Gi EOF [root@tiaoban eck]# kubectl apply -f es.yaml elasticsearch.elasticsearch.k8s.elastic.co/elasticsearch created
查看并验证资源
---
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@tiaoban eck]# kubectl get pod -n elk NAME READY STATUS RESTARTS AGE elasticsearch-es-all-0 1/1 Running 0 3m48s elasticsearch-es-all-1 1/1 Running 0 3m48s elasticsearch-es-all-2 1/1 Running 0 3m48s [root@tiaoban eck]# kubectl get svc -n elk NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch-es-all ClusterIP None <none> 9200/TCP 4m7s elasticsearch-es-http ClusterIP 10.96.196.197 <none> 9200/TCP 4m9s elasticsearch-es-internal-http ClusterIP 10.98.63.89 <none> 9200/TCP 4m9s elasticsearch-es-transport ClusterIP None <none> 9300/TCP 4m9s [root@tiaoban eck]# kubectl get es -n elk NAME HEALTH NODES VERSION PHASE AGE elasticsearch green 3 8.15.3 Ready 4m22s
获取elastic用户密码
1 2 [root@tiaoban eck]# kubectl get secrets -n elk elasticsearch-es-elastic-user -o go-template='{{.data.elastic | base64decode}}' A1i529P3q783xblCSChV8zY1
导出CA证书
1 [root@tiaoban eck]# kubectl -n elk get secret elasticsearch-es-http-certs-public -o go-template='{{index .data "ca.crt" | base64decode }}' > ca.crt
访问验证
1 2 3 4 5 [root@rockylinux /]# curl -k https://elastic:A1i529P3q783xblCSChV8zY1@elasticsearch-es-http.elk.svc:9200/_cat/nodes?v ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 10.244.0.55 8 71 8 0.65 0.69 0.66 cdfhilmrstw - elasticsearch-es-all-0 10.244.2.32 45 72 9 0.90 0.98 0.82 cdfhilmrstw * elasticsearch-es-all-2 10.244.1.24 25 70 7 1.04 0.91 0.73 cdfhilmrstw - elasticsearch-es-all-1
创建ingress资源
---
自签证书创建secret资源
1 2 3 4 5 [root@tiaoban eck]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=elk-tls" Generating a RSA private key writing new private key to 'tls.key' [root@tiaoban eck]# kubectl create secret tls -n elk elk-tls --cert=tls.crt --key=tls.key secret/elk-tls created
创建IngressRouter规则文件和ServersTransport文件,配置insecureSkipVerify使得traefik代理访问后端服务时跳过证书验证。
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 [root@tiaoban eck]# cat > es-ingress.yaml << EOF apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: elasticsearch-transport namespace: elk spec: serverName: "elasticsearch.local.com" insecureSkipVerify: true --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: elasticsearch namespace: elk spec: entryPoints: - websecure routes: - match: Host(`elasticsearch.local.com`) kind: Rule services: - name: elasticsearch-es-http port: 9200 serversTransport: elasticsearch-transport tls: secretName: elk-tls EOF [root@tiaoban eck]# kubectl apply -f es.yaml serverstransport.traefik.io/elasticsearch-transport created ingressroute.traefik.io/elasticsearch created
添加hosts后访问验证
Kibana部署
---
创建kibana资源
---
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 [root@tiaoban eck]# cat > kibana.yaml << EOF apiVersion: kibana.k8s.elastic.co/v1 kind: Kibana metadata: name: kibana namespace: elk spec: version: 8.15.3 image: harbor.local.com/elk/kibana:8.15.3 count: 1 elasticsearchRef: # 与Elasticsearch资源名称匹配 name: elasticsearch podTemplate: spec: containers: - name: kibana env: - name: NODE_OPTIONS value: "--max-old-space-size=2048" - name: SERVER_PUBLICBASEURL value: "https://kibana.local.com" - name: I18N_LOCALE # 中文配置 value: "zh-CN" resources: requests: memory: 1Gi cpu: 0.5 limits: memory: 2Gi cpu: 2 EOF [root@tiaoban eck]# kubectl apply -f kibana.yaml kibana.kibana.k8s.elastic.co/kibana created
查看验证
1 2 3 4 5 6 7 [root@tiaoban eck]# kubectl get pod -n elk | grep kibana kibana-kb-6698c6c45d-r7jj6 1/1 Running 0 3m39s [root@tiaoban eck]# kubectl get svc -n elk | grep kibana kibana-kb-http ClusterIP 10.105.217.119 <none> 5601/TCP 3m43s [root@tiaoban eck]# kubectl get kibana -n elk NAME HEALTH NODES VERSION AGE kibana green 1 8.15.3 3m50s
创建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 [root@tiaoban eck]# cat > kibana-ingress.yaml << EOF apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: kibana-transport namespace: elk spec: serverName: "kibana.local.com" insecureSkipVerify: true --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: kibana namespace: elk spec: entryPoints: - websecure routes: - match: Host(`kibana.local.com`) kind: Rule services: - name: kibana-kb-http port: 5601 serversTransport: kibana-transport tls: secretName: elk-tls EOF [root@tiaoban eck]# kubectl apply -f kibana.yaml serverstransport.traefik.io/kibana-transport created ingressroute.traefik.io/kibana created
访问验证
---
客户端添加hosts记录后访问kibana测试