[KANS] AWS EKS : VPC CNI

2024·Cloud/Kubernetes
목차
  1. 환경 구성
  2. AWS VPC CNI
  3. 실습 시작
  4. 파드 생성 개수 제한
  5. AWS Loadbalancer Controller
  6. ExternalDNS
728x90

환경 구성

구성 : VPC 1ea, Pub Subnet 3ea, Priv Subnet 3ea, EKS (Worker node 3ea)

 

AWS VPC CNI

참고 URL : https://trans.yonghochoi.com/translations/aws_vpc_cni_increase_pods_per_node_limits.ko

- K8s CNI는 Container Network Interface로 Kubernetes 환경의 네트워크를 위한 구성이다.

이를 통해 다양한 플러그인, 오브젝트간의 통신 같은 네트워크 통신이 이뤄진다.

 

AWS VPC CNI는 VPC Container Network Interface로 Kubernetes의 오브젝트들이 VPC 대역의 IP를 갖을 수 있도록 해주는,

플러그인입니다. 파드 내부는 네트워크 네임스페이스를 통해 통신이 이뤄집니다.

 

Secondary IPv4 Addr : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정

IPv4 Prefix Delegation : IPv4 28bit 서브넷(prefix)를 위임하여 할당 가능 IP 수와 인스턴스 유형에 권장하는 최대 갯수로 선정

 

실습 시작

- Network 기본 정보 확인

## CNI 정보 확인
$ k describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# k get ds -n kube-system
NAME         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
aws-node     3         3         3       3            3           <none>          18m

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

-----------------------------
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
[mode: "iptables"]
nodePortAddresses: null
oomScoreAdj: -998
portRange: ""
-----------------------------

## Node 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

-----------------------------------------------------------------
|                       DescribeInstances                       |
+----------------+-----------------+-----------------+----------+
|  InstanceName  |  PrivateIPAdd   |   PublicIPAdd   | Status   |
+----------------+-----------------+-----------------+----------+
|  myeks-ng1-Node|  192.168.2.171  |  43.203.113.24  |  running |
|  myeks-ng1-Node|  192.168.3.47   |  43.200.174.39  |  running |
|  myeks-ng1-Node|  192.168.1.49   |  52.78.144.133  |  running |
|  myeks-bastion |  192.168.1.100  |  3.35.0.91      |  running |
+----------------+-----------------+-----------------+----------+

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

NAME                       IP              STATUS
aws-node-f9qqf             192.168.1.49    <none>
aws-node-n7tlf             192.168.2.171   <none>
aws-node-vmw9k             192.168.3.47    <none>
coredns-699d8c5988-7tdqs   192.168.3.137   <none>
coredns-699d8c5988-xwdhc   192.168.3.130   <none>
kube-proxy-hbk9c           192.168.1.49    <none>
kube-proxy-hlf9g           192.168.3.47    <none>
kube-proxy-zhj9g           192.168.2.171   <none>

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

pod/aws-node-f9qqf
pod/aws-node-n7tlf
pod/aws-node-vmw9k
pod/coredns-699d8c5988-7tdqs
pod/coredns-699d8c5988-xwdhc
pod/kube-proxy-hbk9c
pod/kube-proxy-hlf9g
pod/kube-proxy-zhj9g

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

 

- 노드의 네트워크 정보 확인

## CNI 정보 확인
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i tree /var/log/aws-routed-eni; echo; done
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/plugin.log | jq
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/ipamd.log | jq
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/egress-v6-plugin.log | jq
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/ebpf-sdk.log | jq
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/network-policy-agent.log | jq

## 네트워크 정보 확인 : eniY는 pod network 네임스페이스와 veth pair
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -br -c addr; echo; done
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c addr; echo; done

3: enib32e00ccba3@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether b6:23:b8:10:f4:5a brd ff:ff:ff:ff:ff:ff link-netns cni-4fba2760-6bc4-14e6-7cf7-93e4e3eca198
    inet6 fe80::b423:b8ff:fe10:f45a/64 scope link
       valid_lft forever preferred_lft forever
4: eni585f849df8c@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 1a:5d:af:5f:e1:6c brd ff:ff:ff:ff:ff:ff link-netns cni-be63700a-10d8-6b81-734a-6a73bdb243bd
    inet6 fe80::185d:afff:fe5f:e16c/64 scope link
       valid_lft forever preferred_lft forever

$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
$ ssh ec2-user@$N1 sudo iptables -t nat -S
$ ssh ec2-user@$N1 sudo iptables -t nat -L -n -v

- network 네임스페이스는 호스트와 파드 별로 구분된다

- 특정한 파드(kube-proxy, aws-node)는 호스트(Root)의 IP를 그대로 사용한다 => 파드의 Host Network 옵션

https://xn--vj5b11biyw.kr/306

 

[Kubernetes] Pod 관련 Host Network 옵션과 동작원리

얼마전 보안 스터디 멤버의 질문으로 확인하게된 내용을 포스팅하려고한다. 멤버의 궁금증 덕분에 또하나 알게된 것 같다^^ 스터디의 순기능이다!!(Thanks to Malatto) Kubernetes의 Pod의 spec 하위에 존

xn--vj5b11biyw.kr

- ENI0, ENI1 으로 2개의 ENI는 자신의 IP 이외에 추가적으로 5개의 보조 프라이빗 IP를 가질 수 있다.

- coredns 파드는 veth로 호스트에는 eniY@ifN 인터페이스와 파드에 eth0과 연결되어 있다

 

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

## coredns 파드 IP 정보 확인
$ k get pod -n kube-system -l k8s-app=kube-dns -o wide

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# kubectl get pod -n kube-system -l k8s-app=kube-dns -owide

NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE                                              NOMINATED NODE   READINESS GATES
coredns-699d8c5988-7tdqs   1/1     Running   0          25m   192.168.3.137   ip-192-168-3-47.ap-northeast-2.compute.internal   <none>           <none>
coredns-699d8c5988-xwdhc   1/1     Running   0          25m   192.168.3.130   ip-192-168-3-47.ap-northeast-2.compute.internal   <none>           <none>

## 노드의 라우팅 정보 확인
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done

 

실습용 파드 생성

## 테스트용 netshoot 파드 생성 
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

## 파드 이름 변수 지정
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})

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

## 노드의 라우팅 정보 확인
$ for i in $N $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done

 

- 파드가 생성되면, 워커 노드에 eniY@ifN이 추가되고 라우팅 테이블에도 정보가 추가된다

- 테스트용 파드 eniY정보 확인 - 워커 노드 EC2

- 라우트 정보를 확인해보면 알 수 있듯 파드의 IP 인터페이스와 링크된 것을 확인할 수 있습니다.

## 노트3에서 네트워크 인터페이스 정보 확인
$ ssh ec2-user@$N3

$ ip -br -c addr show
$ ip -c link
$ ip route

 

## 마지막에 생성된 네임스페이스 정보 출력 -t net
$ sudo lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1

## 마지막 생성된 네임스페이스 net PID 정보 출력 -t net(네트워크 타입)를 변수 지정
$ MyPID=$(sudo lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1)

## PID 정보로 파드 정보 확인
$ sudo nsenter -t $MyPID -n ip -c addr
$ sudo nsenter -t $MyPID -n ip -c route

 

## 테스트용 파드 접속 후 확인
$ k exec -it $PODNAME1 -- zsh

## 네트워크 정보 확인
$ ip -c addr
$ ip -c route
$ route -n
$ ping -c 1 <pod-2 IP>
$ ps
$ cat /etc/resolv.conf

## 파드2 shell 실행
$ k exec -it $PODNAME2 -- ip -c addr
$ k exec -it $PODNAME3 -- ip -br -c addr

 

파드 생성 개수 제한

모니터링 툴 설치 : kube-ops-view

 

위에 언급한 내용과 같이 인스턴스 타입 별 ENI 최대 갯수와 할당 가능한 최대 IP 개수에 따라서 파드 배치 개수가 결정됩니다.

단, aws-node와 kube-proxy 파드는 호스트의 IP를 사용함으로 최대 갯수에서 제외합니다.

 

 

- 워커 노드의 최대 파드 갯수 확인

## t3 타입의 정보 확인
(hoontest1@myeks:N/A) [root@myeks-bastion ~]# aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \
>  --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
>  --output table
--------------------------------------
|        DescribeInstanceTypes       |
+----------+----------+--------------+
| IPv4addr | MaxENI   |    Type      |
+----------+----------+--------------+
|  6       |  3       |  t3.medium   |
|  15      |  4       |  t3.xlarge   |
|  15      |  4       |  t3.2xlarge  |
|  12      |  3       |  t3.large    |
|  2       |  2       |  t3.nano     |
|  2       |  2       |  t3.micro    |
|  4       |  3       |  t3.small    |
+----------+----------+--------------+

## 현재 설치된 node 기준의 최대 파드 개수 확인
(hoontest1@myeks:N/A) [root@myeks-bastion ~]# k describe node | grep Allocatable: -A6 | grep pod
  pods:               17
  pods:               17
  pods:               17

 

실제 최대 개수까지 배포해보기
## deploy 배포
$ curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/nginx-dp.yaml
$ k apply -f nginx-dp.yaml

## 파드 확인
$ k get pod

 

- deploy replicas로 pod 증설하기

 

(pod 8개) - 정상

## Scale 진행
k scale deploy nginx-deployment --replicas=8

## 모니터링
watch 'kubectl get pods | awk "{print \$1, \$3}" ; echo "Total count: $(kubectl get pods | grep -i running | wc -l)" ; echo "Pending count: $(kubectl get pod | grep -i pending | wc -l)"'

 

(pod 15개) - 정상

## scale 진행
$ kubectl scale deployment nginx-deployment --replicas=15

## 모니터링
watch 'kubectl get pods | awk "{print \$1, \$3}" ; echo "Total count: $(kubectl get pods | grep -i running | wc -l)" ; echo "Pending count: $(kubectl get pod | grep -i pending | wc -l)"'

 

(pod 30개) - 정상

## Scale 진행
$ kubectl scale deployment nginx-deployment --replicas=30

## 모니터링

watch 'kubectl get pods | awk "{print \$1, \$3}" ; echo "Total count: $(kubectl get pods | grep -i running | wc -l)" ; echo "Pending count: $(kubectl get pod | grep -i pending | wc -l)"'

 

(pod 50개) - 비정상

## Scale 진행
$ kubectl scale deployment nginx-deployment --replicas=30

## 모니터링
watch 'kubectl get pods | awk "{print \$1, \$3}" ; echo "Total count: $(kubectl get pods | grep -i running | wc -l)" ; echo "Pending count: $(kubectl get pod | grep -i pending | wc -l)"'

 

 

이렇게 위에서 node를 describe했던 것과 같이 50대가 넘어가며, 더이상 Pod가 생성되지 않고 pending 상태에 빠지는 것을 확인할 수 있습니다.

 

AWS Loadbalancer Controller

서비스 종류

 

[ ClusterIP ]

 

[ NodePort ] 

 

[ LoadBalancer ]

- 기본 모드이고, LB 생성 시 Network 유형으로 생성됩니다.

 

[ Service (Loadbalancer Controller) ] 

- AWS Load Balancer Controller + NLB IP 모드 동작 with AWS VPC CNI

 

AWS Load Balancer Controller는 EKS에서 LB를 자동으로 관리하는 컨트롤러입니다.

 

주요 기능:
Ingress를 ALB로 자동 프로비저닝
Service type: LoadBalancer를 NLB로 자동 프로비저닝
TargetGroupBinding CRD를 통한 직접적인 ALB/NLB 타겟 그룹 관리

 

1. Proxy Protocol v2 비활성화 ⇒ NLB에서 바로 파드로 인입, 단 ClientIP가 NLB로 SNAT 되어 Client IP 확인 불가능
2. Proxy Protocol v2 활성화 ⇒ NLB에서 바로 파드로 인입 및 ClientIP 확인 가능(→ 단 PPv2 를 애플리케이션이 인지할 수 있게 설정 필요)

 

실습 시작
# AWS LoadBalancer Controller 배포
$ 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

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# helm repo add eks https://aws.github.io/eks-charts
"eks" has been added to your repositories
(hoontest1@myeks:N/A) [root@myeks-bastion ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
...Successfully got an update from the "geek-cookbook" chart repository
Update Complete. ⎈Happy Helming!⎈
(hoontest1@myeks:N/A) [root@myeks-bastion ~]# helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME
NAME: aws-load-balancer-controller
LAST DEPLOYED: Sun Nov  3 03:18:21 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

 

설치 확인

## 클러스터 롤 확인

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
Name:         aws-load-balancer-controller-rolebinding
Labels:       app.kubernetes.io/instance=aws-load-balancer-controller
              app.kubernetes.io/managed-by=Helm
              app.kubernetes.io/name=aws-load-balancer-controller
              app.kubernetes.io/version=v2.10.0
              helm.sh/chart=aws-load-balancer-controller-1.10.0
Annotations:  meta.helm.sh/release-name: aws-load-balancer-controller
              meta.helm.sh/release-namespace: kube-system
Role:
  Kind:  ClusterRole
  Name:  aws-load-balancer-controller-role
Subjects:
  Kind            Name                          Namespace
  ----            ----                          ---------
  ServiceAccount  aws-load-balancer-controller  kube-system

 

서비스/파드 배포 테스트 with NLB
## 모니터링
$ watch -d kubectl get pod,svc,ep

## 서비스 / 디플로이 배포
$ curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/echo-service-nlb.yaml
$ kubectl apply -f echo-service-nlb.yaml

### 선언된 파일 중 서비스의 annotion 확인
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  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-healthcheck-port: "8080"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
  selector:

 

NLB가 생성되며, 연결되기 위해 함께 생성된 Target Group도 확인해 봅니다.

$ k get targetgroupbindings -o json | jq

{
  "apiVersion": "v1",
  "items": [
    {
      "apiVersion": "elbv2.k8s.aws/v1beta1",
      "kind": "TargetGroupBinding",
      "metadata": {
        "annotations": {
          "elbv2.k8s.aws/checkpoint": "WOEYl4jDYcJtqlC4GAqdO6YeGuZpYyp1x1tSPLRtEPc/qv-8bMjwEM9jorHjPGuzt8RQ_xgHg0djKORAzTOyduI",
          "elbv2.k8s.aws/checkpoint-timestamp": "1730571731"
        },
        "creationTimestamp": "2024-11-02T18:22:09Z",
        "finalizers": [
          "elbv2.k8s.aws/resources"
        ],
        "generation": 1,
        "labels": {
          "service.k8s.aws/stack-name": "svc-nlb-ip-type",
          "service.k8s.aws/stack-namespace": "default"
        },
        "name": "k8s-default-svcnlbip-ff5bd9bea3",
        "namespace": "default",
        "resourceVersion": "35086",
        "uid": "a463aa9b-c958-4b43-b717-23c05a0a648f"
      },
      "spec": {
        "ipAddressType": "ipv4",
        "networking": {
          "ingress": [
            {
              "from": [
                {
                  "securityGroup": {
                    "groupID": "sg-08d95b222b3d9ee09"
                  }
                }
              ],
              "ports": [
                {
                  "port": 8080,
                  "protocol": "TCP"
                }
              ]
            }
          ]
        },
        "serviceRef": {
          "name": "svc-nlb-ip-type",
          "port": 80
        },
        "targetGroupARN": "arn:aws:elasticloadbalancing:ap-northeast-2:632128666759:targetgroup/k8s-default-svcnlbip-ff5bd9bea3/e5865cee760fb98f",
        "targetType": "ip",
        "vpcID": "vpc-0f0247ec0bf412f6b"
      },
      "status": {
        "observedGeneration": 1
      }
    }
  ],
  "kind": "List",
  "metadata": {
    "resourceVersion": ""
  }
}

 

- LB 정보를 aws cli로 확인

## 분산 접속을 통해 균일하게 통신되는지 확인해 봅니다.
$ for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr

     50 Hostname: deploy-echo-857b6cfb88-g2rh5
     50 Hostname: deploy-echo-857b6cfb88-dbhn2

 

웹으로 접속을 해도 hostname이 바뀌는 것으로 보아 분산되어 접속되는 것을 확인할 수 있습니다.

 

Ingress

 

인그레스는 Proxy 기반으로 클러스터 내부의 서비스를 외부로 노출합니다.

 

- ingress.yaml 배포

apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 2
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-2048
              port:
              	number: 80
                
## 오브젝트 배포
$ k apply -f ingress1.yaml

 

- 배포 확인

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# kubectl get-all -n game-2048

NAME                                                               NAMESPACE  AGE
configmap/kube-root-ca.crt                                         game-2048  39s
endpoints/service-2048                                             game-2048  39s
pod/deployment-2048-85f8c7d69-6fnpp                                game-2048  39s
pod/deployment-2048-85f8c7d69-glwq2                                game-2048  39s
serviceaccount/default                                             game-2048  39s
service/service-2048                                               game-2048  39s
deployment.apps/deployment-2048                                    game-2048  39s
replicaset.apps/deployment-2048-85f8c7d69                          game-2048  39s
endpointslice.discovery.k8s.io/service-2048-d77lc                  game-2048  39s
targetgroupbinding.elbv2.k8s.aws/k8s-game2048-service2-1eeb8d956e  game-2048  35s
ingress.networking.k8s.io/ingress-2048                             game-2048  39s

 

- ingress 상세 정보 확인

$ k describe ingress -n game-2048 ingress-2048

 

- WEB 주소 확인 및 접속

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# kubectl get ingress -n game-2048 ingress-2048 -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Game URL = http://"$1 }'
Game URL = http://k8s-game2048-ingress2-70d50ce3fd-1875255779.ap-northeast-2.elb.amazonaws.com

 

AWS 콘솔에서도 리소스 맵을 살짝 참고해 봅니다.

 

ExternalDNS

ExternalDNS는 서비스 / 인그레스 생성 시 도메인을 설정하면, AWS, Azure, GCP에 A레코드로 자동 생성 / 삭제됩니다.

- 도메인 확인

(실 사용 도메인으로 세부 정보는 제외했습니다.)

## 내 도메인 확인 및 변수 지정
$ MyDomain=ssungz.net
$ echo "export MyDomain=ssungz.net" >> /etc/profile

## 도메인 조회
$ aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq

## A레코드 조회
$ aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
[
  {
    "Name": "gitlab.ssungz.net.",
    "Type": "A",
    "TTL": 300,
    "ResourceRecords": [
      {
        "Value": ""
      }
    ]
  }
]

 

ExternalDNS 설치
## 변수를 통해 데이터 확인
$ echo $MyDomain, $MyDnzHostedZoneId

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

## 배포 확인 및 모니터링
$ k get pod -l app.kubernetes.io/name=external-dns -n kube-system
$ k logs deploy/external-dns -n kube-system -f

 

Service(NLB) + 도메인 연동
## 테트리스 deploy 배포
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
  
$ k apply -f tetris.yaml

 

- 자원 생성 확인

## 배포 확인
$ k get deploy,svc,ep tetris

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

 

- 레코드 연결 확인

$ aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq

  {
    "Name": "tetris.ssungz.net.",
    "Type": "A",
    "AliasTarget": {
      "HostedZoneId": "ZIBE1TIR4HY56",
      "DNSName": "k8s-default-tetris-9b1e7a5afa-49df0f49a71ae3ca.elb.ap-northeast-2.amazonaws.com.",
      "EvaluateTargetHealth": true
    }
  }
]

 

- DNS 배포 확인

(hoontest1@myeks:N/A) [root@myeks-bastion ~]# dig +short tetris.$MyDomain @8.8.8.8
3.37.104.86
43.200.217.68
15.165.243.214

 

레코드 배포 확인 후 사이트 접속 확인

 

 

728x90

'Cloud > Kubernetes' 카테고리의 다른 글

[AEWS] CI/CD  (0) 2025.03.30
[KANS] Cilium + eBPF (2)  (2) 2024.10.27
[KANS] Cilium & Hubble  (0) 2024.10.26
[KANS] Istio - Traffic Management  (0) 2024.10.20
[KANS] Istio example (bookinfo)  (1) 2024.10.20
  1. 환경 구성
  2. AWS VPC CNI
  3. 실습 시작
  4. 파드 생성 개수 제한
  5. AWS Loadbalancer Controller
  6. ExternalDNS
'Cloud/Kubernetes' 카테고리의 다른 글
  • [AEWS] CI/CD
  • [KANS] Cilium + eBPF (2)
  • [KANS] Cilium & Hubble
  • [KANS] Istio - Traffic Management
ssungz
ssungz
250x250
ssungz
임썽 블로그
ssungz
전체
오늘
어제
  • 분류 전체보기 (68)
    • Cloud (62)
      • Terraform (17)
      • AWS (23)
      • NCP (2)
      • Kubernetes (17)
      • CICD (3)
    • Linux (4)
    • Python (2)
      • MLAL (1)
      • Automation (1)

블로그 메뉴

    공지사항

    • 다크모드로 보는 것을 권장합니다.

    인기 글

    태그

    • NKS
    • EC2
    • aws
    • Terraform
    • NCP
    • Kubernetes

    최근 댓글

    최근 글

    hELLO· Designed By정상우.v4.5.2
    ssungz
    [KANS] AWS EKS : VPC CNI

    개인정보

    • 티스토리 홈
    • 포럼
    • 로그인
    상단으로

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.