没事写写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