안녕하세요. 플랫폼의 코미야입니다.
다른 인스턴스를 중복하더라도 NAT 인스턴스를 중복하지 않으면,
사설 세그먼트에 있는 HA 서버들이 AWS API 서버와 통신하지 못하고 멈출 거라고 생각했어요.
우리 선임자들의 조항을 언급하며, 저는 다음과 같은 발언을 했습니다.
**・어떻게든 어떻게 할지 생각해 봐
**
Amazon Linux로 만들었기 때문에 Heartbeat 같은 걸 넣기 어려울 것 같고, 애초에 heartbaet을 쓸 필요도 없을 것 같아요.
대기 시스템에서 모니터링하고 AWS에서 라우팅 테이블을 교체하는 것만으로도 충분할 것 같습니다.
대기 NAT 인스턴스의 경우,
만약 직접 만들지 않으면 라우팅 테이블을 만들고 시작하며 만들어야 하므로 전환 시간이 길어질 것입니다.
인스턴스 수수료가 있지만, 시작해 두는 게 더 나은 것 같습니다.
**・당분간은 기존 Amazon Linux NAT 인스턴스의 설정을 조정하는 것부터 시작하세요.
**
스도
# usermod -G 휠 user-op
# ID 사용자 조작자
UID=500(user-op) gid=501(user-op) groups=501(user-op),10(wheel)
# 비수도
%wheel all=(모두) 모두
댓글을 삭제하세요.
다른 인스턴스 반대편에서 sudo가 가능한지 확인해 보세요
또한, 파이썬 도구를 NAT 인스턴스에 넣으세요
이메일 발송도 설정하세요
sendmail이 Amazon Linux에서 실행되고 있었던 것 같아요.
vi /etc/mail/submit.cf
D{MTAHost}[172.18.10.22]
Djnat01.hoge.com *자연 2가 그렇게 변합니다
서비스 전송 메일 정차
chkconfig sendmail off
Mailx 설치 기능
에코 호게 |메일 -s 테스트코미 komiyay@xxxxx
장소 매칭
mv /etc/localtime /etc/localtime.org
-s: /usr/share/zoneinfo/아시아/도쿄/등/현지 시간
날짜
2013년 11월 14일 목요일 10:25:59 JST
크론탭 -e
# 타임 싱크
0 * * * * * /USR/SBIN/NTPDATE -BS 172.18.10.24
NTPD 정차 서비스
chkconfig ntpd off
커널 튜닝을 넣으세요
# CP -p /etc/sysctl.conf{,.org}
# vi /etc/sysctl.conf
VM.swappiness = 30
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192
net.ipv4.tcp_keepalive_intvl = 3
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_time = 10
# Syctl -p
·별도의 NAT 인스턴스와 이를 기본 게이트웨이로 사용하는 라우팅 테이블을 생성하세요.
NAT 인스턴스는 AMI를 동일한 세그먼트로 복사합니다
만들어졌다
I-005A5E02
Source/DestCheck를 비활성화로 설정하지 않으면, RouterTable로 라우팅할 때 Exit 인스턴스로 나오지 않습니다.
RTB-이이.
라우팅 테이블에서 목적지 0.0.0.0/0(즉, 디포지)의 목표는 다음과 같습니다.
이전 인스턴스에 명시하고 추가하세요
현재 이 테이블에는 연관된 서브넷이 없습니다.
‧일단은 AWS 명령어로 라우팅 테이블을 연결하면서 개인 호스트에서 야후를 핑해 보세요.
매뉴얼을 한번 보세요
# AWS EC2 교체-경로-테이블-연관 도움말
줄거리
교체-경로-테이블-연관
[--리허 연기 | --노-리허 런]
--협회-ID <value>
--route-table-id <value>
--association-id (문자열)
원본 간의 현재 연관성을 나타내는 ID입니다
경로 테이블과 서브넷.
--route-table-id (문자열)
서브넷과 연관할 새로운 경로 테이블의 ID.
# AWS EC2 설명-경로-테이블 도움말
줄거리
설명-경로-테이블
[--리허 연기 | --노-리허 런]
[--경로-테이블-<value>IDS]
[--필터 <value>소리]
--필터 이름=string1,값=string1,string2
협회.subnet-id
명령 내 장애 조치 검사
참고문헌: http://d.hatena.ne.jp/j3tm0t0/20120814/1344971491
active_rt=rtb-xxxxxxxx
standby_rt=rtb-yyyy
SubNetId=subnet-zzzzzzzz
AWS EC2 describe-route-tables --route-table-ids ${active_rt} --filters Name=association.subnet-id,Values=${subnetid}
"협회": [
{
"SubnetId": "subnet-zzzzzzzz",
"RouteTableAssociationId": "; rtbassoc-7c535b1e",
"RouteTableId": "rtb-xxxxxxxx"
},
association='aws ec2 describe-route-tables --route-table-ids ${active_rt} --filters Name=association.subnet-id,Values=${subnetid}|grep -A 1 ${subnetid}|awk '{print $2}'|tail -1|sed -e 's/[",]//g'''
# AWS EC2 replace-route-table-association --route-table-id ${standby_rt} --association-id $association
{
"NewAssociationId": "rtbassoc-52767e30"
}
# aws ec2 describe-route-tables --filters Name=association.sub
net-id,Values=${subnetid}|grep -A 1 ${subnetid}|awk '{print $2}'|tail -1|sed -e
's/[",]//g'
RTBASSOC-52767E30
관리 콘솔에서 대기 경로로 전환된 것을 확인할 수 있었습니다.
명령어만으로 스위칭 테스트는 성공적이었습니다. 야후로의 핑은 중단되지 않았습니다.
·장애 조치 조건을 고려해
아래 참고로 생각해보면, 씬 뒤쪽에서 약 3명의 호스트와 통신할 수 없다면 장애 조치(failover)를 사용할 수 있습니다.
http://d.hatena.ne.jp/hirose31/20131105/1383623672
농노를 쓰는 게 더 쉬운지 궁금하네요. 찾아볼게요.
메시징 도구 Serf in EC2 | Developers.IOSerf - jedipunkz의 블로그https://dl.bintray.com/mitchellh/serf/[Serf] v0.2.0으로 업그레이드하고 변경 사항을 확인함 | Pocketstudio.jp log3serf-munin으로 자동 추가/삭제 munin-node 모니터링 | Pocketstudio.jp log3Serf+HAProxy로 만든 자동 로드 밸런서 - Glide Note - Glide Note
NAT 중복 참조:
NAT 인스턴스 중복의 심연 - (안녕)memossuz-lab - 블로그: "고가용성 NAT" 생성 (CentOS6)cloudpack 블로그: HAProxy(ELB 사용)로 호스트 헤더로 정렬하려고 시도 중복 NAT 인스턴스를 만들려고 시도했습니다 - log4moto
농노를 넣으려고 찾아봤어요.
결과적으로 정보가 너무 적어 너무 새롭게 만들어진 것 같아, 셸 스크립트로 최선을 다해 사용하기로 했습니다.
(커스텀 사용자 이벤트의 사례가 매우 적어 이번에는 수요를 충족시키지 못했다고 느꼈습니다.)
페이스메이커에서 iptables가 떨어질 때 발생하는 익숙한 패턴인 F/O일 수 있습니다.
대기 시스템에서 ssh로 핑을 보내고 약 3개의 노드가 좋지 않다면, F/O가 실제 상황에 더 맞는 것 같습니다.
크론에서 정기적으로 돌리고 싶나요, 아니면 몬에서 돌리고 싶나요?
⇒ 시간이 없고 쉽기 때문에 크론으로 충분합니다.
지금은 핑이니 루트가 아니어도 괜찮아요.
그 뒤에 있는 모든 호스트에서 /home/user-op/.ssh/authorized_keys에 NAT 공개키를 등록하세요.
$ ssh user-op@nfs02 ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) 바이트의 데이터.
8.8.8.8에서 64바이트: icmp_seq=1 ttl=49 time=37.8ms
8.8.8.8에서 64바이트: icmp_seq=2 ttl=49 time=60.2ms
이렇게 확인할 수 있어서 어떤 스크립트를 어떻게 실행할지 고민합니다
·실패하는 스크립트를 어떻게 실행할지 생각해.
완성된 대본↓
mkdir /opt/{bin,log}
vi /opt/bin/chk_backseg_ping.sh
------------------------
#!/빈/쾅
#
# chk_backseg_ping.sh: 사설 세그먼트 내 호스트로부터 핑 검사를 받고, 실패 후 NAT를 위해 F/O 수행
# 의존성: aws 명령어, /etc/hosts
# 업데이트:20131114 - 코미야이 만들기
#
## 변수들
칭호=호게
datetime='/bin/date +%Y/%m/%d.%H:%M:%S'
nochk_time=30
up_time='uptime|grep min|awk '{print $3}'|sed 's/,//g''
mailto=xxxxx@xxxx.net
log=/opt/log/aws_error.log
backseg='172.18.20'
HostGroup='grep $backseg /etc/hosts|egrep -v -a 'vip|sorry|^#'|awk '{print $2}'|perl -pe 's/\n/ /g'''
ssh_chkfile=/home/user-op/.ssh/authorized_keys
dir='echo $(cd $(이름이 $0); pwd''
lockfile=$dir/nat_fo_complete
user=user-op
target1=8.8.8.8
target2=8.8.4.4
target3=yahoo.co.jp
pin_count=4
pin_int=0.5
pin_wait=3
ng_count=3
active_rt=rtb-xxxxxxxx
standby_rt=rtb-yyyy
SubNetId=subnet-zzzzzzzz
## 사용자 정의 함수
nat_failover() {
echo 'date +"%Y-%m-%d %T"' "start replace-route-table-association" >> $log
eval 'AWS EC2 describe-route-tables|grep -A 2 ${subnetid}|egrep '(RouteTableAssociationId| RouteTableId)'|sed -e 's/[", ]//g'|awk -F : '{print $1"="$2}''
만약 [ ${RouteTableId} = ${active_rt} ]
그럼
AWS EC2 replace-route-table-association --route-table-id ${standby_rt} \
--association-id ${RouteTableAssociationId} >> $log 2>&1
result='echo $?'
echo ${result} > ${lockfile}
Failstat="Fail from ${active_rt} to ${standby_rt}, segment:${backseg}, status:${result}"
그렇지 않으면
AWS EC2 replace-route-table-association --route-table-id ${active_rt} \
--association-id ${RouteTableAssociationId} >> $log 2>&1
result='echo $?'
echo ${result} > ${lockfile}
failstat="fail from ${standby_rt} to ${active_rt}, segment:${backseg}, status:${result}"
Fi
}
mail_fail() {
printf "NAT_failover 완료. 사이트를 확인해 주세요.\n ${failstat}" \
|mail -s "(${title}) nat_f/o_${datetime}" ${mailto}
}
## 주요 처리
### 장애 전환 완료 점검
만약 [ -f ${lockfile} ]; 그렇다면
퇴장
그렇지 않으면
:
Fi
## 시작 몇 분 후 체크 무효
만약 [ -n "$up_time" ]; 그렇다면
만약 [ $up_time -lt $nochk_time ]; 그렇다면
퇴장
그렇지 않으면
:
Fi
그렇지 않으면
:
Fi
### SSH 체크
$hostgroup 내 입장을 위해
해야 할
SSH ${user}@${i} ls ${ssh_chkfile}
result='echo $?'
만약 [ $result -eq 0 ]이면;
chkhosts="$chkhosts $i"
Fi
끝났어
### 핑 체크
ng_hosts=0
I in $chkhosts
해야 할
target='printf "$target 1\n$target2\n$target3"|sort -R|head -1'
SSH ${user}@${i} ping -q -c ${pin_count} -i ${pin_int} -W ${pin_wait} ${target} > /dev/null 2>&1
result='echo $?'
만약 [ ${result} -ne 0 ]; 그렇다면
ng_hosts='expr $ng_hosts + 1'
Fi
끝났어
### ng_hosts가 ng_count보다 크면 실패 오버
만약 [ $ng_hosts -ge $ng_count ]
그럼
만약 [ -f ${lockfile} ]; 그렇다면
퇴장
그렇지 않으면
:
Fi
nat_failover
mail_fail
그렇지 않으면
:
Fi
출구 0
------------------------
chmod +x /opt/bin/chk_backseg_ping.sh
보면 이해할 수 있겠지만, 내가 감히 설명한다면,
호스트, 그리고
3개 이상의 호스트에서 핑 결과가 NG라면, NAT02 쪽에서 경로를 다시 연관시킵니다.
SSH 연결 상태를 점검 중입니다.
핑 타겟도 세 명 중에서 무작위로 지정되었으니, 제거되지 않는 한,
타겟에 갈 수 없을 때는 배송하지 않고 글로벌 매장에 갈 수 있습니다. 아마도요.
NAT 자체가 API 서버에 도달하지 못하면 F/O가 실패하지만,
완료 잠금 파일은 생성되어 비정상적인 종료 상태에 들어가므로 재실행되지 않습니다.
정기적으로 중단/재부팅이 반복되는 환경의 경우, NAT를 마지막에 시작하는 등 부팅 순서에 주의를 기울여야 하는 것 같습니다.
NAT가 시작되지 않으면 HA 뒤에 있는 서버는 API와 통신할 수 없습니다.
수표가 몇 분 안에 시작되지 않도록 지점 'a'를 두는 게 더 낫다고 생각했습니다.
・검사 결과
# 타임 배쉬 -x ./chk_backseg_ping.sh
~생략~
+ SSH 사용자 op@nfs01 핑 -q -c 4 -i 0.5 -w 3 yahoo.co.jp
++ 에코 0
+ 결과=0
+ '[' 0 -ne 0 ']''
'$chkhosts'에서 i를 +
++ 헤드 -1
++ 정렬 -R
++ printf '8.8.8.8\n8.8.4.4\nyahoo.co.jp'
+ target=8.8.8.8
+ ssh user-op@nfs02 ping -q -c 4 -i 0.5 -w 3 8.8.8
++ 에코 0
+ 결과=0
+ '[' 0 -ne 0 ']''
+ '[' 0 -ge 3 ']'
+ :
+ 출구 0
실질 0분 19.274초
사용자 0m0.124s
sys 0m0.280s
핑 통신에 문제가 없었기 때문에 장애 조치가 없었던 것 같습니다.
다음으로, nat01의 iptables를 중지하고 전역이 ping되지 않고 f/o가 되지 않도록 하겠습니다.
[root@nat01 ~]# 서비스 iptables 상태
표: 내트
체인 프리라우팅 (정책 ACCEPT)
NUM Target Prot OPT source destination
체인 입력 (정책 ACCEPT)
NUM Target Prot OPT source destination
체인 OUTPUT (정책 ACCEPT)
NUM Target Prot OPT source destination
체인 포스트라우팅 (정책 ACCEPT)
NUM Target Prot OPT source destination
1 마스커레이드 모두 -- 172.18.0.0/16 0.0.0.0/0
[root@nat01 ~]# 서비스 iptables 중단
iptables: 방화벽 규칙 플러싱: [ OK ]
iptables: 체인 설정 ACCEPT: nat [ OK ]
iptables: 모듈 하역 중: [ OK ]
[root@nat01 ~]# 서비스 iptables 상태
iptables: 방화벽이 실행되지 않습니다.
적절한 백 세그먼트의 서버에서 핑을 보낼 때 수행됩니다.
# 타임 배쉬 -x ./chk_backseg_ping.sh
+ title=hoge
++ /bin/date +%Y/%m/%d.%H:%M:%S
+ datetime=2013/11/15.15:34:16
+ mailto=xxxxxxx@xxxx.net
+ log=/opt/log/aws_error.log
+ 백세그=172.18.20
++ awk '{print $2}'
++ perl -pe 's/\n/ /g'
++ egrep -v -a 'vip|sorry|^#'
++ grep 172.18.20 /etc/hosts
+ hostgroup='lvs01 lvs02 cache01 cache02 db01 db02 web01 mov01 nfs01 nfs02 '
+ ssh_chkfile=/home/user-op/.ssh/authorized_keys
++++ dirname ./chk_backseg_ping.sh
+++ CD.
+++ PWD
++ 에코 /opt/bin
+ dir=/opt/bin
+ lockfile = /opt/bin/nat_fo_complete
+ user=user-op
+ target1=8.8.8.8
+ target2=8.8.4.4
+ target3=yahoo.co.jp
+ pin_count=4
+ pin_int=0.5
+ pin_wait=3
+ ng_count=3
+ active_rt=rtb-xxxxxxxx
+ standby_rt=rtb-이이이야
+ subnetid=subnet-zzzzzzzz
+ '[' -f /opt/bin/nat_fo_complete ']''
+ :
'$hostgroup'의 i에 대해 +
+ ssh user-op@lvs01 ls /home/user-op/.ssh/authorized_keys
/home/user-op/.ssh/authorized_keys
++ 에코 0
+ 결과=0
+ '[' 0 -eq 0 ']'
+ chkhosts=' lvs01'
~생략~
'$hostgroup'의 i에 대해 +
+ ssh user-op@nfs02 ls /home/user-op/.ssh/authorized_keys
/home/user-op/.ssh/authorized_keys
++ 에코 0
+ 결과=0
+ '[' 0 -eq 0 ']'
+ chkhosts=' lvs01 lvs02 cache01 cache02 db01 db02 web01 mov01 nfs01 nfs02'
+ ng_hosts=0
'$chkhosts'에서 i를 +
++ 헤드 -1
++ 정렬 -R
++ printf '8.8.8.8\n8.8.4.4\nyahoo.co.jp'
+ target=8.8.4.4
+ SSH user-op@lvs01 ping -q -c 4 -i 0.5 -w 3 8.8.4.4
++ 에코 1
+ 결과=1
+ '[' 1 -ne 0 ']''
++ expr 0 + 1
+ ng_hosts=1
'$chkhosts'에서 i를 +
++ 헤드 -1
++ 정렬 -R
++ printf '8.8.8.8\n8.8.4.4\nyahoo.co.jp'
+ target=yahoo.co.jp
+ ssh user-op@lvs02 ping -q -c 4 -i 0.5 -w 3 yahoo.co.jp
++ 에코 1
+ 결과=1
+ '[' 1 -ne 0 ']''
++ expr 1 + 1
+ ng_hosts=2
~생략~
'$chkhosts'에서 i를 +
++ 헤드 -1
++ 정렬 -R
++ printf '8.8.8.8\n8.8.4.4\nyahoo.co.jp'
+ target=8.8.4.4
+ SSH user-op@nfs02 ping -q -c 4 -i 0.5 -w 3 8.8.4.4
++ 에코 1
+ 결과=1
+ '[' 1 -ne 0 ']''
++ expr 9 + 1
+ ng_hosts=10
+ '[' 10 -ge 3 ']'
+ '[' -f /opt/bin/nat_fo_complete ']''
+ :
+ nat_failover
++ date '+%Y-%m-%d %T'
+ echo 2013-11-15 15:34:50 '시작 replace-route-table-association'
++ egrep '(RouteTableAssociationId| RouteTableId)'
++ sed -e 's/[", ]//g'
++ grep -A 2 subnet-zzzzzzzz
++ awk -F : '{print $1"="$2}'
++ AWS EC2 Describe-Route-Tables
+ 평가 RouteTableAssociationId=rtbassoc-6a212908 RouteTableId=rtb-xxxxxxxx
++ RouteTableAssociationId=rtbassoc-6a212908
++ RouteTableId=rtb-xxxxxxxx
+ '[' RTB-xxxxxxxx = RTB-xxxxxxxx ']'
+ AWS EC2 replace-route-table-association --route-table-id rtb-yyy --association-id RTBASSOC-6A212908
++ 에코 0
+ 결과=0
+ 에코 0
+ failstat='rtb-xxxxxxxx에서 RTB-yyyy로 fail, segment:172.18.20, status:0'
+ mail_fail
+ mail -s '(hoge) nat_f/o_2013/11/15.15:34:16' xxxxxxx@xxxx.net
+ printf '완료NAT_failover. 사이트를 확인해 주세요.\n rtb-xxxxxxxx에서 RTB-YYYYYYYY로 실패, 세그먼트:172.18.20, 상태:0'
+ 출구 0
실물 0m35.361s
사용자 0m1.392s
sys 0m0.456s
페일오버 시 실행 시간은 35초이므로 1분마다 실행해도 괜찮습니다. (호스트가 너무 많으면
백그라운드에서 실행할 때 병렬로 실행할 수 있다는 걸 봤지만, 잘 이해가 안 돼서 걱정하지 않기로 했어요.
(병렬로 실행하는 건 아마 DoS 공격일 거라 생각했는데, 그게 좋지 않을 거라고 생각했어요.) )
로딩이나 실행 시간이 걱정된다면, 모든 호스트가 아니라 여러 무작위로 선택한 호스트를 확인하는 것이 좋을 것 같습니다.
바꿀 수 있다면 이렇게 보일 거예요.
HostGroup='grep $backseg /etc/hosts|egrep -v -a 'vip|sorry|^#'|awk '{print $2}'|perl -pe 's/\n/ /g'''
↓
check_num=6
HostGroup='Grep $backseg /etc/hosts|egrep -v -a 'VIP|Sorry|^#'|awk '{print $2}'|sort -R|head -${check_num}|perl -pe 's/\n/ /g'''
크론 등록을 여러 번 생각하지 않고 잠금 파일을 만들어 두었습니다.
복구 후에는 수동으로 관리해야 합니다.
잠금 파일로 테스트하면 변수가 정의되자마자 종료됩니다.
# 타임 배쉬 -x ./chk_backseg_ping.sh
~생략~
+ pin_wait=3
+ ng_count=3
+ active_rt=rtb-xxxxxxxx
+ standby_rt=rtb-이이이야
+ subnetid=subnet-zzzzzzzz
+ '[' -f /opt/bin/nat_fo_complete ']''
+ 퇴장
실질 0m0.039s
사용자 0m0.000s
sys 0m0.012s
제가 참고한 스크립트는 아래 URL에 나와 있습니다.
중복 NAT 인스턴스를 만들려고 했어요 - log4moto
개인적으로는 yahoo.co.jp 에 핑을 많이 받을 수 있을지 조금 걱정됩니다.
8.~ 구글인 것 같으니 괜찮게 할게.
이런 식의 기능이 있는 것 같아요↓. JP 대신 야후에 핑을 시도해보자는 의견도 있어요.
핑 확인 사이트 (시험 운영) - 학술 정보 네트워크 (SINET4, SINET4) · 당분간 2분마다 크론 등록 (대기 기계)
# 크론탭 -에
# 크론탭 -l
## NAT 점검 및 장애 전환 스크립트
*/2 * * * * /opt/bin/chk_backseg_ping.sh
나중에 수정된 부분이 있어서 추가하겠습니다.
# diff chk_backseg_ping.sh old/chk_backseg_ping.sh.20140210
31d30
< current_ids=$dir/current_ids
36,41c35
> aws ec2 describe-route-tables|grep -A 2 ${subnetid}|egrep '(RouteTableAssociationId| RouteTableId)'|sed -e 's/[", ]//g'|awk -F : '{print $1"="$2}' > $current_ids
> 출처 $current_ids
> [ -z "${RouteTableAssociationId}" ]; 그럼
> printf "RouteTableAssociationId와 RouteTableId의 값을 설정하는 데 실패했습니다.. \n Nat-장애 조치가 시작되지 않았습니다. 아마도 aws-api-server에 접근할 수 없을 것입니다."| tee -a ${log}|mail -s "(${title}) nat_f/o_${datetime}" ${mailto}
> 출구
< fi
---
> eval 'AWS EC2 describe-route-tables|grep -A 2 ${subnetid}|egrep '(RouteTableAssociationId| RouteTableId)'|sed -e 's/[", ]//g'|awk -F : '{print $1"="$2}''
위 내용을 시청해 주셔서 감사합니다.