Golang 实战 ELK 日志系统全流程教程三Elasticsearch 和 Kibana 环境搭建目录Golang 实战 ELK 日志系统全流程教程三Elasticsearch 和 Kibana 环境搭建先说版本不要用 latest目录准备写 .env写 docker-compose.yml启动环境验证 Elasticsearch验证 Kibana手动写入一条 Go 应用日志在 Kibana 里创建 Data View先别急着上 Logstash本地常见坑1. Elasticsearch 容器启动后立刻退出2. Kibana 报连不上 Elasticsearch3. Kibana Discover 里看不到日志4. 端口被占用停止和清理这一篇先到这里参考资料前两篇把 Go 侧日志怎么打、日志字段大概怎么设计捋了一遍以后接下来就绕不开 ELK 里最先要跑起来的两个东西Elasticsearch存日志、查日志 Kibana看日志、筛日志、做一点简单分析我一开始搭这个环境时犯过一个挺典型的错误上来就想把 Elasticsearch、Kibana、Logstash、Filebeat 全部塞进一个 compose 文件里。看起来很完整实际一旦启动失败排查会很痛苦。到底是 ES 没起来还是 Kibana 连不上还是 Logstash pipeline 写错还是 Beat 采集路径不对日志一堆问题反而看不清。所以这篇先只做一件事把 Elasticsearch 和 Kibana 稳稳跑起来并且手动写入一条 Go 应用日志确认 Kibana 能查到。先说版本不要用 latestElastic 这套东西最怕“版本随缘”。我写这篇时是2026-05-28Elastic 官方 Docker 文档当前示例已经是9.4.1。但真实项目里我不建议写latest原因很简单今天能跑不代表下周同一份 compose 还能用同样的方式跑。这里统一固定版本Elasticsearch9.4.1 Kibana9.4.1Kibana 和 Elasticsearch 尽量保持同一个大版本、同一个小版本。它们本来就是一套栈里的组件版本错开以后经常不是直接报一个很好懂的错误而是在启动、认证、API 兼容上给你一点小惊喜。这篇是本地开发环境所以我会先关闭安全认证xpack.security.enabledfalse这不是生产建议。生产环境要启用认证、TLS、账号权限、审计等配置。但学习 Go 日志链路时第一阶段先把“日志能写进去、Kibana 能查出来”跑通认知负担会小很多。目录准备我习惯把 ELK 环境单独放一个目录mkdirgo-elk-democdgo-elk-demo目录最后大概长这样go-elk-demo ├── .env └── docker-compose.yml写 .env.env里只放版本号STACK_VERSION9.4.1这样后面升级版本时不用在 compose 文件里到处改。写 docker-compose.yml下面这个 compose 是我本地学习日志系统时比较常用的最小版本services:elasticsearch:image:docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}container_name:go-elk-elasticsearchenvironment:-node.namees01-cluster.namego-elk-demo-discovery.typesingle-node-bootstrap.memory_locktrue-xpack.security.enabledfalse-ES_JAVA_OPTS-Xms1g-Xmx1gulimits:memlock:soft:-1hard:-1ports:-9200:9200-9300:9300volumes:-es-data:/usr/share/elasticsearch/datahealthcheck:test:[CMD-SHELL,curl -fsS http://localhost:9200 /dev/null || exit 1]interval:10stimeout:5sretries:12kibana:image:docker.elastic.co/kibana/kibana:${STACK_VERSION}container_name:go-elk-kibanaenvironment:-SERVER_NAMEkibana-ELASTICSEARCH_HOSTShttp://elasticsearch:9200ports:-5601:5601depends_on:elasticsearch:condition:service_healthyvolumes:es-data:几个配置我单独说一下不然很容易照抄完了不知道为什么这么写。discovery.typesingle-node是告诉 Elasticsearch我现在就是单节点开发环境不要再等别的节点加入集群。ES_JAVA_OPTS-Xms1g -Xmx1g是限制 JVM 堆内存。ES 很吃内存本地机器如果还开着 IDE、浏览器、数据库别一上来就给太大。xpack.security.enabledfalse是为了本地教程先绕过账号密码和证书。等后面日志链路通了再单独补安全配置更清楚。ELASTICSEARCH_HOSTShttp://elasticsearch:9200这里的elasticsearch不是本机域名而是 Docker Compose 内部服务名。Kibana 在容器网络里访问 ES要走服务名不是localhost。这个地方我以前就写错过。Kibana 容器里的localhost指的是 Kibana 自己不是宿主机也不是 Elasticsearch 容器。启动环境执行dockercompose up-d看容器状态dockercomposeps正常情况下会看到两个容器都在运行go-elk-elasticsearch running go-elk-kibana running如果 Kibana 还在启动不要急。Kibana 第一次起来会比较慢尤其是机器内存不太宽裕的时候。可以看日志dockerlogs-fgo-elk-elasticsearchdockerlogs-fgo-elk-kibana验证 Elasticsearch访问curlhttp://localhost:9200Windows PowerShell 里建议写成curl.exe http://localhost:9200因为 PowerShell 里的curl很多时候是Invoke-WebRequest的别名输出格式和 Linux/macOS 下不一样。正常会返回类似这样的 JSON{name:es01,cluster_name:go-elk-demo,version:{number:9.4.1},tagline:You Know, for Search}这一步很关键。不要 Elasticsearch 还没验证就直接去开 Kibana。否则 Kibana 页面打不开时你不知道是 Kibana 自己的问题还是后面的 ES 根本没活。验证 Kibana浏览器打开http://localhost:5601因为我们本地关闭了安全认证所以这里不需要输入elastic用户密码。如果页面一直转圈先看 Kibana 日志dockerlogs-fgo-elk-kibana我比较关注这几类信息Kibana is now available Unable to retrieve version information from Elasticsearch nodes connect ECONNREFUSED第一种说明 Kibana 基本好了。后两种大概率是 Kibana 连不上 Elasticsearch。优先检查ELASTICSEARCH_HOSTS再检查 ES 容器健康状态。手动写入一条 Go 应用日志环境起来以后不要急着接 Go 代码。先手动写一条日志进去。curl-XPOSThttp://localhost:9200/go-app-log-000001/_doc\-HContent-Type: application/json\-d{ timestamp: 2026-05-28T10:30:0008:00, service_name: order-api, env: dev, level: INFO, trace_id: trace-20260528-0001, span_id: span-001, message: create order success, method: POST, path: /api/orders, status: 200, cost_ms: 37, user_id: 10001 }PowerShell 可以这样写少一点转义折磨$body {timestamp2026-05-28T10:30:0008:00service_name order-apienv devlevel INFOtrace_id trace-20260528-0001span_id span-001message create order successmethod POSTpath /api/ordersstatus 200 cost_ms 37 user_id 10001}|ConvertTo-JsonInvoke-RestMethod-Method Post -Urihttp://localhost:9200/go-app-log-000001/_doc-ContentTypeapplication/json-Body$body返回里看到result: created说明写入成功。再查一下curlhttp://localhost:9200/go-app-log-000001/_search?pretty如果能看到刚才那条日志Elasticsearch 这一侧就没问题。在 Kibana 里创建 Data View接下来去 Kibana 看这条日志。打开 Kibana 后进入Stack Management - Data Views - Create data view填Name: go-app-log Index pattern: go-app-log-* Timestamp field: timestamp保存后进入Discover选择go-app-log这个 Data View把时间范围调大一点比如Last 7 days或者手动覆盖到日志时间。这里有个小坑如果你插入的timestamp是一个很早或者很晚的时间而 Kibana 默认只看最近 15 分钟你会以为日志没写进去。我第一次用 Kibana 查日志时就被这个时间范围坑过。ES 里_search明明查得到Kibana 里就是空。后来才发现不是索引问题也不是 Data View 问题就是右上角时间范围太窄。先别急着上 Logstash到这里我们已经完成了一个最小闭环Elasticsearch 已启动 Kibana 已启动 能手动写入日志 能在 Kibana 查到日志这个闭环看起来简单但它很重要。因为后面接 Go 服务、Filebeat、Logstash 时只要日志没出现就可以分段排查Go 程序有没有输出日志文件 Filebeat 有没有采集到 Logstash 有没有收到 Logstash 有没有写入 Elasticsearch Elasticsearch 里有没有索引 Kibana 的 Data View 和时间范围对不对如果一上来就把所有组件混在一起排查路径会变成一锅粥。本地常见坑1. Elasticsearch 容器启动后立刻退出先看日志dockerlogs go-elk-elasticsearchLinux 机器上比较常见的是vm.max_map_count太小。可以临时设置sudosysctl-wvm.max_map_count262144如果是 Docker Desktop通常要看 Docker Desktop 给 Linux VM 分配的资源。ES 内存不够时表现也可能是启动慢、卡住、容器被杀。2. Kibana 报连不上 Elasticsearch重点看这个配置ELASTICSEARCH_HOSTShttp://elasticsearch:9200在 compose 网络里Kibana 访问 ES 用服务名elasticsearch。不要写ELASTICSEARCH_HOSTShttp://localhost:9200除非你非常清楚自己在做什么。容器里的localhost不是宿主机的localhost。3. Kibana Discover 里看不到日志按这个顺序查curlhttp://localhost:9200/_cat/indices?vcurlhttp://localhost:9200/go-app-log-000001/_search?pretty如果 ES 能查到Kibana 看不到优先检查Data View 是否匹配 go-app-log-* 时间字段是不是 timestamp 右上角时间范围是否覆盖日志时间很多时候问题不在写入而在 Kibana 默认时间范围。4. 端口被占用9200和5601都是常见端口。如果启动时报端口占用可以先看本机端口netstat-ano|findstr :9200netstat-ano|findstr :5601或者直接改 compose 里的宿主机端口ports:-19200:9200这样宿主机访问就是http://localhost:19200容器内部还是9200不要把 Kibana 的ELASTICSEARCH_HOSTS也跟着改乱。停止和清理停止dockercompose down如果想把数据卷也删掉重新来一遍dockercompose down-v注意-v会删除 Elasticsearch 里的数据。学习环境无所谓项目环境别手滑。这一篇先到这里这一篇没有接 Go 代码也没有上 Logstash。我更想先把前面弄稳Elasticsearch 能存Kibana 能看索引和时间字段能对上。后面真正接 Go 日志时我们就不用再怀疑底层环境是不是坏的可以把精力放到日志格式、trace_id、采集链路和字段映射上。下一篇就可以开始做 Go 应用日志输出然后考虑到底是Go - 日志文件 - Filebeat - Elasticsearch还是Go - 日志文件 - Filebeat - Logstash - Elasticsearch我个人更倾向先从 Filebeat 直写 ES 开始链路短排错快。等字段清洗、脱敏、复杂路由需求出现再把 Logstash 加进来。参考资料Elastic 官方文档Install Elasticsearch with DockerElastic 官方文档Install Kibana with DockerDocker 官方文档Docker ComposeElasticsearch kibana 8.4.2 搭建单机版 ElasticSearch 和 Kibana 快速搭建Docker安装Elasticsearch9.0.1与Kibana9.0.1 保姆教程基于Docker搭建ElasticSearch和Kibana环境
【Golang 实战 ELK 日志系统全流程教程(三):ElasticSearch和kibanna环境搭建】
Golang 实战 ELK 日志系统全流程教程三Elasticsearch 和 Kibana 环境搭建目录Golang 实战 ELK 日志系统全流程教程三Elasticsearch 和 Kibana 环境搭建先说版本不要用 latest目录准备写 .env写 docker-compose.yml启动环境验证 Elasticsearch验证 Kibana手动写入一条 Go 应用日志在 Kibana 里创建 Data View先别急着上 Logstash本地常见坑1. Elasticsearch 容器启动后立刻退出2. Kibana 报连不上 Elasticsearch3. Kibana Discover 里看不到日志4. 端口被占用停止和清理这一篇先到这里参考资料前两篇把 Go 侧日志怎么打、日志字段大概怎么设计捋了一遍以后接下来就绕不开 ELK 里最先要跑起来的两个东西Elasticsearch存日志、查日志 Kibana看日志、筛日志、做一点简单分析我一开始搭这个环境时犯过一个挺典型的错误上来就想把 Elasticsearch、Kibana、Logstash、Filebeat 全部塞进一个 compose 文件里。看起来很完整实际一旦启动失败排查会很痛苦。到底是 ES 没起来还是 Kibana 连不上还是 Logstash pipeline 写错还是 Beat 采集路径不对日志一堆问题反而看不清。所以这篇先只做一件事把 Elasticsearch 和 Kibana 稳稳跑起来并且手动写入一条 Go 应用日志确认 Kibana 能查到。先说版本不要用 latestElastic 这套东西最怕“版本随缘”。我写这篇时是2026-05-28Elastic 官方 Docker 文档当前示例已经是9.4.1。但真实项目里我不建议写latest原因很简单今天能跑不代表下周同一份 compose 还能用同样的方式跑。这里统一固定版本Elasticsearch9.4.1 Kibana9.4.1Kibana 和 Elasticsearch 尽量保持同一个大版本、同一个小版本。它们本来就是一套栈里的组件版本错开以后经常不是直接报一个很好懂的错误而是在启动、认证、API 兼容上给你一点小惊喜。这篇是本地开发环境所以我会先关闭安全认证xpack.security.enabledfalse这不是生产建议。生产环境要启用认证、TLS、账号权限、审计等配置。但学习 Go 日志链路时第一阶段先把“日志能写进去、Kibana 能查出来”跑通认知负担会小很多。目录准备我习惯把 ELK 环境单独放一个目录mkdirgo-elk-democdgo-elk-demo目录最后大概长这样go-elk-demo ├── .env └── docker-compose.yml写 .env.env里只放版本号STACK_VERSION9.4.1这样后面升级版本时不用在 compose 文件里到处改。写 docker-compose.yml下面这个 compose 是我本地学习日志系统时比较常用的最小版本services:elasticsearch:image:docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}container_name:go-elk-elasticsearchenvironment:-node.namees01-cluster.namego-elk-demo-discovery.typesingle-node-bootstrap.memory_locktrue-xpack.security.enabledfalse-ES_JAVA_OPTS-Xms1g-Xmx1gulimits:memlock:soft:-1hard:-1ports:-9200:9200-9300:9300volumes:-es-data:/usr/share/elasticsearch/datahealthcheck:test:[CMD-SHELL,curl -fsS http://localhost:9200 /dev/null || exit 1]interval:10stimeout:5sretries:12kibana:image:docker.elastic.co/kibana/kibana:${STACK_VERSION}container_name:go-elk-kibanaenvironment:-SERVER_NAMEkibana-ELASTICSEARCH_HOSTShttp://elasticsearch:9200ports:-5601:5601depends_on:elasticsearch:condition:service_healthyvolumes:es-data:几个配置我单独说一下不然很容易照抄完了不知道为什么这么写。discovery.typesingle-node是告诉 Elasticsearch我现在就是单节点开发环境不要再等别的节点加入集群。ES_JAVA_OPTS-Xms1g -Xmx1g是限制 JVM 堆内存。ES 很吃内存本地机器如果还开着 IDE、浏览器、数据库别一上来就给太大。xpack.security.enabledfalse是为了本地教程先绕过账号密码和证书。等后面日志链路通了再单独补安全配置更清楚。ELASTICSEARCH_HOSTShttp://elasticsearch:9200这里的elasticsearch不是本机域名而是 Docker Compose 内部服务名。Kibana 在容器网络里访问 ES要走服务名不是localhost。这个地方我以前就写错过。Kibana 容器里的localhost指的是 Kibana 自己不是宿主机也不是 Elasticsearch 容器。启动环境执行dockercompose up-d看容器状态dockercomposeps正常情况下会看到两个容器都在运行go-elk-elasticsearch running go-elk-kibana running如果 Kibana 还在启动不要急。Kibana 第一次起来会比较慢尤其是机器内存不太宽裕的时候。可以看日志dockerlogs-fgo-elk-elasticsearchdockerlogs-fgo-elk-kibana验证 Elasticsearch访问curlhttp://localhost:9200Windows PowerShell 里建议写成curl.exe http://localhost:9200因为 PowerShell 里的curl很多时候是Invoke-WebRequest的别名输出格式和 Linux/macOS 下不一样。正常会返回类似这样的 JSON{name:es01,cluster_name:go-elk-demo,version:{number:9.4.1},tagline:You Know, for Search}这一步很关键。不要 Elasticsearch 还没验证就直接去开 Kibana。否则 Kibana 页面打不开时你不知道是 Kibana 自己的问题还是后面的 ES 根本没活。验证 Kibana浏览器打开http://localhost:5601因为我们本地关闭了安全认证所以这里不需要输入elastic用户密码。如果页面一直转圈先看 Kibana 日志dockerlogs-fgo-elk-kibana我比较关注这几类信息Kibana is now available Unable to retrieve version information from Elasticsearch nodes connect ECONNREFUSED第一种说明 Kibana 基本好了。后两种大概率是 Kibana 连不上 Elasticsearch。优先检查ELASTICSEARCH_HOSTS再检查 ES 容器健康状态。手动写入一条 Go 应用日志环境起来以后不要急着接 Go 代码。先手动写一条日志进去。curl-XPOSThttp://localhost:9200/go-app-log-000001/_doc\-HContent-Type: application/json\-d{ timestamp: 2026-05-28T10:30:0008:00, service_name: order-api, env: dev, level: INFO, trace_id: trace-20260528-0001, span_id: span-001, message: create order success, method: POST, path: /api/orders, status: 200, cost_ms: 37, user_id: 10001 }PowerShell 可以这样写少一点转义折磨$body {timestamp2026-05-28T10:30:0008:00service_name order-apienv devlevel INFOtrace_id trace-20260528-0001span_id span-001message create order successmethod POSTpath /api/ordersstatus 200 cost_ms 37 user_id 10001}|ConvertTo-JsonInvoke-RestMethod-Method Post -Urihttp://localhost:9200/go-app-log-000001/_doc-ContentTypeapplication/json-Body$body返回里看到result: created说明写入成功。再查一下curlhttp://localhost:9200/go-app-log-000001/_search?pretty如果能看到刚才那条日志Elasticsearch 这一侧就没问题。在 Kibana 里创建 Data View接下来去 Kibana 看这条日志。打开 Kibana 后进入Stack Management - Data Views - Create data view填Name: go-app-log Index pattern: go-app-log-* Timestamp field: timestamp保存后进入Discover选择go-app-log这个 Data View把时间范围调大一点比如Last 7 days或者手动覆盖到日志时间。这里有个小坑如果你插入的timestamp是一个很早或者很晚的时间而 Kibana 默认只看最近 15 分钟你会以为日志没写进去。我第一次用 Kibana 查日志时就被这个时间范围坑过。ES 里_search明明查得到Kibana 里就是空。后来才发现不是索引问题也不是 Data View 问题就是右上角时间范围太窄。先别急着上 Logstash到这里我们已经完成了一个最小闭环Elasticsearch 已启动 Kibana 已启动 能手动写入日志 能在 Kibana 查到日志这个闭环看起来简单但它很重要。因为后面接 Go 服务、Filebeat、Logstash 时只要日志没出现就可以分段排查Go 程序有没有输出日志文件 Filebeat 有没有采集到 Logstash 有没有收到 Logstash 有没有写入 Elasticsearch Elasticsearch 里有没有索引 Kibana 的 Data View 和时间范围对不对如果一上来就把所有组件混在一起排查路径会变成一锅粥。本地常见坑1. Elasticsearch 容器启动后立刻退出先看日志dockerlogs go-elk-elasticsearchLinux 机器上比较常见的是vm.max_map_count太小。可以临时设置sudosysctl-wvm.max_map_count262144如果是 Docker Desktop通常要看 Docker Desktop 给 Linux VM 分配的资源。ES 内存不够时表现也可能是启动慢、卡住、容器被杀。2. Kibana 报连不上 Elasticsearch重点看这个配置ELASTICSEARCH_HOSTShttp://elasticsearch:9200在 compose 网络里Kibana 访问 ES 用服务名elasticsearch。不要写ELASTICSEARCH_HOSTShttp://localhost:9200除非你非常清楚自己在做什么。容器里的localhost不是宿主机的localhost。3. Kibana Discover 里看不到日志按这个顺序查curlhttp://localhost:9200/_cat/indices?vcurlhttp://localhost:9200/go-app-log-000001/_search?pretty如果 ES 能查到Kibana 看不到优先检查Data View 是否匹配 go-app-log-* 时间字段是不是 timestamp 右上角时间范围是否覆盖日志时间很多时候问题不在写入而在 Kibana 默认时间范围。4. 端口被占用9200和5601都是常见端口。如果启动时报端口占用可以先看本机端口netstat-ano|findstr :9200netstat-ano|findstr :5601或者直接改 compose 里的宿主机端口ports:-19200:9200这样宿主机访问就是http://localhost:19200容器内部还是9200不要把 Kibana 的ELASTICSEARCH_HOSTS也跟着改乱。停止和清理停止dockercompose down如果想把数据卷也删掉重新来一遍dockercompose down-v注意-v会删除 Elasticsearch 里的数据。学习环境无所谓项目环境别手滑。这一篇先到这里这一篇没有接 Go 代码也没有上 Logstash。我更想先把前面弄稳Elasticsearch 能存Kibana 能看索引和时间字段能对上。后面真正接 Go 日志时我们就不用再怀疑底层环境是不是坏的可以把精力放到日志格式、trace_id、采集链路和字段映射上。下一篇就可以开始做 Go 应用日志输出然后考虑到底是Go - 日志文件 - Filebeat - Elasticsearch还是Go - 日志文件 - Filebeat - Logstash - Elasticsearch我个人更倾向先从 Filebeat 直写 ES 开始链路短排错快。等字段清洗、脱敏、复杂路由需求出现再把 Logstash 加进来。参考资料Elastic 官方文档Install Elasticsearch with DockerElastic 官方文档Install Kibana with DockerDocker 官方文档Docker ComposeElasticsearch kibana 8.4.2 搭建单机版 ElasticSearch 和 Kibana 快速搭建Docker安装Elasticsearch9.0.1与Kibana9.0.1 保姆教程基于Docker搭建ElasticSearch和Kibana环境