目录
1、Service定义详解
1.1、 yaml格式的Service定义文件的完整内容
|
1.2、Service定义文件中各属性的说明表
属性名称 | 取值类型 | 是否必选 | 取值说明 |
---|---|---|---|
| string | required | v1 |
| string | required | Service |
| object | required | 元数据 |
metadata.name | string | required | service 名称 |
| string | required | 命名空间,默认default |
metadata.labels[] | list | 自定义标签属性列表 | |
metadata.annotations[] | list | 自定义注解属性列表 | |
spec | object | required | 详细描述 |
spec.selector[] | list | required | Label Selector配置,将选择具有指定Label标签的Pod作为管理范围 |
spec.type | string | required | Service的类型,指定Service的访问方式,默认值为ClusterIP。取值范围如下: |
spec.clusterIP | string | 虚拟服务的IP地址,当type=clusterIP时,如果不指定,则系统进行自动分配。 | |
spec.sessionAffinity | string | 是否支持Session,可选值为ClientIP,表示将同一个源IP地址的客户端访问请求都转发到同一个后端Pod。默认值为空。 | |
spec.ports[] | list | Service需要暴露的端口列表 | |
spec.ports[].name | string | 端口名称 | |
spec.ports[].protocol | string | 端口协议,支持TCP和UDP,默认值为TCP | |
spec.ports[].port | int | 服务监听的端口号 | |
spec.ports[].targetPort | int | 需要转发到后端Pod的端口号 | |
spec.ports[].nodePort | int | 当spec.type=NodePort时,指定映射到物理机的端口号 |
2、Service 服务类型
Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
Type 的取值以及行为如下:
- ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
- NodePort:通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。
- LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
- ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版
k8s中有3种IP地址:
- Node IP: Node节点的IP地址,这是集群中每个节点的物理网卡的IP地址;
- Pod IP: Pod的IP地址,这是Docker Engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络;
- Cluster IP:Service 的IP地址,这也是一个虚拟的IP,但它更像是一个“伪造”的IP地址,因为它没有一个实体网络对象,所以无法响应ping命令。它只能结合Service Port组成一个具体的通信服务端口,单独的Cluster IP不具备TCP/IP通信的基础。在k8s集群之内,Node IP网、Pod IP网与Cluster IP网之间的通信采用的是k8s自己设计的一种编程实现的特殊的路由规则,不同于常见的IP路由实现。
3、服务发现
Kubernetes 支持2种基本的服务发现模式 —— 环境变量和 DNS。
3.1、环境变量
当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量。 它同时支持 Docker links兼容 变量、简单的 {SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT 变量,这里 Service 的名称需大写,横线被转换成下划线。
3.2、DNS
一个强烈推荐的集群插件 是 DNS 服务器。 DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录。 如果整个集群的 DNS 一直被启用,那么所有的 Pod 应该能够自动对 Service 进行名称解析。
例如,有一个名称为 "my-service" 的 Service,它在 Kubernetes 集群中名为 "my-ns" 的 Namespace 中,为 "my-service.my-ns" 创建了一条 DNS 记录。 在名称为 "my-ns" 的 Namespace 中的 Pod 应该能够简单地通过名称查询找到 "my-service"。 在另一个 Namespace 中的 Pod 必须限定名称为 "my-service.my-ns"。 这些名称查询的结果是 Cluster IP。
Kubernetes 也支持对端口名称的 DNS SRV(Service)记录。 如果名称为 "my-service.my-ns" 的 Service 有一个名为 "http" 的 TCP 端口,可以对 "_http._tcp.my-service.my-ns" 执行 DNS SRV 查询,得到 "http" 的端口号。
Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式。 更多信息可以查看DNS Pod 和 Service。
Kubernetes 从 1.3 版本起, DNS 是内置的服务,通过插件管理器 集群插件 自动被启动。Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通知个别容器使用 DNS Service 的 IP 解析 DNS 名字。
4、Service的基本用法
一般来说,对外提供服务的应用程序需要通过某种机制来实现,对于容器应用最简便的方式就是通过TCP/IP机制及监听IP和端口号来实现。
创建一个基本功能的Service。
4.1 创建deployment
我们定义一个提供web服务的Deploy,由两个tomcat容器副本组成,每个容器通过containerPort设置提供服务号为8080:
webapp-deploy.yaml
|
创建该Deploy
|
获取pod的IP地址
[root@docker ~]# kubectl get pods -l app=webapp -o yaml|grep podIP
podIP: 172.20.1.157
podIP: 172.20.2.219
直接通过这两个Pod的IP地址和端口号访问Tomcat服务:
#curl 172.20.2.219:8080
直接通过Pod的IP地址和端口号可以访问容器内的应用服务,但是Pod的IP地址是不可靠的,例如Pod所在的Node发生故障,Pod将被k8s重新调度到另一台Node。Pod的IP地址将发生变化,更重要的是,如果容器应用本身是分布式的部署方式,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器来实现请求的分发。kubernetes中的Service就是设计出来用于解决这些问题的核心组件。
4.2 创建一个Service来提供服务
webapp-svc.yaml
|
Service定义中的关键字段是ports和selector。
本例中ports定义部分指定了Service所需的虚拟端口号为8081,由于与Pod容器端口号8080不一样,所以需要在通过targetPort来指定后端Pod的端口。
selector定义部分设置的是后端Pod所拥有的label: app=webapp
创建svc
|
获取clusterIP
|
查看Endpoints
|
5、集群外部访问Service
5.1、将Service的端口号映射到物理机
通过设置nodePort映射到物理机,同时设置Service的类型为NodePort
webapp-svc-nodeport.yaml
|
创建这个Service
|
|
通过物理机的IP和端口访问:
6、Ingress
我们知道Service的表现形式为IP:Port,即工作在TCP/IP层,而对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的Service机制是无法实现的。kubernetes v1.1版本中新增的Ingress资源对象将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。
使用 Ingress 进行负载分发时,Ingress Controller 将基于 Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint(即 Pod)上,这样会跳过 kube-proxy 的转发功能,kuber-proxy 不在起作用。如果 Ingress Controller 提供的是对外服务,则实际上实现的是边缘路由器的功能。
为使用Ingress,需要创建Ingress Controller(带一个默认backend服务)和Ingress策略设置来共同完成。
nginx-ingress.yaml文件
查看 nginx-ingress-controller
|
Ingress的策略配置
my-web-ingress.yaml
|
本地电脑C:\Windows\System32\drivers\etc 修改hosts文件,添加 : 172.18.10.41 zly.com.cn
浏览器地址输入:zly.com.cn