• 구성 환경
    • AWS - EC2 - t2.medium & AZ Split
    • AMI - Amazon Linux2
    • Bare-Metal
  • 구성 목적
    • AWS - Nginx Plus HA ( With EIP / HA )

  • NGINX HA Bare-Metal vs AWS

    • Bare-Metal
      • VIP 와 RealIP 와 같은 대역 이용
    • AWS
      • VIP 를 EIP 로 사용
      • Routing 에 대해 사전 설정 필요 ( 양 노드간 통신 가능해야함 )
  • AWS - NGINX HA 구성 간 제약사항

    • EIP 를 Instance 에 Mapping 시킴
    • ENI 가 2개 이상이면 사용 불가
      • 별도의 Script 수정시, ENI 지정하여 EIP Mapping 가능
  • OS 환경 구성 - Package 설치

yum -y install wget keepalived
  • OS 환경 구성 - Hostname 등록
vi /etc/hosts
192.168.0.150 ip-192-168-0-150.ap-northeast-1.compute.internal
192.168.0.200 ip-192-168-0-200.ap-northeast-1.compute.internal
  • Keepalived 용 Script Download
## GIT URL : <https://github.com/nginxinc/aws-ha-elastic-ip>
wget <https://github.com/nginxinc/aws-ha-elastic-ip/archive/refs/heads/master.zip>
unzip master.zip
cd aws-ha-elastic-ip-master
cp nginx-ha-check nginx-ha-notify /usr/libexec/keepalived

  • Keepalived 구성
    • vi /etc/keepalived/keepalived.conf
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org
vrrp_script chk_nginx_service {
script "/usr/libexec/keepalived/nginx-ha-check"
#script "<path-to-health-check-script>"
interval 3
weight 50
}
vrrp_instance VI_1 {
interface eth0
priority 101  ## 100 : Backup / 101 : Master
virtual_router_id 51
advert_int 1
unicast_src_ip 10.10.10.10  ## 자기자신 IP
unicast_peer {
10.10.10.40 ## 상대방 IP
}
authentication {
auth_type PASS
auth_pass <password>
}
track_script {
chk_nginx_service
}
notify "/usr/libexec/keepalived/nginx-ha-notify"
#notify "<path-to-notify-script>"
}
  • Check Script
    • vi /usr/libexec/keepalived/nginx-ha-notify
    • 필요 정보
      • AWS_Access_key_ID / AWS_Secret_access_key / AWS_default_region HA_Node 지정 : hostname / Allocation_ID : EIP 할당 ID 기입
      • instance-data > 169.254.169.254 로 수정 필요

#!/bin/bash
#############--USER DEFINED VARIABLES SET HERE--##############
#Set the AWS credentials here if you didn't create an IAM instance profile
export AWS_ACCESS_KEY_ID=################################
export AWS_SECRET_ACCESS_KEY=#######################################

#Set the AWS default region
export AWS_DEFAULT_REGION=ap-northeast-1
#Set the internal or private DNS names of the HA nodes here
HA_NODE_1=ip-10-10-10-10.ap-northeast-2.compute.internal
HA_NODE_2=ip-10-10-10.40.ap-northeast-2.compute.internal
#Set the ElasticIP ID Value here
ALLOCATION_ID=eipalloc-00ec3ce42a6783693
###############################################################
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
#Values passed in from keepalived
TYPE=$1
NAME=$2
STATE=$3
#Determine the internal or private dns name of the instance
LOCAL_INTERNAL_DNS_NAME=`wget -q -O - <http://instance-data/latest/meta-data/local-hostname`>
LOCAL_INTERNAL_DNS_NAME=`echo $LOCAL_INTERNAL_DNS_NAME | sed -e 's/% //g'`
#OTHER_INSTANCE_DNS_NAME is the other node than this one, default assignment is HA_NODE_1
OTHER_INSTANCE_DNS_NAME=$HA_NODE_1
#Use LOCAL_INTERNAL_DNS_NAME to determine which node this is and to set the Other Node name
if [ "$HA_NODE_1" = "$LOCAL_INTERNAL_DNS_NAME" ]
then
OTHER_INSTANCE_DNS_NAME=$HA_NODE_2
fi
#Get the local instance ID
INSTANCE_ID=`wget -q -O - http://**instance-data**/latest/meta-data/instance-id`
INSTANCE_ID=`echo $INSTANCE_ID | sed -e 's/% //g'`
#Get the instance ID of the other node
OTHER_INSTANCE_ID=`aws ec2 describe-instances --filter "Name=private-dns-name,Values=$OTHER_INSTANCE_DNS_NAME" | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Reservations"][0]["Instances"][0]["InstanceId"]'`
#Get the ASSOCIATION_ID of the ElasticIP to the Instance
ASSOCIATION_ID=`aws ec2 describe-addresses --allocation-id $ALLOCATION_ID | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Addresses"][0]["AssociationId"]'`
#Get the INSTANCE_ID of the system the ElasticIP is associated with
EIP_INSTANCE=`aws ec2 describe-addresses --allocation-id $ALLOCATION_ID | /usr/bin/python -c 'import json,sys;obj=json.load(sys.stdin); print obj["Addresses"][0]["InstanceId"]'`
STATEFILE=/var/run/nginx-ha-keepalived.state
logger -t nginx-ha-keepalived "Params and Values: TYPE=$TYPE -- NAME=$NAME -- STATE=$STATE -- ALLOCATION_ID=$ALLOCATION_ID -- INSTANCE_ID=$INSTANCE_ID -- OTHER_INSTANCE_ID=$OTHER_INSTANCE_ID -- EIP_INSTANCE=$EIP_INSTANCE -- ASSOCIATION_ID=$ASSOCIATION_ID -- STATEFILE=$STATEFILE"
logger -t nginx-ha-keepalived "Transition to state '$STATE' on VRRP instance '$NAME'."
case $STATE in
"MASTER")
aws ec2 disassociate-address --association-id $ASSOCIATION_ID
aws ec2 associate-address --allocation-id $ALLOCATION_ID --instance-id $INSTANCE_ID
service nginx start ||:
echo "STATE=$STATE" > $STATEFILE
exit 0
;;
"BACKUP"|"FAULT")
if [ "$INSTANCE_ID" = "$EIP_INSTANCE" ]
then
aws ec2 disassociate-address --association-id $ASSOCIATION_ID
aws ec2 associate-address --allocation-id $ALLOCATION_ID --instance-id $OTHER_INSTANCE_ID
logger -t nginx-ha-keepalived "BACKUP Path Transfer from $INSTANCE_ID to $OTHER_INSTANCE_ID"
fi
echo "STATE=$STATE" > $STATEFILE
exit 0
;;
*)        logger -t nginx-ha-keepalived "Unknown state: '$STATE'"
exit 1
;;
esac
  • Keepalived Process 기동
systemctl start keepalived.service
sleep 1
systemctl status keepalived.service
  • Node 확인
cat /var/run/nginx-ha-keepalived.state
  • 서비스 구동 확인
    • CURL EIP