【云原生 • Kubernetes】kubernetes 核心技术 - Service

举报
敬 之 发表于 2022/09/01 22:57:18 2022/09/01
【摘要】 本文导读 一、Service 详解与基本用法1. Service 的定义2. Service 的基本用法3. 多端口 Service4. 外部服务 Service 二、Service ...

在这里插入图片描述


一、Service 详解与基本用法

1. Service 的定义

Service 是 Kubernetes 的核心概念之一,创建一个 Service 可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。

完整 yaml 格式的 Service 定义文件如下:

apiVersion: v1                    #版本号
kind: Service 
metadata:                         #元数据
    name: string                  #Service名称
    namespace: string             #命名空间,默认为default
    labels:                       #自定义标签属性列表
        - name: string
    annotations:                  #自定义注解属性列表
        - name: string
spec:                             #详细描述
    selector: []                  #Label Selector配置
    type: string                  #Service的类型
    clusterIP: string             #虚拟服务的IP地址
    sessionAffinity: string       #是否支持Session
    ports:                        #Service需要暴露的端口列表
    - name: string                #端口名称
        protocol: string          #端口协议,支持TCP/UDP,默认TCP
        port: int                 #服务监听的端口号
        targetPort: int           #需要转发到后端Pod的端口号
        nodePort: int
    status:
        loadBalancer:             #外部负载均衡器
            ingress:
                ip: string 	      #外部负载均衡器IP地址
                hostname: string  #主机名


  
 
  • 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

2. Service 的基本用法

一般情况下,对外部提供服务的应用程序需要通过某种机制来实现。而对于容器应用来说,最简单的方式就是通过 TCP/UDP 机制及监听 IP 端口号来实现。

如下案例:创建一个基本功能的 Service;

apiVersion: v1
kind: ReplicationController
metadata:
    name: mywebapp
spec:
	replicas: 2
	template:
	  metadata: 
	    name: mywebapp
	    labels:
	      app: mywebapp
	  spec:
	    containers:
	    - name: mywebapp
	    image: tomcat
	    ports:
	    - containerPort: 8080

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后通过 kubectl get pods -l app=mywebapp -o yaml | grep podIP 命令获取 Pod 的 IP 地址和端口号,最后使用 curl podIP:8080 来访问 Tomcat 服务。

但是要知道直接通过 Pod IP 和端口号访问应用服务是不可靠的,因为如果 Pod 所在的 Node 发生了故障,那么 Pod 将会被 Kubenetes 重新调度到另一台 Node,这也就导致 Pod 地址发生了改变。

为了避免这个问题,我们可以先配置一个 yaml 文件来定义 Service,然后通过 kubectl create 来创建,这样就可以通过 Service 的地址访问后端的 Pod 了。

如下案例:先 vim 定义一个 Service 的 yaml 文件;

apiVersion: v1
kind: Service
metadata:
  name: mywebapp-svc
spec:
  ports:
  - port: 8081
    targetPort: 8080
  selector:
    app: mywebapp

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后通过命令 kubectl get svc 获取到我们所创建的 Service 的 IP 地址;

最后使用命令 curl IP:8081 即可访问 Pod。

这里我使用 8081 端口号是因为我们在定义 service 的文件当中是用 8081 来映射 8080 的。

3. 多端口 Service

有时一个容器应用也可能需要提供多个端口的服务,那么在 Service 的定义中就可以相应的将其设置为多个端口对应多个应用服务。格式如下:

apiVersion: v1
kind: Service
metadata:
  name: mywebappService
spec:
  ports:
  - port: 8080
    targetPort: 8080
    name: web
  - port: 8005
    targetPort: 8005
    name: management
  selector:
    app: mywebapp

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4. 外部服务 Service

在某些特殊服务环境中,应用系统需要将一个外部数据库作为后端服务进行连接,或将另一个集群中的服务作为服务的后端,这时可以通过创建一个 无Label Selector 的 Service 来实现。格式如下:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80 
-----------------------
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
- addresses:
  - IP: 目标pod IP
  ports: 
    port: 8080

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

可以看到,无 Label Selector 的 Service 与普通 Service 的区别在于它没有了 selector 标签来指定 Label,而是需要创建一个 Endpoints 指定一个同名 的元数据来映射到自己要访问的 Pod 上。

二、Service 存在的意义

1. 防止 Pod 失联(服务发现)

通常一个网站包含前端和后端两个部分,通过在前端页面的操作访问后台服务。比如在前端有三个 Pod,后端也有三个 Pod,那么这个访问过程也就时通过前端的 Pod 进入到后端的 Pod 中,这最常用的方式就是通过 Pod 的 IP 地址进行访问。

但是 Pod 的 IP 地址并不固定,比如做了升级回滚、更新等操作,IP 地址都会改变。当访问了某一个 Pod,过了几分钟之后再次访问该 Pod 时,由于一些操作这个 IP 却不存在了,这也就是所说的 Pod 失联。

而 Service 恰恰解决了这个问题,具体实现方式就是每一个 Pod 在操作之前先在 Service 中(注册中心)使用自己的 IP 和名字做一个“注册”,当要进行访问时,先到 Service 中找到注册用的 IP,然后再访问。如果某个 Pod 的 IP 进行了改变,也会第一时间通知到 Service IP 的变化,使得其他服务再次访问时使用新的 IP。

2. 定义一组 Pod 访问策略(负载均衡)

如果说前端的某个 Pod 访问后端,而后端有若干个 Pod,那么到底访问哪个 Pod 就成了问题。这时候就需要 Service 发挥作用了,它使得访问请求可以平均的分配到不同的 Pod 中,也就是实现 负载均衡。分配规则可以是根据 响应时间并发量 进行分配或者是根据 空闲时间 等进行分配,这也就实现了 Pod 访问策略的定义。

三、Pod 和 Service 的关系

首先,Pod 和 Service 也是通过 Label 和 selector 标签建立联系的,如下。

#service中
selector:
  app: redis

#pod中
labels:
  app: redis

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

其次,Pod 的服务发现和负载均衡是通过 Service 来实现的。

四、Service 的三种常用类型

  • ClusterIP:通常用于集群内部。
  • NodePort:对外访问应用时使用。
  • LoadBalancer:对外访问应用时使用,也可用于公有云环境中。

文章来源: majinjian.blog.csdn.net,作者:Developer 小马,版权归原作者所有,如需转载,请联系作者。

原文链接:majinjian.blog.csdn.net/article/details/126608253

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。