写点什么

GKE 上同一组 pod 同时支持多种 Service 模式

2020 年 4 月 06 日

GKE上同一组pod同时支持多种Service模式

GKE 是 Google Cloud 的 Kubernetes 的服务。其架构如下:



Master Node 是 Google 免费提供的,用户自己创建 Node Pool,不同的 Node Pool 可以采用不同的硬件配置,比如带 GPU 或不带 GPU。


在 GKE 上,创建不同的对外的服务接口,相应的将自动生成不同的服务:


  • 如果创建一个 ingress,系统将自动创建一个 http(s)的负载均衡或 L7 的 internal LB;

  • 如果创建一个 LoadBalancer 类型的 Service,系统将自动创建一个 TCP 的负载均衡;

  • 如果创建一个 LoadBalancer 类型的内网地址的 service,系统将自动创建一个 TCP 的 Internal loadbalancer;

  • 如果创建一个 nodeport 类型的 Service,不会自动生成 loadBalancer


本文将介绍这几种 service 如何创建,并特别介绍如何同时支持 ingress 和内网地址的 service。


创建 GKE cluster

创建 cluster

通过界面创建 GKE 的 cluster:



Cluster 创建成功:



kubectl 与 cluster 连接

在界面上点击 connect




复制 gcloud 命令


并在 cloud shell 中运行:



连接成功,可以通过 kubectl 控制 cluster:



二 部署 workload

通过 kubectl 命令创建 3 个 pod nginx 的 deployment:


$ kubectl run nginx --image=nginxdeployment.apps "nginx" created
$ kubectl scale deployment nginx --replicas=3deployment.extensions "nginx" scaled
复制代码


在 console 上可以看到:



通过 kubectl 查看:



cluster 网络

pod IP 地址段

查看 cluster 的详情:



因为 Google 的 GKE 采用的是 per pod per IP 的模式,Pod 的 IP 地址在 VPC 内:



这段地址是在创建 cluster 时自动创建的,专门用于 pods 的 IP 地址。另外在 VPC 内还有一段 IP 地址用于将来 Service 使用,比如 cluster IP。


node IP 地址


查看 node 的 IP:


可以看到,除标准段 primary Internal IP 外,这个 node 有一个 alias IP,是在 pods IP 内的一个 24 位掩码的地址段。在这个 node 上的 pod 将会使用这段地址。这样,每个 node 会有一段 IP 地址。这种设计和 K8s 网络的 flannel 类似:



GKE 中,这段 Alias IP 用于 Pod 间通讯,也可以用于和 GCE 的通讯。如上图,Node2 的 IP 地址为 10.1.1.22,Pod 的 IP 地址段是 10.40.2.0/24。此 Node 上的 Pod 地址都在这个 Alias IP 段内。GCE 10.100.1.10 与 Node2 的 Pod 进行通讯,可以直接和 10.40.2.10 或 10.40.2.11 直接通讯。跨 Node 的 Pod 间通讯,也直接用 Pod IP 进行通讯,比如 10.40.1.10 <-> 10.40.2.10。


pod 的 IP

查看 pod 信息可以看到 3 个 pod,运行在不同的 node 上,并且 IP 地址是 10.40.0.0/24,10.40.1.0/24, 10.40.2.0/24 的地址段。印证了我们前面观察到的 node ip 地址段。



在同一个网段的 VM 去 ping 和 curl 一个 pod,发现可以直接访问:



如前所述,这样的设计解决了在 K8s 集群中,跨 node 的 pod 通讯问题,也解决了非 cluster 内 IP 和 pod 通讯的问题。


创建 Load Balancer 类型的 service

创建 Service

在 Google Cloud console 中,



在 workload 界面中选择 expose



填入相应的参数,点击 expose:



由于类型选择的是 loadbalancer,GCP 会自动创建一个 TCP 的 loadbalancer。


Service 详情

首先查看 service:



看到 service 已经创建成功,类型是 load balancer 的。


负载均衡详情

再查看 loadbalancer:



可以看到一个 TCP 的 load balancer 已经创建成功。


后端采用的是添加 Instance 的方式:



前端生成一个公网 IP 地址:



通过这个 IP 地址,可以访问到访问:



创建内部 IP 的 service

通过 yaml 文件创建

在 cloud shell 中创建一个 yaml 文件:



apiVersion: v1


kind: Servicemetadata:  annotations:    cloud.google.com/load-balancer-type: Internal  labels:    run: nginx  name: nginx-internalspec:  ports:  - port: 80    protocol: TCP    targetPort: 80  selector:    run: nginx  type: LoadBalancer
复制代码


通过 kubectl 创建这个内部 IP 的 service:


$ kubectl apply -f ./internallb.yamlservice "nginx-internal" created
复制代码


service 详情


在 console 上可以看到已经创建成功。


详细信息中,可以看到:



内部 IP 是 10.1.1.27,这个地址是这个网段的 primary IP 地址段,Cluster IP 在 cluster 中定义的一致,后端有 3 个 pod,服务端口是 80,node port 是 30660,pod 内的 port 是 80.


ILB 详情

查看 ilb 信息:



在详细信息中,可以看到 backend 信息:



ILB 的后端采用 instance group 的形式。


ILB 的前端:



创建 ingress

创建基于 node port 的 service

创建 yaml 文件:


apiVersion: v1kind: Servicemetadata:  labels:    run: nginx  name: nginx-nodeportspec:  ports:  - port: 80    protocol: TCP    targetPort: 80  selector:    run: nginx  type: NodePort
复制代码


通过 kubectl 创建:


$ kubectl apply -f ./nodeport.yamlservice "nginx-nodeport" created
复制代码


nodeport service 详情


详情如下:



创建 ingress

创建 ingress 的 yaml 文件:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: prod-ingress-2spec:  rules:  - http:      paths:      - backend:          serviceName: nginx-nodeport          servicePort: 80
复制代码


创建 ingress:


$ kubectl apply -f ./ingress01.yamlingress.extensions "prod-ingress-2" created
复制代码


Ingress 详情

可以看到 ingress 创建成功:



详细内容:



http 负载均衡详情

可以看到 http 负载均衡已经创建成功:



后端情况,有两个 backend,但 instance group 相同:



Load balancer mode 采用的是 rate 模式:



Rule 有 3 条,分布引用这两个 backend service:



前端是有公网 IP 的 HTTP 配置:



通过这个公网 IP,同样可以访问到服务:



注意事项

注意到在 ingress 的 http 负载均衡中,load balancer 模式采用的是 rate 模式。


在实际操作中,如果先创建 ingress,有可能会采用 utilization 模式,而 ILB 的 backend 只能采用 rate 模式,此时再创建内部 IP 的 service 时,会出错:



查看 HTTP 负载均衡情况:



这个是 utilization 模式。造成不能创建 ILB。


目前,建议先创建内部 IP 的 service,再创建 ingress,这样可以避免这个问题。


总结

通过介绍如何创建 GKE 上各种 Service 类型,介绍了 Cluster 的创建、GKE 的网络组成、Ingress、ILB 模式的 Service,nodeport 模式的 service 的 Yaml 文件。以及在需要同时支持 ingress 和 ILB 模式 Service 是要注意的问题。


2020 年 4 月 06 日 20:14620

评论

发布
暂无评论
发现更多内容

Go1.16 发布

Rayjun

go

(28DW-S8-Day1) 定个魔幻的范围:在线教育+区块链

mtfelix

比特币 区块链 在线教育 28天写作 教育+区块链

翻译:《实用的Python编程》02_01_Datatypes

codists

Python 人工智能 数据结构与算法 字典 元组

Nginx零成本、易操作实现网站视频加速

运维研习社

nginx 流媒体 网站优化

程序员成长第十篇:从阅读代码开始

石云升

28天写作 2月春节不断更 阅读代码

计算机中的层次化存储是个什么鬼?

冰河

程序员 数据结构 算法 计算机 层次化存储

【看小说学编程】程序员在异世界生个娃 第二篇:外挂已准备就绪

1_bit

小说 C语言 原创小说 编程小说

MySQL 批量修改所有表字段字符集及排序规则

运维研习社

MySQ

管理笔记 [9]:组织与督导,管理者的两个宝

俊毅

28 天写作

说说规则引擎

张老蔫

28 天写作

2020 年行摄回忆录(下)

穿过生命散发芬芳

生活 摄影

游戏与心理学现学现卖系列·序章

Justin

心理学 28 天写作 游戏设计

如何解决Nginx实现动静分离或反向代理时资源路径不匹配

运维研习社

nginx 反向代理 动静分离

Let's Encrypt签发工具CertBot-auto不再维护

运维研习社

Dart 后台开发 Aqueduct ORM初始化数据库

人生如梦

Dart 后台开发 Aqueduct集成Swagger客户端

人生如梦

flutter dart

微服务架构:网关概念与zuul

程序员架构进阶

服务化 API网关 日更挑战 28天写作 2月春节不断更

【Python】关于 Type Hints 你应该知道这些(1/2)

zhujun

Python

干货 | Redis 实现发布订阅原理与实践

架构精进之路

redis 28 天写作 发布订阅

我的这一期=孩子

Ian哥

28 天写作

关于智商测试的一点闲话 Day1

道伟

科普 28天写作

2021 Flutter从零开始之全栈开发,后台到在线教育APP上线。

人生如梦

flutter dart

Flutter安卓项目第一次启动失败解决方案

人生如梦

flutter

为什么ElasticSearch比MySQL更适合全文索引

程序员历小冰

数据库 lucene elasticsearch BitMap 跳表

Java线程池趣味事:这不是线程池

Java王路飞

Java 程序员 面试 算法 JVM

这才是打开“金三银四”Java面试的正确方式,2021“金三银四”看这个就对了

云流

Java 架构 面试

28天瞎写的第二百三十九天:什么是正念冥想?

树上

冥想 28 天写作 正念

Dart 后台开发 Aqueduct 插入数据 获取数据API

人生如梦

flutter dart

Jenkins通过OpenSSH实现Windows下的CI/CD

运维研习社

jenkins CI/CD Windows Server 2012 R2

亿级流量架构之资源隔离思路与方法

程序员小毕

Java 程序员 架构 面试 分布式

Dart 后台开发 Aqueduct @Column标记

人生如梦

微服务架构下如何保证事务的一致性

微服务架构下如何保证事务的一致性

GKE上同一组pod同时支持多种Service模式-InfoQ