실습환경 구성
배포
cloudformation template를 적용하여 stack을 배포하겠습니다.
https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/kans/eks-oneclick.yaml
stack 이름을 myeks로 설정한 다음 배포해줍니다.
cloudformation stack이 모두 완료되는 시간은 20분정도 소요될 수 있습니다.
모든 리소스가 생성된 이후에는 ec2에서 bastion host를 통해서 클러스터에 접근할 수 있습니다.
배포 확인
# default 네임스페이스 적용
kubectl ns default
# 설치 확인
kubectl cluster-info
# 클러스터 정보 확인
eksctl get cluster
# 클러스터 노드그룹 정보 확인
eksctl get nodegroup --cluster $CLUSTER_NAME
# 클러스터 구성정보 확인
kubectl config view
# node 조회
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
# iam identity mapping
eksctl get iamidentitymapping --cluster myeks
# krew 플러그인 확인
kubectl krew list
# 모든 네임스페이스에서 모든 리소스 확인
kubectl get-all
# 클러스터에 설치된 add on 조회
eksctl get addon --cluster $CLUSTER_NAME
VPC CNI
소개
파드가 VPC의 ip를 직접 사용하므로, VPC내 다른 리소스와 원활하게 통신할 수 있습니다.
오버레이 네트워크를 사용하지 않아서 네트워크 성능이 우수합니다.
CNI 플러그인은 노드에서 ENI를 관리합니다. 노드가 프로비저닝되면 CNI 플러그인은 노드의 서브넷에서 기본 ENI로 슬롯 풀(IP 또는 접두사)을 자동으로 할당합니다. 이를 웜 풀이라고 하며 크기는 노드의 인스턴스 유형에 따라 결정됩니다. CNI 설정에 따라 슬롯은 IP 주소 또는 접두사가 될 수 있습니다. ENI의 슬롯이 할당되면 CNI는 슬롯의 웜 풀이 있는 추가 ENI를 노드에 연결할 수 있습니다. 이러한 추가 ENI를 보조 ENI라고 합니다. 각 ENI는 인스턴스 유형에 따라 특정 수의 슬롯만 지원할 수 있습니다. CNI는 필요한 슬롯 수에 따라 인스턴스에 더 많은 ENI를 연결하며, 이는 일반적으로 Pod 수에 해당합니다. 이 프로세스는 노드가 더 이상 추가 ENI를 지원할 수 없을 때까지 계속됩니다. CNI는 또한 더 빠른 Pod 시작을 위해 웜 ENI와 슬롯을 미리 할당합니다. 각 인스턴스 유형에는 연결할 수 있는 최대 ENI 수가 있습니다. 이는 컴퓨팅 리소스 외에도 Pod 밀도(노드당 Pod 수)에 대한 제약 조건 중 하나입니다.
calico CNI vs VPC CNI
Calico CNI에는 오버레이를 통해 노드간 통신이 가능한 반면, VPC CNI는 VPC 와 같은 대역을 활용하기 때문에 파드간 통신을 같은 네트워크 내에서 가능합니다.
네트워크
노드의 기본 네트워크
워커 노드에서 Private IP와 Secondary Private IP가 있는 것을 확인할 수 있습니다.
secondary private IP를 사용하는지 확인하기 위해 파드를 생성해보겠습니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 3
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
새로운 파드를 생성하니, 보조 프라이빗 IP를 사용합니다.
# network 정보 조회
ip -br -c addr show
ip -c link
ip -c addr
ip route # 혹은 route -n
노드간 파드 통신
파드간 통신 흐름 : AWS VPC CNI 경우 별도의 오버레이(Overlay) 통신 기술 없이, VPC Native 하게 파드간 직접 통신이 가능하다.
파드에서 외부 통신
파드에서 외부 통신 흐름 : iptable 에 SNAT 을 통하여 노드의 eth0 IP로 변경되어서 외부와 통신됨
파드 생성 제한
Secondary IPv4 addresses (기본값) : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
- 인스턴스 타입 별 ENI 최대 갯수와 할당 가능한 최대 IP 갯수에 따라서 파드 배치 갯수가 결정됨
- 단, aws-node 와 kube-proxy 파드는 호스트의 IP를 사용함으로 최대 갯수에서 제외함
최대 파드 생성 갯수 : (Number of network interfaces for the instance type × (the number of IP addressess per network interface - 1)) + 2
인스턴스의 MaxENI 테이블 확인하는 방법
aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \
--query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
--output table
최대 파드 생성 확인
# 디플로이먼트 생성
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/nginx-dp.yaml
kubectl apply -f nginx-dp.yaml
# 파드 증가 to 8
kubectl scale deployment nginx-deployment --replicas=8
# 파드 증가 to 50
kubectl scale deployment nginx-deployment --replicas=50
현재까지는 요청한 파드가 모두 생성되고 있음을 확인할 수 있습니다.
파드 갯수를 50개로 늘리자 Pending 인 파드가 하나씩 보이기 시작합니다.
Pending인 파드의 수를 세보니 10개로 확인됩니다.
t3.medium 노드 3대에는 각각 17개의 파드가 생성되어 있는 것을 알 수 있습니다. 이 수를 넘어서는 파드를 생성할 수 없기 때문에 현재 모드에서 노드당 지원하는 파드 수를 알아두어야 합니다.
이를 해결하기 위한 방법으로 IPv4 Prefix Delegation을 활용할 수 있습니다.
접두사 모드를 활용하면 ENI당 16개의 IPv4를 활용할 수 있습니다.
https://www.eksworkshop.com/docs/networking/vpc-cni/prefix/
Service, loadbalancer controller
k8s의 서비스는
ClusterIP
NodePort
LoadBalancer (NLB 인스턴스 유형)
LoadBalancer (NLB IP모드 동작 with AWS VPC CNI)
가 있습니다.
ClusterIP 는 파드의 요청을 Control Plane의 iptables의 rule를 통해 각 node의 pod로 전달해줍니다.
NodePort 는 각요청을 Data Plane의 노드 내에 있는 iptables의 rule을 통해 대상 pod로 전달해줍니다.
Loadblancer는 별개의 로드밸런서 리소스가 요청을 각 노드의 iptables로 전달, iptables rule에 의해 대상 pod 로 요청을 전달합니다.
이때 AWS VPC CNI 구성에서 NLB IP모드에서는 로드밸런서가 각각의 파드 ip를 알고 파드로 요청을 바로 전달하는 유형입니다.
Ingress
인그레스는 클러스터 내부의 서비스 (ClusterIP, NodePort, LoadBalancer)를 외부로 노출하는 proxy 역할을 제공해주는 리소스입니다.
ExternalDNS
서비스나 인그레스 생성시에 설정된 도메인 (AWS Route53과 같은)에 레코드를 자동으로 생성/삭제 해주는 리소스입니다.
이를 활용하기 위해서는 route53에 public domain을 소유하고 있어야 합니다. 또한 ExternalDNS 리소스가 직접 route53에 접근해야하므로, IRSA 혹은 pod-identity와 같은 자격증명을 필요로합니다.
'스터디' 카테고리의 다른 글
[KANS 3기] 8주차 Cilium CNI (2) | 2024.10.26 |
---|---|
[KANS 3기] 6주차 GatewayAPI (7) | 2024.10.12 |
[KANS 3기] 6주차 Ingress (4) | 2024.10.12 |
[KANS 3기] 5주차 MetalLB (6) | 2024.10.05 |
KCD 참석후기 - 쿠버네티스에서 스케줄링 작동 방식 (0) | 2024.09.28 |