222 lines
6.6 KiB
Bash
222 lines
6.6 KiB
Bash
#!/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 |