华为云DevOps系列之 —— 持续部署与发布(四)容器编排 & K8s
【摘要】 华为云DevOps系列之 —— 持续部署与发布(四)容器编排 & K8s
什么是容器编排
- 为了管理分布在不同节点上成百上千个容器,这些节点会形成一个
容器集群
,容器集群实际上是一组互相连接的操作系统
,可能是实体机、虚拟机或者容器,容器集群的管理节点会在集群的每个业务节点中部署一个 agent,形成一个整体的资源池,并且作为环境抽象层存在 - 容器应用可以运行在这个统一的资源池中,并不需要关心具体运行在哪个节点上,会有
管理节点
进行统一协调与分配,轻松实现容器应用的快速部署,并且可以扩展到上千个节点上,具备自我修复与弹性伸缩能力,这些部署、弹性伸缩能力其实都是指编排能力
什么是 Kubernetes
- kubernetes(K8s) 是
容器编排的标准
,是谷歌根据自己内部的容器系统 Borg,去除掉了业务属性,贡献给开源社区的产品,它是完全的开源软件
- K8s 是用于自动部署,扩展和管理容器化应用程序的开源软件
- 生产级别的容器编排系统
- 数据中心 OS
- 新生代的云平台
Kubernetes 与 Docker 的关系
- Docker 容器是基于
操作系统层
,打包了软件对环境的依赖,保证同一软件交付件在开发、测试、生产不同环境的一致性,对节点上的容器资源实现一定的管理能力 - k8s 针对的是
容器集群的管理
,可能对于几个容器应用来说,你可以在docker的容器节点上手动地进行操作与管理,但是针对很多的容器应用的时候,比如成百上千个容器,Kubernetes 提供资源的管理和容器的调度技术,提供容器应用生命周期管理
、弹性伸缩
、监控运维
的基本机制,决定容器之间如何进行交互
- 由 Docker、Kubernetes 所带动的容器标准化大幅简化了各种环境管理工作,提升了部署流程自动化程度,因此大大加速了 DevOps 理念落地进程
Kubernetes 整体架构
- 我们往往所说的集群中一般有一个
主控节点 Master
,负载管理整个集群的一个集群,一般用 etcd 作为后端存储,高可用版本一般是三个 Master。Master 的主要功能就是调度
,决定将应用放在哪里去运行- API Server:提供了接口供客户端(kubectl)或者 K8s 其他组件,管理 cluster 的各种资源,主要提供 Kubernetes API,提供对 Pods,Services,ReplicationController 等对象的 CRUD ,处理 REST 操作,并验证它们
- etcd:更新相应的对象 API,负责保存 cluster 的配置信息和各类资源的状态信息,当数据发生变化的时候,etcd 会迅速的通知 Kubernetes 组件,所有的持久性状态都保存在 etcd 中,etcd 支持 watch,这样组件就很容易得到系统状态的变化,从而响应以及做一些协调工作
- Scheduler:负责决定将 Pod 放在哪个 Node 上运行,在调度时会充分考虑高可用、性能、数据亲和性的需求
- Controller Manager:负责管理 Cluster 各种资源,由多种 Controller 组成,包括 replication controller、namespace controller 等
- Replication controller:管理 deployment、replicaset、daemonset 等的生命周期
- 用户使用 Kubernetes 的时候,会通过 Master 节点上的
API server
,向 Master 描述清楚资源的定义,Master 按照定义进行对象的创建,并且一直跟踪监控对象的情况,保证其一直符合用户的定义 - 集群中的业务节点叫做
Node(Worker)
,负责运行用户实际的业务应用,Master 在每个 Node 上会安装 Kubelet,Kubelet 作为 agent 对 Node 上面的容器资源进行管理- Kubelet:Node 上的 Agent,有多少个 Node 就有多少个 Kubelet,当 Scheduler 确定在某个 Node 上运行 pod 后,会将 Pod 的具体配置信息(image、volume等)发送给该节点的 kubelet,kubelet 会根据这些创建和运行容器,并向 Master 报告运行状态。Kubelet 管理 pods 和它们的容器、镜像、卷等
- Kube-proxy:简单的网络代理和负载均衡器,具体实现了 service 的模型,提供统一的访问能力。转发 Service 请求到 Pod,如果有多个副本,kube-proxy 会实现负载均衡
- Kubectl:k8s 的命令行工具,kubectl 连接 APIServer,通过 kubectl 可以部署和管理应用,查看各种资源、创建、删除更新各种组件
Kubernetes 关键概念
POD
- 在 Kubernetes 中,Pod 是能够创建、调度和管理的
最小部署单元
,是一组容器实例的集合,不是单独的应用容器 - 同一个 Pod 里面的容器共享同一个网络命名空间,IP 地址及端口空间和卷
- 为什么不直接使用容器,而是在容器上面再封装一层 Pod?
- 首先,很多时候,我们需要使用容器去承载微服务,做微服务设计的时候,我们一般推荐一个应用一个进程,如果承载体为容器的话,就是一个容器一个进程,但是现实很多时候,为了管理微服务,需要安装相关的服务监控软件,或者是数据读取软件,那也就意味着我们要在一个容器中安装多个软件,也就是多个进程,这样就破坏了我们刚刚所说的
一个容器一个进程
的原则,为了符合微服务的设计原则,Google 设计了 Pod 这个概念 - 一般一个 Pod 会有多个容器,一个服务容器用于提供服务;多个辅助容器用于完成服务容器的监控或者是数据管理
- 我们以一个案例来说明一下,比如我们有一个 Pod,Pod 里面有三个容器:web 容器、监控容器、日志读取容器,web 容器中只运行 wen 软件,对外暴露的端口是 80。监控容器中运行 web 监控软件,这个监控软件只需要监控本地的 80 端口,就可以完成对 web 服务的 web 容器的监控(Pod 内的容器是共享 IP 地址的)。然后还需要收集日志信息,创建日志容器,日志来读取 web 软件的信息只需要将相关路径下的文件读取上报到对应的日志管理平台就可以了(Pod 的容器是共享数据存储的)
- 首先,很多时候,我们需要使用容器去承载微服务,做微服务设计的时候,我们一般推荐一个应用一个进程,如果承载体为容器的话,就是一个容器一个进程,但是现实很多时候,为了管理微服务,需要安装相关的服务监控软件,或者是数据读取软件,那也就意味着我们要在一个容器中安装多个软件,也就是多个进程,这样就破坏了我们刚刚所说的
- 从生命周期来说,Pod 的短暂的而不是长久的的应用。Pod 被调度到节点,保持在这个节点上直到被销毁
ReplicaSet
- Replicaset是
副本控制器
,主要作用是控制 deployment 应用副本的数量 - 确保 Pod 的一定数量的份数(replica)在运行。如果超过这个数量,控制器会杀死一些;如果少了,控制器会启动一些
- ReplicaSet 用于解决 Pod 的扩容和缩容问题
- 通常用于
无状态应用
,因为无状态应用经常会涉及到扩缩容
Deployment
- 容器应用部署的时候,Kubernetes 会根据它的特点对其进行封装,对于无状态应用一般使用 Deployment 对象,Kubernetes 通过 Deployment 控制器进行管理
- 无状态应用的本质就是一个应用的多个实例之间
完全没有区别
,每个请求在不同的实例返回的结果都是一样的,k8s 对他们的处理也是随机的,比如缩容,会随机杀掉几个容器 - 如果重启了无状态应用,由于它不需要对接持久化存储,应用产生的数据是不会被保存下来的,Kubernetes 的重启会杀掉这个容器,并且重新拉起一个新的容器
- Deployment 即在 K82 中部署的无状态应用
- 典型应用代表:Nginx,Tomcat
- 不必为应用保持状态/持久化数据
- 每个实例对于同一个请求响应的结果完全一致
- 实例重启会丢失运行态数据
- 对于用户来说,用户会去创建一个 Deployment,Deployment 会自己建一个 ReplicaSet,ReplicaSet 会建 Pod,然后一个个容器(Contaioner)就会运行在 Pod 中
Statefulset
- 有状态应用本质是在运行过程中会保存数据或状态的工作负载称为
有状态工作负载
,每个实例都是唯一的
- Statefulset 即在 K8s 中部署的有状态应用
- 典型应用代表:MySQL、redis
- 每个实例具有唯一的网络标识符
- 生命周期的操作将有序的在不同实例进行
- 一般会挂载持久化存储保证数据持久性
DaemonSet
- DaemonSet 能够让所有(或者一些特定)的 Node 节点运行同一个 Pod。当节点加入到 K8S 集群中,Pod 会被(DaemonSet)调度到该节点运行,当节点从 K8S 集群中被移除,被(DaemonSet)调度的 Pod 会被移除,如果删除 DaemonSet,所有跟这个 DaemonSet 相关的 Pods 都会被删除。
- 比如说在所有的节点上要跑一个小工具(对所有的节点上的容器进行监控、日志收集或者是分布式存储),使用 DaemonSet 就会自动地在所有节点中启动,如果增加了新的实例,也会在新的实例上自己启动小工具
Service
- K8S 为了实现服务间的发现和负载均衡,设计了 Service,Service负责提供容器应用的访问,是通过
4层协议
访问,通过端口
进行区分 - 应用部署在集群中如何相互发现?如何对外提供访问?保证 POD 变化时候,对访问段透明呢?
- 访问端只需要知道 service 的地址就可以了,由 service 提供代理,不管容器漂到什么地方,service 都能找到它
- service 定义了 Pods 的逻辑集合和访问这个集合的策略。Pods 集合是通过定义 service 时的 lable 选择器完成的
- service 的抽象使得前端客户和后端 Pods 进行了解耦
- K8S Service 支持 TCP 和 UDP 协议,默认是 TCP
- K8S 支持两种方式的服务发现方法:环境变量和 DNS
service 的类型和解释
- ClusterIP
- 使用集群内的
私有IP
- ClusterIP 主要在每个节点使用 iptables,将发向 clusterIP 对应端口的数据,转发到 kube-proxy 中,然后 kube-proxy 将自己内部实现有负载均衡的方法,并可以查询到这个 service 下对应 Pod 的地址和端口,进而把数据转发给对应 Pod 的地址和端口
- 使用集群内的
- NodePort
- 除了使用 clusterIP 外,也将 service 的 port 映射到每个 node 的一个指定内部 port 上,映射的每个 node 的内部都一样
- NodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步导给对应的 Pod
- LoadBalancer
- 使用一个 clusterIP & NodePort,但是会向 Cloud provider 申请映射到 service 本身的负载均衡
- LoadBalancer 跟 NodePort 其实是容一种方法,区别在于 LoadBalancer 比 NodePort 多了一步,就是可以调用 cloud provider 去创建 LB 来向节点导流
它们三者的关系是:逐层包含,由内到外
Ingress
- Service 提供了4层的访问,ingress 提供了7层的访问,在集群北向提供7层负载均衡能力,对接创建的 service 实现7层转发能力,一般通过 nginx 实现网络转发
- 七层负载均衡是采用了增强型弹性负载均衡,在四层负载均衡访问方式的基础上支持了 URL 配置,通过对应的 URL 将访问流量分发到对应的服务。同时,服务根据不同 URL 实现不同的功能
- 通过配置公网类型和私网类型的负载均衡实例可以实现公网的七层路由转发和内网(同一VPC内)的七层路由转发
Kubernetes 工作原理
- 首先,用户通过 kubectl 下发创建容器应用的命令,比如说去创建一个 deployment 应用
- 首先会发送创建 ReplicaSet 的信息,然后 Master 节点里的 API-server 收到指令后将信息同步到后端存储 etcd 中
- etcd 会反馈 ReplicaSet Created 事件到 API-server 当中,API-server 再将这个事件上报给 controller-manager
- controller-manager 收到这个 ReplicaSet 信息后,就会根据 ReplicaSet 的设置(比如你设置了3个Pod)下发创建 Pod 的命令
- API-server 收到指令后,将 Pod 信息同步到 etcd,etcd 又上报 Pod Created 事件给 API-server,API-server 收到这个信息后又上报给 scheduler
- scheduler 收到信息后,会根据这个信息去确定 Pod 要在哪个节点上创建,然后更新调度 Pod 的结果以及绑定的 node 节点的指令发送给 API-server,同步信息到 etcd,etcd 再上报 Pod Bound 事件给 API-server
- 最后 API-server 发送这个事件到对应节点的 kubelet
- kubelet 执行创建 Pod 的操作,这样就完成了整个创建的流程
- 在整个生命周期中,controller-manager 会持续 watch 各类 set 定期同步,保证最终的一致性
- scheduler 会持续 watch 集群的 node,供调度使用
- kubelet 会持续 watch 被调度到本节点的 Pod,执行相关的生命周期的动作
应用容器化之 CI/CD
- Docker和kubernetes实现了应用容器化,并且促进了CI/CD的流程,降低了应用从构建到部署流程的复杂性,加速业务的快速迭代
华为云容器引擎 CCE
- 华为云容器引擎 CCE,基于开源 Kubernetes 和 Docker,提供了高性能、高可靠的企业级容器服务
- CCE的主要价值在于开放和开源的生态、增强的商业化特性、灵活兼容易购基础设施
CCE 产品关键特性
应用场景 —— DevOps 持续交付
- 可定制化持续交付流程
- 配置第三方开发流水线开发测试工具,自动完成从代码提交到应用部署的 DevOps 完整流程,替代部署复杂、迭代缓慢的传统方式,提高企业代码交付和部署的频率
- 配置第三方开发流水线开发测试工具,自动完成从代码提交到应用部署的 DevOps 完整流程,替代部署复杂、迭代缓慢的传统方式,提高企业代码交付和部署的频率
思考题
关于容器技术,以下哪些说法是正确的()
- A. Docker 镜像文件 image,包含了已经打包好的应用程序和运行环境,多个容器无法共享 image 存储
- B. 使用 “华为云容器引擎CCE” 可以一键创建 Kubernetes 集群
- C. Docker 为应用提供了一个统一的环境,避免应用在不同主机上因为环境不同而产生问题
- D. K8S 中 deployment 的每个实例对于同一个请求响应的结果未必完全一致
答案:BC
解析:
- A. 多个容器对于基础镜像 base image 是共享存储的
- B. CCE 的关键特性
- D. 对于 deployment 对象,每个实例对同一个请求响应结果一定的完全一致的
最后,欢迎大家关注我的个人微信公众号 『小小猿若尘』,获取更多IT技术、干货知识、热点资讯。同时,我在公众号中分享了精心整理的一些视频资料(包括 Python全栈教程、AI教程、前端、数据库等),大家回复相应关键词即可获取网盘视频链接,感谢大家的关注😊
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)