k8s中service代理外部的服务(mysql\nginx)

K8s中Service、Endpoints、Pod之间的关系

一个 Service的目标Pod集合通常是由Label Selector 来决定的。

Endpoints 是一组实际服务的端点集合。一个 Endpoint 是一个可被访问的服务端点,即一个状态为 running 的 pod 的可访问端点。一般 Pod 都不是一个独立存在,所以一组 Pod 的端点合在一起称为 EndPoints。只有被 Service Selector 匹配选中并且状态为 Running 的才会被加入到和 Service 同名的 Endpoints 中。
注:只有配置了 selector 的 service 才会自动创建一个同名的 endpoints,没有配置 selector 的 service 不会产生 endpoints 资源对象。

Service工作原理

k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)

 kubernetes集群中有三类IP地址

1、Node Network(节点网络),物理节点或者虚拟节点的网络,如ens33接口上的网路地址

2、Pod network(pod 网络),创建的Pod具有的IP地址

[root@k8s-master01 ~]# kubectl get pods -o wide
NAME             READY   STATUS          IP               NODE      
frontend-h78gw   1/1     Running         10.244.187.76    node2

Node Network和Pod network这两种网络地址是我们实实在在配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的。

3、Cluster Network(集群地址,也称为service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

[root@k8s-master01 ~]# kubectl get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)       
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP  

创建一个service代理外部的服务nginx

创建一个没有标签选择器的service,这样的service就不会关联到任何pod,从而也不会自动创建endpoint。这时我们手动创建一个与service同名的endpoint,使用endpoint来定义外部服务的地址端口,service会自动关联该endpoint。

service是如何与endpoint关联的?需要特别注意一下几点:

1、endpoint的名称必须要与service的名称相同,这样两者才能关联;
2、service定义spec.ports的ports的时候,包含port端口、name端口名称、protocol协议;
3、endpoint中定义外部服务的IP和端口,endpoint的名称一定要与service的名称一样,协议也要一样,端口的name也要与service的端口的name一样,端口协议也要与service的端口协议一样,不然endpoint不能与service进行关联。
 1 [root@k8s-master01 endpoint]# cat outside_agent_nginx.yaml 
 2 ---
 3 apiVersion: v1
 4 kind: Service
 5 metadata:
 6   name: outside-agent-svc                #service的名称叫做outside-agent-svc
 7   namespace: default
 8 spec:
 9   ports:
10   - name: out-agent-port                #service端口的名称
11     port: 8056                            #service的端口
12     protocol: TCP                        #端口协议
13 #   targetPort: 80                        #目标端口可以不定义,因为我们代理的不是pod,不定义targetPort,其默认等于port
14   sessionAffinity: None
15   type: ClusterIP
16 
17 ---
18 apiVersion: v1
19 kind: Endpoints
20 metadata:
21   name: outside-agent-svc                #endpoint的名称一定要与service的名称一致
22   namespace: default
23 subsets:
24 - addresses:
25   - ip: 192.168.118.129                    #定义外部服务地址
26   ports:
27   - port: 80                            #外部服务的端口
28     name: out-agent-port                #端口的name,这个名称一定要与service端口的名称
29     protocol: TCP                        #端口协议,这个协议一定要与service的端口协议一致
30 [root@k8s-master01 endpoint]# 

查看两者是否关联

 1 [root@k8s-master01 endpoint]# kubectl describe   -f outside_agent_nginx.yaml 
 2 Name:              outside-agent-svc
 3 Namespace:         default
 4 Labels:            <none>
 5 Annotations:       <none>
 6 Selector:          <none>
 7 Type:              ClusterIP
 8 IP Family Policy:  SingleStack
 9 IP Families:       IPv4
10 IP:                10.111.9.114
11 IPs:               10.111.9.114
12 Port:              out-agent-port  8056/TCP
13 TargetPort:        8056/TCP    
14 Endpoints:         192.168.118.129:80        #可以发现,service已经与同名的endpoint关联起来了
15 Session Affinity:  None
16 Events:            <none>
17 
18 
19 Name:         outside-agent-svc
20 Namespace:    default
21 Labels:       <none>
22 Annotations:  <none>
23 Subsets:
24   Addresses:          192.168.118.129
25   NotReadyAddresses:  <none>
26   Ports:
27     Name            Port  Protocol
28     ----            ----  --------
29     out-agent-port  80    TCP
30 
31 Events:  <none>
32 [root@k8s-master01 endpoint]# 

测试

 1 #访问service,查看是否能正常访问外部服务
 2 [root@ks8-master01 endpoint]# curl   10.111.9.114:8056            #访问service的ip和端口,能正常访问外部服务
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5 <head>
 6   <title>Welcome to CentOS</title>
 7   <style rel="stylesheet" type="text/css"> 
 8 
 9         html {
10         background-image:url(img/html-background.png);
11         background-color: white;
12         font-family: "DejaVu Sans", "Liberation Sans", sans-serif;
13         font-size: 0.85em;
14         line-height: 1.25em;
15         margin: 0 4% 0 4%;
16         }

创建一个service代理外部的服务mysql

在 node2 上安装 mysql 数据库:

 1 [root@k8s-node2 ~]# yum install mariadb-server.x86_64 -y
 2 [root@k8s-node2 ~]# systemctl start mariadb
 3  
 4 [root@k8s-master01 ~]# vim mysql_service.yaml
 5 apiVersion: v1
 6 kind: Service
 7 metadata:
 8   name: mysql
 9 spec:
10   type: ClusterIP
11   ports:
12   - port: 3306
13  
14 [root@k8s-master01 ~]# kubectl apply -f mysql_service.yaml
15 service/mysql created
16  
17 [root@k8s-master01 ~]# kubectl get svc
18 NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                            PORT(S)    AGE
19 client-svc   ExternalName   <none>          nginx-svc.nginx-ns.svc.cluster.local   80/TCP     21m
20 kubernetes   ClusterIP      10.96.0.1       <none>                                 443/TCP    52d
21 mysql        ClusterIP      10.101.57.164   <none>                                 3306/TCP   94s
22  
23 # 关联不到任何 pod
24 [root@k8s-master01 ~]# kubectl describe svc mysql
25 Name:              mysql
26 Namespace:         default
27 Labels:            <none>
28 Annotations:       <none>
29 Selector:          <none>
30 Type:              ClusterIP
31 IP Family Policy:  SingleStack
32 IP Families:       IPv4
33 IP:                10.101.57.164
34 IPs:               10.101.57.164
35 Port:              <unset>  3306/TCP
36 TargetPort:        3306/TCP
37 Endpoints:         <none>        # 还没有 endpoint
38 Session Affinity:  None
39 Events:            <none>    

创建 endpoint 资源

# 查看帮助命令
[root@k8s-master01 ~]# kubectl explain endpoints
[root@k8s-master01 ~]# kubectl explain endpoints.subsets
[root@k8s-master01 ~]# kubectl explain endpoints.subsets.addresses
[root@k8s-master01 ~]# kubectl explain endpoints.subsets.ports
 
[root@k8s-master01 ~]# vim mysql_endpoint.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: mysql             # 必须与前面创建的 service 名称一样
subsets:
- addresses:
  - ip: 192.168.78.132    # node 节点的物理 ip
  ports:
  - port: 3306
 
[root@k8s-master01 ~]# kubectl apply -f mysql_endpoint.yaml
endpoints/mysql created
 
[root@k8s-master01 ~]# kubectl describe svc mysql
Name:              mysql
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.101.57.164
IPs:               10.101.57.164
Port:              <unset>  3306/TCP
TargetPort:        3306/TCP
Endpoints:         192.168.78.132:3306    # 这个就是定义的外部数据库
Session Affinity:  None
Events:            <none>

 

posted @ 2023-02-22 12:51  yxy_linux  阅读(1051)  评论(0编辑  收藏  举报