service
Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service通过标签来选取服务后端,一般配合Replication Controller或者Deployment来保证后端容器的正常运行。
Service有三种类型:
- ClusterIP:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP
- NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过
来访问该服务:NodePort - LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到
:NodePort
Ingress Controller
Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如
- 对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在支持的cloud provider上面
Ingress就是为了解决这些限制而引入的新资源,主要用来将服务暴露到cluster外面,并且可以自定义服务的访问策略。比如想要通过负载均衡器实现不同子域名到不同服务的访问:
1 2 3 4 |
foo.bar.com --| |-> foo.bar.com s1:80 | 178.91.123.132 | bar.foo.com --| |-> bar.foo.com s2:80 |
可以这样来定义Ingress:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: 80 |
注意: Ingress本身并不会自动创建负载均衡器,cluster中需要运行一个ingress controller来根据Ingress的定义来管理负载均衡器。目前社区提供了nginx和gce的参考实现。
Endpoints
有几种情况下需要用到没有selector的service。
- 使用kubernetes集群外部的数据库时
- service中用到了其他namespace或kubernetes集群中的service
- 在kubernetes的工作负载与集群外的后端之间互相迁移
可以这样定义一个没有selector的service。
1 2 3 4 5 6 7 8 9 10 |
kind: Service apiVersion: v1 metadata: name: my-service spec: ports: - protocol: TCP port: 80 targetPort: 9376 |
定义一个Endpoints来对应该service。
1 2 3 4 5 6 7 8 9 10 |
kind: Endpoints apiVersion: v1 metadata: name: my-service subsets: - addresses: - ip: 1.2.3.4 ports: - port: 9376 |
使用kubernetes时有一个很常见的需求,就是当数据库部署在kubernetes集群之外的时候,集群内的service如何访问数据库呢?当然你可以直接使用数据库的IP地址和端口号来直接访问,有没有什么优雅的方式呢?你需要用到ExternalName Service。
1 2 3 4 5 6 7 8 9 10 11 |
kind: Service apiVersion: v1 metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com ports: - port: 12345 |