服务发现与负载均衡。

一、背景

在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;

对于测试「Tes」环境或者生产「Pro」环境,出于安全或者环境隔离性来考虑,在正常情况下只会开放网关服务,而「注册、配置」中心并不会对外暴露;

对于架构中的其它业务服务一般不会对外开放,在K8S集群内部服务间是可以正常通信的,对于「Dev」环境来说,研发会使用「注册、配置」中心,网关是系统的访问入口;

在K8S集群中,通过Service组件,可以快速简单的实现服务发现和负载均衡;

二、Service组件

1、简介

在K8S集群中是通过Pod组件来部署应用服务,Deployment组件实现Pod编排管理,Service组件实现应用的访问;

【Pod】自身的特点是临时的,使用过后直接抛弃的实体,这样在Pod创建和销毁的状态中,会导致IP地址发生变化,即无法使用固定的IP进行应用访问;

【Deployment】控制器通过管理ReplicaSet间接实现Pod管理,比如发布方式,更新和回滚策略,维持Pod副本数量,对应用进行快速的编排,但是并没有涉及应用的访问;

【Service】是将运行在一个或一组Pod上的网络应用程序公开为网络服务的方法,可以在不修改现有应用程序的情况下,使用服务发现机制访问到该应用;

基于Pod、Deployment、Service三个组件的协作,同一个应用的部署脚本可以在开发、测试、生产不同环境中复用;

2、基础语法

这里提供一个简单的【Service】语法做参考;

需要注意的是:在该脚本中没有指定服务类型即ServiceType,默认采用的是ClusterIP,通过集群的内部IP暴露服务,选择该值时服务只能够在集群内部访问;

三、内部服务发现

1、Pod创建

基于【Deployment】组件,创建「auto-serve」应用;

apiVersion: apps/v1
kind: Deployment
metadata:
name: serve-deployment
labels:
app: auto-serve
spec:
replicas: 1
selector:
matchLabels:
app: auto-serve
template:
metadata:
labels:
app: auto-serve
spec:
containers:
- name: auto-serve
image: auto-serve:latest
imagePullPolicy: Never
ports:
- containerPort: 8082
name: auto-serve-port

执行创建命令

kubectl apply -f serve-deployment.yaml

2、Service创建

简单的脚本文件:app-service.yaml

apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: auto-serve
ports:
- name: app-service-port
protocol: TCP
port: 8082
targetPort: auto-serve-port

创建【Service】

kubectl apply -f app-service.yaml

查看【Service】,可以使用命令行或者界面;

kubectl describe svc app-service

删除【Service】

kubectl delete -f app-service.yaml

3、内部访问

在上面已经说明,当Type不指定时采用的是ClusterIP,只能在集群内部访问,集群外部的网络是无法访问的;

在【auto-client】服务中提供一段访问【auto-serve】接口的代码,并制作镜像【auto-client:3.3.3】,完成部署后查看日志打印;

@Component
public class HttpServiceJob { private static final Logger LOG = LoggerFactory.getLogger(HttpServiceJob.class.getName()) ; private static final String SERVER_NAME = "http://app-service:8082/serve";
private static final String SERVER_IP = "http://10.103.252.94:8082/serve"; /**
* 每30秒执行一次
*/
@Scheduled(fixedDelay = 30000)
public void systemDate () {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(3000);
factory.setConnectTimeout(6000);
RestTemplate restTemplate = new RestTemplate(factory); try {
Map<String, String> paramMap = new HashMap<>();
String result = restTemplate.getForObject(SERVER_NAME, String.class, paramMap);
LOG.info("service-name-resp::::" + result);
} catch (Exception e) {
e.printStackTrace();
} try {
Map<String, String> paramMap = new HashMap<>();
String result = restTemplate.getForObject(SERVER_IP, String.class, paramMap);
LOG.info("service-ip-resp::::" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}

在代码中通过服务名:端口IP:端口都可以正常访问,在Pod中查看两个应用的日志,请求和响应都正常;

四、外部服务发现

1、NodePort类型

指定类型为NodePort的脚本:app-np-service.yaml

apiVersion: v1
kind: Service
metadata:
name: app-np-service
spec:
type: NodePort
selector:
app: auto-serve
ports:
- protocol: TCP
port: 8082
targetPort: 8082
nodePort: 30010

创建【Service】

kubectl apply -f app-np-service.yaml

使用NodePort类型,K8S控制平面会在指定的范围内分配端口,如果需要特定的端口号可以指定nodePort字段中的值,但是该类型需要自己设置负载均衡解决方案;

2、LoadBalancer类型

指定类型为LoadBalancer的脚本:app-lb-service.yaml

apiVersion: v1
kind: Service
metadata:
name: app-lb-service
spec:
type: LoadBalancer
selector:
app: auto-serve
ports:
- protocol: TCP
port: 8082
targetPort: 8082

创建【Service】

kubectl apply -f app-lb-service.yaml

查看【Service】

在查看「app-lb-service」时,值得注意一下Endpoints的字段属性,这里就是Pod选择器选中的Pod

kubectl get svc app-lb-service -o wide

NAME             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE     SELECTOR
app-lb-service LoadBalancer 10.111.65.220 localhost 8082:30636/TCP 6m49s app=auto-serve kubectl describe svc app-lb-service Name: app-lb-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=auto-serve
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.65.220
IPs: 10.111.65.220
LoadBalancer Ingress: localhost
Port: <unset> 8082/TCP
TargetPort: 8082/TCP
NodePort: <unset> 30636/TCP
Endpoints: 10.1.0.160:8082,10.1.0.161:8082,10.1.0.162:8082
Session Affinity: None
External Traffic Policy: Cluster
Events: <none> kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE
serve-deployment-f6f6c5bbd-9qvgr 1/1 Running 0 39m 10.1.0.162 docker-desktop
serve-deployment-f6f6c5bbd-w7nj2 1/1 Running 0 39m 10.1.0.161 docker-desktop
serve-deployment-f6f6c5bbd-x7v4d 1/1 Running 0 39m 10.1.0.160 docker-desktop

五、参考源码

文档仓库:
https://gitee.com/cicadasmile/butte-java-note 脚本仓库:
https://gitee.com/cicadasmile/butte-auto-parent

K8S | Service服务发现的更多相关文章

  1. k8s DNS 服务发现的一个坑

    按照官当文档,以及大家的实践进行k8s dns 服务发现搭建还是比较简单的,但是会有一个因为系统默认dns 配置造成的一个问题 1. linux  默认dns 配置在 /etc/resolv.conf ...

  2. kubernetes service服务发现两种方式

    service服务发现ClusterIP方式 1.暴露deployment服务 kubectl expose deployment nginx4 --port=8000 --target-port=8 ...

  3. k8s之服务发现

    一.概述 k8s中支持两种服务发现方法: 环境变量和DNS 二.环境变量 当Pod被创建的时候,k8s将为Pod设置每一个Service的相关环境变量,这些环境变量包括两种类型: k8s Servic ...

  4. ZooKeeper是按照CP原则构建的,不适合做Service服务发现

    一.cap 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据变动都是同步的. ②A:Avail ...

  5. Service 服务发现的两种方式-通过案例来理解+服务外部访问类型+selector-label

    1.环境变量 在创建一个Pod时,kubelet在该Pod的所有容器中为当前所有Service添加一系列环境变量. 例如,已存在名称为“redis-master”的Service,它对外暴露6379的 ...

  6. 从零开始入门 | Kubernetes 中的服务发现与负载均衡

    作者 | 阿里巴巴技术专家  溪恒 一.需求来源 为什么需要服务发现 在 K8s 集群里面会通过 pod 去部署应用,与传统的应用部署不同,传统应用部署在给定的机器上面去部署,我们知道怎么去调用别的机 ...

  7. Kubernetes 中的服务发现与负载均衡

    原文:https://www.infoq.cn/article/rEzx9X598W60svbli9aK (本文转载自阿里巴巴云原生微信公众号(ID:Alicloudnative)) 一.需求来源 为 ...

  8. k8s service NodePort 方式向外发布

    k8s service NodePort 方式向外发布 k8s 无头service 方式向内发布 k8s service 服务发现 {ServiceName}.{Namespace}.svc.{Clu ...

  9. Docker与k8s的恩怨情仇(七)—— “服务发现”大法让你的内外交互原地起飞

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 第一章:Docker与k8s的恩怨情仇(一)-成为PaaS前浪的Cloud Foundry 第二章:Dock ...

  10. Prometheus服务发现之kubernetes_sd_config

    一.为什么要使用Prometheus服务发现 之前我们讲过通过配置prometheus-operator的CRD ServiceMonitor来达到K8S集群相关组件和微服务的监控的目的,可以在Ser ...

随机推荐

  1. AGC061 F Perfect String

    毒瘤出题人,史诗加强 AGC 的 F-- 然而我连原题都不会,所以只学了原题做法. 翻译一下题意就是给定一张循环网格图,求经过 \((0,0)\) 的闭合回路条数. 由于网格图中每一个位置都等价,所以 ...

  2. 高级Java程序员必问,Redis事务终极篇

    1. 简介 1.1 什么是Redis事务 Redis事务(Transaction)通过将多个Redis操作封装为一个原子性的操作序列,确保在事务执行过程中,不会受到其他客户端的干扰.从而在保证数据一致 ...

  3. LeetCode 周赛 344(2023/05/07)手写递归函数的固定套路

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 今天下午有力扣杯战队赛,不知道官方是不是故意调低早上周赛难度给选手们练练手. 往期周赛回 ...

  4. oracle异常处理

    序言 最近在工作中遇到这么一个场景: 在同一网段内存在着A库和B库,需要将A库下某些表的数据同步到B库 B库跑着定时任务,定时调用存储过程将A库下的数据同步到B库. B库和A库是通过建立dblink建 ...

  5. Vue 前端开发团队风格指南(史上最全)

    Vue官网的风格指南按照优先级(依次为必要.强烈推荐.推荐.谨慎使用)分类,本文根据项目实际情况整理了一份适用于团队开发的vue风格指南,供大家参考. 一.命名规范 常用的命名规范: camelCas ...

  6. Grafana系列-统一展示-7-ElasticSearch数据源

    系列文章 Grafana 系列文章 ElasticSearch 数据源 Grafana内置了对Elasticsearch的支持.你可以进行多种类型的查询,以可视化存储在Elasticsearch中的日 ...

  7. Tensorflow 2下载网址

    Tensorflow2: 官网:https://tensorflow.google.cn/ 一个核心开源库,可以帮助您开发和训练机器学习模型.您可以通过直接在浏览器中运行 Colab 笔记本来快速上手 ...

  8. Vue3.3 的新功能的体验(下):泛型组件(Generic Component) 与 defineSlots

    上一篇说了 DefineOptions.defineModel.Props 的响应式解构和从外部导入类型 这几个新功能,但是没有说Generic.defineSlots等,这是因为还没有完全搞清楚可以 ...

  9. HashMap 以及多线程基本感念

    接口 Map :映射项,(键值对 ) 的容器注意: 键 是唯一的 值 是可以重复的实现类 HashMap :哈希表结构 允许使用null值 和 null 键 线程不安全 键唯一 无序 linkedHa ...

  10. Python time strftime() 方法的使用

    1.描述 strftime() 用于格式化时间,返回以可读字符串表示的时间,格式自定义. 2.说明 python中日期和时间的格式化符号有很多,下面列举常用的符号:  %y 两位数的年份表示(00-9 ...