Elasticsearch 8.x 在 GitLab CI 中的正确配置指南

gitlab ci 中运行 elasticsearch 8.x 需禁用默认安全机制(如 `xpack.security.enabled=false`),并显式设置 `discovery.type=single-node`,否则因强制 tls/认证导致连接拒绝。本文提供可直接复用的 yaml 配置与关键注意事项。

Elasticsearch 自 8.0 版本起默认启用安全特性(X-Pack Security),包括强制 HTTPS、内置用户认证及 TLS 加密通信。这在本地开发或 CI 环境中(尤其是无外部证书管理能力的 GitLab Runner)会导致典型的 Connection refused 或 Protocol error —— 并非端口未暴露或服务未启动,而是 HTTP 请求被安全层拦截或重定向至 HTTPS。

要使 Elasticsearch 8.x 在 GitLab CI 中正常作为测试服务运行,必须显式禁用安全模块,同时保留单节点发现模式以绕过集群初始化检查。以下是推荐的、经验证的 .gitlab-ci.yml 片段:

lint_and_test:
  stage: test
  services:
    - postgis/postgis:14-3.4
    - name: docker.elastic.co/elasticsearch/elasticsearch:8.10.2  # 推荐使用官方镜像
      alias: elasticsearch
      command:
        - bash
        - -c
        - >
          exec /usr/local/bin/docker-entrypoint.sh
          elasticsearch
          -Ediscovery.type=single-node
          -Expack.security.enabled=false
          -Ehttp.port=9200
          -Etransport.port=9300
  tags:
    - healthcloud-multi
  script:
    - timeout 60 bash wait_for_service_up.sh elasticsearch:9200 || (echo "Elasticsearch failed to start"; exit 1)
    - curl -s "http://elasticsearch:9200/_cat/health?v"

关键说明:

  • alias: elasticsearch 确保容器内 DNS 解析为 elasticsearch,避免依赖默认主机名;
  • -Expack.security.enabled=false 是核心修复项:关闭内置身份验证、TLS 和角色权限控制;
  • -Ediscovery.type=single-node 必须保留,否则 ES 8+ 会等待其他节点加入,导致启动挂起;
  • 显式指定 -Ehttp.port=9200 可增强可

    预测性(尽管默认即为 9200);
  • 使用 docker.elastic.co/... 官方镜像(而非 Docker Hub 的 elasticsearch)更可靠,避免第三方维护滞后问题。

⚠️ 注意事项:

  • 此配置仅适用于测试/CI环境,切勿用于生产;
  • 若项目代码中已使用 https:// 协议访问 ES(如 Java High Level REST Client 或新版 @elastic/elasticsearch SDK),需同步降级为 http:// 并移除证书校验逻辑;
  • GitLab Runner 必须启用 Docker-in-Docker(dind)或使用 docker 执行器,且服务容器网络互通;
  • 建议搭配轻量健康检查脚本(如 wait_for_service_up.sh)提升稳定性,避免因启动延迟导致测试失败。

通过以上配置,Elasticsearch 8.x 可在 GitLab CI 中稳定启动并响应 HTTP 请求,无缝支撑集成测试流程。