1주차 - EKS 준비
개요
이 문서에서는 기본적인 EKS를 사용하는 시간을 가져본다.
과거에는 eksctl을 이용했는데, 사실 eks를 만드는 데에는 다양한 방법이 있다.
이번에는 총 5가지 방법을 활용해보고 각각을 비교해볼 것이다.
원래 이 노트는 클라우드넷 AEWS 스터디 1주차를 진행하기 이전에 혼자 먼저 실습을 하기 위해 마련한 노트이다.
그러나 일이 생겨 제 시간에 의도했던 바를 전부 마치지 못 했고, 이에 따라 스터디에서 배운 내용은 뒤늦게 병합하며 글을 진행한다.
또한 이 글은 단순 외부 전파보다는 내 복습과 지식 습득을 우선 목표로 삼는다.
완전히 정리된 글은 다른 글에서 진행한다.
요구 사항
내 터미널에서 접근 가능하도록 kubeconfig 파일을 내 로컬에 받을 수 있도록 설정.
클러스터 구축만을 목표로 하기 때문에 최소한의 사양을 통해서 만들 것이다.
실습을 마친 후 각 리소스는 완벽하게 정리돼야만 한다.
기본 설치
클라우드네타 팀에서 제공하는 클라우드 포메이션을 이용하여 설치를 진행한다.
이후에 알게 됐지만, 이 방법은 구체적으로 먼저 인프라 환경을 구성해놓은 뒤에 eksctl을 이용해서 구축을 하는 방식이다.
클라우드넷팀에서 제공해준 클포 양식이 이미 있으므로, 해당 양식을 통해 먼저 진행한다.
이걸 먼저 하는 것은 이걸 기준으로 다른 수단으로 같은 리소스들을 만들기 위함이다.
만약 직접 클포를 사용한다면, 직접 템플릿을 만드는 것이 당연히 선행돼야 한다.
먼저 인프라 컴포저로 어떤 구성이 돼있는지 확인해보자.
하나의 VPC안에 서브넷을 4개 배치한다.
퍼블릭과 프라이빗 각각 2개씩 배치한 후, eks에 접근할 수 있는 바스티온 격 EC2도 하나 두는 모습을 볼 수 있다.
해당 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를 조회해보자.
나중에 따로 정리할 것 같지만, 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 컨트롤 플레인의 구성도도 나온 자료가 있으니 보자.
이것에 대한 명확한 글이 올라왔다.
![[AWS re_Invent 2021 - Getting to large Amazon EKS clusters.pdf]]
요지는 과거에는 중간에 로드밸런서를 두었으나, 이제는 그냥 쿠버네티스의 자체 로드밸런싱의 기능을 활용한다는 것.
노드 정보 확인
# 노드 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를 다룰 것이다.
노드 유형은 다양하다.
- managed node groups
- eks에 최적화된 ami를 제공한다.
- 보안이 강화된 bottlerocket이란 것도 있다.
- 자체 노드 그룹
- Karpenter
- auto mode
- 어떤 장단이 있는지 확인해보자.
- hybrid mode
- fargate
- firecracker라는 micro vm을 이용한다.
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가 있다.
이걸로 조금 필요한 정보들만 편하게 볼 수 있따.
애드온을 추가해보자.
콘솔로도 쉽게 할 수 있따.
애드온이 설치되기 전에는, 이렇게 메모리, 디스크 관련 정보만 컨디션에 나온다.
그런데 애드온을 넣으면 다른 정보들도 나오게 된다.
krew로 stern을 쓰면 파드 로그도 볼 수 있따.
eks 클러스터 웹 대시 보드도 존재한다.
자원삭제는 두 단계로.
https://www.youtube.com/watch?v=2LEFG3MlaqQ
해야할 내용
- etcd와 api서버의 로드밸런싱
심화 진행
- 심화
- ctr 써보기
- node monitoring agent
- 노드 그룹 스케일링
- 헬스체크 방식
- ㄴ드 축출
- qos
- etcd base size
- 도전
- 테라폼으로 세팅
- 클러스터 프라이빗으로 만들ㅇ기
- 다양한 노드 사용
- 이건 웬만해서 콘솔로하자.
- 스팟, 그라비톤, 파게이트
- ami 비교
- 프라이빗 ecr
- 스케줄링
- vpc
혼자 다시 진행
이번에는 내 로컬에서 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 확인
제대로 됐다면 이런 식으로 표시가 될 것이다.
이건 iam으로는 확인이 안 되고 있어서 아직 조금 잘 모르겠는데, 내가 eks를 만들 때 root 계정으로 만들어버려서 그런 것 같다.
폴리시들을 추가해봐도 잘 되진 않는다.
이건 나중에 추가적으로 더 확인해봐야할 듯.
보안 그룹 확인
생성된 보안 그룹들도 확인해보자.
ssh 허용을 하여 생긴 보안 그룹 말고 3개의 보안 그룹이 있는 것이 확인된다.
- 클러스터 보안 그룹(clutser SG)
- 클러스터의 모든 eni(컨트롤 플레인 포함)가 받게 되는 보안 그룹으로, 자기 자신과 노드 그룹에 대한 인바운드를 허용한다.
- 이걸 통해 클러스터 내의 요청이 전부 허용된다.
- 컨트롤 플레인 보안 그룹(control plane SG)
- 컨트롤 플레인의 인스턴스들이 받게 되는 보안 그룹으로 추정된다.
- 해당 ec2를 직접 확인할 수는 없기 때문에 추정이나, 아래 [[#네트워크 인터페이스 확인]] 부분에서 특정 eni가 이걸 받는 것이 보인다.
- 클러스터 공유 노드 보안 그룹(cluster shared node SG)
- 인바운드로 자기 자신과, 위의 클러스터 보안 그룹을 두고 있다.
- 노드 유형이 관리형이던, 직접 조작하는 노드던, 이 보안 그룹을 가지면 결국 클러스터와 통신이 가능해진다.
네트워크 인터페이스 확인
5개의 인터페이스가 만들어진 것이 확인된다.
이중에서 이름 붙여진 것들은 워커 노드들이 기본적으로 가지게 되는 네트워크 인터페이스이다.
퍼블릭 서브넷에 노드를 배치했기에 퍼블릭 ip를 받은 것도 확인할 수 있다.
기본 클러스터 보안 그룹에 속해있다.
재밌게 볼 것은 이 녀석이다.
내가 바로 이름을 컨트롤로 붙여버렸는데, 이 친구가 바로 컨트롤 플레인에서 우리의 vpc로 연결된 eni이다.
그래서 보안 그룹도 컨트롤 플레인 보안 그룹도 붙어 있는 것이 보인다.
인스턴스 소유자가 우리의 id가 아닌데, eks에서 소유한 eni이기 때문에 그렇다.
마찬가지로 우리의 인스턴스가 아닌, eks가 관리하는 인스턴스라 어떤 인스턴스인지도 보여주지 않는다.
이 친구는 잘 모르겠어서 일단 세이프.
이 친구는 일단 내가 설명 부분을 보고 k8s라 이름 붙였는데, 정확하게 무엇인가?
ip 주소를 이용해서 노드에 직접 들어가서 확인해보자.
오토스케일링 그룹
노드 스케일링은 오토 스케일링을 통해 이뤄진다.
처음 클러스터가 생길 때 인스턴스를 두 개로 잡았기에 이렇게 2개가 만들어지게 됐다.
cli 확인
완료되면 이렇게 알아서 로컬에 config 파일을 넣어준다.
k config view
들어간 정보를 한번 본다.
aws eks 명령을 통해 토큰을 받아오고, 이를 이용해서 클러스터와 통신을 하는 것이다.
구체적으로는 sts를 활용하는 방식으로 로컬의 사용자 정보를 활용하여 aws cli가 동작한다.
달리 말해서 직접 이걸 쳐볼 수 있는데, 유효기간이 길지는 않다.
이 토큰이 클러스터의 인증을 통과하도록 돼있다는 것은 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 주소를 확인해보자.
short로 보지 않고 출력했는데, 아무튼 퍼블릭 ip가 들어오는 것이 보인다.
현재 api 서버로의 통신을 위한 도메인, 이 도메인에 대한 ip는 3.36.162.138, 3.34.117.193이다.
[[Amazon Route53]]에서 vpc 관련 설정이 들어간 것을 확인할 수 있다.
kube-system 네임스페이스에는 온프레미스와 다르게 정적 파드에 대한 정보가 하나도 없다.
aws에서 관리하는 만큼, 아예 접근조차 할 수 없도록 만들어둔 듯하다.
아예 정적 파드 기능 자체가 비활성화돼있다고 들었는데, 과연 실제로도 사용하지 않는 모습을 보이는 듯하다.
Metric API도 기본으로 지원해주고 있고, aws-node라 적힌 것은 뜯어보니 aws-cni였다.
k ns kube-system
k get node --show-labels -o wide
노드에는 어떤 라벨이 있고 어떤 정보가 들어있는가?
음.. 라벨이 어무막지하게 많이 붙어있는데, 나중에 활용할 구석을 찾을 수 있을 것 같다.
노드 접속 후 정보 확인
kubectl get node -o jsonpath='{.items}' | jq -r '.[] | .status.addresses[] | select( .type == "ExternalIP").address'
현재 존재하는 각 노드의 공인 ip를 꺼내본다.
처음 클러스터를 구성할 때 ssh에 대한 설정을 했기 때문에 별다른 설정 없이도 현재 호스트에서 ssh 접속이 가능하다.
인터페이스 정보를 보면, 콘솔에서 확인했던 eni 관련 값들이 보인다.
중간에 eni뭐라 붙은 녀석들은 aws cni가 관리하는 인터페이스로 보인다.
근데 저 7번 인터페이스는 콘솔에서 볼 때도 궁금했는데, 대체 왜 있는 걸까?
라우팅 테이블도 한번 보자.
차주에 배우겠지만, cni가 완벽히 vpc의 ip 대역을 활용하고 있는 것을 알 수 있다.
달리 말해 각종 컴포넌트나 파드에 그냥 노드에서 접근하는 것이 가능하다는 것.
아니 근데 7번에 대한 라우팅 테이블도 존재하지 않는데;
containerd를 기본 oci로 활용하고 있다.
처음에 설정했던 스토리지 20기비바이트 짜리가 붙어있따.
컨트롤 플레인과의 통신
이제 본격적으로 어떻게 컨트롤 플레인과 연결돼있는지 추적해보자.
ss -tnp
현재 열려 있는 프로세스들이 어떤 소켓으로, 어떤 주소와 연결되고 있는 확인한다.
재밌는 건, kubelet, kube-proxy가 퍼블릭 ip로 어딘가에 연결되고 있는 것이 보인다!
이 ip는 위에서도 봤지만, api 서버로 통신하는 퍼블릭 ip이다.
즉, 클러스터 바깥으로 트래픽이 나갔다 다시 들어오고 있다는 뜻이다..
아래 ipv6와 매핑된 ipv4는 노드의 kubelet가 노출하고 있는 10250포트로 연결되고 있는 소켓이다.
peer address를 보면 프라이빗 ip가 있는데, 이 친구는 뭘까?
cni에서 연결해주는 어떤 인터페이스로 빠져나가는 것을 볼 수 있다.
iptables -t nat -L | egrep -A5 -B5 114
이러고 싶지 않았지만.. cni가 관리하는 인터페이스로 빠져나가는 이상 iptables 규칙도 확인해봐야한다.
정답은 [[메트릭 서버]] 파드의 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서버가 웹소켓으로 클라이언트를 노드에 연결해준다.
그러자 내부 ip로 연결된 소켓이 보이는데, 이 ip는 무엇일까?
세번째 옥텟 2는 다른 az의 퍼블릭 서브넷 대역이다.
잘 모르겠어서, 한 노드에서 다른 노드로도 접속도 해보았다.
파드가 띄워진 노드에서 똑같은 ip로 열린 소켓 정보가 하나 더 보인다.
eni를 다시 찾아보니, 해당 ip는 컨트롤 플레인의 eni가 가지고 있다.
클러스터 액세스 엔드포인트가 어떤 모드이던 간에, 컨트롤플레인에서 워커 노드로 보내는 트래픽은 eni를 타고 간다는 것을 확인할 수 있다.
엔드포인트 액세스 모드 변경
기본으로 마지막으로 해볼 것은 api 서버로의 통신 경로 변경이다.
그냥 만든 eks는 기본적으로 api 서버에 대한 접근이 퍼블릭으로 설정돼있다.
그래서 워커 노드의 kube-proxy, kubelet이 전부 외부로 나갔다가 들어오는 것을 확인할 수 있었다.
혼용(퍼블릭, 프라이빗) 모드
이것을 퍼블릭, 프라이빗 모드로 수정해본다.
실제로 완료되는 데에는 대충 10분 가량이 걸린다.
while true; do dig +short 74EA06D41A0AECDFF9DFA2A30A8854A3.gr7.ap-northeast-2.eks.amazonaws.com ; echo "------------------------------" ; date; sleep 3; done
그동안 워커 노드에서는 어떻게 dns가 변경되는지 확인할 수 있게 한무 루프를 만들었다.
어느 순간부터 dns 조회가 안 되는 것이 보인다.
총 9분을 기다리다보니.. 드디어 프라이빗 ip가 뜨는 것이 확인된다!
위에서 보았던, eni의 ip이다.
그러나 아직 컴포넌트들은 퍼블릭 ip로 통신하고 있다!
이건 컴포넌트들이 이전에 통신한 내용을 바탕으로 계속 통신을 하고 있기 때문에 그렇다.
귀찮게도, 이걸 수정해주려면 직접 각 컴포넌트들을 재시작 해줘야만 한다;
systemctl restart kubelet
직접 재시작을 해주면..
드디어 통신이 내부로 이어지게 된다.
데몬셋으로 배포된 kube-proxy는 rollout restart
를 해주면 반영될 것이다.
참고로 내 로컬에서는 그냥 똑같이 퍼블릭 ip가 표기되는데, 이것은 스플릿 호라이즌 dns 기능을 이용했기 때문이다.
프라이빗 모드
마지막으로 프라이빗 모드로 변경해본다.
이제부터는 내 로컬에서는 아예 접근하는 것이 불가능해진다.
업데이트가 완료된 후, dns 조회를 해보니 이렇게 내부 ip만 리턴된다.
외부에서는 이 ip를 가지고 할 수 있는 게 당연히 아무것도 없다..
이제부터 외부에서 클러스터를 사용하고 싶다면 바스티온 호스트를 하나 파던가 해야 한다.
나는 [[SSH 터널링]]을 쓰기로 마음 먹었다.
ssh -L 2222:74EA06D41A0AECDFF9DFA2A30A8854A3.gr7.ap-northeast-2.eks.amazonaws.com:443 ec2-user@$N1 -i ../pki/pub.pem
이런 식으로 로컬 터널링을 뚫어주었다.
내 로컬에는 이제 listen 상태의 2222번 tcp 소켓이 있다.
그럼 내 로컬에서 이렇게 통신을 할 수 있게 된다.
# 실습 자원 삭제
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'
도커가 이미 설치돼있다면, 이것만 이용해서 쉽게 명령어를 항상 최신 것으로 쓸 수 있다!
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 |