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
아래 링크대로 따라서 Kops 설치
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의 tag 를 cloudLabels 을 통해 미리 달아줄 수 있습니다.
cloudLabels:
    Email: ktk0011+dev@gmail.com
    Owner: 9to5
    Team: devops
여기서는 instance type 과 cloudLabels 만을 변경했습니다.
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
Status 가 Ready 입니다. 이제 kubernetes 를 사용할 수 있습니다!!… 만!
실제 서비스를 쿠베에서 사용하려면, route53 연동은 필수 입니다. 외부에서 kubernetes 로 접근하려면, 당연히 dns 가 필요하기 때문입니다. ip는 계속 변할 수 있기 때문에…
Route53연동은 다음 글에서 계속 하겠습니다.