K8s中Service

一些服务发现的工具,比如Consul 、ZooKeeper 还有etcd等 工具,我们就可以只需要把我们的服务注册到这些服务发现中心去就可 以,然后让这些工具动态的去更新Nginx的配置就可以了,完全不用去手工的操作了。

而Kubernetes 集群就为我们提供了这样的一个对象 - Service,Service 是一种抽象的对象,它定义了一组Pod 的逻辑集合和一个用于访问它们的策略,其实这个概念和微服务非常类似。一个Serivce下面包含的Pod 集合一般是由Label Selector来决定的

Kubernetes 系统中的三 种IP这个问题。

Node IP:Node节点的IP 地址

Pod IP: Pod 的IP地址

Cluster IP: Service的 IP 地址

首先, Node IP是Kubernetes 集群中节点的物理网卡IP 地址(一般为内 网),所有属于这个网络的服务器之间都可以直接通信,所以Kubernetes 集群外要想访问Kubernetes 集群内部的某个节点或者服务,肯定得通过 Node IP进行通信(这个时候一般是通过外网IP 了)

然后Pod IP 是每个Pod 的IP 地址,它是Docker Engine 根据docker0网桥的IP 地址段进行分配的

最后Cluster IP 是一个虚拟的 IP ,仅仅作用于Kubernetes Service这 个对象,由Kubernetes 自己来进行管理和分配地址,当然我们也无法 ping这个地址,他没有一个真正的实体对象来响应,他只能结合Service Port来组成一个可以通信的服务。

例:

定义Service的方式和我们前面定义的各种资源对象的方式类型,例如, 假定我们有一组Pod服务,它们对外暴露了 8080 端口,同时都被打上了 app=myapp 这样的标签,那么我们就可以像下面这样来定义一个Service 对象:

vim nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  selector:
    app: myapp     #将myservice绑定到app: myapp标签
  ports:
  - protocol: TCP
    port: 80            #声明service端口80并映射到容器8080端口
    targetPort:8080     #容器里对外暴漏的端口
    name: myapp-http
#通过命令查看
[root@k8s-master service]# kubectl describe svc myservice 
Name:              myservice
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=myapp
Type:              ClusterIP
IP Families:       <none>
IP:                10.105.235.233
IPs:               10.105.235.233
Port:              myapp-http  80/TCP
TargetPort:        8080/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

创建一个名 为myservice 的Service对象,它会将请求代理到使用 TCP 端口为 8080,具有标签app=myapp 的Pod 上,这个Service会被系统分配 Cluster IP ,该 Service还会持续的监听selector下面的Pod ,会把这 些Pod 信息更新到一个名为 myservice 的Endpoints 对象上去,这个对象 就类似于Pod 集合。

需要注意的是,Service能够将一个接收端口映射到任意的targetPort 。 默认情况下, targetPort 将被设置为与port字段相同的值。targetPort 可以是一个字符串,引用了 backend Pod 的一个端口的名称。 因为实际指 派给该端口名称的端口号,在每个 backend Pod 中可能并不相同,所以对 于部署和设计 Service ,这种方式会提供更大的灵活性。

kube-proxy

在Kubernetes 集群中,每个Node会运行一个kube-proxy进程, 负责为Service实现一种 VIP(虚拟 IP,就是上面的 clusterIP )的代理形式,现在的Kubernetes 中默认是使用的 iptables 这种模式来代理。这种模式,kube-proxy会监视Kubernetes master 对Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会添加上 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某一个上面。 对于每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一 个 backend Pod。

另外需要了解的是如果最开始选择的 Pod 没有响应,iptables 代理能够自动地重试另一个 Pod,所以它需要依赖 readiness probes。

Service 类型

我们在定义Service的时候可以指定一个自己需要的类型的Service,如果不指定的话默认是ClusterIP 类型

ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。

NodePort:通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务 会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务

LoadBalancer:使用云提供商的负载均衡器,可以向外部暴露服务。 外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务,这个需要结合具体的云厂商进行操作。

ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

NodePort 类型

如果设置 type 的值为 "NodePort",Kubernetes master 将从给定的配置 范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的话会自动生成一个端 口。

需要注意的是,Service 将能够通过 :spec.ports[*].nodePort 和 spec.clusterIp:spec.ports[*].port 而对外可见。

#其他项目调用配置文件可写:
mysql-service.work:3306