什么是Service?
Service是逻辑上的一组Pod,一种可以访问Pod的策略,而且其他Pod可以通过Service访问到这个Service代理的Pod,可以把它理解为传统架构中的反向代理。
相对于Pod而言,Service有一个固定的名称,不会发生改变,并且提供了负载均衡的功能。
通过Service的定义,可以对客户端应用屏蔽后端Pod实例数量及Pod IP地址的变化,通过负载均衡策略实现请求到后端Pod实例的转发,为客户端应用提供一个稳定的服务访问入口地址。
Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、服务负载均衡等。
创建一个Service实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
apiVersion: v1 kind: Service metadata: labels: app: nginx-svc name: nginx-svc spec: ports: - name: http #service端口名称 port: 80 #service自己的端口 protocol: TCP #支持TCP UDP SCTP等 targetPort: 80 #后端应用接口 - name: https port: 443 protocol: TCP targetPort: 443 selector: app: nginx #这个就是匹配规则,代理标签中有nginx的后端服务器 sessionAffinity: None type : ClusterIP |
执行上面的yaml文件,创建一个service
1
2
3
4
5
6
|
[root@k8s-master01 ~] # kubectl create -f nginx-svc.yaml service /nginx-svc created [root@k8s-master01 ~] # kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443 /TCP 9d nginx-svc ClusterIP 10.110.150.87 <none> 80 /TCP ,443 /TCP 15s |
我们通过访问svc地址就能访问到后端的nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[root@k8s-master01 ~] # curl 10.110.150.87 <!DOCTYPE html> <html> < head > <title>Welcome to nginx!< /title > <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } < /style > < /head > <body> <h1>Welcome to nginx!< /h1 > <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.< /p > <p>For online documentation and support please refer to <a href= "http://nginx.org/" rel= "external nofollow" >nginx.org< /a >.<br/> Commercial support is available at <a href= "http://nginx.com/" rel= "external nofollow" >nginx.com< /a >.< /p > <p><em>Thank you for using nginx.< /em >< /p > < /body > < /html > |
- 在同一个namespace中,其他Pod访问svc只需要curl http://nginx-svc就可以
-
跨namespace的话,需要在svc名称后加
.namespace名称
就可以了,使用需谨慎,没必要不推荐 - 不建议通过IP地址访问,因为IP不是固定的,删除或重建后IP会随机生成
注意,以上内容只能在集群内部访问
集群外部访问svc
- 希望在生产中使用某个固定的名称而非IP地址进行访问外部的中间件服务
- 希望Service指向另一个namespace中或其他集群中的服务
- 某项目正在迁移至k8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理外部的服务
创建代理外部应用的Service实例
下面我们定义一个外部应用的service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
apiVersion: v1 kind: Service metadata: labels: app: nginx-svc-w name: nginx-svc-w spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 # - name: https # port: 443 # protocol: TCP # targetPort: 443 # selector: # app: nginx sessionAffinity: None type : ClusterIP |
区别就是少了这两个参数:
1
2
|
selector: app: nginx |
创建成功后查看,可以发现虽然创建成功了但是没有ENDPOINTS
1
2
3
4
5
6
7
8
9
|
[root@k8s-master01 ~] # kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443 /TCP 9d nginx-svc ClusterIP 10.110.150.87 <none> 80 /TCP ,443 /TCP 31m nginx-svc-w ClusterIP 10.110.144.61 <none> 80 /TCP 58s [root@k8s-master01 ~] # kubectl get ep NAME ENDPOINTS AGE kubernetes 192.168.10.2:6443,192.168.10.3:6443,192.168.10.4:6443 9d nginx-svc 172.17.125.10:443,172.18.195.22:443,172.17.125.10:80 + 1 more ... 31m |
接下来我们需要手动创建一个自定义的ENDPOINTS借用存在的ep生成一个新的ep文件
1
|
[root@k8s-master01 ~] # kubectl get ep nginx-svc -o yaml > nginx-ep-w.yaml |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
apiVersion: v1 kind: Endpoints metadata: labels: app: nginx-svc-w name: nginx-svc-w namespace: default subsets: - addresses: - ip: 110.242.68.3 # 代理的外部服务的地址 ports: - name: http port: 80 protocol: TCP |
可以看到已经有外部的代理了
1
2
3
4
5
6
7
|
[root@k8s-master01 ~] # kubectl create -f nginx-ep-w.yaml endpoints /nginx-svc-w created [root@k8s-master01 ~] # kubectl get ep NAME ENDPOINTS AGE kubernetes 192.168.10.2:6443,192.168.10.3:6443,192.168.10.4:6443 9d nginx-svc 172.17.125.10:443,172.18.195.22:443,172.17.125.10:80 + 1 more ... 47m nginx-svc-w 110.242.68.3:80 11s |
接下来试试能不能访问成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# 直接访问的话是通的,返回值200 [root@k8s-master01 ~] # curl baidu.com -I HTTP /1 .1 200 OK Date: Mon, 14 Feb 2022 01:43:18 GMT Server: Apache Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Tue, 15 Feb 2022 01:43:18 GMT Connection: Keep-Alive Content-Type: text /html # 通过访问service的IP可以看到也是通的,返回值200 [root@k8s-master01 ~] # curl 10.110.144.61 -I HTTP /1 .1 200 OK Date: Mon, 14 Feb 2022 01:44:20 GMT Server: Apache Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Tue, 15 Feb 2022 01:44:20 GMT Connection: Keep-Alive Content-Type: text /html |
如果业务变更ep地址变了怎么办?只需要在ep中将代理的地址更换即可。
比如我们更换一个taobao的地址测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 取出taobao的IP [root@k8s-master01 ~] # ping taobao.com PING taobao.com (140.205.94.189) 56(84) bytes of data. 64 bytes from 140.205.94.189 (140.205.94.189): icmp_seq=1 ttl=128 time =27.4 ms 64 bytes from 140.205.94.189 (140.205.94.189): icmp_seq=2 ttl=128 time =27.4 ms # 修改ep的yaml文件:nginx-ep-w.yaml apiVersion: v1 kind: Endpoints metadata: labels: app: nginx-svc-w name: nginx-svc-w namespace: default subsets: - addresses: - ip: 140.205.94.189 # taobao ports: - name: http port: 80 protocol: TCP # 重新加载 [root@k8s-master01 ~] # kubectl replace -f nginx-ep-w.yaml |
访问测试一下看是否连通:这个返回501是没问题的。
1
2
3
4
5
6
7
|
[root@k8s-master01 ~] # curl 10.110.144.61 -I HTTP /1 .1 501 Not Implemented Server: Tengine Date: Mon, 14 Feb 2022 01:39:16 GMT Content-Type: text /html Content-Length: 583 Connection: close |
Service反代外部域名
这个不说了,知道怎么配就行了。
Service的yaml文件:
1
2
3
4
5
6
7
8
9
|
apiVersion: v1 kind: Service metadata: labels: app: nginx-svc-wname name: nginx-svc-wname spec: type : ExternalName externalName: www.baidu.com |
然后创建就行了:
1
|
kubectl apply -f nginx-svc-wname.yaml |
Service 的类型:
ClusterIP
:在集群内部使用,默认
ExternalName
:通过返回定义的CNAME别名
NodePort
:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节点的IP地址和NodePort端口号访问到集群Pod服务。端口取值范围默认30000-32767
LoadBalancer
:使用云服务商提供的负载均衡器公开服务
以上就是服务发现与负载均衡机制Service实例创建的详细内容,更多关于服务发现与负载均衡Service的资料请关注服务器之家其它相关文章!
原文链接:https://yyang.blog.csdn.net/article/details/122878503