在我之前的文章 “Elastic:用 Docker 部署 Elastic 栈”,我详细讲述了如何在 Docker 中部署 Elasticsearch 以及 Kibana。在今天的文章中,我们来详细介绍一下如何在 Docker 中部署 Logstash。

首先,我们来创建一个目录 docker-logstash。在该目录下,有如下的文件:

$ pwd
/Users/liuxg/data/docker-logstash
$ ls -al
total 16
drwxr-xr-x    5 liuxg  staff   160 May  7 22:13 .
drwxr-xr-x  132 liuxg  staff  4224 May  7 21:58 ..
-rw-r--r--    1 liuxg  staff    29 May  7 21:59 .env
-rw-r--r--    1 liuxg  staff  1039 May  7 22:37 docker-compose.yml
drwxr-xr-x    3 liuxg  staff    96 May  7 22:18 logstash_pipeline
$ tree -L 3
.
├── docker-compose.yml
└── logstash_pipeline
    └── ports.conf

如上所示,在该目录中,它有一个 .env 文件。它里面定义了一个在 docker-compose.yml 需要用到的环境变量:

$ cat .env
ELASTIC_STACK_VERSION=7.12.1

我们可以通过使用 ELASTIC_STACK_VERSION 来定义我们想要的 Elastic Stack 的版本。在上面,我们使用最新的发布版 7.12.1。

接下来我们创建一个叫做 docker-compose.yml 的文件:

docker-compose.yml

version: '3.7'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_STACK_VERSION}
    container_name: es01
    environment:
      - discovery.type=single-node
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata01:/usr/share/elasticsearch/data        
    ports:
      - 9200:9200
    networks:
      - elastic
 
  kibana:
    image: docker.elastic.co/kibana/kibana:${ELASTIC_STACK_VERSION}
    container_name: kibana
    ports: ['5601:5601']    
    networks: ['elastic']
    environment:
      - SERVER_NAME=kibana.localhost
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - I18N_LOCALE=zh-CN
    depends_on: ['elasticsearch']

  logstash:
    image: logstash:${ELASTIC_STACK_VERSION}
    ports:
      - 5000:5000
    volumes: 
      - type: bind
        source: ./logstash_pipeline/
        target: /usr/share/logstash/pipeline
        read_only: true
    networks:
      - elastic        
 
volumes:
  esdata01:
    driver: local
 
networks:
  elastic:
    driver: bridge

如上所示,它使用 Docker 来安装 Elasticsearch,Kibana 以及 Logstash。为了说明问题的方便,我们使用一个节点来安装 Elasticsearch。

针对 Logstash 的安装,我们定义了一个 port 5000,这样我们在 Logstash 的配置文件中可以使用 TCP 的口地址 5000 把数据传入到 Logstash 的 pipeline 中,并进行处理。同时,我们使用 volumes 的定义,把本地目录 logstash_pipeline 中的文件 bind 到 Logstash 的 /usr/share/logstash/pipeline 目录中,从而使得在 logstash_pipeline 中所定义的 pipeline 能够在 Logstash 启动后自动运行起来。

我们接下来看看在 logstash_pipeline 目录中定义的 ports.conf 文件:

ports.conf

input {
    tcp {
        port => 5000
    }
}

output {
    elasticsearch {
        hosts => ["elasticsearch:9200"]
        index => "hello-logstash-docker"
    }
}

这个配置文件非常简单。它接受来自 port 5000 的数据,并直接发到 Elasticsearch 中去。为了方便说明问题,我这里没有使用任何的 filter。

现在所有的一切都准备好了。我们安装好 Docker,并在 docker-compose.yml 所在的目录打入如下的命令:

docker-compose up

docker plumelog部署 docker部署logstash_docker plumelog部署

如果你之前没有下载过所需 Elastic Stack 的版本的话,那么它会自动帮我们下载所需要的镜像。当所有的 docker 运行起来后,我们可以看到:

docker plumelog部署 docker部署logstash_大数据_02

Logstash 已经正常运行起来了。

我们可以到 Kibana 中查看当前的所有索引:

GET _cat/indices
green open .kibana_7.12.1_001              G4sOvCHwSqG0mgI5bHb3Yg 1 0 15   6   2.1mb   2.1mb
green open .apm-custom-link                fZ14FvQSQoGdgDRaiBL_Cw 1 0  0   0    208b    208b
green open .apm-agent-configuration        rjldKIhSTYqhoknTMUmO2w 1 0  0   0    208b    208b
green open .kibana_task_manager_7.12.1_001 BGSG-dSfSmOLyLk7FK9IGQ 1 0  9 383 237.4kb 237.4kb
green open .kibana-event-log-7.12.1-000001 5dUT5TJPSpOLBV60R9q8nA 1 0 15   0  34.5kb  34.5kb
green open .tasks                          BBEUxgA2QxCsD9LWeklppg 1 0 11   2  68.4kb  68.4kb

从上面的输出中,我们看不到 hello-logstash-docker 索引。

我们在另外一个 terminal 中打入如下的命令:

telnet localhost 5000

然后,我们随便打入一些字符串:

docker plumelog部署 docker部署logstash_elasticsearch_03

我们再次回到 Kibana 中,并查看所有的索引:

GET _cat/indices
green  open .kibana_7.12.1_001              G4sOvCHwSqG0mgI5bHb3Yg 1 0 24   2   4.2mb   4.2mb
green  open .apm-custom-link                fZ14FvQSQoGdgDRaiBL_Cw 1 0  0   0    208b    208b
green  open .apm-agent-configuration        rjldKIhSTYqhoknTMUmO2w 1 0  0   0    208b    208b
green  open .kibana_task_manager_7.12.1_001 BGSG-dSfSmOLyLk7FK9IGQ 1 0  9 458 233.1kb 233.1kb
yellow open hello-logstash-docker           ENOQrJYZSM2JlhtV4yvJLg 1 1  3   0  16.3kb  16.3kb
green  open .kibana-event-log-7.12.1-000001 5dUT5TJPSpOLBV60R9q8nA 1 0 15   0  34.5kb  34.5kb
green  open .tasks                          BBEUxgA2QxCsD9LWeklppg 1 0 11   2  68.4kb  68.4kb

上面显示一个新的索引 hello-logstash-docker 已经生成。我们可以使用如下的命令来查看它里面的内容:

GET hello-logstash-docker/_search

上面的命令将返回:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "hello-logstash-docker",
        "_type" : "_doc",
        "_id" : "CSCvSXkBnY-NEmvD2mLa",
        "_score" : 1.0,
        "_source" : {
          "port" : 59430,
          "@timestamp" : "2021-05-08T01:55:31.938Z",
          "message" : """Hello, liuxg!
""",
          "@version" : "1",
          "host" : "gateway"
        }
      },
      {
        "_index" : "hello-logstash-docker",
        "_type" : "_doc",
        "_id" : "CCCvSXkBnY-NEmvD2mLZ",
        "_score" : 1.0,
        "_source" : {
          "port" : 59430,
          "@timestamp" : "2021-05-08T01:55:31.952Z",
          "message" : """This is so cool and nice
""",
          "@version" : "1",
          "host" : "gateway"
        }
      },
      {
        "_index" : "hello-logstash-docker",
        "_type" : "_doc",
        "_id" : "CiCvSXkBnY-NEmvD_GJP",
        "_score" : 1.0,
        "_source" : {
          "port" : 59430,
          "@timestamp" : "2021-05-08T01:55:40.644Z",
          "message" : """I love to see Logstash working
""",
          "@version" : "1",
          "host" : "gateway"
        }
      }
    ]
  }
}

我们可以看到刚才输入的内容已经被成功地导入到 Elasticsearch 中了。