endpoint实际上是service以及其对应pods 的数据集合;在kubernetes 多种机制中,相关数据来源都是取自endpoint,故了解endpoint,才会更明晰机制的实现逻辑以及问题的诞生原因。
apiVersion: v1 kind: Endpoints metadata: name: nginx namespace: default subsets: - addresses: - ip: 10.168.84.187 nodeName: caas-node targetRef: kind: Pod name: nginx-5ccd677bdb-44vjt namespace: default ports: - port: 80 protocol: TCP targetPort: 80
endpoint.metadata.name : 代表着service name
endpoint.subsets[].addresses[].ip 代表 状态为ready pod 的ip
endpoint.subsets[].targetRef: 代表来自该ip的pod详情
endpoint. subsets[].ports[]: 数据来源于service.spec.ports,当pods内的port 并不满足targetPort ,则会在endpoint.subsets[].addresses[]中剔除该pod ip
endpoint controller
Endpoint controller 主要是维护endpoint,保证endpoint内ip:port 能够提供正常服务
- endpoint controller 建立 service 与 pod 的list-watch
- 轮询service队列,查询属于对应该service的pods
- 判断pods状态以及port情况,生成endpoint对象
- 过滤掉状态为not ready 的pods
- 过滤掉不满足service.spec.targetPort 的pods
- 获取pods 的ip 以及service.spec.ports ,生成endpoint对象
- 比较该endpoint对象与当前endpoint ,若当前endpoint不存在,则发送给apiserver创建请求,若与当前endpoint不一致,则发送给apiserver更新请求
kube-dns
kube-dns 是为kubernetes提供域名解析服务的组件。每个pod创建的时候,会自动把dns服务
kube-dns由三个容器组成:
- kube-dns:DNS 服务的核心组件,主要由 KubeDNS 和 SkyDNS 组成
- KubeDNS 负责监听 Service 和 Endpoint 的变化情况,并将相关的信息更新到 SkyDNS 中
- SkyDNS 负责 DNS 解析,监听在 10053 端口 (tcp/udp),同时也监听在 10055 端口提供 metrics
- kube-dns 还监听了 8081 端口,以供健康检查使用
- dnsmasq-nanny:负责启动 dnsmasq,并在配置发生变化时重启 dnsmasq
- dnsmasq 的 upstream 为 SkyDNS,即集群内部的 DNS 解析由 SkyDNS 负责
- sidecar:负责健康检查和提供 DNS metrics(监听在 10054 端口)
支持的dns解析格式:
- service:my-svc.my-namespace.svc.cluster.local,解析返回ip:
普通service 返回 service的cluster IP
headless service 返回pod ip list
- pod: pod-ip-address.my-namespace.pod.cluster.local ,解析返回pod ip,pod-ip-address格式就是将pod ip :xx.xx.xx.xx 转换为xx-xx-xx-xx
kube-proxy
每台机器上都运行一个 kube-proxy 服务,它监听 API server 中 service 和 endpoint 的变化情况,并通过 iptables 等来为服务配置负载均衡(仅支持 TCP 和 UDP)。
kube-proxy 当前支持一下几种实现
- userspace:最早的负载均衡方案,它在用户空间监听一个端口,所有服务通过 iptables 转发到这个端口,然后在其内部负载均衡到实际的 Pod。该方式最主要的问题是效率低,有明显的性能瓶颈。
- iptables:目前推荐的方案,完全以 iptables 规则的方式来实现 service 负载均衡。该方式最主要的问题是在服务多的时候产生太多的 iptables 规则,非增量式更新会引入一定的时延,大规模情况下有明显的性能问题
- ipvs:为解决 iptables 模式的性能问题,v1.8 新增了 ipvs 模式,采用增量式更新,并可以保证 service 更新期间连接保持不断开
- winuserspace:同 userspace,但仅工作在 windows 上
注意:使用 ipvs 模式时,需要预先在每台 Node 上加载内核模块 nf_conntrack_ipv4, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh 等。
Kube-proxy iptables 模式:
kube-proxy 目前仅支持 TCP 和 UDP,不支持 HTTP 路由,并且也没有健康检查机制。故可以使用ingress-controller 来解决该问题
ingress-controller
ingress-controller 会根据ingress 内配置的规则,确定要暴露的服务,生成nginx.conf,让外部服务能够通过nginx负载均衡到暴露服务上
ingress 为进入集群的请求提供路由规则的集合
ingress demo
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: rules: - host: foo.bar.com http: paths: - path: /testpath backend: serviceName: test servicePort: 80
ingress.spec.rules[].host : 代表定义域名
ingress.spec.rules[].http:代表访问的协议为http
ingress.spec.rules[].http.paths[].path 代表该域名的path
ingress.spec.rules[].http.paths[].backend: 代表访问该域名该path,转发到对应的服务以及端口
ingress-controller 逻辑
- ingress-controller list-watch ingress ,service变化
- 轮询ingress列表,获取ingress 对应服务service
- 根据service 获取endpoint
- 根据endpoint ip 数据,port 与 ingress host,path 数据 生成 nginx-conf 对象
- 进行 排序,比较旧的nginx-conf对象,判断是否一致
- 若不一致,则生成nginx.conf , 将nginx 进行热更新,使配置生效
深入Ingress-Nginx
- Deployment? 使用Deployment管理ingress-controller是否合适,在节点变化控制是否方便
调整为DaemonSet类型
好处:不用关心实例数,需要在那个机器上运行打个标签就可以;如果使用Deployment,每次增加或者减少就需要调整replicas
- 四层代理? 服务如果对外提供的是tcp,而不是http,如何做服务发现?
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: ingress-nginx data: # tcp四层代理,使用30000端口代理web服务 "30000": dev/web-demo:80
- 定制配置? 调整Nginx的配置:如超时、BufferSize如何设置?
kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app: ingress-nginx data: proxy-body-size: "64m" proxy-read-timeout: "180" proxy-send-timeout: "180"
- Https? 如何配置证书?
- 访问控制?Session保持?小流量?AB测试?
服务访问形式
内部服务互相访问:
内部服务之间的调用往往通过serviceName.serviceNamespace 域名形式访问,域名通过kube-dns解析ClusterIp,ClusterIp经过iptables,确定pod ip
内部服务访问外部服务
内部服务访问外部服务,可以直接访问外部服务的域名或ip,也可以将外部服务配置成没有selector的服务,使内部服务访问该服务,也可以达到访问外部服务效果
外部服务访问内部服务
1. 内部服务通过nodeport开放,外部服务可以通过nodeip:nodeport访问到该服务
2. 内部服务信息配置在ingress-nginx,外部服务访问ingress-nginx, ingress-nginx统一进行负载均衡