学无先后,达者为师

网站首页 编程语言 正文

服务发现与负载均衡机制Service实例创建_服务器其它

作者:、重明   更新时间: 2022-05-21 编程语言

什么是Service?

Service是逻辑上的一组Pod,一种可以访问Pod的策略,而且其他Pod可以通过Service访问到这个Service代理的Pod,可以把它理解为传统架构中的反向代理。

相对于Pod而言,Service有一个固定的名称,不会发生改变,并且提供了负载均衡的功能。

通过Service的定义,可以对客户端应用屏蔽后端Pod实例数量及Pod IP地址的变化,通过负载均衡策略实现请求到后端Pod实例的转发,为客户端应用提供一个稳定的服务访问入口地址。

Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、服务负载均衡等。

创建一个Service实例

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

[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               443/TCP          9d
nginx-svc    ClusterIP   10.110.150.87           80/TCP,443/TCP   15s

我们通过访问svc地址就能访问到后端的nginx

[root@k8s-master01 ~]# curl 10.110.150.87



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

  • 在同一个namespace中,其他Pod访问svc只需要curl http://nginx-svc就可以
  • 跨namespace的话,需要在svc名称后加.namespace名称就可以了,使用需谨慎,没必要不推荐
  • 不建议通过IP地址访问,因为IP不是固定的,删除或重建后IP会随机生成

注意,以上内容只能在集群内部访问

集群外部访问svc

  • 希望在生产中使用某个固定的名称而非IP地址进行访问外部的中间件服务
  • 希望Service指向另一个namespace中或其他集群中的服务
  • 某项目正在迁移至k8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理外部的服务

创建代理外部应用的Service实例

下面我们定义一个外部应用的service

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

区别就是少了这两个参数:

  selector:
    app: nginx 

创建成功后查看,可以发现虽然创建成功了但是没有ENDPOINTS

[root@k8s-master01 ~]# kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes    ClusterIP   10.96.0.1               443/TCP          9d
nginx-svc     ClusterIP   10.110.150.87           80/TCP,443/TCP   31m
nginx-svc-w   ClusterIP   10.110.144.61           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文件

[root@k8s-master01 ~]# kubectl get ep nginx-svc -o yaml > nginx-ep-w.yaml
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

可以看到已经有外部的代理了

[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

接下来试试能不能访问成功

# 直接访问的话是通的,返回值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的地址测试:

# 取出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是没问题的。

[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文件:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-wname
  name: nginx-svc-wname
spec:
  type: ExternalName
  externalName: www.baidu.com

然后创建就行了:

kubectl apply -f nginx-svc-wname.yaml

Service 的类型:

ClusterIP:在集群内部使用,默认

ExternalName:通过返回定义的CNAME别名

NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节点的IP地址和NodePort端口号访问到集群Pod服务。端口取值范围默认30000-32767

LoadBalancer:使用云服务商提供的负载均衡器公开服务

原文链接:https://yyang.blog.csdn.net/article/details/122878503

栏目分类
最近更新