k8s 服务发现和负载均衡:Service |
您所在的位置:网站首页 › k8s的service负载均衡策略 › k8s 服务发现和负载均衡:Service |
四层负载均衡 Service
在 kubernetes 中,Pod 是有生命周期的,如果 Pod 重启它的 IP 很有可能会发生变化。如果我们的服务都是将 Pod 的 IP 地址写死,Pod 挂掉或者重启,和刚才重启的 pod 相关联的其他服务将会找不 到它所关联的 Pod,为了解决这个问题,在 kubernetes 中定义了 service 资源对象,Service 定义了 一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service 是一组 Pod 的 逻辑集合,这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector 实现的。
1、pod ip 经常变化,service 是 pod 的代理,我们客户端访问,只需要访问 service,就会把请求 代理到 Pod 2、pod ip 在 k8s 集群之外无法访问,所以需要创建 service,这个 service 可以在 k8s 集群外访 问的。 Service 概述service 是一个固定接入层,客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端pod,这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件,就是 kubernetes 的 dns 服 务(不同 kubernetes 版本的 dns 默认使用的也是不一样的,1.11 之前的版本使用的是 kubeDNs,较 新的版本使用的是 coredns),service 的名称解析是依赖于 dns 附件的,因此在部署完 k8s 之后需要再部署 dns 附件,kubernetes 要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel, calico 等)。每个 K8s 节点上都有一个组件叫做 kube-proxy,kube-proxy 这个组件将始终监视着 apiserver 中有关 service 资源的变动信息,需要跟 master 之上的 apiserver 交互,随时连接到 apiserver 上获取任何一个与 service 资源相关的资源变动状态,这种是通过 kubernetes 中固有的一种 请求方法 watch(监视)来实现的,一旦有 service 资源的内容发生变动(如创建,删除),kube- proxy 都会将它转化成当前节点之上的能够实现 service 资源调度,把我们请求调度到后端特定的 pod 资源之上的规则,这个规则可能是 iptables,也可能是 ipvs,取决于 service 的实现方式。 Service 工作原理 k8s 在创建 Service 时,会根据标签选择器 selector(lable selector)来查找 Pod,据此创建与 Service 同名的 endpoint 对象,当 Pod 地址发生变化时,endpoint 也会随之发生变化,service 接 收前端 client 请求的时候,就会通过 endpoint,找到转发到哪个 Pod 进行访问的地址。(至于转发到哪 个节点的 Pod,由负载均衡 kube-proxy 决定) kubernetes 集群中有三类 IP 地址 1、Node Network(节点网络):物理节点或者虚拟节点的网络,如 ens33 接口上的网路地址 ~]# ip addr 2: ens33: mtu 1500 qdisc pfifo_fast state UP link/ether 00:0c:29:87:60:d5 brd ff:ff:ff:ff:ff:ff inet 192.168.1.63/24 brd 192.168.1.255 scope global noprefixroute ens33 2、Pod network(pod 网络),创建的 Pod 具有的 IP 地址 ]# kubectl get pods -o wide NAME READY STATUS IP NODE frontend-h78gw 1/1 Running 10.244.187.76 god62 Node Network 和 Pod network 这两种网络地址是我们实实在在配置的,其中节点网络地址是配 置在节点接口之上,而 pod 网络地址是配置在 pod 资源之上的,因此这些地址都是配置在某些设备之上 的,这些设备可能是硬件,也可能是软件模拟的 3、Cluster Network(集群地址,也称为 service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在 service 的规则当中。 kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 21d nginx NodePort 10.105.245.139 3000:31003/TCP 7d23h #查看定义 Service 资源需要的字段有哪些?kubectl explain service FIELDS: apiVersion . #service 资源使用的 api 组 kind #创建的资源类型 metadata #定义元数据 spec #查看 service 的 spec 字段如何定义?clusterIP . #动态分配的地址,也可以自己在创建的时候指定,创建之后就改不了了 ports #定义 service 端口,用来和后端 pod 建立联系 publishNotReadyAddresses selector #通过标签选择器选择关联的 pod 有哪些 sessionAffinity sessionAffinityConfig #service 在实现负载均衡的时候还支持 sessionAffinity,sessionAffinity 什么意思?会话联系,默认是 none,随机调度的(基于 iptables 规则调度的);如果我们定义sessionAffinity 的 client ip,那就表示把来自同一客户端的 IP 请求调度到同一个 pod 上 type #定义 service 的类型 Service 的四种类型kubectl explain service.spec.type DESCRIPTION: type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. 1、ExternalName: 适用于 k8s 集群内部容器访问外部资源,它没有 selector,也没有定义任何的端口和Endpoint。以下 Service 定义的是将 prod 名称空间中的 my-service 服务映射到 my.database.example.com kind: Service apiVersion: v1 metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com 当查询主机 my-service.prod.svc.cluster.local 时,群集 DNS 将返回值为my.database.example.com 的 CNAME 记录。 2、ClusterIP: 通过 k8s 集群内部 IP 暴露服务,选择该值,服务只能够在集群内部访问,这也是默认的 ServiceType。3、NodePort: 通过每个 Node 节点上的 IP 和静态端口暴露 k8s 集群内部的服务。通过请求 :可以把请求代理到内部的 pod。Client----->NodeIP:NodePort---- ->Service Ip:ServicePort----->PodIP:ContainerPort。 4、LoadBalancer: 使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务 和 ClusterIP 服务。 Service 的端口 kubectl explain service.spec.portsname #定义端口的名字 nodePort |#宿主机上映射的端口,比如一个 Web 应用需要被 k8s 集群之外的其他用户访问,那么需要配置 type=NodePort,若配置 nodePort=30001,那么其他机器就可以通过浏览器访问 scheme://k8s 集 群中的任何一个节点 ip:30001 即可访问到该服务,例如 http://192.168.1.63:30001。如果在 k8s 中 部署 MySQL 数据库,MySQL 可能不需要被外界访问,只需被内部服务访问,那么就不需要设置 NodePort port -required- #service 的端口,这个是 k8s 集群内部服务可访问的端口 protocol targetPort. # targetPort 是 pod 上的端口,从 port 和 nodePort 上来的流量,经过 kube-proxy 流入到后端 pod 的 targetPort 上,最后进入容器。与制作容器时暴露的端口一致(使用 DockerFile 中的 EXPOSE),例如官方的 nginx 暴露 80 端口。 创建 Service:type 类型是 ClusterIPdocker load -I nginx.tar.gzcat pod_test.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - image: nginx name: my-nginx ports: - containerPort: 80 #pod容器中暴露的端口 kubectl apply -f pod_test.yaml kubectl get pods -l run=my-nginx -o wide curl ip 看主页 Welcome to nginx! kubectl exec -it my-nginx-5b56ccd65f-cwqbg -- /bin/bash 需要注意的是,pod 虽然定义了容器端口,但是不会使用调度到该节点上的 80 端口,也不会使用任 何特定的 NAT 规则去路由流量到 Pod 上。 这意味着可以在同一个节点上运行多个 Pod,使用相同的容 器端口,并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。 误删除其中一个 Pod: kubectl delete pods my-nginx-5b56ccd65f-cwqbg kubectl get pods -l run=my-nginx -o wide kubectl get pods -l run=my-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-5b56ccd65f-d7j7v 1/1 Running 0 21s 10.244.187.103 god62 my-nginx-5b56ccd65f-h2kjl 1/1 Running 0 14m 10.244.209.135 god64 通过上面可以看到重新生成了一个 pod :my-nginx-5b56ccd65f-7xzr4,ip 是 10.244.187.102,在 k8s 中创建 pod,如果 pod 被删除了,重新生成的 pod ip 地址会发生变化,所 以需要在 pod 前端加一个固定接入层。接下来创建 service: 创建 Service cat service_test.yamlapiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: type: ClusterIP ports: - port: 80 #service 的端口,暴露给 k8s 集群内部服务访问 protocol: TCP #通过ip和端口代理 targetPort: 80 #pod 容器中定义的端口 selector: run: my-nginx #选择拥有 run=my-nginx 标签的 pod 上述 yaml 文件将创建一个 Service,具有标签 run=my-nginx 的 Pod,目标 TCP 端口 80,并 且在一个抽象的 Service 端口(targetPort:容器接收流量的端口;port:抽象的 Service 端口,可 以使任何其它 Pod 访问该 Service 的端口)上暴露。 kubectl apply -f service_test.yaml kubectl get svc -l run=my-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx ClusterIP 10.102.215.115 80/TCP 3m34s #在 k8s 控制节点访问 service 的 ip:端口就可以把请求代理到后端 pod curl 10.102.215.115:80 Welcome to nginx!#通过上面可以看到请求 service IP:port 跟直接访问 pod ip:port 看到的结果一样,这就说明 service 可以把请求代理到它所关联的后端 pod 注意:上面的 10.102.215.115:80 地址只能是在 k8s 集群内部可以访问,在外部无法访问,比方说 我们想要通过浏览器访问,那么是访问不通的,如果想要在 k8s 集群之外访问,是需要把 service type 类型改成 nodePort 的 #通过上面可以看到请求 service IP:port 跟直接访问 pod ip:port 看到的结果一样,这就说明 service 可以把请求代理到它所关联的后端 pod 注意:上面的 10.102.215.115:80 地址只能是在 k8s 集群内部可以访问,在外部无法访问,比方说 我们想要通过浏览器访问,那么是访问不通的,如果想要在 k8s 集群之外访问,是需要把 service type 类型改成 nodePort 的 #查看 service 详细信息 kubectl describe svc my-nginx kubectl get ep my-nginx NAME ENDPOINTS AGE my-nginx 10.244.187.106:80,10.244.209.138:80 6m8s service 可以对外提供统一固定的 ip 地址,并将请求重定向至集群中的 pod。其中“将请求重定向 至集群中的 pod”就是通过 endpoint 与 selector 协同工作实现。selector 是用于选择 pod,由 selector 选择出来的 pod 的 ip 地址和端口号,将会被记录在 endpoint 中。endpoint 便记录了所有 pod 的 ip 地址和端口号。当一个请求访问到 service 的 ip 地址时,就会从 endpoint 中选择出一个 ip地址和端口号,然后将请求重定向至 pod 中。具体把请求代理到哪个 pod,需要的就是 kube-proxy 的 轮询实现的。service 不会直接到 pod,service 是直接到 endpoint 资源,就是地址加端口,再由 endpoint 再关联到 pod。 service 只要创建完成,我们就可以直接解析它的服务名,每一个服务创建完成后都会在集群 dns 中 动态添加一个资源记录,添加完成后我们就可以解析了,资源记录格式是: SVC_NAME.NS_NAME.DOMAIN.LTD. 服务名.命名空间.域名后缀 集群默认的域名后缀是 svc.cluster.local. 就像我们上面创建的 my-nginx 这个服务,它的完整名称解析就是 my-nginx.default.svc.cluster.local # kubectl exec -it my-nginx-5b56ccd65f-7xzr4 -- /bin/bash root@my-nginx-5b56ccd65f-7xzr4:/# curl my-nginx.default.svc.cluster.local Welcome to nginx!创建 Service:type 类型是 NodePort cat pod_nodeport.yamlapiVersion: apps/v1 kind: Deployment metadata: name: my-nginx-nodeport spec: selector: matchLabels: run: my-nginx-nodeport replicas: 2 template: metadata: labels: run: my-nginx-nodeport spec: containers: - name: my-nginx-nodeport-contauber image: nginx ports: - containerPort: 80 kubectl apply -f pod_nodeport.yaml #查看 pod 是否创建成功 kubectl get pods -l run=my-nginx-nodeport NAME READY STATUS RESTARTS AGE my-nginx-nodeport-6cb5fff859-9c4lm 1/1 Running 0 54s my-nginx-nodeport-6cb5fff859-lqdnc 1/1 Running 0 54s 创建 service,代理 podcat service_nodeport.yaml apiVersion: v1 kind: Service metadata: name: my-nginx-nodeport labels: run: my-nginx-nodeport spec: type: NodePort ports: - port: 80 protocol: TCP targetPort: 80 selector: 30380 run: my-nginx-nodeport kubectl apply -f service_nodeport.yaml #查看刚才创建的 service kubectl get svc -l run=my-nginx-nodeport NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx-nodeport NodePort 10.100.132.187 80:30380/TCP 2m36s curl 10.100.132.187 Welcome to nginx! 10.100.132.187是 k8s 集群内部的 service ip 地址,只能在 k8s 集群内部访问,在集群外无法访问。 #在集群外访问 service curl 192.168.172.163:30380 过程就是192.168.172.163:30380。---> 10.100.132.187:80(kubectl get svc -l run=my-nginx-nodeport)----> pod ip:container port 随机生成的如下 创建 Service:type 类型是 ExternalName应用场景:跨名称空间访问 需求:default 名称空间下的 client 服务想要访问 nginx-ns 名称空间下的 nginx-svc 服务 docker load -I busybox.tar.gz. 工作节点 cat client.yaml apiVersion: apps/v1 kind: Deployment metadata: name: client spec: replicas: 1 selector: matchLabels: app: busybox template: metadata: labels: app: busybox spec: containers: - name: busybox image: busybox command: ["/bin/sh","-c","sleep 36000"] kubectl apply -f client.yaml #. cat client_svc.yaml apiVersion: v1 kind: Service metadata: name: client-svc spec: type: ExternalName externalName: nginx-svc.nginx-ns.svc.cluster.local ports: - name: http port: 80 targetPort: 80 #该文件中指定了到 nginx-svc 的软链,让使用者感觉就好像调用自己命名空间的服务一样。 #查看 pod 是否正常运行 kubectl get pods | grep client-76b6556d97-xqkzk client-76b6556d97-xqkzk 1/1 Running 0 64m kubectl apply -f client_svc.yaml kubectl apply -f client_svc.yaml #创建名称空间 kubectl create ns nginx-ns cat server_nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: nginx-ns spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent kubectl apply -f server_nginx.yaml #查看 pod 是否创建成功 kubectl get pods -n nginx-ns NAME READY STATUS RESTARTS AGE nginx-7cf7d6dbc8-glps2 1/1 Running 0 79m cat nginx_svc.yaml apiVersion: v1 kind: Service metadata: name: nginx-svc namespace: nginx-ns spec: selector: app: nginx ports: - name: http protocol: TCP port: 80 targetPort: 80 kubectl apply -f nginx_svc.yaml #登录到 client pod kubectl exec -it client-76b6556d97-xqkzk -- /bin/sh wget -q -O - client-svc.default.svc.cluster.local wget -q -O - nginx-svc.nginx-ns.svc.cluster.local k8s 映射外部服务分享场景 1:k8s 集群引用外部的 mysql 数据库 在 god62 上安装 mysql 数据库: yum install mariadb-server.x86_64 -y systemctl start mariadb cat mysql_service.yaml apiVersion: v1 kind: Service metadata: name: mysql pec:kubectl apply -f mysql_service.yaml type: ClusterIP ports: - port: 3306 kubectl apply -f mysql_service.yaml kubectl get svc | grep mysql mysql ClusterIP 10.109.176.8 3306/TCP 49s kubectl describe svc mysql Name: mysql Namespace: default Labels: Annotations: Selector: Type: ClusterIP IP Families: IP: 10.109.176.8 IPs: 10.109.176.8 Port: 3306/TCP TargetPort: 3306/TCP Endpoints: #还没有endpoint Session Affinity: None Events: cat mysql_endpoint.yaml apiVersion: v1 kind: Endpoints metadata: name: mysql subsets: - addresses: - ip: 192.168.172.162 ports: - protocol: TCP port: 3306 kubectl describe svc mysql Name: mysql Namespace: default Labels: Annotations: Selector: Type: ClusterIP IP Families: IP: 10.109.176.8 IPs: 10.109.176.8 Port: 3306/TCP TargetPort: 3306/TCP Endpoints: 192.168.172.162:3306 #这个 定义的外部数据库,name与之对应 Session Affinity: None Events: 上面配置就是将外部 IP 地址和服务引入到 k8s 集群内部,由 service 作为一个代理来达到能够访问 外部服务的目的。 Service 代理:kube-proxy 组件详解 Kubernetes service 只是把应用对外提供服务的方式做了抽象,真正的应用跑在 Pod 中的container 里,我们的请求转到 kubernetes nodes 对应的 nodePort 上,那么 nodePort 上的请求是如何进一步转到提供后台服务的 Pod 的呢? 就是通过 kube-proxy 实现的:kube-proxy 部署在 k8s 的每一个 Node 节点上,是 Kubernetes 的核心组件,我们创建一个 service 的时候,kube-proxy 会在 iptables 中追加一些规则,为我们实现路由与负载均衡的功能。在 k8s1.8 之前,kube-proxy 默认使用的是 iptables 模式,通过各个 node 节点上的 iptables 规则来实 现 service 的负载均衡,但是随着 service 数量的增大,iptables 模式由于线性查找匹配、全量更新等 特点,其性能会显著下降。从 k8s 的 1.8 版本开始,kube-proxy 引入了 IPVS 模式,IPVS 模式与 iptables 同样基于 Netfilter,但是采用的 hash 表,因此当 service 数量达到一定规模时,hash 查表 的速度优势就会显现出来,从而提高 service 的服务性能。 service 是一组 pod 的服务抽象,相当于一组 pod 的 LB,负责将请求分发给对应的 pod。service 会为这个 LB 提供一个 IP,一般称为 cluster IP。kube-proxy 的作用主要是负责 service 的实现,具体 来说,就是实现了内部从 pod 到 service 和外部的从 node port 向 service 的访问。 1、kube-proxy 其实就是管理 service 的访问入口,包括集群内 Pod 到 Service 的访问和集群外访问 service。 2、kube-proxy 管理 sevice 的 Endpoints,该 service 对外暴露一个 Virtual IP,也可以称为是 Cluster IP, 集群内通过访问这个 Cluster IP:Port 就能访问到集群内对应的 serivce 下的 Pod。 kube-proxy 三种工作模式 1、Userspace 方式:Client Pod 要访问 Server Pod 时,它先将请求发给内核空间中的 service iptables 规则,由它再将请求转给监听在指定套接字上的 kube-proxy 的端口,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求转发给内核空间中的 service ip,由 service iptables 将请求转给各个节点中 的 Server Pod。 这个模式有很大的问题,客户端请求先进入内核空间的,又进去用户空间访问 kube-proxy,由 kube-proxy 封装完成后再进去内核空间的 iptables,再根据 iptables 的规则分发给各节点的用户空间 的 pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差。在 Kubernetes 1.1 版本之 前,userspace 是默认的代理模型。 2、iptables 方式:客户端 IP 请求时,直接请求本地内核 service ip,根据 iptables 的规则直接将请求转发到到各 pod 上,因为使用 iptable NAT 来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存上万的 Service/Endpoint,那么 Node 上的 iptables rules 将会非常庞大,性能还会再打折 iptables 代理模式由 Kubernetes 1.1 版本引入,自 1.2 版本开始成为默认类型。 3、ipvs 方式:Kubernetes 自 1.9-alpha 版本引入了 ipvs 代理模式,自 1.11 版本开始成为默认设置。客户端 请求时到达内核空间时,根据 ipvs 的规则直接分发到各 pod 上。kube-proxy 会监视 KubernetesService 对象和 Endpoints,调用 netlink 接口以相应地创建 ipvs 规则并定期与 KubernetesService 对象和 Endpoints 对象同步 ipvs 规则,以确保 ipvs 状态与期望一致。访问服务 时,流量将被重定向到其中一个后端 Pod。与 iptables 类似,ipvs 基于 netfilter 的 hook 功能,但 使用哈希表作为底层数据结构并在内核空间中工作。这意味着 ipvs 可以更快地重定向流量,并且在同步 代理规则时具有更好的性能。此外,ipvs 为负载均衡算法提供了更多选项,例如: rr:轮询调度 lc:最小连接数 dh:目标哈希 sh:源哈希 sed:最短期望延迟 nq:不排队调度 如果某个服务后端 pod 发生变化,标签选择器适应的 pod 又多一个,适应的信息会立即反映到 apiserver 上,而 kube-proxy 一定可以 watch 到 etc 中的信息变化,而将它立即转为 ipvs 或者 iptables 中的规则,这一切都是动态和实时的,删除一个 pod 也是同样的原理。如图: 注: 以上不论哪种,kube-proxy 都通过 watch 的方式监控着 apiserver 写入 etcd 中关于 Pod 的最 新状态信息,它一旦检查到一个 Pod 资源被删除了或新建了,它将立即将这些变化,反应再 iptables 或 ipvs 规则中,以便 iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod 时,不会出现 Server Pod 不存在的情况。自 k8s1.1 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则. 但在 1.1 以前,service 使用的模式默认为 userspace。Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相 当多的 iptables 规则,如果宿主机有大量的 Pod,不断刷新 iptables 规则,会消耗大量的 CPU 资源。 kube-proxy 生成的 iptables 规则分析 在 k8s 创建的 service,虽然有 ip 地址,但是 service 的 ip 是虚拟的,不存在物理机上的,是在 iptables 或者 ipvs 规则里的。 ]# kubectl get svc | grep my-nginx my-nginx ClusterIP 10.99.198.177 80/TCP 10.99.198.177 是 kubernetes 的 service ip,这个 ip 我们在物理机上看不到,它是在 iptables 规则里。 iptables -t nat -L |grep 10.99.198.177 KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.99.198.177 /* default/my-nginx cluster IP */ tcp dpt:http KUBE-SVC-L65ENXXZWWSAPRCR tcp -- anywhere 10.99.198.177 /* default/my-nginx cluster IP */ tcp dpt:http #通过上面可以看到之前创建的 service,会通过 kube-proxy 在 iptables 中生成一个规则,来实现流量路由,有一系列目标为 KUBE-SVC-xxx 链的规则,每条规则都会匹配某个目标 ip 与端口。也 就是说访问某个 ip:port 的请求会由 KUBE-SVC-xxx 链来处理。这个目标 IP 其实就是 service ip。 Service 服务发现:coredns 组件详解DNS 全称是 Domain Name System:域名系统,是整个互联网的电话簿,它能够将可被人理解的 域名翻译成可被机器理解 IP 地址,使得互联网的使用者不再需要直接接触很难阅读和理解的 IP 地址。域 名系统在现在的互联网中非常重要,因为服务器的 IP 地址可能会经常变动,如果没有了 DNS,那么可 能 IP 地址一旦发生了更改,当前服务器的客户端就没有办法连接到目标的服务器了,如果我们为 IP 地 址提供一个『别名』并在其发生变动时修改别名和 IP 地址的关系,那么我们就可以保证集群对外提供的 服务能够相对稳定地被其他客户端访。DNS 其实就是一个分布式的树状命名系统,它就像一个去中心化 的分布式数据库,存储着从域名到 IP 地址的映射。 CoreDNS 其实就是一个 DNS 服务,而 DNS 作为一种常见的服务发现手段,所以很多开源项目 以及工程师都会使用 CoreDNS 为集群提供服务发现的功能,Kubernetes 就在集群中使用 CoreDNS 解决服务发现的问题。 作为一个加入 CNCF(Cloud Native Computing Foundation)的服务, CoreDNS 的实现非常简单。验证 coredns docker load -I dig.tar.gz 工作节点解压 cat dig.yaml apiVersion: v1 kind: Pod metadata: name: dig namespace: default spec: containers: - name: dig image: god/xianchao/dig:latest command: - sleep - "3600" imagePullPolicy: IfNotPresent restartPolicy: Always kubectl apply -f dig.yaml #查看默认名称空间的 kubernetes 服务 # kubectl get svc | grep kubernetes kubectl get svc | grep kubernetes kubernetes ClusterIP 10.96.0.1 443/TCP 23 #解析 dns,如有以下返回说明 dns 安装成功 kubectl exec -it dig -- nslookup kubernetes Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 kubernetes.default.svc.cluster.local 服务名.名称空间.默认后缀 在 k8s 中创建 service 之后,service 默认的 FQDN 是..svc.cluster.local,那么 k8s 集群内部的服务就可以通过 FQDN 访问 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |