.NET Core + Kubernetes:Service
通过 .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
文件,配置如下,主要是 ports
和 selector
字段的设置,指定了 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相关推荐
- 增加service_.NET Core + Kubernetes:Service
通过 .NET Core + Kubernetes:Deployment 文章的介绍,我们可以通过 Deployment 控制器快速创建一组 Pod 来提供服务,每个 Pod 都会被分配一个集群内可见 ...
- .NET Core + Kubernetes:Deployment
在上篇文章 .NET Core + Kubernetes:Pod 中,主要介绍了 Pod 的相关内容, 基于 Pod 为单位能更加合理进行容器编排,然而 Pod 只是个启动了一个或一组容器的资源类型, ...
- .NET Core + Kubernetes:Pod
在 .NET Core + Kubernetes:快速体验 文章中,已经实现将一个 .NET Core API 服务部署在 Kubernetes 集群中,接下来将逐步了解 Kubernetes 中各核 ...
- .NET Core + Kubernetes:StatefulSet
在 Kubernetes 中,Pod 资源的控制器 Deployment.Replicaset.Daemonset 等常用于管理无状态应用,它们所管理的 Pod 对应的 IP.名字,启停顺序等都是随机 ...
- .NET Core + Kubernetes:Volume
和 Docker 类似,Kubernetes 中也提供了 Volume 来实现数据卷挂载,但 Kubernetes 中 Volume 是基于 Pod,而不是容器,它可被 Pod 中多个容器共享,另外 ...
- .NET Core + Kubernetes:快速体验
Kubernetes[1] 是目前非常主流的容器编排工具,在应用创建.应用部署.应用扩容.应用更新等方面都非常的方便,而且在应用故障时,也可以快速自愈.所以基于微服务架构下的产品,了解 Kuberne ...
- k8s使用volume将ConfigMap作为文件或目录直接挂载_NET Core + Kubernetes:Volume
和 Docker 类似,Kubernetes 中也提供了 Volume 来实现数据卷挂载,但 Kubernetes 中 Volume 是基于 Pod,而不是容器,它可被 Pod 中多个容器共享,另外 ...
- .NET Core + Kubernetes:Helm
Helm[1] 作为 Kubernetes 体系的包管理工具,已经逐渐成为了应用分发标准,在 .NET 开发中,可以理解为与 NuGet 包类似.回顾之前文章中的介绍,Kubernetes 中单个服务 ...
- Kubernetes:Service
文章目录 1.Service 定义 1.1.无选择符的服务 1.2.Endpoints 2.服务发布类型 2.1.ClusterIP 2.2.NodePort 2.3.ExternalName 2.4 ...
最新文章
- Ubuntu16.04 + caffe-ssd + [CPU_ONLY] + KITTI 训练总结
- 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
- Sql server 2005 中的dense_rank()函数的应用
- iptables 学习笔记 二 参数指令
- HDF及HDF-EOS数据格式简介
- Hyper-V passes Microsoft’s checkmarks exam: isn’t that always the case?
- 蓝桥杯 ALGO-11算法训练 瓷砖铺放(递归/动态规划)
- 网络工程师考试视频教程
- 七周成为数据分析师 第五周:Mysql
- Learning to Fuse Asymmetric Feature Maps in Siamese Trackers 论文与代码笔记
- Matlab同步脉冲触发器参数,脉冲参数有哪些?脉冲参数介绍
- 万人总结的软件测试面试简历及软件测试面试题
- linux系统用户默认的shell,linux默认的shell是什么
- opencv05:图像的基本操作
- Intel 计划在Linux kernel中引入 User Interrupts,效率是eventfd的10倍
- 虚拟机(一)虚拟机安装Mysql
- DC入门(一)综合基础
- Windows Server Core 2022 (一)安装
- 超级3合1U盘维护系统
- Unity中实现放大镜的功能
热门文章
- 面向对象——一起来复习托付与事件!
- Log4j.properties 配置详解
- 数据结构C#版笔记--堆栈(Stack)
- 从零开始学习jQuery (九) jQuery工具函数 【转】
- vista磁盘使用100%_如何在Windows 7或Vista中创建和使用密码重置磁盘
- 什么是Adobe Lightroom,我需要它吗?
- natcat for mysql_用Navicat for mysql连接mysql报错1251-解决办法
- java B2B2C 仿淘宝电子商城系统-Spring Cloud Eureka参数配置项详解
- Java并发(二十一):线程池实现原理
- box-shadow阴影合集