`
m635674608
  • 浏览: 5043392 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Kubernetes(k8s)如何使用kube-dns实现服务发现

 
阅读更多

大纲:

  • Kubernetes中如何发现服务

  • 如何发现Pod提供的服务
  • 如何使用Service发现服务
  • 如何使用kube-dns发现服务
  • kube-dns原理

  • 组成
  • 域名格式
  • 配置

注:本次分享内容基于Kubernetes 1.2版本!

下面从一个简单的例子开始讲解。

1、Kubernetes中如何发现服务

◆   发现Pod提供的服务

首先使用nginx-deployment.yaml文件创建一个Nginx Deployment,文件内容如图所示:

首先创建两个运行Nginx服务的Pod:

20161014201039

使用kubectl create -f nginx-deployment.yaml指令创建,这样便可以得到两个运行nginx服务的Pod。待Pod运行之后查看一下它们的IP,并在k8s集群内通过podIP和containerPort来访问Nginx服务:

获取Pod IP:

20161014201048

在集群内访问Nginx服务:

20161014201057

看到这里相信很多人会有以下疑问:

  1. 每次收到获取podIP太扯了,总不能每次都要手动改程序或者配置才能访问服务吧,要怎么提前知道podIP呢?
  2. Pod在运行中可能会重建,IP变了怎么解?
  3. 如何在多个Pod中实现负载均衡嘞?

这些问题使用k8s Service就可以解决。

◆   使用Service发现服务

下面为两个Nginx Pod创建一个Service。使用nginx-service.yaml文件进行创建,文件内容如下:

20161014201106

创建之后,仍需要获取Service的Cluster-IP,再结合Port访问Nginx服务。

Service可以将pod  IP封装起来,即使Pod发生重建,依然可以通过Service来访问Pod提供的服务。此外,Service还解决了负载均衡的问题,大家可以多访问几次Service,然后通过kubectl logs <Pod Name>来查看两个Nginx Pod的访问日志来确认。

获取IP:

20161014201113

在集群内访问Service:

20161014201119

虽然Service解决了Pod的服务发现和负载均衡问题,但存在着类似的问题:不提前知道Service的IP,还是需要改程序或配置啊。看到这里有没有感觉身体被掏空?

接下来聊聊kube-dns是如何解决上面这个问题的。

◆   使用kube-dns发现服务

kube-dns可以解决Service的发现问题,k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务。

可能有人会问如果集群中没有部署kube-dns怎么办?没关系,实际上kube-dns插件只是运行在kube-system命名空间下的Pod,完全可以手动创建它。可以在k8s源码(v1.2)的cluster/addons/dns目录下找到两个模板(skydns-rc.yaml.in和skydns-svc.yaml.in)来创建,为大家准备的完整示例文件会在分享结束后提供获取方式,PPT中只截取了部分内容。

通过skydns-rc.yaml文件创建kube-dns Pod,其中包含了四个containers,这里开始简单过一下文件的主要部分,稍后做详细介绍。

第一部分可以看到kube-dns使用了RC来管理Pod,可以提供最基本的故障重启功能。

创建kube-dns Pod,其中包含了4个containers

20161014201128

接下来是第一个容器  etcd  ,它的用途是保存DNS规则。

20161014201134

第二个容器  kube2sky ,作用是写入DNS规则。

20161014201141

第三个容器是  skydns ,提供DNS解析服务。

20161014201148

最后一个容器是  healthz ,提供健康检查功能。

20161014201154

有了Pod之后,还需要创建一个Service以便集群中的其他Pod访问DNS查询服务。通过skydns-svc.yaml创建Service,内容如下:

20161014201201

创建完kube-dns Pod和Service,并且Pod运行后,便可以访问kube-dns服务。

下面创建一个Pod,并在该Pod中访问Nginx服务:

创建之后等待kube-dns处于运行状态

20161014201212

再新建一个Pod,通过其访问Nginx服务

20161014201220

在curl-util Pod中通过Service名称访问my-nginx Service:

20161014201227

只要知道需要的服务名称就可以访问,使用kube-dns发现服务就是那么简单。

虽然领略了使用kube-dns发现服务的便利性,但相信有很多人也是一头雾水:kube-dns到底怎么工作的?在集群中启用了kube-dns插件,怎么就能通过名称访问Service了呢?

2、kube-dns原理

◆   Kube-dns组成

之前已经了解到kube-dns是由四个容器组成的,它们扮演的角色可以通过下面这张图来理解。

20161014201235

其中:

  • SkyDNS是用于服务发现的开源框架,构建于etcd之上。作用是为kubernetes集群中的Pod提供DNS查询接口。项目托管于https://github.com/skynetservices/skydns
  • etcd是一种开源的分布式key-value存储,其功能与ZooKeeper类似。在kube-dns中的作用为存储SkyDNS需要的各种数据,写入方为kube2sky,读取方为SkyDNS。项目托管于https://github.com/coreos/etcd。
  • kube2sky是k8s实现的一个适配程序,它通过名为kubernetes的Service(通过kubectl get svc可以查看到该Service,由集群自动创建)调用k8s的list和watch API来监听k8s Service资源的变更,从而修改etcd中的SkyDNS记录。代码可以在k8s源码(v1.2)的cluster/addons/dns/kube2sky/目录中找到。
  • exec-healthz是k8s提供的一种辅助容器,多用于side car模式中。它的原理是定期执行指定的Linux指令,从而判断当前Pod中关键容器的健康状态。在kube-dns中的作用就是通过nslookup指令检查DNS查询服务的健康状态,k8s livenessProbe通过访问exec-healthz提供的Http API了解健康状态,并在出现故障时重启容器。其源码位于https://github.com/kubernetes/contrib/tree/master/exec-healthz。
  • 从图中可以发现,Pod查询DNS是通过ServiceName.Namespace子域名来查询的,但在之前的示例中只用了Service名称,什么原理呢?其实当我们只使用Service名称时会默认Namespace为default,而上面示例中的my-nginx Service就是在default Namespace中,因此是可以正常运行的。关于这一点,后续再深入介绍。
  • skydns-rc.yaml中可以发现livenessProbe是设置在kube2sky容器中的,其意图应该是希望通过重启kube2sky来重新写入DNS规则。

◆   域名格式

接下来了解一下kube-dns支持的域名格式,具体为:<service_name>.<namespace>.svc.<cluster_domain>。

其中cluster_domain可以使用kubelet的–cluster-domain=SomeDomain参数进行设置,同时也要保证kube2sky容器的启动参数中–domain参数设置了相同的值。通常设置为cluster.local。那么之前示例中的my-nginx Service对应的完整域名就是my-nginx.default.svc.cluster.local。看到这里,相信很多人会有疑问,既然完整域名是这样的,那为什么在Pod中只通过Service名称和Namespace就能访问Service呢?下面来解释其中原因。

3、配置

◆   域名解析配置

为了在Pod中调用其他Service,kubelet会自动在容器中创建域名解析配置(/etc/resolv.conf),内容为:

20161014201244

感兴趣的可以在网上查找一些resolv.conf的资料来了解具体的含义。之所以能够通过Service名称和Namespace就能访问Service,就是因为search配置的规则。在解析域名时会自动拼接成完整域名去查询DNS。

刚才提到的kubelet –cluster-domain参数与search的具体配置是相对应的。而kube2sky容器的–domain参数影响的是写入到etcd中的域名,kube2sky会获取Service的名称和Namespace,并使用–domain参数拼接完整域名。这也就是让两个参数保持一致的原因。

◆   NS相关配置

kube-dns可以让Pod发现其他Service,那Pod又是如何自动发现kube-dns的呢?在上一节中的/etc/resolv.conf中可以看到nameserver,这个配置就会告诉Pod去哪访问域名解析服务器。

20161014201251

相应的,可以在之前提到的skydns-svc.yaml中看到spec.clusterIP配置了相同的值。通常来说创建一个Service并不需要指定clusterIP,k8s会自动为其分配,但kube-dns比较特殊,需要指定clusterIP使其与/etc/resolv.conf中的nameserver保持一致。

修改nameserver配置同样需要修改两个地方,一个是kubelet的–cluster-dns参数,另一个就是kube-dns Service的clusterIP。

4、总结

接下来重新梳理一下本文的主要内容:

  • 在k8s集群中,服务是运行在Pod中的,Pod的发现和副本间负载均衡是我们面临的问题。
  • 通过Service可以解决这两个问题,但访问Service也需要对应的IP,因此又引入了Service发现的问题。
  • 得益于kube-dns插件,我们可以通过域名来访问集群内的Service,解决了Service发现的问题。
  • 为了让Pod中的容器可以使用kube-dns来解析域名,k8s会修改容器的/etc/resolv.conf配置。

 

有了以上机制的保证,就可以在Pod中通过Service名称和namespace非常方便地访问对应的服务了。

 

https://www.kubernetes.org.cn/273.html

分享到:
评论

相关推荐

    kubernetes-server-linux-amd64.tar.gz

    6. **kube-proxy**:在每个节点上运行,实现服务的网络路由和负载均衡。 7. **container runtime**:例如Docker或CRI-O,用于实际运行容器。 现在,让我们深入探讨如何在Linux AMD64系统上部署这个压缩包: 1. **...

    kubernetes-k8s v1.21.2版本镜像包

    IT运维、k8s、kubernetes搭建(包含kube-apiserver-v1.21.2、kube-controller-manager-v1.21.2、kube-scheduler-v1.21.2、coredns、pause、etcd、calico。。。。)

    kubernetes-v1.20.6+calio-v3.20.0镜像包

    说明:kubernetes-v1.20.6镜像完整包,包含 k8s.gcr.io/kube-apiserver:v...k8s.gcr.io/coredns:1.7.0 calico/pod2daemon-flexvol:v3.20.0 calico/node:v3.20.0 calico/cni:v3.20.0 calico/kube-controllers:v3.20.0

    安装k8s 1.28 所需的离线镜像包

    部署k8s1.28集群所需离线镜像包,已经为大家准备好了,大家有需要可以自行下载,下载后部署的方法,在主页k8s专栏的文章中有详细说明,如果大家有疑问可以查看文章,或者私信我,我会尽快回复,谢谢大家 registry....

    搭建k8s高可用集群所需容器

    alpine-keepalived.tar haproxy.tar kubernetes-dashboard-amd64.tar k8s-dns-dnsmasq-nanny-amd64.tar k8s-dns-kube-dns-amd64.tar k8s-dns-sidecar-amd64.tar registry.tar 搭建k8s高可用集群所需容器

    kube-flannel.yml

    在Kubernetes(K8s)集群中,网络通信是核心组成部分,而kube-flannel.yml则扮演着至关重要的角色。它是Kubernetes网络插件Flannel的配置文件,用于实现跨节点的Pod通信。本文将深入解析kube-flannel.yml的构成和...

    kubeadm依赖:kube-apiserver:v1.23.0、kube-controller-manager:v1.23等

    kubeadm依赖镜像: registry.aliyuncs....registry.aliyuncs.com/google_containers/coredns:v1.8.6 操作: 镜像包上传到集群的各个节点后执行导入镜像脚本 chmod +x load_images.sh ./load_images.sh

    kube-controller-manager-v1.18.4.tar.gz

    │ ├── coredns-1.6.7.tar.gz │ ├── kube-proxy-v1.18.4.tar.gz │ ├── node-v3.15.1.tar.gz │ ├── pause-3.2.tar.gz │ └── pod2daemon-flexvol-v3.15.1.tar.gz ├── save.sh └── server ├...

    kube-proxy-v1.18.4.tar.gz

    │ ├── coredns-1.6.7.tar.gz │ ├── kube-proxy-v1.18.4.tar.gz │ ├── node-v3.15.1.tar.gz │ ├── pause-3.2.tar.gz │ └── pod2daemon-flexvol-v3.15.1.tar.gz ├── save.sh └── server ├...

    kube-controllers-v3.15.1.tar.gz

    │ ├── coredns-1.6.7.tar.gz │ ├── kube-proxy-v1.18.4.tar.gz │ ├── node-v3.15.1.tar.gz │ ├── pause-3.2.tar.gz │ └── pod2daemon-flexvol-v3.15.1.tar.gz ├── save.sh └── server ├...

    kubernetes-v1.20.6+calio-v3.18.0镜像包

    说明:kubernetes-v1.20.6镜像完整包,包含 k8s.gcr.io/kube-apiserver:v...k8s.gcr.io/coredns:1.7.0 calico/pod2daemon-flexvol:v3.18.0 calico/node:v3.18.0 calico/cni:v3.18.0 calico/kube-controllers:v3.18.0

    kubernetes-server-linux-amd64-1.19.3.tar.gz

    Kubernetes(简称K8s)是当前最流行的容器编排系统,它提供了一种高效、灵活的方式来管理跨多个主机的容器化应用。本文将详细介绍如何使用“kubernetes-server-linux-amd64-1.19.3.tar.gz”这个二进制安装包来部署...

    kube-apiserver-v1.18.4.tar.gz

    │ ├── coredns-1.6.7.tar.gz │ ├── kube-proxy-v1.18.4.tar.gz │ ├── node-v3.15.1.tar.gz │ ├── pause-3.2.tar.gz │ └── pod2daemon-flexvol-v3.15.1.tar.gz ├── save.sh └── server ├...

    Kubernetes v1.23.5 全离线资源安装包

    coredns-v1.8.6.tar etcd-3.5.1-0.tar 安装包: Docker containerd.io-1.3.7-3.1.el7.x86_64.rpm container-selinux-2.107-3.el7.noarch.rpm docker-ce-19.03.9-3.el7.x86_64.rpm docker-ce-cli-19.03.9-3.el7.x86_...

    kubernetes-client-linux-amd64.tar.gz

    7. **网络和连接**: Kubernetes的Service概念提供了一种抽象,使得Pods可以通过DNS名称相互访问,`kubectl expose`命令可以将Pod公开为Service。 8. **配置管理**: `kubectl config`命令用于管理用户的kubeconfig...

    安装k8s和kubeedge手动下载的一些文件

    在本文中,我们将深入探讨如何手动安装Kubernetes (k8s) 和 KubeEdge 这两个先进的云原生技术,并了解这两个系统的核心组件及其交互方式。Kubernetes 是一个开源的容器编排平台,用于自动化应用部署、扩展和管理。而...

    kubernetes 1.20.4 必需镜像

    包含kubernetes v1.20.4必需镜像,有问题私信我 docker load -i kube-apiserver-v1.20.4.tar docker load -i kube-controller-manager-v1.20.4.tar docker load -i kube-scheduler-v...docker load -i coredns-1.7.0.tar

    k8s.1-18-8.tar.gz

    【描述】中提到的“k8s集群二进制包”意味着这个压缩文件包含了Kubernetes集群的所有必要二进制文件,如kube-apiserver、kube-controller-manager、kube-scheduler、kubelet和kube-proxy等,这些是Kubernetes集群的...

    K8s-1.22.0镜像包一键拉取

    k8s.gcr.io/coredns/coredns v1.8.4 kubernetesui/metrics-scraper v1.0.7 k8s.gcr.io/etcd 3.5.0-0 eipwork/kuboard-agent v3 k8s.gcr.io/kube-scheduler v1.22.0 k8s.gcr.io/kube-proxy v1.22.0 k8s.gcr.io/kube-...

    kube-scheduler-v1.18.4.tar.gz

    │ ├── coredns-1.6.7.tar.gz │ ├── kube-proxy-v1.18.4.tar.gz │ ├── node-v3.15.1.tar.gz │ ├── pause-3.2.tar.gz │ └── pod2daemon-flexvol-v3.15.1.tar.gz ├── save.sh └── server ├...

Global site tag (gtag.js) - Google Analytics