[AWS] High Available cho Bastion Host

 

Chào mọi người, lâu rồi mới có time viết bài lại, bữa giờ loay hoay với gia đình và các dự định cá nhân nên cũng không care cái blog (bữa giờ nó update tè le ko để ý luôn với lại lười viết voãi… chắc chuyển qua là vlog cho nhanh quá =))), à mà bữa nay mình muốn giới thiệu đến các bạn một tuts mới đó là làm thế nào để tăng High Available cho Bastion Host.

 

I. Bastion host là gì?

 

Khái niệm này có thể các bạn đã nghe qua ít nhất là một lần rồi đúng không? Hiểu đơn giản thì nó là một SSH proxy cũng được, trong môi trường product của các bạn trên AWS, không phải instances nào bạn cũng gán Elastic IP để SSH đúng không nào, ví dụ vài ba instances thì chuối lắm cho làm như vậy đi, nhưng với một system lớn hơn, 20 – 50 – 100… instances thì đó là một vấn đề khác, bastion host ra đời nhầm giúp bạn nhiệm vụ trung gian để có thể SSH đến tất cả các instances, kể khả instance trong subnet public hay private.

Hôm nay mình cũng không nói quá sâu về khái niệm này cũng như cách để step by step tạo ra nó, mình muốn cùng thảo luận về tính sẵn sàng cao cho bastion host này, nếu chỉ đơn giản dùng một instances để làm bastion host thì khi disaster do thiên tai, do vật lý, do human … thì làm sao bạn SSH vào được các instances bên trong môi trường của bạn? Cùng mình khám phá 2 cách sau nhé.

P/s: Bài lab sẽ tốn tiền, hãy chắc rằng bạn dư tiền thì hãy practice nhé =))

 

II. Chuẩn bị môi trường

 

Mình giả định phần tạo VPC và subnet, Nat-Gateway… này nọ đã xong nha, có time mình viết tuts tạo sau, giả định bạn có một VPC với 2 phần:

Mỗi phần sẽ có 2 subnet riêng và chúng có AZ riêng.

 

VPC network: 10.20.0.0/16

Name Subnet IP
public-zone-a 10.20.1.0/24
public-zone-b 10.20.3.0/24
private-zone-a 10.20.2.0/24
private-zone-b 10.20.4.0/24

 

nó sẽ hao hao giống với Diagram sau:

Với route cho public subnet mình cấu hình internet gateway để internet trực tiếp đi vào được.

Với route cho private subnet thì mình chỉ cấu hinh Nat Gateway để instance bên trong đi theo chiều outgoing, nhầm mục đích install package hoặc update nếu cầu thiết.

Tất nhiên, Bastion host nằm trên public subnet rồi !!!

 

III. Cách 1: Cấu hình Bastion host với Network Load Balance

 

Với cách này bạn cần 2 instance để làm bastion host, bạn tạo trước instance nhu sau:

Chọn IAM
Chọn instance type – quất cái t2.micro cho free 720h/month :))
Chọn public subnet
Tạo EBS – bastion host không có nhiệm vụ nào ngoài ssh proxy nến chỉ cần defaul 8GB là được
Review lại Security group mình vừa tạo, chỉ allow những thứ cần allow thôi nhé!
Review và Launch
Tạo ssh key pair nếu chưa có, nếu có rồi thì chọn exist

instance thứ 2 tạo tương tụ nhưng nhớ phải khác public subnet nhé.

2 instance vừa khởi tạo và khác subnet

Tiếp tục vào Menu >> EC2 >> Load Balancers >> Create Load Balancer

Chọn Network Load Balancer type

input tên, schema chọn internet-facing để chiều ingoing đi vào được

Chọn đúng VPC mình tạo trước đó, Mapping chọn vào 2 subnet public

Tới phần Listener and routing, chọn TCP port 22, nếu chưa có target group thì bạn phải tạo đã nhé.

trong phần tạo target group bạn chọn như hình, target type chọn instance, protocol port TCP 22, chọn đúng VPC. Các phần khác để mặc định >> Next

Khi đến giao điện Register Target, bạn chọn đúng 2 bastion hosts vừa tạo ở bước prepare.

Kết quả như hình là được

Quay lại bước tạo Network Load Balance >> nhấn vào icon refresh sẽ thấy cập nhật target group mới tạo.

Giờ thì click để tạo thôi, kết quả như hình là success

Quay lại giao diện ELB >> Bạn sẽ thấy state đang là provision tức là đang cấp phát, đợi một chút để nó active lên nhé, đâu đó tầm 3-5p gì đó mình không nhớ rõ nhưng phải kiên nhẫn đấy :))

Khi đã active rồi, bạn vào ELB đã tạo này để lấy DNS nó sinh ra, rồi thử telnet và SSH thử nhé, chú ý là ở phần tạo instance mình đã add Security group rồi nên mới SSH được đó nhé, nếu chưa có thì bạn phải add vào bastion host.

Bạn chú ý cái IP private trong hình, bây giờ mình thử stop một bastion host đi, theo lý thuyết nó vẫn sẽ phải work được vì đã có HA ở đây.

Đấy, ELB detect health check fail trên con bastion-1 rồi, thử telnet và ssh lại nha…

Toẹt vời, work như mình expect. Thời gian để nó tái cân bằng tải tầm ~2p, lẽ ra nó phải nhanh hơn mới đúng, mình chưa có time để check lại, nhưng case đặt ra ban đầu đã có solution rồi nhen, so ra 2p chờ để SSH vào instance cũng đỡ hơn là đợi DR (Disaster Recovery) nhỉ 😐

IV. Cách 2: Cấu hình với Scaling Group

Đây là giải pháp tiết kiệm hơn so với cách trên, chỉ cần một instance thôi, khi instance gặp issue (stop, health check fail…), autoscaling group sẽ tạo ra một instance mới với AZ khác để thay thế, đảm bảo vẫn có tính HA, tuy nhiên time khởi tạo lại instance mình check thấy lâu hơn so với cách 1, cũng là một điều để bạn suy ngẫm …

Cách cấu hình như sau, trước tiên bạn tạo 1 bastion instance thôi, only one thôi nhaaa!!

Tiếp đến mình cần tạo một role để apply vào template để nó có quyền chạy một vài lệnh mà xíu nữa bạn sẽ biết, cách tạo role như sau:

trên menu >> Identify and Access Management (IAM) >> Roles >> Create Role

Tiếp đến chọn như trong hình

Tại Attach Permissions policies >> search EC2, chọn AmazonEC2FullAccess >> Next

Next luôn =))

Nhập Roles name >> Create role

Vậy là xong phần tạo role, tiếp đến là tạo template để auto scaling dùng khi khởi tạo một instance

Menu >> EC2 >> Launch Configurations >> Create launch configuration

Nhập launch configuration name.

Tại AMI bạn có thể vào lại instances >> chọn bastion host >> xem trong Detail sẽ có thông tin về AMI này

Chọn instance type

Additional configuration >> IAM instance profile >> Chọn role khi nãy mình vừa tạo

IAM instance profile chọn role khi nãy đã tạo

Kéo xuống tiếp, phần monitoring bạn có thể tick vào nếu muốn monitor với cloudwatch.

Cái hấp dẫn đây rồi, trong user data bạn phải thêm vào một script sau, để đảm bảo khi tạo instance, nó phải lấy Elastic IP từ instance cũ gán vào instance mới, hợp lý đúng không nào, mình share đoạn script bên dưới, bạn copy vào nhé. Và phải có role khi nãy mình tạo thì script này mới work được, đó là lý do vì sao mình mention đến khi nãy.

Chú ý rằng variable ALLOC_ID=eipalloc-xxxxxxxxxxx trong script bạn phải sửa lại tương ứng với IP public của riêng bạn, để lấy biến này bạn vào EC2 >> Elastic IPs >> Chọn trực tiếp IP >> kéo xuống phần detail sumary sẽ thấy Allocation ID >> bạn copy nó và replace vào trong script này.

Đồng thời sửa luôn cái biến region AWS_DEFAULT_REGION cho đúng với region bạn đang làm nhé.

#!/bin/bash

INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
MAXWAIT=3
ALLOC_ID=eipalloc-xxxxxxxxxxx
AWS_DEFAULT_REGION=us-east-1

# Make sure the EIP is free
echo "Checking if EIP with ALLOC_ID[$ALLOC_ID] is free...."
ISFREE=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --query Addresses[].InstanceId --output text --region $AWS_DEFAULT_REGION)
STARTWAIT=$(date +%s)
while [ ! -z "$ISFREE" ]; do
    if [ "$(($(date +%s) - $STARTWAIT))" -gt $MAXWAIT ]; then
        echo "WARNING: We waited 30 seconds, we're forcing it now."
        ISFREE=""
    else
        echo "Waiting for EIP with ALLOC_ID[$ALLOC_ID] to become free...."
        sleep 3
        ISFREE=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --query Addresses[].InstanceId --output text --region $AWS_DEFAULT_REGION)
    fi
done

# Now we can associate the address
echo Running: aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --allow-reassociation --region $AWS_DEFAULT_REGION
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --allow-reassociation --region $AWS_DEFAULT_REGION

Tại Bước IP address type Bạn chọn giúp mình là “Assign a public IP address to every instance” nhé, sorry mình capture cái hình này lúc chưa select ^^

Bước cuối bạn update lại security group và key pair

Sau khi tao xong tempate mình sẽ tạo auto scaling group.

Step 1 choose launch template or configuration >> điền tên của auto scaling group

tại Launch template >> switch đến launch template >> chọn template vừa tạo khi nãy

Step 2 Configure setting >> network bạn chọn VPC tương ứng, chọn tiếp vào 2 public subnet để việc tạo instance sau này sẽ được tạo với một trong 2 vùng public subnet ấy.

Step 3 Configure advance options >> không chọn load balance nào hết vì mình chỉ muốn dung cho 1 bastion host >> time để health check tùy bạn cấu hình, đây là lab nên mình để 60s cho nhanh.

Step 4 Configure group size and scaling policies >> group size mình để tất cả là 1, tức là default chỉ tạo ra 1 instance để thay thế nếu bastion host cũ bị fail >> Scaling policies mình để None.

Step 5 Add notifications >> mình để mặc định và bỏ qua, cũng không cần thiết lắm trong bài lab này.

Step 6 Add Tags >> các bạn có thể add giá trị Name: <tên bastion host> cũng được, để nó define name khi tạo instance thôi chứ không có gì.

Step 7 Reviews >> bạn review lại toàn bộ các config của mình rồi bấm vào Create auto scaling group

Quay lại giao diện Auto Scaling Group >> activity >> bạn sẽ thấy nó khởi tạo một instance mới. Giờ bạn xóa cái instance gốc đi, dung instance được tạo ra bởi auto scaling group này.

Bạn cũng có thể test lại bằng cách stop instance này đi, và xem thử action của nó trong Activity như thế nào.

instance cũ bị terminal, instance mới được tạo và Elastic IP sẽ associate tới instance mới.

Vậy là phần lab đến đây coi như hoàn tất.

V. Tổng kết & ứng dụng

Qua bài tuts này cũng hy vọng giúp bạn đánh giá ưu nhược điểm của 2 cách cũng như ứng dụng trong môi trường của bạn, nội dụng bài viết mang tính chất tham khảo chứ mình thấy xài cái Bastion này chuối muốn chớt =))

Mình dùng VPN có phải tiện hơn nhiều không, triển khai cũng không quá khó, mình có một bài viết hướng dẫn rồi đó, có thể xem lại tại đây, ý kiến cá nhân thôi và cám ơn mọi người đã theo dõi bài hướng dẫn High Available cho Bastion Host ^^ !!