external-dns 阿里云容器服务实战
受Kubernetes的集群内部DNS服务器Kubernetes DNS的启发,ExternalDNS使Kubernetes资源可通过公共DNS服务器配置与发布。 与KubeDNS一样,它从Kubernetes API中检索资源列表(Service,Ingress等),以确定所需的DNS记录列表。 然而,与KubeDNS不同,它本身不是DNS服务器,而是仅相应地配置其他DNS提供商 - 例如, Alibaba Cloud 或其他服务商。
配置 RAM 信息
首先在阿里云容器服务创建一个Kubernetes 集群,选择节点列表内任意一个Worker节点,打开对应的节点列表信息页面。
寻找到对应的 RAM 角色,打开ram 控制台 https://ram.console.aliyun.com/#/role/list
,找到对应的角色管理。
选择管理 -> 角色授权策略 -> 查看权限 -> 修改授权策略
添加以下权限
{
"Action": "alidns:AddDomainRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "alidns:DeleteDomainRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "alidns:UpdateDomainRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "alidns:DescribeDomainRecords",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "alidns:DescribeDomains",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:AddZoneRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:DeleteZoneRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:UpdateZoneRecord",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:DescribeZoneRecords",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:DescribeZones",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "pvtz:DescribeZoneInfo",
"Resource": "*",
"Effect": "Allow"
}
部署External-DNS
配置完毕RAM后,就可以部署External-DNS,部署yaml如下:
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: external-dns
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.cn-beijing.aliyuncs.com/xianlu/external-dns:v0.5.17-102-gc4bcada
args:
- --source=service
- --source=ingress
- --provider=alibabacloud
- --policy=sync # enable full synchronization
- --registry=txt
- --txt-owner-id=my-identifier
- --alibaba-cloud-config-file= # enable sts token
volumeMounts:
- mountPath: /usr/share/zoneinfo
name: hostpath
volumes:
- name: hostpath
hostPath:
path: /usr/share/zoneinfo
type: Directory
使用External-DNS
我们以公有域名为例,Aliyun dns 控制台地址为https://dns.console.aliyun.com/#/dns/domainList
,目前已经有一个域名托管。
下面我们创建一个Service测试一下
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: nginx.xianlubird.top.
spec:
type: LoadBalancer
ports:
- port: 80
name: http
targetPort: 80
selector:
app: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
name: http
请注意这个annotation external-dns.alpha.kubernetes.io/hostname: nginx.xianlubird.top.
这里就是用来配置你想要挂载的 DNS 名称。External-dns会自动帮你将 IP 对应的 DNS 记录建立好。稍等片刻就能看到结果。
[root@izwz9dn4v9m0fowyqhbwhvz ~]# curl nginx.xianlubird.top
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
可以看到,这里域名已经可以正常访问了。 如果删除对应的Service ,对应的 DNS 解析记录也会被删除。
使用私有域名
阿里云 DNS 提供PrivateZone功能,可以针对特定的 VPC 使用私有域名解析,如果想使用私有域名解析,请修改external-dns 配置
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.cn-beijing.aliyuncs.com/xianlu/external-dns:v0.5.17-102-gc4bcada
args:
- --source=service
- --source=ingress
- --provider=alibabacloud
- --policy=sync # enable full synchronization
- --registry=txt
- --txt-owner-id=my-identifier
- --alibaba-cloud-zone-type=private
- --alibaba-cloud-config-file= # enable sts token
volumeMounts:
- mountPath: /usr/share/zoneinfo
name: hostpath
volumes:
- name: hostpath
hostPath:
path: /usr/share/zoneinfo
type: Directory
注意 - --alibaba-cloud-zone-type=private
这里指定了zone 类型为私有,这样就可以监控私有域名的解析。
以下面的例子说明
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: ingress-sg2.sg.private.local.
spec:
type: LoadBalancer
ports:
- port: 80
name: http
targetPort: 80
selector:
app: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
name: http
这里希望将这个Service 注册到ingress-sg2.sg.private.local.
域名下,首先在阿里云DNS privatezone 里面创建根域名private.local
请注意,一定要先关联 VPC,否则无法添加记录,您可以先手动添加一个无效记录,然后绑定对应的 VPC。
配置完毕后,external-dns 就可以自动帮助域名注册
使用子域名
如果使用阿里云DNS托管子域名,那么在部署external-dns 的时候就需要指定监听的子域名名称,这里我们以ack.dns-example.xyz
为例。
在部署external-dns的时候,需要使用一下模板
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.cn-beijing.aliyuncs.com/xianlu/external-dns:v0.5.17-102-gc4bcada
args:
- --source=service
- --source=ingress
- --domain-filter=ack.dns-example.xyz
- --provider=alibabacloud
- --policy=sync # enable full synchronization
- --registry=txt
- --txt-owner-id=my-identifier
- --alibaba-cloud-config-file= # enable sts token
volumeMounts:
- mountPath: /usr/share/zoneinfo
name: hostpath
volumes:
- name: hostpath
hostPath:
path: /usr/share/zoneinfo
type: Directory
这里请注意,一个巨大的区别点就在于- --domain-filter=ack.dns-example.xyz
,这里的意思是,指定监听哪个域名domain。部署完毕后,我们创建一个例子看一下:
apiVersion: v1
kind: Service
metadata:
name: nginx
annotations:
external-dns.alpha.kubernetes.io/hostname: nginx.ack.dns-example.xyz.
spec:
type: LoadBalancer
ports:
- port: 80
name: http
targetPort: 80
selector:
app: nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
name: http
可以看到域名已经成功解析
目前External-DNS 已经开源,项目地址: https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/alibabacloud.md
更多参数详情,可以参考。