새소식

반응형
k8s/CloudNet@

[CloudNet@] AWS EKS Workshop Study - 2주차.

  • -
728x90
반응형

 

 

 

안녕하세요 늑대양입니다 😍

 

 

 

늑대양 레몬 버전!!

 

 

 

 

이번에 CloudNet@에서 진행하는 AWS EKS Workshop Study(AEWS)에 참여하여 관련 내용을 공유드리고자 합니다.

 

 

 

AEWS Study #2주차

 

 

오늘은 AEWS 스터디 2주차 학습 내용을 안내해드리록하겠습니다.

 

 

 

CloudNet@ 팀 블로그 메인 커버

 

 

 

 

CloudNet@ 팀 블로그 Main URL:

https://www.notion.so/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863

 

CloudNet@ Blog

CloudNet@ 팀에서 Cloud Infra & Network 기술에 대한 정보를 공유하는 블로그 입니다.

www.notion.so

 

 

 

 

AWS EKS Workshop Study - 2주차

2주차 학습 주제: EKS Networking

Index.

  • 실습 환경 배포
  • AWS VPC CNI 소개
  • 노드에서 기본 네트워크 정보 확인
  • 노드 간 파드 통신
  • 파드에서 외부 통신
  • 노드에서 파드 생성 개수 제한
  • Service & AWS LoadBalancer Controller
  • ExternalDNS
  • Istio
  • kube-ops-view
  • (실습 완료 후) 자원 삭제

 

 

 

실습 환경 배포

EKS 실습 배포 아키텍처 - Image Source: CloudNet@

 

  • 이번 주차 AEWS 스터디의 실습 환경 배포 아키텍처!!
  • 가시다님의 CloudFormation Template을 통해, 손쉽게 배포가 가능합니다🙏

 

 

AWS VPC CNI 소개

k8s CNI

k8s의 Container Network Interface는 k8s 네트워크 환경을 구성

 

 

AWS VPC CNI

Networking plugin for pod networking in Kubernetes using ENIs(Elastic Network Interfaces) on AWS

 

AWS VPC CNI

 

VPC CNI 의 특징

  • 노드의 IP 대역과 파드의 IP 네트워크 대역이 같아서 직접 통신이 가능하다!!
  • VPC와 통합을 통해, VPC Flow logs, 라우팅 정책, 보안그룹 활용 가능
  • VPC 대역 내에서 각각의 파드에 IP 할당
  • VPC ENI에 미리 할당된 IP(Local-IPAM Warm IP Pool)를 파드에서 사용 가능

 

 

일반적인 K8S CNI 플러그인(Calico) 와 AWS VPC CNI 간 노드와 파드 네트워크 대역 비교 - Image Source: CloudNet@

 

 

 

VPC CNI는 왼쪽의 Calico CNI 통신에서 overlay를 활용하는 것과 달리 원본 패킷을 통한 직접 통신 가능!! - Image Source: CloudNet@

 

 

 

실습

네트워크 기본 정보 확인

# CNI 정보 확인
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.12.6-eksbuild.1
amazon-k8s-cni:v1.12.6-eksbuild.1

# kube-proxy config 확인 : 모드 iptables 사용 >> ipvs 모드 사용하지 않는 이유???
kubectl describe cm -n kube-system kube-proxy-config
...
mode: "iptables"
...

# 노드 IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table

# 파드 IP 확인
kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase

# 파드 이름 확인
kubectl get pod -A -o name

# 파드 갯수 확인
kubectl get pod -A -o name | wc -l

 

 

네트워크 기본 정보 확인 실습

 

 

 

노드 네트워크 기본 정보 확인

# 노드 IP 설정
N1=[az-2a worker node IP]
N2=[az-2b worker node IP]
N3=[az-2c worker node IP]

# 노드에 툴 설치
ssh ec2-user@$N1 sudo yum install links tree jq tcpdump -y
ssh ec2-user@$N2 sudo yum install links tree jq tcpdump -y
ssh ec2-user@$N3 sudo yum install links tree jq tcpdump -y

# CNI 정보 확인
ssh ec2-user@$N1 tree /var/log/aws-routed-eni
ssh ec2-user@$N1 cat /var/log/aws-routed-eni/plugin.log | jq
ssh ec2-user@$N1 cat /var/log/aws-routed-eni/ipamd.log | jq
ssh ec2-user@$N1 cat /var/log/aws-routed-eni/egress-v4-plugin.log | jq

# 네트워크 정보 확인 : eniY는 pod network 네임스페이스와 veth pair
ssh ec2-user@$N1 sudo ip -br -c addr
ssh ec2-user@$N1 sudo ip -c addr
ssh ec2-user@$N1 sudo ip -c route
ssh ec2-user@$N1 sudo iptables -t nat -S
ssh ec2-user@$N1 sudo iptables -t nat -L -n -v

 

 

 

노드에서 기본 네트워크 정보 확인

네트워크 네임스페이스는 Host(root) / Pod 로 구분

 

 

  • kube-proxy, aws-node는 host(실습 중 노드)의 IP를 그대로 사용

 

실습

보조 IPv4 주소를 파드가 사용하는지 확인

# coredns 파드 IP 정보 확인
kubectl get pod -n kube-system -l k8s-app=kube-dns -owide
NAME                       READY   STATUS    RESTARTS   AGE   IP             NODE                                               NOMINATED NODE   READINESS GATES
coredns-6777fcd775-g5lw6   1/1     Running   0          15m   192.168.1.68   ip-192-168-1-242.ap-northeast-2.compute.internal   <none>           <none>
coredns-6777fcd775-hbxkt   1/1     Running   0          15m   192.168.3.72   ip-192-168-3-94.ap-northeast-2.compute.internal    <none>           <none>

# 노드의 라우팅 정보 확인 >> EC2 네트워크 정보의 '보조 프라이빗 IPv4 주소'와 비교해보자
ssh ec2-user@$N1 sudo ip -c route
ssh ec2-user@$N2 sudo ip -c route
ssh ec2-user@$N3 sudo ip -c route

 

coredns 파드의 IP 정보 확인

 

 

 

노드 1번의 라우팅 정보 확인 결과, Secondary private IP 중 하나를 사용하고 있음을 확인 가능!!

 

 

 

테스트용 파드 생성

# [터미널1~3] 노드 모니터링
ssh ec2-user@$N1
watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

ssh ec2-user@$N2
watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

ssh ec2-user@$N3
watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

# 테스트용 파드 netshoot-pod 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: netshoot-pod
  template:
    metadata:
      labels:
        app: netshoot-pod
    spec:
      containers:
      - name: netshoot-pod
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
EOF

# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})
PODNAME3=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[2].metadata.name})

# 파드 확인
kubectl get pod -o wide
kubectl get pod -o=custom-columns=NAME:.metadata.name,IP:.status.podIP

 

 

 

테스트용 netshoot 파드 생성 후, IP 확인!!

 

 

 

watch 명령어를 활용한 노드 모니터링, 파드 생성 시, 라우팅 테이블 정보 추가

 

 

 

노드 간 파드 통신

AWS VPC CNI 경우 별도의 오버레이(Overlay) 통신 기술 없이, VPC Native 하게 파드간 직접 통신이 가능

Pod 간(pod-2 to pod-1) 통신 흐름 - Image Source: CloudNet@

 

 

실습

# 파드 IP 변수 지정
PODIP1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].status.podIP})
PODIP2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].status.podIP})
PODIP3=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[2].status.podIP})

# 파드1 Shell 에서 파드2로 ping 테스트
kubectl exec -it $PODNAME1 -- ping -c 2 $PODIP2

# 파드2 Shell 에서 파드3로 ping 테스트
kubectl exec -it $PODNAME2 -- ping -c 2 $PODIP3

# 파드3 Shell 에서 파드1로 ping 테스트
kubectl exec -it $PODNAME3 -- ping -c 2 $PODIP1

# 워커 노드 EC2 : TCPDUMP 확인 - 왜지???? 패킷 덤프 확인이 되나요?
sudo tcpdump -i any -nn icmp
sudo tcpdump -i eth1 -nn icmp
sudo tcpdump -i eth0 -nn icmp

[워커 노드1]
# routing policy database management 확인
ip rule

# routing table management 확인
ip route show table local

# 디폴트 네트워크 정보를 eth0 을 통해서 빠져나간다
ip route show table main
default via 192.168.1.1 dev eth0
...

 

 

Pod1 to Pod2 ping test 진행!!

 

 

 

tcpdump 명령어를 통해 확인 결과, 별도의 NAT 동작 없이 통신 확인!!

 

 

 

파드에서 외부 통신

Life of a Pod to External Packet

 

 

 

SNAT for pods - Amazon EKS

SNAT for pods If you deployed your cluster using the IPv6 family, then the information in this topic isn't applicable to your cluster, because IPv6 addresses are not network translated. For more information about using IPv6 with your cluster, see Tutorial:

docs.aws.amazon.com

 

실습

# 작업용 EC2 : pod-1 Shell 에서 외부로 ping
kubectl exec -it $PODNAME1 -- ping -c 1 www.google.com
kubectl exec -it $PODNAME1 -- ping -i 0.1 www.google.com

# 워커 노드 EC2 : TCPDUMP 확인
sudo tcpdump -i any -nn icmp
sudo tcpdump -i eth0 -nn icmp

# 워커 노드 EC2 : 퍼블릭IP 확인
curl -s ipinfo.io/ip ; echo

# 작업용 EC2 : pod-1 Shell 에서 외부 접속 확인 - 공인IP는 어떤 주소인가?
## The right way to check the weather - 링크
kubectl exec -it $PODNAME1 -- curl -s ipinfo.io/ip ; echo
kubectl exec -it $PODNAME1 -- curl -s wttr.in/seoul
kubectl exec -it $PODNAME1 -- curl -s wttr.in/seoul?format=3
kubectl exec -it $PODNAME1 -- curl -s wttr.in/Moon
kubectl exec -it $PODNAME1 -- curl -s wttr.in/:help

# 워커 노드 EC2
## 출력된 결과를 보고 어떻게 빠져나가는지 고민해보자!
ip rule
ip route show table main
sudo iptables -L -n -v -t nat
sudo iptables -t nat -S

# 파드가 외부와 통신시에는 아래 처럼 'AWS-SNAT-CHAIN-0, AWS-SNAT-CHAIN-1' 룰(rule)에 의해서 SNAT 되어서 외부와 통신!
# 참고로 뒤 IP는 eth0(ENI 첫번째)의 IP 주소이다
# --random-fully 동작
sudo iptables -t nat -S | grep 'A AWS-SNAT-CHAIN'
-A AWS-SNAT-CHAIN-0 ! -d 192.168.0.0/16 -m comment --comment "AWS SNAT CHAIN" -j AWS-SNAT-CHAIN-1
-A AWS-SNAT-CHAIN-1 ! -o vlan+ -m comment --comment "AWS, SNAT" -m addrtype ! --dst-type LOCAL -j SNAT --to-source 192.168.1.251 --random-fully

## 아래 'mark 0x4000/0x4000' 매칭되지 않아서 RETURN 됨!
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
-A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE --random-fully
...

# 카운트 확인 시 AWS-SNAT-CHAIN-0, AWS-SNAT-CHAIN-1 에 매칭되어, 목적지가 192.168.0.0/16 아니고 외부 빠져나갈때 SNAT 192.168.1.251(EC2 노드1 IP) 변경되어 나간다!
sudo iptables -t filter --zero; sudo iptables -t nat --zero; sudo iptables -t mangle --zero; sudo iptables -t raw --zero
watch -d 'sudo iptables -v --numeric --table nat --list AWS-SNAT-CHAIN-0; echo ; sudo iptables -v --numeric --table nat --list AWS-SNAT-CHAIN-1; echo ; sudo iptables -v --numeric --table nat --list KUBE-POSTROUTING'

# conntrack 확인
sudo conntrack -L -n |grep -v '169.254.169'
conntrack v1.4.5 (conntrack-tools): 
icmp     1 28 src=172.30.66.58 dst=8.8.8.8 type=8 code=0 id=34392 src=8.8.8.8 dst=172.30.85.242 type=0 code=0 id=50705 mark=128 use=1
tcp      6 23 TIME_WAIT src=172.30.66.58 dst=34.117.59.81 sport=58144 dport=80 src=34.117.59.81 dst=172.30.85.242 sport=80 dport=44768 [ASSURED] mark=128 use=1

 

 

 

 

노드에서 파드 생성 개수 제한

Image Source: CloudNet@

 

 

  • Secondary IPv4 addresses : 인스턴스 유형에 최대 ENI 개수와 할당 가능 IP 수를 조합하여 선정
  • 워커 노드의 인스턴스 타입 별 파드 생성 개수 제한
    • 인스턴스 타입 별, ENI 최대 개수 할당 가능한 최대 IP 개수에 따라서 파드 배치 개수가 결정됨
    • 단, aws-node 와 kube-proxy 파드는 호스트의 IP를 사용함으로 최대 개수에서 제외함

 

 

최대 파드 생성 개수 공식:
(Number of network interfaces for the instance type × (the number of IP addressess per network interface - 1)) + 2

*t3.medium의 예시:
(3 * (6-1)) + 2 = 17 (aws-node, kube-proxy 로 인해, 2개 추가하여 17 > 커스텀하게 할당 가능한 것은 15)

 

 

 

해결방안:

Image Source: CloudNet@

 

  • Prefix Delegation
  • WARM & MIN IP/Prefix Targets
  • Change instance type

 

 

 

 

 

 

Service & AWS LoadBalancer Controller

Service?!

  • k8s 에서 서비스란, 클러스터 내에서 실행되는 파드들에 대해서 공용 IP 주소를 할당하는 개념
  • 파드들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출시키는 가상의 컴포넌트
  • 서비스를 통해 파드들을 식별하고 접근할 수 있게 해줌!!

 

 

ClusterIP

클러스터 내부에서만 접근 가능한 IP 주소 할당, 외부에서 접근 불가능!! Source: CloudNet@

 

 

 

NodePort

클러스터 내부에서도 접근 가능하지만 클러스터 외부에서도 특정 포트를 통해 접근 가능!! Source: CloudNet@

 

 

 

LoadBalancer

클러스터 외부에서도 접근 가능하며, 로드밸런싱을 제공!! Source: CloudNet@

 

 

 

AWS LB Controller + NLB IP 모드 동작!! Source: CloudNet@

 

 

 

NLB 모드 정리:

  1. 인스턴스 유형
    1. externalTrafficPolicy : ClusterIP ⇒ 2번 분산 및 SNAT으로 Client IP 확인 불가능 ← LoadBalancer 타입 (기본 모드) 동작
    2. externalTrafficPolicy : Local ⇒ 1번 분산 및 ClientIP 유지, 워커 노드의 iptables 사용함
  2. IP 유형 ⇒ 반드시 AWS LoadBalancer 컨트롤러 파드 및 정책 설정이 필요함!
    1. Proxy Protocol v2 비활성화 ⇒ NLB에서 바로 파드로 인입, 단 ClientIP가 NLB로 SNAT 되어 Client IP 확인 불가능
    2. Proxy Protocol v2 활성화 ⇒ NLB에서 바로 파드로 인입 및 ClientIP 확인 가능
      (→ 단 PPv2 를 애플리케이션이 인지할 수 있게 설정 필요)

 

 

 

실습

AWS LoadBalancer Controller 배포 with IRSA

# OIDC 확인
aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text
aws iam list-open-id-connect-providers | jq

# IAM Policy (AWSLoadBalancerControllerIAMPolicy) 생성
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json

# 혹시 이미 IAM 정책이 있지만 예전 정책일 경우 아래 처럼 최신 업데이트 할 것
# aws iam update-policy ~~~

# 생성된 IAM Policy Arn 확인
aws iam list-policies --scope Local
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --query 'Policy.Arn'

# AWS Load Balancer Controller를 위한 ServiceAccount를 생성 >> 자동으로 매칭되는 IAM Role 을 CloudFormation 으로 생성됨!
# IAM 역할 생성. AWS Load Balancer Controller의 kube-system 네임스페이스에 aws-load-balancer-controller라는 Kubernetes 서비스 계정을 생성하고 IAM 역할의 이름으로 Kubernetes 서비스 계정에 주석을 답니다
eksctl create iamserviceaccount --cluster=$CLUSTER_NAME --namespace=kube-system --name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --override-existing-serviceaccounts --approve

## IRSA 정보 확인
eksctl get iamserviceaccount --cluster $CLUSTER_NAME

## 서비스 어카운트 확인
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml | yh

# Helm Chart 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
  --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller

## 설치 확인
kubectl get crd
kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller | grep 'Service Account'
  Service Account:  aws-load-balancer-controller
 
# 클러스터롤, 롤 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role
...
PolicyRule:
  Resources                                     Non-Resource URLs  Resource Names  Verbs
  ---------                                     -----------------  --------------  -----
  targetgroupbindings.elbv2.k8s.aws             []                 []              [create delete get list patch update watch]
  events                                        []                 []              [create patch]
  ingresses                                     []                 []              [get list patch update watch]
  services                                      []                 []              [get list patch update watch]
  ingresses.extensions                          []                 []              [get list patch update watch]
  services.extensions                           []                 []              [get list patch update watch]
  ingresses.networking.k8s.io                   []                 []              [get list patch update watch]
  services.networking.k8s.io                    []                 []              [get list patch update watch]
  endpoints                                     []                 []              [get list watch]
  namespaces                                    []                 []              [get list watch]
  nodes                                         []                 []              [get list watch]
  pods                                          []                 []              [get list watch]
  endpointslices.discovery.k8s.io               []                 []              [get list watch]
  ingressclassparams.elbv2.k8s.aws              []                 []              [get list watch]
  ingressclasses.networking.k8s.io              []                 []              [get list watch]
  ingresses/status                              []                 []              [update patch]
  pods/status                                   []                 []              [update patch]
  services/status                               []                 []              [update patch]
  targetgroupbindings/status                    []                 []              [update patch]
  ingresses.elbv2.k8s.aws/status                []                 []              [update patch]
  pods.elbv2.k8s.aws/status                     []                 []              [update patch]
  services.elbv2.k8s.aws/status                 []                 []              [update patch]
  targetgroupbindings.elbv2.k8s.aws/status      []                 []              [update patch]
  ingresses.extensions/status                   []                 []              [update patch]
  pods.extensions/status                        []                 []              [update patch]
  services.extensions/status                    []                 []              [update patch]
  targetgroupbindings.extensions/status         []                 []              [update patch]
  ingresses.networking.k8s.io/status            []                 []              [update patch]
  pods.networking.k8s.io/status                 []                 []              [update patch]
  services.networking.k8s.io/status             []                 []              [update patch]
  targetgroupbindings.networking.k8s.io/status  []                 []              [update patch]

 

 

 

 

ExternalDNS

k8s 서비스/인그레스 생성 시 도메인을 설정하면, AWS(Route 53), Azure(DNS), GCP(Cloud DNS) 에 A 레코드(TXT 레코드)로 자동 생성/삭제

 

External DNS - Image Source: https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c

 

 

 

ExternalDNS CTRL 권한 주는 방법 3가지

  • Node IAM Role
  • Static credentials
  • IRSA

 

 

실습

# 자신의 도메인 변수 지정 : 소유하고 있는 자신의 도메인을 입력하시면 됩니다
MyDomain=<자신의 도메인>
MyDomain=wolf-sheep.name

# 자신의 Route 53 도메인 ID 조회 및 변수 지정
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Name"
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text
MyDnzHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`
echo $MyDnzHostedZoneId

# (옵션) NS 레코드 타입 첫번째 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'NS']" | jq -r '.[0].ResourceRecords[].Value'
# (옵션) A 레코드 타입 모두 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']"

# A 레코드 타입 조회
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" --output text

# A 레코드 값 반복 조회
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done

 

 

Route53에 등록한 도메인을 활용하여 설정 진행

 

 

 

ExternalDNS 설치

# EKS 배포 시 Node IAM Role 설정되어 있음
# eksctl create cluster ... --external-dns-access ...

# 
MyDomain=<자신의 도메인>
MyDomain=wolf-sheep.name

# 자신의 Route 53 도메인 ID 조회 및 변수 지정
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)

# 변수 확인
echo $MyDomain, $MyDnzHostedZoneId

# ExternalDNS 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
cat externaldns.yaml | yh
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -

# 확인 및 로그 모니터링
kubectl get pod -l app.kubernetes.io/name=external-dns -n kube-system
kubectl logs deploy/external-dns -n kube-system -f

 

 

 

Service(NLB) + 도메인 연동(ExternalDNS)

# 터미널1 (모니터링)
watch -d 'kubectl get pod,svc'
kubectl logs deploy/external-dns -n kube-system -f

# 테트리스 디플로이먼트 배포
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tetris
  labels:
    app: tetris
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tetris
  template:
    metadata:
      labels:
        app: tetris
    spec:
      containers:
      - name: tetris
        image: bsord/tetris
---
apiVersion: v1
kind: Service
metadata:
  name: tetris
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
    #service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "80"
spec:
  selector:
    app: tetris
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
EOF

# 배포 확인 : CLB 배포 확인
kubectl get deploy,svc,ep tetris

# NLB에 ExternanDNS 로 도메인 연결
kubectl annotate service tetris "external-dns.alpha.kubernetes.io/hostname=tetris.$MyDomain"

# Route53에 A레코드 확인
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq .[]

# 확인
dig +short tetris.$MyDomain @8.8.8.8
dig +short tetris.$MyDomain

# 도메인 체크
echo -e "My Domain Checker = https://www.whatsmydns.net/#A/tetris.$MyDomain"

# 웹 접속 주소 확인 및 접속
echo -e "Tetris Game URL = http://tetris.$MyDomain"

 

 

 

Tetris 관련 리소스 배포 및 모니터링

 

 

NLB를 활용하여 tetris 파드와 서비스 연결

 

 

DNS Name이 Route53 레코드로 등록되어 tetris.DOMAIN_NAME 을 통해 테트리스 실행 가능

 

 

 

Istio

Service Mesh

마이크로서비스 간에 매시 형태의 통신이나 그 경로를 제어

 

해당 부분은 추후 업데이트 예정

 

 

 

 

 

kube-ops-view

노드의 파드 상태 정보를 웹 페이지에서 실시간으로 출력

 

관련 링크:

https://artifacthub.io/packages/helm/geek-cookbook/kube-ops-view

 

kube-ops-view 1.2.2 · funkypenguin/geek-cookbook

A read-only system dashboard for multiple K8s clusters

artifacthub.io

 

 

# 설치
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"

# 접속 주소 확인 : 각각 1배, 1.5배, 3배 크기
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=3.0"

# nginx 파드 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/nginx-dp.yaml
kubectl apply -f nginx-dp.yaml
kubectl scale deployment nginx-deployment --replicas 15
kubectl scale deployment nginx-deployment --replicas 40
kubectl delete -f nginx-dp.yaml

 

Cluster에 배포된 리소스를 시작적으로 확인 가능, 박스별로 pod 표현

 

 

 

배포된 Nginx 파드에 대해 확인 가능

 

 

 

추가적으로 파드를 배포할 경우, (굉장히) 화려하게 시작적으로 표현

 

 

 

생성된 파드를 삭제할 경우, 생성할 때와 비슷하게 시각적으로 표현

 

 

 

 

(실습 완료 후) 자원 삭제

# LoadBalancer 관련 IRSA 스택 삭제
aws cloudformation delete-stack --stack-name eksctl-$CLUSTER_NAME-addon-iamserviceaccount-kube-system-aws-load-balancer-controller

# 1줄 삭제 방안 (SSH 세션 유지 필수!!)
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME

 

 

 

 

 

 

 

긴 글 읽어주셔서 감사합니다🤗

 

 

 

 

728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.