应用部署演进(二)

前言

鸽了一个多月,更文虽迟但到

近两个月的打工人时光,让人变秃了,也变懒了(试图解释

以及忙着忙着,就模糊了工作和个人生活的界限,不似996,胜似996,有点心累

希望接下来能好好调整

话不多说,进入正题

容器编排

容器本身没有价值,有价值的是“容器编排”

容器编排简介

容器编排,就是对容器的管理,包括:

  • 应用部署:将应用装进容器,部署到某一物理节点上
  • 水平扩展:可动态调整容器副本数量,业务请求压力大的时候,就可以多开几个应用副本来处理
  • 服务发现:一个应用对应一种服务,当你把应用跑起来后,容器编排工具就能发现这一服务,这样其他服务就可以调用当前服务了
  • 负载均衡:容器编排工具能将请求调度到一个服务的不同容器副本上,从而降低各容器的压力
  • 故障自愈:物理节点宕机后,其上的容器会重新部署到另一个节点
  • 滚动更新:对一个服务对应的全部应用进行批量更新
  • 版本回退:可以回退应用版本

目前比较主流的容器编排工具之一就是k8s

k8s简介

k8s,全称为Kubernetes,K8s是谷歌和redhat主导开发的容器编排工具。

Kubernetes这个单词源于希腊语,译为“舵手”

下图是个形象的比喻,将k8s类比成舵手,统筹调度着船上的一个个集装箱(容器):

1605073130205

K8s架构

1605073130205

简单来说就是:master节点管理node节点,node节点上跑着容器

用户通过UI界面或者CLI(命令行)与master节点交互

而不同节点上跑着不同的k8s组件

K8s组件

Master节点上的组件:
  • API server:顾名思义,包括了k8s所有的api,是集群的统一入口。Kubernetes 中所有的组件都会和 API Server 进行连接,组件与组件之间一般不进行独立的连接,都依赖于 API Server 进行消息的传送;
  • scheduler:调度器,当你用k8s跑一个应用时,它会根据应用对 CPU、memory 的请求大小,找一台合适的节点,进行放置
  • etcd:存储系统,保存集群的数据。比如容器部署到了哪些节点上、容器的信息等等
  • controller:控制器,可以用来控制应用的副本数量,实现了服务编排里说的故障自愈和水平伸缩的功能
Node节点上的组件:
  • kubelet:用来管理Node节点,可以理解为master节点派到Node节点的代表
  • kube-proxy:提供网络代理,提供负载均衡等功能
  • docker:运行容器

部署应用的过程分解

  • 用户可以通过 UI 或者 CLI 提交一个 Pod(简单说就是一组容器,后边会介绍) 给 Kubernetes 进行部署
  • 这个 Pod 请求首先会提交给 Kubernetes API Server
  • 下一步 API Server 会把这个信息写入到它的存储系统 etcd
  • 之后 Scheduler 会通过 API Server 的 watch 或者叫做 notification 机制得到这个信息:有一个 Pod 需要被调度。
  • 这个时候 Scheduler 会根据Pod对硬件的要进行一次调度(选出一个合适的节点),在完成这次调度之后,它会向 API Server 反馈 说:“OK!这个 Pod 需要被调度到xx节点上。”
  • 这个时候 API Server 接收到这次操作之后,会把这次的结果再次写到 etcd 中
  • 然后 API Server 会通知相应的节点进行这次 Pod 真正的执行启动
  • 相应节点的 kubelet 会得到这个通知
  • kubelet 就会去调 Container runtime 来真正去启动配置这个容器和这个容器的运行环境,去调度 Storage Plugin 来去配置存储,network Plugin 去配置网络

Pod

Pod,是一组容器

这一组容器装在一个叫infra的容器里(俄罗斯套娃),共享同一个 Network Namespace,可以共享同一个Volume(可简单理解为一个文件夹)。

为什么pod要设计成为一组容器呢?
其实这个概念是类比进程和进程组的关系。

上一篇文章已经说过,一个容器里边一般只跑一个进程,即应用进程;那么一个pod对应一组容器,自然也就对应一个进程组

Google 公司的工程师们发现,他们部署的应用,往往都存在着类似于“进程和进程组”的关系。更具体地说,就是这些应用之间有着密切的协作关系,使得它们必须部署在同一台机器上。

因此,Pod是 k8s项目中的最小编排单位

Deployment和Service

在k8s中,我们对一组pod的部署对应着一个Deployment,可以用一个yaml文件来描述:

1606146838(1).jpg

通过kubectl apply -f xxx.yaml启动deployment,从而来保证pod副本数稳定

一组pod跑起来自然是要对外提供服务的,k8s对此也做了抽象,用一个yaml文件描述Service,eg:

apiVersion: v1
kind: Service
metadata:
  name: demo #服务名
  namespace: default
  labels: 
    app: demo
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: demo
    version: v1
  ......

这些yaml文件也被称为资源清单文件,描述的对象被称为资源,比如DeploymentService,每个资源可以设置对应的labelselector

通过给selector绑定不同的label,建立deployment和pod、service与deployment的映射关系

蓝绿部署

场景:

版本更新不允许两个版本代码同时运行。

方法:

启动一个新的Deployment,给这个deployment一个新的标签

配置service的标签选择(service原先选择老的deployment的标签,后来改成选择新deployment的标签),将流量导向新的Deployment

之前的service.yaml

apiVersion: v1
kind: Service
metadata:
  name: demo #服务名
  namespace: default
  labels: 
    app: demo
spec:
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  # 注意这里我们匹配 app 和 version 标签,当要切换流量的时候,我们更新 version 标签的值,比如:v2
  selector:
    app: demo
    version: v1

v1-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo1-deployment
  namespace: default
  labels:
    app: demo
    version: v1 #deployment的版本:v1
........

v2-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo1-deployment
  namespace: default
  labels:
    app: demo
    version: v2 #deployment的版本:v2
........

通过命令启动service和两个deployment:

kubectl apply -f service.yaml -f v1-deployment.yaml -f v2-deployment.yaml

动态修改service的标签选择器,实现流量从v1版本应用切到v2版本应用

kubectl patch service demo -p '{"spec":{"selector":{"version":"v2"}}}'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值