TOC
到底什么是云原生架构
-
云原生应用定义
- 软件开发行业,早前从XP(ExtremeProgramming)极限编程、敏捷Agile、DevOps等,没有明确定义,是业界最佳实践的一些统称
- Applications adoptiong the principles of Microservices packaged as Containers orchestracted by Platforms running on top of Cloud infrastructure, developed using practices such as Continous Delivery and DevOps.
- 基于微服务原理开发的应用,以容器方式打包;在运行时,容器由运行于云基础设施之上的平台进行调度;应用开发采用持续交付和DevOps实践
-
云演进史
- Non-Virtualized:企业计算一般直接采用硬件服务器,如sun提供的中高端企业计算服务器
- Virtualization:可以用软件方式按需创建虚拟机
- IaaS(Infrastructure as a Service):基础设施即服务,把计算、网络、存储封装成可以按需使用的资源,amazon将其商业化,退出了AWS公有云
- PaaS(Platform as a Service):平台即服务,比IaaS的抽象层次更高,IaaS主要面向计算、网络、存储这些计算资源,PaaS是一个应用的运行时平台,用户在PaaS平台上可直接部署应用,不需要关心底层的计算资源;HEROKU可认为是现代云原生平台的鼻祖或原型
- Open Souce IaaS:开源IaaS产品,标志性的就是Openstack,它满足中大型企业自建私有云的需求
- Open Souce PaaS:开源PaaS产品,标志性的就是Cloud Foundry,后被Pivotal收购
- Containers:颠覆式的Docker容器技术出现,从开始就走开源路线,使得容器技术在行业内快速普及
- Cloud Native:随着Docker和K8s的快速普及,大厂开始了立标准的过程,成立了CNCF组织,专门推动云原生项目的治理、推广和应用,标志着计算进入了云原生时代
2000 2001 2006 2009 2010 2011 2013 2015 Sun vmware amazon HEROKU openstack CLOUD FOUNDRY docker CLOUD NATIVE Non-Virtualized Hardware Virtualization IaaS PaaS Open Source IaaS Open Source PaaS Containers Cloud Native -
CNCF - Cloud Native Computing Foundation
Kubernetes背景和架构
-
Kubernetes历史
- 支持云原生应用的一个平台,起源于google,每周要启动20亿个容器
- google的容器平台发展:
- 第一代:Borg,内部产品,2003~2004,经典的master-slave架构;master提供api,cli、ui、外部系统通过api跟集群交互;每个slave节点安装一个Borglet的组件,用于管理容器、网络、路由;调度程序scheduler根据slave上的资源使用情况进行调度决策,并且指挥Borglet进行操作
- 第二代:Omega,是Borg的升级版
- 第三代:开源的Kubernetes,古希腊的词语,意为船长、舵手;专门用来指挥调度容器;
-
Kubernetes趋势
- 稳步上升,项目提交数量活跃
-
Kubernetes解决什么问题:
- 本质上简化微服务的开发和部署,解决微服务的公共关注点
- DevOps开发者体验 / 微服务 / IaaS(操作系统,虚拟化,硬件/网络/存储)
- K8s解决微服务中的:
- 服务发现和LB
- 弹性和容错
- API管理
- 服务安全
- 日志监控
- Metrics监控
- 调用链监控
- 调度和发布
- 自愈和自动伸缩
- 和Dubbo、Spring Cloud相比,K8s是解决微服务公共关注点最全面的一个平台性的解决方案;K8s对公共关注点大部分以组件形式封装打包到K8s大平台中,让开发人员在开发微服务时专注业务逻辑的实现,不需要特别关注微服务底层的公共关注点
-
Kubernetes架构:经典的Master-Slave架构
- Master Nodes 和 Worker Nodes,可以是物理机或虚拟机
- Master节点:
- etcd:基于K-V的分布式存储机制,底层采用raft协议;K8s集群的状态数据,包括配置、节点、Pod等等,最终都存储在etcd中
- API server:对外提供操作和获取k8s集群资源的api,是唯一操作etcd的组件,可以简单理解为是etcd的代理
- Scheduler:相当于k8s的大脑,负责调度决策,如对新的应用发布请求,schduler负责决策响应的pods应该分布在哪些worker节点上
- Controller Manager:相当于集群状态的协调者,观察目前集群的实际状态,和etcd中的预期状态进行比对,不一致的话就要对资源进行协调操作,让实际状态和预期状态达到最终一致;所有k8s采用一种最终一致调度机制,支持自愈,只要etcd中的预期数据还在,k8s就能最终恢复到预期状态
- 为保证高可用,master节点一般采用多节点部署,但是真正做调度决策的只有一个master节点,所以有一个选主leader election的动作;如果主master节点挂了,其他节点会再选主节点;
- etcd集群一半是单独部署
- Worker节点
- Container Runttime:下载镜像和运行容器的组件;如果采用docker,那么每个节点上都会运行一个docker daemon,运行容器时,如果本地没有镜像,那么daemon就会从docker registry抓取响应镜像
- Pod:简单理解为对容器的包装,是K8s的基本调度单位;实际的容器是运行在pod中的;一个节点上可以启动一个或多个pod,一个应用的pods也可分布在一个或多个节点上;pod之间进行通讯是通过内部的overlay network
- kubelet:负责管理worker节点上的组件,相当于一个agent角色;和master节点的API server进行交互,接收指令执行操作,如启动pod、关闭pod,也返回一些状态数据或事件到master;是每个worker节点上的小脑
- kube-proxy:负责对pod进行寻址和负载均衡;是实现service和服务发现抽象的关键;底层操作iptable规则
- 用户操作k8s集群,一般是通过kubectl命令行工具或k8s的dashboard访问k8s集群,这些工具都通过API server与集群进行交互;外部流量进入k8s去访问pod一般是通过Load Balancer设备
- K8s外围还有一些存储、监控、日志、分析这些配套的服务
- 架构复杂、重量,中小企业不建议自建集群,而采用公有云k8s集群
Kubernetes有哪些基本概念
-
集群 Cluster
- 很多节点组成,可以按需添加更多节点,节点可以是物理机,也可以是虚拟机
- 每个节点都有CPU和内存
- 整个集群可看作一个超大的计算机
-
容器 Container
- 从宿主机操作系统的视角看,容器是一个一个的进程
- 从容器内部的视角看,容器是一个一个完整的操作系统,文件系统、网络、CPU、Memory等完整的资源
-
POD
- K8s并没有直接调度容器,而是在容器外层封装了一个叫Pod的概念:原因一是考虑一些需要辅助容器的场景,如有些需要sidecar的场景;原因二是考虑可以替换使用不同的容器技术
- POD是k8s的基本调度单位
- 一个Pod内可以跑一个或多个容器,共享该pod的文件系统和网络,每个pod有独立的ip,pod中的容器共享这个ip和端口空间;并且同一个pod中的容器可通过localhost相互访问
- 大部分场景下一个pod只跑一个应用容器
-
副本集 ReplicaSet
- 一个应用发布的时候一般不会只发一个pod实例,而是会发多个pod实例,这样才能实现高可用;ReplicaSet就是和一个应用的一组pod相对应的概念,可通过模板yaml或json来规范某个应用的容器镜像、端口、副本数量、点火和健康检查机制、环境变量、volume挂载等相关信息
- 运行时,ReplicaSet会监控和维护pod的数量,过多则下线pod,过少会启动pod
-
服务 Service
- pod在k8s中是一个ephemeral(短暂的、无常的事物)的,可能会随时挂或重启,响应ip会发生变化,如果一个服务的实例ip不固定,服务的消费者无法寻址
- k8s通过引入service这样的抽象概念来解决:简单来讲,service屏蔽了应用的ip寻址和负载均衡这些小细节,消费方可以直接通过服务名访问目标服务;k8s中的service底层机制会做寻址和负载均衡,即使应用的pod的ip发生变更,service也会屏蔽这种变更,让消费方无感知
-
发布 Deployment
- 副本集可认为是一种基本的发布机制,但是操作起来繁琐,为了简化高级的发布,在ReplicaSet的基础上,引入了Deployment概念
- 简单讲,Deployment是用来管理ReplicaSet,实现蓝绿和滚动这些高级发布机制
- 通过Deployment调度实现滚动发布(Rolling Update)的样例
- 假设应用的1.0绿色版本已发布,对应的ReplicaSet是v1.0,通过Deployment进行升级发布应用的1.1蓝色版本,Deployment就会创建ReplicaSet v1.1,之后Deployment会依次调度:不断拉入蓝色版本,拉出绿色版本,直到所有的蓝色pod全部上线,绿色pod全部下线;过程中service抽象会屏蔽应用地址的变更,让消费方无感知;如果在滚动发布的过程中,蓝色pod有问题,如点火健康检查通不过,delployment会自动终止并回退发布;即使发布成功完成,后续如果根据需要,仍可通过deployment回退到之前发布的某个版本
- 发布和服务总结
- Deployment和Service是和微服务发布相关最重要的两个概念,也是发布过程中经常要使用的两个概念
- 发布微服务时所书写定义的描述文件里面主要就是Deployment和Service的规范
-
ConfigMap/Secret
- 微服务在上线的时候需要设置一些可变配置,针对不同环境对应的设定值不同;这些配置有些是在启动期一次配置完成的,如数据库连接字符串,还有一些配置是在运行期可动态调整的,如缓存过期时间、TTL值、业务促销的商品限购数量等;所以微服务需要配置中心的支持,实现针对不同环境的灵活的动态配置
- K8s内置支持微服务的配置,对应概念叫ConfigMap,是K8s平台支持的一种资源,开发人员将配置填写在ConfigMap中,K8s将ConfigMap中的配置以环境变量的形式注入到pod中,这样pod中的应用可以以环境变量的形式去访问这些配置
- ConfigMap也支持以持久卷Volume的形式mount到Pod中,这样pod的应用以本地配置文件的形式来访问配置
- k8s通过Secret来支持敏感数据的配置,可认为是一种特殊的Config,提供更安全的存储和访问配置的机制
-
DaemonSet
- 一种常见场景:需要在每个节点上常驻一个守护进程,如监控场景需要在每个机器上部署一个fluentD日志采集进程或Prometheus的exporter进程
- K8s针对这样的场景,k8s支持一个叫DaemonSet这样一个概念,可以在每个worker节点上面部署一个守护进程pod,并且保证每个节点上有且仅有这样的一个pod
-
其他概念
-
Volume:存储卷抽象,简单可理解为磁盘文件存储,可以是节点本地文件存储,也可是远程存储;挂载mount之后,volume成为pod的一部分,pod销毁volumen也会销毁,但是支持volume的存储可以还在
-
PersistentVolume:持久卷,如果volume只用节点文件的本地存储,那么下次应用容器重启可能会换一个节点,响应的文件存储就不存在了;持久卷是一种高级的存储资源抽象,可对接各种云存储,由集群管理员统一配置
-
PersistentVolumeClaims:应用申请PV时需要填写的规范,包括磁盘大小、类型等等;应用通过PVC申请PV资源,然后以Volume的形式挂载到pod当中;PV和PVC的引入使得Volume和具体的物理存储可进一步的解耦
-
POD -> Volume -> PVC -> PV -> 物理存储
-
StatefulSet:支持有状态应用的一种发布机制,如发布mysql数据库或redis缓存需要StatefulSet,和ReplicaSet相对应
-
Job:支持跑一次的任务
-
CronJob:支持周期性任务
-
-
概念补充
-
Label/Selector
- Label是给k8s中的资源打标签的一种机制,如在pod上打标签标识该pod是属于后端还是前端、是生产的还是staging的、版本信息等;Selector是通过标签查询定位资源的一种机制
-
Namespace
- k8s中的一种逻辑性隔离机制,基于namespace可以实现诸如多租户、环境、项目、团队这些逻辑隔离;还可以限制配额quota,创建资源时如果没有指定namespace,那么创建的资源都会住在缺省的namespace中
-
Readiness Probe(就绪探针)
- 用于判断pod是否可以接入流量,如通过应用的health健康检查端点可以检查这个pod是否就绪,就绪的话就可以接入流量,否则不可以接入流量
-
Liveness Probe(活跃探针)
- 用于判断pod是否存活,如通过应用的health健康检查端点可以定期检查这个pod是否存活,不存活就kill掉这个pod,并根据配置的策略决定是否要重启这个pod
-
-
概念总结
概念 | 作用 |
---|---|
Cluster | 超大计算机抽象,由节点组成 |
Container | 应用居住和运行在容器中 |
Pod | Kubernetes基本调度单位 |
ReplicaSet | 创建和管理Pod,支持无状态应用 |
Service | 应用Pods的访问点,屏蔽IP寻址和负载均衡 |
Deployment | 管理ReplicaSet,支持滚动等高级发布机制 |
ConfigMap/Secrets | 应用配置,secret敏感数据配置 |
DaemonSet | 保证每个节点有且仅有一个Pod,常见于监控 |
StatefulSet | 类似ReplicaSet,但支持有状态应用 |
Job | 运行一次就结束的任务 |
CronJob | 周期性运行的任务 |
Volume | 可装载磁盘文件存储 |
PersisentVolumne/PersistentVolumeClaims | 超大磁盘存储抽象和分配机制 |
Label/Selector | 资源打标签和定位机制 |
Namespace | 资源逻辑隔离机制 |
Readiness Probe | 就绪探针,流量接入Pod判断依据 |
Liveness Probe | 存活探针,是否kill pod的判断依据 |
理解Kubernetes节点网络和Pod网络
-
节点网络
- K8s最底层的网络,用来保证k8s集群的节点(包括master和worker节点之间、worker节点之间)能够正常做ip寻址和通讯
-
Pod网络
深入理解Service和Service Discovery
-
Service如何寻址
-
用户空间代理模式
-
iptables/ipvs模式
NodePort vs. LoadBalancer vs. Ingress
-
外部流量如何对Service寻址
-
NodePort
-
Load Balancer
-
Ingress
-
总结
本地测试Kubernetes部署文件剖析
- 本地Kubernetes部署架构
- 与docker-compose相比,增加mysql-svc
- DB与k8s在两个不同的网络,通过mysql-svc间接去访问db
- faraday网关需要向外暴露端口
- 在本机,如果要把k8s内部的服务暴露,采用NodePort方式30001:80
- 通过端口转发将faraday网关再暴露80:80
- 与docker-compose相比,增加mysql-svc
- 部署文件剖析 staffjoy-master/k8s/
- test/config/config.yaml
- 私密数据单独放置
- 使用kide: ConfigMap形式,使k8s管理配置
- test/mysql-svc.yaml
- 使用kind: Service创建mysql服务
- ip地址和端口
- test/account-svc.yaml
- 定义kind: Deployment用于发布,底层管理replicaset,管理pod
- 定义kind: Service用于屏蔽pod ip,用于做负载均衡
- …
- test/config/config.yaml
本地测试Kubernetes环境搭建
-
Docker Desktop for Mac/Win
-
校验Kubernetes
-
查看版本
kubectl version
-
查看当前context
kubectl config current-context
-
查看集群信息
kubectl cluster-info
-
查看nodes
kubectl get nodes
-
-
安装和访问Kubernetes Dashboard
-
安装kubernetes dashboard https://github.com/kubernetes/dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc1/aio/deploy/recommended.yaml
或
kubectl create -f kubernetes-dashboard.yaml
通过查看pod检查dashboard是否安装好,需指定namespace为kube-system
kubectl get pods --namespace=kube-system
-
启动kube proxy
kubectl proxy
-
生成访问令牌
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
或
$TOKEN=((kubectl -n kube-system describe secret default | Select-String "token:") -split " +")[1]
-
将staffjoy部署到本地Kubernetes环境
-
构建镜像
mvn clean package -DskipTests
docker-compose build
docker images
-
部署数据库,授予ip访问权限
use mysql; select user, host from user; grant all privileges on *.* to root@192.168.1.38 identified by 'root' with grant option;
-
部署staffjoy(k8s/test),k8s dashboard查看nodes、pods、config maps、services
kubectl apply -f config.yml
kubectl get configmaps
kubectl apply -f test
-
端口转发:因为在本地通过NodePort把faraday网关暴露出来,但NodePort是30001端口,如果要用域名方式访问本地微服务要求端口是80,所以需要将faraday的80端口转发到主机上的80
- 查询faraday的pod名
kubectl get pods
- 端口转发
kubectl port-forward faraday-svc-deployment-6f8f7ff9b7-rgqm4 80:80
-
启用switchhosts
-
命令行校验
kubectl get pods -o wide
kubectl get services
kubectl get deployments
-
k8s dashboard校验
- 查看nodes、pods、config maps、services
-
staffjoy校验
-
清理
kubectl delete deployments --all
kubectl delete services --all
kubectl delete configmaps --all
生产环境Kubernetes部署文件剖析
-
Staffjoy阿里云Kubernetes部署架构
- 阿里云k8s住在aliyun VPC(虚拟私有云)中
- VPC隔离性较好,生产环境一般都住在VPC中
- 数据库使用aliyun RDS(关系型数据库服务)
- 生产环境一般用云提供的数据库
- 使用aliyun ELB(弹性负载均衡)来暴露微服务应用
- 可通过ELB提供的ip访问微服务应用
- 阿里云k8s住在aliyun VPC(虚拟私有云)中
-
阿里云Kubernetes拓扑结构
-
部署文件 staffjoy-master/k8s/uat
- …
阿里云Kubernetes环境创建
-
创建VPC
- https://homenew.console.aliyun.com
- 专有网络VPC -> 选区域 -> 创建专有网络
- 专有网络:名称staffjoy-k8s-vpc,IPv4网段默认,资源组默认
- 交换机:名称staffjoy-k8s-switch001,可用区B,IPv4网段192.168.1.0/24
-
创建RDS
- RDS管理控制台 -> 创建实例 -> 按量付费
- 地域与VPC相同,资源组默认,数据库MySQL,版本5.7,系列基础版,存储类型SSD云盘,可用区与VPC可用区相同,网络类型专有网络,规格2核4G,存储空间150G,立即购买,支付(0.65元/时)
- 管理控制台 -> 点击实例名称进行设置
- 设置白名单,添加白名单分组
- 选专有网络,分组名称staffjoy_rds,组内白名单192.168.1.0/24,确定
- 复制内网地址
- 更新JDBC连接字符串
- 更新config.yaml文件中的连接字符串中的连接、账户、密码
- 创建root账户
- 账号管理,创建帐号
- 数据库帐号root,密码Root1234
- 创建数据库和表
- 登录数据库,root,Root1234;设置所有实例
- 数据库管理;创建数据库:数据库名staffjoy_account,确定;创建数据库:数据库名staffjoy_company,确定
- SQL操作,SQL窗口,执行建表语句
- RDS管理控制台 -> 创建实例 -> 按量付费
-
创建共享版Kubernetes集群
- 容器服务Kubernetes版,创建Kubernetes集群,标准托管集群
- 集群名称staffjoy-k8s-cluster,地域一致,专有网络如前VPC,虚拟交换机选中,Worker实例新增实例,节点类型按量付费,实例规格4核8G,数量3台,系统盘SSD云盘120GB,Kubernetes版本1.12.6-aliyun.1,操作系统Linux,网络插件Flannel,Pod网络CIDR 172.20.0.0/16,Service CIDR 172.21.0.0/20,配置SNAT 为专有网络配置SNAT,公网访问 使用EIP暴露API Server,Ingress不需要选中,RDS白名单添加
- 更新 .kube/config(配置context,使用本地kubectl指向阿里云kubernetes)
- 点击集群名称,KubeConfig(公网访问),复制到$HOME/.kube/config
- 复制 -cluster,添加到目标文件
- 复制 -context到current-context,替换目标文件响应内容
- 复制 -name,添加到目标文件
- 容器服务Kubernetes版,创建Kubernetes集群,标准托管集群
-
校验
- kubectl config current-context
- kubectl cluster-info
- kubectl get nodes
将staffjoy部署到阿里云Kubernetes环境
-
部署staffjoy(k8s/UAT)
- 部署config.yaml和logback-config.yaml
kubectl apply -f config
- 部署service和deployment
kubectl apply -f uat
-
阿里云dashboard校验
- 容器服务Kubernetes版,集群的控制台
- 注意:微服务的镜像要docker-compose push到docker hub
- 查看pod、logs
- 查看config maps:common-config,logback-config
-
命令行校验
kubectl get pods -o wide
kubectl get services
kubectl get deployments
-
更新并启用SwitchHosts
- 获取faraday公网ip
- 更新ELB IP地址
-
staffjoy校验
-
删除阿里云kubernetes和RDS
Kubernetes应用动态配置实验
-
k8s dashboard校验
- 进入account-svc的pod命令控制台
- /etc/staffjoy下有logback-spring.xml(这是发布uat环境时,把logback以configMap的形式mount到了pod里面)
- 校验logback-spring.xml文件内容
- scanPeriod为配置刷新时间间隔
- level为日志级别
-
更新logback配置(k8s/UAT/config)
- 更新logback-config.yaml中的level为debug
- kubectl apply -f logback-config.yaml
-
k8s dashboard校验
- account-svc的pod命令控制台,校验logback-spring.xml文件更新
- 等待30秒
- account-svc的pod日志控制台输出debug日志
Kubernetes应用金丝雀发布实验
-
金丝雀发布
- 假设线上有一个v1版本,现在有一个v2版本需要更新;金丝雀发布就是先发布一个v2版本,让其接受一小部分的流量,大部分流量仍然是在老版本上;如果v2版本运行ok,就把其他的v2版本依次发布;如果v2版本有问题,则退回老版本
- 也称灰度发布,是指在黑白之间能够平滑过渡的一种发布方式;可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度
-
金丝雀发布步骤
- 将www服务www-web-deployment扩容到3个实例
- k8s/uat/www-web.yaml中replica改为3
- kubectl get pods查看pod情况
- kubectl apply -f www-web.yaml
- kubectl get deployments查看实例个数
- 发布金丝雀 www-web-deployment-canary
- k8s/uat/canary/www-web-canary.yaml中image改为boboweike/www-svc:blue
- kubectl apply -f canary
- 校验
- 扩容金丝雀到3个实例
- k8s/uat/canary/www-web-canary.yaml中replicas改为3
- kubectl apply -f canary
- kubectl get deployments查看实例个数
- 删除www-web-deployment
- kubectl get deployments查看实例个数
- k8s/uat/canary/www-web.yaml中replicas改为0
- kubectl apply -f www-web.yaml
- kubectl get deployments查看实例个数
- 将www服务www-web-deployment扩容到3个实例
阿里云资源释放
-
释放aliyun RDS
- 云数据库RDS版本,更多,释放实例,短信验证码,确定
-
释放k8s
- 容器服务Kubernetes版,更多,删除,已知晓,确定
- 日志服务,project列表,删除
-
专有网络VPC
- 不产生费用,可不删
- 如果要删除,先删交换机,再删VPC
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
