網(wǎng)站介紹詞百度一下瀏覽器
文章目錄
- 為什么要通過(guò)腳本來(lái)部署服務(wù)器?
- EC2實(shí)例類型+硬件選擇
- 實(shí)例類型的選擇
- 內(nèi)存
- CPU
- 存儲(chǔ)
- 架構(gòu)
- 操作系統(tǒng)
- 最終的選擇
- 其他配置
- 安全組配置
- 網(wǎng)絡(luò)配置
- IAM Role
- Key Pair
- 內(nèi)部域名
- 書寫自動(dòng)化腳本
- 屬性文件
- EBS配置文件
- 創(chuàng)建EC2實(shí)例命令
- user data 文件
- OpenTelemetry監(jiān)控
- 創(chuàng)建內(nèi)部域名
- 發(fā)送部署結(jié)果消息通知相關(guān)人員
- 驗(yàn)證
- 總結(jié)
由于最近參與了部分部署服務(wù)器的工作,記錄并總結(jié)下第一次參與利用腳本自動(dòng)化部署服務(wù)器的過(guò)程和思路。
為什么要通過(guò)腳本來(lái)部署服務(wù)器?
在實(shí)際生產(chǎn)中,我們規(guī)定當(dāng)新創(chuàng)建一臺(tái)服務(wù)器、上線或下線某臺(tái)服務(wù)器時(shí)不允許通過(guò)在云服務(wù)廠商的控制臺(tái)上用鼠標(biāo)完成操作這種方式來(lái)創(chuàng)建,原因是
- 流程無(wú)法標(biāo)準(zhǔn)化,誰(shuí)知道每次鼠標(biāo)點(diǎn)點(diǎn)點(diǎn)都干了什么,如果換其他人維護(hù),不熟悉的人不知道創(chuàng)建一臺(tái)服務(wù)器需要哪些步驟
- 流程無(wú)法標(biāo)準(zhǔn)化帶來(lái)的后果就是無(wú)法自動(dòng)化,每部署一臺(tái)服務(wù)器都要這么干,重復(fù)工作且長(zhǎng)期這么做極容易出錯(cuò)
- 通過(guò)腳本實(shí)現(xiàn),將腳本的每次改動(dòng)通過(guò)git的版本控制,日后回顧時(shí)知道當(dāng)時(shí)為什么要增加或減少某個(gè)步驟
EC2實(shí)例類型+硬件選擇
在書寫腳本之前,我們得先根據(jù)實(shí)際應(yīng)用場(chǎng)景選擇對(duì)應(yīng)的類型和硬件。
實(shí)例類型的選擇
我們打算在該實(shí)例上安裝單機(jī)版的ElasticSearch+Kibana,所以我們選擇內(nèi)存優(yōu)化型而不是通用型或計(jì)算優(yōu)化型或其他類型
內(nèi)存
由于我們對(duì)這個(gè)ElasticSearch存儲(chǔ)的都是非核心數(shù)據(jù)且是單機(jī),再加上以往的經(jīng)驗(yàn),我們認(rèn)為16GB是一個(gè)合適的值
CPU
根據(jù)ElasticSearch官方文檔,CPU通常不是限制ElasticSearch的因素,所以我們初期認(rèn)為2個(gè)CPU足夠
存儲(chǔ)
我們使用EBS+gp3,初始容量為30GB。容量預(yù)估是根據(jù)實(shí)際測(cè)試結(jié)果確定的
架構(gòu)
有x86_64和arm64兩種選擇,arm64相對(duì)便宜一點(diǎn),而且我們開始逐漸將架構(gòu)由x86_64過(guò)渡到arm64,所以選擇arm64
操作系統(tǒng)
操作系統(tǒng)全平臺(tái)保持一致,統(tǒng)一為Rocky Linux 8.10。AWS中對(duì)應(yīng)的AMI為ami-06459b48b47a92d77
最終的選擇
經(jīng)過(guò)上述條件過(guò)濾之后,可選的實(shí)例類型為r6g.large、r7g.large、r8g.large。由于r8g.large是最新的,我們擔(dān)心其穩(wěn)定性,所有我們選擇了中間版本r7g.large
其他配置
安全組配置
根據(jù)需求將kibana的5601,elasticsearch的9200端口開放以允許內(nèi)部web server服務(wù)器訪問(wèn)
網(wǎng)絡(luò)配置
和其他服務(wù)器一樣,使用統(tǒng)一的VPC和子網(wǎng)
IAM Role
根據(jù)需要配置IAM Role
Key Pair
和其他服務(wù)器一樣,使用統(tǒng)一的key pair
內(nèi)部域名
我們所有的服務(wù)器都通過(guò)內(nèi)部域名訪問(wèn)而不是IP,因?yàn)镮P可能會(huì)變。所以在寫腳本之前要把最終要用的內(nèi)部域名確定下來(lái),例如:elastic-stack-standalone.xxx.io
書寫自動(dòng)化腳本
使用aws ec2 cli的run-instances命令來(lái)創(chuàng)建實(shí)例和aws route53 cli的change-resource-record-sets命令來(lái)創(chuàng)建內(nèi)部域名
屬性文件
我們將上述硬件的配置和其他配置都放到一個(gè)屬性文件中server.properties
SERVER_TYPE="elastic-stack-standalone"
SERVER_INSTANCE_TYPE="r7g.large"
# arm64 rocky linux 8.9 instead of x86_64
SERVER_AMI="ami-06459b48b47a92d77"# security group id
SG_ID="security group id"# key pair.
KEY_PAIR_NAME=keyPairName# networking
SUBNET_ID="subnet id"# elastic stack standalone server does not need public IP
PUBLIC_IP=""# private domain name
ROUTE53_FILE="change-resource-record-sets.json"
PRIVATE_DOMAIN="elastic-stack-standalone.xxx.io"
HOSTED_ZONE_ID=hostZoneId
EBS配置文件
device-mappings.json
[{"DeviceName": "/dev/sda1","Ebs": {"VolumeSize": 30,"VolumeType": "gp3","DeleteOnTermination": true}}
]
創(chuàng)建EC2實(shí)例命令
除USER_DATA 所有變量都從server.properties中讀取
aws ec2 run-instances --image-id ${SERVER_AMI} \
--key-name $KEY_NAME \
--user-data "${USER_DATA}" \
--instance-type ${SERVER_INSTANCE_TYPE} \
--block-device-mappings device-mappings.json \
--subnet-id ${SUBNET_ID} \
--security-group-ids ${SG_ID} \
--private-ip-address $PRIVATE_IP
user data 文件
user data可以理解為AWS 創(chuàng)建Instance之后,你希望執(zhí)行的后續(xù)操作。
例如
- 升級(jí)操作系統(tǒng)
- 安裝軟件,如git, ldap client
- 創(chuàng)建及配置用戶
user-data.txt內(nèi)容為
install_software() {echo "install required software"yum install expect git openldap-clients sssd sssd-ldap net-tools compat-openssl10 bc -y
}
init_os() {# upgrade rocky linux to 8.10 from 8.9yum -y updateconfig_securityconfig_network_and_firewallconfig_system_settings_for_elastic_stackinstall_software
}config_ldap_client() {echo "config ldap client"CONF="/git/repositories/deployment/server-setup/ldap-client"yes | cp -fp $CONF/etc/openldap/ldap-pro.conf /etc/openldap/ldap.confyes | cp -fp $CONF/etc/sssd/sssd-pro.conf /etc/sssd/sssd.conf# reload sssd servicechmod 600 /etc/sssd/sssd.confsystemctl restart sssd oddjobdsystemctl enable sssd oddjobd# create home directory for ldap loginauthselect select sssd with-mkhomedirsystemctl restart sshd#Add LDAP users to proper user groupsfor U in userList; dousermod -aG wheel $Udone
}install_elastic_stack_with_rpm() {rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearchcat <<EOF | tee /etc/yum.repos.d/elasticsearch.repo >/dev/null
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=0
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
EOFinstall_elasticsearch_then_startinstall_kibana_then_start
}install_monitor() {cp -rp /root/repositories/deployment/server-setup/monitored_host /opt/chmod u+x /opt/monitored_host/elastic-stack/standalone/monitor.sh/opt/monitored_host/elastic-stack/standalone/monitor.sh
}main() {init_ospull_git_repoconfig_ldap_clientinstall_elastic_stack_with_rpminstall_otel_monitor
}
main
主要流程見main函數(shù),我沒有把所有函數(shù)都寫出來(lái),只列舉了幾個(gè)函數(shù):例如將Rocky Linux 8.9 升級(jí)到8.10,因?yàn)锳WS 提供的AMI最新為8.9,我們使用的是8.10; 關(guān)于服務(wù)器用戶我們使用LDAP進(jìn)行管理
OpenTelemetry監(jiān)控
不了解opentelemetry的同學(xué),建議查看官方文檔去了解它到底是干什么的。
我們對(duì)于OS級(jí)別的監(jiān)控使用node_exporter,對(duì)于ElasticSearch的監(jiān)控使用elasticsearch_exporter,然后統(tǒng)一使用otel_collector進(jìn)行收集metrics并暴露出去供Prometheus服務(wù)器收集。
monitor.sh
#!/bin/bash
# this scirpt will install node_exporter, elasticsearch_exporter opentelemetry collector
workspace=/opt/monitored_hostarchitecture=$(arch)
hardware_architecture=$( [ "$architecture" = "aarch64" ] && echo "arm64" || ( [ "$architecture" = "x86_64" ] && echo "amd64" || echo "unknown-architecture" ) )echo "The architecture is: $hardware_architecture"install_node_exporter() {cd /optURL=$(curl -s https://api.github.com/repos/prometheus/node_exporter/releases | grep browser_download_url | grep "linux-$hardware_architecture" | head -n 1 | cut -d '"' -f 4)FILE=$(echo $URL|awk -F"/" '{print $NF}')DIR=$(echo $URL|awk -F"/" '{print $NF}'|sed 's/\.tar\.gz//g')curl -LO $URLtar -zxf $FILErm -rf /opt/node_exporterln -s /opt/$DIR /opt/node_exporterrm -f $FILE# add node_exporter servicecd $workspace\cp systemd_service/node_exporter.service /etc/systemd/systemsystemctl daemon-reloadsystemctl enable node_exporter.servicesystemctl start node_exporter.service
}install_elasticsearch_exporter() {cd /optURL=$(curl -s https://api.github.com/repos/prometheus-community/elasticsearch_exporter/releases | grep browser_download_url | grep "linux-$hardware_architecture" | head -n 1 | cut -d '"' -f 4)FILE=$(echo $URL|awk -F"/" '{print $NF}')DIR=$(echo $URL|awk -F"/" '{print $NF}'|sed 's/\.tar\.gz//g')curl -LO $URLtar -zxf $FILEln -s /opt/$DIR /opt/elasticsearch_exporterrm -f $FILE# add servicecd $workspace\cp systemd_service/elastic_stack_sre_exporter.service /etc/systemd/systemsystemctl daemon-reloadsystemctl enable elastic_stack_sre_exporter.servicesystemctl start elastic_stack_sre_exporter.service
}install_otelcol() {cd /optURL=$(curl -s https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases|grep "browser_download_url"|grep -v "otelcol-contrib"|grep rpm|grep "linux_$hardware_architecture"|head -n 1|cut -d '"' -f 4)FILE=$(echo $URL|awk -F"/" '{print $NF}')curl -LO $URLrpm -iUh $FILErm -f $FILE# add otel useruseradd otel -s /sbin/nologin -M# add otel config pathmkdir /etc/otelcolcd "$workspace"\cp elastic-stack/standalone/otelcol.yml /etc/otelcol/config.yamlsed -ri 's#( *host_name: ).*#\1"'$(hostname)'"#' /etc/otelcol/config.yaml\cp systemd_service/otelcol.service /etc/systemd/systemsystemctl daemon-reloadsystemctl enable otelcol.servicesystemctl restart otelcol.service
}
main() {install_node_exporterinstall_elasticsearch_exporterinstall_otelcol
}
main
otel_collector配置文件
extensions:health_check:receivers:prometheus/os:config:scrape_configs:- job_name: 'node_exporter'scrape_interval: 5sstatic_configs:- targets:- "127.0.0.1:9100"prometheus/elasticsearch:config:scrape_configs:- job_name: 'elasticsearch_exporter'scrape_interval: 5sstatic_configs:- targets:- "127.0.0.1:9114"exporters:prometheus/main:endpoint: "0.0.0.0:8090"const_labels:host_locale: "product"host_name: "replace_me"service:pipelines:metrics/00:receivers: [prometheus/os, prometheus/elasticsearch]exporters: [prometheus/main]
創(chuàng)建內(nèi)部域名
change-resource-record-sets.json
{"Changes": [{"Action": "UPSERT","ResourceRecordSet": {"Name": "host.xxxx.io","Type": "A","TTL": 300,"ResourceRecords": [{"Value": "IP0"}]}}]
}
route53 cli 請(qǐng)求命令
# 替換json文件中的值
ROUTE53_REQUEST=$(cat ${ROUTE53_FILE});
ROUTE53_REQUEST=${ROUTE53_REQUEST/host.${PRIVATE_DOMAIN}/${HN}.${PRIVATE_DOMAIN}}
ROUTE53_REQUEST=${ROUTE53_REQUEST/IP0/${PRIVATE_IP}}aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} --change-batch "${ROUTE53_REQUEST}" --output json
發(fā)送部署結(jié)果消息通知相關(guān)人員
部署流程為只需要執(zhí)行一個(gè)腳本,然后即可干別的事情去了。等到主要腳本執(zhí)行完畢,發(fā)送部署結(jié)果通知相關(guān)人員或更新上線服務(wù)器列表。這一部分是集成哪家IM,看你們公司實(shí)際用哪家,按需接入即可
驗(yàn)證
驗(yàn)證的流程,按照道理來(lái)說(shuō)也要集成到腳本中,我這里沒有集成。采取了手動(dòng)驗(yàn)證的方式,主要驗(yàn)證:
- OS是否已升級(jí)
- 配置的用戶是否可以登錄服務(wù)器
- elasticsearch和kibana是否可以正常訪問(wèn)
- 其他web server是否可以通過(guò)內(nèi)部域名訪問(wèn)elasticsearch
- 是否可以通過(guò)Prometheus收集指標(biāo)
總結(jié)
整體思路如下:
- 所有服務(wù)器部署流程使用同一個(gè)部署腳本來(lái)保證部署流程標(biāo)準(zhǔn)化
- 每個(gè)服務(wù)器的server.properties和user-data.txt不一樣,每次部署只需要提供這兩個(gè)文件即可
- 對(duì)于部署之后的驗(yàn)證也可寫成腳本集成到部署流程中來(lái)