------------ # 一、基本架构和原理 *容器比宿主机优势在哪?* - 可移植性:容器提供了运行应用程序的基本包装,可以在任何支持容器的云上部署 - 高效率:启动一个容器只需一个镜像,且启动时间非常短 - 隔离性:宿主机上往往安装很多服务,且各自依赖不一样。而一个容器只跑一个服务 - 版本控制:方便追溯不同版本差异,方便快速回滚,只需替换镜像版本,无需宿主机上一套复杂的流程 - 低成本:小巧轻便,不需要像宿主机或虚拟机一样占用很多资源 *k8s的出现又解决了容器的什么问题?* - 自动编排调度:大量容器剧增后,如何管理、如何调度的问题 - 分布式解决方案:节点可水平扩展,容器可方便扩缩容 - 自愈能力:故障自动发现,并进行自我修复 ## 1、Master节点的组件 **apiServer** - 提供资源操作的唯一入口,提供api注册、发现、认证、访问控制等功能 **etcd** - 一个key-value数据库 - 保存整个机器的状态 **controller-manager** - 负责维护机器状态,比如:自动扩容、故障检查、滚动更新 - 实现集群自动化的关键组件 **scheduler** - 负责资源调度 - 将未分配节点的pod调度到合适的节点上 ## 2、Node节点的组件 **kubelet** - 负责容器生命周期管理,比如:创建、删除 - 同时负责Volume,网络的管理 **kube-proxy** - 负责为Service提供负载均衡、服务发现 **Container Runtime** - 容器运行环境 - 默认是Docker,同时还支持其他容器引擎 ![Kubernetes架构图简版.png](https://www.xiaoleizhang.com/usr/uploads/2022/04/832663646.png) ![Kubernetes数据流转图.png](https://www.xiaoleizhang.com/usr/uploads/2022/04/4092833764.png) # 二、资源对象 **概述** - k8s中大部分概念,如Node,Pod,Service都可以看做一种资源对象 - 资源的描述:yaml文件或json文件 - 资源的操作:对象可以通过kubectl(或者api)执行增、删、改、查 - 资源的存储:信息在etcd中持久化 *Kubernetes通过对比资源的“实际状态”和etcd中的“期望状态”,实现自动化控制* ![常用资源概述图.png](https://www.xiaoleizhang.com/usr/uploads/2022/04/523422550.png) ## 1、Pod - Pod是k8s中最重要最基本的资源 - pod是在容器之外又封装的一层概念 - pod是容器调度的基本单元(不是docker容器) - 每个pod包含一个特殊的根容器:Pause容器,和一个或多个业务容器 - 每个pod有唯一的ip,pod内的容器可通过localhost通讯 *为什么要新增pod这个概念?* - 一组容器作为一个单元,很难判断整体状态,以及对整体进行管控。新增业务无关的pause容器,用于管控整体 - 简化了关联容器通信和共享的问题 ## 2、Deployment - 实现Pod自动编排:创建、删除、扩容、缩容 - 通过replicas控制pod数量,template控制要创建的pod的模板 ```yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: k8s-demo namespace: spring-test spec: replicas: 3 template: metadata: labels: app: k8s-demo spec: containers: - name: k8s-demo image: k8s-demo:0.0.1-SNAPSHOT ports: - containerPort: 8080 ``` ## 3、Service *pod异常时,可能会被调度到另一台机器,导致pod的ip改变,使用ip访问服务不可靠* - k8s里最核心的资源之一,类似微服务架构中的“微服务” - 前端应用通过入口地址访问服务,服务通过label对接到后端的pod,即使pod的ip变了 - kube-proxy负责把service请求转发到后端,并做负载均衡 - service整个生命周期内,ClusterIp不会变,对外提供的服务地址也就不会变 ```yaml apiVersion: v1 kind: Service metadata: name: k8s-demo namespace: spring-test spec: type: NodePort selector: app: k8s-demo ports: - protocol: TCP port: 8888 targetPort: 8080 nodePort: 30003 ``` ## 4、Ingress * service提供了ip:port的访问方式,即工作在tcp/ip层,而http服务需要将不同的url对应到不同的后端服务,service是无法实现这一功能的。* - Ingress提供http层的负载分发功能 - Ingress可以实现不同的请求,分发到不同的后端服务 - Ingress定义后,需要结合Ingress Controller,才能形成完整的功能 ```yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: k8s-demo namespace: spring-test spec: rules: - host: www.k8s-demo.com http: paths: - path: /hello backend: serviceName: k8s-demo servicePort: 8888 ``` **Ingress Controller定义** - 可以使用公有云提供的Ingress Controller - 也可以使用google提供的Ingress Controller,以pod形式运行,功能如下: 1. 监听apiserver,获取ingress的定义 2. 基于ingress定义,生成nginx的配置文件的内容 3. 执行nginx -s reload,重新加载配置 **Ingress定义** - 创建类型为Ingress的yaml文件 - 配置spec.rules,指定hostname中url和service的对应关系 # 三、Kubernetes网络模型 ## 1、Docker网络模型 - docker第一次启动时,会创建虚拟网桥docker0 - 为docker0分配一个子网 - docker创建每个容器时,会创建veth设备对,一端关联到网桥上,另一端使用linux的网络命名空间技术连接到容器内,并给容器内eth0设备分配一个ip地址 ![docker网络模型.png](https://www.xiaoleizhang.com/usr/uploads/2022/04/148830008.png) **Docker网络的局限性** - Docker网络模型没有考虑到多主机互联的网络解决方案,崇尚简单为美 - 同一机器内的容器之间可以直接通讯,但是不同机器之间的容器无法通讯 - 为了跨节点通讯,必须在主机的地址上分配端口,通过端口路由或代理到容器 - 分配和管理容器特别困难,特别是水平扩展时 ##2、 Kubernetes网络模型概述 **Kubernetes网络模型的原则:** - 每个pod都拥有唯一个独立的ip地址,称IP-Per-Pod模型 - 所有pod都在一个可连通的网络环境中 - 不管是否在同一个node,都可以通过ip直接通讯 - pod被看作一台独立的物理机或虚拟机 *目前原生docker和kubernetes还不能打通多节点容器与容器的通讯,要支持该模型,必须依靠第三方网络插件实现,比如:Calico、flannel* **设计这个原则的原因:** - 用户不需要额外考虑如何建立pod之间的连接 - 用户不需要考虑将容器端口映射到主机端口的问题 - 可以兼容过去跑在宿主机和KVM的应用 **IP-Per-Pod与Docker端口映射的区别** - docker端口映射到宿主机会引入端口管理的复杂性 - docker最终被访问的ip和端口,与提供的不一致,引起配置的复杂性 ## 3、Kubernetes网络模型详解 **容器与容器的通讯** - 同一个容器的pod直接共享同一个linux协议栈 - 就像在同一台机器上,可通过localhost访问 - 可类比一个物理机上不同应用程序的情况 **pod与pod的通讯** **1. 同一Node内的pod之间通讯** - 同一Node内的pod都是通过veth连接在同一个docker0网桥上,地址段相同,所以可以直接通讯 **2. 不同Node的pod之间通讯** - docker0网段与宿主机不在同一个网段,所以不同pod之间的pod不能直接通讯 - 不同node之间通讯只能通过宿主机物理网卡 - 前面说过k8s网络模型需要不同的pod之间能通讯,所以ip不能重复,这就要求k8s部署时要规划好docker0的网段 - 同时,要记录每个pod的ip地址挂在哪个具体的node上 - 为了达到这个目的,有很多开源软件增强了docker和k8s的网络 ![Kubernetes网络实现.png](https://www.xiaoleizhang.com/usr/uploads/2022/04/2340794157.png) **Calico简介** Calico组件是Tigera公司以Apache 2.0开源协议开源的网络和网络解决方案组件,可用于容器、虚拟机、原生宿主机侧负载。Calico CNI插件在 CNI(Container Network Interface) 框架内封装了Calico的功能,以对k8s环境做支持。 虽然Flannel被公认为是最简单的选择,但Calico以其性能、灵活性而闻名。Calico的功能更为全面,不仅提供主机和pod之间的网络连接,还涉及网络安全和管理。从Calico 3.x开始,默认配置使用的是IPIP模式这种Overlay的传输方案而非BGP。 最后修改:2022 年 04 月 12 日 © 允许规范转载 赞 1 如果觉得我的文章对你有用,请随意赞赏
1 条评论
写的挺好