前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes系列之Service

Kubernetes系列之Service

作者头像
编程识堂
发布2023-05-24 14:45:12
3500
发布2023-05-24 14:45:12
举报
文章被收录于专栏:编程识堂编程识堂

前言

通过小堂的上篇文章,我们已经能够通过Deployment来创建一组Pod来提供高可用性服务。虽然每 个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:

  • Pod IP仅仅是集群内可见的虚拟IP,外部无法访问。
  • Pod IP会随着Pod的销毁而消失,当Deployment对Pod进行动态伸缩时,Pod IP可能随时随地都会变化,这样对于我们访问这个服务带来了难度。

因此,Kubernetes中的Service对象就是解决以上问题的实现服务发现核心关键。

Service类型

ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟IP。

NodePort:在ClusterIP基础上为 Service在每台机器上绑定一个端口,这样就可以通过 NodePort 来访问该服务。

LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到NodePort。是付费服务,而且价格不菲。

ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建, 这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持 。

Service和Pods

Kubernetes的Pods是有生命周期的。他们可以被创建,而且销毁不会再启动。如果您使用Deployment来运行您的应用程序,则它可以动态创建和销毁Pod。

一个Kubernetes的Service是一种抽象,它定义了一组Pods的逻辑集合和一个用于访问它们的策略 (有的时候被称之为微服务)。一个Service的目标Pod集合通常是由Label Selector 来决定的 。

Pod 的 IP 地址,它实际路由到一个固定的目的地,Service 的 IP实际上不能通过单个主机来进行应答。相反,我们使用 iptables(Linux 中的数据包处理逻辑)来定义一个虚拟IP地址(VIP),它可以根据需要透明地进行重定向。当客户端连接到 VIP 时,它们的流量会自动地传输到一个合适的 Endpoint、环境变量和 DNS,实际上会根据 Service 的 VIP 和端口来进行填充。

kube-proxy代理模式

kube-proxy支持三种代理模式: 用户空间,iptables和IPVS;它们各自的操作略有不同。

Userspace代理模式

Client Pod要访问Server Pod时,它先将请求发给本机内核空间中的service规则,由它再将请求转给监听在指定套接字上的kube-proxy,kube-proxy处理完请求,并分发请求到指定Server Pod后,再将请求递交给内核空间中的service,由service将请求转给指定的Server Pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差 。

iptables代理模式

当一个客户端连接到一个 VIP,iptables 规则开始起作用。一个 backend 会被选择(或者根据会话亲和性,或者随机),数据包被重定向到这个backend。不像 userspace 代理,数据包从来不拷贝到用户空间,kube-proxy 不是必须为该 VIP 工作而运行,并且客户端 IP 是不可更改的。当流量打到 Node 的 端口上,或通过负载均衡器,会执行相同的基本流程,但是在那些案例中客户端 IP 是可以更改的。

IPVS代理模式

在大规模集群(例如10,000个服务)中,iptables 操作会明显降低速度。IPVS 专为负载平衡而设计, 并基于内核内哈希表。因此,您可以通过基于 IPVS 的 kube-proxy 在大量服务中实现性能一致性。同时,基于 IPVS 的 kube-proxy 具有更复杂的负载平衡算法(最小连接,局部性,加权,持久性)。

使用 ipvs 代理。在 Kubernetes v1.0 版本, Service 是 “4层”(TCP/UDP over IP)概念。在 Kubernetes v1.1 版本,新增了Ingress API(beta 版),用来表示 “7层”(HTTP)服务 。

这种模式,kube-proxy 会监视 Kubernetes Service 对象和 Endpoints ,调用 netlink 接口以相应地创建 ipvs 规则并定期与 Kubernetes Service 对象和 Endpoints 对象同步 ipvs 规则,以确保 ipvs 状态与期望一 致。访问服务时,流量将被重定向到其中一个后端 Pod与 iptables 类似,ipvs 于 netfilter 的 hook 功 能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着 ipvs 可以更快地重定向流量,并且在同步代理规则时具有更好的性能。此外,ipvs 为负载均衡算法提供了更多选项。

注:在 Kubernetes 1.14 版本开始默认使用 ipvs 代理。

ClusterIP

类型为ClusterIP的service,这个service有一个Cluster-IP,其实就一个VIP。具体实现原理依靠 kubeproxy组件,通过iptables或是ipvs实现。clusterIP 主要在每个 node 节点使用 iptables,将发向 clusterIP 对应端口的数据,转发到 kube-proxy 中。然 后 kube-proxy 自己内部实现有负载均衡的方法,并可以查询到这个 service 下对应 pod 的地址和端 口,进而把数据转发给对应的 pod 的地址和端口 。

这种类型的service 只能在集群内访问。

使用镜像

代码语言:javascript
复制
docker pull tomcat:9.0.20-jre8-alpine

部署Service

service/clusteripdemo.yml:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clusteripdemo
  labels:
    app: clusteripdemo
spec:
  replicas: 1
  template:
    metadata:
      name: clusteripdemo
      labels:
        app: clusteripdemo
    spec:
      containers:
        - name: clusteripdemo
          image: tomcat:9.0.20-jre8-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
      restartPolicy: Always
  selector:
    matchLabels:
      app: clusteripdemo

---
apiVersion: v1
kind: Service
metadata:
  name: clusterip-svc
spec:
  selector:
    app: clusteripdemo
  ports:
    - port: 8080
  type: ClusterIP

注:一个Service的目标Pod集合通常是由Label Selector 来决定的,即Service模板spec.selector.app 与spec.template.metadata.labels.app 对应的值必须一样

资源与资源之间用三个中划线隔开 ---

运行Service

代码语言:javascript
复制
#运行服务
kubectl apply -f clusteripdemo.yml
# 查询pod
kubectl get pod -o wide
#查询 deployment
kubectl get deploy
#查询service
kubectl get svc
#访问服务
curl 10.1.178.19:8080
#删除服务
kubectl delete -f clusteripdemo.yml

NodePort

我们的场景不全是集群内访问,也需要集群外业务访问。那么ClusterIP就满足不了了。NodePort当然是其中的一种实现方案。nodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步到给对应的 pod 。

使用镜像

代码语言:javascript
复制
docker pull tomcat:9.0.20-jre8-alpine

部署service

service/nodeportdemo.yml

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodeportdemo
  labels:
    app: nodeportdemo
spec:
  replicas: 1
  template:
    metadata:
      name: nodeportdemo
      labels:
        app: nodeportdemo-test
    spec:
      containers:
        - name: nodeportdemo
          image: tomcat:9.0.20-jre8-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
      restartPolicy: Always
  selector:
    matchLabels:
      app: nodeportdemo-test
---
apiVersion: v1
kind: Service
metadata:
  name: nodeport-src
spec:
  selector:
    app: nodeportdemo-test
  ports:
    - port: 8081 #集群内其他服务访问的端口号
      targetPort: 8080 # pod容器的端口号
      nodePort: 30008 #集群外部访问的端口号
  type: NodePort

运行service

代码语言:javascript
复制
#运行服务
kubectl apply -f nodeportdemo.yml
#查看服务
kubectl get svc
#访问服务
curl 10.1.58.136:8081
#浏览器访问tomcat均可以访问
http://192.168.150.128:30008/
http://192.168.150.129:30008/
http://192.168.150.130:30008/
http://192.168.150.131:30008/

LoadBalancer

LoadBalancer类型的service 是可以实现集群外部访问服务的另外一种解决方案。不过并不是所有的 k8s集群都会支持,大多是在公有云托管集群中会支持该类型。负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过Service的status.loadBalancer字段被发布出去,并且需要付费,作为开发人员,我们只做简单了解。

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: loadBalancerdemo
spec:
  selector:
    app: pod-bcst
  ports:
    - port: 8081 #集群内其他服务访问的端口号
      targetPort: 8080 # pod容器的端口号
      nodePort: 30008 #集群外部访问的端口号
  type: LoadBalancer

ExternalName

类型为ExternalName 的service将服务映射到 DNS 名称,而不是典型的选择器,例如my-service或者 mysql数据库。您可以使用spec.externalName参数指定这些服务。这种类型的 Service 通过返回域名和它的值,可以将服务映射到externalName 字段的内容( 例 如:hub.bcst.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何 的端口和 Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的域名这种方式来提供服务。作为开发人员,不经常使用,只做了解

创建 ExternalName 类型的服务的 yaml 如下:

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: externalNamedemo
spec:
  selector:
    app: pod-bcst
  ports:
    - port: 3000
      protocol: TCP
      targetPort: 443
  type: ExternalName
  externalName: www.bcst.com
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程识堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Service类型
  • Service和Pods
  • kube-proxy代理模式
    • Userspace代理模式
      • iptables代理模式
        • IPVS代理模式
        • ClusterIP
          • 使用镜像
            • 部署Service
              • 运行Service
              • NodePort
                • 使用镜像
                  • 部署service
                    • 运行service
                    • LoadBalancer
                    • ExternalName
                    相关产品与服务
                    容器服务
                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档