티스토리 뷰

Cloud/Kubernetes

Custom domain lookup on Kubernetes

jacobbaek Jacob_baek 2021. 5. 7. 21:42

Kubernetes 는 내부에 coredns를 통해 별도의 DNS서버를 구성하게 되어 있다.
그러다보니 외부에 등록되지 않은 별도의 도메인을 사용하기 위해서는 추가적인 작업이 필요하다.
하여 이를 어떤식으로 설정할수 있는지 알아보도록 하자.

Kubernetes DNS의 기본구성

먼저 간단히 구성을 확인해보면 다음과 같은 coredns와 nodelocadns를 다수 확인할수 있다.

[root@localhost ~]# kubectl get pod -n kube-system | grep dns
coredns-7677f9bb54-5p6xl                                          1/1     Running   1          4d
coredns-7677f9bb54-p9j47                                          1/1     Running   2          30d
dns-autoscaler-5b7b5c9b6f-czlcl                                   1/1     Running   2          30d
nodelocaldns-ndlww                                                1/1     Running   2          30d
nodelocaldns-rrnpk                                                1/1     Running   3          30d
nodelocaldns-v65cp                                                1/1     Running   2          30d

이중 coredns가 bind의 zone 파일과 같은 설정정보를 가지고 있고 이는 configmap으로 생성되어 있음을 확인할 수 있다.

[root@localhost ~]# kubectl describe configmap -n kube-system coredns
Name:         coredns
Namespace:    kube-system
Labels:       addonmanager.kubernetes.io/mode=EnsureExists
Annotations:  <none>

Data
====
Corefile:
----
.:53 {
    errors
    health {
        lameduck 5s
    }
    ready
    kubernetes mgmtkube.local in-addr.arpa ip6.arpa {
      pods insecure
      fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    forward . /etc/resolv.conf {
      prefer_udp
    }
    cache 30
    loop
    reload
    loadbalance
}

Events:  <none>

Kubernetes 환경에서 DNS 설정 및 control

다음과 같은 domain lookup에 대한 control이 가능하다.

  • /etc/hosts 에 lookup 가능한 domain 등록
  • custom resolving 가능한 domain을 kubernetes에 등록
  • external-dns라는 외부 dns를 kubernetes 내부에서 사용할수 있는 project

/etc/hosts 에 lookup 가능한 domain 등록

pod들은 host node에 /etc/hosts를 상속받지 않고 kubernetes 의 nodelocaldns의 IP를 nameserver로 가지고 있다.

root@nginx-example-757b4c8546-8xmwc:/# cat /etc/resolv.conf
search nginx-example.svc.cluster.local svc.cluster.local cluster.local
nameserver 169.254.25.10
options ndots:5

이말인즉슨, host node에 설정한 /etc/hosts 정보를 사용하지 않고 kubernetes pod 자체의 hosts파일을 따로 관리한다는 의미로 볼수 있다.

NOTE
참고로 아래는 nodelocaldns가 동작되는 arguments 정보이다.

[root@master001 ~]# kubectl get pod/nodelocaldns-4mjvv -n kube-system -o jsonpath='{.spec.containers[0].args}'
["-localip","169.254.25.10","-conf","/etc/coredns/Corefile","-upstreamsvc","coredns"]

앞서 nameserver로 등록된 169.254.25.10이 확인된다.

그렇다고 pod가 사용하는 /etc/hosts 파일을 직접 변경하면 잠시나마 사용은 가능하겠지만 영구적으로 사용할수는 없다.
하여 이를 deployment에 직접 설정하여 사용할수 있는 방법이 hostAliases이다.
다음과 같이 deployment에 추가가 가능하다.

  hostAliases:
  - ip: "192.168.100.100"
    hostnames:
    - "testweb.jacobbaek.com"

이렇게 하여 배포를 하게 되면 혹은 deployment 자체를 수정하게 되면
아래와 같이 deployment에 의해 배포된 pod에서 hsots 정보를 확인하면 다음과 같이 "Entries added by HostAliases" 주석과 함께 추가된 hosts 정보를 확인할수 있다.

bash-5.1# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.233.90.185   nginx-example-4hbfv-83sp8

# Entries added by HostAliases.
192.168.100.100 testweb.jacobbaek.com

custom resolving 가능한 domain을 kubernetes에 등록

kubernetes 내부의 pod 나 service IP가 아닌 host에서 통신이 가능한 IP에 대해 통신이 필요하거나 등록되지 않은 Nameserver에 질의를 해야 하는 경우 해당 도메인을 kubernetes에서 직접 질의가 되도록 할수 있다.
아래 예시는 coredns이라는 configmap에 추가로 설정한 것이다. (## 주석을 확인해보자)

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        kubernetes mgmtkube.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf {
          prefer_udp
        }
        cache 30
        loop
        reload
        loadbalance
        ## === start
        ### option 1
        hosts {
          192.168.100.100 ldap.jacobbaek.com
          192.168.100.254 sso.jacobbaek.com
          192.168.100.10  test.jacobbaek.io
        }
        ### option 2
        #hosts jacobbaek.com {
        #  192.168.100.100 ldap.jacobbaek.com
        #  192.168.100.254 sso.jacobbaek.com
        #  fallthrough
        #}
        ## === end
    }
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system

해당 configmap을 위와 같이 원하는 도메인과 IP를 넣어 수정하고 저장하자.

참고
coredns configmap 상에 hosts 를 여러개 사용할수 없다.

안타깝지만 configmap은 변경한다고 바로 해당 configmap을 적용하지는 않는다.
하여 configmap을 다시 적용할수 있게 coredns pod들을 삭제하여 다시 배포도되록 한다.

kubectl delete pod -n kube-system -l k8s-app=kube-dns

하지만 이것만으로 pod들이 바로 lookup할수 있는 환경이 갖추어지지 않는다.
nodelocadns ConfigMap도 변경이 필요하다.
(kubernetes DNS 구조상 nodelocaldns가 1차적으로 domain 질의를 받게 되는데 해당 도메인에 대한 resolving을
forward로 지정된 DNS 서버에서 처리하도록 해야만 lookup이 되는 환경이 구성되고 여기서 설정된
10.233.0.3(각 kubernetes 환경마다 상이하여 coredns service의 IP 확인 필요)의 경우 앞서 지정한 coredns 의
서버 IP이기에 이를 지정하면 custom domain에 대한 질의가 되는 환경이 되게 된다.)

    ldap.jacobbaek.com:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.25.10
        forward . 10.233.0.3 {
            force_tcp
        }
        prometheus :9253
    }
    jacobbaek.kr:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.25.10
        forward . 10.233.0.3 {
            force_tcp
        }
        prometheus :9253
    }

수정후 nodelocaldns또한 재시작이 필요하다. nodelocaldns 의 경우 daemonset으로 각 node마다 동작되고 있어
아래와 같은 명령을 통해 모든 nodelocaldns을 재시작한다.

kubectl delete pod -n kube-system -l k8s-app=nodelocaldns

이후 앞서 추가했던 domain인 ldap.jacobbaek.com/sso.jacobbaek.com/test.jacobbaek.kr이 pod에서 lookup되는것을 확인할 수 있다.

참고
kubespray를 사용해 k8s를 배포한 경우 아래와 같은 dns_etchosts를 사용하는것을 추천한다.

root@localhost:/home/kubespray/inventory/testk8s# cat group_vars/k8s-cluster/k8s-cluster.yml | grep -A 2 dns_etchosts
dns_etchosts: |
 192.168.0.100 api-test.jacobbaek.com
 192.168.0.200 ingress-test.jacobbaek.com

위와 같은 설정을 추가하면 앞선 custom domain 작업을 kubespray를 통해 관리할수 있다.

External-DNS

참고사이트

'Cloud > Kubernetes' 카테고리의 다른 글

Custom domain lookup on Kubernetes  (0) 2021.05.07
Kustomize  (0) 2021.04.19
initcontainer with multicommand  (0) 2021.04.13
Velero  (0) 2021.04.06
ingress with subpath  (0) 2021.03.23
Cluster-API  (0) 2021.03.20
댓글
댓글쓰기 폼