Service 将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为
Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进
行负载均衡。
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —
— 通常称为微服务。 Service 所针对的 Pods 集合通常是通过选择算符来确定的。

一、Service 服务 ClusterIP 方式

1、创建 ClusterIp 服务

服务的连接对所有的后端 pod 是负载均衡的,至于哪些 pod 被属于哪个服务,通过在定义
服务的时候设置标签选择器;
可以通过 yaml 和 kubectl expose/kubectl create svc 方式
Deployment 创建

vi test1.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
 name: test1
spec:
 replicas: 1
 selector:
     matchLabels:
      app: test1
     template:
      metadata:
       labels:
         app: test1
     spec:
         containers:
         - image: nginx:1.7.9
             name: test
             ports: - containerPort: 80
         resources:
             requests:
                 cpu: 0.1
             limits:
                 cpu: 1

服务创建
1. Yaml 文件

apiVersion: v1
kind: Service
metadata:
 name: test1
spec:
 ports:
 - name: myngx
 port: 2180
 targetPort: 80
 selector:
 app: test1

2. 命令行创建

K get pod/deployment
K expose deployment test1 –name=test1 –port=3280
K create svc 
kubectl create -f test1.yaml
kubectl get pod

使用之前的 yaml 文件创建 pod,模版中设置的标签为 app: test1,所以创建服务的 yaml(还
有之前介绍的 kubectl expose 方式也可以创建服务)中也需要指定相同的标签:
首先指定的资源类型为 Service,然后指定了两个端口分别:port 服务提供的端口,targetPort
指定 pod 中进程监听的端口,最后指定标签选择器,相同标签的 pod 被当前服务管理;
K get svc 
Curl 
创建完服务之后,可以发现给 kubia 分配了 CLUSTER-IP,这是一个内部 ip;至于如何测试
可以使用 kubectl exec 命令远程地在一个已经存在的 pod 容器上执行任何命令;pod 名称可以随意指定三个中的任何一个,接收到 crul 命令的 pod,会转发给 Service,由 Service 来
决定将请求交给哪个 pod 处理,所以可以看到多次执行,发现每次处理的 pod 都不一样;
如 果 希 望 特 定 客 户 端 产 生 的 所 有 请 求 每 次 都 指 向 同 一 个 pod, 可 以 设 置 服 务 的
sessionAffinity 属性为 ClientIP;

 

2.测试 Service 的服务发现

 

如果使用 ipvs,当你创建 Service 的时候,kube-proxy 会获取 Service 对应的 Endpoint,
调用 LVS 帮我们实现负载均衡的功能。
通过删除和增加 Pod 观看服务发现的作用

K exec -it pod-name -- sh
echo 111 > /usr/share/nginx/html/index.html
echo 222> /usr/share/nginx/html/index.html
echo 333 > /usr/share/nginx/html/index.html
cat /usr/share/nginx/html/index.html
curl serviceIP:port

3.Headless service clusterIP

顾名思义,就是没头的 Service。有啥用呢?很简单,dns 查询会如实的返回 2 个真实的
endpoint,有时候 client 想自己来决定使用哪个 Real Server,可以通过查询 DNS 来获取 Real Server 的信息。
Headless Service 的对应的每一个 Endpoints,即每一个 Pod,都会有对应的 DNS 域名;这
样 Pod 之间就可以互相访问.
web 为我们创建的 StatefulSets,对应的 pod 的域名为 web-0,web-1,他们之间可以互相
访问,这样对于一些集群类型的应用就可以解决互相之间身份识别的问题了。

 

vi sts1.yaml 
apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
 app: nginx
spec:
 ports:
 - port: 80
 name: web
 clusterIP: None
 selector:
 app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: web
spec:
 serviceName: "nginx"
 replicas: 3 selector:
 matchLabels:
 app: nginx
 template:
 metadata:
 labels:
 app: nginx
 spec:
 containers:
 - name: nginx
 image: nginx:1.9
 ports:
 - containerPort: 80
 name: web

可以单独寻址。

4.同一个 deployment 暴露多次显示多个服务名称

如果 pod 监听了两个或者多个端口,那么服务同样可以暴露多个端口

cat test1-multi-name.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
 name: test1
spec:
 replicas: 1
 selector:
 matchLabels:
 app: test1
 template:
 metadata:
 labels:
 app: test1
 spec:
 containers:
 - image: nginx:1.7.9
 name: test
 ports:
 - containerPort: 80
 resources:
 requests:
 cpu: 10m
 limits: cpu: 100m
---
apiVersion: v1
kind: Service
metadata:
 name: test1
spec:
 selector:
 app: test1
ports:
 - name: myngx
 port: 2180
 targetPort: 80
 - name: myngx1
 port: 3180
 targetPort: 80

这里在 Service 里面配置两个端口都指向同一个目标端口,看是否都能访问:
kubectl create -f test1-multi-name.yaml
k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) 
AGE
test1 NodePort 10.20.203.207 <none> 
2180:32187/TCP,3180:32188/TCP 66m
[root@k18-5 ingress]# curl 10.20.203.207:2180
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐