Elasticsearch:如何在 Docker 容器中安装 Elastic Stack

Posted Elastic 中国社区官方博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch:如何在 Docker 容器中安装 Elastic Stack相关的知识,希望对你有一定的参考价值。

在之前的文章 “Elastic:用 Docker 部署 Elastic Stack” 中,我详述了如何使用 Docker 部署 Elastic Stack。我也在之前的文章 “Elastic:如何在 AWS 上一步一步地安装 Elastic Stack” 讲述了如何在 Ubuntu OS 中安装 Elastic Stack。在今天的文章中,我想在 Ubuntu OS 系统的机器上一步一步地安装 Docker,并进而把 Elastic Stack 运行于 Docker 容器中。对于还没有 Ubuntu OS 的开发者来说,我将使用 Vagrant 来安装 Ubuntu OS。

如果你从来还没有安装过 Vagrant,请参照我之前的教程 “Vagrant 入门教程” 来进行学习。

创建 Ubuntu OS

我们使用 Vagrant 来创建 Ubuntu。我们首先在自己的电脑上创建一个目录,并在该目录中创建一个如下的 Vagrantfile:

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

ENV['VAGRANT_NO_PARALLEL'] = 'yes'

Vagrant.configure(2) do |config|

  config.vm.provision "shell", path: "bootstrap.sh"

  NodeCount = 1

  (1..NodeCount).each do |i|

    config.vm.define "ubuntuvm#i" do |node|

      node.vm.box               = "generic/ubuntu2004"
      node.vm.box_check_update  = false
      node.vm.box_version       = "3.3.0"
      node.vm.hostname          = "ubuntuvm#i.example.com"

      node.vm.network "private_network", ip: "172.16.16.10#i"

      node.vm.provider :virtualbox do |v|
        v.name    = "ubuntuvm#i"
        v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]    
        v.memory  = 2048
        v.cpus    = 1
      end

      node.vm.provider :libvirt do |v|
        v.nested  = true
        v.memory  = 1024
        v.cpus    = 1
      end

    end

  end

end

在上面,我们可以通过设置 NodeCount 来控制 Ubuntu OS 的数量。为了叙述的方便,在我们的练习中,我们设置它的值为 1,也就是只创建一个 Ubuntu OS 的实例。同时它的 IP 地址是按照 Ubuntu OS 实例的顺序来分配的,比如 172.16.16.101,172.16.16.102。我们使用 Ubuntu 20.04 的版本来进行练习。

我们也同时创建如下的 boostrap.sh 文件:

bootstrap.sh

#!/bin/bash

# Enable ssh password authentication
echo "Enable ssh password authentication"
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl reload sshd

# Set Root password
echo "Set root password"
echo -e "admin\\nadmin" | passwd root >/dev/null 2>&1

这样在我们的目录中含有如下的两个文件:

$ pwd
/Users/liuxg/data/focal
$ ls
Vagrantfile  bootstrap.sh

接下来,我们使用如下的命令来创建 Ubuntu OS:

从上面的输出中,我们可以看出来我们 Ubuntu OS 已经被成功地安装了。我们也可以从 virtualbox 应用的界面查看 Ubuntu OS 的运行:

在上面显示 ubuntuvm1 已经成功地运行。我们可以使用如下的命令来登录 Ubuntu OS:

$ pwd
/Users/liuxg/data/focal
$ ls
Vagrantfile  bootstrap.sh
$ vagrant ssh
vagrant@ubuntuvm1:~$ 

从上面,我们可以看出来,我们已经成功地使用 vagrant ssh 来登录 Ubuntu OS。我们也可以通过如下的方式来使用 root 权限来进行登录。首先在自己的 host 机器的 /etc/hosts 里添加如下的行:

172.16.16.101   ubuntuvm1.example.com ubuntuvm1

然后,我们可以通过如下的方式来 ping Ubuntu OS:

$ ping 172.16.16.101
PING 172.16.16.101 (172.16.16.101): 56 data bytes
64 bytes from 172.16.16.101: icmp_seq=0 ttl=64 time=0.654 ms
64 bytes from 172.16.16.101: icmp_seq=1 ttl=64 time=0.431 ms
$ ping ubuntuvm1
PING ubuntuvm1.example.com (172.16.16.101): 56 data bytes
64 bytes from 172.16.16.101: icmp_seq=0 ttl=64 time=0.464 ms
64 bytes from 172.16.16.101: icmp_seq=1 ttl=64 time=0.390 ms

 我们可以使用如下的命名对 root 用户进行登录:

ssh root@ubuntuvm1
$ ssh root@ubuntuvm1
The authenticity of host 'ubuntuvm1 (172.16.16.101)' can't be established.
ECDSA key fingerprint is SHA256:uqdoaDcn8pHMvpwtc0yr8k8JHBNNDr+K6/5oab4b5JU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ubuntuvm1,172.16.16.101' (ECDSA) to the list of known hosts.
root@ubuntuvm1's password: 
root@ubuntuvm1:~# 

记得在上面使用 admin 作为密码。这个在 bootstrap.sh 中已经定义了。

这样我们的 Ubunut OS 已经安装好了。我们可以打入如下的命令对 Ubuntu OS 进行 update:

root@ubuntuvm1:~# apt update
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]      
Hit:2 http://us.archive.ubuntu.com/ubuntu focal InRelease                      
Get:3 http://us.archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:4 http://us.archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]   
Fetched 336 kB in 9s (35.8 kB/s)                                               
Reading package lists... Done
Building dependency tree       
Reading state information... Done
112 packages can be upgraded. Run 'apt list --upgradable' to see them.

我们可以使用如下的命令来对 Ubuntu OS 进行更新:

root@ubuntuvm1:~# apt upgrade

等我们完成上面的命令后。我们的 Ubuntu OS 就基本已经安装完毕了。我们可以通过如下的命令来检查 Ubuntu OS 的版本:

root@ubuntuvm1:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.3 LTS
Release:	20.04
Codename:	focal

安装 Docker

我们可以使用如下的命令来安装 docker:

apt install docker.io

一旦 docker 安装完毕,它会自动启动 docker 服务:

 我们不需要做任何的启动。

如果我们是以如下的方式来登录 Ubuntu OS的话:

vagrant ssh

那么当我们执行如下的命令时:

vagrant@ubuntuvm1:~$ docker info
Client:
 Context:    default
 Debug Mode: false

Server:
ERROR: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info: dial unix /var/run/docker.sock: connect: permission denied
errors pretty printing info
vagrant@ubuntuvm1:~$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: dial unix /var/run/docker.sock: connect: permission denied

我们会发现,我们不能执行上面的任何 docker 命令。我们可以把 vagrant 这个用户添加到 docker 里:

sudo gpasswd -a vagrant docker
vagrant@ubuntuvm1:~$ sudo gpasswd -a vagrant docker
Adding user vagrant to group docker

我们再次执行上面的命令:

我们需要 logout,然后再重新使用:

vagrant ssh

再次使用 docker info,我们可以看到该命令是成功的。

安装 Elasticsearch 及 Kibana

我们可以参考官方文档 Install Elasticsearch with Docker。我们创建如下的 docker-compose.yml 文件。和官方文档不同的是,在这里,我们只创建一个 Elasticsearch 节点。

docker-compose.yml

version: '2.2'

services:

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.2
    container_name: elasticsearch
    environment:
      - node.name=elasticsearch
      - discovery.seed_hosts=elasticsearch
      - cluster.initial_master_nodes=elasticsearch
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200

  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.2
    container_name: kibana
    environment:
      ELASTICSEARCH_URL: "http://elasticsearch:9200"
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch

volumes:
  esdata1:
    driver: local

 在上面,我们使用最新的 Elasticsearch 7.15.2 版本。

vagrant@ubuntuvm1:~$ pwd
/home/vagrant
vagrant@ubuntuvm1:~$ vi docker-compose.yml
vagrant@ubuntuvm1:~$ ls
docker-compose.yml

我们的文件结构如上。

按照官方文档中的要求:Install Elasticsearch with Docker | Elasticsearch Guide [7.15] | Elastic,在生产环境中,我们需要做一些额外的配置:

设置 vm.max_map_count

我们修改文件 /etc/sysctl.conf 文件。在该文件的最后面,添加如下的行:

vm.max_map_count=262144

 并保存该文件。我们可以使用如下的命令来进行验证:

vagrant@ubuntuvm1:~$ grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144

我们使用如下的命令让它立即起作用:

sysctl -w vm.max_map_count=262144
vagrant@ubuntuvm1:~$ grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144
vagrant@ubuntuvm1:~$ sudo sysctl -w vm.max_map_count=262144
vm.max_map_count = 262144

我们使用如下的命令来检查设置是否已经起作用了:

vagrant@ubuntuvm1:~$ grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144
vagrant@ubuntuvm1:~$ sudo sysctl -w vm.max_map_count=262144
vm.max_map_count = 262144
vagrant@ubuntuvm1:~$ sudo sysctl -a | grep max_map_count
vm.max_map_count = 262144

到目前为止,我们已经对系统配置好了。

我们使用如下的命令来安装 docker-compose:

sudo apt install docker-compose

等 docker-compose 安装完毕后,我们使用如下的命令来安装 Elasticsearch 及 Kibana:

docker-compose up

从上面我们可以看出来,它会自动下载 Elasticsearch 及 Kibana 的镜像并安装。整个安装过程依赖于你的网络情况。它可能需要一点时间来完成整个操作:

从上面的输出中,我们可以看到 Kibana 已经完全运行起来了。我们保持当前的 terminal 在运行状态。

我们可以在另外一个 terminal 中通过如下的命令进入到 Ubuntu OS 中:

vagrant ssh

 我们然后使用如下的命令来查看:

从上面,我们可以看出来有两个容器在运行。它们分别运行 Elasticsearch 及 Kibana。

我们使用如下的命令来检查端口的使用情况。我们使用如下的命令来安装 netstat 命令:

sudo apt install net-tools
vagrant@ubuntuvm1:~$ sudo netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:9200            0.0.0.0:*               LISTEN      97374/docker-proxy  
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      53424/systemd-resol 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      52982/sshd: /usr/sb 
tcp        0      0 127.0.0.1:33051         0.0.0.0:*               LISTEN      94143/containerd    
tcp        0      0 0.0.0.0:5601            0.0.0.0:*               LISTEN      97527/docker-proxy  
tcp6       0      0 :::22                   :::*                    LISTEN      52982/sshd: /usr/sb 

从上面,我们可以看出来,有两个端口 9200 及 5601 被使用。它们绑定的地址是 0.0.0.0,意味着它绑定了 Ubuntu 所有的网路接口。我们可以通过如下的命令来查看所有的网路接口:

vagrant@ubuntuvm1:~$ ifconfig
br-10bd90984cfb: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:58:7a:8e:e3  txqueuelen 0  (Ethernet)
        RX packets 1951  bytes 83243 (83.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2983  bytes 43501685 (43.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ab:fb:b6:68  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::a00:27ff:fe7d:76d0  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:7d:76:d0  txqueuelen 1000  (Ethernet)
        RX packets 1047316  bytes 1534393261 (1.5 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 78470  bytes 5301813 (5.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.16.101  netmask 255.255.255.0  broadcast 172.16.16.255
        inet6 fe80::a00:27ff:fedd:5dde  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:dd:5d:de  txqueuelen 1000  (Ethernet)
        RX packets 4280  bytes 301351 (301.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4037  bytes 583373 (583.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 312  bytes 31646 (31.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 312  bytes 31646 (31.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth91cc229: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 76:96:4d:93:51:80  txqueuelen 0  (Ethernet)
        RX packets 24359  bytes 2829772 (2.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 26151  bytes 51157033 (51.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth990f57a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether a2:bb:cb:8f:cb:48  txqueuelen 0  (Ethernet)
        RX packets 23216  bytes 7658484 (7.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22459  bytes 2722477 (2.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

从上面的接口输出,我们可以看出来,它绑定了 127.0.0.1,也即 localhost,同时它也绑定了自己的 private IP 172.16.16.101。我们可以在 Ubuntu 的 terminal 中打入如下的命令:

vagrant@ubuntuvm1:~$ curl localhost:9200

  "name" : "elasticsearch",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "UNv1mTw1T-qM8tXBUp8sQw",
  "version" : 
    "number" : "7.15.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "93d5a7f6192e8a1a12e154a2b81bf6fa7309da0c",
    "build_date" : "2021-11-04T14:04:42.515624022Z",
    "build_snapshot" : false,
    "lucene_version" : "8.9.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  ,
  "tagline" : "You Know, for Search"

也即,它可以在 localhost 被访问。当让我们也可以在浏览器中输入如下的地址 http://172.16.16.101:9200/

显然,它也绑定了自己的私有地址,可以被外界的浏览器所访问。

我们在浏览器中打入地址  http://172.16.16.101:5601/

从上面的画面我们可以看出来,Kibana 已经成功地运行起来了。

如果你对数据分析感兴趣,你可以导入 Kibana 中自带的 sample 数据集来作为一个起点来对数据进行分析:

在三个数据集是 Kibana 自带的数据。我们可以针对这些数据进行各种分析。

可能有开发者想,如果我们退出 docker 的话,那么我们的数据是否还会保存呢?

我们使用如下的命令:

vagrant@ubuntuvm1:~$ docker volume ls
DRIVER    VOLUME NAME
local     vagrant_esdata1

上面显示我们的数据是一个 local 的叫做 vagrant_esdata1 的卷。它实际上是在我们的 docker-compose.yml 里定义的:

volumes:
  esdata1:
    driver: local

 它的位置处于如下的地方:

vagrant@ubuntuvm1:~$ sudo ls /var/lib/docker/volumes
backingFsBlockDev  metadata.db	vagrant_esdata1

你可以在运行 docker-compose 的 terminal 中使用 Ctrl + C 组合键来终止 docker-compose 的运行。我们可以使用如下的命令来查看 container 的运行:

我们可以看到没有任何运行的 container。我们可以使用如下的命令来重新启动 Elasticsearch 及 Kibana:

docker-compose start

  

好了,今天的教程就写到这里。希望大家和我一样能够顺利地完成 Elasticsearch 及 Kibana 的安装。 

以上是关于Elasticsearch:如何在 Docker 容器中安装 Elastic Stack的主要内容,如果未能解决你的问题,请参考以下文章

如何在docker中部署Elasticsearch集群和kibana

Elasticsearch:保护你的 Elasticsearch 实例 - 如何使用带有内置证书的 Docker 镜像

Elasticsearch:保护你的 Elasticsearch 实例 - 如何使用带有内置证书的 Docker 镜像

如何在docker下安装elasticsearch(上)

Elasticsearch:如何在 Docker 容器中安装 Elastic Stack

Elasticsearch:如何在 Docker 容器中安装 Elastic Stack