Pod的生命是有限的,如果Pod重启或者worker节点宕机都会触发pod重建导致IP地址变化,如果写死会导致服务不可用,所以我们需要一个概念:服务发现。通过,Consul,ZooKeeper还有我们熟悉的etcd等工具,只需要把我们的服务注册到这些服务发现中心去就可以,然后让这些工具动态的去更新Nginx的配置就可以了,我们完全不用去手工的操作了。
那么服务发现的方式有哪些呢?
- ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。
apiVersion: v1
kind: Service
metadata:
labels:
name: test
name: svc1
spec:
ports: - port: 80
targetPort: 80
selector:
app: nginx
type: NodePort
- NodePort:通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
selector:
app: httpd
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30088
- LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务,这个需要结合具体的云厂商进行操作。
- ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
- ingress:可以简单认为是一个nginx。相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。
详细来说下ingress。
ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。ingress包括:ingress controller和ingress resources
ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。Kubernetes给出的方案就是Ingress,Ingress包含了两大主件Ingress Controller和Ingress。
Ingress解决的是新的服务加入后,域名和服务的对应问题,基本上是一个ingress的对象,通过yaml进行创建和更新进行加载。
Ingress Controller是将Ingress这种变化生成一段Nginx的配置,然后将这个配置通过Kubernetes API写到Nginx的Pod中,然后reload.(注意:写入 nginx.conf 的不是service的地址,而是service backend 的 pod 的地址,避免在 service 在增加一层负载均衡转发)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-https
namespace: test
spec:
tls:
- hosts:
- nginx.test.com
- tomcat.test.com
secretName: tls-secret
rules:
- host: nginx.test.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.test.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080