DEV Community

Cover image for มาลองสร้างระบบ Failover แบบ Multi-Region กับ Amazon EKS (แบบ Step-by-step)
Mongkol Thongkraikaew
Mongkol Thongkraikaew

Posted on

มาลองสร้างระบบ Failover แบบ Multi-Region กับ Amazon EKS (แบบ Step-by-step)

มีใครได้ลองคิดหรือเตรียมตัวเผื่อไว้หรือยังหาก Region ที่เราใช้งานอยู่ ล่มไปในช่วงเวลาที่มีผู้ใช้งานระบบเราอยู่จำนวนมาก เราจะทำอย่างไร?

ช่วงนี้หลายคนน่าจะได้เห็นข่าวหรือเจอเหตุการณ์ AWS ในบาง Region เกิดปัญหาจนระบบต่าง ๆ ใช้งานไม่ได้ ซึ่งเป็นอีกหนึ่ง Reminder ว่าระบบที่เราทำงานอยู่จะมองข้ามเรื่อง Availability หรือการเตรียมพร้อมรับมือกับปัญหาลักษณะแบบนี้ไม่ได้เลย

ในบทความนี้ ผมจะพามาลองตั้งค่าระบบ Failover แบบ Multi-Region กับ Amazon EKS แบบ Step-by-step ให้เห็นกันชัด ๆ ว่าทำอย่างไร เหมาะสำหรับเอาไปปรับใช้กับระบบงานที่ทุกคนใช้กันอยู่ได้ เพื่อเพิ่ม resiliency ให้กับระบบของเรามากขึ้น

เครื่องมือที่จำเป็นสำหรับ workshop นี้

  • AWS Account
  • Route 53 (Public Hosted Zone)
  • AWS CloudShell
  • CLI ที่ต้องใช้: aws, envsubst, eksctl, kubectl, kubectx, kubens

เมื่อพร้อมแล้ว มาลองลงมือสร้างระบบไปพร้อม ๆ กันได้เลยครับ ทุกคนสามารถรันคำสั่งตามขั้นตอนที่ผมโชว์ไว้ได้ทันที

Diagram Workshop

ขั้นตอนที่ 1 : ติดตั้งและตั้งค่า EKS Cluster

1.1 เปิด CloudShell ขึ้นมาก่อน
***ในบทความนี้ ผมจะรันทุกคำสั่งจาก CloudShell ที่ Region: Singapore เท่านั้น เนื่องจากตอนนี้ CloudShell ยังไม่มีให้บริการที่ Region: Thailand

1.2 ตั้งค่าพื้นฐานและติดตั้งเครื่องมือที่ต้องใช้งาน

export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export Region1=ap-southeast-7
export Region2=ap-southeast-1
export Region1ClusterName=eks-cluster-th
export Region2ClusterName=eks-cluster-sg
export ALBName=web-alb

# เปลี่ยนตาม domain ของแต่ละคน
export apphostname=web-demo.cloudation101.net
export HostedZoneName=cloudation101.net
export HostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name $HostedZoneName --query 'HostedZones[0].Id' --output text |  cut -d'/' -f3)

# Install envsubst cli 
sudo yum install gettext -y 

# Install eksctl
ARCH=amd64
PLATFORM=$(uname -s)_$ARCH
curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
sudo install -m 0755 /tmp/eksctl /usr/local/bin && rm /tmp/eksctl

# Install kubectx, kubens cli
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
Enter fullscreen mode Exit fullscreen mode

1.3 สร้าง EKS Cluster ในทั้ง 2 Region
ดำเนินการสร้าง EKS Cluster ใน Region หลักและ Region สำรอง เตรียมพร้อมสำหรับการทำ Multi-Region

# Create EKS cluster auto mode in Region: Thailand
eksctl create cluster --name=$Region1ClusterName --enable-auto-mode --region=$Region1

# Create EKS cluster auto mode in Region: Singapore
eksctl create cluster --name=$Region2ClusterName --enable-auto-mode --region=$Region2

# Validate cluster status (Status: Active)
aws eks describe-cluster \--name $Region1ClusterName \--region $Region1 \--output json \--query 'cluster.status'

aws eks describe-cluster \--name $Region2ClusterName \--region $Region2 \--output json \--query 'cluster.status'

# รอประมาณ 15 นาทีในการสร้างแต่ละ cluster
Enter fullscreen mode Exit fullscreen mode



เมื่อ EKS Cluster สร้างแล้ว เราจะพบว่ามี EKS Cluster ถูกสร้างขึ้นในแต่ละ Region

Region: Thailand
EKS Cluster Region: Thailand
Region: Sigapore
EKS Cluster Region: Singapore



1.4 ทดสอบเชื่อมต่อกับ EKS Cluster ด้วย kubectl

kubectx $(kubectx | grep "eks-cluster-th")
kubectl get node

kubectx $(kubectx | grep "eks-cluster-sg")
kubectl get node 
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผลลัพธ์การทดสอบเรียก EKS API
Kubectl get node result

ขั้นตอนที่ 2 : Deploy Web Application

2.1 สร้าง IngressClass alb

# Config ingressclassconfiguration for Thailand
kubectx $(kubectx | grep "eks-cluster-th")
curl -s https://raw.githubusercontent.com/aws-samples/multi-region-ingress/refs/heads/main/ingressclassconfiguration.yaml | kubectl apply -f -
kubectl get ingressclass,ingressclassparams

# Config ingressclassconfiguration for Singapore
kubectx $(kubectx | grep "eks-cluster-sg")
curl -s https://raw.githubusercontent.com/aws-samples/multi-region-ingress/refs/heads/main/ingressclassconfiguration.yaml | kubectl apply -f -
kubectl get ingressclass,ingressclassparams
Enter fullscreen mode Exit fullscreen mode

2.2 สร้าง ServiceAccount, Clusterrole, Service และ Deploy Web App Demo
Deploy Web App @ Region: Thailand

# Switch EKS cluster
kubectx $(kubectx | grep "eks-cluster-th")

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: webapp-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: webapp-clusterrole
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: webapp-clusterrolebinding
subjects:
  - kind: ServiceAccount
    name: webapp-sa
    namespace: default
roleRef:
  kind: ClusterRole
  name: webapp-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      serviceAccountName: webapp-sa
      containers:
      - image: dumlutimuralp/demoapp
        name: webapp
        env:
        - name: APP_NAME
          value: "WebApp_Demo_TH"
        - name: BG_COLOR
          value: "green" 
        - name: HEALTH
          value: "webapphealth"  
        - name: MY_NODENAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
---
apiVersion: v1
kind: Service
metadata:
  name: webappservice
spec:
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 80
EOF
Enter fullscreen mode Exit fullscreen mode

Deploy Web App @ Region: Singapore

# Switch EKS cluster
kubectx $(kubectx | grep "eks-cluster-sg")

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: webapp-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: webapp-clusterrole
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: webapp-clusterrolebinding
subjects:
  - kind: ServiceAccount
    name: webapp-sa
    namespace: default
roleRef:
  kind: ClusterRole
  name: webapp-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      serviceAccountName: webapp-sa
      containers:
      - image: dumlutimuralp/demoapp
        name: webapp
        env:
        - name: APP_NAME
          value: "WebApp_Demo_SG"
        - name: BG_COLOR
          value: "red" 
        - name: HEALTH
          value: "webapphealth"  
        - name: MY_NODENAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
---
apiVersion: v1
kind: Service
metadata:
  name: webappservice
spec:
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 80
EOF
Enter fullscreen mode Exit fullscreen mode

2.3 สร้าง Ingress สำหรับ Web App ทั้ง Thailand และ Singapore Region

# Switch EKS cluster to Thailand
kubectx $(kubectx | grep "eks-cluster-th")

cat <<EOF | envsubst | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webapp-ingress 
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: $ALBName
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb 
  rules:
  - host: $apphostname
    http:
      paths:
      - path: / 
        pathType: Prefix
        backend:
          service:
            name: webappservice 
            port:
               number: 80 
  - http:
      paths:
      - path: /webapphealth
        pathType: Prefix
        backend:
          service:
            name: webappservice
            port:
               number: 80 
EOF

# Switch EKS cluster to Singapore
kubectx $(kubectx | grep "eks-cluster-sg")

cat <<EOF | envsubst | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webapp-ingress 
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: $ALBName
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb 
  rules:
  - host: $apphostname
    http:
      paths:
      - path: / 
        pathType: Prefix
        backend:
          service:
            name: webappservice 
            port:
               number: 80 
  - http:
      paths:
      - path: /webapphealth
        pathType: Prefix
        backend:
          service:
            name: webappservice
            port:
               number: 80 
EOF
Enter fullscreen mode Exit fullscreen mode

2.4 ตรวจสอบ Resource ที่ถูกสร้างในทั้ง 2 Region ขั้นตอนนี้ เราควรจะเห็น resource อย่างเช่น Deployment และ Ingress ถูกสร้างขึ้นครบถ้วนทั้ง 2 Region

kubectx $(kubectx | grep "eks-cluster-th")
kubectl get all,ingress

kubectx $(kubectx | grep "eks-cluster-sg")
kubectl get all,ingress
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผลลัพธ์ Kubernetes resource
kubectl get all,ingress result
ทดสอบเข้าถึง website ทั้งสอง region ด้วย ALB domain
Region: Thailand (สีเขียว)
Example website of thailand region
Region: Singapore (สีแดง)
Example website of singapore region

ขั้นตอนที่ 3 : ตั้งค่า Route 53 Health Check และ Record

3.1 ตั้งค่า Health Check เพื่อคอยตรวจสอบสถานะ web application ในทั้ง 2 Region ว่ายังทำงานปกติหรือไม่

# Find ALB Domain
export Region1ALB=$(aws elbv2 describe-load-balancers --region $Region1 --query "LoadBalancers[?contains(LoadBalancerName, '$ALBName')].DNSName | [0]" --output text)
export Region2ALB=$(aws elbv2 describe-load-balancers --region $Region2 --query "LoadBalancers[?contains(LoadBalancerName, '$ALBName')].DNSName | [0]" --output text)

# Create Route 53 health check for Thailand region
aws route53 create-health-check --caller-reference "RegionTH-WebApp-$(date +%s)" \
--health-check-config "{\"Port\":80,\"Type\":\"HTTP\",\"ResourcePath\":\"/webapphealth\",\"FullyQualifiedDomainName\":\"$Region1ALB\",\"RequestInterval\":10,\"FailureThreshold\":2,\"MeasureLatency\":true,\"Inverted\":false,\"Disabled\":false,\"EnableSNI\":false}"

# Create Route 53 health check for Singapore region
aws route53 create-health-check --caller-reference "RegionSG-WebApp-$(date +%s)" \
--health-check-config "{\"Port\":80,\"Type\":\"HTTP\",\"ResourcePath\":\"/webapphealth\",\"FullyQualifiedDomainName\":\"$Region2ALB\",\"RequestInterval\":10,\"FailureThreshold\":2,\"MeasureLatency\":true,\"Inverted\":false,\"Disabled\":false,\"EnableSNI\":false}"
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผลลัพธ์การสร้าง Route 53 Health Check

3.2 สร้าง Route 53 Alias Record ซึ่งเราจะสร้าง 2 Alias record สำหรับ domain: web-demo.cloudation101.net ไปยัง ALB ของทั้ง 2 region และผมจะทำการ associate แต่ละ record ด้วย healthcheck ที่ถูกสร้างขึ้นก่อนหน้านี้

# Find Health Check ID
export HealthCheckRegion1AppId=$(aws route53 list-health-checks \
  --query "HealthChecks[?HealthCheckConfig.FullyQualifiedDomainName=='$Region1ALB' && HealthCheckConfig.ResourcePath=='/webapphealth'] | [0].Id" \
  --output text)

export HealthCheckRegion2AppId=$(aws route53 list-health-checks \
  --query "HealthChecks[?HealthCheckConfig.FullyQualifiedDomainName=='$Region2ALB' && HealthCheckConfig.ResourcePath=='/webapphealth'] | [0].Id" \
  --output text)

# Find Hosted Zone ID of your domain
export Region1ALBHostedZoneId=$(aws elbv2 describe-load-balancers --region $Region1 --query "LoadBalancers[?DNSName=='$Region1ALB'].CanonicalHostedZoneId" --output text)
export Region2ALBHostedZoneId=$(aws elbv2 describe-load-balancers --region $Region2 --query "LoadBalancers[?DNSName=='$Region2ALB'].CanonicalHostedZoneId" --output text)

# Create the alias record for ALB's Thailand
aws route53 change-resource-record-sets --hosted-zone-id $HostedZoneId \
  --change-batch "{\"Changes\":[{\"Action\":\"CREATE\",\"ResourceRecordSet\":{\"Name\":\"$apphostname\",\"Type\":\"A\",\"SetIdentifier\":\"Region1-Primary\",\"Weight\":100,\"HealthCheckId\":\"$HealthCheckRegion1AppId\",\"AliasTarget\":{\"HostedZoneId\":\"$Region1ALBHostedZoneId\",\"DNSName\":\"$Region1ALB\",\"EvaluateTargetHealth\":false}}}]}"

# Create the alias record for ALB's Singapore
aws route53 change-resource-record-sets --hosted-zone-id $HostedZoneId \
  --change-batch "{\"Changes\":[{\"Action\":\"CREATE\",\"ResourceRecordSet\":{\"Name\":\"$apphostname\",\"Type\":\"A\",\"SetIdentifier\":\"Region2-Secondary\",\"Weight\":0,\"HealthCheckId\":\"$HealthCheckRegion2AppId\",\"AliasTarget\":{\"HostedZoneId\":\"$Region2ALBHostedZoneId\",\"DNSName\":\"$Region2ALB\",\"EvaluateTargetHealth\":false}}}]}"

Enter fullscreen mode Exit fullscreen mode

หมายเหตุ:
ผมเลือกใช้ Routing Policy แบบ Weighted เพื่อกำหนดให้ Route 53 ตอบ ALB IP จาก Region: Thailand เป็นลำดับแรกเสมอ ตราบใดที่ Health Check ของ web app ในทั้ง 2 region ยัง healthty ทุกตัว

ตรวจสอบว่า DNS Record ถูกสร้างใน Hosted Zone ตามที่ต้องการแล้วหรือยัง

aws route53 list-resource-record-sets --hosted-zone-id $HostedZoneId --query "ResourceRecordSets[?Name=='$apphostname.']"
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผลลัพธ์

หากทำการสร้าง Route 53 record เรียบร้อยแล้ว เราสามารถทดสอบเข้าใช้งาน website ผ่าน URL ที่เรากำหนดได้เลย (ตัวอย่าง http://web-demo.cloudation101.net)

ขั้นตอนที่ 4 : Test application failure

ในขั้นตอนนี้ เราจะจำลองสถานการณ์ที่ web application ใน Region: Thailand มีปัญหา

4.1 Scale down web application ในฝั่ง Thailand region

kubectx $(kubectx | grep "eks-cluster-th")
kubectl scale deployment webapp --replicas=0
Enter fullscreen mode Exit fullscreen mode

หลังจากที่เราทำการ scale down (ลดจำนวน pod) ของ web application ใน Region: Thailand แล้ว จะเห็นได้ว่า Health Check ของ Route 53 สำหรับฝั่งนี้จะเปลี่ยนสถานะเป็น Unhealthy ทันที

เมื่อเราทดสอบเข้าเว็บไซต์ผ่าน URL เดิมอีกครั้ง ระบบ Route 53 จะเปลี่ยนเส้นทางการเข้าถึงไปยัง web application ในฝั่ง Singapore region ให้โดยอัตโนมัติ

หมายเหตุ:
ความเร็วในการเปลี่ยนเส้นทาง (redirect) ผู้ใช้ไปยัง Singapore region จะขึ้นอยู่กับหลายปัจจัย เช่น เงื่อนไขของ Health Check ที่ตั้งไว้, ค่า DNS TTL ของฝั่ง client, รวมถึงการตั้งค่า ALB และค่า HTTP Keepalive ของ ALB ด้วย

ขั้นตอนที่ 5 : Clean up Environment

5.1 Delete Route53 Alias Record

aws route53 change-resource-record-sets --hosted-zone-id $HostedZoneId \
  --change-batch "{\"Changes\":[{\"Action\":\"DELETE\",\"ResourceRecordSet\":{\"Name\":\"$apphostname\",\"Type\":\"A\",\"SetIdentifier\":\"Region1-Primary\",\"Weight\":100,\"HealthCheckId\":\"$HealthCheckRegion1AppId\",\"AliasTarget\":{\"HostedZoneId\":\"$Region1ALBHostedZoneId\",\"DNSName\":\"$Region1ALB\",\"EvaluateTargetHealth\":false}}}]}"

aws route53 change-resource-record-sets --hosted-zone-id $HostedZoneId \
  --change-batch "{\"Changes\":[{\"Action\":\"DELETE\",\"ResourceRecordSet\":{\"Name\":\"$apphostname\",\"Type\":\"A\",\"SetIdentifier\":\"Region2-Secondary\",\"Weight\":0,\"HealthCheckId\":\"$HealthCheckRegion2AppId\",\"AliasTarget\":{\"HostedZoneId\":\"$Region2ALBHostedZoneId\",\"DNSName\":\"$Region2ALB\",\"EvaluateTargetHealth\":false}}}]}"
Enter fullscreen mode Exit fullscreen mode

5.2 Delete Route53 Health Check

aws route53 delete-health-check --health-check-id $HealthCheckRegion1AppId
aws route53 delete-health-check --health-check-id $HealthCheckRegion2AppId
Enter fullscreen mode Exit fullscreen mode

5.3 Delete EKS Cluster

eksctl delete cluster --name=$Region1ClusterName --region=$Region1
eksctl delete cluster --name=$Region2ClusterName --region=$Region2
Enter fullscreen mode Exit fullscreen mode

Lesson learned จาก Workshop

  1. Granular failover effect: หากผูกหลายๆ service กับ ALB ตัวเดียวกัน, Route 53 จะไม่ทำการ failover ไปอีก region ทั้งหมด ถึงแม้ว่าจะมีแค่บาง service unhealthty (เนื่องจากมีการกำหนด Evaluate Target Health : No ใน alias records)
  2. Active-active Routing: หากต้องการให้ระบบทำงานแบบ Active-active failover ให้กำหนด routing policy ให้เหมือนกันในทั้งสอง alias record
  3. Health Check แบบ HTTPS: ถ้าตั้งค่า health check endpoint เป็น HTTPS, Route 53 health checker จะไม่ทำการ validate SSL/TLS Certificate แต่อย่างใด
  4. Monitoring Private IP: Route 53 health checker ไม่รองรับการตรวจสอบ endpoint ที่เป็น private IP หากต้องการ monitor private IP แนะนำให้ใช้งาน CloudWatch alarms หรือ AWS Lambda
  5. ค่าใช้จ่าย Health Check: ควรระมัดระวังการสร้าง AWS Route 53 Health Check ในปริมาณมาก เนื่องจากอาจเกิดค่าใช้จ่ายที่สูงได้


Ref: https://aws.amazon.com/route53/pricing/

What can be improved?

แม้ในบทความนี้จะพูดถึงการทำ Multi-Region Failover สำหรับ workload ที่รันบน EKS เป็นหลัก แต่ในความเป็นจริงเราก็คงไม่ใช้แค่ Kubernetes อย่างเดียวแน่นอน ส่วนใหญ่มักจะมี service อื่น ๆ ที่ต้องเกี่ยวข้องด้วย เช่น RDS, MSK, S3, ไปจนถึง storage อย่าง EBS ด้วย ซึ่งแต่ละ service ก็จะมีเทคนิคหรือ practice ในการเตรียมพร้อมรับมือกรณี Region ล่มที่แตกต่างกันออกไป

Amazon RDS
ถ้าใช้ RDS MySQL, PostgreSQL หรือ Aurora สามารถตั้งค่า “Read Replica” ข้าม Region ได้เลย หรือข้ามไปใช้ Aurora Global Database (ยังไม่รองรับที่ Thailand Region) เลยก็ได้ ขึ้นอยู่ RTO, RPO ที่เราต้องการ

Amazon MSK (Kafka)
สำหรับ MSK ยังไม่มี fully managed multi-region replication เหมือน RDS Aurora ดังนั้นจึงจำเป็นต้องใช้เครื่องมือช่วยอย่าง MSK Replicator หรือ Open source อย่าง MirrorMaker2 ในการ replicate ข้อมูลระหว่าง 2 region

Amazon S3
S3 รองรับการทำ “Cross-Region Replication” (CRR) อยู่แล้ว สามารถตั้ง policy ให้ bucket สำคัญ replicate ข้อมูลข้าม Region ได้อัตโนมัติ

Amazon EBS
EBS ไม่สามารถ attach ข้าม Region ได้โดยตรง วิธีป้องกันที่ดีที่สุดคือ สร้าง snapshot แล้ว replicate snapshot ไปยัง Region ปลายทาง

ส่วน Practices อื่นๆ ผมอยากแนะนำให้ลองอ่าน series Creating a Multi-Region Application with AWS Services series เพื่อเป็นแนวทาง

AWS Services Multi-region pracetics diagram

สรุป

หวังว่าบทความนี้จะช่วยให้ทุกคนเห็นภาพและเข้าใจแนวคิดการออกแบบระบบ Failover แบบ Multi-Region สำหรับ EKS ได้ชัดเจนขึ้นนะครับ ไม่ว่าจะวางแผนสำหรับโปรเจกต์ขนาดใหญ่ หรือเริ่มต้นยกระดับมาตรฐานของระบบที่ดูแลอยู่ แนวทางนี้สามารถนำไปประยุกต์ใช้ได้ในหลากหลายรูปแบบ และผมเชื่อว่าการออกแบบให้ระบบรองรับการ failover ได้ จะช่วยให้เราจัดการกับสถานการณ์ไม่คาดคิดได้ดีขึ้น

สุดท้ายแล้ว การเลือกว่า​จะออกแบบระบบ failover ของเราให้ละเอียดหรือทำ Multi-Region สำหรับทุก service หรือไม่ อาจไม่มีสูตรสำเร็จตายตัว สิ่งสำคัญคือต้องประเมินทั้งต้นทุนที่ต้องลงทุนเพิ่มเติม (ไม่ว่าจะเป็นค่า infrastructure หรือค่าใช้จ่ายในการดูแล) เทียบกับเป้าหมาย RTO/RPO ที่องค์กรรับได้ รวมถึงผลกระทบต่อธุรกิจหากเกิดเหตุระบบล่มขึ้นมา ซึ่งบางทีเราอาจต้องเลือกแค่ service ที่ critical จริง ๆ หรือข้อมูลที่สำคัญเท่านั้นให้รองรับ Multi-Region ก็พอ ในขณะที่ service อื่น ๆ ที่ business impact ไม่มากอาจไม่ต้องลงทุนสูงขนาดนั้น และอย่าลืมเรื่องการวางแผน ทดลอง และทดสอบ Disaster Recovery (DR) ข้าม region อย่างสม่ำเสมอ เพื่อให้มั่นใจว่าระบบที่ออกแบบมานั้นสามารถใช้รับมือเหตุการณ์ฉุกเฉินได้จริง ไม่ใช่เพิ่งมาพบปัญหาในวันที่เกิดเหตุแล้ว

ถ้าใครมีคำถามหรืออยากแลกเปลี่ยนประสบการณ์ในการทำ Multi-Region Failover บน EKS สามารถคอมเมนต์พูดคุยกันได้เลยครับ ยินดีแชร์และตอบทุกเคสเหมือนเดิม ขอให้ทุกคนมี Infrastructure ที่พร้อมกับทุกสถานการณ์ครับ

Original Workshop: https://aws.amazon.com/blogs/containers/implementing-granular-failover-in-multi-region-amazon-eks/

Top comments (0)