k8s学习-通过Service访问Pod

假设Pod中的容器很可能因为各种原因发生故障而死掉。Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性。换句话说,Pod是脆弱的,但应用是健壮的。

每个Pod都有自己的IP地址。当Controller用新Pod替代发生故障的Pod时,新Pod会分配到新的IP地址。这样就产生了⼀个问题:如果⼀组Pod对外提供服务(比如HTTP),它们的IP很有可能发⽣变化,那么客户端如何找到并访问这个服务呢?Kubernetes给出的解决方案是Service。

1.1 Service是什么

由于Pod的动态性,Service解决了一个重要问题:如果一组Pod(称为“后端”)为其他Pod(称为“前端”)提供服务,前端如何找到并连接到后端的IP地址。Kubernetes中的Service为此提供了解决方案,通过提供稳定的虚拟IP和DNS,使服务发现变得简单而可靠。

1.2 Service的几种类型

(1)ClusterIP
ClusterIP 服务是 Kubernetes 的默认服务。它给你一个集群内的服务,集群内的其它应用都可以访问该服务,但是集群外部无法访问它。
(2)NodePort
除了只在内部访问的服务,我们总有很多是需要暴露出来公开访问的服务吧。在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过:NodePort来访问这些服务。
(3)LoadBalancer
LoadBalancer 服务是暴露服务到 internet 的标准方式,它借助Cloud Provider创建一个外部的负载均衡器,并将请求转发到:NodePort(向节点导流)。

1.3 ClusterIP

先创建Deployment。
vi httpd.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: httpd
spec:replicas: 3selector:  # 添加这一行,定义标签选择器matchLabels:run: httpdtemplate:metadata:labels:run: httpdspec:containers:- name: httpdimage: httpdports:- containerPort: 80

我们启动了三个Pod,运行httpd镜像,label是run: httpd,Service将会用这个label来挑选Pod。

kubectl get pod -o wide

Pod分配了各自的IP,这些IP只能被KubernetesCluster中的容器和节点访问,如图所示。

[root@k8s-master ~]# kubectl get pod -o wide
NAME                                READY   STATUS      RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
httpd-ff8d77b9b-dpp79               1/1     Running     1          43h   10.244.2.104   k8s-node2   <none>           <none>
httpd-ff8d77b9b-n5w6x               1/1     Running     1          43h   10.244.2.103   k8s-node2   <none>           <none>
httpd-ff8d77b9b-t6jhg               1/1     Running     1          43h   10.244.2.105   
[root@k8s-master ~]# curl 10.244.2.103
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 10.244.2.104
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 10.244.2.105
<html><body><h1>It works!</h1></body></html>

接下来创建Service,其配置文件如下。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:name: httpd-svc
spec:selector:run: httpdports:- protocol: TCPport: 8080targetPort: 80

执⾏kubectl apply创建Service httpd-svc,查看service

kubectl get service
[root@k8s-master ~]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
httpd-svc    ClusterIP   10.1.216.8   <none>        8080/TCP   43h
kubernetes   ClusterIP   10.1.0.1     <none>        443/TCP    10d

httpd-svc分配到⼀个CLUSTER-IP 10.1.216.8。可以通过该IP访问后端的httpd Pod,如图。

[root@k8s-master ~]# curl 10.1.216.8:8080
<html><body><h1>It works!</h1></body></html>

通过kubectl describe可以查看httpd-svc与Pod的对应关系,如图

[root@k8s-master ~]# kubectl describe service httpd-svc
Name:              httpd-svc
Namespace:         default
Labels:            <none>
Annotations:       Selector:  run=httpd
Type:              ClusterIP
IP:                10.1.216.8
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.103:80,10.244.2.104:80,10.244.2.105:80
Session Affinity:  None
Events:            <none>

Endpoints罗列了三个Pod的IP和端口。我们知道Pod的IP是在容器中配置的,那么Service的Cluster IP又是配置在哪⾥的呢?CLUSTER-IP又是如何映射到Pod IP的呢?
答案是iptables。

1.4 Cluster IP底层实现

ClusterIP是⼀个虚拟IP,是由Kubernetes节点上的iptables规则管理的。可以通过iptables-save命令打印出当前节点的iptables规则,因为输出较多,这里只截取与httpd-svcClusterIP10.1.216.8相关的信息,如下。

-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.1.216.8/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 808       0 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.1.216.8/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-RL3JAE4GN7VOGDGP

这两条规则的含义是:
(1)如果Cluster内的Pod(源地址来⾃10.244.0.0/16)要访问
httpd-svc,则允许。
(2)其他源地址访问httpd-svc,跳转到规则KUBE-SVC-
RL3JAE4GN7VOGDGP。KUBE-SVC-RL3JAE4GN7VOGDGP规则如下。

-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.33333333349 -j KU       BE-SEP-EQHMOIHNIUPMH73P
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.50000000000 -j KU       BE-SEP-7VYTM2IXTFTHGXZQ
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -j KUBE-SEP-6OZMKNJKUPLE2HZF

(1)1/3的概率跳转到规则KUBE-SEP-EQHMOIHNIUPMH73P。
(2)1/3的概率(剩下2/3的⼀半)跳转到规则KUBE-SEP-7VYTM2IXTFTHGXZQ。
(3)1/3的概率跳转到规则KUBE-SEP-6OZMKNJKUPLE2HZF。

-A KUBE-SEP-EQHMOIHNIUPMH73P -s 10.244.2.106/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-EQHMOIHNIUPMH73P -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.106:80-A KUBE-SEP-7VYTM2IXTFTHGXZQ -s 10.244.2.107/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-7VYTM2IXTFTHGXZQ -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.107:80-A KUBE-SEP-6OZMKNJKUPLE2HZF -s 10.244.2.108/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-6OZMKNJKUPLE2HZF -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.108:80

可以看到是将请求分别转发到后端的三个Pod。
通过上面的分析,我们得到结论:iptables将访问Service的流量转发到后端Pod,而且使用类似轮询的负载均衡策略。

1.5 DNS访问Service

kubeadm部署时会默认安装kube-dns组件。

[root@k8s-master ~]#  kubectl get deployment --namespace=kube-system
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
coredns          2/2     2            2           12d
metrics-server   1/1     1            1           12d

kube-dns是⼀个DNS服务器。每当有新的Service被创建,kube-dns会添加该Service的DNS记录。Cluster中的Pod可以通过<SERVICE_NAME>.<NAMESPACE_NAME>访问Service。比如可以用httpd-svc.default访问Servicehttpd-svc。

[root@k8s-master ~]# kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # curl httpd-svc.default:8080
/bin/sh: curl: not found
/ # wget httpd-svc.default:8080
Connecting to httpd-svc.default:8080 (10.1.216.8:8080)
saving to 'index.html'
index.html           100% |******************************************************************************************|    45  0:00:00 ETA
'index.html' saved

如果要访问其他namespace中的Service,就必须带上namesapce了。在kube-public中部署Service httpd2-svc。
vi httpd2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: httpd2namespace: kube-public
spec:replicas: 1selector:matchLabels:run: httpd2template:metadata:labels:run: httpd2spec:containers:- name: httpd2image: httpdports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: httpd2-svcnamespace: kube-public
spec:selector:run: httpd2ports:- protocol: TCPport: 8080targetPort: 80

通过namespace:kube-public指定资源所属的namespace。多个资源可以在⼀个YAML⽂件中定义,⽤“—”分割。执⾏kubectlapply创建资源。

[root@k8s-master ~]#  kubectl apply -f httpd2.yaml
deployment.apps/httpd2 created
service/httpd2-svc unchanged
[root@k8s-master ~]# kubectl get service --namespace=kube-public
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
httpd2-svc   ClusterIP   10.1.19.55   <none>        8080/TCP   9m15s
[root@k8s-master ~]# kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget httpd2-svc.kube-public:8080
Connecting to httpd2-svc.kube-public:8080 (10.1.19.55:8080)
saving to 'index.html'
index.html           100% |******************************************************************************************|    45  0:00:00 ETA
'index.html' saved

1.5 NodePort

Service通过Cluster节点的静态端口对外提供服务。Cluster外部可以通过:访问Service。
下面我们来实践NodePort,Service httpd-svc的配置文件修改。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:name: httpd-svc
spec:type: NodePortselector:run: httpdports:- protocol: TCPport: 8080targetPort: 80

添加type: NodePort,重新创建httpd-svc

[root@k8s-master ~]# vi httpdservice.yaml
[root@k8s-master ~]#  kubectl apply -f httpdservice.yaml
service/httpd-svc configured
[root@k8s-master ~]# kubectl get service httpd-svc
NAME        TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
httpd-svc   NodePort   10.1.216.8   <none>        8080:30560/TCP   2d23h

Kubernetes依然会为httpd-svc分配⼀个ClusterIP,不同的是:
(1)EXTERNAL-IP为nodes,表示可通过Cluster每个节点自身的IP访问Service。
(2)PORT(S)为8080:30560。8080是ClusterIP监听的端口,30560则是节点上监听的端口。Kubernetes会从30000〜32767中分配⼀个可用的端口,每个节点都会监听此端⼝并将请求转发给Service。

测试NodePort是否正常工作,通过三个节点IP+30560端口都能够访问httpd-svc。:

[root@k8s-master ~]# curl 192.168.200.128:30560
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.129:30560
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.130:30560
<html><body><h1>It works!</h1></body></html>

Kubernetes是如何将:映射到Pod的呢?执行iptables-save
与ClusterIP⼀样,也是借助了iptables。与ClusterIP相比,每个节点的iptables中都增加了下面两条规则。

-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 30560 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 30560 -j KUBE-SVC-RL3JAE4GN7VOGDGP

规则的含义是:访问当前节点32312端口的请求会应用规则KUBE-
SVC-RL3JAE4GN7VOGDGP,内容如下

-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-EQHMOIHNIUPMH73P
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-7VYTM2IXTFTHGXZQ
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -j KUBE-SEP-6OZMKNJKUPLE2HZF

其作用就是负载均衡到每⼀个Pod。

NodePort默认的是随机选择,不过我们可以用nodePort指定某个特定端口。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:name: httpd-svc
spec:type: NodePortselector:run: httpdports:- protocol: TCP nodePort: 31000port: 8080targetPort: 80

现在配置文件中就有三个Port了:

  • nodePort是节点上监听的端口。
  • port是ClusterIP上监听的端口。
  • targetPort是Pod监听的端口。
[root@k8s-master ~]# vi httpdservice.yaml
[root@k8s-master ~]#  kubectl apply -f httpdservice.yaml
service/httpd-svc configured
[root@k8s-master ~]# curl 192.168.200.130:31000
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.128:31000
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.129:31000
<html><body><h1>It works!</h1></body></html>

最终,Node和ClusterIP在各自端口上接收到的请求都会通过 iptables转发到Pod的targetPort。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

颠覆传统楼宇管理,拥抱城市美好生活

智慧楼宇是指通过智能化技术和设备&#xff0c;对楼宇的设施、环境和应用进行全面感知、连接和优化&#xff0c;实现楼宇的智能化、高效化和安全化的建筑。智慧楼宇具有全面感知、实时监控、智能控制、优化管理、节能环保等特点&#xff0c;可以为建筑提供更高效、更便捷、更安…

V90伺服PN总线绝对值编码器点动模式往复运动控制实验(SCL代码)

V90伺服驱动器其它相关介绍,请参考V90控制专栏,常用地址如下: V90 Epos模式下点动控制 https://rxxw-control.blog.csdn.net/article/details/134263795https://rxxw-control.blog.csdn.net/article/details/134263795绝对定位往复运动可以参考下面文章链接: https://rx…

【深度学习】MNN ImageProcess处理图像顺序,逻辑,均值,方差

文章目录 介绍Opencv numpy等效的MNN处理 介绍 MNN ImageProcess处理图像是先reisze还是后resize&#xff0c;均值方差怎么处理&#xff0c;是什么通道顺序&#xff1f;这篇文章告诉你答案。 Opencv numpy 这段代码是一个图像预处理函数&#xff0c;用于对输入的图像进行一系…

Python Django

Django 是一个用于构建 Web 应用程序的高级 Python Web 框架。它遵循 "Dont Repeat Yourself"&#xff08;不要重复自己&#xff09;和 "Convention over Configuration"&#xff08;约定大于配置&#xff09;的原则&#xff0c;以提高开发效率。 以下是 …

【数据结构 06】二叉树

一、原理 二叉树算法核心思维&#xff1a;递归 满二叉树&#xff1a;二叉树的层数为K&#xff0c;节点数为 完全二叉树&#xff1a;二叉树的层数为K&#xff0c;前K-1层是满的&#xff0c;第K层是连续的 满二叉树是完全二叉树的子集。 任意二叉树&#xff1a;若叶子节点的…

CRF条件随机场学习记录

阅读建议 仔细阅读书[1]对应的序列标注章节&#xff0c;理解该方法面向的问题以及相关背景&#xff0c;然后理解基础的概念。 引言 威胁情报挖掘的相关论文中&#xff0c;均涉及到两部分任务&#xff1a;命名实体识别&#xff08;Named Entity Recognition&#xff0c;NER&a…

ubuntu+nginx+uwsgi部署django项目

相比较学习Django来说,部署应该是在整个环节中比较难的一项,特别是一些自学者,对liunx系统的命令行操作不熟悉,甚至是从来没有接触过服务器,这一块我相信劝退了很多人!当初我自己学习的时候也是如此! 但我仍然觉得自学是一件非常酷的事,虽说可能会走些弯路,但这些弯路…

android学习笔记----ListView和各种适配器简介

打气筒&#xff08;LayoutInflater对象&#xff09;介绍&#xff1a; MainActivity.java import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import an…

Springboot 实现基于用户和物品的协同过滤算法

目录 简介 协同过滤算法(简称CF) 算法详解 算法使用 基于用户 基于物品 总结 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&#xff0c;我们往往容易陷入工作的漩涡&#xff0c;忘记了停…

对作用域链的理解(详细解析)

文章目录 一、作用域全局作用域函数作用域块级作用域 二、词法作用域三、作用域链 一、作用域 作用域&#xff0c;即变量&#xff08;变量作用域又称上下文&#xff09;和函数生效&#xff08;能被访问&#xff09;的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变…

CSRF笔记整理

跨站请求伪造 类型 GET&#xff1a;基于url直接修改 POST&#xff1a;基于表单修该 基本原理 用户在同一浏览器登陆了网站A并访问了攻击者在网站B上构造的恶意链接&#xff08;针对网站A用户信息的一些数据操作&#xff09; 用户点击恶意链接瞬间会触发csrf攻击&#xff1b;通过…

Vue3前端框架:动态组件详解

当谈到现代前端开发框架时&#xff0c;Vue.js 通常是一个备受推崇的选择。在 Vue.js 3 中&#xff0c;动态组件是一个强大而灵活的功能&#xff0c;为开发人员提供了更多的控制权和创造性。本文将深入探讨 Vue.js 3 中动态组件的详细内容&#xff0c;探讨其用法、优势以及如何在…

腾讯云部署vue+node项目

文章目录 一、安装宝塔二、vue项目部署三、node项目部署 前言: 关于项目部署,一开始也是找了很多资料,费了点时间,所以记录一下。希望能对各位有所帮助。 一、安装宝塔 1.首先在控制台,进入云服务器的终端界面 2.输入命令和密码获取权限,并且安装宝塔界面 yum install -y w…

已解决com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException异常的正确解决方法,亲测有效!!!

已解决com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 文章目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 检查SQL语句的拼写和语法 核对数据库结构 阅读并理解…

php-fpm详细讲解

PHP-FPM&#xff08;FastCGI Process Manager&#xff09;是PHP的一种运行模式&#xff0c;用于处理动态HTTP请求。 它与传统的模块式PHP&#xff08;如Apache模块&#xff09;相比&#xff0c;将PHP解析和执行过程单独封装为一个独立的进程池&#xff0c;通过FastCGI协议与We…

腾讯云0基础10秒搭建幻兽帕鲁游戏联机服务器

幻兽帕鲁&#xff08;Palworld&#xff09;是一款多人在线游戏&#xff0c;为了获得更好的游戏体验&#xff0c;需要搭建一个稳定、高效的游戏联机服务器。腾讯云提供了一种简单、快速的方法&#xff0c;让新手小白也能0基础10秒搭建幻兽帕鲁游戏联机服务器&#xff01; 本文将…

计算机网络_1.2因特网概述

1.2因特网概述 一、网络、互联网与因特网的区别与联系1、网络2、互联网3、因特网4、 互联网与因特网辨析 二、因特网介绍1、因特网发展的三个阶段2、因特网简介&#xff08;1&#xff09;因特网服务提供者&#xff08;ISP&#xff09;&#xff08;2&#xff09;因特网已经发展成…

基于Springboot的视频网站系统的设计与实现(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的视频网站系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层…

ESP8266 传感器搭配 Node-RED实时显示数据,邮件告警 实验

前言 esp8266 12f,wif模块,接倾斜传感器,火焰传感器,烟雾传感器,水浸传感器,蜂鸣器。通过mqtt发布数据,并使用node-red实时获取数据,显示到页面上。并且通过邮件和页面两种方式报警。 需求如下: ①倾斜传感器:监测是否保持平衡。UI界面显示平衡度。如果不平衡,UI界…

Observability:在 Elastic Stack 8.12 中使用 Elastic Agent 性能预设

作者&#xff1a;来自 Elastic Nima Rezainia, Bill Easton 8.12 中 Elastic Agent 性能有了重大改进 最新版本 8.12 标志着 Elastic Agent 和 Beats 调整方面的重大转变。 在此更新中&#xff0c;Elastic 引入了 Performance Presets&#xff0c;旨在简化用户的调整过程并增强…