곧바로 두번째 포스팅 시작합니다.
EKS Cluster Endpoint Access 소개 - Docs

EKS 데이터 플레인
워커 노드(EC2/Fargate 등)는 Customer VPC에 존재하며 Control Plane과는 EKS가 생성한 ENI(EKS owned ENI)를 통해 통신
Cluster Endpoint 유형 (3가지)
Public: 노드와 kubectl 모두 퍼블릭 API 엔드포인트로 Control Plane에 접근

Public + Private: 노드는 프라이빗 ENI(IP)로 kubectl은 퍼블릭 엔드포인트로 접근

Private: 노드와 kubectl 모두 VPC 내부 프라이빗 엔드포인트로만 접근

EKS Cluster Endpoint Access 실습해보자

노드(client) → EKS API(server) 요청 시 정보 확인
for i in $NODE1 $NODE2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp | grep -v ssh; echo; done
# EKS 엔드포인트 IP 확인
CLUSTER_NAME=myeks
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS
# DoS 공격 가능?
curl -sk https://$APIDNS
curl -sk https://$APIDNS/version

‘EKS API(client) → 노드 kubelet(server)’ 요청 시 정보 확인
# 파드 1개 bash 접속 해두기!
kubectl exec -it -n kube-system deploy/kube-ops-view -- bash
I have no name!@kube-ops-view-97fd86569-tjf2t:/$ # 대기
# 확인 : exec 실행으로 추가된 연결 정보의 Peer Address는 어딘인가요? + AWS 네트워크 인터페이스 ENI에서 해당 IP 정보 확인
for i in $NODE1 $NODE2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp | grep -v ssh; echo; done
eks access endpoint 변경 by Terraform : 퍼블릭 및 프라이빗 + 액세스 소스 설정 7분 소요
endpoint_public_access = true
endpoint_private_access = true
endpoint_public_access_cidrs = [
var.ssh_access_cidr
]
#적용 7분 소요
terraform apply -auto-approve
eks access endpoint ‘퍼블릭 및 프라이빗’ 상세 동작 확인 및 적용

eks access endpoint 퍼블릭 및 프라이빗 상세 동작 확인
변경하면 아래 사진처럼 퍼블릭 및 프라이빗 으로 변경된것을 확인할 수 있다

while true; do ssh ec2-user@$NODE1 dig +short $APIDNS ; date ; echo "-----" ; sleep 1 ; done
# 하지만 여전히 공인 IP
ssh ec2-user@$NODE1 sudo ss -tnp | grep -v ssh
# kube-proxy rollout : ss에 kube-proxy peer IP 변경 확인
kubectl rollout restart ds/kube-proxy -n kube-system
ssh ec2-user@$NODE1 sudo ss -tnp | grep -v ssh
for i in $NODE1 $NODE2; do echo ">> node $i <<"; ssh ec2-user@$i sudo systemctl restart kubelet; echo; done
ssh ec2-user@$NODE1 sudo ss -tnp | grep -v ssh
# aws-node
kubectl rollout restart ds/aws-node -n kube-system
ssh ec2-user@$NODE1 sudo ss -tnp | grep -v ssh

실습 완료 후 삭제
rm -rf ~/.kube/config
nohup sh -c "terraform destroy -auto-approve" > delete.log 2>&1 &
tail -f delete.log
이제는 정말 실무적인 private을 학습해보겠습니다
인터넷 액세스가 제한된 프라이빗 클러스터 - Docs

EKS Fully Private Cluster 배포 : 16분 소요 - Docs , Link
# 실습 디렉터리 진입
cd eks-private
# 변수 지정
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
# 초기화
terraform init
terraform plan
# vpc 배포 : 2분 소요 -> 이후 aws vpc 정보 확인!
terraform apply -target="module.vpc" -auto-approve
# eks 등 배포 : 14분 소요
terraform apply -auto-approve
# 자격증명 설정
aws eks --region ap-northeast-2 update-kubeconfig --name eks-private
kubectl config rename-context $(cat ~/.kube/config | grep current-context | awk '{print $2}') eks-private
# kubectl 조회 시도
kubectl get node -v=7
...
I0312 18:01:51.102015 28018 round_trippers.go:527] "Request" verb="GET" url="https://4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com/api?timeout=32s" headers=<
Accept: application/json;g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList,application/json;g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList,application/json
User-Agent: kubectl/v1.35.2 (darwin/arm64) kubernetes/fdc9d74
E0312 18:02:21.493542 28018 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com/api?timeout=32s\": dial tcp 10.0.14.147:443: i/o timeout"
# 자격증명 삭제
rm -rf ~/.kube/config
완전한 private

그렇기 때문에 조회 자체가 안된다

bastion EC2 접속 후 확인해보자
# bastion ec2 접속
ssh -o StrictHostKeyChecking=no ubuntu@$(terraform output -raw bastion_ec2-public_ip)
# admin IAM User 자격 증명 설정
aws configure
# 자격증명 설정
aws eks --region ap-northeast-2 update-kubeconfig --name eks-private
kubectl config rename-context $(cat ~/.kube/config | grep current-context | awk '{print $2}') eks-private
# eks access endpoint 확인
APIDNS=$(aws eks describe-cluster --name eks-private | jq -r .cluster.endpoint | cut -d '/' -f 3)
echo $APIDNS
4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com
dig +short $APIDNS
10.0.14.147
10.0.28.171
# kubectl 조회 시도 : DNS Lookup resolved" host="4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com" address=[{"IP":"10.0.28.171","Zone":""},{"IP":"10.0.14.147","Zone":""}]
kubectl cluster-info
kubectl get node -v=9
...
curl -v -XGET -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.34.2 (linux/amd64) kubernetes/0ea4984" 'https://4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500'
>
I0312 18:36:06.092396 2708 round_trippers.go:547] "HTTP Trace: DNS Lookup resolved" host="4924E16AD07400AA0CA66718E179E887.gr7.ap-northeast-2.eks.amazonaws.com" address=[{"IP":"10.0.28.171","Zone":""},{"IP":"10.0.14.147","Zone":""}]
위 세팅을 하고 bastion sg 허용후 api 날려보면

위와 같이 ec2에서 확인이 가능합니다.
파드 생성 및 노드 Shell 접속 - Blog
# 노드 정보 확인
kubectl get node -owide
# node-shell 파드 배포
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: node-shell
spec:
containers:
- name: debug
image: public.ecr.aws/docker/library/alpine:latest
command: ["/bin/sh", "-c", "sleep 36000"]
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: hostfs
hostNetwork: true
hostPID: true
hostIPC: true
volumes:
- name: hostfs
hostPath:
path: /
EOF
# 파드 내에서 chroot 실행으로 호스트 노드 진입!
kubectl exec -it node-shell -- chroot /host /bin/bash

이로서 1주차 실습 및 공유를 마치겠습니다