热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

k8sservicetype_K8S实战(十)|Service

前言Pod已经成功运行起来了,但是有两个问题。一是这些Pod无法从集群外部直接访问到,二是Pod出现故障自愈后,IP会发生变化。如何解决这
f3472f56779ffa6cf719a70519d4f773.png

前言

Pod 已经成功运行起来了,但是有两个问题。

一是这些 Pod 无法从集群外部直接访问到,二是 Pod 出现故障自愈后,IP 会发生变化。

如何解决这两个问题,这里有一个非常重要的概念:Service

更新历史

  • 20200625 - 初稿 - 左程立
  • 原文地址 - https://blog.zuolinux.com/2020/06/25/about-service.html

Service 的意义和特点

  1. 对一组 Pod 提供负载均衡(工作在 TCP/UDP 4 层)
  2. 防止 Pod 更换 IP 失联,即服务发现
  3. 通过 label selector 关联 Pod

Service 工作原理

Service 是由 kube-proxy 组件加上 iptables/LVS 共同实现。 说白了就是通过 kube-proxy 生成了一堆 iptables 规则,通过 iptables 规则来转发数据。

iptables 转发:

  1. K8S 默认的转发设置。
  2. 选择后端 Pod 为随机选择。
  3. 当 Pod 没有响应,连接会失败,并没有健康检查机制。
  4. 需要配合 Pod 就绪探测器来确保访问到健康的 Pod。
  5. 当集群规模达到上万个服务时,iptables 转发效率会显著降低。

LVS转发:

  1. 基于内核哈希表,性能强大,具有更高网络吞吐量。
  2. 适用于 Pod 量级大,转发规则更多的大规模集群。
  3. LVS 支持更多的 Pod 负载均衡调度算法。
  4. LVS 只负责负载均衡和代理功能,剩余的包过滤和SNAT等操作还是需要 iptables 处理,但这些操作规则数量不会因 Pod 数量的增加而增加。
  5. 也叫 IPVS 。

Service 的默认工作方式

创建 Pod 和 默认Service,进行默认工作状态的测试。

先创建3个 Pod

cat nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:selector:matchLabels:app: nginxreplicas: 3template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80

创建一个默认类型的 Service,名称为 nginx-service

cat nginx-service.yaml

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:app: nginxports:- port: 80targetPort: 80protocol: TCP

port: 80 是 service 在集群内部的VIP端口

targetPort: 80 是 Pod 的端口

执行创建

kubectl apply -f nginx.yaml
kubectl apply -f nginx-service.yaml

查看运行情况

[root@master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-d46f5678b-cldf4 1/1 Running 0 21m 192.10.137.153 work03
nginx-deployment-d46f5678b-lnxh9 1/1 Running 0 21m 192.10.205.252 work01
nginx-deployment-d46f5678b-th8xq 1/1 Running 0 21m 192.10.75.89 work02 [root@master01 ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 192.20.150.26 80/TCP 13m

查看名称为 nginx-service 的 service 成功挂载的后端 Pod

[root@master01 ~]# kubectl get endpoints nginx-service
NAME ENDPOINTS AGE
nginx-service 192.10.137.153:80,192.10.205.252:80,192.10.75.89:80 14m

可以看到我们创建的名为 nginx-service 的 Service 后端挂载了3个 Pod

给3个 Pod 写入内容,访问 Pod 时返回自身的主机名

kubectl exec nginx-deployment-d46f5678b-cldf4 -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html';
kubectl exec nginx-deployment-d46f5678b-lnxh9 -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html';
kubectl exec nginx-deployment-d46f5678b-th8xq -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html';

我们访问 Service IP 看看

[root@master01 ~]# curl 192.20.150.26
nginx-deployment-d46f5678b-th8xq
[root@master01 ~]# curl 192.20.150.26
nginx-deployment-d46f5678b-cldf4
[root@master01 ~]# curl 192.20.150.26
nginx-deployment-d46f5678b-lnxh9

可以看到 Service 成功将请求代理到了后端的一组 Pod,并且进行了流量的分配。

这是 Service 的默认工作类型,只能在集群所属的节点上访问到,离开集群后无法被访问到。

这种工作类型叫做 ClusterIP。

Service 对外提供服务的三种方式

上一节可以看到,Service 默认不对集群外部提供服务,那么如何才能在集群外部访问到呢,有三种方案。

externalIPs 方式

Service 中配置可以 externalIPs,IP 为本集群中 work 节点宿主机 IP。

apiVersion: v1
kind: Service
。。。
。。。
spec:。。。。。。externalIPs:- 192.168.10.16- 192.168.10.17

在 192.168.10.16/17 上执行 ss -lntp 可以看到 Service 定义的暴露端口。 在集群外部访问 192.168.10.16/17 上 Service 暴露的端口即可。

NodePort 方式

改造 nginx-service.yaml,增加一行 type: NodePort

cat nginx-service.yaml

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:type: NodePortselector:app: nginxports:- port: 80targetPort: 80protocol: TCP

创建 service

kubectl apply -f nginx-service.yaml

查看运行情况

[root@master01 ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 192.20.167.221 80:30913/TCP 13m

参数 PORT(S) 80:30913/TCP,其中 30913 就是用来集群外部访问的端口。

可以访问任何一台物理宿主机的 ip:30913 来访问到 Pod。

30913 是 K8S 从固定范围 30000-32767 中选择的,也可以通过参数 nodePort 指定固定端口。

可选择范围可以通过 kube-apiserver 的 –service-node-port-range 参数来修改。

[root@master01 ~]# ss -nltp | grep 30913
LISTEN 0 128 *:30913 *:*

可以看到宿主机上监听了 30913 端口。

测试

在没有运行 K8S 集群的机器上访问 K8S 宿主机[root@192-168-10-18 ~]# curl 192.168.10.12:30913
nginx-deployment-d46f5678b-2pmts
[root@192-168-10-18 ~]# curl 192.168.10.12:30913
nginx-deployment-d46f5678b-zv8m4
[root@192-168-10-18 ~]# curl 192.168.10.12:30913
nginx-deployment-d46f5678b-2pmts

可以看到从集群外部可以成功访问到 Pod 中内容,并且为随机分配。

原理

kube-proxy 在宿主机上创建了 iptables 规则,对宿主机 IP:30913 的访问将被转发到 Service IP,然后 Service 再通过自己的 iptables 规则分发到 Pod

LoadBalancer 方式

NodePort 方式中,如果要正式对外提供服务,我们需要在集群外部再创建一个高可用的负载均衡器,以方便把流量转发到宿主机开放的端口上,如果宿主机开放端口发生了变更,我们需要手工修改前端负载均衡器。

公有云的 LoadBalancer 自动化了这一过程。

LoadBalancer 这种方式应用于公有云,提交一个 type: LoadBalancer 的 Service 创建申请后,公有云会帮我们创建一个负载均衡器,该负载均衡器会把请求直接分发给 Pod,同时 Pod IP 发生变化后,会自动更新到负载均衡器上。

其他:Headless Service

通过指定 spec.clusterIP 的值为 "None" 可以创建 Headless Service。

Headless Service 不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。

定义了 selector 的无头服务,Endpoint 控制器会在 API 中创建 Endpoints 记录, 并且修改 DNS 配置返回 A 记录,通过这个地址,请求可以直接到达 Service 的后端 Pod 上。

结束语

Service 对 IP 信息易变的 Pod 提供了服务发现、负载均衡等管理功能,同时提供了外部访问的能力,从而使外部用户能够稳定的访问到运行在集群内部的 Pod 提供的服务。

上面说的三种工作方式有如下问题:

  1. ClusterIP 方式默认工作在集群内部,使用参数 externalIPs 可指定哪个及诶按暴露端口,但无法进行7层的URL跳转等控制
  2. NodePort 方式下,全部节点都会暴露该端口,但一个端口只能对应一个业务,适合业务比较少的环境或者测试环境,业务多了以后无法有效管理
  3. LoadBalance 方式只适合于现有的公有云平台,无法用于自建集群,同时还需要额外费用

这些问题导致无法直接应用于生产环境中。

如果想提供给自建集群的生产环境使用,需要在 Service 前面再加一层 Ingress Controller。

联系我

微信公众号:zuolinux_com

http://weixin.qq.com/r/nUzg_DbEaGsXrXKb9xmP (二维码自动识别)



推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • python计算数据包校验和(python接口数据校验)
    本文目录一览:1、怎么用python算p值和t检验 ... [详细]
  • 【2021Java最新学习路线】开启mysql远程连接
    前言面试技巧另外开篇再说,先上面试干货吧。面试的题目并不一定有严格的顺序关系,有的是从前一个问题延伸而来,(探究的是一个知 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Linux防火墙配置—允许转发
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • SQL Server 2008 到底需要使用哪些端口?
    SQLServer2008到底需要使用哪些端口?-下面就来介绍下SQLServer2008中使用的端口有哪些:  首先,最常用最常见的就是1433端口。这个是数据库引擎的端口,如果 ... [详细]
  • Ansem 最新雄文:软着陆后,加密市场下阶段趋势与核心叙事
    市场最糟糕的时候已经过去,以太坊合并前不太会看到新的低点;但仍需来自关注宏观市场的不确定风险。撰文:Ansem ... [详细]
  • c# java socketn 字节流_C#Socket编程详解(一)TCP与UDP简介
    一、TCP与UDP(转载)1、TCP1.1定义TCP(TransmissionControlProtocol)传输控制协议。是一种可靠的、面向连接的协议(eg:打电话)、传输效率低 ... [详细]
  • centos 6.5 mysql 集群_CentOS 6下安装部署Galera Cluster for MySQL集群
    GaleraClusterforMySQL是一套基于同步复制的多主MySQL集群解决方案,使用简单,没有单点故障,可用性高, ... [详细]
author-avatar
双鱼2502858483
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有