当前位置: 首页 > news >正文

Kubernetes -Kubernetes中的Network组件

Network是Kubernetes体系中的重头戏,相比于其它组件来说也比较难,因为Kubernetes中所有的Pod或者服务之间一定是需要进行网络通信的,如果不能解决网络通信的问题,那可以说整个Kubernetes体系中的Pod是没有灵魂的。

所以必须要把Network这个组件搞清楚,那Network这个组件该从哪里开始入手呢?

首先,为了更好的了解Kubernetes中的Network组件,我们先回想下,在Docker中我们的网络是如何做的?
在Docker中,无非是划分成单机和多机,单机中Docker的网络可以由下图所示:
在这里插入图片描述

两个容器在同一个Centos中,为什么彼此能够ping通?是因为有docker0这样的网卡,我们都通过veth这样的一个pair对去匹配,这是最简单的一种场景,是容器之间的通信。

如果一个容器搬到了一个机器中,一个容器搬到了另外一个容器中,我们该如何解决呢?这就涉及到了Docker Swarm多机集群中的通信,可以使用overlay的网络实现,如下图所示:
在这里插入图片描述
如果没有overlay网络,两个container之间是不能进行通信的,那怎么样让两个container进行通信呢?
我们将整个container的信息,通过veth0这样一个跟互联网能够交互的网卡,把整个数据包通过overlay这样的网络发送给我们另外一端,另外一端接收到信息之后再去进行解包, 这样就能进行通信了。这是overlay网络帮我们做的实现,保证了两个容器在多机之间可以进行通信。

但是现在的问题是,我们讨论的并不是container,而讨论的是Pod,因为Pod是Kubernetes中最小的操作单元,所以Kubernetes的网络组件一定是从Pod开始入手。

在这里插入图片描述
我们可以先思考一个问题,在同一个pod中的两个container之间可以通信吗?答案是肯定的,因为同一个Pod中的container肯定会在同一个node上,可以参考单机Docker中container之间的通信。在Docker体系中,container之间通过docker0网卡进行通信;在Kubernetes中,当我们创建一个pod的时候,pod中一定会创建一个名字为pause container的容器,pod中所有的container都会连接到整个container中,这样就可以实现pod中container之间的通信
在这里插入图片描述

了解了同一个pod中container之间的通信之后,我们要思考的问题是同一个集群中pod之间如何通信。Pod之间的通信又可以划分为两个维度:

  1. 同一个Node中Pod之间的通信
  2. 不同Node中Pod之间的通信

我们通过一个例子展示:准备一个nginx-pod,一个busybox-pod

nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:name: nginx-podlabels:app: nginx
spec:containers:- name: nginx-containerimage: nginxports:- containerPort: 80

busybox-pod.yaml

apiVersion: v1
kind: Pod
metadata:name: busyboxlabels:app: busybox
spec:containers:- name: busyboximage: busyboxcommand: ['sh', '-c', 'echo The app is running! && sleep 3600']

将两个pod运行起来,并且查看运行情况

在这里插入图片描述
发现:nginx-pod的ip为192.168.14.11,运行在work01节点;busybox-pod的ip为192.168.221.74,运行在worker02节点。

上面两个ip和我们虚拟机的IP是没有任何关系的,那这个IP是谁帮忙生成的呢?答案是网络插件帮忙生成的,比如calico等。
在这里插入图片描述
经测试发现,我们可以在任意Node上去访问Pod。

在worker02节点访问运行在01节点中的nginx
在这里插入图片描述

在worker01节点上ping busybox pod的ip
在这里插入图片描述

结论:通过网络插件(calico),集群中任意Node中的Pod之间可以彼此通信。
官网:https://kubernetes.io/docs/concepts/cluster-administration/networking/#the-kubernetes-network-model

另外,Pod其实是很不稳定的,因为deployment随时会对Pod进行扩缩容,随时会有Pod被删除和创建(IP也会变化),也就意味着我们不能通过IP稳定的访问Pod内的服务,那要如何解决呢?能不能有一个固定的IP能够让我们去访问特定的Pod呢?答案是肯定的,我们可以通过service组件来控制,也就是在Pod的外面再添加一层service,我们只要访问service的IP,然后service帮忙去负载均衡到servic对应的Pod,如下图所示:
在这里插入图片描述
案例

  1. 创建whoami-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: whoami-deploymentlabels:app: whoami
spec:replicas: 3selector:matchLabels:app: whoamitemplate:metadata:labels:app: whoamispec:containers:- name: whoamiimage: jwilder/whoamiports:- containerPort: 8000
  1. 创建Pod
    在这里插入图片描述
    在这里插入图片描述
  2. 在任意一台机器都可以通过ip和port访问成功
    在这里插入图片描述
  3. 添加service
    先查看默认namespace下有哪些service
    在这里插入图片描述
    通过下面命令给whoami-deployment这个deployment创建service
kubectl expose deployment whoami-deployment

在这里插入图片描述
可以看到我们为whoami-deployment创建了一个ip为10.100.145.244的service。在任意节点通过这个ip去访问whoami,发现都可以访问成功,并且可以做负载均衡。
在这里插入图片描述
注意:这个IP只能在集群内访问,集群外访问不了。

service组件是如何实现这个功能的呢?可以通过下面命令查看service的详细信息

kubectl describe svc whoami-deployment

在这里插入图片描述
可以看到所有Pod的IP信息都在service得到endpoints中。
结论: Cluster IP类型的service的IP可以供集群内访问,并且对很多deployment进行负载均衡。

上面了解了集群内各个Node中Pod之间的通信,那么集群内和集群外面是如何通信的呢?
集群外面访问集群内Pod

方案一:NodePort类型的service

  1. 根据whoami-deployment.yaml创建Pod
    在这里插入图片描述
    此时,我们只能在集群内通过IP去访问。
  2. 创建NodePort类型的service
kubectl expose deployment whoami-deployment --type=NodePort

在这里插入图片描述
可以看到,创建了一个IP为10.104.253.245,类型为NodePort的service,并且把8000端口映射到宿主机上的30448端口。现在我们在集群外面访问30448端口:
在这里插入图片描述
这种类型的service会有一个潜在的问题,那就是端口可能会被占用,随着我们的service越来越多,宿主机的端口可能不够用,所以这种方式不建议在生产环境中使用。

方案二:Loadbalance 类型的service
这种service需要结合第三方供应商帮忙提供域名,并且有一定的约束性,所以也不常用。

方案三:Ingress 类型的网络
官网:https://kubernetes.io/docs/concepts/services-networking/ingress/
通过官网可以发现,Ingress就是帮助我们访问集群内的服务的。不过在看Ingress之前,我们还是先以一个案例出发。很简单,在K8S集群中部署tomcat
浏览器想要访问这个tomcat,也就是外部要访问该tomcat,用之前的Service-NodePort的方式是可以的,比如暴露一个32008端口,只需要访问192.168.0.61:32008即可。显然,Service-NodePort的方式生产环境不推荐使用,那接下来就基于上述需求,使用Ingress实现访问tomcat的需求。

官网Ingress:https://kubernetes.io/docs/concepts/services-networking/ingress/

GitHub Ingress Nginx:https://github.com/kubernetes/ingress-nginx

Nginx Ingress Controller:<https://kubernetes.github.io/ingress-nginx/

  1. 创建tomcat-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: tomcat-deploymentlabels:app: tomcat
spec:replicas: 1selector:matchLabels:app: tomcattemplate:metadata:labels:app: tomcatspec:containers:- name: tomcatimage: tomcatports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:name: tomcat-service
spec:ports:- port: 80   protocol: TCPtargetPort: 8080selector:app: tomcat
  1. 通过yaml创建pod
    在这里插入图片描述
  2. 该Pod为Ingress Nginx Controller,要想让外界访问,可以通过Service的NodePort或者HostPort方式,这里选择HostPort,比如指定worker01运行
#确保nginx-controller运行到w1节点上
kubectl label node w1 name=ingress   #mandatory.yaml下载地址
https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/mandatory.yaml
修改mandatory.yamlspec:# wait up to five minutes for the drain of connectionsterminationGracePeriodSeconds: 300serviceAccountName: nginx-ingress-serviceaccounthostNetwork: truenodeSelector:name: ingresskubernetes.io/os: linuxcontainers:#使用HostPort方式运行,需要增加配置
hostNetwork: true#搜索nodeSelector,并且要确保w1节点上的80和443端口没有被占用,镜像拉取需要较长的时间,这块注意一下哦
kubectl apply -f mandatory.yaml  
kubectl get all -n ingress-nginx
  1. 创建Ingress以及定义转发规则nginx-ingress.yaml
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: nginx-ingress
spec:rules:- host: tomcat.demo.comhttp:paths:- path: /backend:serviceName: tomcat-serviceservicePort: 80

kubectl apply -f nginx-ingress.yaml
kubectl get ingress
kubectl describe ingress nginx-ingress

在这里插入图片描述
5. 修改win的hosts文件,添加dns解析

192.168.0.61   tomcat.demo.com
  1. 打开浏览器,访问tomcat.demo.com

总结:如果以后想要使用Ingress网络,其实只要定义ingress,service和pod即可,前提是要保证nginx ingress controller已经配置好了。

相关文章:

  • lv12 系统移植导学 1
  • Word插件-好用的插件-一键设置字体--大珩助手
  • Chatgpt如何完成论文写作及python机器学习和深度学习领域的运用
  • 4.8 构建onnx结构模型-Less
  • 中文分词演进(查词典,hmm标注,无监督统计)新词发现
  • 【重点】【二叉树】114. 二叉树展开为链表
  • 【go语言开发】go项目打包成Docker镜像,包括Dockerfile命令介绍、goctl工具生成
  • leetcode 100.相同的树
  • 非常抱歉的通知
  • linux 命令 tmux 用法详解
  • JVM实战-掌握分派方法规则
  • MyBatis 四大核心组件之 StatementHandler 源码解析
  • STM32——继电器
  • Photoshop Circular Text
  • 鸿蒙应用开发(二)环境搭建
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【前端学习】-粗谈选择器
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • avalon2.2的VM生成过程
  • CSS 三角实现
  • Git初体验
  • Java,console输出实时的转向GUI textbox
  • java正则表式的使用
  • node入门
  • Quartz初级教程
  • Terraform入门 - 3. 变更基础设施
  • vue-router的history模式发布配置
  • 回顾2016
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 前端技术周刊 2019-02-11 Serverless
  • 如何在 Tornado 中实现 Middleware
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • (2)nginx 安装、启停
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (NSDate) 时间 (time )比较
  • (zt)最盛行的警世狂言(爆笑)
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (七)Knockout 创建自定义绑定
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • .form文件_一篇文章学会文件上传
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net Application的目录
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Core跨平台微服务学习资源
  • .NET 分布式技术比较
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET成年了,然后呢?
  • .net开发时的诡异问题,button的onclick事件无效