shell5(es x-pack初始化)
一、写法记忆点
1、set -euo pipefail
#!/bin/bash set -euo pipefail # 示例1:未定义变量会报错 echo "Starting script..." echo "$undefined_var" # 报错并终止 # 示例2:命令失败会终止脚本 rm non_existent_file.txt # 如果文件不存在,脚本终止 # 示例3:管道命令失败会终止 cat /tmp/no_file | grep "pattern" # cat 失败时,整个管道失败
含义:
-e (errexit) |
命令失败时终止脚本 | 避免错误累积 |
-u (nounset) |
使用未定义变量时终止脚本 | 防止变量拼写错误 |
-o pipefail |
管道中任意命令失败则整体失败 | 确保管道操作的完整性 |
补充: 临时忽略错误
命令1 || true
rm non_existent_file.txt || true # 即使失败,脚本继续执行
2、wait_for_something_ready
场景:循环等待操作,等待某个服务初始化、running等再进行后续操作
until xxx;do
doing something
done
until curl -s -u "$elastic_admin:$elastic_password" http://localhost:9200 >/dev/null; do
sleep 2
done
3、curl -s -w "\n%{http_code}"
-w "%{http_code}" 能够输出响应状态码,根据状态码判断成功与否
response=$(curl -s -w "\n%{http_code}" -u "$elastic_admin:$es_password" -X POST "localhost:9200/_xpack/security/user/$user" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"password": "$pass",
"roles": ["superuser"],
"full_name": "$full_name",
"email": "admin@example.com"
}
EOF
)
body=$(echo "$response" | head -n1)
code=$(echo "$response" | tail -n1)
if [ "$code" -ne 200 ]; then
echo "Error creating user $user: $body" >&2
exit 1
fi
4、echo "Failed to xxx" >&2
将标准输出转到标准错误,方便规范记录
5、systemctl list-unit-files
场景:需要循环多个节点重启每一个服务,如es集群,es_node1..3, 但是序号与节点不匹配
使用通配符过滤出service服务
for service in $(systemctl list-unit-files | awk '{print $1}' | grep '^es_node.*\.service$'); do
echo "Restarting $service..."
systemctl restart "$service" && echo "$service restarted." || {
echo "Failed to restart $service" >&2
exit 1
}
done
6、&& 逻辑与 、|| 逻辑或
&&(逻辑与,AND):
- 作用:只有前一个命令成功(返回状态码
0)时,才会执行后面的命令
||(逻辑或,OR):
-
作用:只有前一个命令失败(返回非零状态码)时,才会执行后面的命令。
组合使用
命令1 && 命令2 || 命令3
逻辑解释:
-
如果
命令1成功 → 执行命令2(命令3不执行)。 -
如果
命令1失败 → 跳过命令2,直接执行命令3。
如:这种写法代码量简单明了
systemctl restart "$service" && echo "$service restarted." || {
echo "Failed to restart $service" >&2
exit 1
}
7、函数式写法
var1=""
var2=""
var3=""
func1(){
do ...
}
func2(){
do ...
}
func3(){
do ...
}
main() {
func1
func2
func3
}
main "$@"
二、脚本及其功能
1、场景
es 5.5.0 版本的es 开启x-pack功能
配置文件启用x-pack、禁用默认账户、新增账户、配置kibana
2、完整脚本
#!/bin/bash
set -euo pipefail
registry_ip=""
es_password="xxxx"
node_list="xxxxt"
kibana_config="xxxx"
es_config_file="xxx"
kibana_image_tar="xxx"
docker_image_src="xxxx"
docker_image_tag="xxxx"
docker_stack_file="xxxx"
elastic_admin="elastic"
elastic_password="changeme"
app_user="xxx"
app_pass="xxx"
collect_user="xxx"
collect_pass="xxx"
update_es_file() {
local node=$1
echo "Processing node: $node"
ssh "$node" 'bash -s' <<'EOF'
es_config_file="/backup/elasticsearch/elasticsearch.yml"
if [ -f "$es_config_file" ]; then
echo "Found elasticsearch.yml file, updating security settings..."
if grep -q "^xpack.security.enabled:" "$es_config_file"; then
sed -i '/^xpack.security.enabled:/s/false/true/' "$es_config_file"
echo "Existing security setting updated"
else
echo "xpack.security.enabled: true" >> "$es_config_file"
echo "New security setting added"
fi
echo "Restarting Elasticsearch service..."
for service in $(systemctl list-unit-files | awk '{print $1}' | grep '^es_node.*\.service$'); do
echo "Restarting $service..."
systemctl restart "$service" && echo "$service restarted." || {
echo "Failed to restart $service" >&2
exit 1
}
done
else
echo "Error: $es_config_file not found" >&2
exit 1
fi
EOF
}
wait_for_elasticsearch_ready() {
echo "Waiting for Elasticsearch HTTP service to be available..."
until curl -s -u "$elastic_admin:$elastic_password" http://localhost:9200 >/dev/null; do
sleep 2
done
echo "Elasticsearch is ready."
}
create_user() {
local user=$1
local pass=$2
local full_name=$3
echo "Creating user: $user"
response=$(curl -s -w "\n%{http_code}" -u "$elastic_admin:$es_password" -X POST "localhost:9200/_xpack/security/user/$user" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"password": "$pass",
"roles": ["superuser"],
"full_name": "$full_name",
"email": "admin@example.com"
}
EOF
)
body=$(echo "$response" | head -n1)
code=$(echo "$response" | tail -n1)
if [ "$code" -ne 200 ]; then
echo "Error creating user $user: $body" >&2
exit 1
fi
}
disable_user() {
local user=$1
local cred=$2
echo "Disabling user: $user"
curl -s -u "$cred" -X PUT "localhost:9200/_xpack/security/user/$user/_disable" || \
echo "Warning: Failed to disable $user user" >&2
}
change_elastic_password() {
echo "Updating default elastic user password..."
curl -u elastic:$elastic_password -X PUT 'http://localhost:9200/_xpack/security/user/elastic/_password?pretty' \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"password": "$es_password"
}
EOF
}
wait_for_security_ready() {
echo "Waiting for .security index to be ready..."
until curl -s -u "$elastic_admin:$es_password" http://localhost:9200/_cluster/health/.security \
| grep -q '"status":"green"'; do
echo "Waiting for .security index to turn green..."
sleep 2
done
echo "Elasticsearch is ready."
}
add_new_user() {
create_user "$app_user" "$app_pass" "New User App"
create_user "$collect_user" "$collect_pass" "New User Collect"
}
disable_builtin_users() {
disable_user "kibana" "$elastic_admin:$es_password"
disable_user "logstash_system" "$elastic_admin:$es_password"
disable_user "elastic" "$app_user:$app_pass"
}
load_and_push_kibana_image() {
echo "Loading and pushing new Kibana image..."
if [ -z "$registry_ip" ]; then
registry_ip=$(hostname -i | awk '{print $1}')
echo "Using auto-detected registry IP: $registry_ip"
fi
docker load -i "$kibana_image_tar" || {
echo "Error: Failed to load Kibana image" >&2
exit 1
}
docker tag "$docker_image_src" "$registry_ip:5000/kibana:$docker_image_tag"
docker push "$registry_ip:5000/kibana:$docker_image_tag"
docker rmi "$docker_image_src" || true
}
update_kibana_config() {
echo "Updating Kibana configuration..."
if [ -f "$kibana_config" ]; then
if grep -q "^elasticsearch.username:" "$kibana_config"; then
sed -i "s/^elasticsearch.username:.*/elasticsearch.username: \"$app_user\"/" "$kibana_config"
else
echo "elasticsearch.username: \"$app_user\"" >> "$kibana_config"
fi
if grep -q "^elasticsearch.password:" "$kibana_config"; then
sed -i "s/^elasticsearch.password:.*/elasticsearch.password: \"$app_pass\"/" "$kibana_config"
else
echo "elasticsearch.password: \"$app_pass\"" >> "$kibana_config"
fi
else
echo "Error: Kibana config not found: $kibana_config" >&2
exit 1
fi
}
redeploy_kibana() {
echo "Cleaning up old Kibana service..."
docker service rm hs-opts_kibana || true
docker config rm kibana_config.yml || true
echo "Creating new Kibana config and redeploying stack..."
docker config create kibana_config.yml "$kibana_config"
docker stack deploy -c "$docker_stack_file" hs-opts
}
main() {
local nodes
nodes=$(awk -F',' '{print $2}' "$node_list")
for node in $nodes; do
update_es_file "$node"
done
wait_for_elasticsearch_ready
change_elastic_password
wait_for_security_ready
add_new_user
disable_builtin_users
load_and_push_kibana_image
update_kibana_config
redeploy_kibana
echo "Upgrade completed. All operations executed successfully."
}
main "$@"

浙公网安备 33010602011771号