[AWS]/[EKS]

2주차 Study - EKS Networking (실습 환경 구축)

scdo 2025. 2. 15. 19:37

1. 환경 배포

EKS 배포 전 기본 환경을 AWS CloudFormation을 통해 배포합니다.

필요사항

  • EC2: 운영용 서버 1대
  • VPC: 운영용 VPC 1개, EKS용 VPC 1개
  • 서브넷: 각 AZ 별 Public/Private 서브넷
  • VPC Peering: 내부 통신용

 

YAML 파일 다운로드

curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/myeks-2week.yaml

 

CloudFormation을 이용한 배포

aws cloudformation deploy --template-file ~/myeks-2week.yaml --stack-name myeks --parameter-overrides KeyName=test-key01 SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

배포 화면

 

배포가 완료되면 다음 정보를 확인할 수 있습니다.

 

EC2 서버 공인 확인

aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[*].OutputValue' --output text

EC2 서버 공인 IP

 

VPC 확인

aws ec2 describe-vpcs |jq -r .Vpcs[].VpcId

VPC ID
VPC AWS 콘솔 화면

서브넷 확인

aws ec2 describe-subnets | jq -r .Subnets[].SubnetId

서브넷 ID
서브넷 AWS 콘솔 화면

 

라우팅 테이블 확인

aws ec2 describe-route-tables | jq -r '.RouteTables[] | select(any(.Associations[]?.Main; . == false)) | .RouteTableId'

라우팅 테이블 ID
라우팅테이블 AWS 콘솔 화면

 

VPC Peering 확인

aws ec2 describe-vpc-peering-connections |jq -r .VpcPeeringConnections[].VpcPeeringConnectionId

VPC Peering ID
VPC Peering AWS 콘솔 화면

 


2. EKS 배포

eksctl을 통해 EKS를 배포합니다.

 

생성된 VPC/서브넷 정보 확인 및 변수 지정

#VPC 정보 확인 및 변수 지정
export CLUSTER_NAME=myeks
export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" --query 'Vpcs[*].VpcId' --output text)
echo $VPCID

#서브넷 정보 확인 및 변수 지정
export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet3=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet3" --query "Subnets[0].[SubnetId]" --output text)
echo $PubSubnet1 $PubSubnet2 $PubSubnet3

VPC
서브넷

 

YAML 파일 생성

--dry-run 옵션으로 실제 명령어 실행하지 않고 YAML 파일로 생성

eksctl create cluster --name $CLUSTER_NAME --region=ap-northeast-2 --nodegroup-name=ng1 --node-type=t3.medium --nodes 3 --node-volume-size=30 --vpc-public-subnets "$PubSubnet1","$PubSubnet2","$PubSubnet3" --version 1.31 --with-oidc --external-dns-access --full-ecr-access --alb-ingress-access --node-ami-family AmazonLinux2023 --ssh-access --dry-run > myeks.yaml

 

환경에 맞게 YAML 파일 수정

  • 네트워크 설정 확인 및 각 환경 정보로 수정
  • EKS 애드온 설정
  • 추가 패키지 설치(preBootstrapCommands)
  • 노드 그룹 설정
참고: VS Code를 연동하여 이용 시 좀 더 쉽게 파일 내용을 수정할 수 있습니다.
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: myeks
  region: ap-northeast-2
  version: "1.31"

kubernetesNetworkConfig:
  ipFamily: IPv4

iam:
  vpcResourceControllerPolicy: true
  withOIDC: true

accessConfig:
  authenticationMode: API_AND_CONFIG_MAP

vpc:
  autoAllocateIPv6: false
  cidr: 192.168.0.0/16
  clusterEndpoints:
    privateAccess: true # if you only want to allow private access to the cluster
    publicAccess: true # if you want to allow public access to the cluster
  id: vpc-0f555405700d125a3  # 각자 환경 정보로 수정
  manageSharedNodeSecurityGroupRules: true # if you want to manage the rules of the shared node security group
  nat:
    gateway: Disable
  subnets:
    public:
      ap-northeast-2a:
        az: ap-northeast-2a
        cidr: 192.168.1.0/24
        id: subnet-00594328b72af1ec5  # 각자 환경 정보로 수정
      ap-northeast-2b:
        az: ap-northeast-2b
        cidr: 192.168.2.0/24
        id: subnet-0fab33ec4399251dd  # 각자 환경 정보로 수정
      ap-northeast-2c:
        az: ap-northeast-2c
        cidr: 192.168.3.0/24
        id: subnet-015e7eb16af3781b8  # 각자 환경 정보로 수정

addons:
  - name: vpc-cni # no version is specified so it deploys the default version
    version: latest # auto discovers the latest available
    attachPolicyARNs: # attach IAM policies to the add-on's service account
      - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    configurationValues: |-
      enableNetworkPolicy: "true"

  - name: kube-proxy
    version: latest

  - name: coredns
    version: latest

  - name: metrics-server
    version: latest

privateCluster:
  enabled: false
  skipEndpointCreation: false

managedNodeGroups:
- amiFamily: AmazonLinux2023
  desiredCapacity: 3
  disableIMDSv1: true
  disablePodIMDS: false
  iam:
    withAddonPolicies:
      albIngress: false # Disable ALB Ingress Controller
      appMesh: false
      appMeshPreview: false
      autoScaler: false
      awsLoadBalancerController: true # Enable AWS Load Balancer Controller
      certManager: true # Enable cert-manager
      cloudWatch: false
      ebs: false
      efs: false
      externalDNS: true # Enable ExternalDNS
      fsx: false
      imageBuilder: true
      xRay: false
  instanceSelector: {}
  instanceType: t3.medium
  preBootstrapCommands:
    # install additional packages
    - "dnf install nvme-cli links tree tcpdump sysstat ipvsadm ipset bind-utils htop -y"
    # disable hyperthreading
    - "for n in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | cut -s -d, -f2- | tr ',' '\n' | sort -un); do echo 0 > /sys/devices/system/cpu/cpu${n}/online; done"
  labels:
    alpha.eksctl.io/cluster-name: myeks
    alpha.eksctl.io/nodegroup-name: ng1
  maxSize: 3
  minSize: 3
  name: ng1
  privateNetworking: false
  releaseVersion: ""
  securityGroups:
    withLocal: null
    withShared: null
  ssh:
    allow: true
    publicKeyName: test-key01  # 각자 환경 정보로 수정
  tags:
    alpha.eksctl.io/nodegroup-name: ng1
    alpha.eksctl.io/nodegroup-type: managed
  volumeIOPS: 3000
  volumeSize: 30
  volumeThroughput: 125
  volumeType: gp3

 

kubeconfig 파일 경로 위치 지정

export KUBECONFIG=$HOME/kubeconfig

 

EKS 최종 배포

eksctl create cluster -f myeks.yaml --verbose 4

 


3. EKS 배포 확인

EKS 클러스터 정보 확인

kubectl cluster-info
eksctl get cluster

kubectl
eksctl
AWS콘솔 > EKS > 클러스터 > 개요

 

AWS콘솔 > EKS > 클러스터 > 네트워킹

 

AWS콘솔 > EKS > 클러스터 > 액세스

 

생성된 관리형 노드 그룹 확인

eksctl get nodegroup --cluster $CLUSTER_NAME
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name ng1 | jq

eksctl
aws cli
AWS콘솔 > EKS > 클러스터 > 컴퓨팅 > 노드 그룹

 

EKS 애드온 확인

eksctl get addon --cluster $CLUSTER_NAME

eksctl
AWS콘솔 > EKS > 클러스터 > 추가 기능

 

 

컨텍스트 확인 및 변경

#컨텍스트 확인
kubectl ctx
cat $KUBECONFIG | grep current-context

현재 컨텍스트 확인

참고: 컨텍스트 이름을 짧고 알아보기 쉽게 하기위해 변경합니다.
#"<각자 자신의 IAM User>@myeks.ap-northeast-2.eksctl.io"를 "eksworkshop"으로 변경
kubectl config rename-context "aws-jgyun@myeks.ap-northeast-2.eksctl.io" "eksworkshop"
cat $KUBECONFIG | grep current-context

컨텍스트 이름 변경

 

관리형 노드들의 상태 확인

kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone

 

노드 정보

kubectl get node -v=6

verbose 모드로 확인

참고: API 요청, 응답 등 상세한 로그 확인이 가능합니다.

 

 

배포된 파드 확인

kubectl get pod -A

전체 네임스페이스에 파드 확인

PDB(Pod Disruption Budget) 확인

kubectl get pdb -n kube-system

kube-system 네임스페이스의 PDB

참고: PDB란 강제적으로 파드 종료 시 특정 개수 이상의 파드가 살아있도록 보장하는 정책입니다.
현재 확인 시 coredns와 metrics-server는 최대 1개까지 중단 가능하도록 PDB가 보장합니다.

관리형 노드 그룹 접속

인스턴스들의 공인 IP 확인 및 변수 지정

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

DescribeInstances

인스턴스 접속을 좀더 쉽게 하기 위해 공인 IP를 변수 지정해준다.

#AZ1에 배치된 EC2 공인 IP
export N1=3.35.138.154
#AZ2에 배치된 EC2 공인 IP
export N2=43.200.71.160
#AZ3에 배치된 EC2 공인 IP
export N3=52.78.202.182
#확인
echo $N1, $N2, $N3

결과 확인

Ping 테스트

현재는 보안 그룹에 접속하려는 PC의 공인IP가 등록되어 있지 않기 때문에 통신은 되지 않는다.

ping -c $N1
ping -c $N2

Ping 테스트 실패

 

접속하려는 PC의 공인IP를 관리 노드의 보안 그룹에 정책을 추가해주자.

 

보안 그룹 ID 확인 및 변수 지정

AWS 콘솔에 보안 그룹에서 nodegroup-ng1이 포함되어 있는 보안 그룹 ID를 확인한다.

AWS 콘솔 > 보안 그룹

 

aws cli로도 확인 가능하다.

aws ec2 describe-security-groups --filters "Name=group-name,Values=*nodegroup-ng1*" --query "SecurityGroups[].GroupId" --output text

aws cli

 

명령어를 쉽게 사용하기 위해 확인된 보안 그룹 ID에 대해 변수를 지정해준다.

export MNSGID=sg-0f6db4ff8723abacb

 

 

보안 그룹 정책 추가

해당 보안 그룹 Inbound 정책에 접속하려는 PC 공인 IP를 추가해준다.

aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr $(curl -s ipinfo.io/ip)/32

 

해당 보안 그룹 Inboubd 정책에 운영서버의 내부 IP도 추가해준다.

aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr 172.20.1.100/32

 

접속 확인

다시 한번 Ping을 해보면 통신이 되는 것을 확인할 수 있다.

Ping 확인

SSH 접속도 정상적으로 된다.

SSH 접속 확인

 

관리형 노드들의 정보 추가 확인 방법

# 노드 정보 확인
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i hostnamectl; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c addr; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo iptables -t nat -S; echo; done

# Node cgroup version : v1(tmpfs), v2(cgroup2fs) - Link
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i stat -fc %T /sys/fs/cgroup/; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i findmnt -t cgroup2; echo; done

#
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo systemctl status kubelet; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i ps axf |grep /usr/bin/containerd; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo tree /etc/kubernetes/kubelet/; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo cat /etc/kubernetes/kubelet/config.json | jq; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo cat /etc/kubernetes/kubelet/config.json.d/00-nodeadm.conf | jq; echo; done

# 디스크 정보
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i lsblk; echo; done
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i df -hT /; echo; done

# 컨테이너 리스트 확인
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ctr -n k8s.io container list; echo; done

# 컨테이너 이미지 확인
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ctr -n k8s.io image list --quiet; echo; done

# 태스크 리스트 확인
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ctr -n k8s.io task list; echo; done