Kubernetes service探究

Kubernetes是google开源的容器编排器,非常适合当下火热的微服务架构,在容器编排领域,正逐步建立起主导地位。本文主要针对kubernetes service做一些剖析,先简单介绍一下基本概念。
基本概念
Pod:kubernetes最小调度单位,是一组容器集合,可以理解成一个容器。
replication controller:副本控制器,保证pod个数始终与设定值一致,如果遇到pod故障,节点离线等,控制器会删除这些状态异常的pod,重新调度生成新的pod。通过label匹配pod,在弹性伸缩、滚动升级中发挥重要作用。
service:服务,是一个虚拟概念,逻辑上代理后端pod。众所周知,pod生命周期短,状态不稳定,pod异常后新生成的pod ip会发生变化,之前pod的访问方式均不可达。通过service对pod做代理,service有固定的ip和port,ip:port组合自动关联后端pod,即使pod发生改变,kubernetes内部更新这组关联关系,使得service能够匹配到新的pod。这样,通过service提供的固定ip,用户再也不用关心需要访问哪个pod,以及pod会否发生改变,大大提高了服务质量。如果pod使用rc创建了多个副本,那么service就能代理多个相同的pod,通过kube-proxy,实现负载均衡。
通过下面模版定义一个service,这个service代理了所有具有"app": "MyApp"标签的pod,服务对外端口是80,服务ip在创建service的时候生成,也可以指定,这组ip:port在service的生命周期里保持固定。访问ip:port的流量会被重定向到后端pod的9376端口上,就是targetPort指定的。
{    "kind": "Service",    "apiVersion": "v1",    "metadata": {        "name": "my-service"    },    "spec": {        "selector": {            "app": "MyApp"        },        "ports": [            {                "protocol": "TCP",                "port": 80,                "targetPort": 9376            }        ]    }}
说到service,绕不开的一个组件是kube-proxy,实际上这个组件是专门为service服务的,每个minion节点都会运行一个kube-proxy。通过kube-proxy,实现流量从service到pod的转发,kube-proxy还可以实现简单的负载均衡功能。kube-proxy有多种代理模式,下面是userspace方式,kube-proxy在minion节点上为每一个服务创建一个临时端口,service的ip:port过来的流量转发到这个临时端口上,kube-proxy会用内部的负载均衡机制(一般是轮寻),选择一个后端pod,然后建立iptables,把流量导入到某个pod里。

服务发现在微服务架构里,服务之间经常要进行通信,服务发现就是解决不同服务之间通信的问题。比如一个nginx的pod,要访问一个mysql服务,就需要知道mysql服务的ip的port,获取ip和port的过程就是服务发现。Kubernetes 支持两种服务发现模式,分别是环境变量和dns。
环境变量:pod创建的时候,服务的ip和port信息以环境变量的形式注入到pod里,比如pod创建时有一个redis-master服务,服务ip地址是10.0.0.11,port是6379,则会把下面一系列环境变量注入到pod里,通过这些环境变量访问redis-master服务。 REDIS_MASTER_SERVICE_HOST=10.0.0.11REDIS_MASTER_SERVICE_PORT=6379REDIS_MASTER_PORT=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP_PROTO=tcpREDIS_MASTER_PORT_6379_TCP_PORT=6379REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 

dns服务器:

Kubernetes集群内会内置一个dns服务器,service创建成功后,会在dns服务器里导入一些记录,想要访问某个服务,通过dns服务器解析出对应的ip和port,从而实现服务访问。
外部服务对于一些前端应用,可能需要暴露服务到外网,而其他服务只运行在内部。Service的Types字段可以指定服务类型,默认的是ClusterIP类型。这是集群内部的服务类型,服务ip是一个内部ip;NodePort 和LoadBalancer是两种外部服务类型。
NodePortNodePort类型,会为服务在每个minion节点上暴露一个端口,通过节点ip和节点port可以访问这个服务,同时服务依然会有ClusterIP类型的ip和端口,内部通过ClusterIP方式访问,外部通过NodePort方式访问。 LoadBalancer如果kubernetes集群运行在第三方云平台上,比如openstack,那么可以通过外部的loadbalancer来暴露服务,还能借用第三方的负载均衡机制实现负载均衡。以openstack为例,借助neutron的lbaas,访问服务的流量会被直接转发到后端的pod,跳过了内置的kube-proxy负载均衡。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章