刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • Docker

  • k8s

    • k8s基础概念
    • k8s 集群架构
    • k8s工作负载
    • Pod网络
    • Service网络
    • 外部接入网络
      • NodePort
      • LoadBalancer
      • Ingress
      • 总结
    • 一张图搞懂k8s各种port
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • docker+k8s
  • k8s
bigox
2022-06-06
目录

外部接入网络

  • K8s网络的4层抽象

image-20220725013452246

# NodePort

  • 先看架构图,可以看出NodePort是K8s将内部服务对外暴露的基础,后面的LoadBalancer底层有赖于NodePort。

    image-20220725010933206

    image-20220725010955576

  • Kube-Proxy是K8s内部服务发现的一个关键组件,事实上,它还是K8s将内部服务暴露出去的关键组件。Kube-Proxy在K8s集群中所有Worker节点上都部署有一个,它掌握Service网络的所有信息,知道怎么和Service网络以及Pod网络互通互联。如果要将Kube-Proxy和节点网络打通(从而将某个服务通过Kube-Proxy暴露出去),只需要让Kube-Proxy在节点上暴露一个监听端口即可。这种通过Kube-Proxy在节点上暴露一个监听端口,将K8s内部服务通过Kube-Proxy暴露出去的方式,术语就叫NodePort(顾名思义,端口暴露在节点上)。下图是通过NodePort暴露服务的简化概念模型。

    image-20220725011207490

# LoadBalancer

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

  • 将K8s内部的服务通过NodePort方式暴露出去,K8s会在每个Worker节点上都开启对应的NodePort端口。逻辑上看,K8s集群中的所有节点都会暴露这个服务,或者说这个服务是以集群方式暴露的(实际支持这个服务的Pod可能就分布在其中有限几个节点上,但是因为所有节点上都有Kube-Proxy,所以所有节点都知道该如何转发)。既然是集群,就会涉及负载均衡问题,谁负责对这个服务的负载均衡访问?答案是需要引入负载均衡器(Load Balancer)。下图是通过LoadBalancer,将服务对外暴露的概念模型。

    在这里插入图片描述

  • 假设我们有一套阿里云K8s环境,要将K8s内部的一个服务通过LoadBalancer方式暴露出去,可以将服务发布(Kind: Service)的type设定为LoadBalancer。服务发布后,阿里云K8s不仅会自动创建服务的NodePort端口转发,同时会自动帮我们申请一个SLB,有独立公网IP,并且阿里云K8s会帮我们自动把SLB映射到后台K8s集群的对应NodePort上。这样,通过SLB的公网IP,我们就可以访问到K8s内部服务,阿里云SLB负载均衡器会在背后做负载均衡。

  • 如果是在本地开发测试环境里头搭建的K8s,一般不支持Load Balancer也没必要,因为通过NodePort做测试访问就够了。但是在生产环境或者公有云上的K8s,例如GCP或者阿里云K8s,基本都支持自动创建Load Balancer。

# Ingress

  • k8s 的服务(service)暴露service的三种方式ClusterIP、NodePort与LoadBalance,这 几种方式都是在service的维度提供的,单独用service暴露服务的方式,在实际生产 环境中不太合适:

    • ClusterIP的方式只能在集群内部访问。

    • NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时NodePort的端口管理是灾难。

    • LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。

  • k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。ingress规则是很灵活的,可以根据不同域名、不同path转发请求到不同的service,并且支持https/http。

  • Ingress本质上就是K8s集群中的一个比较特殊的Service(发布Kind: Ingress)。

  • 这个Service提供的功能主要就是7层反向代理(也可以提供安全认证,监控,限流和SSL证书等高级功能),功能类似Nginx。

  • 这个Service对外暴露出去是通过HostPort(80/443),可以和上面LoadBalancer对接起来。有了这个Ingress Service,我们可以做到只需购买一个LB+IP,就可以通过Ingress将内部多个(甚至全部)服务暴露出去,Ingress会帮忙做代理转发。

  • Ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。ingress规则是很灵活的,可以根据不同域名、不同path转发请求到不同的service,并且支持https/http。

  • Ingress(入口): Service 的统一网关入口

    • 底层是nginx 做的反向代理
    • 官网地址:https://kubernetes.github.io/ingress-nginx/

    image-20220725012152119

  • 有了前面的NodePort + LoadBalancer,将K8s内部服务暴露到外网甚至公网的需求就已经实现了,那么为啥还要引入Ingress这样一个概念呢?它起什么作用?

  • 在公有云(阿里云/AWS/GCP)上,公网LB+IP是需要花钱买的。我们回看上图的通过LoadBalancer(简称LB)暴露服务的方式,发现要暴露一个服务就需要购买一个独立的LB+IP,如果要暴露十个服务就需要购买十个LB+IP,显然,从成本考虑这是不划算也不可扩展的。那么,有没有办法只需购买一个(或者少量)的LB+IP,但是却可以按需暴露更多服务出去呢?答案其实不复杂,就是想办法在K8内部部署一个独立的反向代理服务,让它做代理转发。谷歌给这个内部独立部署的反向代理服务起了一个奇怪的名字,就叫Ingress,它的简化概念模型如下图所示:

    在这里插入图片描述

  • 那么哪些软件可以做这个Ingress?

    • 传统的Nginx/Haproxy可以,现代的微服务网关Zuul/SpringCloudGateway/Kong/Envoy/Traefik等等都可以。当然,谷歌别出心裁给这个东东起名叫Ingress,它还是做了一些包装,以简化对Ingress的操作。如果你理解了原理,那么完全可以用Zuul或者SpringCloudGateway,或者自己定制开发一个反向代理,来替代这个Ingress。部署的时候以普通Service部署,将type设定为LoadBalancer即可
  • 特点总结

    1. Ingress(入口): Service 的统一网关入口
    2. Ingress 本质上就是K8s集群中的一个比较特殊的Service(发布Kind: Ingress)。
    3. 这个Service提供的功能主要就是7层反向代理(也可以提供安全认证,监控,限流和SSL证书等高级功能),功能类似Nginx。
    4. Ingress是一个7层反向代理,如果你要暴露的是4层服务,还是需要走独立LB+IP方式。

# 总结

  1. NodePort是K8s内部服务对外暴露的基础,LoadBalancer底层有赖于NodePort。NodePort背后是Kube-Proxy,Kube-Proxy是沟通Service网络、Pod网络和节点网络的桥梁。
  2. 将K8s服务通过NodePort对外暴露是以集群方式暴露的,每个节点上都会暴露相应的NodePort,通过LoadBalancer可以实现负载均衡访问。公有云(如阿里云/AWS/GCP)提供的K8s,都支持自动部署LB,且提供公网可访问IP,LB背后对接NodePort。
  3. Ingress扮演的角色是对K8s内部服务进行集中反向代理,通过Ingress,我们可以同时对外暴露K8s内部的多个服务,但是只需要购买1个(或者少量)LB。Ingress本质也是一种K8s的特殊Service,它也通过HostPort(80/443)对外暴露。
  4. K8s的Service发布主要有3种type
    • type=ClusterIP,表示仅内部可访问服务
    • type=NodePort,表示通过NodePort对外暴露服务
    • type=LoadBalancer,表示通过LoadBalancer对外暴露服务(底层对接NodePort,一般公有云才支持)。
上次更新: 2023/06/02, 19:38:12
Service网络
一张图搞懂k8s各种port

← Service网络 一张图搞懂k8s各种port→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式