kubernetes + Kops + ExternalDNS 정리 – 1

kubernetes + Kops + ExternalDNS 정리


AWS 서비스에서 kops를 활용해서 kubernetes cluster를 구성해보고,
AWS의 DNS 서비스인 Route53에 ExternalDNS라는 Plugin을 통해 연동해보겠습니다.

이 글은 kubernetes study를 하며 알게된 부분을 정리하는데 목적이 있습니다.

Prerequisite

  • kops 1.9.0
  • kubectl client v1.10.1, server v1.9.3
  • externalDNS **v0.5.0
  • aws-cli/1.11.69 Python/2.7.10 Darwin/17.5.0 botocore/1.5.32
  • jq v1.5

install

아래 링크대로 따라서 설치
Following this ref

Get started


이제 쿠베 설정을 해보겠습니다.

kops IAM settings


kops/aws.md at master · kubernetes/kops · GitHub
위의 링크를 참고해서 IAM 에서 해당 권한을 가진 user 생성

The kops user will require the following IAM permissions to function properly:

AmazonEC2FullAccess
AmazonRoute53FullAccess
AmazonS3FullAccess
IAMFullAccess
AmazonVPCFullAccess

User created save on local machine

로컬 aws-cli 에서 사용할 access key 와 secret key 저장

vi ~/.aws/credentials

~/.aws/credentials

[DevelopRole]
aws_access_key_id = AKIAAAAAA4FEOBBB65BA
aws_secret_access_key = aNVAAAAAACavjag5HvO7BBBbbebG/ewDefWdFicq

Domain settings


먼저 도매인이 없다면 구매를 해야합니다.
buy your own domain
구매후 약간의 시간이 필요합니다.

도매인(example.com)이 있다고 가정하고 진행합니다.
kops/aws.md at master · kubernetes/kops · GitHub

parent domain ID 확인

aws --profile DevelopRole route53 list-hosted-zones | jq '.HostedZones[] | select(.Name=="example.com.") | .Id'

Output

"/hostedzone/ZKASHKH31HAHA"

create subdomain

ID=$(uuidgen) && aws --profile DevelopRole route53 create-hosted-zone --name k8s.example.com --caller-reference $ID | \
    jq .DelegationSet.NameServers

Output

[
  "ns-1234.awsdns-17.org",
  "ns-400.awsdns-60.com",
  "ns-800.awsdns-38.net",
  "ns-1800.awsdns-46.co.uk"
]

위의 output 내용을 아래처럼 subdomain.json 파일에 저장합니다.

subdomain.json

{
  "Comment": "Create a subdomain NS record in the parent domain",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "k8s.example.com",
        "Type": "NS",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "ns-1234.awsdns-17.org"
          },
          {
            "Value": "ns-400.awsdns-60.com"
          },
          {
            "Value": "ns-800.awsdns-38.net"
          },
          {
            "Value": "ns-1800.awsdns-46.co.uk"
          }
        ]
      }
    }
  ]
}

Parent domain 에 subdomain 정보를 저장합니다.

aws --profile DevelopRole route53 change-resource-record-sets \
 --hosted-zone-id "/hostedzone/ZKASHKH31HAHA" \
 --change-batch file://subdomain.json

Output

{
    "ChangeInfo": {
        "Status": "PENDING",
        "Comment": "Create a subdomain. NS record in the parent domain",
        "SubmittedAt": "2018-05-09T08:12:45.256Z",
        "Id": "/change/C3GYMM3KUW8HAC"
    }
}

Testing your DNS setup

dig ns k8s.example.com

Output

; <<>> DiG 9.10.6 <<>> ns k8s.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 643
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;k8s.example.com.           IN  NS

;; ANSWER SECTION:
k8s.example.com.        300 IN  NS  ns-480.awsdns-60.com.
k8s.example.com.        300 IN  NS  ns-820.awsdns-38.net.
k8s.example.com.        300 IN  NS  ns-1909.awsdns-46.co.uk.
k8s.example.com.        300 IN  NS  ns-1162.awsdns-17.org.

;; Query time: 880 msec
;; SERVER: 10.3.21.236#53(10.3.21.236)
;; WHEN: Wed May 09 17:14:59 KST 2018
;; MSG SIZE  rcvd: 182

kops S3 settings


kops에서는 S3를 사용합니다.
S3에 저장된 데이터를 이용해서 다중 사용자가 같은 kubernetes cluster를 컨트롤할 수 있게 합니다.

Create s3 bucket for saving cluster state

clusters.k8s.example.com S3 bucket 을 생성합니다.

aws --profile DevelopRole s3 mb s3://clusters.k8s.example.com

kops/aws.md at master · kubernetes/kops · GitHub

아래 이유를 들어 kops팀에서는 versionning 설정을 추천하고 있습니다.
설정 해줍시다.

Note: We STRONGLY recommend versioning your S3 bucket in case you ever need to revert or recover a previous state store.

Versioning

aws --profile DevelopRole s3api put-bucket-versioning --bucket clusters.k8s.example.com --versioning-configuration. Status=Enabled

앞으로 있을 kops 사용을 위해 아래 3가지를 environment variables 에 등록 해 줍니다.

export KOPS_STATE_STORE=s3://clusters.k8s.example.com
export AWS_PROFILE=DevelopRole
export NAME=useast1.k8s.example.com

kubernetes cluster settings by kops


이제 드디어 쿠베 클러스터에 대한 설정을 시작합니다.
위의 내용은 쿠베 클러스터 설정을 kops로 하기위한 준비과정으로 보시면 됩니다.

Create cluster configuration.

어떤 az 를 사용할 지 ,를 사용해서 선택합니다.

kops create cluster --zones="us-east-1a,us-east-1c" useast1.k8s.example.com
kops create cluster \
 --cloud=aws \
 --zones="us-east-1a" \
 --name $NAME \
 --vpc vpc-d71411b2 \
 --ssh-public-key="~/.ssh/id_rsa.pub"

Note: 아직 cluster 가 생성된 것은 아닙니다. 실제 적용을 위해서는 kops update cluster —yes 명령이 추가로 필요합니다.

Master / node check

cluster 는 마스터 노드와 마스터노드가 관리하는 여러 노드들로 구성 됩니다.
현재 구성을 아래 명령을 통해 확인 합니다.

kops get ig --name $NAME

Output

NAME            ROLE    MACHINETYPE MIN MAX ZONES
master-us-east-1a   Master  t2.small    1   1   us-east-1a
nodes           Node    t2.small    2   2   us-east-1a

노드 타입을 본인이 원하는 사이즈로 변경하고 싶을 경우, 아래 명령을 통해 가능합니다.

edit master spec

kops edit ig master-us-east-1a --name $NAME
apiVersion: kops/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: 2018-05-10T04:40:40Z
  labels:
    kops.k8s.io/cluster: useast1.k8s.example.com
  name: master-us-east-1a
spec:
  cloudLabels:
    Email: ktk0011+dev@gmail.com
    Owner: 9to5
    Team: devops
  image: kope.io/k8s-1.8-debian-jessie-amd64-hvm-ebs-2018-02-08
  machineType: m4.large
  maxSize: 1
  minSize: 1
  nodeLabels:
    kops.k8s.io/instancegroup: master-us-east-1a
  role: Master
  subnets:
  - us-east-1a

이때 spec 하단에 aws instance가 생성될 때 aws의 tagcloudLabels 을 통해 미리 달아줄 수 있습니다.

cloudLabels:
    Email: ktk0011+dev@gmail.com
    Owner: 9to5
    Team: devops

여기서는 instance typecloudLabels 만을 변경했습니다.

edit nodes spec

노드의 설정 또한 변경해줍니다.

kops edit ig nodes --name $NAME
apiVersion: kops/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: 2018-05-10T04:40:41Z
  labels:
    kops.k8s.io/cluster: useast1.k8s.example.com
  name: nodes
spec:
  cloudLabels:
    Email: ktk0011+dev@gmail.com
    Owner: 9to5
    Team: devops
  image: kope.io/k8s-1.8-debian-jessie-amd64-hvm-ebs-2018-02-08
  machineType: c4.large
  maxSize: 2
  minSize: 2
  nodeLabels:
    kops.k8s.io/instancegroup: nodes
  role: Node
  subnets:
  - us-east-1a

원하시면 cluster 구성시에 사용할 instance size 를 늘려주시면 됩니다.

Apply cluster

이제 클러스터를 실제 aws instance 에 적용해 봅시다.
kops는 dry-run을 지원하기 때문에 —yes 없이 실행하면 변경내역을 미리 확인 해볼 수 있습니다.

kops update cluster --yes $NAME

이제 kubernetes cluster 구성이 완료 되었습니다.

check cluster

Nodes 들이 잘 동작하는지 확인 해봅시다.

kubectl get nodes

Output

9to5-macbook:~/projects/k8s ktg$ kubectl get nodes
NAME                            STATUS    ROLES     AGE       VERSION
ip-10-110-39-39.ec2.internal    Ready     node      6d        v1.9.3
ip-10-110-47-235.ec2.internal   Ready     master    6d        v1.9.3
ip-10-110-63-48.ec2.internal    Ready     node      6d        v1.9.3

StatusReady 입니다. 이제 kubernetes 를 사용할 수 있습니다!!… 만!

실제 서비스를 쿠베에서 사용하려면, route53 연동은 필수 입니다. 외부에서 kubernetes 로 접근하려면, 당연히 dns 가 필요하기 때문입니다. ip는 계속 변할 수 있기 때문에…

Route53연동은 다음 글에서 계속 하겠습니다.