了解什么是容器编排?
容器编排就是有关管理容器生命周期的全部工作,特别是在大型动态环境中。 软件团队使用容器编排来控制和自动化许多任务:
调配和部署容器
容器的冗余和可用性
扩展或删除容器以在主机基础结构中平均分配应用程序负载
如果主机中的资源不足或主机死亡,则将容器从一个主机移至另一主机
容器之间的资源分配
在外部容器中运行的服务的外部暴露
容器之间服务发现的负载平衡
容器和主机的健康监控
与运行它的容器有关的应用程序配置
Kubernetes
- Kubernetes是一个开源系统,用于跨多个主机管理容器化的应用程序,提供了用于部署,维护和扩展应用程序的基本机制
- Kubernetes建立在Google十年半的经验之上,使用称为Borg的系统大规模运行生产工作负载,并结合了社区中的最佳创意和实践
Kubernetes集群
•运行中的Kubernetes集群包含节点代理(kubelet)和集群控制平面(AKA主节点),集群状态由分布式存储系统(etcd)支持
Kubernetes主要由以下几个核心组件组成:
Master 组件
etcd 保存了整个集群的状态;
kube-apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
kube-scheduler 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
Node 组件
kubelet 负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理;
kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡;
Container runtime 负责镜像管理以及Pod和容器的真正运行(CRI);
除了核心组件,还有一些推荐的插件,其中有的已经成为CNCF中的托管项目:
Addons
CoreDNS 负责为整个集群提供DNS服务
Ingress Controller为服务提供外网入口
Prometheus提供资源监控
Dashboard提供GUI
Federation提供跨可用区的集群
Kubernetes Master
Kube-Master 的工作流程图
Kubecfg 将特定的请求发送给 Kubernetes Client(比如:创建 Pod 的请求)。
Kubernetes Client 将请求发送给 API Server。
API Server 会根据请求的类型选择用何种 REST API 对请求作出处理(比如:创建 Pod 时 Storage 类型是 Pods 时,其对应的就是 REST Storage API)。
REST Storage API 会对请求作相应的处理并将处理的结果存入高可用键值存储系统 Etcd 中。
在 API Server 响应 Kubecfg 的请求后,Scheduler 会根据 Kubernetes Client 获取的集群中运行 Pod 及 Minion / Node 信息将未分发的 Pod 分发到可用的 Minion / Node 节点上。
API Server 「资源操作入口」
API Server 提供了资源对象的唯一操作入口,其它所有组件都必须通过它提供的 API 来操作资源数据。只有 API Server 会与存储通信,其它模块都必须通过 API Server 访问集群状态。
API Server 作为 Kubernetes 系统的入口,封装了核心对象的增删改查操作。API Server 以 RESTFul 接口方式提供给外部客户和内部组件调用,API Server 再对相关的资源数据(全量查询 + 变化监听)进行操作,以达到实时完成相关的业务功能。
以 API Server 为 Kubernetes 入口的设计主要有以下好处:1. 保证了集群状态访问的安全。2. API Server 隔离了集群状态访问和后端存储实现,这样 API Server 状态访问的方式不会因为后端存储技术 Etcd 的改变而改变,让后端存储方式选择更加灵活,方便了整个架构的扩展。
Controller Manager 「内部管理控制中心」
Controller Manager 用于实现 Kubernetes 集群故障检测和恢复的自动化工作。Controller Manager 主要负责执行以下各种控制器:
Replication Controller Replication Controller 的作用主要是定期关联 Replication Controller (RC) 和 Pod,以保证集群中一个 RC (一种资源对象) 所关联的 Pod 副本数始终保持为与预设值一致。
Node Controller Kubelet 在启动时会通过 API Server 注册自身的节点信息,并定时向 API Server 汇报状态信息。API Server 在接收到信息后将信息更新到 Etcd 中。 Node Controller 通过 API Server 实时获取 Node 的相关信息,实现管理和监控集群中的各个 Node 节点的相关控制功能。
ResourceQuota Controller 资源配额管理控制器用于确保指定的资源对象在任何时候都不会超量占用系统上物理资源。
Namespace Controller 用户通过 API Server 可以创建新的 Namespace 并保存在 Etcd 中,Namespace Controller 定时通过 API Server 读取这些 Namespace 信息来操作 Namespace。 比如:Namespace 被 API 标记为优雅删除,则将该 Namespace 状态设置为 Terminating 并保存到 Etcd 中。同时 Namespace Controller 删除该 Namespace 下的 ServiceAccount、RC、Pod 等资源对象。
Service Account Controller Service Account Controller (服务账号控制器),主要在命名空间内管理 ServiceAccount,以保证名为 default 的 ServiceAccount 在每个命名空间中存在。
Token Controller Token Controller(令牌控制器)作为 Controller Manager 的一部分,主要用作:监听 serviceAccount 的创建和删除动作以及监听 secret 的添加、删除动作。
Service Controller Service Controller 是属于 Kubernetes 集群与外部平台之间的一个接口控制器,Service Controller 主要用作监听 Service 的变化。 比如:创建的是一个 LoadBalancer 类型的 Service,Service Controller 则要确保外部的云平台上对该 Service 对应的 LoadBalancer 实例被创建、删除以及相应的路由转发表被更新。
Endpoint Controller Endpoints 表示了一个 Service 对应的所有 Pod 副本的访问地址,而 Endpoints Controller 是负责生成和维护所有 Endpoints 对象的控制器。 Endpoint Controller 负责监听 Service 和对应的 Pod 副本的变化。定期关联 Service 和 Pod (关联信息由 Endpoint 对象维护),以保证 Service 到 Pod 的映射总是最新的。
Scheduler「集群分发调度器」
Scheduler 主要用于收集和分析当前 Kubernetes 集群中所有 Minion / Node 节点的资源 (包括内存、CPU 等) 负载情况,然后依据资源占用情况分发新建的 Pod 到 Kubernetes 集群中可用的节点。
Scheduler 会实时监测 Kubernetes 集群中未分发和已分发的所有运行的 Pod。
Scheduler 会实时监测 Minion / Node 节点信息,由于会频繁查找 Minion/Node 节点,Scheduler 同时会缓存一份最新的信息在本地。
Scheduler 在分发 Pod 到指定的 Minion / Node 节点后,会把 Pod 相关的信息 Binding 写回 API Server,以方便其它组件使用。
Kube-Node「服务节点」
Kubelet 「节点上的 Pod 管家」
负责 Node 节点上 Pod 的创建、修改、监控、删除等全生命周期的管理。
定时上报本地 Node 的状态信息给 API Server。Kubelet 是 Master API Server 和 Minion / Node 之间的桥梁,接收 Master API Server 分配给它的 Commands 和 Work。
Kubelet 通过 Kube ApiServer 间接与 Etcd 集群交互来读取集群配置信息。
Kubelet 在 Node 上做的主要工作具体如下:1. 设置容器的环境变量、给容器绑定 Volume、给容器绑定 Port、根据指定的 Pod 运行一个单一容器、给指定的 Pod 创建 Network 容器。2. 同步 Pod 的状态,从 cAdvisor 获取 Container Info、 Pod Info、 Root Info、 Machine info。3. 在容器中运行命令、杀死容器、删除 Pod 的所有容器。
Proxy「负载均衡、路由转发」
Proxy 是为了解决外部网络能够访问集群中容器提供的应用服务而设计的,Proxy 运行在每个 Minion / Node 上。
Proxy 提供 TCP / UDP 两种 Sockets 连接方式 。每创建一个 Service,Proxy 就会从 Etcd 获取 Services 和 Endpoints 的配置信息(也可以从 File 获取),然后根据其配置信息在 Minion / Node 上启动一个 Proxy 的进程并监听相应的服务端口。当外部请求发生时,Proxy 会根据 Load Balancer 将请求分发到后端正确的容器处理。
Proxy 不但解决了同一宿主机相同服务端口冲突的问题,还提供了 Service 转发服务端口对外提供服务的能力。
Proxy 后端使用随机、轮循等负载均衡算法进行调度。
Kubectl 「集群管理命令行工具集」
- Kubectl 是 Kubernetes 的 客户端的工具。 通过 Kubectl 命令对 API Server 进行操作,API Server 响应并返回对应的命令结果,从而达到对 Kubernetes 集群的管理。
Kubernetes Network
客户端访问 ——> service1 ——> Pod1 ——> service2 ——>Pod2
所有的Pod之前的访问都是由其service来代理的,当Pod间知道相应的Pod的IP后,就会直接进行通信,可以理解为DNS的作用。
Kubernetes的关键概念
• Pod - 一组容器
• 标签 - 用于识别Pods的标签
• Kubelet - 容器代理
• kube-proxy - Pod的负载平衡器
• etcd - 元数据服务
• cAdvisor - 容器顾问提供者资源使用/性能统计
• Replication Controller - 管理Pod的复制
• Scheduler- 调度工作节点中的Pod
• API Server - Kubernetes API服务器
什么是Pod?
一组或多个容器,这些容器始终位于同一位置并共同调度,并共享上下文
Pod中的容器共享相同的IP地址,端口,主机名和存储
像虚拟机一样建模
每个容器表示一个进程
在同一Pod中的容器紧密耦合
Pods被安排在Nodes节点中
Kubernetes的基本部署单位
同一个Pod内的容器使用IPC相互通信;
容器可以通过本地主机找到彼此;
每个容器都继承Pod的名称
每个Pod在扁平的共享网络空间中都有一个IP地址
Volumes卷由Pod中的容器共享
Pod用例
内容管理系统,文件和数据加载器,本地缓存管理器等。
日志和检查点备份,压缩,循环,快照等。
数据更改监视程序,日志尾部,日志记录和监视适配器,事件 出版商等
代理,网桥和适配器
控制器,管理器,配置器和更新器
Replication Controller
确保一个Pod或同类Pods始终处于可用状态
始终保持所需的Pods数量
如果有过多的Pod,它们会被杀死
新Pods失败,被删除或终止时将启动它们
创建至少一个Replication Controller以确保Pod始终可用
创建Replication Controller和容器通过标签关联
Controller
管理Pod | 复制集
处理复制和推出 | 部署
提供自我修复功能 | 守护程序集
使用个Pod模板制作真实的Pods | 工作
Service
Kubernetes Pods不是永久的,待面世停止运转后,是不能再次够恢复使用的
Controllers专用于动态创建和销毁Pods(例如,在放大或缩小或滚动更新时)
虽然每个POD都有自己的IP地址,但这些IP地址不能长期稳定
这会导致一个问题:如果kubernetes集群中的一些pod(我们称之为后端)为其他pod(我们称之为前端)提供功能,那么这些前端如何发现并跟踪该集群中的哪些后端?
Kubernetes Service是一种抽象概念,它定义了Pod的逻辑集和访问它们的策略-有时称为微服务
Service 所针对的Pod集(通常)由标签选择器确定
对于Kubernetes原生应用程序,Kubernetes提供了一个简单的Endpoints API,只要Service中的Pod集发生更改,该API就会更新
对于非本机应用程序,Kubernetes提供了基于虚拟IP的服务桥,该桥可重定向到后端Pod
Labels & Selectors
与Kubernetes对象关联的键/值对
用于组织和选择对象的子集
在创建时附加到对象,但可以随时修改
标签是将一个API对象与另一个API对象关联的必要粘合剂
Replication Controller ->Pods
Service -> Pods
Pods->Nodes
Service
定义一组逻辑pod的抽象,这些逻辑pod通过访问策略绑定他们
通过内部和外部端点公开Service
务还可以通过Virtual-IP-Bridge指向非Kubernetes端点
支持TCP和UDP
与kube-proxy的接口以操作iptables
Service可以在集群内部或外部公开
Service作为静态API对象
虚拟但静态IP
无需发现Service
一群一起工作的Pods
按选择器分组
定义访问策略
“负载平衡”或“无头”
获得稳定的虚拟IP和端口
有时称为服务门户
也是一个dns名称
VIP由Kube代理管理
监视所有Service
当后端发生变化时更新iptables
对于非本地应用程序隐藏复杂度理想的选择
kube-proxy
在每个节点上运行-代理udp和tcp-不理解http-提供负载平衡-仅用于访问Service
kubernetes网络代理在每个节点上运行
这反映了每个节点上kubernetes api中定义的Service,可以跨一组后端执行简单的tcp、udp流转发或循环tcp、udp转发。
Service群集IP和端口当前通过Docker Link兼容的环境变量找到,这些环境变量指定Service代理打开的端口
有一个可选的插件为这些群集IP提供群集DNS
用户必须使用APIServer API创建Service以配置代理
Proxy-mode: userspace
- 对于每个Service,它都会在本地节点上打开一个端口(随机选择)
- 与此“代理端口”的任何连接都将代理到Service的后端Pod之一
Proxy-mode: iptables
- 为每个Service安装iptables规则,以捕获到Service的clusterIP(虚拟)和端口的流量,并将该流量重定向到Service的后端集之一
- 为每个Endpoints对象安装iptables规则,该规则选择一个后端Pod
Discovering services
kubernetes支持查找Service的两种主要模式-环境变量和dns
环境变量
当pod在节点上运行时,kubelet为每个活Service务添加一组环境变量。它同时支持docker links兼容变量和更简单的{SVCNAME}SERVICE_HOST和{SVCNAME}SERVICE_PORT变量,其中Service名称为大写,破折号转换为下划线。
DNS
一个可选的(尽管强烈建议)群集附加组件是DNS服务器
DNS服务器监视Kubernetes API以获取新Service,并为每个Service创建一组DNS记录
如果在整个集群中启用了dns,那么所有pod都应该能够自动执行Service的名称解析
Ingress
- 通常,Service和pod只有ips可以通过集群网络路由。所有最终到达边缘路由器的流量要么被丢弃,要么被转发到其他地方
- Ingress 是允许入站连接访问集群Service的规则集合
- Ingress——基于URL的路由
- Ingress是允许入站连接访问集群Service的规则集合
Overlay network concept
kubernetes Object
kubernetes对象是kubernetes系统中的持久性实体
kubernetes使用这些实体来表示集群的状态
具体来说,他们可以描述:
哪些docker化应用程序正在运行(以及在哪些节点上运行)
这些应用程序可用的资源
有关这些应用程序行为的策略,如重启策略、升级和容错
kubernetes对象是一个“意图记录”-创建对象后,kubernetes系统将不断工作以确保对象存在
通过创建一个对象,您可以有效地告诉kubernetes系统您希望集群的工作负载是什么样的;这是集群的期望状态
要使用kubernetes对象,无论是创建、修改还是删除它们,都需要使用kubernetes api
例如,当您使用kubectl命令行界面时,cli会为您进行必要的kubernetes api调用;您也可以在自己的程序中直接使用kubernetes api
Object 规格和状态
每个Kubernetes对象都包含两个嵌套的对象字段,用于控制对象的配置:对象规格和对象状态
您必须提供的规范描述了对象的所需状态-希望对象具有的特征
状态描述对象的实际状态,并由Kubernetes系统提供和更新。
在任何给定时间,Kubernetes控制平面都会主动管理对象的实际状态以匹配您提供的所需状态
描述Kubernetes对象
在Kubernetes中创建对象时,必须提供描述其所需状态的对象规范,以及有关该对象的一些基本信息(例如名称)
当您使用Kubernetes API创建对象(直接或通过kubectl)时,该API请求必须在请求正文中以JSON形式包含该信息
通常,您会在.yaml文件中将信息提供给kubectl。 发出API请求时,kubectl将信息转换为JSON
K8s主要由Master,Node组成
Client -> Master(API Server)
Registry: Docker Hub,gcr.io,quay.io
测试环境:
1 Master
3 Nodes
kubeadm:
Master,Node
CentOS:kubeadm,kubelet