blank的编程之路


  • 首页

  • 归档

  • 搜索
consul atomikos mybatisplus druid nexus nas named bind mysqldump acme.sh Dockerfile rsync keepalived swarm kibana ubuntu linux scp bugfix https ssl certbot curl gogs adminer harbor yum portainer python kubernetes idea java springboot maven docker-compose redis nginx mysql brew git chocolatey jenkins elasticsearch docker haproxy rabbitmq centos

docker-compose 运行 带证书链接的 es

发表于 2020-07-02 | 分类于 开发 | 2 | 阅读次数 1018

Docker elasticsearch with certificates

创建 es 数据目录

Create elasticsearch data directory

# 所有 es 相关的数据将存储于 /docker/es 下
# All elasticsearch data will be store in /docker/es
mkdir -p /docker/es/certs &&
mkdir -p /docker/es/data/es01 &&
mkdir -p /docker/es/data/es02 &&
mkdir -p /docker/es/data/es03 &&
mkdir -p /docker/es/logs/es01 &&
mkdir -p /docker/es/logs/es02 &&
mkdir -p /docker/es/logs/es03

给数据目录授权

Authorize the data directory

chmod 777 -R /docker/es/certs /docker/es/data /docker/es/logs

运行临时 es 容器用来创建证书

Run temporary elasticsearch container to create certificate files

docker run -dit --name=es elasticsearch:6.8.10 /bin/bash

# 进入 es 容器内部
# Into the es container
docker exec -it es /bin/bash

# 生成 ca 文件: elastic-stack-ca.p12 全部回车空密码
# Generate ca file: elastic-stack-ca.p12 All questions directly press Enter
bin/elasticsearch-certutil ca

# 然后使用 ca 生成 cert 文件: elastic-certificates.p12 全部回车空密码
# Then use ca to generate the cert file: elastic-certificates.p12  All questions directly press Enter
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

# 退出容器
# Exit container
exit

将证书从容器内复制到宿主机 /docker/es/certs

Copy the certificate from the container to the host docker/es/certs

docker cp es:/usr/share/elasticsearch/elastic-certificates.p12 /docker/es/certs

关闭 清理临时 es 容器

Close clean up temporary es container

docker kill es && docker rm es

创建 .env 变量配置文件

Create .env variable configuration file

echo '
# es 容器内的证书存储位置
# certificate storage location in elasticsearch container
CERTS_DIR=/usr/share/elasticsearch/config/certificates
# elastic 用户的密码, 请在修改后再进行下面的操作!
# Elastic user's password, please perform the following operations after modification!
ELASTIC_PASSWORD=pleaseChangeMe
' > /docker/es/.env

### 创建 instances.yml 文件
### Create instances.yml file

echo "
instances:
  - name: es01
    dns:
      # es容器的dns名
      - es01
      - localhost
    ip:
      # 使用IP访问时此处要改成调用容器的IP
      # 不一定是容器自身的IP, 而是各个服务进行调用的IP
      # 否则证书认证将无法通过
      # 可填多个IP
      - 127.0.0.1

  - name: es02
    dns:
      - es02
      - localhost
    ip:
      # 使用IP访问时此处要改成调用容器的IP
      # 不一定是容器自身的IP, 而是各个服务进行调用的IP
      # 否则证书认证将无法通过
      # 可填多个IP
      - 127.0.0.1

  - name: es03
    dns:
      - es03
      - localhost
    ip:
      # 使用IP访问时此处要改成调用容器的IP
      # 不一定是容器自身的IP, 而是各个服务进行调用的IP
      # 否则证书认证将无法通过
      # 可填多个IP
      - 127.0.0.1
" > /docker/es/instances.yml

创建 create-certs.yml

Create create-certs.yml

echo "
version: '2.2'

services:
  create_certs:
    container_name: create_certs
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.10
    command: >
      bash -c '
        if [[ ! -d config/certificates/certs ]]; then
          mkdir config/certificates/certs;
        fi;
        if [[ ! -f /local/certs/bundle.zip ]]; then
          bin/elasticsearch-certgen --silent --in config/certificates/instances.yml --out config/certificates/certs/bundle.zip;
          # 将新生成的证书文件放到"config/certificates/certs"
          unzip config/certificates/certs/bundle.zip -d config/certificates/certs; 
        fi;
        chgrp -R 0 config/certificates/certs
      '
    # user: ${UID:-1000}
    user: root
    working_dir: /usr/share/elasticsearch
    volumes: ['.:/usr/share/elasticsearch/config/certificates']
" > /docker/es/create-certs.yml

这个生成的 elastic-certificates.p12 就是我们需要使用的
This generated elastic-certificates.p12 is what we need to use

创建 es docker-compose.yml 文件

Create es docker-compose.yml file

cat > /docker/es/docker-compose.yml <<\EOF

version: '2.2'

services:
  es01:
    container_name: es01
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.10
    restart: always
    # 生产环境建议设置ulimits
    # It is recommended to set ulimits in production environment
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
      nproc:
        soft: 65536
        hard: 65536
    environment:
      - cluster.name=es
      - node.name=es01
      - node.master=true
      - node.data=true
      - transport.tcp.port=9300
      
      # 生产环境建议开启
      # Production environment recommended to open
      - bootstrap.memory_lock=true
      - bootstrap.system_call_filter=false
      - discovery.zen.minimum_master_nodes=2
      # elastic用户的密码, 需要在".env"文件中修改
      # The password of the elastic user needs to be modified in the ".env" file before use in production environment
      - ELASTIC_PASSWORD=$ELASTIC_PASSWORD
      - 'ES_JAVA_OPTS=-Xms256m -Xmx256m'
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.truststore.type=PKCS12
      - xpack.security.transport.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.transport.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
    volumes:  
      - /docker/es/certs:$CERTS_DIR
      - /docker/es/data/es01:/usr/share/elasticsearch/data
      - /docker/es/logs/es01:/usr/share/elasticsearch/logs  
    ports:
      - 9200:9200
      - 9300:9300
    healthcheck:
      test: curl --cacert $CERTS_DIR/ca/ca.crt -s https://localhost:9200 >/dev/null; if [[ $$? == 52 ]]; then echo 0; else echo 1; fi
      interval: 30s
      timeout: 10s
      retries: 5

  es02:
    container_name: es02
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.10
    restart: always
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
      nproc:
        soft: 65536
        hard: 65536
    environment:
      - cluster.name=es
      - node.name=es02
      - bootstrap.memory_lock=true
      - bootstrap.system_call_filter=false
      - discovery.zen.minimum_master_nodes=2
      - ELASTIC_PASSWORD=$ELASTIC_PASSWORD
      - discovery.zen.ping.unicast.hosts=es01
      - 'ES_JAVA_OPTS=-Xms256m -Xmx256m'
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.truststore.type=PKCS12
      - xpack.security.transport.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.transport.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
    volumes:  
      - /docker/es/certs:$CERTS_DIR
      - /docker/es/data/es02:/usr/share/elasticsearch/data
      - /docker/es/logs/es02:/usr/share/elasticsearch/logs      

  es03:
    container_name: es03
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.10
    restart: always
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
      nproc:
        soft: 65536
        hard: 65536
    environment:
      - cluster.name=es
      - node.name=es03
      - bootstrap.memory_lock=true
      - bootstrap.system_call_filter=false
      - discovery.zen.minimum_master_nodes=2
      - ELASTIC_PASSWORD=$ELASTIC_PASSWORD
      - discovery.zen.ping.unicast.hosts=es01
      - 'ES_JAVA_OPTS=-Xms256m -Xmx256m'
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.truststore.type=PKCS12
      - xpack.security.transport.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.transport.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.keystore.path=$CERTS_DIR/elastic-certificates.p12
      - xpack.security.http.ssl.truststore.path=$CERTS_DIR/elastic-certificates.p12
    volumes:
      - /docker/es/certs:$CERTS_DIR
      - /docker/es/data/es03:/usr/share/elasticsearch/data
      - /docker/es/logs/es03:/usr/share/elasticsearch/logs   

  wait_until_ready:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.10
    command: /usr/bin/true
    depends_on: { 'es01': { 'condition': 'service_healthy' } }
EOF

生成证书

Generate certificate

cd /docker/es/ && docker-compose -f create-certs.yml up

Pulling create_certs (docker.elastic.co/elasticsearch/elasticsearch:6.8.10)...
6.8.10: Pulling from elasticsearch/elasticsearch
Digest: sha256:f8e21f6b2ef75dcda374da505fcb0ff4bf7e8d025f12096c498123fa4e372c1b
Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch:6.8.10
Creating create_certs ... done
Attaching to create_certs
create_certs    | Archive:  config/certificates/certs/bundle.zip
create_certs    |    creating: config/certificates/certs/ca/
create_certs    |   inflating: config/certificates/certs/ca/ca.crt  
create_certs    |   inflating: config/certificates/certs/ca/ca.key  
create_certs    |    creating: config/certificates/certs/es01/
create_certs    |   inflating: config/certificates/certs/es01/es01.crt  
create_certs    |   inflating: config/certificates/certs/es01/es01.key  
create_certs    |    creating: config/certificates/certs/es02/
create_certs    |   inflating: config/certificates/certs/es02/es02.crt  
create_certs    |   inflating: config/certificates/certs/es02/es02.key  
create_certs    |    creating: config/certificates/certs/es03/
create_certs    |   inflating: config/certificates/certs/es03/es03.crt  
create_certs    |   inflating: config/certificates/certs/es03/es03.key  
create_certs exited with code 0

给生成的证书文件修改访问权限

Modify the access permissions for the generated certificate file

chmod 777 -R /docker/es/certs 

通过 docker-compose 启动 es

Start elasticsearch via docker-compose

cd /docker/es && docker-compose up -d

SpringBoot java client elasticsearch configuration

将服务器上生成的证书 elastic-certificates.p12 复制到 resources 目录中

Copy the certificate elastic-certificates.p12 generated on the server to the resources directory

配置 Maven pom.xml 添加 es springboot-starter 依赖

Configure Maven pom.xml to add elasticsearch springboot-starter dependency

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-elasticsearch -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

配置 application.yml

Configure application.yml

spring:
  data:
    elasticsearch:
      repositories:
        enabled: true
      user: elastic
      password: plelaseChangeMe
      cluster-name: es
      host: YOU_SERVER_IP
      tcpPort: 9300
      httpPort: 9200
      schema: https
      pckCertificatesPath: elastic-certificates.p12
      certificatesType: pkcs
      pkcsClientFilePath: elastic-certificates.p12

配置 ElasticSearchProperties.java

Configure ElasticSearchProperties.java

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.HashMap;
import java.util.Map;

/**
 * ElasticSearchProperties
 *
 * @author blank
 * @since 2020-07-02 下午 12:05
 **/
@ConfigurationProperties(prefix = "spring.data.elasticsearch")
@Data
public class ElasticSearchProperties {
    private String clusterName;
    private String host;
    private String schema;
    private int tcpPort;
    private int httpPort;
    private String user;
    private String password;
    private String pckCertificatesPath;
    private String certificatesType;
    private String pkcsClientFilePath;
    private Map<String, String> properties = new HashMap<>();
}

配置 ElasticSearchTransportConfig.java

Configure ElasticSearchTransportConfig.java

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.file.Paths;

/**
 * ES配置
 *
 * @author blank
 * @since 2019-10-08 上午 11:49
 **/
@Slf4j
@EnableConfigurationProperties(ElasticSearchProperties.class)
@Configuration
public class ElasticSearchTransportConfig implements DisposableBean {

    @Resource
    private ElasticSearchProperties properties;

    private Releasable releasable;

    /**
     * TransportClient 只支持到 6.X 版本的 ES 后面 7.X 不推荐 需要使用 RestClient
     * 而 springboot data es 整合的又是 TransportClient 如果 直接用 RestClient 改动量太大
     * https://blog.csdn.net/taoli1986/article/details/83818188
     * https://segmentfault.com/a/1190000022102940
     */
    @Bean
    public TransportClient getTransportClient() throws UnknownHostException, URISyntaxException {
        log.info("init TransportClient");
        String path = Paths.get(getClass().getClassLoader().getResource(properties.getPckCertificatesPath()).toURI()).toString();
        TransportClient client = new PreBuiltXPackTransportClient(Settings.builder()
                .put("cluster.name", properties.getClusterName())
                // missing authentication credentials for action
                .put("xpack.security.user", String.format("%s:%s", properties.getUser(), properties.getPassword()))
                .put("xpack.security.transport.ssl.enabled", true)
                .put("xpack.security.transport.ssl.verification_mode", "certificate")
                .put("xpack.security.transport.ssl.keystore.path", path)
                .put("xpack.security.transport.ssl.truststore.path", path)
                .build()).addTransportAddress(new TransportAddress(InetAddress.getByName(properties.getHost()), properties.getTcpPort()));
        log.info("=======================");
        log.info("==   init ES   ==");
        log.info("=======================");
        return client;
    }

    @Bean
    public ElasticsearchTemplate elasticsearchTemplate() throws Exception {
        return new ElasticsearchTemplate(getTransportClient());
    }

    /**
     * 重写销毁方法调用关闭连接
     *
     * @author blank
     * @date 2019-10-9 上午 9:29
     */
    @Override
    public void destroy() {
        if (this.releasable != null) {
            try {
                if (log.isInfoEnabled()) {
                    log.info("Closing Elasticsearch client");
                }
                try {
                    this.releasable.close();
                } catch (NoSuchMethodError ex) {
                    // Earlier versions of Elasticsearch had a different method
                    // name
                    ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(Releasable.class, "release"), this.releasable);
                }
            } catch (final Exception ex) {
                if (log.isErrorEnabled()) {
                    log.error("Error closing Elasticsearch client: ", ex);
                }
            }
        }
    }
}

  • 本文作者: blank
  • 本文链接: https://blankhang.com/2020/07/02/docker-compose-elasticsearch
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# consul # atomikos # mybatisplus # druid # nexus # nas # named # bind # mysqldump # acme.sh # Dockerfile # rsync # keepalived # swarm # kibana # ubuntu # linux # scp # bugfix # https # ssl # certbot # curl # gogs # adminer # harbor # yum # portainer # python # kubernetes # idea # java # springboot # maven # docker-compose # redis # nginx # mysql # brew # git # chocolatey # jenkins # elasticsearch # docker # haproxy # rabbitmq # centos
搭建 Maven 私服
提升IDEA开发效率
© 2023 blank
Everything is energy and everything has a frequency