kops로 AWS에 k8s 클러스터 생성하기

  • 최초작성일 [2020.03.10]

  • 1차 수정일 [2020.03.13]

    • VPC에 생성하는 내용 빼고 Route53 hosted zone 내용 보강

    • Route53에 상위도메인 등록 & NS 레코드 추가하는 내용 더함

    2차 수정일 [2020.03.14]

    • 마스터/워커 노드에 SSH 접속하는 내용 더함

kops는 쿠버네티스 클러스터의 인프라 리소스를 CLI를 통해 프로비저닝하는 오픈소스다. Go로 작성되었으며 공식적으로 AWS에 리소스를 생성하고 관리하는게 가능하다.

kops로 AWS에 쿠버네티스 클러스터를 생성해보자. 사전에 필요한 것은 아래와 같다.

1. 클러스터에 부여할 hosted zone 생성하기

클러스터를 생성하는 데 필요한 서브도메인을 Route53에서 만들어보자.

클러스터 외부에서 클러스터에 접근하거나, 클러스터 내부에서 각 노드를 식별하려면 도메인이 필요하므로k8s-cluster1.dev-daeun.com이라는 도메인을 생성하려고 한다.

Route53은 어떤 도메인과 도메인의 하위주소 집합을 hosted zone이라는 단위로 관리한다. (hosted zone의 개념은 여기에서 '도메인과 호스팅 영역의 차이점은 무엇입니까?' 참고)

아래의 커맨드는 k8s-cluster1.dev-daeun.com 이라는 이름의 hosted zone을 생성한다. (상위도메인 dev-daeun.com은 Route53 콘솔에서 직접 등록했다.)

--caller-reference옵션은 같은 --name의 값으로 들어오는 요청을 식별함으로써 동일한 도메인의 생성을 방지하는 용도다. hosted zone 생성에 실패하여 다시 요청할 때마다 --caller-reference의 값을 매번 다르게 줘야한다.

$ aws route53 create-hosted-zone \
--name k8s-cluster1.dev-daeun.com \
--caller-reference dev-daeun

커맨드를 실행하고 Route53 콘솔에 접속하면 아래와 같이 NSSOA 레코드가 생성된 것을 확인할 수 있다. NS(Name Server)는 k8s-cluster1.dev-daeun.com 주소와 관련된 질의의 응답을 담당하는 네임서버 주소를, SOA(Start Of Authority)는 k8s-cluster1.dev-daeun.com 관리영역의 시작점을 나타낸다.

2. 상위도메인의 record set에 NS record 추가하기

서브도메인 k8s-cluster1.dev-daeun.com을 만들고나면, 상위도메인 dev-daeun.com의 record set에 NS 레코드를 추가해야 한다. 추가하려는 레코드는 k8s-cluster1.dev-daeun.com의 네임서버 주소다.

dev-daeun.comk8s-cluster1이라는 서브도메인의 네임서버 주소를 가지고 있어야 그 네임서버에게 k8s-cluster1.dev-daeun.com에 대한 질의를 위임할 수 있기 때문이다. (자세한 내용은 여기 참고.)

TTL은 Time To Live의 약자로 dev-daeun.com의 네임서버에 질의한 노드가 받아온 응답을 캐싱하는 기간을 뜻한다.

3. 클러스터의 설정 정보를 저장할 S3 버킷 생성

kops는 쿠버네티스 클러스터의 설정 정보를 S3 버킷에 저장한다. 따라서 kops가 사용할 S3 버킷을 미리 생성해야 한다. cloudformation의 템플릿 s3.yml을 작성했다.

Resources:
  Resources:
  S3:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: k8s-cluster-state.dev-daeun.com
      VersioningConfiguration:
        Status: Enabled

VersioningConfigurationStatusEnabled로 지정하면 클러스터의 설정을 업데이트할 때마다 기존의 문서를 덮어쓰지 않고 업데이트된 버전의 문서를 새로 생성한다.

아래의 커맨드로 스택을 생성한다.

$ aws cloudformation create-stack \
--stack-name k8s-cluster \
--template-body file://s3.yml \
--capabilities CAPABILITY_NAMED_IAM

{
    "StackId": "arn:aws:cloudformation:ap-northeast-2:133143555446:stack/k8s-cluster1/c82a5260-62de-11ea-81be-067951d64fea"
}

4. kops로 k8s 클러스터 생성하기

kops는 클러스터에서 마스터와 노드로 쓰일 EC2 인스턴스들을 생성한다. 따라서 EC2 인스턴스 접속에 필요한 ssh키가 필요하다. k8s_rsa 라는 이름으로 ssh키를 만들자.

$ ssh-keygen -f /home/dev-daeun/.ssh/k8s_rsa

클러스터를 생성하기 전에 특정 AWS profile의 credential을 사용하고 싶다면 아래와 같이 환경변수를 정의한다.

$ export AWS_PROIFLE=<aws 프로필 이름>

아래 커맨드로 AWS에 쿠버네티스 클러스터를 생성한다.

$ kops create cluster \
k8s-cluster1.dev-daeun.com \
--zones ap-northeast-2a \
--networking calico \
--ssh-public-key ~/.ssh/k8s_rsa.pub \
--state s3://cluster-config.dev-daeun.com \

5. 클러스터 설정 변경하기

EC2 인스턴스의 타입을 바꾸거나, 워커 노드의 최소, 최대 갯수를 변경하는 등 클러스터의 기본 옵션을 변경해보자. 아래의 커맨드는 워커 노드와 관련된 옵션을 변경하고자 할 때 실행한다.

$ kops edit ig nodes --name k8s-cluster1.dev-daeun.com

위 커맨드를 실행하면 s3 버킷에서 관리되는 yaml 형식의 문서가 터미널에서 열린다. auto-scaling의 대상인 워커 노드의 최소, 최대 갯수를 변경해보자. minSize를 3으로, maxSize를 6으로 변경한다.

apiVersion: kops.k8s.io/v1alpha2  
kind: InstanceGroup
metadata:
  creationTimestamp: "2020-03-10T17:10:46Z"
  labels:
    kops.k8s.io/cluster: k8s-cluster1.dev-daeun.com
  name: nodes
spec:
  image: kope.io/k8s-1.16-debian-stretch-amd64-hvm-ebs-2020-01-17
  machineType: t2.medium
  maxSize: 6
  minSize: 3
  nodeLabels:
    kops.k8s.io/instancegroup: nodes
  role: Node
  subnets:
  - ap-northeast-2a

변경한 옵션을 클러스터에 반영하려면 아래의 커맨드를 실행한다.

$ kops update cluster --yes k8s-cluster1.dev-daeun.com

클러스터의 생성 과정을 체크하려면 아래의 커맨드를 실행한다. 생성이 완료되면 인스턴스 정보와 함께 마스터와 워커노드의 프라이빗 주소를 출력한다.

$ kubectl validate cluster --name k8s-cluster1.dev-daeun.com
Validating cluster k8s-cluster1.dev-daeun.com

INSTANCE GROUPS
NAME			ROLE	MACHINETYPE	MIN	MAX	SUBNETS
master-ap-northeast-2a	Master	c4.large	1	1	ap-northeast-2a
nodes			Node	t2.medium	3	3	ap-northeast-2a

NODE STATUS
NAME							ROLE	READY
ip-172-20-43-190.ap-northeast-2.compute.internal	master	True
ip-172-20-55-180.ap-northeast-2.compute.internal	node	True
ip-172-20-61-2.ap-northeast-2.compute.internal		node	True
ip-172-20-62-91.ap-northeast-2.compute.internal		node	True

kubectl 으로도 확인할 수 있다.

$ kubectl get nodes
NAME                                               STATUS   ROLES    AGE   VERSION
ip-172-20-43-190.ap-northeast-2.compute.internal   Ready    master   71m   v1.16.7
ip-172-20-55-180.ap-northeast-2.compute.internal   Ready    node     69m   v1.16.7
ip-172-20-61-2.ap-northeast-2.compute.internal     Ready    node     69m   v1.16.7
ip-172-20-62-91.ap-northeast-2.compute.internal    Ready    node     69m   v1.16.7

아래의 커맨드는 클러스터를 생성할 때 --ssh-public-key 옵션으로 넘겨줬던 공개키의 계정을 확인할 수 있다. 클러스터의 마스터나 워커 노드에 SSH로 접속하려면 admin 계정으로 접속해야 한다.

$ kops get secrets --type sshpublickey
Using cluster from kubectl context: k8s-cluster1.dev-daeun.com

TYPE		NAME	ID
SSHPublicKey	admin	5f:9f:87:6f:00:59:8f:1e:0a:87:ba:de:25:65:be:79
$ ssh -i ~/.ssh/k8s_rsa admin@<마스터/워커노드 주소>

공개키를 수정하려면 여기 참고.

참고 및 출처

Last updated