가시다님께서 진행하신 AEWS라는 스터디를 진행하면서 작성하는 글입니다.
AEWS= AWS EKS Workshop Study
AEWS 스터디는 4월 23일 ~ 6월 4일동안 총 7번 진행될 예정입니다.
PKOS 스터디에서 정말 좋은 경험을 했어서 다시 이렇게 참가하게 되었습니다.
가시다님께서 진행하시는 스터디에 관심있으신 분들은 Cloudnet@Blog에 들어가시면 자세한 정보를 확인하실 수 있습니다.
가시다님께서 만들어주신 Cloudformation을 이용한 EKS 원클릭 배포로 실습 환경을 쉽게 배포할 수 있습니다.
배포할 EKS 아키텍처는 아래와 같습니다.
배포를 완료한 후 잘 배포가 되었는지 노드 정보를 확인 해보겠습니다.
Cloud Native Computing Foundation 프로젝트인 CNI( Container Network Interface ) 는 지원되는 여러 플러그인과 함께 Linux 컨테이너에서 네트워크 인터페이스를 구성하기 위한 플러그인을 작성하기 위한 사양 및 라이브러리로 구성된다고 합니다.
(출처: cni 공식 레파지토리)
AWS에서 만든 k8s의 pod 네트워킹을 위한 네트워킹 플러그인입니다.
VPC의 IP주소를 각 pod에 할당
pod의 IP 네트워크 대역과 워커노드의 IP 대역이 같아서 직접 통신이 가능
VPC ENI 에 미리 할당된 IP를 pod에서 사용할 수 있음
더 자세한 내용은 여기에서 보실 수 있습니다.
네트워크 통신의 최적화(성능, 지연)를 위해서 노드와 파드의 네트워크 대역을 동일하게 설정함
파드 간 통신 시
Secondary IPv4 addresses
인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
IPv4 Prefix Delegation
IPv4 28bit 서브넷(prefix)를 위임하여 할당 가능 IP 수와 인스턴스 유형에 권장하는 최대 갯수로 선정
CNI 정보 확인
kube-proxy config 확인
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /var/lib/kube-proxy/kubeconfig
qps: 5
clusterCIDR: ""
configSyncPeriod: 15m0s
conntrack:
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0:10249
mode: "iptables"
nodePortAddresses: null
oomScoreAdj: -998
portRange: ""
udpIdleTimeout: 250ms
노드 IP 확인
pod ip 확인
AWS VPC CNI 경우 별도의 오버레이(Overlay) 통신 기술 없이, VPC Native 하게 파드간 직접 통신이 가능하다는 것을 K8S Calico CNI 와 AWS VPC CNI 차이에서 알아봤습니다.
파드 통신을 진행할 때 직접 통신이 되는지 테스트 해보겠습니다.
우선 테스트용 파드를 생성하고 변수를 지정했습니다.
# 테스트 파드 생
cat <<EOF | kubectl create -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
# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})
PODNAME3=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[2].metadata.name})
# 파드 IP 변수 지정
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})
그리고 핑 테스트를 진행했습니다.
Pod는 생성될 때 마다 IP가 변경되는 특성을 가지고 있어서 클러스터 내/외부와 통신을 유지하는 것은 어렵습니다.
그래서 k8s는 pod와 통신을 할 수 있는 고정IP를 가진 Service를 지원합니다.
서비스 종류
Cluster IP
NodePort
LoadBalancer
externalTrafficPolicy
로 클라이언트 IP를 보존LoadBalancer Controller - AWS Load Balancer Controller + NLB IP 모드 동작 with AWS VPC CNI
**# IAM Policy (AWSLoadBalancerControllerIAMPolicy) 생성**
curl -o **iam_policy.json** https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
aws iam create-policy --policy-name **AWSLoadBalancerControllerIAMPolicy** --policy-document file://**iam_policy.json**
eksctl create **iamserviceaccount** --cluster=$CLUSTER_NAME --namespace=kube-system --name=**aws-load-balancer-controller** \
--attach-policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/**AWSLoadBalancerControllerIAMPolicy** --override-existing-serviceaccounts --**approve**
helm repo add eks https://aws.github.io/eks-charts
helm repo update
**helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller**
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/echo-service-nlb.yaml
**kubectl apply -f echo-service-nlb.yaml**
클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalancer)를 외부로 노출(HTTP/HTTPS) - Web Proxy 역할
ingress도 배포해보겠습니다.
AWS LoadBalancer Controller 배포가 된 상태에서 진행했습니다.
게임 파드와 Service, Ingress 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ingress1.yaml
kubectl apply -f ingress1.yaml
ingress를 확인합니다.
ingress DNS name을 확인 한 후 접속을 진행해보겠습니다.
kubectl scale deployment -n game-2048 deployment-2048 --replicas 3
kubectl scale deployment -n game-2048 deployment-2048 --replicas 1