service discory

kubernetes中查找服务主要有两种方式:环境变量和DNS

  • 环境变量

kubelet给每个pod中添加了每个service对应的一组环境变量,包括简单变量{SVCNAME}_SERVICE_HOST和Docker-links变量{SVCNAME}_PORT,变量中的service_name全部大写,中划线转为下划线。
我的一个svc相关变量如下:

SVC_MALIBU_SERVICE_HOST=172.21.39.194
SVC_MALIBU_PORT_8080_TCP_ADDR=172.21.39.194
SVC_MALIBU_PORT_8080_TCP_PORT=8080
SVC_MALIBU_SERVICE_PORT=8080
SVC_MALIBU_PORT_8080_TCP=tcp://172.21.39.194:8080
SVC_MALIBU_PORT_8080_TCP_PROTO=tcp
SVC_MALIBU_PORT=tcp://172.21.39.194:8080

注:在pod中使用这些变量的时候,一定要在pod运行前先创建好svc,不然pod里面读不到的

  • DNS

像coredns等集群感知的DNS server监视了kubernetes api,它会为新service创建一组dns记录。

  • A记录
    除了Headless Service外的svc,会以 svc-name.svc-namespace.svc.cluster-domain.example 的形式添加一条A记录。记录值为svc的Cluster IP。
    “Headless” Service也会以 svc-name.svc-namespace.svc.cluster-domain.example 这种名字的形式添加一条A记录,它会解析成该 Service 选择(selector)的一组Pod的IP。客户端使用round-robin策略从这一组IP中进行选择。
  • SRV记录
    命名端口会创建一条SRV记录,格式 _port-name._port-protocol.svc-name.svc-namespace.svc.cluster-domain.example,普通的svc解析结果是端口号和CNAME(svc-name.svc-namespace.svc.cluster-domain.example)。headless类型的svc会解析出多个值,每个pod一个对应的port和CNAME(pod-name.svc-name.svc-namespace.svc.cluster-domain.example)

我们在应用配置文件中,经常会看到写多个地址,比如zookeeper地址配置为zookeeper://10.0.1.11:2181?backup=10.0.1.12:2181,在k8s中,创建headless类型的svc,会在kube-dns中为每个pod添加一条记录 $(podname).$(headless-svc-name).namespace.svc.cluster.local,值为pod的ip。这样配合stateful-set类型的控制器,每个pod就会有固定的hostname和域名。

headless service

不需要负载均衡或者pod间访问的情况下可能会用到。它不会创建cluster ip和proxy规则。ExternalName接受IPv4地址字符串,但作为包含数字的DNS名称,而不是IP地址。

无selector的service

可以自己手动创建endpoint,与service关联

externalname service

就是返回一条cname记录,访问service的方式与其他服务相同,但主要区别在于重定向发生在DNS级别,而不是通过代理或转发。
service还支持配置会话亲和性
External IPs

默认情况下,没有为pod名称创建A记录,PodSpec有可选字段hostname和subdomain,添加了hostname字段,pod的主机名会被设置为hostname的值。设置了subdomain,那么pod的FQDN为$(hostname).$(subdomain).namespace.svc.cluster-domain.example。如果Headless Service与Pod在同一个Namespace中,且它们具有相同的子域名,集群的KubeDNS服务也会为该Pod的完整合法主机名返回A记录。(参考)

PodSpec.dnsPolicy配置

  • Default: Pod从运行所在的节点继承dns配置。
  • ClusterFirst: 与配置的集群域后缀不匹配的任何DNS查询(例如 “www.taobao.com”)都将转发到从节点继承的上游dns服务器。
  • ClusterFirstWithHostNet: 对于与hostNetwork一起运行的Pod,需要设置其DNS策略为”ClusterFirstWithHostNet“,pod里面nameserver为集群dns地址。
  • None: 它使Pod忽略Kubernetes环境中的DNS设置,使用Pod Spec中的 dnsConfig字段提供所有DNS设置。

自定义pod dns服务

dnsConfig字段,配合dnsPolicy生成pod里面的resolv.conf文件。
nameservers:最多可以指定3个ip地址。列出的ip将合并到从指定的DNS策略生成的nameserver地址,并删除重复的地址。
searches:DNS搜索域的列表,同样是合并dns策略生成的列表。Kubernetes最多允许6个搜索域。
options:对象的可选列表,其中每个对象可能具有name属性(必需)和value属性(可选),同样是合并生成resolv.conf文件。