当前位置: 首页 > 工具软件 > external-dns > 使用案例 >

External-DNS安装与使用

高展
2023-12-01

注:本文基于kubeadm安装的k8s集群编写

1 背景

k8s中的服务通过ingress暴露给外部后,我们就能访问该服务。但是此时我们只能基于ingress暴露的ip来访问,这肯定不是个好主意,此时我们就需要将域名绑定到IP上。一般来说这里都需要手动到DNS服务商配置,对于ip变化频繁的话,还是很繁琐的。这时我们就可以考虑使用external-dns服务。

external-dns将Kubernetes的Service/Ingress暴露的服务(的DNS记录)同步给外部的DNS Provider

2 安装external-dns

为了更方便演示效果,我们直接用coredns做为external-dns的提供商,但是这样解析的效果只能作用于集群内,大家可以根据实际情况与aws集成。

2.1 安装CoreDNS的Etcd插件

因为我们使用的是coredns,因此后端存储就用集群内的etcd实例,需要添加对应插件,其实就是添加响应的配置,

.:53 {
        ...
        etcd example.org {
          path /skydns
          endpoint https://192.168.0.180:2379
          tls /tls/server.crt /tls/server.key /tls/ca.crt
          fallthrough .
        }
    }

修改coredns的configmap,添加etcd section,其中,
example.org:指定应用的域名范围
path:指定数据存放路径
endpoint:指定etcd的地址,这里需要用节点ip,不能用127地址,不然其他节点就无法访问
tls:指定对应的证书,因为我们需要从其他节点访问,因此需要验证,后面还会对这个路径说明

上面用到的证书,其实就是目录/etc/kubernetes/pki/etcd/下的证书,由kubeadm生成,我们可以将他们导入集群,作为secret来引用,

kubectl create secret generic etcd-client-certs --from-file=ca.crt=/etc/kubernetes/pki/etcd/ca.crt --from-file=server.crt=/etc/kubernetes/pki/etcd/server.crt --from-file=server.key=/etc/kubernetes/pki/etcd/server.key -n kube-system

修改对应deployment,添加对应的volume和volumeMounts,

    spec:
      volumes:
        - name: etcd-client-certs
          secret:
            secretName: etcd-client-certs
            defaultMode: 400
        ...
      containers:
        - name: coredns
          ...
          volumeMounts:
            - name: etcd-client-certs
              readOnly: true
              mountPath: /tls/

这样,coredns部分就就绪了,下面就可以开始安装external-dns。

2.2 helm安装external-dns

我们直接使用helm来安装,先添加external-dns的repo,这里我们使用bitnami,

helm repo add bitnami https://charts.bitnami.com/bitnami

然后我们需要设置一些配置,

helm install external-dns bitnami/external-dns --namespace=external-dns \
--set sources="{ingress}" --set policy=sync --set logLevel=debug \
--set provider=coredns --set image.tag=0.10.0 \
--set coredns.etcdEndpoints=https://192.168.0.180:2379 \
--set coredns.etcdTLS.enabled=true \
--set coredns.etcdTLS.caFilename=ca.crt \
--set coredns.etcdTLS.certFilename=server.crt \
--set coredns.etcdTLS.keyFilename=server.key

其中,

  • namespace:指定namespace为external-dns
  • sources:指定导出的来源,这里将ingress导出到dns提供商中,当然也可以将service也一起导出
  • provider:指定coredns为dns provider,如果用aws的route53,这里就设置为aws
  • image.tag: 指定镜像tag
  • coredns.etcdEndpoints:指定etcd的地址,需要用node ip,和上面coredns里的设置类似
  • coredns.etcdTLS.caFilename:指定ca证书名称
  • coredns.etcdTLS.certFilename:指定客户端证书
  • coredns.etcdTLS.keyFilename:指定客户端私钥

另外,因为coredns provider默认使用etcd-client-certs这个secret,因此我们需要将对应的证书导入,和上面coredns里类似,只不过换个namespace,

kubectl create secret generic etcd-client-certs --from-file=ca.crt=/etc/kubernetes/pki/etcd/ca.crt --from-file=server.crt=/etc/kubernetes/pki/etcd/server.crt --from-file=server.key=/etc/kubernetes/pki/etcd/server.key -n external-dns

这样,external-dns也配置完毕,我们可以看下pod状态,

[root@master etcd]# kubectl get pod -n external-dns
NAME                            READY   STATUS    RESTARTS   AGE
external-dns-76cb6d74c6-c8vq5   1/1     Running   0          23h

3 测试效果

为了测试效果,我们需要新建一个ingress资源,假设集群里已经部署了一个webservice的服务,我们需要将其域名设置为web.example.org,

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test1-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /
  namespace: ingress-nginx
spec:
  ingressClassName: nginx
  rules:
  -  host: web.example.org
     http:
      paths:
      - path: /
        backend:
          service:
            name: webservice
            port:
              number: 10080
        pathType: Prefix

创建资源后,确认address已分配,

[root@master ingress]# kubectl get ingress -n ingress-nginx
NAME            CLASS   HOSTS                    ADDRESS         PORTS   AGE
test1-ingress   nginx   web.example.org          192.168.0.180   80      24h

此时,我们可以在集群中创建一个debug pod来测试这个域名,

[root@master ~]# kubectl run centos -it --image=centos:7 -- /bin/bash
If you don't see a command prompt, try pressing enter.
[root@centos /]# yum install -y bind-utils
[root@centos /]# nslookup web.example.org
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	web.example.org
Address: 192.168.0.180

可见此时域名已经在集群内生效了。

一般我们在生产环境中,会部署两套external-dns,一套对内,一套的对外,这样更方便管理。


参考文档:

  1. https://artifacthub.io/packages/helm/bitnami/external-dns
  2. https://kubernetes.io/docs/concepts/configuration/secret/
 类似资料: