Kubernetes - DevOps
基本概念流程概览
实现自动化,最核心的投入为编写测试用例
分支管理
提交 PR 时会触发 CI Pipeline;生产系统版本不能直接使用 master 分支(最新代码),而是要基于 Release 分支
CICD
CI
CD
GitOps
一切皆代码,通过 Git 来触发 Ops
Jenkins
Jenkins 不是云原生
Container CI
需要保证 CI 构建环境和开发环境的统一
使用容器作为标准的构建环境,将代码库作为 Volume 挂载进容器
需要在构建容器中执行 docker build 命令,即 Docker in Docker = DIND
Kubernetes CI
Jenkins 可以被容器化(on Kubernetes),并支持 Cloud Provider,通过插件的方式支持 Kubernetes
https://github.com/jenkinsci/kubernetes-pluginJenkins plugin to run dynamic agents in a Kubernetes/Docker environment
...
Kubernetes - Production Ops
镜像仓库
镜像仓库(Registry)负责存储、管理和分发镜像
Registry 管理多个 Repository(通过命名区分)
每个 Repository 包含一个或多个镜像(通过镜像名和标签区分)
客户端拉取镜像:Registry/Repository/Image:Tag
分发规范
镜像仓库应遵循 OCI Distribution Spec
HTTP Verb
URL
Desc
GET
/v2/
检查 Registry 实现的规范和版本
GET
/v2/_catalog
获取 Repository 列表
GET
/v2//tags/list
获取某个 Repository 下所有的标签
PUT
/v2//manifests/
上传 Image 的 manifest 信息
DELETE
/v2//manifests/
删除 Image
GET
/v2//manifests ...
Kubernetes - Manage Production Clusters
操作系统
通用操作系统 - 成熟
Ubuntu
CentOS
Fedora
专为容器优化的操作系统 - 最小化主机操作系统
CoreOS
最早的容器化操作系统,已被收购
RedHat Atomic
将 RPM Repository 转换成 ostree,可以被 bootloader 直接加载
Snappy Ubuntu Core
Canonical 出品,最初为移动设备设计
RancherOS
相对较新,RancherOS 中运行的所有服务都是 Docker 容器
评估选型的标准
是否有生态系统
成熟度
内核版本
对运行时的支持
Init System
包管理和系统升级
安全
不可变基础设施
不可变的容器镜像
不可变的主机操作系统
Atomic - 打包成一个经过裁剪后的操作系统
由 Red Hat 支持的软件包安装系统
多种发行版:Fedora / CentOS / RHEL
优势
不可变操作系统,面向容器优化的基础设施
只有 /etc 和 /var 可以修改,其它目录均为只读
基于 rpm-ostree 管理系统包
IaC:输 ...
Kubernetes - Service Discovery
基本概念发展历程
数据包
负载均衡的核心原理 - 修改包头数据
通过浏览器访问某网站的过程(组包在应用层,传包在内核层)
在浏览器输入网站的网址
浏览器本质上是一个 HTTP 客户端,组装成 HTTP 包
做 DNS 解析(递归)
封装 TCP 包(源端口 + 目标端口)
封装 IP 包(源 IP + 目标 IP - 来自于 DNS)
负载均衡
面向连接的负载均衡不一定能保证平均,如 grpc 是基于 http/2,会复用 TCP 连接,L4 的负载均衡就无法实现平均
方案集中式
F5(HLB) / Nginx(SLB) - 接入集群外部流量
在服务消费者和服务提供者之间有一个独立的 LB
LB 上有所有服务的地址映射表,通常由运维配置注册
当服务消费者调用某个目标服务时,向 LB 发起请求,由 LB 以某种策略做负载均衡后将请求转发到目标服务
LB 一般具备健康检查的能力,能自动摘除不健康的服务实例
服务消费者通过 DNS 发现 LB,运维人员配置一个指向该 LB 的 DNS 域名
优缺点
优点
方案简单,在 LB 上容易实现集中式的访问控制,为业界主流
...
Go - Design Philosophy
简单
语言特性始终保持少且足够的水平,不走语言融合的道路,简单的设计哲学是 Go 生产力的源泉
仅有 25 个关键字,主流编程语言最少
内置 GC,降低开发人员内存管理的心智负担
首字母大小写决定可见性,无需通过额外关键字修饰
变量初始为类型零值,避免以随机值作为初值的问题
内置数组边界检查,极大减少越界访问带来的安全隐患
内置并发支持,简化并发程序设计
内置接口类型,为组合的设计哲学奠定基础
原生提供完善的工具链,开箱即用
显式
Go - 程序员应该明确知道在做什么;C - 信任程序员
Go 不允许不同类型的变量进行混合计算,也不会进行隐式自动转换
Go 采用基于值比较的错误处理方案
函数或方法的错误会通过 return 语句显式地返回,并且调用者通常不能忽略对返回的错误的处理
组合
组合是构建 Go 程序骨架的主要方式,可以大幅度降低程序元素间的耦合,提高程序的可扩展性和灵活性
在 Go 中,找不到经典的 OOP 语法元素、类型体系和继承机制,Go 推崇的是组合的设计哲学
提供正交的语法元素,以供后续组合使用
包之间相对独立,没有子包的概念
没有类型层次体系,各类型之间互相独立,没 ...
Kubernetes - Pod Life Cycle
生命周期
Pending - 调度尚未成功,ContainerCreating - 完成调度
Pod 状态机
Pod Phase
Pod Phase: Pending / Running / Succeeded / Failed / Unknown
k get pod 显示的 STATUS 是由 pod.status.phase 和 pod.status.conditions 计算得出
123$ k get po nginxNAME READY STATUS RESTARTS AGEnginx 1/1 Running 0 35s
k get po nginx -oyaml
12345678910111213141516171819202122232425262728293031status: conditions: - lastProbeTime: null lastTransitionTime: "2022-08-28T07:00:45Z" status: & ...
Kubernetes - CSI
运行时存储
运行时存储:镜像只读层 + 容器读写层(写性能不高)
容器启动后,运行时所需文件系统的性能直接影响容器性能
早期 Docker 使用 DeviceMapper 作为容器运行时的存储驱动,因为 OverlayFS 尚未合并进 Linux Kernel
目前 Docker 和 containerd 都默认以 OverlayFS 作为运行时存储驱动
OverlayFS 的性能很好,与操作主机文件的性能几乎一致,比 DeviceMapper 优 20%
CSI分类
以插件的形式来实现对不同存储的支持和扩展
Plugin
Desc
in-tree
代码耦合在 Kubernetes 中,社区不再接受新的 in-tree 存储插件
out-of-tree - FlexVolume - Native Call
Kubernetes 通过调用 Node 的本地可执行文件与存储插件进行交互FlexVolume 插件需要 Node 用 root 权限安装插件驱动执行模式跟 CNI 非常类似
out-of-tree - CSI - RPC
CSI 通过 RPC 与存储驱动进行交互
插 ...
Kubernetes - CNI
网络分类
Type
Desc
CNI
Pod 到 Pod 的网络,Node 到 Pod 的网络
kube-proxy
通过 Service 访问
Ingress
入站流量
基础原则
所有 Pod 能够不通过 NAT 就能互相访问
所有 Node 能够不通过 NAT 就能互相访问
容器内看到的 IP 地址和外部组件看到的容器 IP 是一样的
补充说明
在 Kubernetes 集群,IP 地址是以 Pod 为单位进行分配的,每个 Pod 拥有一个独立的 IP 地址
一个 Pod 内部的所有容器共享一个网络栈,即宿主上的一个 Network Namespace
Pod 内的所有容器能够通过 localhost:port 来连接对方
在 Kubernetes 中,提供一个轻量的通用容器网络接口 CNI
Container Network Interface,用来设置和删除容器的网络连通性
Container Runtime 通过 CNI 调用网络插件来完成容器的网络设置
插件分类
下面的 Plugin 均由 ContainerNetworking 组维护
IPAM -&g ...
Kubernetes - CRI
概述
Container Runtime 位于 Node 上,负责容器的整个生命周期,其中 Docker 应用最为广泛
CRI 是 Kubernetes 定义的一组 gRPC 服务
Dockershim 支持 CRI,代码耦合在 kubelet 中
而 Docker 本身是不支持 CRI 的,但 Docker 内部的 containerd 是支持 CRI 的
Kubelet 作为客户端,基于 gRPC 框架,通过 Socket 和 Container Runtime 通信
Container Runtime 提供 gRPC 服务
Image Service - 下载、检查和删除镜像
Runtime Service - 容器生命周期管理 + 与容器交互
区分了 SandBox + Container
Push Image 并不在 CRI 中 – 开发环境用 Docker,生产环境用 containerd
运行时分层
Runtime
Impl
CRI - High-level - gRPC
Dockershim / containerd / CRI-O
...
Kubernetes - Kubelet
架构
每个 Node 上运行一个 Kubelet 服务进程,默认监听 10250 端口
接收并执行 Master 的指令
管理 Pod 以及 Pod 中的容器
在 API Server 注册 Node 信息,定期向 Master 汇报 Node 的资源使用情况
通过 cAdvisor 监控 Node 和容器的资源
cAdvisor 通过 Cgroups 收集并上报容器的资源用量
Node 管理
Node 自注册 + Node 状态更新
自注册模式:Kubelet 通过启动参数 --register-node 来确定是否向 API Server 注册
Kubelet 没有选择自注册模式
用户需要自己配置 Node 资源信息
告知 Kubelet 集群上的 API Server 的位置
Kubelet 选择自注册模式
Kubelet 定时向 API Server 发送 Node 信息
API Server 在接收到 Node 信息后,转存到 etcd
Pod 管理
syncLoop - Kubelet 本身也是控制器模式
computePodActions - 比对 Pod Ma ...