ARM环境ELK Docker集群部署详细步骤

基于ARM架构的ELK部署需要特别注意镜像版本兼容性和架构适配。以下是针对ARM64环境的完整部署方案。

一、环境信息

  • 架构: ARM64 (aarch64)

  • 节点1 (主节点): 192.168.157.35 - 部署ES主节点 + Kibana + Logstash

  • 节点2 (数据节点): 192.168.157.36 - 部署ES数据节点

  • 节点3 (数据节点): 192.168.157.37 - 部署ES数据节点

  • 推荐版本: 7.14.0及以上(官方从该版本开始支持ARM64)

    二、准备工作(所有节点执行)

    1. 安装Docker

    # CentOS ARM64
    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    sudo yum install -y docker-ce docker-ce-cli containerd.io
    sudo systemctl start docker
    sudo systemctl enable docker
    
    # Ubuntu ARM64
    sudo apt update
    sudo apt install -y docker.io
    sudo systemctl start docker
    sudo systemctl enable docker
    
    # 验证ARM架构
    docker info | grep Architecture  # 应显示aarch64

    2. 创建必要目录

    mkdir -p /data/{es-node1,es-node2,es-node3,logstash/{config,pipeline},script}
    chmod g+rwx /data/es-node*
    chgrp 0 /data/es-node*

    3. 配置内核参数

    # 编辑/etc/sysctl.conf
    echo "vm.max_map_count=262144" >> /etc/sysctl.conf
    sysctl -p

    4. 设置主机名(用于节点识别)

    # 在192.168.157.35执行
    hostnamectl set-hostname elk-node1
    
    # 在192.168.157.36执行
    hostnamectl set-hostname elk-node2
    
    # 在192.168.157.37执行
    hostnamectl set-hostname elk-node3

    三、Docker Swarm集群初始化

    1. 在主节点(192.168.157.35)初始化Swarm

    docker swarm init --advertise-addr 192.168.157.35
    # 记录生成的worker token

    2. 在其他节点加入集群

    # 在192.168.157.36和192.168.157.37上执行
    docker swarm join --token <SWARM_TOKEN> 192.168.157.35:2377

    3. 创建overlay网络

    docker network create --driver overlay --attachable elk-network

    四、配置文件准备(主节点)

    1. 创建环境变量文件 /data/script/.env

    cat > /data/script/.env << EOF
    # Elasticsearch密码
    ELASTIC_PASSWORD=elk#bd@123
    # Kibana密码
    KIBANA_PASSWORD=elk#bd@123
    # Elastic Stack版本(ARM64必须≥7.14.0)
    STACK_VERSION=8.13.3
    # 集群名称
    CLUSTER_NAME=arm-elk-cluster
    # 许可证类型
    LICENSE=basic
    # ES端口
    ES_PORT=9200
    # Kibana端口
    KIBANA_PORT=5601
    # 内存限制(ARM环境建议适当降低)
    MEM_LIMIT=1717986918  # 1.6GB
    # JVM堆大小(ARM架构优化)
    ES_JAVA_OPTS=-Xms800m -Xmx800m
    # 项目名
    COMPOSE_PROJECT_NAME=arm-elk-cluster
    EOF

    2. 创建Logstash配置

    # 创建Logstash管道配置
    cat > /data/logstash/pipeline/logstash.conf << EOF
    input {
      beats {
        port => 5044
      }
      tcp {
        port => 5000
        codec => json
      }
    }
    
    output {
      elasticsearch {
        hosts => ["https://es-node1:9200"]
        index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
        user => "elastic"
        password => "elk#bd@123"
        cacert => "/usr/share/logstash/config/certs/ca/ca.crt"
        ssl_certificate_verification => true
      }
    }
    EOF

    3. 创建主docker-compose文件 /data/script/elk-arm.yml

    version: '3.8'
    
    services:
      es-setup:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - /data/script:/usr/share/elasticsearch/config/setup
        command: >
          bash -c '
            echo "Waiting for Elasticsearch availability";
            until curl -s --cacert /usr/share/elasticsearch/config/certs/ca/ca.crt https://es-node1:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
            echo "Setting kibana_system password";
            until curl -s -X POST --cacert /usr/share/elasticsearch/config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es-node1:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
            echo "All done!";
          '
        networks:
          - elk-network
        depends_on:
          - es-node1
    
      es-node1:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - /data/es-node1:/usr/share/elasticsearch/data
          - /data/script/certs:/usr/share/elasticsearch/config/certs
        ports:
          - "9200:9200"
        environment:
          - node.name=es-node1
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es-node1,es-node2,es-node3
          - discovery.seed_hosts=es-node1,es-node2,es-node3
          - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es-node1/es-node1.key
          - xpack.security.http.ssl.certificate=certs/es-node1/es-node1.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es-node1/es-node1.key
          - xpack.security.transport.ssl.certificate=certs/es-node1/es-node1.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.license.self_generated.type=${LICENSE}
          - "ES_JAVA_OPTS=-Xms800m -Xmx800m"
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        networks:
          - elk-network
        deploy:
          placement:
            constraints:
              - node.hostname == elk-node1
    
      es-node2:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - /data/es-node2:/usr/share/elasticsearch/data
          - /data/script/certs:/usr/share/elasticsearch/config/certs
        environment:
          - node.name=es-node2
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es-node1,es-node2,es-node3
          - discovery.seed_hosts=es-node1,es-node2,es-node3
          - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es-node2/es-node2.key
          - xpack.security.http.ssl.certificate=certs/es-node2/es-node2.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es-node2/es-node2.key
          - xpack.security.transport.ssl.certificate=certs/es-node2/es-node2.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.license.self_generated.type=${LICENSE}
          - "ES_JAVA_OPTS=-Xms800m -Xmx800m"
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        networks:
          - elk-network
        deploy:
          placement:
            constraints:
              - node.hostname == elk-node2
    
      es-node3:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - /data/es-node3:/usr/share/elasticsearch/data
          - /data/script/certs:/usr/share/elasticsearch/config/certs
        environment:
          - node.name=es-node3
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es-node1,es-node2,es-node3
          - discovery.seed_hosts=es-node1,es-node2,es-node3
          - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es-node3/es-node3.key
          - xpack.security.http.ssl.certificate=certs/es-node3/es-node3.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es-node3/es-node3.key
          - xpack.security.transport.ssl.certificate=certs/es-node3/es-node3.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.license.self_generated.type=${LICENSE}
          - "ES_JAVA_OPTS=-Xms800m -Xmx800m"
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        networks:
          - elk-network
        deploy:
          placement:
            constraints:
              - node.hostname == elk-node3
    
      kibana:
        image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
        ports:
          - "5601:5601"
        environment:
          - SERVERNAME=kibana
          - ELASTICSEARCH_HOSTS=https://es-node1:9200
          - ELASTICSEARCH_USERNAME=kibana_system
          - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
          - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/usr/share/kibana/config/certs/ca/ca.crt
          - I18N_LOCALE=zh-CN
          # ARM架构优化
          - NODE_OPTIONS=--max-old-space-size=512
        volumes:
          - /data/script/certs:/usr/share/kibana/config/certs
        networks:
          - elk-network
        depends_on:
          - es-node1
        deploy:
          placement:
            constraints:
              - node.hostname == elk-node1
    
      logstash:
        image: docker.elastic.co/logstash/logstash:${STACK_VERSION}
        ports:
          - "5044:5044"
          - "5000:5000"
        volumes:
          - /data/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
          - /data/logstash/pipeline/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
          - /data/script/certs:/usr/share/logstash/config/certs
        environment:
          - LS_JAVA_OPTS=-Xms512m -Xmx512m
          - pipeline.batch.size=500
          - pipeline.workers=2
        networks:
          - elk-network
        depends_on:
          - es-node1
        deploy:
          placement:
            constraints:
              - node.hostname == elk-node1
    
    networks:
      elk-network:
        external: true

    五、生成TLS证书(主节点)

    # 进入证书目录
    cd /data/script
    
    # 创建证书生成脚本
    cat > create-certs.yml << EOF
    version: '2.2'
    
    services:
      create_certs:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        command: >
          bash -c '
            if [[ ! -f /certs/ca/ca.crt ]]; then
              bin/elasticsearch-certutil ca --silent --pem -out /certs/ca.zip;
              unzip /certs/ca.zip -d /certs;
            fi;
            for instance in es-node1 es-node2 es-node3; do
              if [[ ! -f /certs/\$instance/\$instance.crt ]]; then
                bin/elasticsearch-certutil cert --silent --pem -out /certs/\$instance.zip --in /usr/share/elasticsearch/config/instances.yml;
                unzip /certs/\$instance.zip -d /certs/\$instance;
              fi;
            done;
            chown -R 1000:0 /certs
          '
        volumes:
          - .:/usr/share/elasticsearch/config
          - ./certs:/certs
    EOF
    
    # 创建实例配置
    cat > instances.yml << EOF
    instances:
      - name: es-node1
        dns: [es-node1]
        ip: [192.168.157.35]
      - name: es-node2
        dns: [es-node2]
        ip: [192.168.157.36]
      - name: es-node3
        dns: [es-node3]
        ip: [192.168.157.37]
    EOF
    
    # 生成证书
    docker-compose -f create-certs.yml up

    六、验证ARM镜像兼容性

    # 在主节点验证镜像架构
    docker pull docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    docker inspect docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} | grep Architecture
    # 应输出:"Architecture": "arm64"
    
    # 验证其他组件
    docker pull docker.elastic.co/kibana/kibana:${STACK_VERSION}
    docker pull docker.elastic.co/logstash/logstash:${STACK_VERSION}

    七、部署ELK集群

    # 在主节点(192.168.157.35)执行
    cd /data/script
    docker stack deploy -c elk-arm.yml elk-arm
    
    # 查看部署状态
    docker stack ps elk-arm
    docker service ls

    八、验证部署

    # 等待2-3分钟,让集群完成初始化
    
    # 查看集群健康状态
    curl -k -u elastic:elk#bd@123 https://192.168.157.35:9200/_cluster/health?pretty
    
    # 查看节点信息
    curl -k -u elastic:elk#bd@123 https://192.168.157.35:9200/_cat/nodes?v
    
    # 查看服务日志
    docker service logs -f elk-arm_es-node1
    docker service logs -f elk-arm_kibana

    九、访问Kibana

    1. 浏览器访问: http://192.168.157.35:5601

    2. 用户名: elastic

    3. 密码: elk#bd@123

    4. 语言: 已设置为中文

      十、ARM环境特有注意事项        

      1. 版本选择要点

      • 必须使用7.14.0及以上版本,早期版本不支持ARM64

      • 官方镜像采用manifest合并技术,自动匹配ARM64架构

      • 避免使用latest标签,明确指定版本号

        2. 性能调优建议

        ARM架构JVM参数优化(已在配置中体现) 1. 堆内存设置为物理内存的40-50% 2. 禁用JVM的UseAVX选项(ARM不支持) 3. 调整GC策略为G1GC

        3. 资源限制调整

        • ARM服务器的内存和CPU特性可能与x86不同

        • 建议从较低资源限制开始,逐步调整

        • 监控容器资源使用情况:docker stats

          4. 依赖库兼容性

          • Kibana依赖Node.js,确保使用ARM64版本的Node.js

          • Logstash的JRuby组件在ARM上可能需要额外配置

          • 如遇插件问题,考虑使用替代插件或手动编译

            5. 网络性能

            • ARM平台的网络性能可能较低,建议:

              • 使用overlay网络模式

              • 适当增加超时时间

              • 监控网络吞吐量

              6. 存储性能

              • ARM设备的存储I/O性能可能差异较大

              • 建议使用SSD存储ES数据

              • 调整Elasticsearch的index.translog.sync_interval参数

                十一、推送日志验证

                # 在需要收集日志的服务器上安装Filebeat(ARM版本)
                # 下载ARM64版本的Filebeat
                wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${STACK_VERSION}-linux-arm64.tar.gz
                
                # 配置filebeat.yml
                output.logstash:
                  hosts: ["192.168.157.35:5044"]
                  ssl.certificate_authorities: ["/path/to/ca.crt"]
                
                # 启动Filebeat
                ./filebeat -e -c filebeat.yml

                十二、故障排查

                1. 镜像拉取失败

                # 检查Docker架构支持
                docker version --format 'Server: {{.Server.Arch}}'
                # 如果不是arm64,需要安装ARM版本的Docker
                
                # 手动指定平台拉取
                docker pull --platform linux/arm64 docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}

                2. 容器启动失败

                # 查看详细错误
                docker service logs elk-arm_es-node1
                
                # 常见ARM相关问题:
                # - 内存不足:调整MEM_LIMIT和ES_JAVA_OPTS
                # - 权限问题:检查/data目录权限
                # - 证书问题:确保证书已正确生成

                3. 性能问题

                # 监控CPU使用率
                top
                
                # 监控内存
                free -h
                
                # 监控容器资源
                docker stats

                Logo

                电影级数字人,免显卡端渲染SDK,十行代码即可调用,工业级demo免费开源下载!

                更多推荐