Kubernetes - 集群中容器访问集群外部服务

如今微服务大行其道,以一种更合理的架构方式代理了“单体应用”,微服务有一个不一样于单体应用的特色:各个微服务单元之间存在互相依赖问题,例如服务和数据库,而数据库每每会在应用容器集群外部单独布设为数据中心,这就须要集群内服务有访问集群外部服务的需求。mysql

若是你使用云服务,可能会有链接RDS的需求,怎么作到呢,ExternalName类型的Service和EndPoint均可以知足咱们的要求,但在谈它们以前,咱们先来看一下集群内是如何通讯的。web

集群内服务之间通讯

DNSsql

Service type:ExternalName

在Docker环境中,因为Docker Engine自带 DNS Server,咱们使用容器名来访问其它容器,由于容器是不稳定的,当容器宕掉,再从新启动相同镜像的容器,IP地址会改变,因此咱们不使用IP访问其它容器;一样的,在Kubernetes集群中,因为咱们使用 kube-DNS,咱们经常使用Service名称来访问某个服务,Service资源对象能保证其背后的容器副本始终是最新的IP。数据库

所以,咱们能够利用这个特性,对Service名称和外部服务地址作一个映射,使之访问Service名称既是访问外部服务。例以下面的例子是将 svc1xxx.xxx.xxx.xxx 作了对等关系。api

kind: Service
apiVersion: v1
metadata:
  name: svc1
  namespace: default
spec:
  type: ExternalName
  externalName: somedomain.org

设置 Service 的 EndPoint

在Kubernetes集群中,同一个微服务的不一样副本会对集群内或集群外(取决于服务对外暴露类型)暴露统一的服务名称,一个服务背后是多个 EndPointEndPoint解决映射到某个容器的问题,在 EndPoint 中不只能够指定集群内容器的IP,还能够指定集群外的IP,咱们能够利用这个特性使用集群外部的服务。架构

EndPoint 方式的缺点是只能指定IP,不能使用网址,好比网址,好比RDS的地址,这种状况下只能使用ExternalName来解决。dom

apiVersion: v1
kind: Service
metadata:
  name: mysql-production
spec:
  ports:
    - port: 3306
---
kind: Endpoints
apiVersion: v1
metadata:
  name: mysql-production
  namespace: default
subsets:
  - addresses:
      - ip: 192.168.1.25
    ports:
      - port: 3306

总结

本文介绍了集群内部访问外部服务的两种方法,ExternalName 类型的服务适用于外部服务使用域名的方式,缺点是不能指定端口;而EndPoint的方式适合于外部服务是IP的状况,可是能够指定端口。根据须要使用吧!svg