文章目录
- 目录结构
- install_docker_es.sh
- elasticsearch.yml.template
没事写写shell[我自己都不信,如果不是因为工作需要,我才不要写shell],努力让自己的脚本更健壮[就像我自己一样臃肿]
目录结构
创建两个目录,准备两个文件即可
./bin # 脚本存放路径
└── install_docker_es.sh # 脚本名称随意
./conf # 配置文件模板存放路径
└── elasticsearch.yml.template # 配置文件模板
install_docker_es.sh
脚本执行方式:sh 脚本名称 镜像名称
#!/bin/bash
# 遇到报错就退出脚本
set -e
# $(cd `dirname $0`; pwd)是脚本当前所在目录
# $(dirname `cd $(dirname $0);pwd`)是脚本当前所在目录的上一级目录
base_dir=$(cd `dirname $0`; pwd)
conf_dir=$(dirname `cd $(dirname $0);pwd`)/conf
# 利用位置变量定义镜像的名称
image_name="$1"
# 填写当前机器的ip地址
ip_host='172.31.243.179'
# 填写es需要暴露的端口,此端口和容器内部的端口一致
es_port='
9200
9201
9202
'
# 填写es集群之间通信需要暴露的端口,此端口和容器内部的端口一致
es_cluster_port='
9300
9301
9302
'
# 配置es的jvm内存大小
xms='-Xms256m'
xmx='-Xmx256m'
# 配置es的集群名称
es_cluster_name='elasticsearch-cluster'
# 配置es的data、logs、conf目录,只需要写一个总的目录即可[目录可以不存在,脚本会创建父级目录],脚本会分别创建
es_data_path='/opt/elasticsearch'
es_logs_path='/opt/elasticsearch'
es_conf_path='/opt/elasticsearch'
# 容器内的es部署目录
es_docker_path=$(docker inspect ${image_name} | awk -F '"' '/WorkingDir/ {print $4}' | uniq)
# 通过printf "%q\n"命令格式化输出变量值为数组的格式
es_port_array=($(printf "%q\n" ${es_port}))
es_cluster_port_array=($(printf "%q\n" ${es_cluster_port}))
# 如果位置变量没有输入值,则输出使用方法[sh 脚本名称 镜像名称],并退出脚本
# 镜像名称可以是<镜像名称:tag>,也可以是镜像id,只要存在即可
if [ -z "${image_name}" ];then
echo "Usage: sh $0 elasticsearch:latest"
exit 1
fi
# es需要配置系统参数max_map_count_num[jvm线程数量]
# 如果/etc/sysctl.conf配置的max_map_count_num不是262144,则会注释掉已有的配置,重新写入配置
# 通过sysctl -p使配置立即生效
max_map_count_num=$(awk -F '=' '/vm.max_map_count/ {print $NF}' /etc/sysctl.conf)
if [[ x"${max_map_count_num}" != x"262144" ]];then
sed -i '/vm.max_map_count/s/^/#/' /etc/sysctl.conf
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p &> /dev/null
fi
# 修改cluster.name为用户定义的
sed -i "/cluster.name/s/:.*/: ${es_cluster_name}/" ${conf_dir}/elasticsearch.yml.template
# 修改es的主机ip为用户定义的
sed -i "/network.publish_host/s/:.*/: ${ip_host}/" ${conf_dir}/elasticsearch.yml.template
# 配置es的发现主机的ip加端口
sed -i "/discovery.zen.ping.unicast.hosts/s/:.*/: \[\"${ip_host}:$(echo ${es_cluster_port_array[@]} | cut -d " " -f 1)\"\]/" ${conf_dir}/elasticsearch.yml.template
for (( n=2; n<=${#es_cluster_port_array[@]}; n++ ))
do
sed -i "/discovery.zen.ping.unicast.hosts/s/: \[/&\"${ip_host}:$(echo ${es_cluster_port_array[@]} | cut -d " " -f ${n})\",/" ${conf_dir}/elasticsearch.yml.template
done
for (( i=0; i<${#es_port_array[@]}; i++ ))
do
# 判断data、logs、conf目录是否存在,不存在则创建
[ -d "${es_data_path}/es-data-${es_port_array[i]}" ] || mkdir -p ${es_data_path}/es-data-${es_port_array[i]}
[ -d "${es_logs_path}/es-logs-${es_port_array[i]}" ] || mkdir -p ${es_logs_path}/es-logs-${es_port_array[i]}
[ -d "${es_conf_path}/es-conf-${es_port_array[i]}" ] || mkdir -p ${es_conf_path}/es-conf-${es_port_array[i]}
# 通过-e修改多个内容[节点名称、es服务端口、es集群通信端口],重定向成以服务端口为名称的配置文件
sed -e "/node.name/s/:.*/: es-node-${es_port_array[i]}/" \
-e "/http.port/s/:.*/: ${es_port_array[i]}/" \
-e "/transport.tcp.port/s/:.*/: ${es_cluster_port_array[i]}/" ${conf_dir}/elasticsearch.yml.template \
> ${conf_dir}/elasticsearch-${es_port_array[i]}.yml
# 将模板配置文件目录下的配置文件,复制到es的conf目录下,统一管理
cp ${conf_dir}/elasticsearch-${es_port_array[i]}.yml ${es_conf_path}/es-conf-${es_port_array[i]}/elasticsearch-${es_port_array[i]}.yml
# ES_JAVA_OPTS 指定jvm内存大小
# TAKE_FILE_OWNERSHIP 因为es容器内默认的属主是uid=1000的用户,宿主机的目录属主是uid=0的用户,会造成Permission denied[权限被拒绝]的情况
# -p 暴露服务端口以及集群通信端口
# -v 宿主机与容器内的目录/文件映射
# -v /etc/localtime:/etc/localtime 容器内的时间与宿主机一致[否则容器内的时间与宿主机的时间会相差8小时]
# --name 指定es容器的名称,以服务端口为后缀
# ${image_name} 指定启动的docker镜像
docker run -d -e ES_JAVA_OPTS=""${xms}" "${xmx}"" \
-e TAKE_FILE_OWNERSHIP=true \
-p ${es_port_array[i]}:${es_port_array[i]} \
-p ${es_cluster_port_array[i]}:${es_cluster_port_array[i]} \
-v /etc/localtime:/etc/localtime \
-v ${es_data_path}/es-data-${es_port_array[i]}:${es_docker_path}/data \
-v ${es_conf_path}/es-conf-${es_port_array[i]}/elasticsearch-${es_port_array[i]}.yml:${es_docker_path}/config/elasticsearch.yml \
-v ${es_logs_path}/es-logs-${es_port_array[i]}:${es_docker_path}/logs \
--name es-cluster-${es_port_array[i]} ${image_name}
done
elasticsearch.yml.template
cluster.name: elasticsearch-cluster
node.name: es-node1
network.bind_host: 0.0.0.0
network.publish_host: "引号里面随便写,反正我会覆盖掉"
http.port: "引号里面随便写,反正我会覆盖掉"
transport.tcp.port: "引号里面随便写,反正我会覆盖掉"
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.zen.ping.unicast.hosts: ["引号里面随便写,反正我会覆盖掉"]
discovery.zen.minimum_master_nodes: 1