Helm快速搭建ES集群

434 阅读9分钟

前段时间我们的Elasticsearch测试环境突然崩溃了,正当我幸灾乐祸的时候,我们组长找到了我,打算让我搭一套来日常使用,此时我的笑脸瞬间就凝固了,对此我只能说一句:一切交给我,我一定能给你办砸。为了尽快完成任务,我决定使用 Helm 来快速安装一个新的Elasticsearch集群,以便将我的笑容转移到他的脸上。

一 资源准备

1.1 环境信息

集群名称节点类型副本数目CPU内存大小存储大小网络模式描述
elasticsearchKubernetes Master322Gi5GiClusterIP主节节点,用于控制 ES 集群
elasticsearchKubernetes Data322Gi50GiClusterIP数据节点,用于存储 ES 数据
elasticsearchKubernetes Client222GiNodePort(30200)负责处理用户请求,实现请求转发、负载均衡
Kibana112GiNodePort(30601)用于展示 ElasticSearch 数据的应用

1.2 配置StorageClass

为了方便管理我们的es集群,我们先创建一个命名空间并切换过去。

kubectl create namespace es
kubectl config set-context --current --namespace=es

我们需要一个名为nfs-storage的来动态存储服务。

kubectl get StorageClass

二 创建证书

2.1 生成证书

为了方便,我写了一个脚本,直接运行即可。

echo "创建证书存储目录:$WORK_DIR"
mkdir -p "$WORK_DIR"

# 拉取 Elasticsearch 镜像
echo "拉取 Elasticsearch 镜像:$ELASTICSEARCH_IMAGE"
docker pull "$ELASTICSEARCH_IMAGE"

# 运行容器生成证书
echo "运行容器生成证书..."
docker run --rm -i --name "${ELASTIC_NAME}" \
    -e discovery.type=single-node \
    -e xpack.security.enabled=true \
    -v "$WORK_DIR":"$CERTS_DIR" \
    "$ELASTICSEARCH_IMAGE" /bin/sh <<EOF
#!/bin/bash
# 使用 elasticsearch-certutil 创建 CA 文件
bin/elasticsearch-certutil ca --out $CERTS_DIR/elastic-stack-ca.p12 --pass '' --days $DAYS

# 使用 CA 文件创建节点证书
bin/elasticsearch-certutil cert --name security-master --dns security-master --ca $CERTS_DIR/elastic-stack-ca.p12 --pass '' --ca-pass '' --out $CERTS_DIR/elastic-certificates.p12 --days $DAYS
EOF

# 检查是否生成了证书文件
if [ ! -f "$WORK_DIR/elastic-certificates.p12" ]; then
    echo "错误:证书文件未生成,请检查日志!"
    exit 1
fi

# 提取 pcks12 信息到 pem 文件
echo "提取 PKCS12 信息到 PEM 文件..."
openssl pkcs12 -nodes -passin pass:'' -in "$WORK_DIR/elastic-certificates.p12" -out "$WORK_DIR/elastic-certificate.pem"

# 查看证书有效期
echo "证书有效期:"
openssl pkcs12 -in "$WORK_DIR/elastic-certificates.p12" -nodes -passin pass:'' | openssl x509 -noout -dates

# 打印完成信息
echo "==== Elasticsearch 证书生成完成! ===="
echo "证书路径:$WORK_DIR"

2.2 添加证书到集群

# 添加证书
kubectl create secret generic elastic-certificates --from-file=elastic-certificates.p12
kubectl create secret generic elastic-certificate-pem --from-file=elastic-certificate.pem

# 设置集群用户名密码,用户名不建议修改
kubectl create secret generic elastic-credentials \
  --from-literal=username=elastic --from-literal=password=admin@1233

配置应用参数

注意:因为测试所以给的cpu和内存以及存储都比较小,正式部署适当调高。

3.1 创建es-master-values.yaml

# ============设置集群名称============
## 设置集群名称
clusterName: "elasticsearch"
## 设置节点名称
nodeGroup: "master"
## 设置角色
roles:
  master: "true"
  ingest: "false"
  data: "false"

# ============镜像配置============
## 指定镜像与镜像版本
#image: "docker.io/huoyujia/elasticsearch-with-ik"
image: "docker.elastic.co/elasticsearch/elasticsearch"
imageTag: "7.17.3"
#imagePullPolicy: Never
## 副本数
replicas: 3

# ============资源配置============
## JVM 配置参数
esJavaOpts: "-Xmx1g -Xms1g"
## 部署资源配置(生成环境一定要设置大些)
resources:
  requests:
    cpu: "2000m"
    memory: "2Gi"
  limits:
    cpu: "2000m"
    memory: "2Gi"


## 数据持久卷配置
persistence:
  enabled: true
volumeClaimTemplate:
  storageClassName: nfs-storage
  accessModes: [ "ReadWriteOnce" ]
  resources:
    requests:
      storage: 5Gi
                  
# ============安全配置============
## 设置协议,可配置为 http、https
protocol: http
## 证书挂载配置,这里我们挂入上面创建的证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs

## 允许您在/usr/share/elasticsearch/config/中添加任何自定义配置文件,例如 elasticsearch.yml
## ElasticSearch 7.x 默认安装了 x-pack 插件,部分功能免费,这里我们配置下
## 下面注掉的部分为配置 https 证书,配置此部分还需要配置 helm 参数 protocol 值改为 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12

## 环境变量配置,这里引入上面设置的用户名、密码 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password

# ============调度配置============
## 设置调度策略
## - hard:只有当有足够的节点时 Pod 才会被调度,并且它们永远不会出现在同一个节点上
## - soft:尽最大努力调度
antiAffinity: "hard"
## 容忍配置(一般 kubernetes master 或其它设置污点的节点,只有指定容忍才能进行调度,如果测试环境只有三个节点,则可以开启在 master 节点安装应用)
tolerations:
  - operator: "Exists"  ##容忍全部污点

3.2 创建es-data-values.yaml

# ============设置集群名称============
## 设置集群名称
clusterName: "elasticsearch"
## 设置节点名称
nodeGroup: "data"
## 设置角色
roles:
  master: "false"
  ingest: "true"
  data: "true"

# ============镜像配置============
## 指定镜像与镜像版本
#image: "docker.io/huoyujia/elasticsearch-with-ik"
image: docker.elastic.co/elasticsearch/elasticsearch
imageTag: "7.17.3"
#imagePullPolicy: Never

## 副本数
replicas: 3

# ============资源配置============
## JVM 配置参数
esJavaOpts: "-Xmx1g -Xms1g"
## 部署资源配置(生成环境一定要设置大些)
resources:
  requests:
    cpu: "1000m"
    memory: "2Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"

## 数据持久卷配置
persistence:
  enabled: true
  ## 存储数据大小配置
volumeClaimTemplate:
  storageClassName: nfs-storage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi

# ============安全配置============
## 设置协议,可配置为 http、https
protocol: http
## 证书挂载配置,这里我们挂入上面创建的证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs
## 允许您在/usr/share/elasticsearch/config/中添加任何自定义配置文件,例如 elasticsearch.yml
## ElasticSearch 7.x 默认安装了 x-pack 插件,部分功能免费,这里我们配置下
## 下面注掉的部分为配置 https 证书,配置此部分还需要配置 helm 参数 protocol 值改为 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
## 环境变量配置,这里引入上面设置的用户名、密码 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password

# ============调度配置============
## 设置调度策略
## - hard:只有当有足够的节点时 Pod 才会被调度,并且它们永远不会出现在同一个节点上
## - soft:尽最大努力调度
antiAffinity: "hard"
## 容忍配置(一般 kubernetes master 或其它设置污点的节点,只有指定容忍才能进行调度,如果测试环境只有三个节点,则可以开启在 master 节点安装应用)
tolerations: 
  - operator: "Exists"  ##容忍全部污点

3.3 创建es-client-values.yaml

# ============设置集群名称============
## 设置集群名称
clusterName: "elasticsearch"
## 设置节点名称
nodeGroup: "client"
## 设置角色
roles:
  master: "false"
  ingest: "false"
  data: "false"

# ============镜像配置============
## 指定镜像与镜像版本
#image: "docker.io/huoyujia/elasticsearch-with-ik"
image: docker.elastic.co/elasticsearch/elasticsearch
imageTag: "7.17.3"
#imagePullPolicy: Never
## 副本数
replicas: 2

# ============资源配置============
## JVM 配置参数
esJavaOpts: "-Xmx1g -Xms1g"
## 部署资源配置(生成环境一定要设置大些)
resources:
  requests:
    cpu: "1000m"
    memory: "2Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"

# ============临时存储配置============
## 使用临时存储,而不是持久化存储
persistence:
  enabled: false  # 关闭持久化存储

## 删除 volumeClaimTemplate 配置,因为临时存储不需要PVC

# ============安全配置============
## 设置协议,可配置为 http、https
protocol: http
## 证书挂载配置,这里我们挂入上面创建的证书
secretMounts:
  - name: elastic-certificates
    secretName: elastic-certificates
    path: /usr/share/elasticsearch/config/certs

## 允许您在/usr/share/elasticsearch/config/中添加任何自定义配置文件,例如 elasticsearch.yml
## ElasticSearch 7.x 默认安装了 x-pack 插件,部分功能免费,这里我们配置下
## 下面注掉的部分为配置 https 证书,配置此部分还需要配置 helm 参数 protocol 值改为 https
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.enabled: true
    # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
    # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12

## 环境变量配置,这里引入上面设置的用户名、密码 secret 文件
extraEnvs:
  - name: ELASTIC_USERNAME
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: ELASTIC_PASSWORD
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password

# ============Service 配置============
## Service 类型
service:
  type: NodePort
  nodePort: "30200"

3.4 创建es-kibana-values.yaml

# ============镜像配置============
## 指定镜像与镜像版本
image: "docker.elastic.co/kibana/kibana"
imageTag: "7.17.3"
## 配置 ElasticSearch 地址
elasticsearchHosts: "http://elasticsearch-client:9200"

# ============环境变量配置============
## 环境变量配置,这里引入上面设置的用户名、密码 secret 文件
extraEnvs:
  - name: 'ELASTICSEARCH_USERNAME'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: username
  - name: 'ELASTICSEARCH_PASSWORD'
    valueFrom:
      secretKeyRef:
        name: elastic-credentials
        key: password

# ============资源配置============
resources:
  requests:
    cpu: "1000m"
    memory: "2Gi"
  limits:
    cpu: "1000m"
    memory: "2Gi"

# ============配置 Kibana 参数============
## kibana 配置中添加语言配置,设置 kibana 为中文
kibanaConfig:
  kibana.yml: |
    i18n.locale: "zh-CN"

# ============Service 配置============
service:
  type: NodePort
  nodePort: "30601"

四 部署测试

4.1 Helm安装

# 添加 Chart 仓库
helm repo add  elastic  https://helm.elastic.co
helm repo update
# 安装 ElasticSearch Master 节点
helm install elasticsearch-master -f es-master-values.yaml --version 7.17.3 elastic/elasticsearch
# 安装 ElasticSearch Data 节点
helm install elasticsearch-data -f es-data-values.yaml --version 7.17.3 elastic/elasticsearch
# 安装 ElasticSearch Client 节点
helm install elasticsearch-client -f es-client-vlues.yaml --version 7.17.3 elastic/elasticsearch
# 安装 Kibana
helm install kibana -f es-kibana-values.yaml --version 7.17.3 elastic/kibana

4.2 Kibana 浏览 ElasticSearch 数据

先查看一下service和pod:kubectl get service,pod | grep -E 'elasticsearch|kibana'

访问kibnaa,用户名、密码elastic/admin@1233

登录成功后就跳转到 Kibana 主界面:

五 安装ik分词器

安装ik分词器主要我感觉主要有两种解决方式:

  1. 持久化存储插件的目录,然后在每个pod上安装ik分词器。
  2. 将es与ik分词器打成一个镜像。

为什么采用2而不是1呢?我感觉2更简单,采用1的话需要修改所有的yaml,然后给每个pod创建一个pvc,然后还需要在每个pod上都执行安装ik分词器的命令。其次我感觉可维护性还有启动速度方面也更占优。所以我将自己构建一个镜像。

5.1 准备镜像

创建一个DockerFile。

#Docker image of elasticsearch with ik tokenizer
# VERSION 7.17.3
# Author: huoyujia

#基础镜像使用elasticsearch:7.17.3
FROM docker.elastic.co/elasticsearch/elasticsearch:7.17.3

#作者
MAINTAINER HuoYuJia
RUN sh -c '/bin/echo -e "y" | bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/7.17.3'

构建镜像docker build -t huoyujia/elasticsearch-with-ik:7.17.3 .,然后测试docker run -p 9201:9200 -p 9300:9300 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" huoyujia/elasticsearch-with-ik:7.17.3

查看日志注意到有analysis-ik插件就代表成功了。

将我们构建的镜像上传到harbor即可,我没有harbor,我就上传到k8s的node节点了。

#打包镜像
docker save -o elasticsearch-with-ik:7.17.3.tar huoyujia/elasticsearch-with-ik:7.17.3
#改权限
chmod +777 elasticsearch-with-ik:7.17.3.tar
#传送到k8s的节点,然后导入
ctr -n k8s.io image import elasticsearch-with-ik_7.17.3.tar
#查看镜像名字
ctr -n k8s.io images list
#发现名字为 docker.io/huoyujia/elasticsearch-with-ik

5.2 更新测试

最后修改es-master-values.yaml、es-data-values.yaml、es-client-values.yaml的镜像部分修改成新的镜像地址和只使用本地镜像。

image: "docker.io/huoyujia/elasticsearch-with-ik"
imageTag: "7.17.3"
imagePullPolicy: Never

然后更新Helm Release:

# 更新 ElasticSearch Master 节点
helm upgrade elasticsearch-master -f es-master-values.yaml --version 7.17.3 elastic/elasticsearch

# 更新 ElasticSearch Data 节点
helm upgrade elasticsearch-data -f es-data-values.yaml --version 7.17.3 elastic/elasticsearch

# 更新 ElasticSearch Client 节点
helm upgrade elasticsearch-client -f es-client-values.yaml --version 7.17.3 elastic/elasticsearch

最后进入kibana测试,发现ik分词器成功。

 GET /_analyze
{
    "text": "林俊杰在上海市开演唱会啦",
    "analyzer": "ik_smart"
}

参考

cloud.tencent.com/developer/i…

cloud.tencent.com/developer/a…

github.com/infinilabs/…