요즘 EKS 공부를 하고 있는데 eks 세팅 작업을 자꾸만 까먹게 되고, 세팅하면서 발견한 어려움들을 기록하고자 블로그로 남기게 되었습니다.

사실 EKS 의 작업은 EKS Workshop 에서 쉽게 확인 가능합니다. 다만 이번 블로그에서는 eksctl 을 사용하지 않고 cloudformation 을 사용하고자 합니다.

IAM 구성하기

보통 AWS 를 사용할 때 IAM user 를 따로 생성해서 만들게 됩니다. 현재는 간단한 튜토리얼 이므로 admin 권한을 user 에게 주도록 하겠습니다.

아래처럼 admin 권한을 가진 그룹을 생성합니다.

iam_group

그 후 IAM user 를 생성합니다.

여기서 저희는 (1) 프로그래밍 방식, console 접근 모두 할 것이므로 체크를 해주시고

iam_user_01

(2) 방금 전 만든 그룹이 이 유저를 추가하고

iam_user_02

(3) 태그를 설정하고(알아볼 수 있는 태그를 달도록 합시다. 태그는 앞으로 계속 나올텐데 이후로는 생략할 것입니다.)

iam_user_03

(4) 마지막으로 csv 파일을 다운받아야 합니다. 이 키 파일들은 나중에 다시 접근이 불가능 하니 반드시 백업을 해놓는 습관을 들이도록 해야 합니다.

iam_user_04

user 생성이 완료 되었다면 EKS 를 위한 IAM role (IAM 역할) 을 만들어 주어야 합니다. 아래와 같이 EKS 권한을 선택해 주시고

iam_role_01

이 역할의 이름을 지정해서 생성합니다.

iam_role_02

이제 IAM 구성을 완료했다면 만든 user 로 aws 에 접속 해주도록 합니다. 이 로그인에 대한 정보는 이전에 다운받은 csv 파일에 저장되어 있습니다. 로그인 링크부터 전부 있으니 확인 바랍니다 ^^

iam_login

위처럼 로그인이 되었다면 자신의 user name 으로 설정이 되어 있을 것입니다.

이 때, 여기서 로그인한 유저로 eks cluster 를 만들면 이 유저를 제외한 다른 유저는 kubernetes control plane 에 접속이 불가능해 집니다. (이 유저에서 접근을 허용하도록 설정해야 합니다) 그러니 어떤 유저로 eks cluster 를 생성했는지 반드시 확인하시기 바랍니다.

쿠버네티스 노드에 사용할 EC2 Key pair 만들기

간단한 작업입니다. 쿠버네티스에서 node 로 EC2 를 생성하게 될 텐데 이 노드에 접속하기 위한 key pair 를 만드는 작업입니다.

  1. EC2 서비스에 접속합니다.
  2. 네트워크 보안 탭의 Key-pair 에 접속합니다.
  3. 키페어를 생성합니다.
  4. 그러면 키를 다운받으라고 하는데 이도 다음에 다시 확인이 불가능하므로 반드시 백업을 하도록 합니다.

key_pair

이 키를 사용해서 나중에 ssh 로 접근할수도 있고 하므로 잊어버리지 않도록 조심합시다.

VPC 구성하기

EKS (kubernetes) 를 위한 private VPC 를 구성해야 합니다. 이 때 cloudformation 을 사용할 예정인데 AWS docs 에 가보시면 cloudformation 파일이 s3 에 있는 것을 보실 수 있습니다. 저희는 이를 이용해서 간단하게 구성할 예정이고, 추후에 시간이 된다면 cloudformation 에 대해서도 포스팅 하기로 하겠습니다.

이전에는 northeast-2 (서울리전) 이 안되었지만 업데이트 된 것으로 보입니다. 현재 제가 포스팅을 작성하고 있을 때의 vpc cloudformation url 은 다음과 같습니다.

https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-09-27/amazon-eks-vpc-sample.yaml

이 cloudformation 을 이용하면 아래 그림과 같은 아키텍처를 만들 수 있게 됩니다. (현재 서울리전의 az 는 3개 인데 아직 2개로 처리하고 있습니다. 따라서 아키텍처의 az 는 추후에 더 추가될 수도 있을 것 같습니다.)

vpc_06

그럼 private vpc 를 구성해보도록 하겠습니다. aws cli 를 사용하지 않고 console 로 진행하겠습니다.

먼저 aws cloudformation 에 접속해줍니다.

스택을 생성합니다.

vpc_01

여기서 앞에서 설명한 s3 url 로부터 clodformation template 을 가져옵니다.

vpc_02

그 후 스택 이름을 설정합니다.

vpc_03

그리고 스택을 만들어주시면 아래와 같이 스택이 만들어지고 있음을 알 수 있습니다.

vpc_04

VPC 서비스에 들어가서 아래처럼 vpc, 서브넷, 보안그룹, 인터넷 게이트웨이 가 잘 생성되었는지 확인해 봅시다.

vpc_05

이렇게 하면 eks 세팅을 위한 vpc 설정이 완료되었습니다.

EKS Control Plane(Master Node, EKS 클러스터) 구성하기

EKS 란 무엇일까요? 바로 이전에 VPC 에서 구성한 것을 바탕으로 AWS 에서 쿠버네티스를 생성해서 관리해주는 기능이라고 보시면 될 것 같습니다. 즉, 저희가 따로 쿠버네티스를 설치할 필요 없이 AWS 에서 생성해줘서 이 챕터를 마치면 아래 그림과 같은 아키텍처를 가지게 될 것입니다.

control_plane_05

이제 eks cluster 를 만들겠습니다. aws console 에서 eks 클러스터를 생성합니다. 클러스터 생성시 여러 메뉴가 나오는데 이전에 구성했던 대로 선택하도록 합니다.

먼저 IAM Role 을 이전에 만들었었던 걸 선택해 줍니다.

control_plane_01

그 뒤 VPC 를 선택하고 subnet 도 잘 선택되어 있는지 확인합니다.

control_plane_02

마지막으로 보안그룹도 선택해주고 태그를 만들고 클러스터를 생성합니다.

control_plane_03

그러면 아래와 같이 cluster 를 생성하는 것을 확인 할 수 있습니다.

control_plane_04

이제 eks cluster 가 완료될때 까지 기다린 후 다음 장으로 넘어가도록 하겠습니다.

kubectl 구성하기

쿠버네티스를 구성을 마쳤으니 쿠버네티스 API 를 활용할 수 있도록 kubectl 을 설치하도록 하겠습니다. EKS 와 kubectl 은 다음과 같은 구조로 이루어지게 될 것입니다.

kubectl_01

즉, 외부에서 kubectl 을 만들어서 eks 에 요청하는 식이 될 것입니다. 여기서 저는 그림에서 보듯이 EC2 인스턴스를 별도로 생성하겠습니다. EC2 생성하는 것은 다들 아실 것으로 생각하고 넘어가도록 하겠습니다. EC2를 생성하신 후 접속해 주시기 바랍니다.

먼저 kubectl 을 다운받도록 하겠습니다. aws docs 를 보시면 운영체제마다 다운받는 방법이 적혀 있습니다. 저는 ubuntu 를 사용하고 kubernetes 1.4 버전을 사용하고 있으니 아래의 명령어로 kubectl 을 설치하도록 하겠습니다.

# 쿠버네티스를 스토리지에서 가져옴
$ curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/kubectl

# 퍼미션 적용
$ chmod +x ./kubectl

# kubectl 바이너리 파일을 적절한 디렉토리에 옮기고 path 지정.
$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH

# bash profile 에 적용
$ echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc

설치가 완료되었다면 kubectl 이 적절하게 설치되어 있는지 확인해 봅니다. 이번 포스팅의 경우 아래 명령어를 입력했을 시 Client Version: v1.14.7-eks-1861c5 와 같은 결과가 나오면 성공입니다.

$ kubectl version --short --client

하지만 kubectl 을 설치했다고 끝이 아니라 이것이 저희가 만든 eks cluster 와 소통할 수 있도록 세팅해주어야 합니다.

저는 aws cli 를 이용해서 iam 을 세팅할 것이므로 aws cli 를 설치하도록 하겠습니다. 이도 문서에 자세히 나와 있습니다. 참고로 pip3 가 설치되어 있어야 합니다.

# cli 설치
$ pip3 install awscli --upgrade --user

# version 확인
$ aws --version

설치가 되셨다면 먼저 kubernetes 에 사용할 키를 등록하도록 합시다. 여기서 나오는 목록은 아래와 같이 적어주시면 됩니다. (저는 서울 리전이므로 ap-northeast-2 를 사용합니다.)

$ aws configure
  • AWS Access Key ID: 위에서 IAM 생성 시 만든 access key
  • AWS Secret Access Key: 위에서 IAM 생성 시 만든 secret key
  • Default region name: ap-northeast-2
  • Default output format: json

AWS 에서 사용할 IAM 세팅이 완료되었습니다. 하지만 EKS 는 aws-iam-authenticator 를 이용하여 세팅한 IAM 을 사용하여 kubernetes cluster 에 인증하게 됩니다. 따라서 이를 설치하고 확인해보도록 하겠습니다. (물론 이도 aws 문서 에 나와있습니다.)

# aws-iam-authenticator 설치
$ curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/aws-iam-authenticator

# 권한 설정
$ chmod +x ./aws-iam-authenticator

# Path 설정
$ mkdir -p $HOME/bin && cp ./aws-iam-authenticator $HOME/bin/aws-iam-authenticator && export PATH=$HOME/bin:$PATH

# 환경 변수에 추가
$ echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc

인증된 사용자를 이용하여 token 을 가져올 수 있는지 확인해 봅시다. 아래에서 저는 클러스터 이름을 cory-eks-cluster 로 만들었었습니다.

$ aws-iam-authenticator token -i {클러스터 이름} | python3 -m json.tool

토큰이 잘 가져와지나요?? 그럼 잘 작동한다는 것을 알 수 있습니다.

하지만!! 아직 끝이 아닙니다. kubectl 를 사용하려면 config 를 설정해 주어야 합니다. 이는 aws 문서 를 보시면 아주 쉽게 아래 명령어로 생성할 수 있으며 개인적으로는 이를 추천하지만 어떤 파일들이 설정되는 건지 설명드리기 위해 저는 수동으로 설정하도록 하겠습니다.

아래는 자동으로 설정해주는 명령어입니다.

$ aws eks --region {리전} update-kubeconfig --name {클러스터 이름}

그럼 이제 수동으로 만들어 보겠습니다. 먼저 config 파일을 만들겠습니다.

# kube 디렉토리 생성 및 config 파일 설정
$ mkdir -p ~/.kube && vi ~/.kube/kubeconfig

config 내용은 아래와 같이 적습니다.

apiVersion: v1
clusters:
- cluster:
    server: <endpoint-url>
    certificate-authority-data: <base64-encoded-ca-cert>
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: aws
  name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: aws-iam-authenticator
      args:
        - "token"
        - "-i"
        - <cluster-name>

여기서 <…> 속에 속한 내용은 아래 그림과 같습니다. 각각 그대로 바꿔서 넣어주시기 바랍니다. 참고로 아래는 aws console 의 eks 서비스에 접속한 화면입니다.

kubectl_02

그 뒤 환경변수를 설정해줍니다.

$ export KUBECONFIG=$KUBECONFIG:~/.kube/kubeconfig

$ echo 'export KUBECONFIG=$KUBECONFIG:~/.kube/kubeconfig' >> ~/.bashrc

잘 설치되어 있는지 확인해 봅시다.

$ kubectl get svc

명령어 입력시 아래와 같이 kubernetes 에 관한 것이 나와야 설정이 잘 완료 된 것입니다.

kubectl_03

그런데 이 때 아래와 같은 에러가 발생하시는 분들도 있을 것입니다.

error: the server doesn't have a resource type "svc"

이는 간단히 말하자면 쿠버네티스와 연결이 안되었다는 소리입니다. eks 를 세팅하다보면 이 에러를 정말 많이 보실지도 모릅니다. 따라서 아래에 해결 방법 여러가지를 적어놨으니 중 자신이 실수한 부분이 무엇인지 확인 바랍니다. (혹시 그 외의 경우라면 aws eks troubleshooting 을 참고 바랍니다.)

  1. kubeconfig 파일이 잘 설정되어 있는지 확인합니다.
  2. 위에서 클러스터 이름을 kubernets 로 했는데 이미 하나가 존재하는 경우
    • cluster name을 자신의 클러스터 이름으로 설정하도록 합니다.
  3. arn 설정에서 충돌난 경우
    • 이도 config 파일에서 arn 을 변경하시기 바랍니다.
  4. cluster 생성시 로그인한 user 와 kubectl 에서 설정한(iam configure 명령어로 설정한) user 가 다른 경우
    • iam configure 를 다시 실행하여 cluster 를 만든 유저로 접속하시기 바랍니다.
    • 혹은 cluster 를 만든 유저로 접속을 먼저 하고 다른 유저를 추가시켜 주어야 합니다. (이 작업은 이후 작업인 kubernetes 노드 생성 이후에 작동시킬 수 있습니다.)

네 이제 kubectl 까지 완료 했습니다. 눈치채신 분들도 있지만 이전에 설정한 config 파일을 보면 kubernetes template 과 동일하다는 것을 아실 수 있을 것입니다. 그럼 이제 쿠버네티스 노드를 생성하겠습니다.

kubernetes 노드 생성하기

쿠버네티스 노드도 간단하게 cloudformation 을 이용하겠습니다. 이 템플릿을 사용할 경우 아래와 같은 아키텍처를 가질 수 있을 것입니다.

nodegroup_06

현재 포스팅할 시점의 template 은 아래와 같습니다. 이는 계속 변할 수 있으므로 참고해주세요~

https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-09-27/amazon-eks-nodegroup.yaml

그럼 이를 이용해서 cloudformation 을 생성하도록 하겠습니다.

여기서 파라미터는 보시는 그대로 동일합니다.

  • ClusterName: 클러스터 이름
  • ClusterControlPlaneSecurityGroup: 앞에서 생성한 control plane 의 VPC 를 선택해 줍니다.
  • NodeGroupName: 이름을 지정해줍니다.
  • NodeAutoScalingGroupMinSize: 최소 노드 갯수 지정 (최대, dsired 는 생략하겠습니다.)
  • NodeInstanceType: 생성할 EC2 인스턴스를 지정합니다.
  • NodeImageIdSSMParam: 1.14 인 경우 그대로 두시면 됩니다. 참고로 이 이미지의 목록은 이미지 목록에 있습니다.
  • NodeImageId: aws 의 image 가 아니라 다른 것을 쓰실 경우 지정합니다.

나머지도 각각 아래 그림을 보면서 지정해 주시기 바랍니다.

nodegroup_01

그 후 EC2 가 잘 생성되었는지 확인해 보겠습니다.

nodegroup_02

그리고 kubernetes 의 node 인지 확인해 봅니다.

$ kubectl get nodes

아마도 resources 가 없다고 나올 것입니다. 그 이유는 node 에 접속해서 확인하시면 되는데 (따라하실 필요 없습니다.) 각각의 node 는 아래와 같은 오류를 내뿜고 있을 것입니다. (참고로 EC2 에 접속한 로그인데 ec2-user@public-ip 로 접근 가능합니다. 유저이름을 주의해주세요)

nodegroup_03

즉, 노드에 대한 인증이 되어 있지 않기 때문입니다. 따라서 이를 설정해 주어야 합니다. 이 또한 문서에서 확인 가능합니다.

먼저 aws-auth 템플릿을 가져오겠습니다. (파일명은 aws-auth-cm.yaml 로 가져와질 것입니다.)

$ curl -o aws-auth-cm.yaml https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-10-08/aws-auth-cm.yaml

이 템플릿에서 mapRoles.rolearn 을 수정해야 합니다. 이를 아래 사진에 있는 부분으로 교체해 줍니다.

nodegroup_04

이렇게 만들어진 kubernetes tempalte (configmap api) 을 적용해봅시다.

# configmap 적용
$ kubectl apply -f aws-auth-cm.yaml

# 확인
$ kubectl describe configmap -n kube-system aws-auth

잘 적용되셨나요?? 이렇게 이 configmap 을 적용시켜주고 나면 위에 나왔던 에러가 더이상 발생하지 않음을 알 수 있습니다.

다시 node 가 잘 나오는지 확인해 봅시다.

$ kubectl get nodes

아래와 같이 세 개의 노드가 검색되고, status 가 ready 가 되었다면 eks 세팅이 완료 된 것입니다. (만약 not-ready 에 머물고 있다면 ami 세팅이 잘 되었는지 확인 바랍니다.)

nodegroup_05

마무리

드디어 eks 세팅이 완료되었습니다. eks 를 사용하면 간단히 eks 세팅을 완료할 줄 알았는데 생각보다 알아야 할 것들이 많더군요. 아마도 다음 aws 포스팅에서는 eks를 이용했을 때 shared volume(efs) 를 어떻게 사용할 수 있는지 알아볼 생각입니다.