Consul中文文档
转载请注明🙂,喜欢请一键三连哦 😊

系列文章目录

Consul专栏—Consul工作原理及落地实践

Consul中文文档1.9


前言

为了提高生产的可用性,减少手动运维成本,目前来看使用k8s编排部署已成为趋势。 当我们逐渐K8s向迁移时, 如何解决当前过渡架构中服务发现的问题呢?
具体来说,就是一部分业务已迁移到K8s中, 一部分还在K8s外面, 如何解决这种中间过渡场景下的服务发现问题?

( 打通服务发现可能只是第一步, 后续我们可能会基于服务发现去做跨平台的服务治理, 这种情况我们后续再分析)

本篇主要分享基于Consul的解决方案, 来实现 非K8s Service(运行在K8s外) 与 原生 K8s Service 间的服务发现互通性

简单来说,就是实现 K8s集群外的应用可以发现调用K8s Service , 同时K8s内的应用又可以像调用集群内native service一样调用集群外的服务。

Consul基于此场景, 提供的了Consul-Sync组件, 来实现Consul和Kubernetes服务互相同步的方案。

一、同步Kubernetes和Consul服务

同步功能由consul-k8s project提供, 可以通过Consul Helm Chart 自动安装和配置。

1.1 同步Kubernetes services到Consul

Consul Sync组件可自动同步Kubernetes Service 注册到Consul Catalog中。

同步的K8s services, 使得用户可通过Consul原生服务发现的方式进行服务发现和连接K8s内服务, 如DNS或 HTTP。

(跨K8s集群的服务发现,也可以这样完)

同步的服务将被注册到 k8s-sync节点上,它这并不是一个真正的Consul节点, 不像Consul Client节点一样去注册和监控服务。 相对的, k8s-sync节点监控的是K8s,并且同步服务到Consul。

同步的Service类型、同步的命名空间、同步的Service都可以通过配置、注解进行设置,后续我将写一篇单独的文章讲解相关配置。

1.1.1 同步支持的Kubernetes Services类型

PS: 值得大家注意的一点是, 默认情况下K8s内使用的虚IP, 因此并不是所有的Services 类型都可以被集群外部访问到。

目前支持四种情况的K8s services同步: NodePort、LoadBalancer、External IPs、Cluster IP, 如果服务类型不属于这四种, 将不会被同步。各类型同步情况如下,我列了一个表格。

服务类型NodePortLoadBalancerExternal IPsCluster IP
服务名称service name + namespaceservice name + namespaceservice name + namespaceservice name + namespace
服务实例数Pod数External IP数External IP 数Pod数
服务实例地址(Address)Node External IPLB External IPExternal IPPod IP
服务实例端口 (Port)Node portfirst portfirst portfirst target port

PS: 关于服务名称、服务端口、服务标签、服务元数据 都其实都可以通过Consul注解或配置进行自定义, 放到下节我们统一介绍。

1.1.2 同步情况预览

我准备了三个例子, 我一个Nginx Deployment , 三副本的,同事创建了三种类型的Service , 分别为 ClusterIP、NodePort、LoadBalancer, 我们来分别看下他们的同步效果。
Nginx Service
来看下Consul集群中,同步后的服务情况。
Consul同步K8s服务

- Cluster-IP
产生三个服务实例。
在这里插入图片描述

- NodePort
产生三个服务实例,每个服务实例IP对应Node公网IP
NodePort

- LoadBalancer(External IP)
LoadBalancer 类型,官网说之后产生一个服务实例, 但是经过我实测, 当我的LB有绑定两个Ip时(比如一个内网,一个公网),这种情况产生两个服务实例, 这就和External Ip情况有点相似了。
lb类型

1.1.3 注意事项

1.1.3.1 关于External IPs

External IP并不是K8s Service类型,而是一种指定了外部Ip的情况,如果一个服务指定了External Ip, 那么这种服务也可以被同步。

针对这种情况, External Ip 可能是被其他系统设置的, 但是 External Ips 一定要是可以配其他服务发现系统解析的, 不要是虚IP。

1.1.3.2 关于ClusterIP

但是大家注意这个类型, 正常情况下, Pod Ip 是虚Ip,是无法被集群外部访问的。如果不想要同步这种ClusterIP类型,可以通过 Helm中的配置进行关掉 syncClusterIPServices=false

其实公有云情况下,一般K8s内的IP会直接使用 VPC IP, 所以集群内、集群外的网络是打平的,可以互通。

1.2 同步Consul service到Kubernetes

对于Consul中每一个Service都将会在K8s创建一个ExternalName Serviceexternal name 为Consul DNS名称。 例如Consul中存在一个名为foo的Service ,那么创建的K8s Service将如下所示

apiVersion: v1
kind: Service
metadata:
  name: foo
  annotations:
    consul.hashicorp.com/service-sync: "false"
  labels:
    consul: "true"
  ...
spec:
  externalName: foo.service.consul
  type: ExternalName

注意: foo.service.consul 需要使用Consul DNS 才可以解析到哦。

// 127.0.0.1 可以替换为Consul Service, 如果Consul是部署在K8s中的。 
dig @127.0.0.1 -p 8600 redis.service.dc1.consul. ANY

补充: 被同步的服务都会带着 consul: "true" ,因此很容易筛选出来。

1.2.1 同步效果预览

带大家看个例子,在Consul集群中,会有个Consul服务的, 我们以它为例看下同步后的情况。

Consul 服务

来看下Kubernetes同步后的Consul服务。
Consul 服务同步至k8s

1.2.2 非同步方案

其实从Consul向Kubernetes同步是非必须的,可以基于目前正使用的Kubernetes的DNS方案,配置Consul DNS。 比如如果你正在使用KubeDNS见 stub-domain configuration, 如果正在使用CoreDNS, 可参考proxy configuration

一旦配置了Consul DNS, 当以<consul-service-name>.service.consul格式发起请求时,Consul DNS将解析成Consul里的Service, 全部的K8s明明空间都可以生效。

当然,如果你近想通过 service-name 格式进行访问,那还是要同步。😀

关于Consul DNS 在K8s中应用可参考: Consul DNS on Kubernetes

二、Consul Sync安装

限于文章篇幅,我们统一放到下一篇文章中介绍Consul Sync的配置和相关安装。

三、总结

3.1 为什么同步Kubernetes services到Consul?

将Kubernetes Service同步到Consul Catalog,可以使Consul集群中的所有节点都可以获取到这些服务。 而且此方案可作为不同多K8s集群的服务发现方案。对于非K8s节点(集群外)可以通过Consul DNS 或者 HTTP API 获取到服务信息。

3.2 为什么同步Consul services到Kubernetes?

同步之后,K8s内的服务就可以像调用K8s内服务一样,调用外部服务。这也似的像一些数据库之类的外部变的自动化。

四、参考文档

  1. Syncing Kubernetes and Consul Services
  2. Announcing First-Class Kubernetes Support for HashiCorp Products
  3. Announcing HashiCorp Consul + Kubernetes
  4. Consul DNS on Kubernetes
Logo

开源、云原生的融合云平台

更多推荐