1、ClusterIP
ClusterIP服务是Kuberntets的默认服务。它在集群内部生成一个服务,供集群内的其他应用访问。外部无法访问。
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
selector:
app: my-app
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
这种方式也可以通过外部网络访问,不过需要使用kubernetes proxy来访问:
开启proxy
kubectl proxy --port=8080
现在可以通过Kubernetes API使用下面这个地址来访问这个服务:
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
2、NodePort
NodePort服务是让外部流量直接访问服务的最原始方式。NodePort,顾名思义,在所有的节点(虚拟机)上开放指定的端口,所有发送到这个端口的流量都会直接转发到服务。
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
selector:
app: my-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP
NodePort服务有两个地方不同于一般的“ClusterIP”服务。首先,它的类型是“NodePort”。还有一个叫做“nodePort"的端口,能在节点上指定开放哪个端口。如果没有指定端口,它会选择一个随机端口 ( 只能使用30000–32767的端口 )
如果节点 / 虚拟机的IP地址发生变化,需要进行处理
3、LoadBalancer
LoadBalancer服务是发布服务到互联网的标准方式。在GKE中,它会启动一个Network Load Balancer,分配一个单独的IP地址,将所有流量转发到服务中。
4、ExternalName类型
这种类型其实是一个没有 selector 的 Service
apiVersion: v1
kind: Service
metadata:
name: pinpoint
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
应用场景:
Servcie 抽象了该如何访问 Kubernetes Pod,但也能够抽象其它类型的 backend,例如:
(1)、希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
(2)、希望服务指向另一个 Namespace 中或其它集群中的服务。
(3)、正在将工作负载转移到 Kubernetes 集群,和运行在 Kubernetes 集群之外的 backend。
由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:(即手动创建endpoint,由于名字相同会进行自动映射)
kind: Endpoints
apiVersion: v1
metadata:
name: pinpoint
subsets:
- addresses:
- ip: 192.168.2.58
ports:
- port: 80
说明:addresses后面的ip就是外接服务的访问ip,可以接多个,可以是外接服务公网IP或者可以访问的私网IP
访问没有 selector 的 Service,与有 selector 的 Service 的原理相同。请求将被路由到用户定义的 Endpoint。(上面的例子则是路由到 192.168.2.58:80)
注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。
ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
当查询主机 my-service.prod.svc.CLUSTER时,集群的 DNS 服务将返回一个值为 my.database.example.com 的 CNAME 记录。 访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。
创建了没有selector的service之后,还需要手动创建endpoint才可以被实际调用。
Ingress (ingress后面需要接service作为后端应用)
Ingress实际上不是一种服务。相反,它在多个服务前面充当“智能路由”的角色,或者是集群的入口。
使用Ingress可以做很多事情,不同类型的Ingress控制器有不同的功能。
默认的GKE ingress控制器会启动一个 HTTP(S) Load Balancer,可以通过基于路径或者是基于子域名的方式路由到后端服务。例如,可以通过foo.yourdomain.com 发送任何东西到foo服务,或者是发送yourdomain.com/bar/路径下的任何东西到bar服务。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: other
servicePort: 8080
rules:
- host: foo.mydomain.com
http:
paths:
- backend:
serviceName: foo
servicePort: 8080
- host: mydomain.com
http:
paths:
- path: /bar/*
backend:
serviceName: bar
servicePort: 8080
Ingress可能是发布服务最强大的方式,同时也是最复杂的。Ingress控制器的类型很多,如 Google Cloud Load Balancer,Nginx,Contour,Istio等等。还有一些Ingress控制器插件,比如证书管理器,可以自动为服务提供SSL认证。
如果想在同一个IP地址下发布多个服务,并且这些服务使用相同的第 7 层协议(通常是 HTTP),Ingress是最有用的。如果使用原生的GCP集成,只需要支付一个负载均衡器的费用。因为Ingress是“智能”的,你可以得到很多开箱即用的特性(比如SSL、认证、路由等)。
更多内容请关注我的知乎账号:https://www.zhihu.com/people/dengjiabo/activities