2026. 3. 19. 03:21ㆍ카테고리 없음
서종호(가시다) 님의 AEWS 4기 스터디 내용 기반으로, 학습 목적으로 작성되었습니다.
노트북 정보: Macbook Pro 2019 (Intel)
EKS 란?
👉 Amazon Elastic Kubernetes Service
- AWS에서 제공하는 관리형 Kubernetes 서비스
- 사용자는 Worker Node / 애플리케이션만 관리
- AWS가 Control Plane (API Server, etcd, scheduler 등) 관리
주요 구성요소 및 역할:
- EKS Control Plane (AWS Managed):
- Kubernetes Control Plane: AWS가 관리하며, 가용성과 보안을 위해 여러 가용 영역(AZ)에 분산 배치됩니다.
- API Server: Kubernetes API를 제공하며, 모든 외부 요청을 처리합니다.
- etcd: 클러스터의 상태 및 구성을 저장하는 분산 키-값 저장소입니다.
- Scheduler: 파드(Pod)를 최적의 워커 노드에 배포하는 역할을 합니다.
- Controller Manager: 클러스터의 상태를 모니터링하고, 원하는 상태로 유지하는 역할을 합니다.
- EKS 서비스: Control Plane의 프로비저닝, 업데이트, 패치 등을 담당합니다.
- Worker Nodes (Customer Managed):
- EC2 인스턴스/Fargate: 애플리케이션 컨테이너가 실행되는 워커 노드입니다. 사용자가 직접 프로비저닝하거나, Managed Node Groups 또는 Fargate를 통해 자동 관리할 수 있습니다.
- Kubelet: 각 워커 노드에서 실행되며, Control Plane과 통신하여 파드를 관리합니다.
- Kube-proxy: 각 워커 노드에서 실행되며, 네트워크 프록시 및 로드 밸런싱 기능을 수행합니다.
- Container Runtime: 컨테이너(예: Docker, containerd)를 실행하는 런타임 환경입니다.
- VPC 및 네트워킹:
- EKS Control Plane 및 워커 노드는 지정된 VPC 내에서 통신합니다.
- Pod 네트워킹: Amazon VPC CNI 플러그인을 사용하여 파드가 VPC IP 주소를 직접 사용할 수 있습니다.
- 로드 밸런서 (ELB): 외부 트래픽을 EKS 서비스로 로드 밸런싱합니다.
- EKS 아키텍처 링크
- EKS 구성요소 링크
실습 환경 구성
AWS 계정 생성 및 기본 세팅은 https://www.youtube.com/watch?v=YZj-0MybwFY 링크를 참조
1) Terraform 설치
## EKS 클러스터 및 관련 인프라를 코드로 프로비저닝하기 위해 Terraform을 설치한다.
## 여러 버전의 Terraform을 관리할 수 있도록 tfenv를 사용한다.
> brew install tfenv
## 설치 후 list 확인
❯ tfenv list-remote
1.15.0-alpha20260304
1.15.0-alpha20260218
1.15.0-alpha20260204
1.15.0-alpha20251203
1.15.0-alpha20251119
1.14.7
...
## 1.14.7 설치 (실습코드는 1.8.5 에 맞춰져 있는데 모르고 최신으로 설치, But 문제없음)
> tfenv install 1.14.7
....
Installation of terraform v1.14.7 successful. To make this your default version, run 'tfenv use 1.14.7'
## 사용
> tfenv use 1.14.7
Switching default version to v1.14.7
...
## zsh 확인
> cat ~/.zshrc
...
autoload -U +X bashcompinit && bashcompinit
complete -o nospace -C /Users/somang/.config/tfenv/versions/1.14.7/terraform terraform
...
2) AWS CLI 구성 및 배포
2-1) awscli 설치 및 구성
# aws cli 설치
> brew install awscli
# aws 버전 확인 (2 버전 인지)
❯ aws --version
aws-cli/2.34.11 Python/3.13.12 Darwin/23.6.0 source/x86_64
❯ aws configure
AWS Access Key ID [None]: <액세스 키>
AWS Secret Access Key [None]: <시크릿 키>
Default region name [None]: ap-northeast-2
## 확인
❯ aws sts get-caller-identity
{
"UserId": "AIDAQBVPxxxxxxxxxx",
"Account": "003590xxxxx",
"Arn": "arn:aws:iam::0035xxxxx:user/admin"
}
2-2) 배포 (12분 ~ 20분 소요)
## workspace 에서 clone
❯ git clone https://github.com/gasida/aews.git
❯ cd aews
Cloning into 'aews'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 15 (delta 1), reused 13 (delta 1), pack-reused 0 (from 0)
Unpacking objects: 100% (15/15), 7.59 KiB | 554.00 KiB/s, done.
## 변수 지정
❯ 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
~/workspace/aws4/week1/aews/1w main 7s
❯ echo $TF_VAR_KeyName $TF_VAR_ssh_access_cidr
kp-somang 59.8.18x.xx/32
## 테라폼 module,provider 확인
❯ ls -al .terraform/
total 0
drwxr-xr-x 4 somang staff 128 Mar 19 00:44 .
drwxr-xr-x 7 somang staff 224 Mar 19 00:45 ..
drwxr-xr-x 6 somang staff 192 Mar 19 00:44 modules
drwxr-xr-x 3 somang staff 96 Mar 19 00:44 providers
# 배포
❯ terraform init
# plan
❯ terraform plan
...
...
Plan: 52 to add, 0 to change, 0 to destroy
# Apply
❯ nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
tail -f create.log
...
Apply complete! Resources: 52 added, 0 changed, 0 destroyed.
배포 후 AWS console 에서 확인해보기
VPC

VPC 리소스맵

서브넷

라우팅 테이블

EKS 화면

EC2 인스턴스

EKS 노드 그룹

EC2 Autoscailng 그룹

... 더 많은 것을 확인 할 수 있고, 자세한 분석 내용은 추후 다시 추가
2-3) AWS 자격증명 설정
## 자격증명 설정
❯ aws eks update-kubeconfig --region ap-northeast-2 --name myeks
Added new context arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks to /Users/somang/.kube/config
## conifg 편하게 설정
❯ kubectl config rename-context $(kubectl config current-context) myeks
Context "arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks" renamed to "myeks".
## node 확인
❯ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-1-223.ap-northeast-2.compute.internal Ready <none> 20m v1.34.4-eks-f69f56f
ip-192-168-3-173.ap-northeast-2.compute.internal Ready <none> 20m v1.34.4-eks-f69f56f
## config view 확인
❯ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://60F8DAA9BD9391BBF80D34A3EB36FC2F.gr7.ap-northeast-2.eks.amazonaws.com
name: arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks
contexts:
- context:
cluster: arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks
user: arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks
name: myeks
current-context: myeks
kind: Config
users:
- name: arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-2
- eks
- get-token
- --cluster-name
- myeks
- --output
- json
command: aws
env: null
interactiveMode: IfAvailable
provideClusterInfo: false
## region output 확인
❯ aws --region ap-northeast-2 eks get-token --cluster-name myeks --output json
{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"spec": {},
"status": {
"expirationTimestamp": "2026-03-18T16:32:40Z",
"token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFRQlZQNzRVWjdNNUFFWFVBJTJGMjAyNjAzMTglMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzE4VDE2MTg0MFomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPWNiMGZhZTVmZjE5NTBkYTMzNjJhZTI0ZGFlZDMxZGU1YTNmNDQ0OTM1ZjBhMGVjMzNlMWI2YjYzYzlkYWYxNjY"
}
}
## -v=7로 자세히 확인
❯ kubectl get node -v=7
I0319 01:19:50.027109 41362 loader.go:405] Config loaded from file: /Users/somang/.kube/config
I0319 01:19:50.029454 41362 envvar.go:172] "Feature gate default state" feature="InOrderInformers" enabled=true
I0319 01:19:50.029474 41362 envvar.go:172] "Feature gate default state" feature="InOrderInformersBatchProcess" enabled=true
I0319 01:19:50.029481 41362 envvar.go:172] "Feature gate default state" feature="InformerResourceVersion" enabled=true
I0319 01:19:50.029485 41362 envvar.go:172] "Feature gate default state" feature="WatchListClient" enabled=true
I0319 01:19:50.029489 41362 envvar.go:172] "Feature gate default state" feature="ClientsAllowCBOR" enabled=false
I0319 01:19:50.029492 41362 envvar.go:172] "Feature gate default state" feature="ClientsPreferCBOR" enabled=false
I0319 01:19:50.037585 41362 round_trippers.go:527] "Request" verb="GET" url="https://60F8DAA9BD9391BBF80D34A3EB36FC2F.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500" headers=<
Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
User-Agent: kubectl/v1.35.2 (darwin/amd64) kubernetes/fdc9d74
>
I0319 01:19:51.326539 41362 round_trippers.go:632] "Response" status="200 OK" milliseconds=1288
NAME STATUS ROLES AGE VERSION
ip-192-168-1-223.ap-northeast-2.compute.internal Ready <none> 22m v1.34.4-eks-f69f56f
ip-192-168-3-173.ap-northeast-2.compute.internal Ready <none> 22m v1.34.4-eks-f69f56f
## cluster info 확인
❯ kubectl cluster-info
Kubernetes control plane is running at https://60F8DAA9BD9391BBF80D34A3EB36FC2F.gr7.ap-northeast-2.eks.amazonaws.com
CoreDNS is running at https://60F8DAA9BD9391BBF80D34A3EB36FC2F.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
## jq 로 cluster 세부정보 확인.
❯ CLUSTER_NAME=myeks
aws eks describe-cluster --name $CLUSTER_NAME | jq
{
"cluster": {
"name": "myeks",
"arn": "arn:aws:eks:ap-northeast-2:003590317363:cluster/myeks",
"createdAt": "2026-03-19T00:48:28.866000+09:00",
"version": "1.34",
"endpoint": "https://60F8DAA9BD9391BBF80D34A3EB36FC2F.gr7.ap-northeast-2.eks.amazonaws.com",
"roleArn": "arn:aws:iam::003590317363:role/myeks-cluster-20260318154802910400000001",
"resourcesVpcConfig": {
"subnetIds": [
"subnet-010ba50bcba770fcf",
"subnet-00269fb65220d340f",
"subnet-02a8e9dc2fee8afa9"
],
"securityGroupIds": [
"sg-01b4353c6744e1659"
],
"clusterSecurityGroupId": "sg-0a6333d4c34941622",
"vpcId": "vpc-06898aebb9b471e26",
"endpointPublicAccess": true,
"endpointPrivateAccess": false,
"publicAccessCidrs": [
"0.0.0.0/0"
]
},
"kubernetesNetworkConfig": {
"serviceIpv4Cidr": "10.100.0.0/16",
"ipFamily": "ipv4",
"elasticLoadBalancing": {
"enabled": false
}
},
"logging": {
"clusterLogging": [
{
"types": [
"api",
"audit",
"authenticator",
"controllerManager",
"scheduler"
],
"enabled": false
}
]
},
"identity": {
"oidc": {
"issuer": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/60F8DAA9BD9391BBF80D34A3EB36FC2F"
}
},
"status": "ACTIVE",
"certificateAuthority": {
"data": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJU1U4VkdGaW1DU293RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBek1UZ3hOVFEzTlRoYUZ3MHpOakF6TVRVeE5UVXlOVGhhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURKWU5Oa2FudTFCVEdaL1pTYUhCS0NNcmdiY1ZUd1VxaUxXZ0MzdUdwciszYU5sVGdzdjhzd093V3YKNFUvMjViRHE1QmxZSjBpanVmbitwcU9Ma0l6RXBHNkNqRG5BbkxDTEtFSmFwYzQwN0ZKWUxRLzZOcEcreEZIRAozeEJxY0hWVERLeGVlZWZDV3AwRFVCejFpZC9YSFJ6bXlDQ2g0Y1Z5cGdkMGdFTjZGK1FianRDOTFkVGRwV1VtCi8xeUw1akpOOE1kYnprYkdjcGpWeTdVNXJJdHMzdFE3ak81dGVxS2xoM1dWVjJVbDhJWlozTDhXM3dyMjAxVXAKcWtLMUNzclUwWHRjN1dvblh2VVRQQkhTa2xwRU1EQXFmcFg1eit4T081MWRMRFJSRVJTSUtGSkhiRUJjcDJJYQozOEJqNnppdC9LWVUwbXFUdFpxTW54K0RraHBOQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJUVzVtTnJXVXBreHZEYzRVNjh5VVRiT3FKc3pUQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRRENQdFMwR3BSaApzUEl6aGtZNkdhekhGbmI5SzBObDlZdkxnS0QrWUxlK2VMbGlMb2w2UG1DcGtkRnZCN0FYZ25uSldMMjcvYm1FCnpqS0g5ZWdhazNZanVaK01ja3dmQjVEQ2lnK1ltKzU1YllBdDE1WGg5TU1DZWhBblA3MEJreDZ1RS81SUd3dEYKak1yNFpkNDU4MjJaNUh4aDZIYmhRNlZITTVKa0l5QU5zU1VlRGlBM2Vmek9jZmlpdFZqY0VlNlEzYkZKT0NkeApzNXFzZm1IYy84OXBBZDF1NUYzTlJEOTlHRXp5YW5HQngvd0dRK25keUdHSWt4ZzdjbWk4eW5ZT0xsQ3BRZHdrClhPZEpQSmJySkFLQ3g1R29hNWpKTGNDRHhmY0VRY1EyWlQ3bllhaVIxTEFEVXVuaWRCMFRQMzdWbTZ1dTlwVlUKVXpWVU1heTZzNWErCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
},
"platformVersion": "eks.18",
"tags": {
"Terraform": "true",
"Environment": "cloudneta-lab"
},
"encryptionConfig": [
{
"resources": [
"secrets"
],
"provider": {
"keyArn": "arn:aws:kms:ap-northeast-2:003590317363:key/2e308a7b-41fd-4909-ad26-182c9d565373"
}
}
],
"accessConfig": {
"authenticationMode": "API_AND_CONFIG_MAP"
},
"upgradePolicy": {
"supportType": "EXTENDED"
},
"computeConfig": {
"enabled": false,
"nodePools": []
},
"storageConfig": {
"blockStorage": {
"enabled": false
}
},
"deletionProtection": false,
"controlPlaneScalingConfig": {
"tier": "standard"
}
}
}
## 노드 라벨 확인
❯ kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
NAME STATUS ROLES AGE VERSION INSTANCE-TYPE CAPACITYTYPE ZONE
ip-192-168-1-223.ap-northeast-2.compute.internal Ready <none> 24m v1.34.4-eks-f69f56f t3.medium ON_DEMAND ap-northeast-2a
ip-192-168-3-173.ap-northeast-2.compute.internal Ready <none> 24m v1.34.4-eks-f69f56f t3.medium ON_DEMAND ap-northeast-2c
❯ kubectl get nodes -o wide --show-labels
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME LABELS
ip-192-168-1-223.ap-northeast-2.compute.internal Ready <none> 25m v1.34.4-eks-f69f56f 192.168.1.223 54.180.230.181 Amazon Linux 2023.10.20260302 6.12.73-95.123.amzn2023.x86_64 containerd://2.1.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=t3.medium,beta.kubernetes.io/os=linux,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup-image=ami-0c19bc6c6295a611b,eks.amazonaws.com/nodegroup=myeks-node-group,eks.amazonaws.com/sourceLaunchTemplateId=lt-08b1090f1913dd342,eks.amazonaws.com/sourceLaunchTemplateVersion=1,failure-domain.beta.kubernetes.io/region=ap-northeast-2,failure-domain.beta.kubernetes.io/zone=ap-northeast-2a,k8s.io/cloud-provider-aws=5553ae84a0d29114870f67bbabd07d44,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-192-168-1-223.ap-northeast-2.compute.internal,kubernetes.io/os=linux,node.kubernetes.io/instance-type=t3.medium,topology.k8s.aws/zone-id=apne2-az1,topology.kubernetes.io/region=ap-northeast-2,topology.kubernetes.io/zone=ap-northeast-2a
ip-192-168-3-173.ap-northeast-2.compute.internal Ready <none> 25m v1.34.4-eks-f69f56f 192.168.3.173 13.209.89.222 Amazon Linux 2023.10.20260302 6.12.73-95.123.amzn2023.x86_64 containerd://2.1.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=t3.medium,beta.kubernetes.io/os=linux,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup-image=ami-0c19bc6c6295a611b,eks.amazonaws.com/nodegroup=myeks-node-group,eks.amazonaws.com/sourceLaunchTemplateId=lt-08b1090f1913dd342,eks.amazonaws.com/sourceLaunchTemplateVersion=1,failure-domain.beta.kubernetes.io/region=ap-northeast-2,failure-domain.beta.kubernetes.io/zone=ap-northeast-2c,k8s.io/cloud-provider-aws=5553ae84a0d29114870f67bbabd07d44,kubernetes.io/arch=amd64,kubernetes.io/hostname=ip-192-168-3-173.ap-northeast-2.compute.internal,kubernetes.io/os=linux,node.kubernetes.io/instance-type=t3.medium,topology.k8s.aws/zone-id=apne2-az3,topology.kubernetes.io/region=ap-northeast-2,topology.kubernetes.io/zone=ap-northeast-2c
## kube-system 확인
❯ kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
aws-node-jvfk5 2/2 Running 0 25m 192.168.1.223 ip-192-168-1-223.ap-northeast-2.compute.internal <none> <none>
aws-node-klscg 2/2 Running 0 25m 192.168.3.173 ip-192-168-3-173.ap-northeast-2.compute.internal <none> <none>
coredns-d487b6fcb-dqjz4 1/1 Running 0 24m 192.168.3.91 ip-192-168-3-173.ap-northeast-2.compute.internal <none> <none>
coredns-d487b6fcb-mddg8 1/1 Running 0 24m 192.168.1.240 ip-192-168-1-223.ap-northeast-2.compute.internal <none> <none>
kube-proxy-9l8vk 1/1 Running 0 24m 192.168.3.173 ip-192-168-3-173.ap-northeast-2.compute.internal <none> <none>
kube-proxy-hclpv 1/1 Running 0 24m 192.168.1.223 ip-192-168-1-223.ap-northeast-2.compute.internal <none>
## 이미지 repo path 확인
❯ kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.21.1-eksbuild.5
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-network-policy-agent:v1.3.1-eksbuild.1
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.13.2-eksbuild.3
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.34.5-eksbuild.2
❯ aws eks list-addons --cluster-name myeks | jq
{
"addons": [
"coredns",
"kube-proxy",
"vpc-cni"
]
}
샘플 워크로드 배포
## 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
"geek-cookbook" has been added to your repositories
NAME: kube-ops-view
LAST DEPLOYED: Thu Mar 19 01:27:35 2026
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace kube-system -o jsonpath="{.spec.ports[0].nodePort}" services kube-ops-view)
export NODE_IP=$(kubectl get nodes --namespace kube-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
❯ kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kube-ops-view 1/1 1 1 18s
NAME READY STATUS RESTARTS AGE
pod/kube-ops-view-97fd86569-t6m97 1/1 Running 0 18s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-ops-view NodePort 10.100.135.199 <none> 8080:30000/TCP 18s
NAME ENDPOINTS AGE
endpoints/kube-ops-view 192.168.1.213:8080 18s
## 마리오게임 배포
# 샘플 애플리케이션 배포
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


EKS Access EndPoint 변경
현재 적용되어 있는 EKS 클러스터 서버에 접속은 public 환경에서 접근은 가능하지만, private 환경에서는 접근이 불가능하다. 다만, public 환경으로 운영하기에는 보안상으로 좋지 않아 private로 운영함. private로 바꿔보자.
현재 API 서버 엔드포인트 엑세스는 아래와 같다.

아래 명령어로, 워커 노드 -> EKS API Server 통신을 확인해보자.
--------------------------------------------------------------------
| DescribeInstances |
+------------------+-----------------+------------------+----------+
| InstanceName | PrivateIPAdd | PublicIPAdd | Status |
+------------------+-----------------+------------------+----------+
| myeks-node-group| 192.168.1.223 | 54.180.230.xxx | running |
| myeks-node-group| 192.168.3.173 | 13.209.89.xxx | running |
+------------------+-----------------+------------------+----------+
##
for i in $NODE1 $NODE2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp | grep -v ssh; echo; done
>> node 54.180.230.xxx <<
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 192.168.1.212:57246 3.37.98.54:443 users:(("kubelet",pid=2234,fd=19))
ESTAB 0 0 192.168.1.212:49442 3.37.98.54:443 users:(("aws-k8s-agent",pid=2456,fd=7))
ESTAB 0 0 192.168.1.212:47474 3.37.98.54:443 users:(("kube-proxy",pid=2865,fd=6))
>> node 13.209.89.xxx <<
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 192.168.3.13:38492 3.37.98.54:443 users:(("aws-k8s-agent",pid=2458,fd=7))
ESTAB 0 0 192.168.3.13:52588 3.37.98.54:443 users:(("kubelet",pid=2236,fd=31))
ESTAB 0 0 192.168.3.13:38638 3.37.98.54:443 users:(("kube-proxy",pid=2861,fd=6))
3-2) 테라폼 코드 수정
# eks.tf 의 아래 내용 수정
endpoint_public_access = true
endpoint_private_access = true
endpoint_public_access_cidrs = [
var.ssh_access_cidr # (내공인 IP)
]
# terraform apply -auto-approve
3-3) 적용 후 DNS 질의 반복
while true; do ssh ec2-user@$NODE1 dig +short $APIDNS ; date ; echo "-----" ; sleep 1 ; done
54.180.230.xxx
13.209.89.xxx
-----
192.168.1.xxx
192.168.3.xxx
3-4) 실습 완료 후 삭제
nohup sh -c "terraform destroy -auto-approve" > delete.log 2>&1 &
tail -f delete.log
도전과제 1) aws eks vs vanilla k8s 간 controlplane , dataplane 비교 정리 해보기
1. 컨트롤 플레인 (Control Plane) 비교
컨트롤 플레인은 쿠버네티스 클러스터의 '두뇌' 역할을 하며, 클러스터의 상태를 관리하고 스케줄링 및 API 요청을 처리합니다.
비교 요약
| 구분 | Vanilla Kubernetes (바닐라 쿠버네티스) | AWS EKS (Elastic Kubernetes Service) |
|---|---|---|
| 관리 주체 | 사용자 직접 관리 | AWS (Managed Service) |
| 인프라 구성 | 사용자가 가상 머신(VM) 또는 베어메탈 서버를 직접 준비하고 마스터 노드를 구성 | AWS가 컨트롤 플레인 인프라(EC2 인스턴스)를 프로비저닝하고 관리 |
| 고가용성 (HA) | 사용자가 직접 3대 이상의 마스터 노드를 구성하고 로드 밸런싱 설정 필요 | 기본적으로 고가용성 제공. AWS가 여러 가용 영역(AZ)에 걸쳐 컨트롤 플레인을 분산 배치 |
| 업데이트/패치 | 사용자가 수동으로 쿠버네티스 버전을 업데이트하고 OS 패치를 수행 (중단 발생 가능성 있음) | EKS 콘솔 또는 CLI를 통해 손쉽게 업데이트 가능. AWS가 운영 체제 패치 및 백업을 담당하며 중단 최소화 |
| 보안 | 사용자가 API 서버 인증, 암호화 설정, 방화벽 등을 직접 구성 | IAM(Identity and Access Management)과 통합되어 세밀한 권한 제어 가능. AWS 수준의 보안 모범 사례 적용 |
구성도 설명 (Vanilla k8s vs EKS):
위 이미지에서 'Control Plane' 박스 전체를 바닐라 쿠버네티스에서는 사용자가 직접 VM에 설치하고 구성해야 하지만, EKS에서는 AWS가 이 영역을 완전히 관리해주기 때문에 사용자에게 보이지 않습니다. 사용자는 단지 AWS가 제공하는 API 서버 엔드포인트를 통해 클러스터와 상호작용할 뿐입니다.
2. 데이터 플레인 (Data Plane) 비교
데이터 플레인은 실제 애플리케이션 컨테이너(Pod)가 실행되는 '작업 공간'입니다. 워커 노드(Worker Node)로 구성됩니다.
비교 요약
| 구분 | Vanilla Kubernetes (바닐라 쿠버네티스) | AWS EKS (Elastic Kubernetes Service) |
|---|---|---|
| 노드 프로비저닝 | 사용자가 워커 노드용 VM을 직접 생성하고 컨테이너 런타임, kubelet, kube-proxy 등을 설치 및 구성 | 자동화된 노드 그룹 관리. EKS 관리형 노드 그룹(Managed Node Groups)을 통해 EC2 인스턴스 자동 생성 및 스케일링 지원 |
| OS 및 런타임 관리 | 사용자가 OS 이미지 선택, 보안 패치, 컨테이너 런타임 버전 관리 수행 | AWS EKS 최적화 AMI 제공. 최적화된 OS와 런타임이 포함된 AMI를 통해 노드 구성 단순화 |
| 네트워킹 | 사용자가 CNI(Container Network Interface) 플러그인(예: Calico, Flannel)을 선택하고 직접 설치 및 구성 | Amazon VPC CNI 기본 제공. AWS VPC 네트워킹과 통합되어 노드와 파드가 VPC IP를 직접 사용. 고성능 네트워킹 지원 |
| 서버리스 워커 | 지원하지 않음. 모든 노드는 서버 형태 | AWS Fargate 지원. 서버 인프라 관리 없이 파드를 직접 실행하는 서버리스 운영 모드 지원 |
| 스케일링 | Cluster Autoscaler 등을 직접 설치하고 클라우드 제공업체의 API와 연동 설정 필요 | Cluster Autoscaler, Karpenter 등과 손쉽게 연동. EKS와 통합되어 자동 스케일링을 효율적으로 관리 |
구성도 설명 (Vanilla k8s vs EKS):
위 이미지에서 'Node' 박스 내부의 구성 요소들(Container Runtime, Kubelet, Kube-proxy)을 바닐라 쿠버네티스에서는 사용자가 모든 노드에 직접 설치하고 관리해야 합니다. 하지만, EKS 관리형 노드 그룹을 사용하면 이 과정이 자동화되어 사용자는 노드의 이미지(AMI)와 인스턴스 유형만 선택하면 됩니다. 또한, Fargate를 사용하면 이 데이터 플레인 인프라 자체를 관리할 필요가 없습니다.
3. 종합 비교 정리
| 특징 | Vanilla Kubernetes (바닐라 쿠버네티스) | AWS EKS (Elastic Kubernetes Service) |
|---|---|---|
| 주요 장점 | 완벽한 제어 권한, 클라우드 종속성 없음, 원하는 하드웨어/OS 구성 가능 | 관리 부담 최소화, 빠른 프로비저닝, AWS 서비스와의 강력한 통합, 고가용성 기본 제공 |
| 주요 단점 | 높은 운영 복잡도, 전문 지식 필요, 고가용성 구성 및 유지보수가 어려움 | AWS 서비스 비용 발생, 특정 클라우드 제공업체에 종속될 가능성 |
| 적합한 유즈케이스 | 강력한 제어 권한이 필요한 경우, 온프레미스 환경, 클라우드 비용을 최소화하고 싶은 경우 | 빠르고 안정적으로 서비스를 배포하고 싶은 경우, 운영 부담을 줄이고 개발에 집중하고 싶은 경우 |
결론
- 운영 오버헤드: EKS는 AWS가 컨트롤 플레인을 관리해주고 데이터 플레인 관리 효율성을 높여주기 때문에 운영 오버헤드가 훨씬 적습니다.
- 제어 권한: 바닐라 쿠버네티스는 클러스터 전체에 대한 완벽한 제어 권한을 제공하지만, EKS는 컨트롤 플레인에 대한 직접적인 접근이 제한됩니다.
- 비용: EKS는 클러스터 관리 비용과 AWS 리소스 비용이 발생하지만, 바닐라 쿠버네티스는 직접 인프라를 구축하고 운영하는 비용이 발생합니다.
따라서 클러스터 구성 및 운영에 대한 전문 지식과 리소스가 부족하거나, AWS 서비스와의 통합이 중요하고 빠른 서비스 배포가 우선이라면 EKS가 좋은 선택입니다. 반면에 강력한 제어 권한이 필요하고 클라우드 종속성을 피하고 싶거나, 직접 인프라를 운영할 수 있는 역량이 있다면 바닐라 쿠버네티스를 고려할 수 있음.
후기)
- 다른 스터디원의 블로그 글을 보고 더 자세하고 가독성있게 글 쓸 필요가 있음.