云原生
Table of Contents
1. 定义
2015 ~ 2018 年,CNCF 对于云原生的定义主要包含三个方面:
- 面向微服务架构
- 应用容器化部署
- 基于容器的编排和调度(Kubernetes)
2018 年后,CNCF 对于云原生的定义改为:
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。
来自 https://github.com/cncf/toc/blob/master/DEFINITION.md
云原生代表技术:不可变的基础设施、声明式 API。容器、服务网格、微服务。
什么是不可变的基础设施?
https://segmentfault.com/a/1190000040449782
- 在程序设计中,不可变变量(Immutable Variable)就是在完成赋值之后就不能发生更改,只能创建新的来整体替换旧的。
- 对于基础设施的不可变性,最基本的就是指运行的服务器在完成部署后,就不再更改。
2. 常见的术语
- CNCF The Cloud Native Computing Foundation,云原生计算基金会。
- OCI Open Container Initiative,开放容器标准。
是一个轻量级的,开放的治理结构(项目),在 Linux 基金会的支持下成立,旨在围绕容器格式和运行时创建的开放行业标准。
OCI 于 2015 年 6 月由 Docker,CoreOS 和其他容器行业领导者成立。当前包含两种规范:
- runtime-spec 运行时规范
- image-spec 镜像规范
- CRI Container Runtime Interface,由 protocol buffers 和 gRPC API 和一些库组成。
是 Kubernetes 提出的给 kubelet 来管理节点的容器来用的。符合 CRI 的容器,Kubernetes 就可以直接使用。
目前 CRI 的实现有 Containerd,CRI-O,Docker 不符合 CRI,所以 Kubernetes 写了 dockershim 来做协议转换
(这也是 Kubernetes v1.20 之后废弃 Docker 的原因,
kubelet->dockershim->dockerd->containerd
这个链路太长, 废弃之后改成了kubelet->containerd
)。
3. 服务可用性定义
谷歌 SRE 对服务的可用性进行了如下三个维度的定义。1
3.1. SLA(Service-Level Agreement):服务级别协议
是服务提供商与客户之间定义的正式承诺,SLO 是 SLA 的基础。
注意:是官方的承诺,是协议、合同。出了问题是要承担责任的。
我们经常说的 N 个 9,对应的宕机容忍(计算器2):
x | 一年 | 一月 | 一周 | 一日 | 适用产品 |
---|---|---|---|---|---|
99.9% | 8h45m | 43m | 10m5s | 1m26s | 个人电脑或者服务器 |
99.99% | 52m34s | 4m19s | 1m | 9s | 企业级设备 |
99.995% | 26m17s | 2m10s | 30s | 4s | 数据库 |
99.999% | 5m15s | 26s | 6s | 不足 1s | 电信级设备 |
阿里云、AWS 等主机的 SLA 是每月 99.95%,即超过 5 分钟主机不可用(可获得赔偿)。
3.2. SLO(Service-Level Objective):服务级别目标
指服务提供者向客户作出的服务保证的量化指标。
注意:是可量化的目标,目标可以包含很多的 SLA。
3.3. SLI (Service-Level Indicator):服务级别指标
是对服务提供商提供给客户的服务级别的度量。是 SLO 的基础,通用性的度量指标,比如:延迟、吞吐量、可用性、错误率。
延迟、吞吐量、可用性、错误率也是目前最常用来度量服务的四个维度(很多监控都是这四个维度的范畴和延伸)。
4. Docker
4.1. 基础知识
4.2. Docker CLI 替代品:Container Tools(podman、buildah、skopeo)
Docker CLI 真的越来越臃肿了(啥都不干,内存好几 G 没了),集合了 compose、swarm、Kubernetes。而且很明显现在整个云原生生态 有种不带 Docker 玩的感觉(这也不能全怪 CNCF,毕竟曾经人家抛了橄榄枝,他非要自己玩),再加上国内网络原因,Docker 的每次升 级慢的令人发指。
容器官方提供了 Container Tools,工具集合,其中包含了覆盖 Docker 不同场景的工具。Docker CLI 被拆分成了 3 个工具:
官网 | github | 说明 | 笔记 |
---|---|---|---|
podman | https://github.com/containers/podman | OCI 容器和 Pod 管理工具 | podman |
buildah | https://github.com/containers/buildah | 构建 OCI 镜像工具 | |
skopeo | https://github.com/containers/skopeo | 镜像仓库工具 |
整个理念来说,打的是无守护进程,无需 root 的招牌,但实际上,这些东西我并不关心。拆分成 3 个工具,会加大学习成本,所以我只 关注 podman 一个替代日常的 Docker CLI 操作。
Mac 不是纯正的 Linux 系统,所以不管是 Docker 还是 podman 都需要引入一个中间层的 Linux 虚拟机。这块 Docker 做的还是不错的, 但是 podman 不行(配置要进入虚拟机,而且主机目录挂载也是个问题)。
结论是:听起来很好,Mac 下实际可行性较差。
5. TODO 容器
7. Kubernetes
Kubernetes 是开源的微服务或者容器化应用的编排工具,是谷歌开发的集群管理工具(前身是谷歌内部运行十几年的集群管理工具 Borg3, Kubernetes 吸取 Borg 的经验,然后针对社区定制的开源版本4),现已捐赠给 CNCF5。
Kubernetes 提供了服务发现和负载均衡、自动部署和回滚、弹性伸缩、健康检测和服务自愈等特性。它的主要目标是通过提供一组 REST APIS 来隐藏管理容器的复杂性6。
7.1. 概念(Concepts)
以下文档大都来自 Kubernetes 官方文档 Concepts,加上自己的理解。
- 概览
- 什么是 Kubernetes?: Kubernetes 是一个用于管理容器化的工作负载和服务的可移植的、可扩展的、开源平台,便于声明式配置和自动化。 它拥有庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。
- Kubernetes 组件: Kubernetes 集群由代表控制平面(control pane)的组件和一组称之为节点的机器组成。
- Kubernetes API: Kubernetes API 允许你查询和操作 Kubernetes 集群中的对象状态。Kubernetes 控制平面的核心是它的 API server 和它暴露的 HTTP API。用户和集群的不同组件以及外部组件都是通过 API server 进行通信。
- 与 Kubernetes 对象一起工作: Kubernetes 对象是 Kubernetes 系统中的持久化实体。Kubernetes 使用这些实体来表示集群的状态。
- 集群架构: kubernetes 架构与组件概览
- 容器
- 镜像
- 容器环境
- 运行时类 RuntimeClass
- 容器生命周期 Hooks
- 工作负载(workloads)
- Pods
[3/6]
[X]
Pod: 概念、为什么需要 Pod、状态标识、健康检查、生命周期等[X]
Pod Lifecyle[X]
Init Containers[ ]
Pod 拓扑扩展约束[ ]
中断[ ]
临时容器
- 工作负载资源
- Deployments: 用于无状态服务部署,在 ReplicaSet 基础上提供了更新策略等
- ReplicaSet: 保证一组 Pod 副本在集群的正常运行
- StatefulSets: 用于部署无状态应用(ZooKeeper,Kafka,Redis 等)
- DaemonSet: 每个节点上跑一个 Pod,用作类似日志收集、系统监控等功能
- Jobs 一次性的任务
- TTL Controller for Finished Resources: 在对象执行完成后 TTL 秒,回收资源(目前仅用于 Job)
- CronJobs 定时任务
ReplicationController: ReplicaSet 是下一代的 RC(支持新的基于集合的标签选择器),建议使用 RS- Garbage Collection: 负责集群资源回收
- Pods
- Services、负载均衡和集群网络
[3/11]
[X]
Service 集群内部的服务暴露抽象,提供虚拟 IP,然后通过负载均衡策略,将流量转发到 Endpoints。 底层实现是 kube-proxy,它支持三种模式(用户空间,iptables,IPVS),主流都是使用 IPVS[ ]
服务拓扑 实现基于 Service 的亲和性[X]
Services 和 Pod 的 DNS[ ]
使用 Services 连接应用[X]
Ingress[ ]
Ingress Controllers[ ]
EndpointSlices[ ]
Service 内部流量策略[ ]
拓扑感知提示[ ]
网络策略[ ]
IPv4/IPv6 双栈
- 存储: Volumes, Persistent Volumes, Storage Class 等
[1/11]
[ ]
Volumes[ ]
持久化卷[ ]
卷快照[ ]
CSI 卷克隆[ ]
Storage Classes[ ]
Volume Snapshot Classes[ ]
Dynamic Volume Provisioning[ ]
Storage Capacity[X]
临时卷[ ]
Node-specific Volume Limits[ ]
Volume Health Monitoring
- 配置
[0/5]
[ ]
配置最佳实践[ ]
ConfigMaps[ ]
Secrets[ ]
为容器管理资源[ ]
Organizing Cluster Access Using kubeconfig Files
- 安全
[0/3]
[ ]
云原生安全概览[ ]
Pod 安全标准[ ]
控制 Kubernetes API 访问
- 策略(Policies)
[0/5]
[ ]
Limit Ranges[ ]
Resource Quotas[ ]
Pod 安全策略[ ]
进程 ID 限制和保留[ ]
节点资源管理器
- 调度,抢占(Preemption)和驱逐(Eviction)
[0/10]
[ ]
Kubernetes 调度器[ ]
把 Pods 分配给节点[ ]
Pod 开销[ ]
污点和容忍[ ]
Pod 优先级和抢占(Pod Priority and Preeemption)[ ]
节点压力驱逐[ ]
API 发起的驱逐[ ]
Resource Bin Packing for Extended Resources[ ]
调度框架[ ]
调度器性能调优
[ ]
集群管理[0/9]
[ ]
证书[ ]
管理资源[ ]
集群网络[ ]
日志架构[ ]
Kubernetes 系统组件指标[ ]
系统日志[ ]
Kubernetes 中的代理[ ]
API Priority and Fairness[ ]
安装插件
[ ]
扩展 Kubernetes[0/4]
[ ]
扩展 Kubernetes API[ ]
计算,存储和网络扩展[ ]
Operator 模式[ ]
Service Catalog
7.2. API 对接
7.3. 集群规模
https://kubernetes.io/docs/setup/best-practices/cluster-large/
大规模集群注意事项,Kubernetes 旨在适应满足一下标准的配置环境:
- 单节点不超过 110 个 Pods
- 单集群不超过 5000 个节点
- 单集群总 Pods 数量不超过 15000 个
- 单集群总容器不超过 30000 个
7.4. 搭建本地 Kubernetes
一般用于 K8s 学习和应用程序开发人员。
- minikube
- kind:全称:”Kubernetes In Docker“,集群节点运行于 Docker 中,很快
- K3S:轻量级的 K8s,旨在资源匮乏的位于边缘的物联网和边缘设备上运行 K8s,可以在 VMWare 和 VirtualBox 等虚拟机环境下运行 简单、安全、优化的 K8s 环境
- MicroK8s 如其名,微小的 K8s
minikube 和 kind 的定位是完全相同的:避免 K8s 安装复杂,用于开发人员本地学习,K3s 和 MicroK8s 也可以实现相同的效果,不过 他们的定位是提供生产级别的 IoT 和边缘场景下的 K8s 需求。
7.5. 构建部署
- Helm Kubernetes 包管理器,用于项目的(含多个微服务,以及每个服务的依赖配置)打包、部署、回滚等生命周期管理
- operator CRD + Controller = Operator,可以认为 Operator 是自定义资源的控制器。Operator 用来对 K8s API 进行扩展,用来创建 配置和管理复杂的应用(数据库、消息中间件、缓存等)。
Helm 一般用于无状态应用的部署,类似中间件的服务也有开源的 charts,但是一般中间件的场景都需要更细粒度的控制,大厂都是用 Operator 来做的。
当然 Helm 要比 Operator 要简单多了,毕竟只是一个工具。好在官方提供了 kubebuilder 和 code generator 等工具可自动生成代码。
目前社区已经开源了很多 helm charts 和 operators:
7.7. 最佳实践
7.8. 监控告警
- 监控: 通过 kube-state-metrics 和 cAdvisor 暴露指标
7.9. 管理平台
Kubernetes 管理平台一般是对 K8s 能力平台化,降低运维管理成本(标准化化、自动化,DevOps),覆盖应用研发迭代生命周期(CI、CD、告警、日志等)。
- OKD OpenShift 的社区版本,红帽 OpenShift 应该是业内做的比较早的的企业级混合云(PaaS),算是行业标杆吧
- rancher 2016 Rancher Labs 发布 1.0 rancher,2020年12月1日,公司被 suse 收购
- KubeSphere 全栈的 Kubernetes 容器云 PaaS 解决方案,如他的描述。KubeSphere 适合作为小企业的私有云,常用的功能比较完备,开箱即用
- portainer 轻量级的 Docker、Docker swarm、Kubernetes 集群管理工具(可以算成一个界面化管理工具)
如果没有一定的容器化、DevOps 人员储备不太敢用 K8s,即便开箱急用的管理平台在生产环境使用大家也不太敢用。那换过来,有人员储 备之后,用原生的开源的各组件方案自研一套难度也不大(而且可以根据业务所需选择合适的技术体系,灵活性高,也易于接受)。所以, 很多企业是不太会用类似的管理平台的(或者有一种场景,有强力的 K8s 运维能力,但是无平台研发能力可以选择)。另外,如果企业直 接使用云服务,云厂商也都提供了简易的 UI 界面来操作 K8s。
8. 日志体系
8.1. 数据收集 agent
- fluentd:开源的数据收集器,2011 年至今,2016.11.8 被 CNCF 所录取,2019 年成为毕业项目。
- 数据统一结构化为 JSON
- 可插拔,支持多种上游数据源(data sources)和下游输出(data output)
- 低资源消耗:使用 C,Ruby 混合编码
- 数据可靠:支持内存和文件缓冲,防止数据丢失,还只是故障转移(高可用);2000+ 数据驱动公司背书
9. Service Mash
Istio
2017年5月,Google、IBM 和 Lyft 宣布 Istio 开源。
- 都 2021 年了,对于服务网格,社区到底在讨论什么? 2021年11月24日,“Istio 架构已经稳定,生产可用,生态正处于萌芽中”
10. Serverless
- Knative “2018.07 首次发布 Knative,2021.11 发布 1.0 版本”
11. Resources
- Docker 生态系统一览 翻译的文章,较为详细的说明了 Docker 的前世今生
- 一文搞懂容器运行时 Containerd 搞清楚 libcontainer, runc, containerd, CRI, OCI 之间的关系
- Kubernetes vs Docker 2021 翻译的文章,容器、Docker、Kubernetes 之间的关系, Kubernetes v1.20 开始废弃了 Dockershim 之后,对于研发人员、管理员以及 CI/CD 流程上会有哪些影响?
- 12-Factor 构建 SaaS 应用方法论
- kubernetes README Kubernetes 书籍、教程和其它资源列表
- How Container Runtimes matter in Kubernetes? PPT,Kubernetes 中的运行时
- Unified Kubernetes CRI runtimes based on Kata Containers PPT,理解 Kubernetes 中的运行时
- Kubernetes Overview Diagrams Kubernetes 概述图(很帅),涵盖架构,工作负载,网络存储,RBAC,资源 requests 和 limits 等
- GCE Kubernetes 最佳实践系列
- DNS Lookups in Kubernetes 主要介绍 ndots 的作用,也是 nslookup 的关键
- Pause 容器,也称之为 Infra 容器,Pause 即暂停,但并不是停止状态,而是启动之后就会把自己阻塞住,什么都不干
- 目标是为了解决多个容器之间最高效的共享某些资源和数据(打破 Linux Namespace/cgroups 隔离), Pause 是为了解决网络问题(如何共享网络);
- Pod 中的其他容器 Join namespace 的方式加入到 Pause 容器的 Network namespace。所以其他容器所看到的网络设备、IP 地址、 Mac 地址等网络信息都是 Pause 容器的;
- Pause 容器为业务容器提供:
- Linux namespace 的基础;
- 启用 pid 命名空间,开启 init 进程。
- minReadySeconds 与 Readiness Probe 更好的理解 Pod 启动
- Kubernetes 疑难杂症排查分享: 诡异的 No route to host Deployment 滚动更新的时候偶尔会报“No Route to host”
- cni 和 kube-proxy 的区别
- CNI:保证每个 Pod 都有一个独立的 IP,而且他们之间可以相互通信,确保 Pod 可以向集群外部通讯
- kube-proxy:是 service 的实现,拥有一个虚拟的 IP,在下游的 endpoints 之间做负载均衡
- 云原生资料库
- kubernetes-under-the-hood 侧重运维部署层面,涉及整体技术架构、网络、DNS 等;如果仅是关注 Kubernetes 本身,不推荐看
- OSSInsight Github 项目洞察,某种程度可以看到开源趋势,但是社区毕竟是社区,只可以参考
- 最佳实践系列 别人家的最佳实践合集
11.1. 书籍
[ ]
Kubernetes: Up and Running[ ]
Kubernetes in Action[ ]
Kubernetes Patterns[ ]
Kubernetes Best Practices[ ]
Cloud Native Patterns[ ]
Kubernetes Patterns[ ]
The Kubernetes Book 这本书每年都会更新一次,以跟上最新的 Kubernetes 生态