K8s 内部培训
介绍
K8s 为 Kubernetes 的简称, 是一个开源的容器编排平台, 最初是由 Google 工程师开发和设计的, 后于 2015 年捐赠给了云原生计算机基金会-CNCF
应用服务管理发展史
早期服务应用大多以单包的形式运行在服务器上, 当我们增加一些服务时, 比如添加 JOB
应用时, 我们会另开一个新的应用, 但基本用一台服务器上就能完成
所以我们早期应用的发展就如下面图表所示, 由于用户数量较少, 所以更新应用时短暂的暂停服务也是可以接受的
随着用户数量的上升, 应用的并发也随之提高, 单台服务器的压力也随之增大, 有了如下情况:
- 高峰期经常出现卡顿
- 更新应用时的暂停服务已经不可接受
- 在服务器出现故障时的高可用有了更高的要求
为了解决上面的问题, 我们就进入了下个时代(下图一), 采购多台服务器, 对应用进行支持集群的改造, 这时我们的应用分别在三台服务器上, 并发能力提高了3倍, 并且冗灾能力大幅提升
尽管我们解决了上面的问题, 但是带来了新的问题, 因为服务器数量过多, 在安装应用需要的工具如 JDK、Tomcat、Node、Nginx、Redis 等等, 可能会因为安装版本和服务器系统版本不一致导致应用运行失败
所以会在环境安装中浪费太多时间, 所以很多企业开始引入如 Docker
的虚拟化技术(下图二), 用来解决环境不一致的问题, 并且一并解决了守护进程, 开机启动等问题
这时我们通过 docker-compose
技术, 升级应用、调整配置相比以前大大简化, 但是随着应用规模的扩大, 对应用高可用有了更高的要求, 纷纷开始进行微服务拆分, 应用数量和服务器数量越来越多, 服务的运维管理越来越复杂、
大家开始开发各种集群管理, 让大家可以在一个地方并且可视化的管理集群中的所有 Docker
, 以 Google 开源的 Kubernetes 做的最功能完善且灵活可配置, 从而开始爆火.
于是众多企业开始上K8s(下图三), 不仅解决运维复杂的问题, 而且带来了更多更好的特性:
- 服务发现和负载均衡
- 存储编排
- 自动部署和回滚
- 自我修复
- 密钥和配置管理
Kubernetes 组件
Control Plane Components
: 控制平面组件kube-apiserver
: 负责公开 Kubernetes API, 处理请求, 类似 cloud 中的网关etcd
: key-value 存储, 用于保存集群数据kube-scheduler
: 任务调度, 监听有新创建但未运行的pods, 选择节点来让 pod 在上面运行kube-controller-manager
: 负责运行控制器进程, 有如下不同类型的控制器Node Controller
: 节点控制器, 负责节点出现故障时进行通知和响应Job Controller
: 任务控制器, 检测代表一次性任务的 Job 对象, 然后创建 Pod 来运行这些任务直至完成EndpointSlice Controller
: 端点分片控制器, 提供 Service 和 Pod 之间的链接ServiceAccount Controller
: 为新的命名空间创建默认的服务账号
cloud-controller-manager
: 云控制管理器, 集成云提供商的API, 我们内网部署的用不到
Node Components
: 节点组件, 运行在各个节点, 负责维护运行的 Pod, 提供 Kubernetes 的运行环境kubelet
: 在每个节点中运行, 保证容器都运行在 Pod 中, kubelet 接受一组 PodSpec, 确保 PodSpec 中描述的容器处于运行状态且健康kube-proxy
: 网络代理, 是实现 Service 的一部分Container Runtime
: 容器运行时, Kubernetes 支持需要容器运行环境, 例如: docker, containerd, CRI-O
Addons
: 插件, 提供集群级别的功能, 插件提供的资源属于 kube-system 命名空间DNS
: 提供集群内的域名系统Web UI/Dashboard
: 通用的基于 Web 的用户界面, 它使用户可以集中管理集群中的应用已经集群本身Container Resource Monitoring
: 将容器的一些常见的时间序列度量值保存到一个集中的数据库中, 并提供浏览这些数据的界面Cluster-level Logging
: 集群级日志, 将容器日志保存到一个集中的日志存储中, 这种集中日志存储提供搜索和浏览接口Network Plugins
: 网络插件, 实现容器网络接口(CNI)规范的软件组件, 负责为 Pod 分配 IP 地址, 并使这些 Pod 能在集群内部互相通信
Kubernetes 架构
Node 节点
Kubernetes 通过将容器放入在节点(Node) 上运行的 Pod 来执行你的负载. 节点可以是一个虚拟机或物理机, 每个节点包含 Pod 所需的服务器, 这些节点由 Control Plane
负责管理
一个集群的节点数量可以是1个, 也可以是多个. 且节点名称是唯一的.
可以通过 kubectl
来创建和修改 Node 对象
# 查一下集群中的所有节点信息
kubectl get node
# 查看某个节点详细信息
kubectl descibe $NODENAME
# 标记一个 Node 为不可调度
kubectl cordon $NODENAME
Controllers 控制器
在机器人和自动化领域, 又一个类似的概念叫控制回路 (Control Loop), 用于调节系统状态, 如: 房间里的温度自动调节器
当你设置了温度, 温度自动调节器让其当前状态接近期望温度; 在 Kubernetes 中, 控制器通过监控集群的公共状态, 并致力于将当前的状态转为期望状态
控制器是通过通知 apiserver
来管理状态的, 就像温度自动调节器是通过控制空调来调节气温的
Container Runtime Interface/CRI 容器运行时接口
CRI 是一个插件接口, 它使 kubelet 能够使用各种容器运行时, 定义了主要 gRPC 协议, 用于节点组件 kubelet 和容器运行时之间的通信
Containers 容器
容器将应用从底层主机设备中解耦, 这使得在不同的云或 OS 环境中部署更加容易
Kubernetes 集群中的每个节点都会运行容器, 这些容器构成分配给该节点的 Pod, 单个 Pod 中的容器会在共同调度下, 运行在相同的节点
容器镜像是一个随时可以运行的软件包, 它包含了运行容器程序所需要的一切, 代码和它需要的运行时、应用程序和系统库, 以及一些基本设置
容器运行时这个基础组件使 Kubernetes 能够有效运行容器, 他负责管理 Kubernetes 环境中的容器的执行和生命周期
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署计算单元
Pod 是有一个或多个容器组成, 这些容器共享存储、网络、已经怎么样运行这些容器的声明, 统一调度.
此外还可以包含 init container, 用于做一些启动主应用前的准备工作, 比如通过 init container 注入 tingyun 等 agent 包
如下示例, 它由一个运行镜像 nginx:1.14.2
的容器组成
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
要创建上面显示的 Pod, 保存上面内容到 my-nginx.yaml
, 可以通过如下命令
kubectl apply -f my-nginx.yaml
Workloads 工作负载
工作负载是在 Kubernetes 上运行的应用程序, 无论是又一个还是多个组件构成, 你都可以通过一组 Pod 来运行它, Pod 代表的是集群上处于运行状态的一组容器的集合, 但通常一个 Pod 内只运行一个容器
Kubernetes 提供若干种内置的工作负载资源:
Deployment
和ReplicaSet
Deployment 适合无状态应用, Deployment 中的所有 Pod 都是互相等价的StatefulSet
有状态应用, 比如可以独立持久化文件, 互不影响DaemonSet
提供节点本地支撑设施的 Pod, 保证每个节点上一个Job
和CronJob
定义只需要执行一次并且执行后视为完完成的任务
Network 网络
Service
Service
是将一个或者一组 Pod 公开代理给集群内部, 使之能够各个应用之间通信, 甚至用于公开到集群外(NodePort 或者 代理给 Ingress)
它提供了类似域名的访问方式, 使用者无需关心后面有多少个 Pod 在提供服务, 他们是否健康, 他们 IP 是否发生变化.
定义 Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: my-nginx
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort: http-web-svc
服务类型(type):
ClusterIp
: 默认值, 智能在集群内访问NodePort
: 直接向集群外暴露, 通过节点端口访问LoadBalancer
: 使用云平台的负载均衡, Kubernetes 不直接提供Externalname
: 将服务映射到 externalName 字段的内容, 例如api.foo.bar.example
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]