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. 如果 命令1 成功 → 执行 命令2命令3 不执行)。

  2. 如果 命令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 "$@"

  

 

posted @ 2019-08-13 19:50  凡人半睁眼  阅读(2074)  评论(0)    收藏  举报