[1주차] EKS 실습환경 구성

Minn·2026년 3월 16일

본 글은 gasida님의 AEWS 강의 및 AWS Docs, 연관 Blog 등을 참고하여 작성하였습니다.


Kubernetes와 EKS

컨테이너

  • 애플리케이션과 실행에 필요한 환경을 하나로 묶은 실행 단위
  • 어디서 실행하든 동일하게 동작 (환경 차이 제거)
  • 가볍고 빠르게 실행되며, VM보다 효율적으로 리소스를 사용

쿠버네티스 (Kubernetes, K8S)

  • 쿠버네티스는 컨테이너를 여러 노드(서버)에서 자동으로 실행/관리하는 시스템
  • 사용자가 원하는 상태(예: 프로그램 최소 3개 유지)를 설정하면, 장애 복구/스케일링/배포를 자동으로 진행

EKS

  • AWS에서 제공하는 Kubernetes 서비스, Kubernetes 클러스터 운영의 복잡성을 제거하는 완전관리형 Kubernetes 서비스
  • 쿠버네티스 운영의 오버헤드를 높히는 컨트롤 플레인을 AWS에서 관리해줌으로써 좀 더 효율적인 운영환경 제공
  • 관리 인터페이스, 액세스 제어 도구, 컴퓨팅 리소스, 스토리지, 보안, 모니터링 도구, 클러스터 기능, Kubernetes 호환성 및 지원 제공

EKS 실행 모드

Stabdard 모드

  • EKS로 클러스터를 생성할 때 AWS가 Kubernetes 컨트롤 플레인을 관리

EKS Auto 모드

  • EKS는 노드(Kubernetes 데이터 플레인)도 관리하도록 제어를 확장

Public / Private EKS

Public EKS

  • EKS를 컨트롤 하는 API 엔드포인트가 외부에 열려있음
    • API 엔드포인트는 외부에 노출되어 있기 때문에 kubectl 또한 어디서든 접근 가능
  • EKS 혹은 노드가 인터넷을 통해 AWS 서비스에 접근 가능

Private EKS

  • EKS를 컨트롤 하는 API 엔드포인트가 프라이빗 VPC에만 있음
    • 해당 VPC와 연결되어 있는 베스천 서버, DX/VPN을 통한 연동만 가능
  • EKS 혹은 노드가 인터넷을 통해 AWS 서비스에 접근 가능불가능 하여 해당 VPC내에 VPC Endpoint를 생성해야함
    • ECR (api + dkr)
    • STS
    • EC2
    • CloudWatch Logs
    • S3

EKS 구성 실습 (Public)

1. AWS 접속 환경 셋팅

  • AWS 접속 환경을 위한 셋팅 진행
# aws cli 설치 (MAC)
brew install awscli
aws --version

# iam (주체) 자격 증명 설정
aws configure

# 확인
aws sts get-caller-identity

2. EKS 설정용 툴 설치

# kubectl
brew install kubernetes-cli
kubectl version --client=true

# helm 설치
brew install helm
helm version

# 테라폼 설치
## tfenv 설치 후 테라폼 버전 확인
brew install tfenv
tfenv list-remote

## 테라폼 특정 버전 설치 및 사용 설정
tfenv install 1.14.7
tfenv use 1.14.7

## 설치한 버전 확인
tfenv list

## 테라폼 버전 정보 확인
terraform version

## 자동완성
terraform -install-autocomplete

## 자동완성 참고
cat ~/.zshrc
## autoload -U +X bashcompinit && bashcompinit
## complete -o nospace -C /usr/local/bin/terraform terraform
  • AWS CLI (AWS를 CLI로 사용하게 해주는 도구)

  • kubectl (kubernetes API를 통해 컨트롤 플레인과 통신하는 도구)

  • helm (kubernetes를 위한 패키지 관리 도구)

3. EKS 환경 배포를 위한 연습용 테라폼 코드 다운로드

aews 교육을 위한 실습코드 Git 레포를 활용합니다.

# 코드 다운로드
git clone https://github.com/gasida/aews.git
cd aews
tree aews

# 작업 디렉터리 이동
cd 1w
  • 디렉터리

4. Terraform 을 사용하여 EKS 배포

# 변수 지정
aws ec2 describe-key-pairs --query "KeyPairs[].KeyName" --output text
export TF_VAR_KeyName=$(aws ec2 describe-key-pairs --query "KeyPairs[].KeyName" --output text)
export TF_VAR_ssh_access_cidr=$(curl -s ipinfo.io/ip)/32
echo $TF_VAR_KeyName $TF_VAR_ssh_access_cidr

# 배포 : 12분 정도 소요
terraform init
terraform plan
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
tail -f create.log
  • 배포 진행
    • EKS와 관련된 52개의 리소스들이 테라폼을 통해 자동 배포됨
    • 자원 생성중...
    • VPC, 서브넷, 보안그룹, 퍼블릭 EKS 등 생성

# EKS 와의 연결을 위한 자격증명 설정
aws eks update-kubeconfig --region ap-northeast-2 --name myeks

# k8s config 확인 및 rename context
cat ~/.kube/config
cat ~/.kube/config | grep current-context | awk '{print $2}'
kubectl config rename-context $(cat ~/.kube/config | grep current-context | awk '{print $2}') myeks
cat ~/.kube/config | grep current-context

EKS 정보 확인

클러스터 정보 확인

# eks 클러스터 정보 확인
kubectl cluster-info

# endpoint 확인
CLUSTER_NAME=myeks
aws eks describe-cluster --name $CLUSTER_NAME

# dig 조회 엔드포인트 IP 소유자 조회
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS

curl -s ipinfo.io/{IP 입력}

노드그룹 정보 확인

# eks 노드 그룹 정보 확인
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-node-group | jq

# 노드 정보 확인 : OS와 컨테이너런타임 확인
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
kubectl get node --label-columns=node.kubernetes.io/instance-type

# 노드의 capacityType 확인
kubectl get node --label-columns=eks.amazonaws.com/capacityType 

kubectl get node
kubectl get node -o wide

# 인증 정보 확인
kubectl get node -v=6

파드 및 리소스 정보 확인

# 파드 정보 확인
kubectl get pod -n kube-system
kubectl get pod -n kube-system -o wide
kubectl get pod -A

# kube-system 네임스페이스에 모든 리소스 확인
kubectl get deploy,ds,pod,cm,secret,svc,ep,endpointslice,pdb,sa,role,rolebinding -n kube-system

# 모든 파드의 컨테이너 이미지 정보 확인 : dkr.ecr 저장소 확인!
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c

# kube-proxy : iptables mode, bind 0.0.0.0, conntrack 등
kubectl describe pod -n kube-system -l k8s-app=kube-proxy
kubectl get cm -n kube-system kube-proxy -o yaml
kubectl get cm -n kube-system kube-proxy-config -o yaml

# coredns 
kubectl describe pod -n kube-system -l k8s-app=kube-dns
kubectl get cm -n kube-system coredns -o yaml
kubectl get pdb -n kube-system coredns -o jsonpath='{.spec}' | jq

# aws-node : 2개의 컨테이너 - aws-node(cni plugin), aws-eks-nodeagent(network policy agent)
kubectl describe pod -n kube-system -l k8s-app=aws-node

애드온 확인

시작 템플릿 확인

노드 통신 확인

# 노드 IP 확인 및 공인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
NODE1=13.124.172.105
NODE2=15.164.250.203

# 노드의IP ping 테스트
ping -c 1 $NODE1
ping -c 1 $NODE2


# 노드 보안그룹 확인
aws ec2 describe-security-groups | jq
aws ec2 describe-security-groups --filters "Name=tag:Name,Values=myeks-node-group-sg" | jq
aws ec2 describe-security-groups --filters "Name=tag:Name,Values=myeks-node-group-sg" --query 'SecurityGroups[*].IpPermissions' --output text

APP 배포 테스트

kube-ops-view

# kube-ops-view
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 service.main.type=NodePort,service.main.ports.http.nodePort=30000 --set env.TZ="Asia/Seoul" --namespace kube-system

# 확인
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view

# kube-ops-view 접속
open "http://$NODE1:30000/#scale=1.5"
open "http://$NODE1:30000/#scale=1.3"

슈퍼마리오

# 샘플 애플리케이션 배포
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mario
  labels:
    app: mario
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mario
  template:
    metadata:
      labels:
        app: mario
    spec:
      containers:
      - name: mario
        image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
   name: mario
spec:
  selector:
    app: mario
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30001
  type: NodePort
EOF

# 확인
kubectl get deploy,pod,svc,ep

# 접속
curl http://$NODE1:30001 -I
open http://$NODE1:30001

# 구성한 환경 삭제
terraform destroy

# terraform 을 tf 로도 사용할 수 있게 하는 방법
echo 'alias tf="terraform"' >> ~/.bash_profile
source ~/.bash_profile

Private EKS

  • 인터넷이 직접 연결되어 있지 않은 영역에 EKS를 구성
  • Bastion을 통해 EKS Endpoint 접근 (SSM을 통한 Bastion 서버 접속)
  • EKS내에서 동작하고 있는 서비스는 NLB 등을 통해 외부에 오픈

  • EKS 구성시 필요한 AWS 서비스 Endpoint의 경우 VPC Endpoint 기능을 사용

참조

profile
클라우드 왕초보

0개의 댓글