Service的基本介绍
Cluster IP:每个 Service 都分配了一个Cluster IP,它是一个虚拟的内部IP地址,用于在集群内部进行访问。这个虚拟IP是由Kubernetes自动分配的,并且与Service对象一一对应。 端口映射:Service可以映射一个或多个端口到后端Pod的端口。这意味着客户端可以通过访问Service 的某个端口来访问后端Pod的应用程序。 负载均衡:Service使用四层代理实现负载均衡,将来自客户端的请求均匀地分发到后端的Pod。当多个Pod属于同一个Service时,Service会自动将请求路由到可用的Pod上,以实现负载均衡。 DNS解析:每个Service都会自动注册到Kubernetes集群的内置DNS中,通过服务名称可以解
析出Service的虚拟IP。这样,客户端可以使用服务名称作为域名来访问Service,而无需知道具体的虚拟IP地址。
Kubernetes 集群中的ip地址
1 、Pod IP 地址:每个运行的Pod都会分配一个独立的IP地址。Pod IP地址是集群内部的IP地
址,用于Pod之间的通信。
2 、Service Cluster IP 地址:Service 对象分配的虚拟IP地址称为Cluster IP。Cluster IP是集群内部的IP地址,用于在集群内部进行服务发现和访问。客户端可以通过访问Service的Cluster IP 地址来访问与该Service相关联的一组Pod。
3 、Node IP地址:Node(节点)是Kubernetes集群中的工作节点,每个节点都有一个IP地
址。Node IP地址用于与集群外部的网络进行通信,例如从外部访问集群中的服务。Node IP地
址可以是物理节点的IP地址或云提供商分配的虚拟IP地址。
这三类IP地址在Kubernetes集群中扮演不同的角色:
1 、Pod IP 地址用于Pod之间的通信,实现了容器间的网络互通。
2 、Service Cluster IP 地址用于提供服务的访问入口,客户端可以通过访问Service的Cluster IP 地址来访问与之关联的一组Pod。
3 、Node IP地址用于与集群外部的网络进行通信,允许外部流量进入集群或从集群中流出。
创建Service资源
kubectl explain service
apiVersion ( string) : 表示 Service 资源使用的API版本。
kind ( string) : 表示创建的资源类型,对于Service资源,值为"Service" 。
metadata ( Object) : 包含定义Service 的元数据,例如名称、命名空间和标签等。
spec ( Object) : 定义 Service 的行为和规范,包含以下字段: • allocateLoadBalancerNodePorts ( boolean) : 表示是否动态分配负载均衡器的节点端口。• clusterIP ( string) : 表示Service的Cluster IP地址,用于集群内部访问Service,
默认由系统自动分配。
• clusterIPs ( [ ] string) : 表示Service的多个Cluster IP地址,用于集群内部访问
Service。
• externalIPs ( [ ] string) : 表示将Service公开到集群外部的外部IP地址列表。
• externalName ( string) : 表示Service的外部名称,用于将Service映射到外部
DNS名称。
• externalTrafficPolicy ( string) : 表示Service外部流量的负载均衡策略,可选值为
"Local" 或"Cluster" 。
• healthCheckNodePort ( integer) : 表示健康检查的节点端口。
• ipFamilies ( [ ] string) : 表示Service支持的IP地址族列表。
• ipFamilyPolicy ( string) : 表示Service的IP地址族策略,可选值为"SingleStack"
或"PreferDualStack" 。
• loadBalancerIP ( string) : 表示分配给负载均衡器的IP地址。
• loadBalancerSourceRanges ( [ ] string) : 表示允许访问负载均衡器的源IP地址范
围。
• ports ( [ ] Object) : 定义Service监听的端口映射配置,包括协议、端口号和目标端口
等。
• publishNotReadyAddresses ( boolean) : 表示是否将未就绪的Pod的地址也发布
给Service。
• selector ( map[ string] string) : 标签选择器,用于选择与Service关联的后端Pod。
• sessionAffinity ( string) : 表示会话亲和性的策略,可选值为"None" 、"ClientIP" 或
"ClientIP" 。
• sessionAffinityConfig ( Object) : 会话亲和性的配置参数。
• topologyKeys ( [ ] string) : 表示用于服务拓扑感知的键列表。
• type ( string) : 表示Service的类型,可选值为"ClusterIP" 、
"NodePort" 、"LoadBalancer" 或"ExternalName" 。 1 . ClusterIP应用场景:
• 类型:ClusterIP是默认的Service类型。
• 应用场景:适用于集群内部的服务发现和访问。ClusterIP将为Service分配一个虚拟
的Cluster IP地址,只能在集群内部访问。通过该地址,其他Pod或Service可以访
问与之关联的一组Pod。2 .NodePort应用场景:
• 类型:NodePort类型将Service公开到集群节点上的某个固定端口。
• 应用场景:适用于需要从集群外部访问Service的场景。通过指定NodePort类型,
Kubernetes会为Service分配一个随机的高端口号,并将该端口映射到每个节点上。
从外部网络,可以通过< NodeIP> :< NodePort> 的方式访问Service。 3 .LoadBalancer:
• 类型:LoadBalancer类型通过云服务提供商的负载均衡器将Service公开到外部网
络。
• 应用场景:适用于需要高可用性和负载均衡的场景。通过LoadBalancer类型,
Kubernetes将与云服务提供商集成,自动创建外部负载均衡器,并将流量分发到
Service关联的Pod。外部客户端可以通过负载均衡器的公共IP访问Service。 4 .ExternalName:
• 类型:ExternalName类型是一种将Service映射到外部DNS名称的方式。
• 应用场景:适用于将Service与外部服务集成的场景。通过ExternalName类型,
Service不会分配Cluster IP或NodePort,而是直接映射到一个外部DNS名称。当
集群内部的Pod或Service访问该Service时,DNS解析将会直接返回该外部DNS
名称对应的IP地址。查看service的spec.ports字段如何定义? • name: 该字段可选,用于标识端口的名称。它在Service定义中起到描述作用,方便理解和管
理端口。
• protocol: 该字段可选,用于指定端口使用的协议,如TCP、UDP或SCTP。默认情况下,为
TCP协议。根据实际需求选择正确的协议。
• port: 该字段必需,用于定义Service监听的端口号。当其他Pod或Service访问该Service
时,将使用此端口号。
• targetPort: 该字段必需,用于指定与该端口关联的Pod容器的端口号或名称。当请求到达
Service 后,将使用此端口号将流量转发到后端Pod的容器端口。
• nodePort: 该字段仅在NodePort类型的Service中可选。它用于指定在每个节点上公开的端
口号。如果未指定,Kubernetes将自动分配一个端口号。通过定义Service的端口,可以实现将流量从Service端口转发到后端Pod的容器端口。每个端口
定义可以映射到一个或多个后端Pod,实现负载均衡和服务发现的功能。根据实际需求,可以在
spec.ports 字段中定义多个端口,以满足不同端口的访问需求。 root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata:name: xpplabels:env: apps
spec:replicas: 3 selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:run: nginx
spec:type: NodePortports:- port: 80 protocol: TCPtargetPort: 80 nodePort: 30085 selector:run: nginx此时 已经关联上了root@ubuntu0:~/matedata/service
Name: nginx
Namespace: default
Labels: run = nginx
Annotations: < none>
Selector: run = nginx
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111 .189.98
IPs: 10.111 .189.98
Port: < unset> 80 /TCP
TargetPort: 80 /TCP
NodePort: < unset> 30085 /TCP
Endpoints: 10.244 .152.95:80,10.244.25.159:80,10.244.25.160:80
Session Affinity: None
External Traffic Policy: Cluster
Events: < none>
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
xpp-b6458f4cb-8spfw 1 /1 Running 0 66s 10.244 .152.95 ubuntu2 < none> < none>
xpp-b6458f4cb-jv9mn 1 /1 Running 0 66s 10.244 .25.159 ubuntu1 < none> < none>
xpp-b6458f4cb-t5prl 1 /1 Running 0 66s 10.244 .25.160 ubuntu1 < none> < none>
root@ubuntu0:~/matedata/service
kubernetes nginx
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
nginx NodePort 10.111 .189.98 < none> 80 :30085/TCP 16s
root@ubuntu0:~/matedata/service
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style> 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/" > nginx.org< /a> .< br/>
Commercial support is available at
< a href = "http://nginx.com/" > nginx.com< /a> .< /p> < p> < em> Thank you for using nginx.< /em> < /p>
< /body>
< /html> 在创建service的时候他也会创建和service一样的ep资源
root@ubuntu0:~/matedata
NAME ENDPOINTS AGE
kubernetes 192.168 .23.99:6443 28d
nginx 10.244 .152.95:80,10.244.25.159:80,10.244.25.160:80 23hclusterIP类型
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata:name: xpplabels:env: apps
spec:replicas: 3 selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:run: nginx
spec:type: ClusterIPports:- port: 8080 protocol: TCPtargetPort: 80 selector:run: nginx
root@ubuntu0:~/matedata/service
Endpoints: 10.244 .152.96:80,10.244.25.161:80,10.244.25.162:80
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
nginx ClusterIP 10.105 .110.237 < none> 8080 /TCP 10s
root@ubuntu0:~/matedata/service
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style>
创建ExternalName类型的Service
应用场景:跨名称空间访问
需求:default名称空间下的pod想要访问nginx名称空间下的pod服务要实现在不同命名空间下的 Pod 之间进行跨命名空间访问,可以按照以下步骤进行操作:
第一步:在nginx名称空间创建pod和service资源
root@ubuntu0:~
namespace/nginx created
root@ubuntu0:~
NAME STATUS AGE
default Active 29d
kube-node-lease Active 29d
kube-public Active 29d
kube-system Active 29d
nginx Active 7s
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata: name: nginxnginx namespace: nginx
spec: replicas: 1 selector: matchLabels: web: nginx template: metadata: labels: web: nginx spec: containers: - name: nginx image: nginximagePullPolicy: IfNotPresent
root@ubuntu0:~/matedata/service
deployment.apps/nginxnginx created
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginxnginx-5f4bf9c4dc-psmnb 1 /1 Running 0 9s 10.244 .152.97 ubuntu2 < none> < none>
root@ubuntu0:~/matedata/service
apiVersion: v1
kind: Service
metadata: name: nginx-svc namespace: nginx
spec: selector: web: nginx ports: - name: http protocol: TCP port: 80 targetPort: 80
root@ubuntu0:~/matedata/service
service/nginx-svc created
root@ubuntu0:~/matedata/service
Name: nginx-svc
Namespace: nginx
Labels: < none>
Annotations: < none>
Selector: web = nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.103 .175.198
IPs: 10.103 .175.198
Port: http 80 /TCP
TargetPort: 80 /TCP
Endpoints: 10.244 .152.97:80
Session Affinity: None
Events: < none> 第二步:在default名称空间创建pod和service资源
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata: name: default namespace: default
spec: replicas: 1 selector: matchLabels: app: busybox template: metadata: labels: app: busybox spec: containers: - name: busybox image: busybox:1.28 imagePullPolicy: IfNotPresent command: [ "/bin/sh" ,"-c" ,"sleep 36000" ]
root@ubuntu0:~/matedata/service
deployment.apps/default configured
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default-55cdb47c4-zl2x9 1 /1 Running 0 6s 10.244 .25.164 ubuntu1 < none> < none> root@ubuntu0:~/matedata/service
apiVersion: v1
kind: Service
metadata: name: client-svc
spec: type: ExternalName externalName: nginx-svc.nginx.svc.cluster.local ports: - name: http port: 80 targetPort: 80 service完整的dns名称
service_name.svc_namespace.svc.cluster.local
root@ubuntu0:~/matedata/service
service/client-svc created
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
client-svc ExternalName < none> nginx-svc.nginx.svc.cluster.local 80 /TCP 17s
root@ubuntu0:~/matedata/service
/
Connecting to client-svc ( 10.103 .175.198:80)
index.html 100 % | *****************************************************************************************************************************************************************| 612 0 :00:00 ETA
/
wget: bad address 'nginx-svc.nginx-ns.svc.cluster.local'
/
Connecting to nginx-svc.nginx.svc.cluster.local ( 10.103 .175.198:80)
wget: can't open ' index.html': File exists
/
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style>
上面两个请求的结果一样
映射外部服务案例
k8s集群引用外部的MariaDB数据库
在机器上安装mariadb数据库
root@ubuntu0:~
root@ubuntu0:~在 ubuntu0节点上创建一个名为 mysql 的目录,并进入该目录:
root@ubuntu0:~
root@ubuntu0:~创建一个 mysql_service.yaml 文件,并在其中定义一个类型为 ClusterIP 的 Service,用于代理外部的 MySQL 服务。设置服务监听的端口为 3306 :
root@ubuntu0:~/mysql
apiVersion: v1
kind: Service
metadata: name: mysql
spec: type: ClusterIP ports: - port: 3306
没写类型默认为clusterIP类型
你会发现以上创建的svc没有selector 没办法关联后端pod,所以他的endpoint它的值为空
root@ubuntu0:~/mysql
service/mysql created
root@ubuntu0:~/mysql
Endpoints: < none>
所以需要创建一个endpoint去关联他
root@ubuntu0:~/mysql
apiVersion: v1
kind: Endpoints
metadata: name: mysql
subsets:
- addresses: - ip: 192.168 .23.99 ports: - port: 3306
root@ubuntu0:~/mysql
endpoints/mysql created
此时就关联上了
root@ubuntu0:~/mysql
Endpoints: 192.168 .23.99:3306通过以上步骤,我们成功在 Kubernetes 集群中引入了外部的 MySQL 数据库。通过创建
Service 和 Endpoints,我们将外部 MySQL 的 IP 地址和端口与集群内内的 Service 进行了关联,
使得集群内部的应用可以通过 Service 名称访问外部的 MySQL 服务。通过访问该 Service,可以使用集群内的应用与外部的 MySQL 数据库进行交互。要测试引入的数据库是否可用,你可以在 Kubernetes 集群内的某个 Pod 中执行以下步骤:
创建一个测试用的 Pod:
root@ubuntu0:~/mysql
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1%Mruuk9z| þ".a" ! { n4T/-1mysql_native_password
Connection closed by foreign host
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1& ) TK] p< zqþHUS~Ahj[ hzKGmysql_native_password8
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1'i& } eb= I7þui2YLP+( 8