主讲内容:docker/kubernetes 云原生技术,大数据架构,分布式微服务,自动化测试、运维。
7月1号-7月29号 8折优惠!!!
7月1号-7月29号 8折优惠!!!
7月1号-7月29号 8折优惠!!!
全栈工程师开发手册 (作者:栾鹏)
架构系列文章
验证一个域名的ip地址可以使用
nslookup xx.xx..xx
涉及到的是Pod和Service之间的相互访问,主要格式如下:
访问Pod:(注意下面不是直接pod的ip,而是由pod的ip组成的字符串)
{pod-ip}.{namespace}.pod.cluster.local
例如某pod的ip为 1.2.3.4,在命名空间default与DNS名称cluster.local将有一个域名:1-2-3-4.default.pod.cluster.local。
{hostname}.{subdomain}.{namespace}.svc.cluster.local
subdomain是在创建pod设定的属性,和hostname可以一起设置
访问StatefulSet:
{pod-name}.{service-name}.{namespace}.svc.cluster.local
可以进入到pod中查看/etc/hosts
访问Service:
{service-name}.{namespace}.svc.cluster.local
当你创建一个Service时,Kubernetes会自动创建一个形如
的DNS项。如果集群中另一个服务调用这个服务时,仅仅指定了
,那么Kubernetes会使用调用方所在的Namespace将
补全。因此如果调用方和被调用方不处于同一个Namespace,你必须使用包含Namespace的service name
可以在 Pod /Deployment中指定pod的 hostname 和 subdomain:,例如:
apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: busybox-subdomain
containers:
name: busybox
- image: busybox
command:
- sleep
- "3600"
因为pod的访问域名是hostname.custom-subdomain.default.svc.cluster.local
所以该 Pod 的域名是 busybox-1.busybox-subdomain.default.svc.cluster.local。
当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts 文件中添加条目,可以在 Pod 级别覆盖对主机名的解析。在 1.7 版本,用户可以通过 PodSpec 的 HostAliases 字段来添加这些自定义的条目。
建议通过使用 HostAliases 来进行修改,因为该文件由 Kubelet 管理,并且可以在 Pod 创建/重启过程中被重写。
让我们从一个 Nginx Pod 开始,给该 Pod 分配一个 IP:
$ kubectl get pods --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
默认,hosts 文件只包含 ipv4 和 ipv6 的样板内容,像 localhost 和主机名称。
除了默认的样板内容,我们可以向 hosts 文件添加额外的条目,将 foo.local、 bar.local 解析为127.0.0.1,将 foo.remote、 bar.remote 解析为 10.1.2.3,我们可以在 .spec.hostAliases 下为 Pod 添加 HostAliases。
hostaliases-pod.yaml docs/concepts/services-networking Copy hostaliases-pod.yaml to clipboard
apiVersion: v1
kind: Pod
metadata:
name: hostaliases-pod
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "foo.local"
- "bar.local"
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
containers:
- name: cat-hosts
image: busybox
command:
- cat
args:
- "/etc/hosts"
hosts 文件的内容看起来类似如下这样:
$ kubectl logs hostaliases-pod
# 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.200.0.4 hostaliases-pod
127.0.0.1 foo.local
127.0.0.1 bar.local
10.1.2.3 foo.remote
10.1.2.3 bar.remote
在最下面额外添加了一些条目。
在 1.7 版本,如果 Pod 启用 hostNetwork,那么将不能使用这个特性,因为 kubelet 只管理非 hostNetwork 类型 Pod 的 hosts 文件。目前正在讨论要改变这个情况。
kubelet 管理 Pod 中每个容器的 hosts 文件,避免 Docker 在容器已经启动之后去 修改 该文件。
因为该文件是托管性质的文件,无论容器重启或 Pod 重新调度,用户修改该 hosts 文件的任何内容,都会在 Kubelet 重新安装后被覆盖。因此,不建议修改该文件的内容。
参考:https://kubernetes.io/zh/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/
DNS,全名为 Domain Name System。DNS 会有一张表格,记录每个 domain name 相对应的 IP 位址。如此,我们不再需要去记录该服务的 IP address,而是可以透过该服务的域名来连接到该服务。以 www.google.com.tw 为例,当我们在浏览器输入 www.google.com.tw 时,DNS会帮我们找到该域名相对应的 IP,并连接到该服务.
如果想知道某个特定的域名相对应的 IP 位址,可以在终端机输入 host 指令,
而 Kubernetes 本身提供了 DNS 的套件,kube-dns。 kube-dns 帮助在同一个 Kubernetes Cluster 中的所有 Pods ,都能透过 Service 的名称找到彼此。透过 kubectl get 指令,会发现 kube-dns 也是一个在 Cluster 中运行的服务,一旦 Kubernetes Cluster 被建立后,便会自动运行。
而 kube-dns 的相关设定档则放是放在 master node 的 /etc/kubernetes/addons 资料夹底下,以 minikube 为例,minikube 运行的 VM 本身就是 master node,所以我们先透过 minikube ssh 指令登入,
在 /etc/kubernetes/addons 资料夹底下,除了可以看到 kube-dns 的相关设定档外,也可以看到 Kubernetes 其他套件的设定档。
如上图我们可以看到 kube-dns 是运行在 Kubernetes Cluster 的一个 Pod,而这个 kube-dns-86f6f55dd5-cht2h Pod,也有一个相对应的 Service 物件。
Kubernetes 在每一个 Pod 创建时,都会在该 Pod 的 /etc/resolve.conf 档案中,自动加入 kube-dns service 的 domain name 与相对应的 IP 位址。因此 其他 Pods 可以透过名称为 kube-dns 的 Service 物件,找到正在运行的 kube-dns,以下图为例:
我们在 Kubernetes Cluster 跑起 alpine Pod,并 ssh 进到 alpine 的 shell,用 cat 指令查看 /etc/resolve.conf 内容,
若是与上上图比对,会发现 /etc/resolve.conf 中的 nameserver 指向的 IP 位置,就是 kube-dns 的 Service。或者是dnsmasq的service
DNS服务有很多中方式, 官方推荐安装的是kube-dns, 我们这里先介绍这个. 如果你的k8s上dns服务不是使用这个插件进行管理的,可以跳过.
kube-dns是Kubernetes中的一个内置插件,目前作为一个独立的开源项目维护,见https://github.com/kubernetes/dns。
Kubernetes 1.6 及以上版本。
集群必须使用 kube-dns 插件进行配置。
从 Kubernetes v1.3 版本开始,使用 [cluster add-on 插件管理器回自动启动内置的 DNS。
Kubernetes DNS pod 中包括 3 个容器:
Kube-DNS以Pod的形式部署到kubernetes集群系统;
Kube-DNS对SkyDNS进行封装优化,由4个容器变成3个;
kubedns容器:基于skydns实现;监视k8s Service资源并更新DNS记录;替换etcd,使用TreeCache数据结构保存DNS记录并实现SkyDNS的Backend接口;接入SkyDNS,对dnsmasq提供DNS查询服务;
dnsmasq容器:为集群提供DNS查询服务,即简易的dns server;设置kubedns为upstream;提供DNS缓存,降低kubedns负载,提高性能;
sidecar容器:监控健康模块,同时向外暴露metrics记录;定期检查kubedns和dnsmasq的健康状态;为k8s活性检测提供HTTP API。
上面的DNS pod 具有静态 IP 并作为 Kubernetes 服务暴露出来。该静态 IP 分配后,kubelet 会将使用 --cluster-dns =
标志配置的 DNS 传递给3个容器的每个容器。
DNS 名称也需要域名。本地域可以使用标志 --cluster-domain =
在 kubelet 中配置。
Kubernetes集群DNS服务器基于 SkyDNS 库。它支持正向查找(A 记录),服务查找(SRV 记录)和反向 IP 地址查找(PTR 记录)
kube-dns 将分别为 service 和 pod 生成不同格式的 DNS 记录。
Service
Pod
运行 Pod 时,kubelet 将预先配置集群 DNS 服务器到 Pod 中,并搜索节点自己的 DNS 设置路径。如果节点能够解析特定于较大环境的 DNS 名称,那么 Pod 应该也能够解析。请参阅下面的已知问题以了解警告。
如果您不想要这个,或者您想要为 Pod 设置不同的 DNS 配置,您可以给 kubelet 指定 --resolv-conf 标志。将该值设置为 “” 意味着 Pod 不继承 DNS。将其设置为有效的文件路径意味着 kubelet 将使用此文件而不是 /etc/resolv.conf 用于 DNS 继承。
通过为 kube-dns (kube-system:kube-dns)提供一个 ConfigMap,集群管理员能够指定自定义存根域和上游 nameserver。
例如,下面的 ConfigMap 建立了一个 DNS 配置,它具有一个单独的存根域和两个上游 nameserver:
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{“acme.local”: [“1.2.3.4”]}
upstreamNameservers: |
[“8.8.8.8”, “8.8.4.4”]
如上面指定的那样,带有“.acme.local”后缀的 DNS 请求被转发到 1.2.3.4 处监听的 DNS。 “8.8.8.8”, “8.8.4.4”(这两个ip为Google Public DNS) 为上游查询提供服务。
ConfigMap 选项
kube-dns kube-system:kube-dns ConfigMap 的选项如下所示:
字段 | 格式 | 描述 |
---|---|---|
stubDomains(可选) | 使用 DNS 后缀 key 的 JSON map(例如 “acme.local”),以及 DNS IP 的 JSON 数组作为 value。 | 目标 nameserver 可能是一个 Kubernetes Service。例如,可以运行自己的 dnsmasq 副本,将 DNS 名字暴露到 ClusterDNS namespace 中。 |
upstreamNameservers(可选) | DNS IP 的 JSON 数组。 | 注意:如果指定,则指定的值会替换掉被默认从节点的 /etc/resolv.conf 中获取到的 nameserver。限制:最多可以指定三个上游 nameserver。 |
注意,集群管理员不希望覆盖节点的上游 nameserver,所以他们不会指定可选的 upstreamNameservers 字段。
下表描述了如何将具有特定域名的查询映射到其目标DNS服务器:
域名 | 响应查询的服务器 |
---|---|
kubernetes.default.svc.cluster.local | kube-dns |
foo.acme.local | 自定义 DNS (1.2.3.4) |
widget.com | 上游 DNS (8.8.8.8 或 8.8.4.4) |
Kubernetes 目前在 Pod 定义中支持两个 DNS 策略:Default 和 ClusterFirst,dnsPolicy 默认为 ClusterFirst。如果将 dnsPolicy 设置为 Default,域名解析配置则完全从 Pod 所在的节点(/etc/resolv.conf)继承而来。
如果包含自定义DNS,则逻辑图为
自定义的上游名称服务器和存根域不会影响那些将自己的 dnsPolicy 设置为 Default 或者 None 的 Pod。
如果 Pod 的 dnsPolicy 设置为 “ClusterFirst”,则其名称解析将按其他方式处理,具体取决于存根域和上游 DNS 服务器的配置。
未进行自定义配置:没有匹配上配置的集群域名后缀的任何请求,例如 “www.kubernetes.io”,将会被转发到继承自节点的上游 nameserver。
进行自定义配置:如果配置了存根域和上游 DNS 服务器(和在 前面例子 配置的一样),DNS 查询将根据下面的流程进行路由:
查询首先被发送到 kube-dns 中的 DNS 缓存层。
从缓存层,检查请求的后缀,并转发到合适的 DNS 上,基于如下的示例:
上面的教程都是配置dns服务器的地址, 我们也可以自己来建一个dns服务器,并添加记录,然后将自定义的dns服务器添加为k8s的上游dns服务器.
dnsmasq的部署参考:https://blog.csdn.net/luanpeng825485697/article/details/84139310
dnsmasq先去解析hosts文件, 再去解析/etc/dnsmasq.d/下的*.conf文件,并且这些文件的优先级要高于dnsmasq.conf,我们自定义的resolv.dnsmasq.conf中的DNS也被称为上游DNS,这是最后去查询解析的;
如果不想用hosts文件做解析,我们可以在/etc/dnsmasq.conf中加入no-hosts这条语句,这样的话就直接查询上游DNS了,如果我们不想做上游查询,就是不想做正常的解析,我们可以加入no-reslov这条语句。
dnsmasq.conf文件中的配置含义参考: http://blog.51cto.com/longlei/2065967
编辑 dnsmasq 的配置文件 /etc/dnsmasq.conf 。这个文件包含大量的选项注释。
(1)dnsmasq经常修改的比较重要参数说明
具体参数 | 参数说明 |
---|---|
resolv-file | 定义dnsmasq从哪里获取上游DNS服务器的地址, 默认从/etc/resolv.conf获取。 |
strict-order | 表示严格按照resolv-file文件中的顺序从上到下进行DNS解析,直到第一个解析成功为止。 |
listen-address | 定义dnsmasq监听的地址,默认是监控本机的所有网卡上。 |
address | 启用泛域名解析,即自定义解析a记录,例如:address=/long.com/192.168.115.10 访问long.com时的所有域名都会被解析成192.168.115.10 |
bogus-nxdomain | 对于任何被解析到此 IP 的域名,将响应 NXDOMAIN 使其解析失效,可以多次指定. 通常用于对于访问不存在的域名,禁止其跳转到运营商的广告站点 |
server | 指定使用哪个DNS服务器进行解析,对于不同的网站可以使用不同的域名对应解析。例如:server=/google.com/8.8.8.8 #表示对于google的服务,使用谷歌的DNS解析。 |
(2)查看配置文件语法是否正确,可执行下列命令
[root@localhost ~]# dnsmasq --test
dnsmasq: syntax check OK.
(3)DNS 缓存设置
要在单台电脑上以守护进程方式启动dnsmasq做DNS缓存服务器,编辑/etc/dnsmasq.conf,添加监听地址:
listen-address=127.0.0.1
如果用此主机为局域网提供默认 DNS,请用为该主机绑定固定 IP 地址,设置:
listen-address=192.168.x.x
这种情况建议配置静态IP
多个ip地址设置:
listen-address=127.0.0.1,192.168.x.x
(4)三个以上域名服务器
Linux 处理 DNS 请求时有个限制,在 resolv.conf 中最多只能配置三个域名服务器(nameserver)。作为一种变通方法,可以在 resolv.conf 文件中只保留 localhost 作为域名服务器,然后为外部域名服务器另外创建 resolv-file 文件。
也就是/etc/resolv.conf内容为
nameserver 127.0.0.1
首先,为 dnsmasq 新建一个域名解析文件:
[root@localhost ~]# vim /etc/resolv.dnsmasq.conf
# Google's nameservers, for example
nameserver 8.8.8.8
nameserver 8.8.4.4
然后编辑 /etc/dnsmasq.conf 让 dnsmasq 使用新创建的域名解析文件:
[root@localhost ~]# vim /etc/dnsmasq.conf
...
resolv-file=/etc/resolv.dnsmasq.conf
通过上面的理论基础我们知道了dns解析的流程.现在我们增加一条自己的记录.
dnsmasq支持读取/etc/hosts文件作为自己的DNS记录,如果/etc/hosts解析不方便的话,还可以指定–addn-hosts,指定某一文件作为hosts添加到dnsmasq缓存中。所以现在方案就简单了
创建一个configmap,其内容为待解析的域名记录;将configmap作为volume挂载到dnsmasq容器的/dns目录下,然后为dnsmasq增加参数–addn-hosts=/dns/key,宿主机主机名记录就可以加到dnsmasq中去了。
如果集群扩容,configmap更新了呢?我们知道configmap更新了以后,会更新挂载到容器中的文件;但遗憾的是,dnsmasq并不会管addn-hosts的文件的变化,新机器的主机名并不能加到kube-dns中。
办法也有,因为kube-dns是一个deployment,所以可以将其scaleout 1 -> 0 -> 1:
kubectl scale kube-dns --replicas=0 -n kube-system
kubectl scale kube-dns --replicas=1 -n kube-system
缺点就是集群内会暂时关闭DNS解析。
或者 我们也可以在/etc/dnsmasq.d/下的*.conf文件中增加一行自己想要的解析记录
address=/long.com/192.168.115.10
增加以后重启pod就可以了. 跟前面的方法其实是一样的.
上面我们使用的是kube-dns进行的dns管理,当然还有很多其他的dns管理工具, 用的多的就是CoreDNS.
要使用CoreDN您的Kubernetes服务器必须是v1.9或更高版本。要检查版本,请输入kubectl version。
注意:在Kubernetes 1.11中,CoreDNS已经而配置为通用可用性(GA)并默认安装。
CoreDNS是一个通用的权威DNS服务器,可以作为集群DNS,符合dns规范。并且在高版本的k8s中CoreDNS作为默认的dns服务器
在Kubernetes 1.10及更高版本中,您还可以在使用kubeadm升级正在使用的群集时移至CoreDNS 。在这种情况下,kubeadm将基于kube-dnsConfigMap 生成CoreDNS配置(“Corefile”),保留联合,存根域和上游名称服务器的配置。
如果要从kube-dns转移到CoreDNS,请确保 在升级期间将CoreDNS功能门设置为true。例如,以下是v1.11.0升级的样子:
kubeadm upgrade apply v1.11.0 --feature-gates=CoreDNS=true
在1.11之前的版本中,Corefile将被升级期间创建的文件覆盖。 如果已对其进行自定义,则应保存现有的ConfigMap。在新的ConfigMap启动并运行后,您可以重新应用自定义。
如果您在Kubernetes 1.11及更高版本中运行CoreDNS,则在升级期间,将保留现有的Corefile。
CoreDNS是一个模块化和可插拔的DNS服务器,每个插件都为CoreDNS添加了新功能。这可以通过维护Corefile来配置,Corefile是CoreDNS配置文件。集群管理员可以修改CoreDNS Corefile的ConfigMap以更改服务发现的工作方式。
在Kubernetes中,CoreDNS安装了以下默认的Corefile配置。
官网参考:https://github.com/coredns/coredns/tree/master/plugin/kubernetes
Corefile配置包括以下CoreDNS 插件:
kubernetes下包含更多的配置项
kubernetes [ZONES...] {
resyncperiod DURATION
endpoint URL [URL...]
tls CERT KEY CACERT
kubeconfig KUBECONFIG CONTEXT
namespaces NAMESPACE...
labels EXPRESSION
pods POD-MODE
endpoint_pod_names
upstream [ADDRESS...]
ttl TTL
noendpoints
transfer to ADDRESS...
fallthrough [ZONES...]
ignore empty_service
}
其中
resyncperiod指定Kubernetes数据API DURATION周期。
Upstream 用于解析指向外部主机的服务(外部服务)。
参考官网:https://github.com/coredns/coredns/tree/master/plugin/kubernetes
我们可以通过修改此configmap来修改默认行为。
如果集群运营商的Consul域服务器位于10.150.0.1,并且所有Consul名称都具有后缀.consul.local。要在CoreDNS中配置它,集群管理员在CoreDNS ConfigMap中创建。
另外如果明确强制所有非群集DNS的查询在172.16.0.1要经过特定的名称服务器,proxy和upstream对域名服务器,而不是/etc/resolv.conf(好吧,我翻译错了)
To explicitly force all non-cluster DNS lookups to go through a specific nameserver at 172.16.0.1, point the proxy and upstream to the nameserver instead of /etc/resolv.conf
则设置成下面的配置
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream 172.16.0.1
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
proxy . 172.16.0.1
cache 30
loop
reload
loadbalance
}
consul.local:53 {
errors
cache 30
proxy . 10.150.0.1
}
在Kubernetes 1.10及更高版本中,kubeadm支持从kube-dns ConfigMap自动转换CoreDNS ConfigMap。
又例如下面coredns配置文件:
1.访问cluster.local后缀的,去查10.254.0.2
2.访问out-of.kubernetes的如server.out-of.kubernetes去查192.168.x.x
3.访问互联网的,走resolve.conf的地址
.:53 {
errors # show errors
log stdout # show query logs
health
kubernetes cluster.local 10.254.0.0/16
proxy out-of.kubernetes 192.168.x.x
proxy . /etc/resolv.conf
再例如
. {
debug
errors
whoami
log
proxy . /etc/resolv.conf {
except mydomain.com
}
file /file/local mydomain.com
}
debug errors whoami log file proxy都是coredns支持的插件,这里就直接使用。上面最重要的是proxy和file两个插件。
proxy插件中 . /etc/resolv.conf表示所有的查询请求都由/etc/resolv.conf中的nameserver来负责解析,但除了mydomain.com的请求。
mydomain.com的请求怎么处理呢?就靠下面的file /file/local。coredns会加载/file/local中的数据,并且使用这个文件的数据来解析所有和mydomain.com有关的请求。这里需要注意,为什么coredns知道mydomain.com有关的数据都在local文件中,是因为file /file/local mydomain.com最后的mydomain.com表示local文件绑定的就是mydomain.com这个域名。
为了让用户更容易控制 Pod 中的 DNS 设置,Kubernetes v1.9 引入了一项新的 Alpha 特性(在 v1.10 中处于 Beta 阶段)。该特性在 v1.10 中被默认启用,在 v1.9 中如果想要启用此功能,集群管理员需要在 apiserver 和 kubelet 上启用 CustomPodDNS 特性,例如:“–feature-gates=CustomPodDNS=true,…”。启用了该特性之后,用户可以将 Pod 的 dnsPolicy 字段设置为 “None”,并且可以在 Pod.Spec 中添加新的字段 dnsConfig。
其中 dnsConfig 用来自定义 DNS 参数,而 dnsPolicy 用来给 Pod 选取预设的 DNS。接下来就看看可以通过哪些手段自定义 DNS。
dnsConfig 可以让操作者延伸到 Pod 内部关于 DNS 的配置,这边需要特别注意的是,我使用的字眼是 延伸 而不是 配置,这是因为通过下一节的 dnsPolicy,每个 Pod 都会有一组预设的 DNS 配置。通过 dnsConfig 我们可以继续往上叠加相关的 DNS 参数到 Pod 之中。
目前总共支持三个参数,分别是:
这三个参数对应的就是大家熟悉的 /etc/resolv.conf 里面的三个参数,下面解释一下
最主要是nameserver关键字,如果没指定nameserver就找不到DNS服务器,其它关键字是可选的。
在 Kubernetes 里面,这三个参数都包含在 dnsConfig 配置项中,而 dnsConfig 包含在 PodSpec 配置项中,因为 Pod 内所有的容器都共享相同的 Network Namespace,所以网络方面的配置都会共享。
这边提供一个简单的 yaml 示例:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-setting
namespace: default
spec:
containers:
- image: hwchiu/netutils
command:
- sleep
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu
restartPolicy: Always
dnsConfig:
nameservers:
- 1.2.3.4
searches:
- ns1.svc.cluster.local
- my.dns.search.suffix
options:
- name: ndots
value: "2"
- name: edns0
通过上述 yaml 创建 Pod 之后,通过下面的命令可以观察到容器中 DNS 配置文件中会出现额外的配置。
$ kubectl exec ubuntu-setting cat /etc/resolv.conf
nameserver 10.254.0.2
nameserver 1.2.3.4
search default.svc.cluster.local svc.cluster.local cluster.local ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0
可以看到 nameserver 多了一个 1.2.3.4,而 search 则多了 ns1.svc.cluster.local my.dns.search.suffix
这两个自定义的值,最后 options 则增加了我们示例中指定的 ndots:2 edns0。
dnsConfig 非常简单直观,如果你需要自定义 DNS 参数,就可以通过这个字段来指定。
前面提过,dnsConfig 提供的是延伸 Pod 内预设的 DNS 配置,而 dnsPolicy 就是决定 Pod 内预设的 DNS 配置有哪些。
目前总共有四个类型可以选择:
接下来针对这四个类型分别介绍。
None 表示会清除 Pod 预设的 DNS 配置,当 dnsPolicy 设置成这个值之后,Kubernetes 不会为 Pod 预先载入任何自身逻辑判断得到的 DNS 配置。因此若要将 dnsPolicy 的值设为 None,为了避免 Pod 里面没有配置任何 DNS,最好再添加 dnsConfig 来描述自定义的 DNS 参数。
Default 表示 Pod 里面的 DNS 配置继承了宿主机上的 DNS 配置。简单来说,就是该 Pod 的 DNS 配置会跟宿主机完全一致。也就是和node上的dns配置是一样的
相对于上述的 Default,ClusterFirst 是完全相反的操作,它会预先把 kube-dns(或 CoreDNS)的信息当作预设参数写入到该 Pod 内的 DNS 配置。
ClusterFirst 是预设的行为,若没有在 Pod 內特別描述 PodPolicy, 则会将 dnsPolicy 预设为 ClusterFirst。
不过ClusterFirst 还有一个冲突,如果你的 Pod 设置了 HostNetwork=true,则 ClusterFirst 就会被强制转换成 Default。
ClusterFirstWithHostNet 用途非常简单,就是为了满足使用 HostNetwork 同时使用 k8s DNS 作为我 Pod 预设 DNS 的配置。
只要將 dnsPolicy 设置为 ClusterFirstWithHostNet, 就会一律返回 k8s DNS 的 clusterIP 这种形式。
hostNetwork就可以并行存在了
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-hostnetwork-policy
namespace: default
spec:
containers:
- image: hwchiu/netutils
command:
- sleep
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu
hostNetwork: true
restartPolicy: Always
dnsPolicy: ClusterFirstWithHostNet
关于如果使用
hostNetwork: true
restartPolicy: Always
dnsPolicy: ClusterFirst
的错误这里解释一下设计上的原理以及流程:
根据上面的知识,我们知道我们可以通过配置Corefile文件来实现
例如重写规则映射添加foo.example.com到foo.default.svc.cluster.local:
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
proxy . /etc/resolv.conf
cache 30
}
通过rewrite实现, 这样在访问域名foo.example.com就是在访问域名foo.default.svc.cluster.local
一旦我们将它添加到ConfigMapvia kubectl edit或者kubectl apply,我们必须让CoreDNS知道它Corefile 已经改变了。您可以发送它SIGUSR1以告诉它重新加载优雅 - 也就是说,不会丢失服务:
$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1
我们可以增加自定义的域名解析文件
我们需要修改coredns.yaml我们用于在pod中创建其他文件的方法。要做到这一点,我们必须ConfigMap通过为区域文件添加file一行Corefile,并example.db为区域文件添加另一个键来编辑:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
file /etc/coredns/example.db example.org
proxy . /etc/resolv.conf
cache 30
}
example.db: |
; example.org test file
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
example.org. IN NS b.iana-servers.net.
example.org. IN NS a.iana-servers.net.
example.org. IN A 127.0.0.1
a.b.c.w.example.org. IN TXT "Not a wildcard"
cname.example.org. IN CNAME www.example.net.
service.example.org. IN SRV 8080 10 10 example.org.
我们还需要编辑模板规范的volumes部分Pod:
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: example.db
path: example.db
一旦我们使用了这个kubectl apply -f
,就会构建一个新的CoreDNS pod,因为卷中有新文件。以后对文件的更改不需要新的pod,只需像我们之前那样优雅地重启。
让我们来看看:
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host example.org
example.org has address 127.0.0.1
/ #