스터디/AEWS

[AEWS] 1주차 EKS 설치 및 EKS Endpoint Access에 따른 아키텍처

안녕유지 2025. 2. 8. 22:22
Cloudnet AWES 1주차 스터디를 진행하며 정리한 글입니다.

 

이전 포스팅에서, EKS란 무엇인지에 대해서 소개했습니다.

이번 포스팅에서는 EKS를 설치하는 방법과 엔드포인트 액세스에 따른 EKS 아키텍처에 대해 소개하겠습니다.

잘못된 부분이 있다면 댓글로 말씀 부탁드립니다.

 

EKS 배포하기

EKS는 AWS Managed Kubernetes 클러스터로, 클러스터를 생성하는 다양한 방법이 있습니다. (재직 중인 회사에서는 클러스터 생성 및 관리는 Cluster API라는 도구를 활용하여 클러스터를 관리하고 있습니다. 해당 방법은 쿠버네티스에 대한 사전 이해도가 필요하고, 단일 클러스터를 운영하는 경우라면 오버 엔지니어링이라고 생각합니다.)

보편적으로 클러스터 생성 시 사용하는 2가지 방법에 대해 우선 소개하겠습니다.

 

1) 웹 관리 콘솔로 생성 - Auto Mode 방식

 

 

컴퓨팅 노드들이 Auto 모드로 되어있습니다.

 

이름, Kubernets 버전을 설정하고, VPC, Subnet 설정 외에 클러스터 IAM 역할, 노드 IAM 역할이 없다면 생성해준 뒤 지정하여 클러스터 생성하면 완성!

 

 

참고) 생성하는 Cluster IAM 역할과, 노드 IAM 역할이 어떻게 다른걸까?

추후에 IAM 관련하여 사용자, 역할, 정책에 대해 포스팅할 수 있도록.! 현재는 Auto Mode로 생성하여 AWS가 자동으로 생성해주는 역할에 정책들이 매핑되어 있는 내용에 대해서만 설명하겠습니다. (w/Chat GPT)

 

Cluster IAM 역할

  • 역할
  • 하는 일
    • 컨트롤 플레인 생성관리
    • VPC, 보안 그룹, ELB, 로드밸런싱 등 AWS 네트워크 리소스와의 통합
    • 클러스터 내에서 IAM OIDC 프로바이더를 통해 ServiceAccount와 IAM을 연동
  • Automode에서 추가된 권한 정책

 

Node IAM 역할

  • 역할
  • 하는 일
    • kubelet이 AWS API를 호출 할 수 있도록 권한을 부여
    • EKS가 아닌 바닐라 쿠버네티스에서는 AWS API 호출할 필요없기 때문에 IAM 역할이 필요없음 
      • ECR에서 컨테이너 이미지를 pull (AmazonEC2ContainerRegistryReadOnly)
      • Cloudwatch로 로그 전송 (awslogs)
      • 시스템 매니저 연결 (AmazonSSMManagedInstanceCore)
      • 클러스터 노드 등록 (kubelet은 클러스터에 자신을 등록할 때 aws eks get-token 명령을 실행하여 인증 AmazonEKSWorkerNodePolicy)
  • Automode에서 추가된 권한 정책

 

오잉 생각보다 설정한 내용이 별로 없어서 놀랐습니다. 알고 보니, EKS 생성 시 2가지 구성 옵션이 있었는데, 기존 사용자 지정 구성 대신 클릭 한 번으로 프로비저닝 관리까지 쿠버네티스 클러스터 관리를 최소화하는 기능이라고 합니다.

EKS 자동 모드를 선택하면, 이 모드에서 최적의 인스턴스를 선택하고, 리소스를 동적으로 할당하고, 비용을 최적화하고, 필요한 애드온을 관리하고 등 쿠버네티스에 대한 전문 지식 없이도 클러스터 관리를 자동화할 수 있다고 합니다. Wow 

https://aws.amazon.com/ko/blogs/korea/streamline-kubernetes-cluster-management-with-new-amazon-eks-auto-mode/

 

Amazon EKS Auto Mode 출시: Kubernetes 클러스터 관리 간소화 | Amazon Web Services

오늘은 Amazon Elastic Kubernetes Service(Amazon EKS) Auto Mode 자동 모드의 정식 출시를 발표합니다. 이 자동 모드는 클릭 한 번으로 프로비저닝부터 지속적인 유지 관리까지 컴퓨팅, 스토리지 및 네트워킹

aws.amazon.com

https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html

 

Manage compute resources by using nodes - Amazon EKS

Excluding hybrid nodes, nodes must be in the same VPC as the subnets you selected when you created the cluster. However, the nodes don’t have to be in the same subnets.

docs.aws.amazon.com

 

생성한 EKS 클러스터에 대한 config 생성한 후 테스트용 어플리케이션 파드를 배포합니다. 파드는 잘 올라오는 것을 확인할 수 있었습니다. 아래 '내 PC에서 EKS 클러스터 구성하기' 먼저 참고하여 사전 세팅이 필요합니다.

(하지만 아차차.! 서브넷 구성이 모두 private이라 외부 노출 LB타입 서비스가 만들어지지 않네요. 다른 방식으로 만들 때, 해당 설정을 수정하여 만들어서 확인해보도록 하겠습니다.)

 

# EKS Config 업데이트
~ ❯ aws eks update-kubeconfig --name "${CLUSTER_NAME}"                                               
Added new context arn:aws:eks:ap-northeast-2:~:cluster/eks-console-automode to /Users/yoo/.kube/config

~ ❯ kubectl get node                                                                
NAME                  STATUS   ROLES    AGE   VERSION
i-0187a~   Ready    <none>   67m   v1.31.4-eks-0f56d01
i-0238c~   Ready    <none>   67m   v1.31.4-eks-0f56d01
                                                                                                        
~ ❯ kubectl config current-context                                                  
arn:aws:eks:ap-northeast-2:~:cluster/eks-console-automode


# 테스트 파드 배포 및 외부에서 접근 테스트 (<- public 서브넷이 없어서 불가능)
~ ❯ kubectl run test-nginx --image=nginx --port=80                                  
pod/test-nginx created

~ ❯ kubectl expose pod test-nginx --type=LoadBalancer --port=80 --target-port=80
service/test-nginx exposed

~ ❯ kubectl get pod                                                        
NAME         READY   STATUS    RESTARTS   AGE
test-nginx   1/1     Running   0          109s

~ ❯ kubectl get svc                                                                 
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.100.0.1      <none>        443/TCP        90m
test-nginx   LoadBalancer   10.100.85.233   <pending>     80:30534/TCP   60s

~ ❯ kubectl describe svc test-nginx                                         
Name:                     test-nginx
Namespace:                default
Labels:                   run=test-nginx
Annotations:              <none>
Selector:                 run=test-nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.100.85.233
IPs:                      10.100.85.233
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30534/TCP
Endpoints:                172.31.24.240:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason            Age                   From     Message
  ----     ------            ----                  ----     -------
  Warning  FailedBuildModel  92s (x16 over 4m18s)  service  Failed build model due to unable to resolve at least one subnet (0 match VPC and tags: [kubernetes.io/role/internal-elb])

 

 

 

2) eksctl로 EKS 생성하기

eksctl은 AWS EKS에서 쿠버네티스 클러스터를 생성 및 관리하기 위한 간단한 명령줄 유틸리티입니다.

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/getting-started-eksctl.html

 

Amazon EKS 시작하기 – eksctl - Amazon EKS

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

AWS EC2 인스턴스를 하나 만들어서 내부에 eksctl 설치 후 EKS를 생성해보도록 하겠습니다.

AEWS 스터디에서 제공해주신 Cloudformation 예제 실습 파일로 VPC, Subnet4개, EC2 1대 + 보안그룹(자신의 집 IP만 허용)된 AWS 리소스를 사전 구성할 수 있었습니다. 만들어진 EC2 내부에서 eksctl로 구성하겠습니다.

 

 

# eksctl help
[root@myeks-host ~]# eksctl
The official CLI for Amazon EKS

Usage: eksctl [command] [flags]

Commands:
  eksctl anywhere                        EKS anywhere
  eksctl associate                       Associate resources with a cluster
  ....
  

# 현재 지원 버전 정보 확인
[root@myeks-host ~]# eksctl create cluster -h | grep version
      --version string        Kubernetes version (default "1.30")


# eks 클러스터 생성 + 노드그룹없이
[root@myeks-host ~]# eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --dry-run
Error: checking AWS STS access – cannot get role ARN for current session: operation error STS: GetCallerIdentity, get identity: get credentials: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, http response error StatusCode: 404, request to EC2 IMDS failed


# aws configure 진행
[root@myeks-host ~]# aws configure
AWS Access Key ID [None]: A~
AWS Secret Access Key [None]: H~
Default region name [None]: ap-northeast-2
Default output format [None]: json


# eks 클러스터 생성 + 노드그룹없이 & 사용 가용영역(2a,2c)
[root@myeks-host ~]# eksctl create cluster --name myeks --region=ap-northeast-2 --without-nodegroup --zones=ap-northeast-2a,ap-northeast-2c --dry-run | yh
accessConfig:
  authenticationMode: API_AND_CONFIG_MAP
addonsConfig: {}
apiVersion: eksctl.io/v1alpha5
availabilityZones:
- ap-northeast-2a
- ap-northeast-2c
cloudWatch:
  clusterLogging: {}
iam:
  vpcResourceControllerPolicy: true
  withOIDC: false
kind: ClusterConfig
kubernetesNetworkConfig:
  ipFamily: IPv4
metadata:
  name: myeks
  region: ap-northeast-2
  version: "1.30"
privateCluster:
  enabled: false
  skipEndpointCreation: false
vpc:
  autoAllocateIPv6: false
  cidr: 192.168.0.0/16
  clusterEndpoints:
    privateAccess: false
    publicAccess: true
  manageSharedNodeSecurityGroupRules: true
  nat:
    gateway: Single


# eks 클러스터 생성 + 관리형노드그룹생성(이름, 인스턴스 타입, EBS볼륨사이즈) & 사용 가용영역(2a,2c) + VPC 대역 지정
[root@myeks-host ~] 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 --dry-run | yh
accessConfig:
  authenticationMode: API_AND_CONFIG_MAP
addonsConfig: {}
apiVersion: eksctl.io/v1alpha5
availabilityZones:
- ap-northeast-2a
- ap-northeast-2c
cloudWatch:
  clusterLogging: {}
iam:
  vpcResourceControllerPolicy: true
  withOIDC: false
kind: ClusterConfig
kubernetesNetworkConfig:
  ipFamily: IPv4
managedNodeGroups:
- amiFamily: AmazonLinux2
  desiredCapacity: 2
  disableIMDSv1: true
  disablePodIMDS: false
  iam:
    withAddonPolicies:
      albIngress: false
      appMesh: false
      appMeshPreview: false
      autoScaler: false
      awsLoadBalancerController: false
      certManager: false
      cloudWatch: false
      ebs: false
      efs: false
      externalDNS: false
      fsx: false
      imageBuilder: false
      xRay: false
  instanceSelector: {}
  instanceType: t3.medium
  labels:
    alpha.eksctl.io/cluster-name: myeks
    alpha.eksctl.io/nodegroup-name: mynodegroup
  maxSize: 2
  minSize: 2
  name: mynodegroup
  privateNetworking: false
  releaseVersion: ""
  securityGroups:
    withLocal: null
    withShared: null
  ssh:
    allow: false
    publicKeyPath: ""
  tags:
    alpha.eksctl.io/nodegroup-name: mynodegroup
    alpha.eksctl.io/nodegroup-type: managed
  volumeIOPS: 3000
  volumeSize: 30
  volumeThroughput: 125
  volumeType: gp3
metadata:
  name: myeks
  region: ap-northeast-2
  version: "1.30"
privateCluster:
  enabled: false
  skipEndpointCreation: false
vpc:
  autoAllocateIPv6: false
  cidr: 172.20.0.0/16
  clusterEndpoints:
    privateAccess: false
    publicAccess: true
  manageSharedNodeSecurityGroupRules: true
  nat:
    gateway: Single
    
# 실제 생성
[root@myeks-host ~]# 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
2025-02-08 20:16:53 [ℹ]  eksctl version 0.203.0
2025-02-08 20:16:53 [ℹ]  using region ap-northeast-2
2025-02-08 20:16:53 [ℹ]  subnets for ap-northeast-2a - public:172.20.0.0/19 private:172.20.64.0/19
2025-02-08 20:16:53 [ℹ]  subnets for ap-northeast-2c - public:172.20.32.0/19 private:172.20.96.0/19
2025-02-08 20:16:53 [ℹ]  nodegroup "mynodegroup" will use "" [AmazonLinux2/1.30]
2025-02-08 20:16:53 [ℹ]  using Kubernetes version 1.30
2025-02-08 20:16:53 [ℹ]  creating EKS cluster "myeks" in "ap-northeast-2" region with managed nodes
2025-02-08 20:16:53 [ℹ]  will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
2025-02-08 20:16:53 [ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-2 --cluster=myeks'
2025-02-08 20:16:53 [ℹ]  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "myeks" in "ap-northeast-2"
2025-02-08 20:16:53 [ℹ]  CloudWatch logging will not be enabled for cluster "myeks" in "ap-northeast-2"
2025-02-08 20:16:53 [ℹ]  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-2 --cluster=myeks'
2025-02-08 20:16:53 [ℹ]  default addons metrics-server, vpc-cni, kube-proxy, coredns were not specified, will install them as EKS addons
2025-02-08 20:16:53 [ℹ]
2 sequential tasks: { create cluster control plane "myeks",
    2 sequential sub-tasks: {
        2 sequential sub-tasks: {
            1 task: { create addons },
            wait for control plane to become ready,
        },
        create managed nodegroup "mynodegroup",
    }
}
2025-02-08 20:16:53 [ℹ]  building cluster stack "eksctl-myeks-cluster"
2025-02-08 20:16:53 [ℹ]  deploying stack "eksctl-myeks-cluster"
2025-02-08 20:17:23 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:17:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:18:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:19:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:20:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:21:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:22:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:23:53 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-cluster"
2025-02-08 20:23:54 [ℹ]  creating addon
2025-02-08 20:23:55 [ℹ]  successfully created addon
2025-02-08 20:23:55 [!]  recommended policies were found for "vpc-cni" addon, but since OIDC is disabled on the cluster, eksctl cannot configure the requested permissions; the recommended way to provide IAM permissions for "vpc-cni" addon is via pod identity associations; after addon creation is completed, add all recommended policies to the config file, under `addon.PodIdentityAssociations`, and run `eksctl update addon`
2025-02-08 20:23:55 [ℹ]  creating addon
2025-02-08 20:23:56 [ℹ]  successfully created addon
2025-02-08 20:23:56 [ℹ]  creating addon
2025-02-08 20:23:56 [ℹ]  successfully created addon
2025-02-08 20:23:57 [ℹ]  creating addon
2025-02-08 20:23:57 [ℹ]  successfully created addon
2025-02-08 20:25:57 [ℹ]  building managed nodegroup stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:25:57 [ℹ]  deploying stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:25:57 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:26:27 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:27:23 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:29:14 [ℹ]  waiting for CloudFormation stack "eksctl-myeks-nodegroup-mynodegroup"
2025-02-08 20:29:14 [ℹ]  waiting for the control plane to become ready
2025-02-08 20:29:15 [✔]  saved kubeconfig as "/root/.kube/config"
2025-02-08 20:29:15 [ℹ]  no tasks
2025-02-08 20:29:15 [✔]  all EKS cluster resources for "myeks" have been created
2025-02-08 20:29:15 [ℹ]  nodegroup "mynodegroup" has 2 node(s)
2025-02-08 20:29:15 [ℹ]  node "ip-172-20-0-182.ap-northeast-2.compute.internal" is ready
2025-02-08 20:29:15 [ℹ]  node "ip-172-20-41-89.ap-northeast-2.compute.internal" is ready
2025-02-08 20:29:15 [ℹ]  waiting for at least 2 node(s) to become ready in "mynodegroup"
2025-02-08 20:29:15 [ℹ]  nodegroup "mynodegroup" has 2 node(s)
2025-02-08 20:29:15 [ℹ]  node "ip-172-20-0-182.ap-northeast-2.compute.internal" is ready
2025-02-08 20:29:15 [ℹ]  node "ip-172-20-41-89.ap-northeast-2.compute.internal" is ready
2025-02-08 20:29:15 [✔]  created 1 managed nodegroup(s) in cluster "myeks"
2025-02-08 20:29:16 [ℹ]  kubectl command should work with "/root/.kube/config", try 'kubectl get nodes'
2025-02-08 20:29:16 [✔]  EKS cluster "myeks" in "ap-northeast-2" region is ready

# 생성 확인
(admin@myeks:N/A) [root@myeks-host ~]# kubectl get node
NAME                                              STATUS   ROLES    AGE     VERSION
ip-172-20-0-182.ap-northeast-2.compute.internal   Ready    <none>   4m54s   v1.30.8-eks-aeac579
ip-172-20-41-89.ap-northeast-2.compute.internal   Ready    <none>   4m57s   v1.30.8-eks-aeac579

(admin@myeks:N/A) [root@myeks-host ~]# kubectl config current-context
admin@myeks.ap-northeast-2.eksctl.io

 

EKS 클러스터가 생성되었습니다. 컨트롤플레인과 워커 노드 사이 통신 하는 연결 아이피인 ENI에 대해 확인하기 위해 워커 노드 내부에 SSH로 접근하려고 했는데, 아차차,, 외부에서 노드에 SSH 접근하겠다는 옵션을 넣지 않아서, 추가하여 다시 생성하였습니다.

 

 

2-1) 클러스터 엔드포인트가 Public인 경우

(admin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
>> node 192.168.1.77 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.1.77:44918            3.37.51.116:443   users:(("kubelet",pid=2896,fd=30))
ESTAB 0      0               192.168.1.77:38952            3.37.51.116:443   users:(("aws-k8s-agent",pid=3372,fd=7))
ESTAB 0      56              192.168.1.77:22             192.168.1.100:47844 users:(("sshd",pid=10517,fd=3),("sshd",pid=10485,fd=3))
ESTAB 0      0               192.168.1.77:43524           52.95.195.99:443   users:(("ssm-agent-worke",pid=2477,fd=14))
ESTAB 0      0               192.168.1.77:52350             10.100.0.1:443   users:(("controller",pid=3493,fd=12))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))

>> node 192.168.2.32 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.2.32:38644             10.100.0.1:443   users:(("controller",pid=3497,fd=12))
ESTAB 0      0               192.168.2.32:51158            3.37.51.116:443   users:(("aws-k8s-agent",pid=3376,fd=7))
ESTAB 0      0               192.168.2.32:46450         43.201.244.135:443   users:(("kube-proxy",pid=3114,fd=9))
ESTAB 0      56              192.168.2.32:22             192.168.1.100:37808 users:(("sshd",pid=10789,fd=3),("sshd",pid=10757,fd=3))
ESTAB 0      0               192.168.2.32:38360          52.95.195.121:443   users:(("ssm-agent-worke",pid=2467,fd=14))
ESTAB 0      0               192.168.2.32:40078            3.37.51.116:443   users:(("kubelet",pid=2895,fd=25))
ESTAB 0      0      [::ffff:192.168.2.32]:10250 [::ffff:192.168.1.249]:48460 users:(("kubelet",pid=2895,fd=13))
ESTAB 0      0      [::ffff:192.168.2.32]:10250  [::ffff:192.168.2.29]:51544 users:(("kubelet",pid=2895,fd=11))

 

EC2에서 EKS 워커 노드에 SSH 접근하여 연결 상태를 확인하였습니다.

 

위의 명령어 필드가 나타내는 항목

  • state : 연결 상태 (ESTAB, LISTEN, TIME-WAIT, CLOSE-WAIT 등)
  • Recv-Q : 수신 대기 중인 데이터 크기 (바이트 단위)
  • Send-Q : 송신 대기 중인 데이터 크기 (바이트 단위)
  • Local Address Port : 이 노드 (EC2)에서 사용 중인 IP와 포트
  • Peer Address Port : 통신하는 대상의 IP와 포트
  • Process : 해당 포트 사용 중인 프로세스와 PID

 

1. kubectl -> api-server : Public 통신

cluster 엔드포인트가 모두 퍼블릭 IP로, 로컬 PC 혹은 EC2 내부에서 모두 EKS 엔드포인트는 퍼블릭 구간으로 통신합니다.

(admin@myeks:N/A) [root@myeks-host ~]# APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
(admin@myeks:N/A) [root@myeks-host ~]# dig +short $APIDNS
43.201.244.135
3.37.51.116

 

2. api-server -> kubelet : Private 통신

kubelet은 api-server와 통신하기 위해 10250 포트를 오픈하고, kube api-server는 10250 포트를 사용하여 kubelet api를 호출합니다. 이 때 kubelet의 peer address가 VPC 내부 IP (192.168.x.x) 대역으로 api-server에서 kubelet으로 통신할때는 프라이빗 구간으로 통신합니다.

이때 AWS 내부에서 VPC 내부 통신을 우선 사용하도록 설계되어 있기 때문에 API 서버가 Kubelet과 통신할 때, 퍼블릭 IP가 아닌 프라이빗 IP(192.168.1.77)를 사용하여 요청을 보내므로 VPC 내부 Private ENI를 통해 이루어집니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))

 

3. kubelet/kube-proxy -> api-server : Public 통신

통신하는 대상 IP와 포트가 모두 퍼블릭 API 서버로, kubelet/kube-proxy에서 api-server으로 통신할때는 퍼블릭 구간으로 통신합니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.1.77:44918            3.37.51.116:443   users:(("kubelet",pid=2896,fd=30))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9)

 

다른 터미널을 하나 더 띄워서 파드를 새로 띄울 때 추가 연결된 정보를 확인합니다.

# 다른 터미널을 하나 더 띄워서 파드를 새로 띄울 때 추가 연결된 정보를 확인
(admin@myeks:N/A) [root@myeks-host ~]# kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh

# 다시 실행
(admin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
>> node 192.168.1.77 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      56              192.168.1.77:22             192.168.1.100:56776 users:(("sshd",pid=29192,fd=3),("sshd",pid=29160,fd=3))
ESTAB 0      0               192.168.1.77:44918            3.37.51.116:443   users:(("kubelet",pid=2896,fd=30))
ESTAB 0      0               192.168.1.77:38952            3.37.51.116:443   users:(("aws-k8s-agent",pid=3372,fd=7))
ESTAB 0      0                  127.0.0.1:36123              127.0.0.1:41314 users:(("containerd",pid=2770,fd=76))
ESTAB 0      0               192.168.1.77:43524           52.95.195.99:443   users:(("ssm-agent-worke",pid=2477,fd=14))
ESTAB 0      0               192.168.1.77:52350             10.100.0.1:443   users:(("controller",pid=3493,fd=12))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9))
ESTAB 0      0                  127.0.0.1:41314              127.0.0.1:36123 users:(("kubelet",pid=2896,fd=23))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.159]:39098 users:(("kubelet",pid=2896,fd=22))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))

>> node 192.168.2.32 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.2.32:38644             10.100.0.1:443   users:(("controller",pid=3497,fd=12))
ESTAB 0      0               192.168.2.32:51158            3.37.51.116:443   users:(("aws-k8s-agent",pid=3376,fd=7))
ESTAB 0      0               192.168.2.32:46450         43.201.244.135:443   users:(("kube-proxy",pid=3114,fd=9))
ESTAB 0      0               192.168.2.32:38360          52.95.195.121:443   users:(("ssm-agent-worke",pid=2467,fd=14))
ESTAB 0      56              192.168.2.32:22             192.168.1.100:38140 users:(("sshd",pid=20001,fd=3),("sshd",pid=19969,fd=3))
ESTAB 0      0               192.168.2.32:40078            3.37.51.116:443   users:(("kubelet",pid=2895,fd=25))
ESTAB 0      0      [::ffff:192.168.2.32]:10250 [::ffff:192.168.1.249]:48460 users:(("kubelet",pid=2895,fd=13))
ESTAB 0      0      [::ffff:192.168.2.32]:10250  [::ffff:192.168.2.29]:51544 users:(("kubelet",pid=2895,fd=11))

 

 

실제로 192.168.1.77 노드에 netdebug 파드가 새로 생성되었고, 파드 생성 후 새로 생성된 통신은 다음과 같습니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0                  127.0.0.1:36123              127.0.0.1:41314 users:(("containerd",pid=2770,fd=76))
ESTAB 0      0                  127.0.0.1:41314              127.0.0.1:36123 users:(("kubelet",pid=2896,fd=23))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.159]:39098 users:(("kubelet",pid=2896,fd=22))

 

1. containerd <-> kubelet

kubelet이 새로운 파드를 실행하면 containerd에게 컨테이너를 실행하도록 요청하고, containerd는 내부적으로 kubelet과 gRPC API를 통해 통신합니다. 

이 때, 127.0.0.1에서 통신하는 이유는, containerd와 kubelet이 동일한 노드에서 실행되기 때문입니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0                  127.0.0.1:36123              127.0.0.1:41314 users:(("containerd",pid=2770,fd=76))

 

2. kubelet <-> containerd

kubelet이 containerd로부터 컨테이너 실행 상태를 모니터링하고 있습니다. containerd가 kubelet의 요청을 처리하고, 컨테이너 상태를 kubelet에게 전달합니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0                  127.0.0.1:41314              127.0.0.1:36123 users:(("kubelet",pid=2896,fd=23))

 

3. kubelet -> 다른 노드 또는 컨트롤러

AWS 네트워크 인터페이스 ENI에서 해당 IP(192.1687.1.159)를 확인할 수 있습니다.

 

그리고, ENI의 상세정보를 확인하면 소유자(941377114730) 요청자(478746564259), 인스턴스 소유자(478746564259) 다른것을 확인할 수 있습니다.

즉, EKS owned ENI는 관리형 노드 그룹의 워커 노드는 내 소유지만, 연결된 ENI는 AWS 소유입니다.

State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.159]:39098 users:(("kubelet",pid=2896,fd=22))

 

참고로, 노드 아이피 (192.168.1.77)의 소유자와 인스턴스 소유자는 모두 (941377114730) 동일한 것을 확인할 수 있습니다.

 

 

++ 위 커넥션을 분석하며 알게 된 사실!

Node의 Internal IP : EC2 인스턴스의 Private IP (eth0 인터페이스)

aws-node 파드 IP : 노드 Internal IP와 동일 (AWS VPC CNI)

kubelet IP : 노드 Internal IP와 동일 (노드의 Internal IP 사용하여 API 서버와 통신)

 

소유자 : EKS 계정, 요청자 : VPC CNI, 인스턴스 소유자 : ENI 붙어있는 EC2 노드

 

AWS VPC CNI는 EKS에서 Pod에 VPC 네트워크 인터페이스 할당하는 역할을 합니다.

즉 Pod이 네트워크 사용할 수 있도록 ENI를 추가하고, 이 ENI의 Secondary IP를 Pod에 할당하는 방식으로 동작합니다.

현재는 Primary IP (192.168.1.77), Secondary IP (192.168.1.249, 192.168.1.234, 192.168.1.155, 192.168.1.29, 192.168.1.83)으로 Pod이 네트워크 사용하기 위해 할당받은 주소 입니다.

aws ec2 describe-instance-types  \
    --filters "Name=instance-type,Values=t3.*" \
    --query "InstanceTypes[].{ \
        Type: InstanceType, \
        MaxENI: NetworkInfo.MaximumNetworkInterfaces, \
        IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
    --output table

# t3.medium 사용
-> Primary ENI 3개, ENI당 IPv4 갯수 6개 -> 총 IPv4 갯수 18개의 Pod이 VPC CNI ENI 통해 Secondary IP 할당 가능
--------------------------------------
|        DescribeInstanceTypes       |
+----------+----------+--------------+
| IPv4addr | MaxENI   |    Type      |
+----------+----------+--------------+
|  12      |  3       |  t3.large    |
|  15      |  4       |  t3.2xlarge  |
|  15      |  4       |  t3.xlarge   |
|  6       |  3       |  t3.medium   |
|  2       |  2       |  t3.nano     |
|  2       |  2       |  t3.micro    |
|  4       |  3       |  t3.small    |
+----------+----------+--------------+


# 실제로 eth0, eth1이 현재 구성된 ENI IP, 해당 ENI에 5개 정도의 보조 프라이빗 IP 주소가 연결되어 있음
[ec2-user@ip-192-168-1-77 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:20:44:7a:f7:c9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.77/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 3468sec preferred_lft 3468sec
    inet6 fe80::20:44ff:fe7a:f7c9/64 scope link
       valid_lft forever preferred_lft forever
3: eni74962343ef0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 26:13:af:7a:b7:16 brd ff:ff:ff:ff:ff:ff link-netns cni-320b5b44-7e13-5afd-ba5d-036bf3e75aad
    inet6 fe80::2413:afff:fe7a:b716/64 scope link
       valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:8b:de:c6:34:d9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.124/24 brd 192.168.1.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::8b:deff:fec6:34d9/64 scope link
       valid_lft forever preferred_lft forever
6: eni7d10a2ff7ed@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 3a:bd:ce:7b:e2:07 brd ff:ff:ff:ff:ff:ff link-netns cni-285edcee-501a-4863-eb47-9abd23b64b26
    inet6 fe80::38bd:ceff:fe7b:e207/64 scope link
       valid_lft forever preferred_lft forever

 

 

API 서버 엔드포인트 엑세스가 Public일 경우 통신 구조는 다음과 같습니다.
(초록색은 Public 서브넷, 통신 / 파란색은 Private 서브넷, 통신)

 

 


2-2) 클러스터 엔드포인트가 Public + Private인 경우

(admin@myeks:N/A) [root@myeks-host ~]# dig F87864DEF3FE1A4E8A6C06AF34333F8E.yl4.ap-northeast-2.eks.amazonaws.com +short
192.168.2.12
192.168.1.159

(admin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
>> node 192.168.1.77 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      56              192.168.1.77:22             192.168.1.100:47202 users:(("sshd",pid=74543,fd=3),("sshd",pid=74511,fd=3))
ESTAB 0      0               192.168.1.77:44918            3.37.51.116:443   users:(("kubelet",pid=2896,fd=30))
ESTAB 0      0               192.168.1.77:38952            3.37.51.116:443   users:(("aws-k8s-agent",pid=3372,fd=7))
ESTAB 0      0               192.168.1.77:55312           192.168.2.12:443   users:(("kubelet",pid=2896,fd=16))
ESTAB 0      0               192.168.1.77:43524           52.95.195.99:443   users:(("ssm-agent-worke",pid=2477,fd=14))
ESTAB 0      0               192.168.1.77:52350             10.100.0.1:443   users:(("controller",pid=3493,fd=12))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))

>> node 192.168.2.32 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.2.32:38644             10.100.0.1:443   users:(("controller",pid=3497,fd=12))
ESTAB 0      0               192.168.2.32:51158            3.37.51.116:443   users:(("aws-k8s-agent",pid=3376,fd=7))
ESTAB 0      0               192.168.2.32:38082           52.95.195.99:443   users:(("ssm-agent-worke",pid=2467,fd=14))
ESTAB 0      56              192.168.2.32:22             192.168.1.100:59564 users:(("sshd",pid=74229,fd=3),("sshd",pid=74197,fd=3))
ESTAB 0      0               192.168.2.32:46450         43.201.244.135:443   users:(("kube-proxy",pid=3114,fd=9))
ESTAB 0      0               192.168.2.32:40078            3.37.51.116:443   users:(("kubelet",pid=2895,fd=25))
ESTAB 0      0      [::ffff:192.168.2.32]:10250 [::ffff:192.168.1.249]:48460 users:(("kubelet",pid=2895,fd=13))
ESTAB 0      0      [::ffff:192.168.2.32]:10250  [::ffff:192.168.2.29]:51544 users:(("kubelet",pid=2895,fd=11))

(admin@myeks:N/A) [root@myeks-host ~]# kubectl get node
^C

 

EC2에서 EKS 워커 노드에 SSH 접근하여 연결 상태를 확인하였습니다.

2-1) 엔드포인트를 Public으로 했을 때와 달리 kubelet이 연결하는 api server 엔드포인트가 퍼블릭 IP외에도 프라이빗 IP도 추가되었습니다.

 

이 때, 개인 PC (AWS 네트워크 외부)에서 api server 도메인 질의 했을 때, 퍼블릭 도메인으로 나옵니다.

~ ❯ dig F87864DEF3FE1A4E8A6C06AF34333F8E.yl4.ap-northeast-2.eks.amazonaws.com +short
3.37.51.116
43.201.244.135

~ ❯ kubectl get node                                                                          
NAME                                              STATUS   ROLES    AGE     VERSION
ip-192-168-1-77.ap-northeast-2.compute.internal   Ready    <none>   3h54m   v1.31.4-eks-aeac579
ip-192-168-2-32.ap-northeast-2.compute.internal   Ready    <none>   3h54m   v1.31.4-eks-aeac579

 

 

API 서버 엔드포인트 엑세스가 Public + Private일 경우 통신 구조는 다음과 같습니다.

(초록색은 Public 서브넷, 통신 / 파란색은 Private 서브넷, 통신)

AWS 네트워크 내부 (VPC 등)에서는 Private IP를, 외부에서는 Public IP를 사용합니다.

 

1) kubectl -> api-server : Public 통신

2. api-server -> kubelet : Private 통신

3. kubelet/kube-proxy -> api-server : Private 통신


이와 같은 구조는 운영의 편의성을 위해 Public 엔드포인트를 제공하면서도, 내부에서는 Private 엔드포인트를 사용하여 안전하고 Nat Gateway의 비용을 절감할 수 있습니다

 

 

 

2-3) 클러스터 엔드포인트가 Private인 경우 (도전과제 1번)

(N/A:N/A) [root@myeks-host ~]# dig F87864DEF3FE1A4E8A6C06AF34333F8E.yl4.ap-northeast-2.eks.amazonaws.com +short
192.168.1.159
192.168.2.12

(admin@myeks:N/A) [root@myeks-host ~]# kubectl get node
^C

---Security Group 추가 후---

(arn:aws:eks:ap-northeast-2:941377114730:cluster/myeks:N/A) [root@myeks-host ~]# kubectl get node
NAME                                              STATUS   ROLES    AGE     VERSION
ip-192-168-1-77.ap-northeast-2.compute.internal   Ready    <none>   4h49m   v1.31.4-eks-aeac579
ip-192-168-2-32.ap-northeast-2.compute.internal   Ready    <none>   4h49m   v1.31.4-eks-aeac579

 

이 때 EC2와 EKS가 같은 VPC 내에 있음에도 통신이 불가능하여, 원인을 파악하였더니 EKS 인바운드 규칙일 것으로 예상되었습니다.

 

1) EC2와 EKS가 같은 VPC 내에 있는가? -> 맞음

2) EKS의 Private 엔드포인트가 정상적으로 활성화 되어있는가? -> 맞음

3) EC2의 Security Group 설정은 이상 없는가? -> 이상 없음

4) EKS의 Security Group 설정은 이상 없는가? -> 인바운드 규칙 추가 필요 예상

5) EKS 서브넷 라우팅, NACL 설정 -> 이상 없음

 

같은 VPC내에 있어도 Ingress 규칙이 없는 경우 기본적으로 외부 요청을 차단하기 때문에, EC2의 Security Group에서 EKS로 인바운드 규칙을 명시적으로 추가해야합니다.

또한, 6443포트가 아닌 443 포트만 여는 것은, AWS에서 제공하는 EKS API는 https://~ 로 443포트 HTTPS를 통해 요청을 받기 때문입니다.

 

(arn:aws:eks:ap-northeast-2:941377114730:cluster/myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
>> node 192.168.1.77 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.1.77:38952            3.37.51.116:443   users:(("aws-k8s-agent",pid=3372,fd=7))
ESTAB 0      56              192.168.1.77:22             192.168.1.100:34492 users:(("sshd",pid=96125,fd=3),("sshd",pid=96093,fd=3))
ESTAB 0      0               192.168.1.77:43524           52.95.195.99:443   users:(("ssm-agent-worke",pid=2477,fd=14))
ESTAB 0      0               192.168.1.77:52350             10.100.0.1:443   users:(("controller",pid=3493,fd=12))
ESTAB 0      0               192.168.1.77:60986          192.168.1.159:443   users:(("kubelet",pid=2896,fd=23))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))

>> node 192.168.2.32 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.2.32:38644             10.100.0.1:443   users:(("controller",pid=3497,fd=12))
ESTAB 0      0               192.168.2.32:51158            3.37.51.116:443   users:(("aws-k8s-agent",pid=3376,fd=7))
ESTAB 0      0               192.168.2.32:46450         43.201.244.135:443   users:(("kube-proxy",pid=3114,fd=9))
ESTAB 0      56              192.168.2.32:22             192.168.1.100:58306 users:(("sshd",pid=95578,fd=3),("sshd",pid=95546,fd=3))
ESTAB 0      0               192.168.2.32:40078            3.37.51.116:443   users:(("kubelet",pid=2895,fd=25))
ESTAB 0      0               192.168.2.32:40884          52.95.195.109:443   users:(("ssm-agent-worke",pid=2467,fd=14))
ESTAB 0      0      [::ffff:192.168.2.32]:10250 [::ffff:192.168.1.249]:48460 users:(("kubelet",pid=2895,fd=13))
ESTAB 0      0      [::ffff:192.168.2.32]:10250  [::ffff:192.168.2.29]:51544 users:(("kubelet",pid=2895,fd=11))

 

EC2에서 EKS 워커 노드에 SSH 접근하여 연결 상태를 확인하였습니다.

2-1) 엔드포인트를 Public으로 했을 때와 달리 kubelet이 연결하는 api server 엔드포인트가 퍼블릭 IP은 제외되고 프라이빗 IP만 존재합니다. 

실제로 ENI를 확인했을 때도 동일한 결과를 확인할 수 있었습니다.

netdebug Pod를 배포했을 때 다음과 같습니다. 192.168.1.77 노드에 2-1)에서와 동일하게, containerd, kubelet, ENI에 대한 연결이 3개 추가된 것을 확인할 수 있습니다.

(arn:aws:eks:ap-northeast-2:941377114730:cluster/myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo ss -tnp; echo; done
>> node 192.168.1.77 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0                  127.0.0.1:44434              127.0.0.1:36123 users:(("kubelet",pid=2896,fd=24))
ESTAB 0      0               192.168.1.77:38952            3.37.51.116:443   users:(("aws-k8s-agent",pid=3372,fd=7))
ESTAB 0      0                  127.0.0.1:36123              127.0.0.1:44434 users:(("containerd",pid=2770,fd=76))
ESTAB 0      56              192.168.1.77:22             192.168.1.100:39020 users:(("sshd",pid=98941,fd=3),("sshd",pid=98909,fd=3))
ESTAB 0      0               192.168.1.77:43524           52.95.195.99:443   users:(("ssm-agent-worke",pid=2477,fd=14))
ESTAB 0      0               192.168.1.77:52350             10.100.0.1:443   users:(("controller",pid=3493,fd=12))
ESTAB 0      0               192.168.1.77:60986          192.168.1.159:443   users:(("kubelet",pid=2896,fd=23))
ESTAB 0      0               192.168.1.77:53048         43.201.244.135:443   users:(("kube-proxy",pid=3109,fd=9))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.29]:54004 users:(("kubelet",pid=2896,fd=12))
ESTAB 0      0      [::ffff:192.168.1.77]:10250 [::ffff:192.168.1.249]:57944 users:(("kubelet",pid=2896,fd=14))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.12]:41014 users:(("kubelet",pid=2896,fd=22))

>> node 192.168.2.32 <<
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0               192.168.2.32:38644             10.100.0.1:443   users:(("controller",pid=3497,fd=12))
ESTAB 0      0               192.168.2.32:51158            3.37.51.116:443   users:(("aws-k8s-agent",pid=3376,fd=7))
ESTAB 0      0               192.168.2.32:46450         43.201.244.135:443   users:(("kube-proxy",pid=3114,fd=9))
ESTAB 0      56              192.168.2.32:22             192.168.1.100:50770 users:(("sshd",pid=98116,fd=3),("sshd",pid=98084,fd=3))
ESTAB 0      0               192.168.2.32:40078            3.37.51.116:443   users:(("kubelet",pid=2895,fd=25))
ESTAB 0      0               192.168.2.32:40884          52.95.195.109:443   users:(("ssm-agent-worke",pid=2467,fd=14))
ESTAB 0      0      [::ffff:192.168.2.32]:10250 [::ffff:192.168.1.249]:48460 users:(("kubelet",pid=2895,fd=13))
ESTAB 0      0      [::ffff:192.168.2.32]:10250  [::ffff:192.168.2.29]:51544 users:(("kubelet",pid=2895,fd=11))


# 추가된 연결
State Recv-Q Send-Q         Local Address:Port            Peer Address:Port Process
ESTAB 0      0                  127.0.0.1:44434              127.0.0.1:36123 users:(("kubelet",pid=2896,fd=24))
ESTAB 0      0                  127.0.0.1:36123              127.0.0.1:44434 users:(("containerd",pid=2770,fd=76))
ESTAB 0      0      [::ffff:192.168.1.77]:10250  [::ffff:192.168.2.12]:41014 users:(("kubelet",pid=2896,fd=22))

 

이 때, 개인 PC (AWS 네트워크 외부)에서 api server 도메인 질의 했을 때, Private IP로 나옵니다. 따라서 외부에서 api server에 대한 호출도 불가능합니다.

~ ❯ dig F87864DEF3FE1A4E8A6C06AF34333F8E.yl4.ap-northeast-2.eks.amazonaws.com +short
192.168.1.159
192.168.2.12

~ ❯ kubectl get node                                       
^C

 

 

API 서버 엔드포인트 엑세스가 Private일 경우 통신 구조는 다음과 같습니다.

(초록색은 Public 서브넷, 통신 / 파란색은 Private 서브넷, 통신)

 

1) kubectl -> api-server : Private 통신

2. api-server -> kubelet : Private 통신

3. kubelet/kube-proxy -> api-server : Private 통신