K8s 001
K8s
前言
k8s 大名鼎鼎,是go语言的代表之作,但是作为后端RD一般是接触不到的,通常操作都已经白屏化了。我说有些鸡架会问,顺便学一下,省着没事打游戏。仅作为了解,浅浅的从八股的角度学习一下。
总览
按照 What Why How 的顺序进行
What
Kubernetes :可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。
说人话就是 Docker -> Docker Compose -> K8s
架构:
kube-apiserver 集群唯一入口,提供REST API | etcd 键值存储,保存集群全部状态 | kube-scheduler 决定Pod调度到哪个节点 | kube-controller-manager 运行控制器,持续逼近期望状态 |
●NODE 1
Container Runtime·containerd
| ●NODE 2
Container Runtime·containerd
|
Pod是最小调度单元,内部可包含一个或多个共享网络与存储的容器。
组件作用:
控制面:
-
kube-apiserver: REST API
-
etcd:分布式KV存储
-
kube-scheduler:监听尚未绑定Node的 Pod,只负责选出应该去哪个 Node
-
kube-controller-manager:一堆控制器,每一个负责一类资源(运行的 Pod 个数,完成的 Job 个数等等)。如果每个是一个死循环,如果运行状态和期望不一样,就进行纠偏。
工作节点:
-
kubelet:和 apiserver 通信
-
kube-proxy:Service (Service 是一组 Pod 的稳定抽象入口)会被 apiserver 分配一个虚拟的内网 IP(ClusterIP)。通过写 iptables / IPVS 规则,实现这个 Node 上的 Pod(或主机)访问这个虚拟 IP 时,自动映射到某个真实 Pod IP,并做负载均衡。
-
Container Runtime:真正运行容器的组件,通过 CRI (Container Runtime Interface ,类似于 DDD 的依赖倒置思想,让 docker / rkt 实现相关抽象接口的操作)被 kubelet 调用,负责 Pod 的生命周期。
负载单位:
- Pod:最小调度单元。同一个 Pod 内的容器共享 Network Namespace 和 Volume,互相连通。类似一个 docker compose
- Container:同 Docker 里面的 container 大小
提供的功能:
- 服务发现和负载均衡
- 存储编排:挂载本地盘/远端存储
- 自动部署和回滚:RD传说中的一键发版
- 自动完成装箱计算:一个 Node 上可以跑很多个 Pod,Kubernetes 会自己决定哪个 Pod 放到哪个 Node 上。
- 自我修复
- 密钥与配置管理:ConfigMap 存非敏感配置,Secret 存敏感信息(base64编码,非安全,需要配合其它加密)。
- 批处理执行 :训练/离线推理场景
- Job:保证成功完成指定数量的 Pod。
- CronJob:定时跑批
- 水平扩缩 :单节点资源压力大自动扩容,扩的是Pod
- IPv4/IPv6 双栈
- 为可扩展性设计:在不改变上游源代码的情况下为你的 Kubernetes 集群添加功能
Why
显而易见,上面提供的功能太多了,比黑屏部署强多了
How
只讲容器的实现即资源隔离机制,因为其它的实现显然是业务/分布式上的逻辑,和操作系统没什么关系。
namespace: 给一组进程套上资源可见性显示,如 PID、网络、主机名、挂载点、用户。
注意存在一个特殊的 PID = 1 进程(docker 的第一个进程),宿主机看到的是类似 12345 的常见 PID,而在容器内它是 1。
最佳实践:
- 应用直接以 exec 形式启动,成为 PID 1。
- 应用自己处理
SIGTERM、回收子进程。 - 如果应用做不到,使用
docker run --init或tini/dumb-init。 - 避免 shell 形式启动,避免
--pid=host。 - 合理设置
STOPSIGNAL和停止超时。
cgroups: 给一组进程套上资源限制和分配优先级
一些QA
- k8s 的服务发现和 consul 的区别
- gpu 推理 k8s 的不足