Infra/AWS

[AEWS] # 2์ฃผ์ฐจ eks vpc cni ์ดํ•ดํ•˜๊ธฐ (1)

์˜ค๋ฌ˜ 2025. 2. 16. 05:37
25๋…„๋„ AWS EKS Hands-on Study ์Šคํ„ฐ๋”” ์ •๋ฆฌ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ

CloudFormation

curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/myeks-2week.yaml

aws cloudformation deploy --template-file ~/Downloads/myeks-2week.yaml \
     --stack-name myeks --parameter-overrides KeyName=[my key] \
     SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

# ec2 ip ์ถœ๋ ฅ
aws cloudformation describe-stacks --stack-name myeks \
    --query 'Stacks[*].Outputs[*].OutputValue' --output text

# ssh ์ ‘์† ํ™•์ธ
ssh ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)

eksctl 

export CLUSTER_NAME=myeks # eks cluster name

export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" --query 'Vpcs[*].VpcId' --output text)
echo $VPCID

# ํผ๋ธ”๋ฆญ ์„œ๋ธŒ๋„ท ํ™•์ธ
export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet3=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet3" --query "Subnets[0].[SubnetId]" --output text)
echo $PubSubnet1 $PubSubnet2 $PubSubnet3

 

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: myeks
  region: ap-northeast-2
  version: "1.31"

kubernetesNetworkConfig:
  ipFamily: IPv4

iam:
  vpcResourceControllerPolicy: true
  withOIDC: true

accessConfig:
  authenticationMode: API_AND_CONFIG_MAP

vpc:
  autoAllocateIPv6: false
  cidr: 192.168.0.0/16
  clusterEndpoints:
    privateAccess: true # if you only want to allow private access to the cluster
    publicAccess: true # if you want to allow public access to the cluster
  id: vpc-0ab40d2acbda845d8  # ๊ฐ์ž ํ™˜๊ฒฝ ์ •๋ณด๋กœ ์ˆ˜์ •
  manageSharedNodeSecurityGroupRules: true # if you want to manage the rules of the shared node security group
  nat:
    gateway: Disable
  subnets:
    public:
      ap-northeast-2a:
        az: ap-northeast-2a
        cidr: 192.168.1.0/24
        id: [ํผ๋ธ”๋ฆญ ์„œ๋ธŒ๋„ท]
      ap-northeast-2b:
        az: ap-northeast-2b
        cidr: 192.168.2.0/24
        id: [ํผ๋ธ”๋ฆญ ์„œ๋ธŒ๋„ท]
      ap-northeast-2c:
        az: ap-northeast-2c
        cidr: 192.168.3.0/24
        id: [ํผ๋ธ”๋ฆญ ์„œ๋ธŒ๋„ท]
addons:
  - name: vpc-cni # no version is specified so it deploys the default version
    version: latest # auto discovers the latest available
    attachPolicyARNs: # attach IAM policies to the add-on's service account
      - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    configurationValues: |-
      enableNetworkPolicy: "true"

  - name: kube-proxy
    version: latest

  - name: coredns
    version: latest

  - name: metrics-server
    version: latest

privateCluster:
  enabled: false
  skipEndpointCreation: false

managedNodeGroups:
- amiFamily: AmazonLinux2023
  desiredCapacity: 3
  disableIMDSv1: true
  disablePodIMDS: false
  iam:
    withAddonPolicies:
      albIngress: false # Disable ALB Ingress Controller
      appMesh: false
      appMeshPreview: false
      autoScaler: false
      awsLoadBalancerController: true # Enable AWS Load Balancer Controller
      certManager: true # Enable cert-manager
      cloudWatch: false
      ebs: false
      efs: false
      externalDNS: true # Enable ExternalDNS
      fsx: false
      imageBuilder: true
      xRay: false
  instanceSelector: {}
  instanceType: t3.medium
  preBootstrapCommands:
    # install additional packages
    - "dnf install nvme-cli links tree tcpdump sysstat ipvsadm ipset bind-utils htop -y"
    # disable hyperthreading
    - "for n in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | cut -s -d, -f2- | tr ',' '\n' | sort -un); do echo 0 > /sys/devices/system/cpu/cpu${n}/online; done"
  labels:
    alpha.eksctl.io/cluster-name: myeks
    alpha.eksctl.io/nodegroup-name: ng1
  maxSize: 3
  minSize: 3
  name: ng1
  privateNetworking: false
  releaseVersion: ""
  securityGroups:
    withLocal: null
    withShared: null
  ssh:
    allow: true
    publicKeyName: [key pair]
  tags:
    alpha.eksctl.io/nodegroup-name: ng1
    alpha.eksctl.io/nodegroup-type: managed
  volumeIOPS: 3000
  volumeSize: 30
  volumeThroughput: 125
  volumeType: gp3

 

eksctl๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•  ๊ตฌ์„ฑ ํŒŒ์ผ์ด๋‹ค. ๊ตฌ์„ฑ๋œ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • myeks๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์„œ์šธ ๋ฆฌ์ „์— 1.31๋กœ ๋ฐฐํฌ๋  ํด๋Ÿฌ์Šคํ„ฐ์ด๋‹ค.
  • vpc ๋ฆฌ์†ŒํŠธ ์ปจํŠธ๋กค๋Ÿฌ ์ •์ฑ…์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ AWS VPC ๋„คํŠธ์›Œํฌ ๋ฆฌ์†Œ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ•œ๋‹ค.
  • OIDC ID ๊ณต๊ธ‰์ž ์„ค์ •์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ IAM, ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์„œ๋น„์Šค ๊ณ„์ •๊ฐ„์˜ ์—ฐ๊ฒฐ ์ง€์›์„ ์„ค์ •ํ•œ๋‹ค.
  • ํด๋Ÿฌ์Šคํ„ฐ ์ ‘๊ทผ ์ธ์ฆ์˜ ๊ฒฝ์šฐ AWS IAM ๊ธฐ๋ฐ˜ ์ธ์ฆ๊ณผ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ RBAC์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • VPC CIDR์˜ ๊ฒฝ์šฐ 192.168.0.0/16์„ ์‚ฌ์šฉํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ์—”๋“œํฌ์ธํŠธ์˜ ๊ฒฝ์šฐ public, private ์•ก์„ธ์Šค๊ฐ€ ๋ชจ๋‘ ์„ค์ •๋˜์–ด ํด๋Ÿฌ์Šคํ„ฐ API ์„œ๋ฒ„ ์ ‘๊ทผ์ด ์™ธ๋ถ€ ๋‚ด๋ถ€ ๋ชจ๋‘ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์• ๋“œ์˜จ์˜ ๊ฒฝ์šฐ VPC CNI, kube proxy, coreDNS, Metrics Server 4๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • EKS ๋…ธ๋“œ ๊ทธ๋ฃน์„ ํ†ตํ•ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์›Œ์ปค ๋…ธ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
eksctl create cluster -f myeks.yaml --verbose 4

๋ฐฐํฌ๋œ eks ํด๋Ÿฌ์Šคํ„ฐ ํ™•์ธ

kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone

kubectl get node -v=6
NAME                                               STATUS   ROLES    AGE     VERSION
ip-192-168-1-112.ap-northeast-2.compute.internal   Ready    <none>   6m25s   v1.31.5-eks-5d632ec
ip-192-168-2-169.ap-northeast-2.compute.internal   Ready    <none>   6m17s   v1.31.5-eks-5d632ec
ip-192-168-3-231.ap-northeast-2.compute.internal   Ready    <none>   6m22s   v1.31.5-eks-5d632ec

 

๋…ธ๋“œ ๊ทธ๋ฃน ์ธ๋ฐ”์šด๋“œ ๋ฃฐ ์ถ”๊ฐ€

aws ec2 describe-instances --query "Reservations[*].Instances[*].{InstanceID:InstanceId, PublicIPAdd:PublicIpAddress, PrivateIPAdd:PrivateIpAddress, InstanceName:Tags[?Key=='Name']|[0].Value, Status:State.Name}" --filters Name=instance-state-name,Values=running --output table

----------------------------------------------------------------------------------------
|                                   DescribeInstances                                  |
+----------------------+-----------------+----------------+----------------+-----------+
|      InstanceID      |  InstanceName   | PrivateIPAdd   |  PublicIPAdd   |  Status   |
+----------------------+-----------------+----------------+----------------+-----------+
|  i-04332dffb3235a12f |  myeks-ng1-Node |  192.168.3.x   |  54.x.x.x      |  running  |
|  i-0c9a528984351cadb |  operator-host  |  172.20.1.x    |  43.x.x.x      |  running  |
|  i-0377ada6c8218a6b8 |  myeks-ng1-Node |  192.168.1.x   |  43.x.x.x      |  running  |
|  i-0681ecb761cc83614 |  myeks-ng1-Node |  192.168.2.x   |  43.x.x.x.     |  running  |
+----------------------+-----------------+----------------+----------------+-----------+

export MNSGID=[๊ด€๋ฆฌํ˜• ๋…ธ๋“œ ๊ทธ๋ฃน ๋ณด์•ˆ๊ทธ๋ฃน]

# ๋ณธ์ธ ์ง‘ ๊ณต์ธ ip ์ถ”๊ฐ€
aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr $(curl -s ipinfo.io/ip)/32

# ec2 IP ๋ฃฐ ์ถ”๊ฐ€
aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr 172.20.1.100/32

ssh -i pemํ‚ค ec2-user@$N1
ssh -i pemํ‚ค ec2-user@$N2
ssh -i pemํ‚ค ec2-user@$N3

 

๋…ธ๋“œ๊ทธ๋ฃน ng1์€ EKS์˜ ๊ด€๋ฆฌํ˜• ๋…ธ๋“œ ๊ทธ๋ฃน์ธ๋ฐ, ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ์›Œ์ปค ๋…ธ๋“œ๋“ค์ด ์†ํ•ด ์žˆ๋Š” ๊ทธ๋ฃน์œผ๋กœ ๋ณด์•ˆ ์ •์ฑ… ๋‚ด ์ธ๋ฐ”์šด๋“œ ๋ฃฐ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

๋ณธ์ธ์˜ ์ง‘์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ณต์ธ ip์™€ ec2 ์„œ๋ฒ„์˜ ๋‚ด๋ถ€ ip๋ฅผ ๋ณด์•ˆ๊ทธ๋ฃน์— ์ถ”๊ฐ€ํ•ด์„œ eks ๋…ธ๋“œ๊ทธ๋ฃน ์ ‘๊ทผ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ํ•‘ ๋ฐ ssh ์ ‘์†์„ ํ™•์ธํ•œ๋‹ค.

 

aws ssm start-session --target i-04332dffb3235a12f

Starting session with SessionId: nana-r66x7642x6tqrv75aiipq5h57i
sh-5.2$ whoami
ssm-user
sh-5.2$ pwd
/usr/bin
sh-5.2$ hostnamectl
 Static hostname: ip-192-168-3-231.ap-northeast-2.compute.internal
       Icon name: computer-vm
         Chassis: vm ๐Ÿ–ด
      Machine ID: ec2df7d5af5533fefc902e710ae161c9
         Boot ID: a02d09acde7b4e82962ba4b70c9bc853
  Virtualization: amazon
Operating System: Amazon Linux 2023.6.20250203
     CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2023
          Kernel: Linux 6.1.127-135.201.amzn2023.x86_64
    Architecture: x86-64
 Hardware Vendor: Amazon EC2
  Hardware Model: t3.medium
Firmware Version: 1.0

sh-5.2$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
ec2-user:x:1000:1000:EC2 Default User:/home/ec2-user:/bin/bash
ssm-user:x:1001:1001::/home/ssm-user:/bin/bash
...

# sudo ๊ถŒํ•œ ํ™•์ธ
sh-5.2$ sudo -l
Matching Defaults entries for ssm-user on ip-192-168-3-231:
    !visiblepw, always_set_home, match_group_by_gid,
    always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY
    HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL QTDIR
    USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
    LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
    env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
    LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS
    _XKB_CHARSET XAUTHORITY",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/var/lib/snapd/snap/bin

User ssm-user may run the following commands on ip-192-168-3-231:
    (ALL) NOPASSWD: ALL

 

๋˜ํ•œ ssh ์—†์ด aws session manager๋ฅผ ํ†ตํ•ด ec2 ์ธ์Šคํ„ด์Šค์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, IAM ๊ถŒํ•œ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ aws configure๋กœ ์‚ฌ์ „์— ํ‚ค ์„ค์ •ํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

์„ธ์…˜ ๋งค๋‹ˆ์ €์˜ ๊ฒฝ์šฐ ssm user๊ฐ€ sudo ๊ถŒํ•œ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€์—ฌ๋˜์–ด์„œ root ๊ถŒํ•œ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

AWS VPC CNI

EKS์—์„œ ํŒŒ๋“œ๋“ค์€ AWS VPC CNI๋ฅผ ํ†ตํ•ด ec2 ์ธ์Šคํ„ด์Šค์ฒ˜๋Ÿผ ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

vpc cni๋Š” cni ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ipamd๋ผ๋Š” 2๊ฐ€์ง€ ํ•ต์‹ฌ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋ผ์žˆ๋Š”๋ฐ, cni ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” kubelet์—์„œ ์ƒˆ๋กœ์šด ํŒŒ๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž๋™์œผ๋กœ ํŒŒ๋“œ ๋„คํŠธ์›Œํฌ๋ฅผ ์„ค์ •ํ•˜์—ฌ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” ๊ฐ ๋…ธ๋“œ์˜ ํŒŒ์ผ์‹œ์Šคํ…œ์— ์„ค์น˜๋˜์–ด ์žˆ๋‹ค.

ipamd๋Š” ec2 eni๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ip์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ec2 ์ธ์Šคํ„ด์Šค ์ข…๋ฅ˜์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. eni์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ip ์ฃผ์†Œ๋ฅผ ๋ฏธ๋ฆฌ ํ™•๋ณดํ•˜๋Š”๋ฐ ์ด๋ฅผ warm pool์ด๋ผ๊ณ  ํ•œ๋‹ค. ํŒŒ๋“œ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๋น ๋ฅด๊ฒŒ ip ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ํ•ด์คŒ์œผ๋กœ์จ, ํŒŒ๋“œ๊ฐ€ ์‚ฌ์šฉํ•  ๋„คํŠธ์›Œํฌ ์ฃผ์†Œ๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•œ๋‹ค.

 

์ฒ˜์Œ ec2 ์ธ์Šคํ„ด์Šค๊ฐ€ ์‹œ์ž‘๋˜๋ฉด ec2๋Š” ํ”„๋ผ์ด๋จธ๋ฆฌ eni๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ์ด eni๋Š” ํผ๋ธ”๋ฆญ, ํ”„๋ผ์ด๋น— ์„œ๋ธŒ๋„ท์œผ๋กœ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ hostNetwork ๋ชจ๋“œ์ผ ๊ฒฝ์šฐ ํŒŒ๋“œ๋Š” eni์˜ ip์™€ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

ํŒŒ๋“œ๊ฐ€ ์ƒ๊ธฐ๋ฉด vpc cni๋Š” ipamd๋ฅผ ํ†ตํ•ด ip๋ฅผ ๋ฐ›๋Š”๋ฐ, vpc cni๋Š” ec2์— ์ถ”๊ฐ€๋กœ eni๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ํŒŒ๋“œ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜๋ก eni๊ฐ€ ์ถ”๊ฐ€๋˜๋Š”๋ฐ ์ด๋ฅผ ์„ธ์ปจ๋”๋ฆฌ eni๋ผ๊ณ  ํ•œ๋‹ค. 

ec2๋งˆ๋‹ค ์ตœ๋Œ€ eni๊ฐœ์ˆ˜์™€ ip ๊ฐœ์ˆ˜๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํŒŒ๋“œ ๊ฐœ์ˆ˜๋„ ์ด๋กœ ๊ฒฐ์ •๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•œ ๊ฐœ์˜ ec2 ์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํŒŒ๋“œ์˜ ๊ฐœ์ˆ˜๋Š” eni * (eni๊ฐ€ ์ง€์›ํ•˜๋Š” ipv4 - 1) + 2๋กœ ๊ณ„์‚ฐ๋œ๋‹ค.

 

coreDNS ํŒŒ๋“œ์™€ eks ๋…ธ๋“œ์˜ ํ”„๋ผ์ด๋น— ip๊ฐ€ ๊ฐ™์€ ์ด์œ 

kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

amazon-k8s-cni-init:v1.19.2-eksbuild.5
amazon-k8s-cni:v1.19.2-eksbuild.5
amazon

+----------------+-----------------+
|  InstanceName  |  PrivateIPAdd   |
+----------------+-----------------+
|  myeks-ng1-Node|  192.168.3.231  |
|  operator-host |  172.20.1.100   | 
|  myeks-ng1-Node|  192.168.1.112  |
|  myeks-ng1-Node|  192.168.2.169  |  
+----------------+-----------------+

kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
NAME                              IP              STATUS
aws-node-7pzrz                    192.168.1.112   Running
aws-node-ctfl4                    192.168.3.231   Running
aws-node-ns6ph                    192.168.2.169   Running
coredns-86f5954566-mlwpn          192.168.1.100   Running
coredns-86f5954566-qfk2r          192.168.3.41    Running
kube-proxy-d6jc4                  192.168.3.231   Running
kube-proxy-d9w9l                  192.168.2.169   Running
kube-proxy-skt8n                  192.168.1.112   Running
metrics-server-6bf5998d9c-lsbq6   192.168.1.160   Running
metrics-server-6bf5998d9c-pfl7z   192.168.3.183   Running

 

eks๋Š” vpc cni๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ๋“œ๋“ค์€ vpc์˜ ์‹ค์ œ ๋„คํŠธ์›Œํฌ์—์„œ IP๋ฅผ ์ง์ ‘ ํ• ๋‹น๋ฐ›๋Š”๋ฐ, ํŒŒ๋“œ๋“ค์€ vpc ์„œ๋ธŒ๋„ท์— ์žˆ๋Š” ec2์™€ ๋™์ผํ•œ ๋„คํŠธ์›Œํฌ์—์„œ ๋™์ž‘ํ•œ๋‹ค.

 

 

aws-node์™€ kube-proxy๋Š” ec2์˜ ๋ฐ๋ชฌ์…‹์œผ๋กœ ์‹คํ–‰๋˜๋Š”๋ฐ ๋ฐ๋ชฌ์…‹์€ ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ์ œ์–ดํ•˜๋Š” ํŒŒ๋“œ์ด๋ฏ€๋กœ ์ด ๋…ธ๋“œ์˜ ํ”„๋ผ์ด๋น— ip๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

์ด ์™ธ ํŒŒ๋“œ๋Š” ec2์˜ eni์—์„œ ํ• ๋‹น๋œ ํ”„๋ผ์ด๋น— ip๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด ํŒŒ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋…ธ๋“œ์˜ ์„œ๋ธŒ๋„ท์—์„œ ํ• ๋‹น๋œ๋‹ค.

 

netshoot-pod ํ…Œ์ŠคํŠธ

 

 

 

[ec2-user@ip-192-168-3-231 ~]$ sudo lsns -t net
        NS TYPE NPROCS   PID USER     NETNSID NSFS                                                COMMAND
4026531840 net     111     1 root  unassigned                                                     /usr/li
4026532211 net       2  3235 65535          0 /run/netns/cni-615c56d6-0bfb-b770-1e4c-29e55aaa917c /pause
4026532291 net       2  3323 65535          1 /run/netns/cni-49185490-e3e4-f8a0-c09d-eedb7e52642a /pause
4026532403 net       2 46278 65535          2 /run/netns/cni-a22f9035-44e1-8bb3-8403-84708f0b21e9 /pause

[ec2-user@ip-192-168-3-231 ~]$ PID=46278
[ec2-user@ip-192-168-3-231 ~]$ sudo nsenter -t $PID -n ip -c addr
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 proto kernel_lo
       valid_lft forever preferred_lft forever
3: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether fa:42:c9:aa:e0:7e brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.3.250/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f842:c9ff:feaa:e07e/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever
       
[ec2-user@ip-192-168-3-231 ~]$ sudo nsenter -t $PID -n ip -c route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link

 

eks์˜ ํŒŒ๋“œ ๋„คํŠธ์›Œํฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ํ™•์ธํ•˜๊ณ , ํŒŒ๋“œ ๋‚ด๋ถ€์˜ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๋ผ์šฐํŒ… ํ…Œ์ด๋ธ”์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŒŒ๋“œ ๋‚ด๋ถ€์—์„œ ์‹คํ–‰ ์ค‘์ธ pause ์ปจํ…Œ์ด๋„ˆ์˜ ํ”„๋กœ์„ธ์Šค ID์ธ 46278๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๋„คํŠธ์›Œํฌ ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

Loopback (lo)

  • 127.0.0.1/8: ํŒŒ๋“œ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฃจํ”„๋ฐฑ ์ธํ„ฐํŽ˜์ด์Šค

eth0@if6 (ํŒŒ๋“œ์˜ ๋ฉ”์ธ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค)

  • eth0@if6: ํŒŒ๋“œ์˜ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค
  • MTU 9001 → AWS์—์„œ ์ œ๊ณตํ•˜๋Š” ์ ๋ณด ํ”„๋ ˆ์ž„
  • MAC ์ฃผ์†Œ: fa:42:c9:aa:e0:7e
  • IPv4 ์ฃผ์†Œ: 192.168.3.250/32 -> aws eni๋กœ ์ œ๊ณต๋œ ๊ฒƒ
  • IPv6 ๋งํฌ-๋กœ์ปฌ ์ฃผ์†Œ: fe80::f842:c9ff:feaa:e07e/64

 

ํŒŒ๋“œ์—์„œ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ณด๋‚ผ ๋•Œ, 169.254.1.1์„ ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, 169.254.1.1์€ AWS VPC CNI์—์„œ ์ œ๊ณตํ•˜๋Š” NAT ๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• ์„ ํ•œ๋‹ค. ๋กœ์ปฌ eni์™€ ์—ฐ๊ฒฐ๋œ ๋„คํŠธ์›Œํฌ๋Š” ํŒŒ๋“œ์™€ ๊ฐ™์€ ec2์—์„œ ์‹คํ–‰๋˜๋Š” ๋‹ค๋ฅธ ํŒŒ๋“œ๋“ค๊ณผ ํ†ต์‹ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

ํŒŒ๋“œ ๊ฐ„ ํ†ต์‹ ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” eni๋กœ ๋ผ์šฐํŒ…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์™ธ๋ถ€ ํŠธ๋ž˜ํ”ฝ์€ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์„ ๋ณด๋‚ธ๋‹ค.

ํŒŒ๋“œ ๊ฐ„ ํ†ต์‹  ํŒจํ‚ท ๋คํ”„

PODIP1=$(kubectl get pod -l app=netshoot-pod -o jsonpath='{.items[0].status.podIP}')
PODIP2=$(kubectl get pod -l app=netshoot-pod -o jsonpath='{.items[1].status.podIP}')
PODIP3=$(kubectl get pod -l app=netshoot-pod -o jsonpath='{.items[2].status.podIP}')

# ํ•‘ ํ…Œ์ŠคํŠธ
kubectl exec -it $PODNAME1 -- ping -c 2 $PODIP2
kubectl exec -it $PODNAME2 -- ping -c 2 $PODIP3
kubectl exec -it $PODNAME3 -- ping -c 2 $PODIP1

 

 

 

# 1๋ฒˆ ํŒŒ๋“œ
ens5  In  IP 192.168.2.27 > 192.168.1.182: ICMP echo request
eni1ca12149b57 Out IP 192.168.2.27 > 192.168.1.182: ICMP echo request

# 2๋ฒˆ ํŒŒ๋“œ
eni3628be173f9 In  IP 192.168.2.27 > 192.168.1.182: ICMP echo request
ens5  Out IP 192.168.2.27 > 192.168.1.182: ICMP echo request

 

1๋ฒˆ ํŒŒ๋“œ -> 2๋ฒˆ ํŒŒ๋“œ๋กœ ํ•‘์„ ์  ๋•Œ ํŒจํ‚ท ๋คํ”„์ด๋‹ค.
์ถœ๋ฐœ์ง€ 192.168.2.27 → ๋ชฉ์ ์ง€ 192.168.1.182์˜ IP๊ฐ€ ๋ชจ๋“  ๊ตฌ๊ฐ„์—์„œ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋Š”๋ฐ, NAT๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
eni๋ฅผ ํ†ตํ•ด ํŒจํ‚ท์ด ์ง์ ‘ ์ „๋‹ฌ๋˜๋ฏ€๋กœ vpc ๋„คํŠธ์›Œํฌ์—์„œ ๊ทธ๋Œ€๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.