1주차 - EKS 준비

개요

이 문서에서는 기본적인 EKS를 사용하는 시간을 가져본다.
과거에는 eksctl을 이용했는데, 사실 eks를 만드는 데에는 다양한 방법이 있다.
이번에는 총 5가지 방법을 활용해보고 각각을 비교해볼 것이다.

글 전개에 대해

원래 이 노트는 클라우드넷 AEWS 스터디 1주차를 진행하기 이전에 혼자 먼저 실습을 하기 위해 마련한 노트이다.
그러나 일이 생겨 제 시간에 의도했던 바를 전부 마치지 못 했고, 이에 따라 스터디에서 배운 내용은 뒤늦게 병합하며 글을 진행한다.
또한 이 글은 단순 외부 전파보다는 내 복습과 지식 습득을 우선 목표로 삼는다.
완전히 정리된 글은 다른 글에서 진행한다.

요구 사항

내 터미널에서 접근 가능하도록 kubeconfig 파일을 내 로컬에 받을 수 있도록 설정.
클러스터 구축만을 목표로 하기 때문에 최소한의 사양을 통해서 만들 것이다.
실습을 마친 후 각 리소스는 완벽하게 정리돼야만 한다.

기본 설치

클라우드네타 팀에서 제공하는 클라우드 포메이션을 이용하여 설치를 진행한다.
이후에 알게 됐지만, 이 방법은 구체적으로 먼저 인프라 환경을 구성해놓은 뒤에 eksctl을 이용해서 구축을 하는 방식이다.
Pasted image 20250202115238.png
클라우드넷팀에서 제공해준 클포 양식이 이미 있으므로, 해당 양식을 통해 먼저 진행한다.
이걸 먼저 하는 것은 이걸 기준으로 다른 수단으로 같은 리소스들을 만들기 위함이다.
만약 직접 클포를 사용한다면, 직접 템플릿을 만드는 것이 당연히 선행돼야 한다.
Pasted image 20250202115408.png
먼저 인프라 컴포저로 어떤 구성이 돼있는지 확인해보자.
하나의 VPC안에 서브넷을 4개 배치한다.
퍼블릭과 프라이빗 각각 2개씩 배치한 후, eks에 접근할 수 있는 바스티온 격 EC2도 하나 두는 모습을 볼 수 있다.
Pasted image 20250202115954.png
해당 ec2에 대해서는 kubectl과 관련된 유틸 툴들을 설치한다.
생각보다 클포 양식이 간단해서, aws만 사용하는 사용자라면 충분히 클포는 좋은 선택지가 되어줄 것 같다.
특히 관련한 리소스들을 함께 구축하고자 한다면 편할 것으로 생각한다.

curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.31.2/2024-11-15/bin/linux/amd64/kubectl
왜 aws에서 사용하는 놈으로 kubectl을 설치하는가?
어떤 차이가 있어서?
git version을 보면 eks 꺼인데, 왜?

이 부분들은 직접 설정을 해야 하도록 제공해주었다.
키는 ssh 키페어를 지정하면 된다.
그리고 ssh를 할 수 있는 공인 ip 대역도 지정해준다.
아무나 접속하면 안 되니까..
다만 지금은 카페에서 하고 있고, 금방 클러스터를 종료시킬 거라 그대로 전부 받도록 설정했다.

구축 전 확인

만들어지는데는 총 1분 30초 가량이 걸렸다.
아무리 봐도 eks 관련한 요소는 없어서 봤는데, eks가 아니라 일단 기본 인프라를 배포하는 양식이었다.
여기에 직접적으로 eksctl을 사용하는 것이다.

내 로컬에서 ec2에 ssh로 접근했다.

이전 유저 데이터를 통해서 필요한 툴은 정말 다 설치가 됐다.

현재 ec2 인스턴스에는 어떠한 신원도 세팅되어 있지 않아 클러스터를 구축할 수 없으므로, 일전에 만들어둔 IAM 유저 정보를 넣어 세팅을 해줄 것이다.
이를 위해서는 먼저 액세스 키를 발급해서 넣어주면 된다.

aws configure를 통해 신원 정보를 넣어주고 확인해보면 이렇게 정상적으로 리소스에 접근할 수 있다.
이제 간단한 확인을 거친 후 바로 세팅에 들어간다.

먼저 vpc를 환경변수로 설정해준다.

이제 편하게 서브넷 id를 알 수 있다.

각 서브넷도 환경 변수로 올린다.

aws eks describe-addon-versions --kubernetes-version 1.29 --query 'addons[].{MarketplaceProductUrl: marketplaceInformation.productUrl, Name: addonName, Owner: owner Publisher: publisher, Type: type}' --output text | wc -l 

이런 식으로 쿠버네티스 버전에 따른 애드온 개수를 알 수 있다.

해봤을 때 1.32는 아직 애드온이 많지 않은 것이 확인된다.

애드온이라 하믄 클러스터의 기본이 될 만한 각종 운영 요소들을 이야기한다.

ADDON_NAME=aws-ebs-csi-driver 
aws eks describe-addon-versions --addon-name $ADDON_NAME | jq -r ' .addons[] | .addonVersions[] | select(.architecture[] | index("amd64")) | [.addonVersion, (.compatibilities[] | .clusterVersion), (.compatibilities[] | .defaultVersion)] | @tsv'

이렇게 하면 애드온 별로 호환되는 eks 버전을 확인할 수 있다.

aws cli의 query 인자 사용법을 아직 잘 몰라서 명확하진 않지만, 원래는 줄바꿈되어 호환에 대한 내용이 나왔어야 했으려나..?
애드온을 쓴다면, 버전을 확인하는 게 꼭 중요하다.
그래서 eks 쓸때는 기왕이면 최신 버전에서 두어 버전 정도 뒤거를 쓰는 게 좋을 것 같다.
그러면서 열심히 버전을 따라가긴 해야겠지.

aws eks describe-addon-versions --addon-name $ADDON_NAME | jq -r '
  .addons[] |
  .addonVersions[] |
  select(.architecture[] | index("amd64")) |
  "AddonVersion:\t" + .addonVersion,
  "ClusterVersion:\t" + ([.compatibilities[].clusterVersion] | join("\t")),
  "DefaultVersion:\t" + ([.compatibilities[].defaultVersion | tostring] | join("\t")),
  ""
'

애드온 버전 호환성을 조금 더 이쁘게 출력하는 방법을 찾아봤다.

eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --dry-run | yh

yh 명령어는 처음 알았네..
기본 클러스터를 생성하는 yaml 파일을 확인해본다.

이런 식으로 구성이 돼있다.
이건 노드 그룹을 구성하지 않고 만드는 옵션이다.

eksctl create cluster --name myeks --region=ap-northeast-2 --nodegroup-name=mynodegroup --node-type=t3.medium --node-volume-size=30 --zones=ap-northeast-2a,ap-northeast-2c --vpc-cidr=172.20.0.0/16 --ssh-access --node-ami-family Ubuntu2004 --dry-run | yh

이런 식으로 세부 옵션을 지정하며 진행하는 것도 가능하다.

처음 보는 것만 말하자면 --ssh-access 옵션을 넣어 현재 호스트에서 ssh로 접속이 가능하게 한다는 것.
이런 식으로 ssh에 대한 정보도 나오게 된다.

본격 구축

while true; do 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 text ; echo "------------------------------" ; sleep 1; done 
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

이렇게 옵션을 넣어서 본격적으로 구축하기 이전에 실시간으로 상태를 모니터링할 수 있도록 해보자.
(스크립트 짜신 분의 노고를 치하합니다.)

이렇게 지속적으로 출력을 거는 터미널을 하나 띄운 채로 시작한다!

eksctl create cluster --name $CLUSTER_NAME --region=$AWS_DEFAULT_REGION --nodegroup-name=$CLUSTER_NAME-nodegroup --node-type=t3.medium --node-volume-size=30 --vpc-public-subnets "$PubSubnet1,$PubSubnet2" --version 1.31 --ssh-access --external-dns-access --dry-run --verbose 4 | yh

이렇게 옵션을 넣어서 세팅할 것이다.

eksctl은 클라우드 포메이션을 이용해서 클러스터를 구축해준다.
사실 eks 클러스터 자체가 클포로 구성이 되기 때문에 당연한 말이기는 하다.

그래서 클포 에 들어가서 보면 이렇게 진행 상황을 확인할 수 있다.
배포에는 15분 정도의 시간이 소요된다.

조금 기다리다보니 한무 스크립트에 서서히 ec2가 생기는 것이 보인다.

# krew 플러그인 확인
kubectl krew list
kubectl ctx
kubectl ns
kubectl ns default
kubectl get-all    # 모든 네임스페이스에서 모든 리소스 확인

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

krew를 통해 kubectl과 관련된 플러그인들이 설치됐고, 이를 토대로 편의를 도모할 수 있다.
나는 여즉껏 kubectx, kubens를 사용해본적 없었는데, 이렇게 플러그인으로 편하게 사용할 수 있다는 것은 또 처음 알았다.
하긴, Calico만 이런 식의 플러그인을 제공할 리가 없으니, 내가 활용법을 더 생각하지 못한 탓이로다.

컨트롤 플레인 정보 확인

eksctl get cluster
aws eks describe-cluster --name $CLUSTER_NAME | jq
aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint

eksctl, aws cli를 이용해 클러스터에 대한 정보를 얻을 수 있다.
맨 아래 명령어를 통해서는 외부에서 클러스터 api 서버에 접근할 url 정보를 알 수 있다.

## dig 조회 : 해당 IP 소유 리소스는 어떤것일까요? : 자신의 PC에서도 해당 도메인 질의 조회 해보자
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS

dig 명령어를 통해서 ip를 조회해보자.
Pasted image 20250203014652.png
나중에 따로 정리할 것 같지만, dig는 DNS에 대한 상세 정보를 분석할 수 있도록 도와주는 도구이다.[1]
nslookup은 단순하게 도메인 네임 서버에 질의하여 도메인에 대한 ip 주소를 알려주는 기능으로 끝이지만 dig는 도메인에 대한 쿼리 진행 시간과 ttl 등의 정보도 확인할 수 있다.
여기에서는 간단하게 어떤 ip들이 나오는지만, nslookup 처럼 조회한다.

# eks API 접속 시도 : 도메인 or 출력되는 ip 주소로 https://<IP>/version 외부에서도 접속 가능!
curl -k -s $(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint)
curl -k -s $(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint)/version | jq

api 서버에 내리는 모든 명령은 그냥 rest api라 그냥 이런 식으로도 정보를 얻어낼 수 있다.

# eks 노드 그룹 정보 확인
eksctl get nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup
aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup | 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
kubectl get node
kubectl get node -owide
# 노드의 capacityType 확인
kubectl get node --label-columns=eks.amazonaws.com/capacityType

각종 정보들을 확인해본다.


# 인증 정보 확인 : 자세한 정보는 보안에서 다룸
kubectl get node -v=6
I0423 02:00:38.691443    5535 loader.go:374] Config loaded from file:  /root/.kube/config
I0423 02:00:39.519097    5535 round_trippers.go:553] GET https://C813D20E6263FBDC356E60D2971FCBA7.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 200 OK in 818 milliseconds
...
cat /root/.kube/config
kubectl config view
kubectl ctx

여기에서 아주 재밌는 것을 볼 수 있는데, kubeconfig 파일의 차이이다.
온프레미스 환경에서는 그냥 x509 인증서를 kubeconfig 파일에 넣어서 인증 인가를 수행한다.
그러나 eks에서는 파일의 모습이 상당히 다른데, 이것은 구체적으로 인증을 받을 수 있는 토큰을 발급 받아서 진행하는 것이다.

## Get a token for authentication with an Amazon EKS cluster
aws eks get-token help 
aws eks get-token --cluster-name $CLUSTER_NAME --region $AWS_DEFAULT_REGION

이런 식으로 말이다.
실제로 이렇게 또 토큰을 받아볼 수 있다.
그러면 이 토큰을 발급 받는 과정은 매번 수행되는가?
캐시되지는 않는가?
받는 토큰은 무엇인가?
내 생각에는 jwt 토큰일 것 같은데, 기본으로는 OIDC를 사용하지 않는 것으로 안다.

# for ARM systems, set ARCH to: `arm64`, `armv6` or `armv7`
ARCH=amd64
PLATFORM=$(uname -s)_$ARCH

curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"

# (Optional) Verify checksum
curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check

tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz

sudo mv /tmp/eksctl /usr/local/bin

참고로 이건 eksctl을 다운 받는 방법이다.[2]
컨테이너를 이용하는 방법도 있으나, 자동완성을 하기가 어려워서 사용하지 않는다.

# 파드 정보 확인 : 온프레미스 쿠버네티스의 파드 배치와 다른점은? , 파드의 IP의 특징이 어떤가요? 자세한 네트워크는 2주차에서 다룸
kubectl get pod -n kube-system
kubectl get pod -n kube-system -o wide

이건 살짝 다음 주 스포인데, 파드들은 vpc의 ip 대역을 공유한다.

kubectl get pod -A
kubectl top node
kubectl top pod -A
kubectl get-all -n kube-system
kubectl get-all
# 모든 파드의 컨테이너 이미지 정보 확인
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.19.0-eksbuild.1
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-network-policy-agent:v1.1.5-eksbuild.1
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.11.3-eksbuild.1
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.31.2-minimal-eksbuild.3
      2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/metrics-server:v0.7.2-eksbuild.1

아주 단순한 내용물 조회, 메트릭 조회라 부연하지 않겠다.
그러나 마지막 명령어는 내가 잘 몰라서 남겨본다.
모든 네임스페이스에서 컨테이너들의 이미지를 나열한다.
이때 tr(translate)로 연속된 문자는 하나로 축소하는데(-s) 이 대상은 공백 문자([[:space:]])이다.
그리고 해당 문자들은 전부 개행으로 바꿔버린다.
그 상태에서 정렬한 이후 중복 항목을 제거하면서 개수(-c)를 센다.
결국 모든 이미지들을 불러와서 각각의 개수를 세고 무엇인지까지 출력해주는 명령어인 것이다.

eks 빌드와 관련된 파드들이 나오는 것이 보인다.

eks 컨트롤 플레인의 구성도도 나온 자료가 있으니 보자.

노드 정보 확인

# 노드 IP 확인 및 PrivateIP 변수 지정
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
kubectl get node --label-columns=topology.kubernetes.io/zone
kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a
kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo $N1, $N2
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile

# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트
ping <IP>
ping -c 1 $N1
ping -c 1 $N2

단순하게 노드에 ping 테스트를 하면 막힐 것이다. 우리는 함부로 인스턴스에 접근할 권한이 주어져 있지 않다.
보안그룹에서 일단 막고 있기 때문이다.

# 노드 보안그룹 ID 확인
aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text)
echo $NGSGID
echo "export NGSGID=$NGSGID" >> /etc/profile

# 노드 보안그룹에 eksctl-host 에서 노드(파드)에 접속 가능하게 룰(Rule) 추가 설정
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32

보안그룹을 업데이트한다.
-1은 허용인데, 호스트 인스턴스를 허용하도록 추가를 해준 것이다.
이제부터는 제대로 ssh, ping 등의 통신이 가능하게 된다.
클러스터 구축 시 ssh access를 설정했기에 설정을 진행했던 호스트의 정보를 통해 접근하는 것이 가능하다.

# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트
ping -c 2 $N1
ping -c 2 $N2

# 워커 노드 SSH 접속
ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no ec2-user@$N1 hostname
ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no ec2-user@$N2 hostname
ssh ec2-user@$N1
exit
ssh ec2-user@$N2
exit

간단하게 테스트를 해본다.

# AWS VPC CNI 사용 확인
kubectl -n kube-system get ds aws-node
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
kubecolor describe pod -n kube-system -l k8s-app=aws-node

# 파드 IP 확인
kubectl get pod -n kube-system -o wide
kubectl get pod -n kube-system -l k8s-app=kube-dns -owide

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

for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i stat -fc %T /sys/fs/cgroup/; echo; done

각 노드의 네트워크 정보를 확인해본다.

for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo systemctl status kubelet; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo pstree; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ps afxuwww; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ps axf |grep /usr/bin/containerd; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ls /etc/kubernetes/manifests/; echo; done    # EKS static pod X
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ls /etc/kubernetes/kubelet/; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i cat /etc/kubernetes/kubelet/kubelet-config.json | jq; echo; done

프로세스, kubelet 관련 설정을 본다.

for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i lsblk; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i df -hT /; echo; done

디바이스 크기도 본다.

# kubelet, kube-proxy 통신 Peer Address는 어딘인가요?
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done

# 참고
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS

# [터미널] 파드 1곳에 shell 실행해두기
## kubectl 명령으로 특정 파드에 접근 (경로) : 작업PC -> API Server -> kubelet -> pod
kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh
$ ip -c a
$ watch uptime
kubectl exec daemonsets/aws-node -it -n kube-system -c aws-eks-nodeagent -- bash

# exec 실행으로 추가된 연결 정보의 Peer Address는 어딘인가요? + AWS 네트워크 인터페이스 ENI에서 해당 IP 정보 확인
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
...
ESTAB 0      0      [::ffff:192.168.1.129]:10250 [::ffff:192.168.1.7]:38238 users:(("kubelet",pid=2933,fd=9))
...

여기에서, exec이나 logs를 실행하면 api 서버가 노드로의 세션을 클라이언트와 유지해준다.
이때 내부에 eni가 하나 더 생기는 것을 확인할 수 있다.

# 노드1 접속
ssh ec2-user@$N1
----------------
# IMDSv2 메타데이터 정보 확인
TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ ;echo
eksctl-myeks-nodegroup-myeks-nodeg-NodeInstanceRole-4nyRq1rhLJLd

curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/eksctl-myeks-nodegroup-myeks-nodeg-NodeInstanceRole-4nyRq1rhLJLd | jq

여기에서 신기한 포인트.
eks 클러스터 엔드포인트

클라우드에서 쓰이는 컨트롤러가 있는데, 이것이 바로 cloud controller manager라고 부른다.
이번에 auto mode, hybrid mode를 다룰 것이다.

노드 유형은 다양하다.

https://awskrug.github.io/eks-workshop/spotworkers/
스팟인스턴스 실습

kata컨테이너.
vm별로 파드 하나.
샌드박스

https://whchoi98.notion.site/Hosting-DeepSeek-R1-on-Amazon-EKS-18b04ef7e60e80d3b714d55a667a4033?pvs=4
eks에 딥시크를 배포하는 방법에 대한 글이다.


공인으로 접속할 수 있도록 돼있다.


정보가 이렇게 출력된다.
공인 ip로 접근이 가능하게 돼있다.

api 서버의 공인 ip가 이렇게 두 개 있다는 것도 확인할 수 있다.
nlb가 설정해주는 방식이다.
근데 그냥 내 로컬에서 해당 명령어를 한다면?


kubeconfig에서는 유저에 대해 이렇게 출력이 나온다.
온프렘과 상당히 다르다.
aws에 어떤 명령을 수행하는데, 이게 eks에 대해 토큰을 받아오는 작업을 진행하여 요청을 수행하는 것이다.
이거 비용적 문제는 없는가?

# AWS VPC CNI 사용 확인
kubectl -n kube-system get ds aws-node
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
kubecolor describe pod -n kube-system -l k8s-app=aws-node

# 파드 IP 확인
kubectl get pod -n kube-system -o wide
kubectl get pod -n kube-system -l k8s-app=kube-dns -owide

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

eks owned eni를 조금더 상세히 확인해보자.

# kubelet, kube-proxy 통신 Peer Address는 어딘인가요?
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done

# 참고
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS


이걸 뜯어보면, kubelet와 proxy가 퍼블릭 ip를 통해 통신하는 것이 보인다.
이걸 수정하는 것이 안정적일 것이다.
비용적으로도 차이가 발생할 것 같다.


# [터미널] 파드 1곳에 shell 실행해두기
## kubectl 명령으로 특정 파드에 접근 (경로) : 작업PC -> API Server -> kubelet -> pod
kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh
$ ip -c a
$ watch uptime
kubectl exec daemonsets/aws-node -it -n kube-system -c aws-eks-nodeagent -- bash

# exec 실행으로 추가된 연결 정보의 Peer Address는 어딘인가요? + AWS 네트워크 인터페이스 ENI에서 해당 IP 정보 확인
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
...
ESTAB 0      0      [::ffff:192.168.1.129]:10250 [::ffff:192.168.1.7]:38238 users:(("kubelet",pid=2933,fd=9))
...


exec을 하니 하나가 더 추가됐다.
eni에서 확인

eni를 보니 하나가 있는데, 이 놈은 instance 오너가 내가 아니다!

퍼블릭 액세스를 해도, kubelet으로 가는 요청은 사실 eks eni를 거친다.
하나의 컨테이너에 세션을 유지하고 있따보니 이 놈이 같이 잡혀 있는 것이다.
이건 결국 내부로 들어가서 통신을 하게 된다.
컨트롤 플레인과 데이터플레인은 eni를 만들어서 접근하고, 이 소유자는 우리가 아니라는 것이 핵심이다.

iam 롤을 보자.

컨트롤 플레인, 데이터 플레인을 각각 본 것이다.

이제 보안 그룹.

eks도 보안이 중요하니, teleport로 사용할 수 있다.
대기업은 사용할 수 없다고 한다..?

https://www.querypie.com/ko/products/kubernetes-access-controller
이건 api 보안 내용이다.
접근 제어 솔루션

krew로 neat가 있다.
이걸로 조금 필요한 정보들만 편하게 볼 수 있따.

애드온을 추가해보자.

콘솔로도 쉽게 할 수 있따.
Pasted image 20250202221536.png
애드온이 설치되기 전에는, 이렇게 메모리, 디스크 관련 정보만 컨디션에 나온다.
Pasted image 20250202221614.png
그런데 애드온을 넣으면 다른 정보들도 나오게 된다.

krew로 stern을 쓰면 파드 로그도 볼 수 있따.

eks 클러스터 웹 대시 보드도 존재한다.

자원삭제는 두 단계로.

https://www.youtube.com/watch?v=2LEFG3MlaqQ

해야할 내용

심화 진행

혼자 다시 진행

이번에는 내 로컬에서 eks를 배포한다.

curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz" | tar xz -C /tmp 
mv /tmp/eksctl /usr/local/bin

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 
unzip awscliv2.zip >/dev/null 2>&1 
./aws/install 
complete -C '/usr/local/bin/aws_completer' aws 
echo 'export AWS_PAGER=""' >>/etc/profile 
export AWS_DEFAULT_REGION=${AWS::Region} 
echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile

일단 관련 툴을 설치했다.
그리고 이전에서 조금 다르게 호스트만 빼고 배포를 진행한다.

aws cloudformation deploy --template-file ~/Downloads/myeks-1week.yaml --stack-name myeks --region ap-northeast-2
aws ec2 describe-vpcs | jq  -r '.Vpcs[] | select(has("Tags") and .Tags[].Value == "myeks-VPC").VpcId'

이렇게 vpc id를 꺼낼 수 있다.

aws ec2 describe-subnets | jq '.Subnets[] | select(.VpcId == env.VPCID).SubnetId'

해당 id를 환경변수로 등록한 다음에는 서브넷 id를 꺼낼 수 있다.

aws eks describe-addon-versions --kubernetes-version 1.32  --query 'addons[].{MarketplaceProductUrl: marketplaceInformation.productUrl, Name: addonName, Owner: owner Publisher: publisher, Type: type}' --output table

쿠버네티스 버전에 따라 존재하는 애드온 목록을 출력할 수 있다.

ADDON_NAME=coredns
aws eks describe-addon-versions --addon-name $ADDON_NAME | jq -r ' .addons[] | .addonVersions[] | select(.architecture[] | index("amd64")) | "AddonVersion:\t" + .addonVersion, "ClusterVersion:\t" + ([.compatibilities[].clusterVersion] | join("\t")), "DefaultVersion:\t" + ([.compatibilities[].defaultVersion | tostring] | join("\t")), "" '

이런 식으로 애드온 별로 호환되는 버전에 대한 정보도 확인할 수 있다.
최근이면서 그나마 많은 애드온을 지원하고 있는 1.31버전을 설치하도록 한다.

본격 설치 준비

yaml 파일로 만들어서 설치를 진행해보자.[3]

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: aews-eks
  region: ap-northeast-2
  version: "1.31"
vpc:
  id: "vpc-05f8e356fa0616959"
  # subnets:
  #   public:
  #     ap-northeast-2a:
  #       id: ""
  #     ap-northeast-2c:
  #       id: ""
managedNodeGroups:
  - name: myeks-nodegroup
    instanceType: t3.medium
    subnets:
      - "subnet-074dfae00dec0a3a5"
      - "subnet-04abe639c8c534ec3"
    volumeSize: 20
    ssh:
      allow: true
      publicKeyPath: ../pki/pub.pub
      # new feature for restricting SSH access to certain AWS security group IDs
      #sourceSecurityGroupIds: ["sg-00241fbb12c607007"]
    labels: {org: aews}
    iam: 
      withAddonPolicies: 
        externalDNS: true

이런 식으로 만들어봤다.
vpc id를 명시할 경우, 안에 활용하게 될 서브넷도 같이 명시하지 않으면 에러가 발생한다.

콘솔 확인

eks 확인

Pasted image 20250204150356.png
제대로 됐다면 이런 식으로 표시가 될 것이다.
Pasted image 20250204150452.png
이건 iam으로는 확인이 안 되고 있어서 아직 조금 잘 모르겠는데, 내가 eks를 만들 때 root 계정으로 만들어버려서 그런 것 같다.
폴리시들을 추가해봐도 잘 되진 않는다.
이건 나중에 추가적으로 더 확인해봐야할 듯.

보안 그룹 확인

Pasted image 20250204150347.png
생성된 보안 그룹들도 확인해보자.
Pasted image 20250204125504.png
ssh 허용을 하여 생긴 보안 그룹 말고 3개의 보안 그룹이 있는 것이 확인된다.

네트워크 인터페이스 확인

Pasted image 20250204150913.png
5개의 인터페이스가 만들어진 것이 확인된다.
Pasted image 20250204151012.png
이중에서 이름 붙여진 것들은 워커 노드들이 기본적으로 가지게 되는 네트워크 인터페이스이다.
퍼블릭 서브넷에 노드를 배치했기에 퍼블릭 ip를 받은 것도 확인할 수 있다.
Pasted image 20250204151356.png
기본 클러스터 보안 그룹에 속해있다.

Pasted image 20250204151710.png
재밌게 볼 것은 이 녀석이다.
내가 바로 이름을 컨트롤로 붙여버렸는데, 이 친구가 바로 컨트롤 플레인에서 우리의 vpc로 연결된 eni이다.
그래서 보안 그룹도 컨트롤 플레인 보안 그룹도 붙어 있는 것이 보인다.
Pasted image 20250204151808.png
인스턴스 소유자가 우리의 id가 아닌데, eks에서 소유한 eni이기 때문에 그렇다.
마찬가지로 우리의 인스턴스가 아닌, eks가 관리하는 인스턴스라 어떤 인스턴스인지도 보여주지 않는다.

Pasted image 20250204152155.png
이 친구는 잘 모르겠어서 일단 세이프.
이 친구는 일단 내가 설명 부분을 보고 k8s라 이름 붙였는데, 정확하게 무엇인가?
Pasted image 20250204152225.png
ip 주소를 이용해서 노드에 직접 들어가서 확인해보자.

오토스케일링 그룹

Pasted image 20250204153743.png
노드 스케일링은 오토 스케일링을 통해 이뤄진다.
처음 클러스터가 생길 때 인스턴스를 두 개로 잡았기에 이렇게 2개가 만들어지게 됐다.

cli 확인

Pasted image 20250204124213.png
완료되면 이렇게 알아서 로컬에 config 파일을 넣어준다.

k config view

들어간 정보를 한번 본다.
Pasted image 20250204124538.png
aws eks 명령을 통해 토큰을 받아오고, 이를 이용해서 클러스터와 통신을 하는 것이다.
구체적으로는 sts를 활용하는 방식으로 로컬의 사용자 정보를 활용하여 aws cli가 동작한다.
Pasted image 20250204154254.png
달리 말해서 직접 이걸 쳐볼 수 있는데, 유효기간이 길지는 않다.
이 토큰이 클러스터의 인증을 통과하도록 돼있다는 것은 api 서버의 인증 모듈에 aws iam과 관련된 것이 존재한다는 것이다.
아마 관련한 내용은 이후 주차에 더 자세히 다룰 가능성이 높으므로 여기까지만 탐구하도록 한다.

그럼 본격적으로 클러스터 정보들을 확인해보도록 하자.

kubectl cluster-info
aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint

다양한 방법으로 현재 클러스터 api 서버의 도메인 주소를 파악할 수 있다.

APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3) 
dig +short $APIDNS

해당 도메인을 통해 받게 되는 ip 주소를 확인해보자.
Pasted image 20250204163707.png
short로 보지 않고 출력했는데, 아무튼 퍼블릭 ip가 들어오는 것이 보인다.
현재 api 서버로의 통신을 위한 도메인, 이 도메인에 대한 ip는 3.36.162.138, 3.34.117.193이다.
Pasted image 20250204163930.png
[[Amazon Route53]]에서 vpc 관련 설정이 들어간 것을 확인할 수 있다.
Pasted image 20250204164251.png
kube-system 네임스페이스에는 온프레미스와 다르게 정적 파드에 대한 정보가 하나도 없다.
aws에서 관리하는 만큼, 아예 접근조차 할 수 없도록 만들어둔 듯하다.
아예 정적 파드 기능 자체가 비활성화돼있다고 들었는데, 과연 실제로도 사용하지 않는 모습을 보이는 듯하다.
Metric API도 기본으로 지원해주고 있고, aws-node라 적힌 것은 뜯어보니 aws-cni였다.

k ns kube-system
k get node --show-labels -o wide

노드에는 어떤 라벨이 있고 어떤 정보가 들어있는가?
Pasted image 20250204164539.png
음.. 라벨이 어무막지하게 많이 붙어있는데, 나중에 활용할 구석을 찾을 수 있을 것 같다.

노드 접속 후 정보 확인

kubectl get node -o jsonpath='{.items}' | jq -r '.[] | .status.addresses[] | select( .type == "ExternalIP").address'

현재 존재하는 각 노드의 공인 ip를 꺼내본다.
Pasted image 20250204174444.png
처음 클러스터를 구성할 때 ssh에 대한 설정을 했기 때문에 별다른 설정 없이도 현재 호스트에서 ssh 접속이 가능하다.
Pasted image 20250204174529.png
인터페이스 정보를 보면, 콘솔에서 확인했던 eni 관련 값들이 보인다.
중간에 eni뭐라 붙은 녀석들은 aws cni가 관리하는 인터페이스로 보인다.
근데 저 7번 인터페이스는 콘솔에서 볼 때도 궁금했는데, 대체 왜 있는 걸까?
Pasted image 20250204174921.png
라우팅 테이블도 한번 보자.
차주에 배우겠지만, cni가 완벽히 vpc의 ip 대역을 활용하고 있는 것을 알 수 있다.
달리 말해 각종 컴포넌트나 파드에 그냥 노드에서 접근하는 것이 가능하다는 것.
아니 근데 7번에 대한 라우팅 테이블도 존재하지 않는데;
Pasted image 20250204182034.png
containerd를 기본 oci로 활용하고 있다.
Pasted image 20250204183018.png
처음에 설정했던 스토리지 20기비바이트 짜리가 붙어있따.

컨트롤 플레인과의 통신

이제 본격적으로 어떻게 컨트롤 플레인과 연결돼있는지 추적해보자.

ss -tnp

현재 열려 있는 프로세스들이 어떤 소켓으로, 어떤 주소와 연결되고 있는 확인한다.
Pasted image 20250204183505.png
재밌는 건, kubelet, kube-proxy가 퍼블릭 ip로 어딘가에 연결되고 있는 것이 보인다!
이 ip는 위에서도 봤지만, api 서버로 통신하는 퍼블릭 ip이다.
즉, 클러스터 바깥으로 트래픽이 나갔다 다시 들어오고 있다는 뜻이다..

아래 ipv6와 매핑된 ipv4는 노드의 kubelet가 노출하고 있는 10250포트로 연결되고 있는 소켓이다.
peer address를 보면 프라이빗 ip가 있는데, 이 친구는 뭘까?
Pasted image 20250204191429.png
cni에서 연결해주는 어떤 인터페이스로 빠져나가는 것을 볼 수 있다.

iptables  -t nat -L | egrep -A5 -B5 114

이러고 싶지 않았지만.. cni가 관리하는 인터페이스로 빠져나가는 이상 iptables 규칙도 확인해봐야한다.
Pasted image 20250204192120.png
정답은 [[메트릭 서버]] 파드의 ip 였답니다!

추가 확인

apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: default
spec:
  containers:
  - image: nicolaka/netshoot
    name: test
    command: 
    - sh
    - -c
    - "sleep infinity"
  restartPolicy: Always
  nodeName: ip-192-168-1-70.ap-northeast-2.compute.internal

디버깅용 파드를 하나 만든다.
현재 접속한 노드에서 정보를 확인하기 위해 아예 노드 이름을 지정해버렸다.

k exec -ti test -- zsh

exec 명령은 api서버가 웹소켓으로 클라이언트를 노드에 연결해준다.
Pasted image 20250204194931.png
그러자 내부 ip로 연결된 소켓이 보이는데, 이 ip는 무엇일까?
세번째 옥텟 2는 다른 az의 퍼블릭 서브넷 대역이다.
잘 모르겠어서, 한 노드에서 다른 노드로도 접속도 해보았다.
Pasted image 20250204202249.png
파드가 띄워진 노드에서 똑같은 ip로 열린 소켓 정보가 하나 더 보인다.
Pasted image 20250204202848.png
eni를 다시 찾아보니, 해당 ip는 컨트롤 플레인의 eni가 가지고 있다.
클러스터 액세스 엔드포인트가 어떤 모드이던 간에, 컨트롤플레인에서 워커 노드로 보내는 트래픽은 eni를 타고 간다는 것을 확인할 수 있다.

엔드포인트 액세스 모드 변경

기본으로 마지막으로 해볼 것은 api 서버로의 통신 경로 변경이다.
Pasted image 20250204204415.png
그냥 만든 eks는 기본적으로 api 서버에 대한 접근이 퍼블릭으로 설정돼있다.
그래서 워커 노드의 kube-proxy, kubelet이 전부 외부로 나갔다가 들어오는 것을 확인할 수 있었다.
Pasted image 20250204204443.png

혼용(퍼블릭, 프라이빗) 모드

이것을 퍼블릭, 프라이빗 모드로 수정해본다.
실제로 완료되는 데에는 대충 10분 가량이 걸린다.

while true; do dig +short 74EA06D41A0AECDFF9DFA2A30A8854A3.gr7.ap-northeast-2.eks.amazonaws.com ; echo "------------------------------" ; date; sleep 3; done

그동안 워커 노드에서는 어떻게 dns가 변경되는지 확인할 수 있게 한무 루프를 만들었다.
Pasted image 20250204205722.png
어느 순간부터 dns 조회가 안 되는 것이 보인다.
Pasted image 20250204210050.png
총 9분을 기다리다보니.. 드디어 프라이빗 ip가 뜨는 것이 확인된다!
위에서 보았던, eni의 ip이다.
Pasted image 20250204205346.png
그러나 아직 컴포넌트들은 퍼블릭 ip로 통신하고 있다!
이건 컴포넌트들이 이전에 통신한 내용을 바탕으로 계속 통신을 하고 있기 때문에 그렇다.
귀찮게도, 이걸 수정해주려면 직접 각 컴포넌트들을 재시작 해줘야만 한다;

systemctl restart kubelet

직접 재시작을 해주면..
Pasted image 20250204213429.png
드디어 통신이 내부로 이어지게 된다.
데몬셋으로 배포된 kube-proxy는 rollout restart를 해주면 반영될 것이다.

Pasted image 20250204213847.png
참고로 내 로컬에서는 그냥 똑같이 퍼블릭 ip가 표기되는데, 이것은 스플릿 호라이즌 dns 기능을 이용했기 때문이다.

프라이빗 모드

Pasted image 20250204213714.png
마지막으로 프라이빗 모드로 변경해본다.
이제부터는 내 로컬에서는 아예 접근하는 것이 불가능해진다.
Pasted image 20250204214628.png
업데이트가 완료된 후, dns 조회를 해보니 이렇게 내부 ip만 리턴된다.
외부에서는 이 ip를 가지고 할 수 있는 게 당연히 아무것도 없다..
이제부터 외부에서 클러스터를 사용하고 싶다면 바스티온 호스트를 하나 파던가 해야 한다.

나는 [[SSH 터널링]]을 쓰기로 마음 먹었다.

ssh -L 2222:74EA06D41A0AECDFF9DFA2A30A8854A3.gr7.ap-northeast-2.eks.amazonaws.com:443 ec2-user@$N1 -i ../pki/pub.pem

이런 식으로 로컬 터널링을 뚫어주었다.
Pasted image 20250204220246.png
내 로컬에는 이제 listen 상태의 2222번 tcp 소켓이 있다.
Pasted image 20250204220557.png
그럼 내 로컬에서 이렇게 통신을 할 수 있게 된다.
# 실습 자원 삭제

eksctl delete cluster --name aews-eks
aws cloudformation delete-stack --stack-name myeks

모든 것을 마친 후에는 반드시 정리!

로컬에서 진행

로컬에서는 [[aws cli]]나, 언어 라이브러리를 쓸 수 있을 텐데, 버전을 최신으로 유지하기 용이한 것은 cli 쪽이라고 생각한다.
왜냐하면 cli를 컨테이너로 사용하는 방법을 지원하는데, 이 경우 최신 버전을 알아서 가져오도록 되어 있기 때문이다.[4]

alias aws='docker run --rm -ti -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli'

도커가 이미 설치돼있다면, 이것만 이용해서 쉽게 명령어를 항상 최신 것으로 쓸 수 있다!
Pasted image 20250202121720.png
eksctl 사용해볼 때 처음 알게 된 방법인데, 다른 명령어들도 다 이 방식을 지원해주면 참 편할 것 같다..
그렇다면 자동완성이 되게까지 할 수는 없나?[5]
cli v2부터 자동완성을 지원하는 방식이 바뀌어서 설정이 쉽지 않다;

사용성을 고민하다가, 그냥 내부에 autocomplete 설정만 해두고 aws를 치면 컨테이너가 실행되어, 그 안에서 명령을 실행하는 것으로 결정했다.
이러면 두 번의 과정을 거치게 되긴 하지만, 자동완성은 조금 더 편하게 할 수 있다.

콘솔로 수동 생성

eksctl

terraform

kops

결론 비교

관련 문서

이름 noteType created
EKS, ECS 비교 knowledge 2024-11-03
Amazon Fargate knowledge 2024-11-03
eksctl knowledge 2025-02-06
Karpenter knowledge 2025-03-04
EKS Automode knowledge 2025-04-23
EKS 사전 준비 project 2025-02-14
1주차 - EKS 준비 project 2025-02-01
1주차 - 테라폼으로 프로비저닝, 다양한 노드 활용해보기 project 2025-02-05
2주차 - 테라폼 세팅 project 2025-02-09
2주차 - 네트워크 project 2025-02-25
3주차 - 스토리지 project 2025-02-16
4주차 - 관측 가능성 project 2025-02-23
3주차 - 다양한 노드 그룹 project 2025-02-24
4주차 - opentelemetry 데모 project 2025-03-01
4주차 - 네트워크 추가 project 2025-03-01
5주차 - 오토스케일링 project 2025-03-02
6주차 - 시큐리티 project 2025-03-09
7주차 - 모드, 노드 project 2025-03-16
8주차 - CICD project 2025-03-23
9주차 - 업그레이드 project 2025-03-30
10주차 - 시크릿 관리 project 2025-04-11
11주차 - ml infra project 2025-04-17
12주차 - aws lattice, gateway api project 2025-04-23
1W - EKS 설치 및 액세스 엔드포인트 변경 실습 published 2025-02-03
2W - 테라폼으로 환경 구성 및 VPC 연결 published 2025-02-11
2W - EKS VPC CNI 분석 published 2025-02-11
2W - ALB Controller, External DNS published 2025-02-15
3W - kubestr과 EBS CSI 드라이버 published 2025-02-21
3W - EFS 드라이버, 인스턴스 스토어 활용 published 2025-02-22
4W - 번외 AL2023 노드 초기화 커스텀 published 2025-02-25
4W - EKS 모니터링과 관측 가능성 published 2025-02-28
4W - 프로메테우스 스택을 통한 EKS 모니터링 published 2025-02-28
5W - HPA, KEDA를 활용한 파드 오토스케일링 published 2025-03-07
5W - Karpenter를 활용한 클러스터 오토스케일링 published 2025-03-07
6W - PKI 구조, CSR 리소스를 통한 api 서버 조회 published 2025-03-15
6W - api 구조와 보안 1 - 인증 published 2025-03-15
6W - api 보안 2 - 인가, 어드미션 제어 published 2025-03-16
6W - EKS api 서버 접근 보안 published 2025-03-16
6W - EKS 파드에서 AWS 리소스 접근 제어 published 2025-03-16
7W - 쿠버네티스의 스케줄링, 커스텀 스케줄러 설정 published 2025-03-22
7W - EKS Automode published 2025-03-22
7W - EKS Fargate published 2025-03-22
8W - 아르고 워크플로우 published 2025-03-30
8W - 아르고 롤아웃 published 2025-03-30
8W - 아르고 CD published 2025-03-30
8W - CICD published 2025-03-30
9W - EKS 업그레이드 published 2025-04-02
10W - Vault를 활용한 CICD 보안 published 2025-04-16
11주차 - EKS에서 FSx, Inferentia 활용하기 published 2025-05-11
11W - EKS에서 FSx, Inferentia 활용하기 published 2025-04-18
12W - VPC Lattice 기반 gateway api published 2025-04-27
E-파드 마운팅 recursiveReadOnly topic/explain 2025-02-27
S-vpc 설정이 eks 액세스 엔드포인트에 미치는 영향 topic/shooting 2025-02-07
T-마운트 전파 Bidirectioal topic/temp 2025-02-28

참고


  1. https://carpfish.tistory.com/entry/DNS-dig-명령어-소개-및-사용법 ↩︎

  2. https://eksctl.io/installation/#for-unix ↩︎

  3. https://github.com/eksctl-io/eksctl/blob/main/examples/01-simple-cluster.yaml ↩︎

  4. https://hub.docker.com/r/amazon/aws-cli ↩︎

  5. https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-prompting.html ↩︎