浅谈Kube-DNS


场景

使用argo时遇到的问题,argoWorkFlow和argo-Events是两个不同的组件,他们分别在不同的命名空间中。此时argo-events命名空间中的Pod需要访问到argoWrokFlow的minio组件,以下以A代替argo-evnets命名空间B代替命名空间argo


一、Kube-DNS

1.Kube-DNS整体架构介绍

集群中定义的每个 Service (包括 DNS 服务器自身)都被赋予一个 DNS 名称。 默认情况下,客户端 Pod 的 DNS 搜索列表会包含 Pod 自身的名字空间和集群 的默认域。它由三个容器组成:kubedns,dnsmasq,sidecar。它将DNS记录直接保存在内存中,提高了查询性能。

  1. kubedns容器:监控kubernetes的Server资源的变化,根据Server的名称和ip地址生成DNS记录然后将DNS记录保存到内存中。
  2. dnsmasq容器:从kubedns中获取DNS记录,提供DNS缓存。为客户端容器提供DNS查询服务。
  3. sidecar:提供对kubedns和dnsmasq服务的健康检测功能

在这里。插入图片描述在这里插入图片描述[https://www.cnblogs.com/allcloud/p/7614123.html]

  1. kubedns:提供了原来 kube2sky + etcd + skyDNS 的功能,可以单独对外提供 DNS 查询服务
  2. dnsmasq: 一个轻量级的 DNS 服务软件,可以提供 DNS 缓存功能。kubeDNS 模式下,dnsmasq 在内存中预留一块大小(默认是 1G)的地方,保存当前最常用的 DNS 查询记录,如果缓存中没有要查找的记录,它会到 kubeDNS 中查询,并把结果缓存起来
  3. 每种模式都可以运行额外的 exec-healthz 容器对外提供 health check 功能,证明当前 DNS 服务是正常的。
    exec-healthz:运行某个命令,根据结果来对外提供 /healthz 结果

2.kubedns功能验证

如果我们此前已经有了部署了许多pod和服务,并且在Kubelet 启动配置文件加入了 --cluster-dns=10.254.0.2 --cluster-domain=cluster.local 参数,则可以进入某个pod中的容器内查看其/etc/resolv.conf 文件
代码如下(示例):

[root@k8s-master ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
search localdomain
nameserver 192.168.160.2
如上所示,根据kubelet的启动参数,kubelet会在每个pod中设置DNS域名解析文件/etc/resolv.conf,加入了nameser和search搜索域。最后应用程序就能够像访问网站一样,仅仅通过服务的名字就能访问到服务了。

Service

  • 域名格式 具体为:<service_name>..svc.<cluster_domain>。
    其中cluster_domain可以使用kubelet的–cluster-domain=SomeDomain参数进行设置,

    A/AAAA 记录
    
    “普通” 服务(除了无头服务)会以 my-svc.my-namespace.svc.cluster-domain.example
    这种名字的形式被分配一个 DNS A 或 AAAA 记录,取决于服务的 IP 协议族。 该名称会解析成对应服务的集群 IP。
    
    “无头(Headless)” 服务(没有集群 IP)也会以
    my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被指派一个 DNS A
    或 AAAA 记录, 具体取决于服务的 IP 协议族。 与普通服务不同,这一记录会被解析成对应服务所选择的 Pod 集合的 IP。
    客户端要能够使用这组 IP,或者使用标准的轮转策略从这组 IP 中进行选择。
    

Kubernetes 目前在 Pod 定义中支持两个 DNS 策略:Default和ClusterFirst,dnsPolicy缺省为ClusterFirst:
如果dnsPolicy设置为Default,那么域名解析配置会从 Pod 所在节点继承而来。注意,本文所述功能在dnsPolicy设置为Default时无效。
如果dnsPolicy设置为ClusterFirst,DNS 查询会被发送到 kube-dns 服务。kube-dns 服务负责相应以集群域名为后缀(例如.cluster.local)的查询。其他的域名查询(例如 www.kubernetes.io )会被转发给来自节点定义的上级域名服务器。创建如下pod 并进入容器 查看其/etc/resolv.conf ,并创建一个service 并通过nslookup进行测试。nslookup可以查询dns记录,查看域名是否正常。
先修改每个Node上的Kubelet启动参数
–cluster_dns=10.96.0.10 为DNS服务的ClusterIP地址
–cluster_domain=cluster.local 为DNS服务中设置的域名

# vim /etc/kubernetes/kubelet
KUBELET_ARGS="--cluster_dns=10.96.0.10 --cluster_domain=cluster.local"

```c
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
  
/ # cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
/ # 
[root@k8s-master ~]# vi redis-master-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  selector:
    name: redis-master
  ports:
  - port: 6379
    targetPort: 6379

[root@k8s-master zqa]# kubectl exec busybox -- nslookup redis-master
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      redis-master
Address 1: 10.105.212.249 redis-master.default.svc.cluster.local
[root@k8s-master zqa]# 
如上可以知道当在同一命名空间下时,pod可以通过域名访问同命名空间下的其他service。

二、ExternalName Service

通过上面的实验我们得知同一命名空间内可以通过服务域名直接访问其ip。不同命名空间我们可以通过ExternalName完成访问。
使用ExternalName将外部服务映射到内部服务。通过返回CNAME和它的值,可以将服务映射到externalName字段的内容上。

代码如下(示例):

kind: Service
apiVersion: v1
metadata:
  name: minio
  namespace: argo-events
spec:
  type: ExternalName
  externalName: minio.argo.svc.cluster.local
  ports:
  -  port: 9000

如下图总流程图所示
  1. 首先在由于mino在argo命名空间中,在argo-events的pod无法通过牌ping mino:9000,访问argo命名空间的service。我们通过在argo-events命名空间中创建一个ExternalNameService。
  2. 当使用kubectl创建该service的时候,apiServer会做一些与其他组件配合通信的功能(略),kubelet通过watch机制会创建Service,会对应mino.argo-events.svc.cluster.local记录留到kube-dns中。
  3. 当命名空间A中的Pod查找集群的minio.argo-events.svc.cluster.local时,会先从dnsmasq内存中查找,找不到则会去kubedns查找,如果在里面找到了就会将其记录加入内存。
  4. KubeDns返回的是minio.argo.svc.cluster.local对应的ip地址。也就是当A命名空间的pod访问minio时访问的是B命名空间的minio。

在这里插入图片描述

总结

命名空间的作用:是建立一些互相分隔的作用域,把一些全局实体分隔开来。要在不同命名空间相互访问,并且以不定死ip的方式访问。即不根据cluster ip/pod ip的访问pod,可以通过K8S自带的域名解析对其pod 暴露的endpoint 进行访问。kubernetes以插件的方式引入了DNS系统,利用DNS对Service进行一个映射,这样我们在APP中直接使用域名进行引用,避免了之前的变量泛滥问题,也避免了创建顺序的尴尬局面。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值