Files
geg-gas-doc/宝策/docker_es.sh

222 lines
6.6 KiB
Bash
Raw Normal View History

2025-10-10 09:12:33 +08:00
#!/bin/bash
# 定义变量
CONTAINER_NAME="elasticsearch"
IMAGE_NAME="elasticsearch:7.17.28" # 镜像版本
DATA_DIR="/docker-data/elasticsearch/data" # 数据目录
CONFIG_DIR="/docker-data/elasticsearch/config" # 配置目录
LOGS_DIR="/docker-data/elasticsearch/logs" # 日志目录
HTTP_PORT=9200 # HTTP端口
TRANSPORT_PORT=9300 # 内部通信端口
CLUSTER_NAME="es-single-cluster" # 集群名称
NODE_NAME="single-node" # 节点名称
ES_JAVA_OPTS="-Xms1g -Xmx1g" # JVM内存根据主机内存调整
# 显示帮助信息
show_help() {
echo "使用方法: $0 [操作类型]"
echo "操作类型:"
echo " deploy - 部署并启动单机模式Elasticsearch"
echo " remove - 停止并删除容器及数据目录"
echo " logs - 查看容器日志"
echo " status - 查看容器状态"
echo " help - 显示帮助信息"
}
# 准备环境(创建目录和配置文件)
prepare_env() {
# 创建数据、配置、日志目录并授权
for dir in "$DATA_DIR" "$CONFIG_DIR" "$LOGS_DIR"; do
if [ ! -d "$dir" ]; then
echo "创建目录: $dir"
mkdir -p "$dir"
fi
chown -R 1000:1000 "$dir" # 匹配容器内用户UID/GID
chmod 755 "$dir"
done
# 生成单机模式配置文件(若不存在)
if [ ! -f "$CONFIG_DIR/elasticsearch.yml" ]; then
echo "生成单机模式配置文件: $CONFIG_DIR/elasticsearch.yml"
cat > "$CONFIG_DIR/elasticsearch.yml" << EOF
cluster.name: es-single-cluster
node.name: single-node
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
discovery.type: single-node # 单机模式核心配置(必须保留)
# 以下行必须删除或注释掉与single-node冲突
# cluster.initial_master_nodes: ["single-node"]
xpack.security.enabled: false
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: true
ingest.geoip.downloader.enabled: false
EOF
fi
# 配置JVM参数若不存在
if [ ! -f "$CONFIG_DIR/jvm.options" ]; then
echo "生成JVM配置文件: $CONFIG_DIR/jvm.options"
# 修正后代码(拆分参数为两行)
cat > "$CONFIG_DIR/jvm.options" << EOF
-Xms1g
-Xmx1g
# 保留其他默认配置(如下)
-XX:+UseG1GC
-XX:MaxGCPauseMillis=50
-XX:+HeapDumpOnOutOfMemoryError
8-13:-XX:+UseConcMarkSweepGC
8-13:-XX:CMSInitiatingOccupancyFraction=75
8-13:-XX:+UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
-XX:+HeapDumpOnOutOfMemoryError
9-:-XX:+ExitOnOutOfMemoryError
-XX:HeapDumpPath=data
-XX:ErrorFile=logs/hs_err_pid%p.log
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
# JDK 9+ GC logging
9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m
EOF
fi
}
# 检查系统配置解决vm.max_map_count问题
check_sys_config() {
current_map_count=$(sysctl -n vm.max_map_count)
if [ $current_map_count -lt 262144 ]; then
echo "检测到vm.max_map_count值不足需要调整..."
if [ "$(id -u)" -ne 0 ]; then
echo "请使用sudo权限运行脚本或手动执行"
echo "sudo sysctl -w vm.max_map_count=262144"
echo "并在/etc/sysctl.conf中添加vm.max_map_count=262144"
exit 1
fi
# 临时调整
sysctl -w vm.max_map_count=262144
# 永久生效
if ! grep -q "vm.max_map_count=262144" /etc/sysctl.conf; then
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
fi
fi
}
# 部署启动
deploy_es() {
check_sys_config # 先检查系统配置
prepare_env # 准备目录和配置
# 停止并删除现有容器
if [ "$(docker ps -aq -f name=$CONTAINER_NAME)" ]; then
echo "停止并删除现有容器: $CONTAINER_NAME"
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
fi
# 启动单机模式容器
echo "启动Elasticsearch单机模式..."
docker run -d --privileged \
--name $CONTAINER_NAME \
--restart always \
--ulimit nofile=65536:65536 \
--ulimit nproc=4096:4096 \
--ulimit memlock=-1:-1 \
-p $HTTP_PORT:9200 \
-p $TRANSPORT_PORT:9300 \
-v $DATA_DIR:/usr/share/elasticsearch/data \
-v $CONFIG_DIR/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v $LOGS_DIR:/usr/share/elasticsearch/logs \
-e TZ=Asia/Shanghai \
$IMAGE_NAME
# 检查启动状态
if [ "$(docker ps -aq -f name=$CONTAINER_NAME -f status=running)" ]; then
echo "Elasticsearch单机模式启动成功"
echo "访问地址: http://localhost:$HTTP_PORT"
echo "集群名称: $CLUSTER_NAME"
echo "JVM配置: $ES_JAVA_OPTS"
else
echo "启动失败,请查看日志: ./$0 logs"
docker logs $CONTAINER_NAME
fi
}
# 移除容器和数据
remove_es() {
if [ "$(docker ps -aq -f name=$CONTAINER_NAME)" ]; then
echo "停止容器: $CONTAINER_NAME"
docker stop $CONTAINER_NAME
echo "删除容器: $CONTAINER_NAME"
docker rm $CONTAINER_NAME
else
echo "容器 $CONTAINER_NAME 不存在"
fi
# 询问是否删除数据目录
for dir in "$DATA_DIR" "$CONFIG_DIR" "$LOGS_DIR"; do
if [ -d "$dir" ]; then
read -p "是否删除目录 $dir? (y/n) " confirm
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
echo "删除目录: $dir"
rm -rf "$dir"
else
echo "保留目录: $dir"
fi
fi
done
}
# 查看日志
show_logs() {
if [ "$(docker ps -aq -f name=$CONTAINER_NAME)" ]; then
echo "查看Elasticsearch日志按Ctrl+C退出..."
docker logs -f $CONTAINER_NAME
else
echo "容器 $CONTAINER_NAME 不存在"
fi
}
# 查看状态
show_status() {
echo "容器状态:"
docker ps -f name=$CONTAINER_NAME --format "表格:{{.Names}} {{.Status}} {{.Ports}}"
if [ "$(docker ps -aq -f name=$CONTAINER_NAME -f status=running)" ]; then
echo "服务健康检查:"
curl -s "http://localhost:$HTTP_PORT/_cluster/health" | jq .
fi
}
# 主逻辑
if [ $# -ne 1 ]; then
show_help
exit 1
fi
case "$1" in
deploy)
deploy_es
;;
remove)
remove_es
;;
logs)
show_logs
;;
status)
show_status
;;
help)
show_help
;;
*)
echo "无效操作: $1"
show_help
exit 1
;;
esac