引子

在上一篇文章Elasticsearch入门(三):Elasticsearch 7.0.0 集群搭建中,我讲了如何在CentOS 7.6环境下搭建 Elasticsearch 7.0.0 集群。本文呢,我将继续讲一讲,如何使用docker搭建集群。在本文中,docker相关的知识我不详细讲解,有疑问的同学请自行百度或留言给我。此外,如果是ES安装、运行,或者Node.js的安装、head插件安装过程中,前面几篇文章中已经出现过的问题,这里我也直接略过了。

需要注意的是,在实际生产环境中,一般是一个容器作为一个ES节点,而不是像我这里这样,一个容器一个集群。这里我主要是为了方便,搭集群主要是为了自己学习,所以才这样搭的。

安装环境

宿主机OS:MacOS        docker版本:18.09.2       linux镜像TAG:latest        Elasticsearch版本:7.0.0      Node.js版本:10.15.3

搭建步骤

1、docker环境、CentOS镜像准备

首先,我们将docker安装好,推荐配置镜像为阿里云镜像,具体方法请自行百度。将docker运行起来。

然后,我们将centos:latest 拉取到本地,执行下面的命令。我们不指定TAG时,默认的TAG就是 latest。

docker pull centos

拉取完毕后,我们执行 docker images,可以查看本地拉取完毕的镜像:

我们可以看到,centos:latest 我们已经拉取到本地了,并且也知道了该镜像的 IMAGE ID。

2、Dockerfile文件的编写

具体的语法请自行参考官方文档或百度。下面我直接给出我编写好了的Dockerfile文档:文件名为 Dockerfile

FROM centos:latest
LABEL MAINTAINER="Zereao,https://github.com/Zereao"

# 创建用户,分配权限
RUN groupadd toms && \
     useradd tom -g toms && \
     chown -R tom:toms /home/tom/ && \
     su tom && \
     mkdir ~/data

COPY data /home/tom/data/

# 配置环境变量
ENV JAVA_HOME /home/tom/data/jdk1.8.0_202
ENV PATH $JAVA_HOME/bin:$PATH
ENV NODE_HOME /home/tom/data/node-v10.15.3-linux-x64
ENV PATH $NODE_HOME/bin:$PATH

# 开放端口
EXPOSE 9100 9200 9201 9202 9300

将上面的内容复制下来,新建文本文档,名为 Dockerfile,粘贴进去,保存。

然后,在Dockerfile 同级的目录下,新建一个文件夹,名为 data,将 JDK、Elasticsearch、head插件、node.js放进去。如下图:

        

目录结构如上图,下面,解释一下Dockerfile文件中的部分命令:

在上面的文件中,我们首先添加了一个toms用户组,然后在toms用户组下新建了一个用户tom,并给tom赋予了 /home/tom 目录的权限,然后切换到了tom用户,在 tom 用户下根目录下新建了一个名为 data 的目录。

然后,将 Dockerfile 文件所在路径下的 data 目录下的文件(不会拷贝data目录本身)Copy到容器的/home/tom/data/目录下。这里,我们也可通过挂载本地目录来实现,具体方法请自行百度。

然后配置了JDK和Node.js的环境变量。

最后,暴露了几个端口,9100是head插件默认的端口,9200/9201/9202分别是ES集群三个节点的端口,9300是ES节点间通信的默认端口,这里不暴露也可以。因为我也是刚学,为了以防万一,我也暴露一下。

3、从Dockerfile文件构建新的ES镜像

在上面的准备工作都做好之后,我们检查一下Dockerfile文件的内容,确定没问题后,我们cd到Docerfile文件所在的目录,执行下面的命令进行构建:

docker build -t es:v1 .      # 注意命令最后有个点  . 

-t 指定了 容器名称:TAG,这里我构建了一个名为  es 的镜像,TAG为 v1。需要注意的是,命令最后有一个点  .  ,代表 Dockerfile文件所在的目录(当前路径)。由于我们拷贝了大量的文件到容器中,所以构建起来可能比较慢。等到 Successfully tagged es:v1 提示的时候,就成功构建完毕了。

这时候,我们再执行  dokcer images,就可以看到我们已经构架成功的镜像 es:v1,并且也知道了其IMAGE ID。

4、基于es:v1创建一个新的容器

执行命令:

docker run -itd -p 9100:9100 -p 9200-9202:9200-9202 -p 9300:9300 27a

这里简单说明下:

-itd 请自行百度;

-p 是建立端口映射。咱们上面的Dockerfile文件中的EXPOSE指令,只是暴露了端口,但是并未和宿主机之间的端口建立映射。这里有两种写法:

  • -p 9100:9100 :宿主机的 9100 端口映射到 容器的 9100 端口;
  •  -p 9200-9202:9200-9202 :宿主机的 9200到9203之间的所有端口,分别映射到 容器的 9200到9203之间的端口。等同于:-p 9200:9200 -p 9201:9201 -p 9202:9202;

最后的 27a,是咱们 es:v1 的 IMAGE ID,我们可以通过其唯一标识一个镜像;由于docker很智能,我们一般都不需要讲 IMAGE ID 写全,只要长度能唯一标识一个镜像即可(一般两三位)。

执行完上面的 docker run 命令后,我们就创建并启动了一个容器。我们使用 docker ps 命令,即可查看容器的状态:

图片呢,我将端口映射部分稍微处理了,否则图片看不清楚。从图中我可看到,该容器的容器ID(CONTAINER ID)。这样,我们的容器就创建好了。

5、进入容器,安装ES

在上一步,我们创建并启动了一个容器。然后,我们执行下面的命令,进入容器:

docker exec -it 7d /bin/bash

同上面类似,这里,我们使用 7d 来指定了上面我们创建并启动的那个容器。执行完,可以看到我们的终端也发生了变化:

这样,我就可以可以对容器进行操作了。

然后,就是ES、Node.js、以及head插件的安装了,接下来的步骤和CentOS下安装的步骤一样,大家可以参考我的前几篇文章:

问题解决

我按照上面的教程安装head插件、搭建集群,除了上面文章中提到的问题,我还碰到了如下情况:

1、编辑 elasticsearch.yml 配置文件的时候,centos 镜像中文乱码。

# 节点名称,这儿我直接取名为 master
?~X??~P??~O?以?~H~P为master?~J~B?~B?
# 网络绑定,这里我绑定 0.0.0.0,支持外网访问
?~Q?~\?~Q?~Z,?~Y?~G~L?~H~Q?~Q?~Z 0.0.0.0,?~T??~L~A?~V?~Q访?~W?

如上面所示,备注的是原文,下面是乱码信息。

解决方式有两种:

  • 1、在创建Dockerfile文件的时候,配置以下环境变量:
#设置语言,centos原生镜像不包含 zh_CN.UTF-8(可以使用 locale -a 命令查看系统所支持的语言),所以这里配置为 en_US.utf8
ENV LANG en_US.utf8
# 设置时区
ENV TZ Asia/Shanghai
  • 2、修改 /etc/bashrc 配置文件。我采用的就是这种方法:
vi /etc/bashrc
# 在末尾加入下面的配置
export LC_ALL="en_US.utf8"
export TZ="Asia/Shanghai"
# 保存退出后,使文件生效
source /etc/bashrc

2、启动ES的时候,报没有权限访问 jvm.options 文件。

Exception in thread "main" java.nio.file.AccessDeniedException: /home/tom/data/elasticsearch-7.0.0/config/jvm.options
	at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
	at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
	at java.nio.file.Files.newByteChannel(Files.java:361)
	at java.nio.file.Files.newByteChannel(Files.java:407)
	at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
	at java.nio.file.Files.newInputStream(Files.java:152)
	at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptionsParser.java:60)

错误信息如上,解决方式很简单,为tom 用户再赋予一次data目录的访问权限即可。

# 首先切换回 root 用户,由于之前运行 elasticsearch 的时候,我们使用 su tom 切换到的 tom 用户,这里,我们直接 使用 exit,即可退回到 切换为 tom 用户之前的用户。
exit
# 为 tom 用户赋予权限。这里可能需要一些时间
chown -R tom:toms /home/tom/

然后在重新启动 ES 即可。

最终,集群搭建完毕,启动head插件,我们访问 localhost:9100,可以看到集群的运行情况:

这里呢,为了节约时间,我只搭建了一主一从。

至此,我们在docker中搭建Elasticsearch 7.0.0 的集群教程就完毕了。如果有什么我没有提到的地方,或者没有讲明白的地方,欢迎大家留言一起探讨。

参考文档

1、https://docs.docker.com/engine/reference/builder/

2、https://docs.docker.com/engine/reference/run/

3、https://www.jianshu.com/p/5d870ec0735f

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐