通过 .NET Core + Kubernetes:Deployment 文章的介绍,我们可以通过 Deployment 控制器快速创建一组 Pod 来提供服务,每个 Pod 都会被分配一个集群内可见的虚拟 IP 地址,然后通过一个独立的 Endpoint(Pod IP + ContainerPort)进行访问。但在提供服务时,并不能依赖 Pod  的 Endpoint,首先 Pod IP 会随着 Pod 的重建而变化,另外同一组 Pod 更希望是以整体对外提供高可用服务,组内的 Pod 在进行动态伸缩、滚动更新等操作后并不能影响服务稳定性。

因此,Kubernetes 中的 Service 对象就是解决此问题的核心,Service 代理 Pod 集合对外表现是为一个访问入口,它提供了一个虚拟的 IP 地址(ClusterIP)和端口,来自 ClusterIP + 端口  的请求将被负载均衡器 (kube-proxy)转发到后端某个 Pod 中的容器。所以借助 Service 的能力,非常方便的实现了服务发现与负载均衡。

本文将主要介绍 Kubernetes 中各 Service 类型的使用,目前有以下四种类型:

  • ClusterIP:默认类型,自动分配一个仅集群内部可以访问的虚拟 IP,也可使用 ClusterIP 字段指定固定 IP,选择此类型意味着只想这个服务在集群内部才可以被访问

  • NodePort:在 ClusterIP 基础上,在集群的每一个节点绑定一个端口,这样就可以通过任意的:NodePort 来访问服务

  • LoadBalancer:在 NodePort 的基础上,通过创建一个外部的负载均衡器,将流量转发到每个节点:NodePort。因为如果外部所有客户端都访问一个 NodeIP,该节点的压力将会很大,LoadBalancer 则可解决此问题

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

下面分别对这几种类型的使用方式进行介绍,在创建 Service 之前,还是先通过 Deployment 控制器创建一组 Pod,配置文件 k8sdemo-deployment.yaml 如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: k8sdemo-deployment
spec:replicas: 3selector:matchLabels:name: k8sdemotemplate:metadata:labels:name: k8sdemospec:containers:- name: k8sdemoimage: beckjin/k8sdemo:1.0.0ports:- containerPort: 80imagePullPolicy: IfNotPresent

ClusterIP 类型

创建 k8sdemo-service.yaml 文件,配置如下,主要是  portsselector 字段的设置,指定了 80 端口(port) 映射到 Pod ContainerPort (targetPort) 端口,最终将通过 ClusterIP:80 访问服务。selector 字段指定将 label 含 name:k8sdemo 的 Pod 作为这个 Service 指向的目标服务。

apiVersion: v1
kind: Service
metadata:name: k8sdemo-service
spec:ports:- port: 80                 # Service PorttargetPort: 80           # Pod ContainerPortselector:name: k8sdemo# clusterIP: 10.1.19.92   # 取消注释指定IP

执行命令 kubectl apply -f k8sdemo-service.yaml 创建 Service,然后通过 kubectl get service 查看服务状态:

从上图可以看出 k8sdemo-service 被分配的 ClusterIP 是 10.1.19.96,所以可以在服务器上通过 curl http://10.1.19.96/WeatherForecast 来访问接口。

因为 ClusterIP 默认是自动分配的,所以每次重建会变化,如果需要固定,可通过 ClusterIP 字段设置。对于只需在集群内部提供的服务,ClusterIP 类型已足够。

NodePort 类型

基于 ClusterIP 类型中使用的配置文件 k8sdemo-service.yaml,增加 type: NodePort 配置,重新创建 Service,如下:

apiVersion: v1
kind: Service
metadata:name: k8sdemo-service
spec:ports:- port: 80targetPort: 80# nodePort: 30080   # 取消注释指定端口selector:name: k8sdemotype: NodePort

从上图可以看出,除了类型变了, PORT(S)也变成了 80:30231/TCP,即将 Service 的 80 端口与集群中各节点的 30231 端口进行映射,所以最终可以通过集群内任意的 NodeIP:30231 来访问,整个过程为:Client > NodeIP:NodePort > ClusterIP:ServicePort > PodIP:ContainerPort。NodePort 默认分配的是 30000-32767 范围内随机选择的一个端口,实际使用时可以通过 nodePort 字段指定。请求结果如下:

注:192.168.124.10 是集群内某一台的 IP

LoadBalancer 类型

通过 NodePort 类型的使用介绍,已经了解可以通过 NodeIP:NodePort 方式来服务访问,而且 NodeIP 可以是集群内任意任何一台的 IP。而 LoadBalancer 则是在外层附加的负载均衡器,使请求能分摊到集群内各个节点上。

MetalLB 搭建

要使用 LoadBalancer 类型会稍微复杂一些,并不能只单纯的修改配置文件,因为一般自建的 Kubernetes 集群默认并不支持 LoadBalancer,所以它需要借助外部的负载均衡器来实现,这里将使用 MetalLB[1] (v0.9.3),安装请参考 Installation By Manifest[2] ,步骤不复杂,但需要确保依赖镜像下载顺利,完成后查看 Pod 状态:

另外需要为 Metallb 设置地址池以及协议相关配置,Metallb 会监控服务对象的变化,当有新的 LoadBalancer 服务运行,但没有可申请的负载均衡器时,就会从配置的地址池中分配一个给该服务。这里以 Metallb Layer2 工作模式为例(Metallb 支持 Layer2/BGP 两种工作模式),创建一个资源类型为 ConfigMap 的配置文件 metallb-layer2-config.yaml,内容如下:

apiVersion: v1
kind: ConfigMap
metadata:namespace: metallb-systemname: config
data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.124.200-192.168.124.210  # IP 地址范围需与自己的集群环境对应

Layer2  工作模式原理图:

配置修改

有了以上的准备工作后,只需要在 Service 配置文件将 type 修改为 LoadBalancer ,然后重新创建 Service,如下:

apiVersion: v1
kind: Service
metadata:name: k8sdemo-service
spec:ports:- port: 80targetPort: 80selector:name: k8sdemotype: LoadBalancer

从上图可以看出,TYPE 已是 LoadBalancer,另外 EXTERNAL-IP 被分配为地址池中的 192.168.124.200,接下来就可以通过这个 IP 进行访问了,结果如下:

ExternalName

ExternalName 类型比较特殊,它没有 selector,也没有定义任何的端口, 对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务,如下:

apiVersion: v1
kind: Service
metadata:name: k8sdemo-external-service
spec:type: ExternalNameexternalName: mingdao.com

当访问 k8sdemo-external-service.default.svc.cluster.local 时,集群的 DNS 服务将返回值为 mingdao.com 的 CNAME 记录,访问这种类型的服务与其它的唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。

进入 Kubernetes 集群的任意一个 Pod 中(必须是集群内部才可访问),如:kubectl exec -it k8sdemo-deployment-68cb864ff6-fzzdq -- /bin/bash,执行 curl -L http://k8sdemo-external-service.default.svc.cluster.local/ 即会重定向请求到 mingdao.com,结果如下:

参考资料

[1]

MetalLB: https://metallb.universe.tf/

[2]

Installation By Manifest: https://metallb.universe.tf/installation/#installation-by-manifest

.NET Core + Kubernetes:Service相关推荐

  1. 增加service_.NET Core + Kubernetes:Service

    通过 .NET Core + Kubernetes:Deployment 文章的介绍,我们可以通过 Deployment 控制器快速创建一组 Pod 来提供服务,每个 Pod 都会被分配一个集群内可见 ...

  2. .NET Core + Kubernetes:Deployment

    在上篇文章 .NET Core + Kubernetes:Pod 中,主要介绍了 Pod 的相关内容, 基于 Pod 为单位能更加合理进行容器编排,然而 Pod 只是个启动了一个或一组容器的资源类型, ...

  3. .NET Core + Kubernetes:Pod

    在 .NET Core + Kubernetes:快速体验 文章中,已经实现将一个 .NET Core API 服务部署在 Kubernetes 集群中,接下来将逐步了解 Kubernetes 中各核 ...

  4. .NET Core + Kubernetes:StatefulSet

    在 Kubernetes 中,Pod 资源的控制器 Deployment.Replicaset.Daemonset 等常用于管理无状态应用,它们所管理的 Pod 对应的 IP.名字,启停顺序等都是随机 ...

  5. .NET Core + Kubernetes:Volume

    和 Docker 类似,Kubernetes 中也提供了  Volume 来实现数据卷挂载,但 Kubernetes 中 Volume 是基于 Pod,而不是容器,它可被 Pod 中多个容器共享,另外 ...

  6. .NET Core + Kubernetes:快速体验

    Kubernetes[1] 是目前非常主流的容器编排工具,在应用创建.应用部署.应用扩容.应用更新等方面都非常的方便,而且在应用故障时,也可以快速自愈.所以基于微服务架构下的产品,了解 Kuberne ...

  7. k8s使用volume将ConfigMap作为文件或目录直接挂载_NET Core + Kubernetes:Volume

    和 Docker 类似,Kubernetes 中也提供了 Volume 来实现数据卷挂载,但 Kubernetes 中 Volume 是基于 Pod,而不是容器,它可被 Pod 中多个容器共享,另外 ...

  8. .NET Core + Kubernetes:Helm

    Helm[1] 作为 Kubernetes 体系的包管理工具,已经逐渐成为了应用分发标准,在 .NET 开发中,可以理解为与 NuGet 包类似.回顾之前文章中的介绍,Kubernetes 中单个服务 ...

  9. Kubernetes:Service

    文章目录 1.Service 定义 1.1.无选择符的服务 1.2.Endpoints 2.服务发布类型 2.1.ClusterIP 2.2.NodePort 2.3.ExternalName 2.4 ...

最新文章

  1. Ubuntu16.04 + caffe-ssd + [CPU_ONLY] + KITTI 训练总结
  2. 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
  3. Sql server 2005 中的dense_rank()函数的应用
  4. iptables 学习笔记 二 参数指令
  5. HDF及HDF-EOS数据格式简介
  6. Hyper-V passes Microsoft’s checkmarks exam: isn’t that always the case?
  7. 蓝桥杯 ALGO-11算法训练 瓷砖铺放(递归/动态规划)
  8. 网络工程师考试视频教程
  9. 七周成为数据分析师 第五周:Mysql
  10. Learning to Fuse Asymmetric Feature Maps in Siamese Trackers 论文与代码笔记
  11. Matlab同步脉冲触发器参数,脉冲参数有哪些?脉冲参数介绍
  12. 万人总结的软件测试面试简历及软件测试面试题
  13. linux系统用户默认的shell,linux默认的shell是什么
  14. opencv05:图像的基本操作
  15. Intel 计划在Linux kernel中引入 User Interrupts,效率是eventfd的10倍
  16. 虚拟机(一)虚拟机安装Mysql
  17. DC入门(一)综合基础
  18. Windows Server Core 2022 (一)安装
  19. 超级3合1U盘维护系统
  20. Unity中实现放大镜的功能

热门文章

  1. 面向对象——一起来复习托付与事件!
  2. Log4j.properties 配置详解
  3. 数据结构C#版笔记--堆栈(Stack)
  4. 从零开始学习jQuery (九) jQuery工具函数 【转】
  5. vista磁盘使用100%_如何在Windows 7或Vista中创建和使用密码重置磁盘
  6. 什么是Adobe Lightroom,我需要它吗?
  7. natcat for mysql_用Navicat for mysql连接mysql报错1251-解决办法
  8. java B2B2C 仿淘宝电子商城系统-Spring Cloud Eureka参数配置项详解
  9. Java并发(二十一):线程池实现原理
  10. box-shadow阴影合集