k8s中hostname,hosts⽂件,DNS和代理问题,service和pod的访问问题全栈⼯程师开发⼿册 (作者:栾鹏)
验证⼀个域名的ip地址可以使⽤
nslookup  李宗翰个人资料
在kubernets中不同命名空间的服务相互访问
涉及到的是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会⾃动创建⼀个形如<service-name>.<namespace-name>.svc.cluster.local的DNS项。如果集中另⼀个服务调⽤这个服务时,仅仅指定了<service-name>,那么Kubernetes会使⽤调⽤⽅所在的Namespace将<service-name>补全。因此如果调⽤⽅和被调⽤⽅不处于同⼀个Namespace,你必须使⽤包含Namespace的service name
修改pod的hostname和subdomain
可以在 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。
使⽤ HostAliases 向 Pod /etc/hosts ⽂件添加条⽬
当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts ⽂件中添加条⽬,可以在 Pod 级别覆盖对主机名的解析。在 1.7 版本,⽤户可以通过 PodSpec 的 HostAliases 字段来添加这些⾃定义的条⽬。
建议通过使⽤ HostAliases 来进⾏修改,因为该⽂件由 Kubelet 管理,并且可以在 Pod 创建/重启过程中被重写。
默认 hosts ⽂件内容
让我们从⼀个 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 和主机名称。
通过 HostAliases 增加额外的条⽬
除了默认的样板内容,我们可以向 hosts ⽂件添加额外的条⽬,将 foo.local、 bar.local 解析为127.0.0.1,将 、
< 解析为 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:
- ""
-
""
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.
10.1.2.
在最下⾯额外添加了⼀些条⽬。
限制
在 1.7 版本,如果 Pod 启⽤ hostNetwork,那么将不能使⽤这个特性,因为 kubelet 只管理⾮ hostNetwork 类型 Pod 的 hosts ⽂件。⽬前正在讨论要改变这个情况。
为什么 Kubelet 管理 hosts⽂件?
kubelet 管理 Pod 中每个容器的 hosts ⽂件,避免 Docker 在容器已经启动之后去 修改 该⽂件。
因为该⽂件是托管性质的⽂件,⽆论容器重启或 Pod 重新调度,⽤户修改该 hosts ⽂件的任何内容,都会在 Kubelet 重新安装后被覆盖。因此,不建议修改该⽂件的内容。
Pod 之间是如何到彼此呢 - DNS Service Discovery
介绍 DNS 是什么?
DNS,全名为 Domain Name System。DNS 会有⼀张表格,记录每个 domain name 相对应的 IP 位址。如此,我们不再需要去记录该服务的 IP address,⽽是可以透过该服务的域名来连接到该服务。以 le.tw 为例,当我们在浏览器输⼊
如果想知道某个特定的域名相对应的 IP 位址,可以在终端机输⼊ host 指令,
介绍 Kubernetes 內部插件 kube-dns
在 /etc/kubernetes/addons 资料夹底下,除了可以看到 kube-dns 的相关设定档外,也可以看到 Kubernetes 其他套件的设定档。
kube-dns 如何运作
若是与上上图⽐对,会发现 /f 中的 nameserver 指向的 IP 位置,就是 kube-dns 的 Service。或者是dnsmasq的service
配置Kubernetes DNS服务kube-dns
DNS服务有很多中⽅式, 官⽅推荐安装的是kube-dns, 我们这⾥先介绍这个. 如果你的k8s上dns服务不是使⽤这个插件进⾏管理的,可以跳过.
前提要求
Kubernetes 1.6 及以上版本。
集必须使⽤ kube-dns 插件进⾏配置。
kube-dns 介绍
从 Kubernetes v1.3 版本开始,使⽤ [cluster add-on 插件管理器回⾃动启动内置的 DNS。
Kubernetes DNS pod 中包括 3 个容器:
kubedns:kubedns 进程监视 Kubernetes master 中的 Service 和 Endpoint 的变化,并维护内存查结构来服务DNS请求。
dnsmasq:dnsmasq 容器添加 DNS 缓存以提⾼性能。
sidecar:sidecar 容器在执⾏双重健康检查(针对 dnsmasq 和 kubedns)时提供单个健康检查端点(监听在10054端⼝)。
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-service-ip> 标志配置的 DNS 传递给3个容器的每个容器。
DNS 名称也需要域名。本地域可以使⽤标志 --cluster-domain = <default-local-domain> 在 kubelet 中配置。
Kubernetes集DNS服务器基于 SkyDNS 库。它⽀持正向查(A 记录),服务查(SRV 记录)和反向 IP 地址查(PTR 记录)kube-dns ⽀持的 DNS 格式
kube-dns 将分别为 service 和 pod ⽣成不同格式的 DNS 记录。
Service
A记录:⽣成-namespace.svc.cluster.local域名,解析成 IP 地址,分为两种情况:
普通 Service:解析成 ClusterIP
Headless Service:解析为指定 Pod 的 IP 列表
康天庥李俊毅
SRV记录:为命名的端⼝(普通 Service 或 Headless Service)⽣成 _my-port-name._-
namespace.svc.cluster.local 的域名
Pod
A记录:⽣成域名 -namespace.pod.cluster.local
继承节点的 DNS
运⾏ Pod 时,kubelet 将预先配置集 DNS 服务器到 Pod 中,并搜索节点⾃⼰的 DNS 设置路径。如果节点能够解析特定于较⼤环境的DNS 名称,那么 Pod 应该也能够解析。请参阅下⾯的已知问题以了解警告。
⾃定义pod中的dns服务器
如果您不想要这个,或者您想要为 Pod 设置不同的 DNS 配置,您可以给 kubelet 指定 --resolv-conf 标志。将该值设置为 “” 意味着Pod 不继承 DNS。将其设置为有效的⽂件路径意味着 kubelet 将使⽤此⽂件⽽不是 /f ⽤于 DNS 继承。
配置存根域和上游 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 数组。
注意:如果指定,则指定的值会替换掉被默认从节点的
/f 中获取到的 nameserver。限制:最多可以指定三
个上游 nameserver。
字段格式描述建筑遗产
注意,集管理员不希望覆盖节点的上游 nameserver,所以他们不会指定可选的 upstreamNameservers 字段。
下表描述了如何将具有特定域名的查询映射到其⽬标DNS服务器:
域名响应查询的服务器
kubernetes.default.svc.cluster.local kube-dns
起亚k3说明书
foo.acme.local⾃定义 DNS (1.2.3.4)
widget上游 DNS (8.8.8.8 或 8.8.4.4)
对 Pod 的影响
Kubernetes ⽬前在 Pod 定义中⽀持两个 DNS 策略:Default 和 ClusterFirst,dnsPolicy 默认为 ClusterFirst。如果将 dnsPolicy 设
置为 Default,域名解析配置则完全从 Pod 所在的节点(/f)继承⽽来。
如果包含⾃定义DNS,则逻辑图为