본문 바로가기

Server Infra/Kubernetes

PKOS 2기 1주차 - kops

728x90

KOPS 설치

https://kubernetes.io/ko/docs/setup/production-environment/tools/kops/

kops(Kubernetes Operation)는 쿠버네티스 생성 및 관리를 쉽게 하도록 도와주는 오픈소스 툴 입니다. 클러스터를 손쉽게 CLI 명령어를 통해 생성, 관리, 업그레이드 및 삭제를 할 수 있도록 지원합니다.

  • 완전 자동화된 설치
  • DNS를 통해 클러스터들의 신원 확인
  • 자체 복구: 모든 자원이 Auto-Scaling Groups에서 실행
  • 다양한 OS 지원(Debian, Ubuntu 16.04 supported, CentOS & RHEL, Amazon Linux and CoreOS) - images.md 보기
  • 고가용성 지원 - high_availability.md 보기
  • 직접 프로비저닝 하거나 또는 할 수 있도록 terraform 매니페스트를 생성 - terraform.md 보기

설치 과정

설치하면 환경

  1. 사전에 설치를 하기 위한 Cloud9이 필요합니다.
  2. Cloud9에 필요한 권한이 부여되어야 합니다.
  3. Domain이 필요합니다. → 일단 구글 도메인 구매후 Route53에 등록했습니다.(기존거는 까먹고 사용을 안해서 갱신주기를 놓쳐버렸습니다..)
## 아래 명령어를 통해 설치합니다
kops create cluster --zones="$REGION"a,"$REGION"c \
--networking amazonvpc \
--cloud aws \
--master-size t3.medium \
--master-volume-size 40 \
--node-size t3.medium \
--node-volume-size 40 \
--node-count=2 \
--network-cidr 172.30.0.0/16 \
--ssh-public-key ~/.ssh/id_rsa.pub \
--name=$KOPS_CLUSTER_NAME \
--kubernetes-version "1.24.10" -y

생성 과정에서 아래와 같은 A Record가 추가로 생성됩니다.

실제로 설치하면 아래와 같이 S3에 폴더가 생성됩니다.

이게 kops를 이용해서 설치할때 사용되는 배포 파일들입니다. 각각 파일을 오픈해보면 etcd 백업부터 해서 다양한 컴포넌트들이 각각 설치 파일로 생성되어 있습니다.

addons폴더만 열어보면 위와 같은 addons이 설치되어 있는것을 볼 수 있습니다.

물론 옵션에 따라서 addons은 여러가지가 있습니다.

  • awsLoadBalancerController
  • clusterAutoscaler
  • certManager
  • karpenter
  • metricsServer

등등등…

자세한 내용은

kops/upup/pkg/fi/cloudup/awstasks at master · kubernetes/kops

위 깃헙의 pkg를 까보면 알 수 있습니다. 각각 aws-go-sdk를 패키징 하여 구현했으며 명령어에 따라 적용되는 cloud 부터 노드의 타입등 다양하게 결정 할 수 있습니다.

설치가 완료되면 아래와 같이 설치된 클러스터를 확인 할 수 있습니다

[root@kops-ec2 ~]# kops get cluster
NAME			           CLOUD	 ZONES
mate-technology.app	 aws	   ap-northeast-2a,ap-northeast-2c

[root@kops-ec2 ~]# kops get ig
NAME			              ROLE	  MACHINETYPE	MIN	MAX	ZONES
master-ap-northeast-2a	Master	t3.medium	  1	  1 	ap-northeast-2a
nodes-ap-northeast-2a	  Node	  t3.medium	  1	  1 	ap-northeast-2a
nodes-ap-northeast-2c	  Node	  t3.medium	  1	  1	  ap-northeast-2c

여기서 EKS와 동일하게 t3.medium이라는 Machinetype에 주의해야 합니다. EC2와 VPC-CNI의 조합은 IP의 제약을 받기 때문이고 신기하게 kops로 설치한 경우에도 같은 제약을 받습니다.

[root@kops-ec2 ~]# aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \\
>  --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \\
>  --output table
--------------------------------------
|        DescribeInstanceTypes       |
+----------+----------+--------------+
| IPv4addr | MaxENI   |    Type      |
+----------+----------+--------------+
|  15      |  4       |  t3.xlarge   |
|  15      |  4       |  t3.2xlarge  |
|  12      |  3       |  t3.large    |
|  2       |  2       |  t3.nano     |
|  6       |  3       |  t3.medium   |
|  2       |  2       |  t3.micro    |
|  4       |  3       |  t3.small    |
+----------+----------+--------------+

위처럼 t3.medium은 ((MaxENI * (IPv4addr-1)) + 2)이므로 총 17개의 IP를 사용할 수 있습니다. 다만 Kube-proxy와 aws-node를 사용중이기에 2개를 제외한 15개의 파드만 실행이 가능합니다.

# 디플로이먼트 생성
kubectl apply -f https://raw.githubusercontent.com/gasida/PKOS/main/2/nginx-dp.yaml

# 파드 증가 테스트
**kubectl scale deployment nginx-deployment --replicas=30

# 파드 생성 실패!
kubectl get pods | grep Pending
nginx-deployment-6fb79bc456-52sqs   0/1     Pending   0          77s
nginx-deployment-6fb79bc456-bhrcn   0/1     Pending   0          77s
nginx-deployment-6fb79bc456-npm4j   0/1     Pending   0          77s
nginx-deployment-6fb79bc456-whxmc   0/1     Pending   0          77s
nginx-deployment-6fb79bc456-xtfxl   0/1     Pending   0          77s

[root@kops-ec2 ~]# kubectl describe pod nginx-deployment-6fb79bc456-xtfxl | grep Events: -A5
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  104s (x2 over 106s)  default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 2 Too many pods. preemption: 0/3 nodes are available: 1 Preemption is not helpful for scheduling, 2 No preemption victims found for incoming pod.**

위처럼 허용치 이상의 파드가 생성되었다고 하면서 파드가 생성되지 않습니다. 이건 vpc-cni의 custom 세팅으로 조절이 가능합니다.

[root@kops-ec2 ~]# kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
daemonset.apps/aws-node env updated
[root@kops-ec2 ~]# kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
daemonset.apps/aws-node env updated
[root@kops-ec2 ~]# kubectl describe daemonsets.apps -n kube-system aws-node | egrep 'ENABLE_PREFIX_DELEGATION|WARM_PREFIX_TARGET'
      ENABLE_PREFIX_DELEGATION:               true
      WARM_PREFIX_TARGET:                     1

다음으로 kops 명령어를 사용해서 max-pods 값을 조절해 줍니다. VPC cni 설정이 변하면 초기 eni 세팅이 변하기 때문에 인스턴스가 전부 다시 생성됩니다.

kops edit cluster
...
  kubelet:
    anonymousAuth: false
    maxPods: 110
...
  networking:
    amazonvpc:
      env:
      - name: ENABLE_PREFIX_DELEGATION
        value: "true"
...

kops update cluster --yes && echo && sleep 5 && kops rolling-update cluster --yes

전부 완료된뒤 아래와 같이 명령어를 실행하여 다시 max pod의 수를 확인합니다.

root@kops-ec2 ~]# kubectl describe node | grep Allocatable: -A6
Allocatable:
  cpu:                2
  ephemeral-storage:  37286723113
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854316Ki
  pods:               17
--
Allocatable:
  cpu:                2
  ephemeral-storage:  37286723113
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854316Ki
  pods:               110
--
Allocatable:
  cpu:                2
  ephemeral-storage:  37286723113
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854324Ki
  pods:               110
--
Allocatable:
  cpu:                2
  ephemeral-storage:  37286723113
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854316Ki
  pods:               110

자 그러면 다시 pods를 100개 이상 배포해 보겠습니다.

[root@kops-ec2 ~]# kubectl scale deployment nginx-deployment --replicas=110

[root@kops-ec2 ~]# kubectl get replicasets
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-6fb79bc456   110       110       104     22m

잘 되네요 ^^

 

사실 중간에 100개이상 pod를 scale한 상황에서 설정을 변경하여 다시 적용하였을때 aws-node pods가 갯수 제한으로 생성되지 않고 control plane의 pods들이 고장나서 완전 지우고 다시 설정 했습니다. ㅠㅠ

Amazon VPC CNI의 더 다양한 정보는 여기에 있습니다.

https://aws.github.io/aws-eks-best-practices/networking/vpc-cni/

 

Amazon VPC CNI - EKS Best Practices Guides

Amazon VPC CNI Amazon EKS implements cluster networking through the Amazon VPC Container Network Interface(VPC CNI) plugin. The CNI plugin allows Kubernetes Pods to have the same IP address as they do on the VPC network. More specifically, all containers i

aws.github.io

BP와 Parameter튜닝 포인트를 아렬주는데 위에 설정한것처럼 Prefix mode를 enable시켜주는것과

WARM_ENI_TARGET, WARM_IP_TARGET, MINIMUM_IP_TARGET Parameter를 적절하게 조합하여 보다 빠르게 Pods를 프로비저닝 할수 있는 값을 제공해 줍니다.

VPC CNI 동작 Flow

WARM_ENI_TARGET -유지 관리할 Warm ENI의 수입니다. ENI는 노드에 보조 ENI로 연결될 때 "Warm" 상태이지만 Pod에서 사용하지 않습니다. 보다 구체적으로 ENI의 IP 주소가 포드와 연결되지 않았습니다.

WARM_IP_TARGET - 유지 관리할 Warm IP 주소의 수입니다. Warm IP는 능동적으로 연결된 ENI에서 사용할 수 있지만 Pod에 할당되지 않았습니다. 즉, 사용 가능한 Warm IP의 수는 추가 ENI 없이 Pod에 할당할 수 있는 IP의 수입니다.
MINUM_IP_TARGET - 언제든지 할당할 최소 IP 주소 수입니다. 이는 일반적으로 인스턴스 시작 시 여러 ENI 할당을 프런트로드하는 데 사용됩니다.

위의 설정을 적절히 혼합하여 사용하자!(뒤에 추가 ENI를 생성하여 Assign 하는 프로세스를 단축시킬 수 있다)

728x90