由于去年换工作,接触到了云原生架构的项目,大部分都是面向B端客户的交付。而且公司在初创期间,规模不大,作为测试人员往往要负责更多的质量保证,不再只针对业务,更要宏观的考虑整体架构。正好也看到testerhome论坛经常关注的一个大佬最近出版了一本相关的书,遂买来支持一下。之前偶然巧合下也看过这位大佬一些关于docker的视频和直播,从测试角度了解了很多更深层更细节的知识,也深深的被吸引。去年买到这本书也翻看了大概三分之一,后来工作和家庭繁忙,一直没有继续下去。今天开始重新翻看阅读,从零开始整理读书笔记,坚持看完。
第一章 认识云原生
云原生最初概念:“I've been thinking a lot about what if means for applications and middleware to work well in a cloud enviornment”,所以云原生本质是为了能让程序在云环境中运行和迭代得更好而产生的一种设计思想。实现云原生的关键不是在哪里运行应用,而是如何构建应用
云原生测试挑战:
- 容器领域的知识储备
- 高可用测试(故障注入测试)
- 性能测试与对应的监控系统(1. 资源配额策略,配额是否合理 --- 容量测试 2. 开发监控和性能数据收集组件)
- 稳定性测试与对应的监控系统(1. 服务中断的监控,2. 瞬时的异常事件监控等)
- 边缘计算
- 持续集成与发布
- 云原生与大数据
第二章 容器技术基础
喜欢本书的原因之一是作者从测试的角度去学习容器和云原生,所以本书的重点不在讲解docker基本命令,这些都能随便查到。
Linux命名空间:
命名空间是为了隔离进程(与K8S的命名空间完全不同,为了隔离Pod),Linux的两个进程互相访问必须处在同一个命名空间,而且在启动进程的时候也会要求传递命名空间参数。所以可以理解为在启动一个容器时其实就启动了一个进程,并为这个进程分配了独立的命名空间,而用户在容器内创建的任何进程其实就是使用了这个命名空间的普通进程。
命名空间类型,用来服务不同的隔离目标:
- Network 网络
- PID 进程
- IPC 信号量,消息队列等
- Mount 文件系统挂载点
- User 用户和用户组
- UTS 主机名与NTS域名
nsenter命令:
kubectl describe <pod> 找到所在服务器信息
docker inspect <容器ID> 进入服务器找到容器对应的PID
nsenter -t PID -n 进入目标容器的网络命名空间
网络模式
bridge网络模式(桥接)
Linux有一种网络设备-虚拟网卡,特点是可以把两块虚拟网卡凑成一堆,可以穿透命名空间的隔离限制。但是如果所有容器之间都有一对,随着容器数量越来越多,网卡的数量会变得不可接受,所以引入了bridge模式(docker的默认网络模式)
docker0就是网桥,veth开头的就是网桥上的虚拟网卡(这些可以在宿主机通过ifconfig命令看到,为什么看不到容器里的网卡呢,因为命名空间不同被隔离了。)
host网络模式
--net == host ,Docker不再为容器创建独立的网络命名空间(仅网络同一个,其他还是隔离的),所以是使用了宿主机默认的网络命名空间(eth0)
适合场景:
host模式广泛应用与路由场景,比如K8S的ingress服务,既可以访问外界网络,也可以访问容器网络,非常适合路由。
container网络模式
启动时使用了某个容器的网络命名空间。
常见场景:
- K8S的每个Pod都会默认启动一个sandbox容器来提供基础网络,业务容器启动会container到这个sandbox的网络命名空间
- K8S中部署mock服务
容器镜像
联合文件系统(union file system UFS)
RUN指令越多,层数越多(需要根据业务需要对RUN指令进行一定程度的合并)
镜像扫描工具的开发:
docker history <镜像名称或容器名称> 列出每一层的信息,可以扫描出镜像的分层细节,可以利用K8S把脚本调度到所有机器上一次性执行,并将分析的结果上报。
docker system df -v 列出机器中所有镜像,容器和卷的相关信息,SHARED SIZE(共享空间大小,越小越差) UNIQUE SIZE(独享空间,越大越差)
第三章 Kubernetes基础
深入解析Pod
Pod的架构
Pod是K8S调度的最小单位,由多个容器组成,容器之间共享一定限度的资源配置。每个Pod会有一个sandbox容器(pause),主流监控软件Prometheus在统计时往往会过滤这些pause容器
除了网络协作,还有文件协作,例如selenium浏览器集群和UI自动化程序部署在k8s集群,然后两个pod使用hostPath类型的卷挂载在宿主机相同的路径,这样ui自动化就能读取浏览器下载的文件了
Pod的调度
Pod重新调度设计:
不论pod中的容器失败多少次,都不会触发这个pod的重新调度,k8s只会尝试重新启动失败的容器。只有判断整个pod节点不可用时,才会删除并尝试在其他节点创建一个新的pod。
nodeSelector: 指定Pod必须调度到哪些节点上
亲和性和反亲和性: 节点亲和性-nodeAffinity , Pod亲和性-podAffinity
Pod的资源管理
Cgroups(Control Group):限制一个进程组能够使用的资源,比如CPU,内存,磁盘,带宽等。 Cgroups以文件和目录的方式在/sys/fs/cgroup路径下展示给用户。
resources:
requests: (为容器预留的资源,即使不用,其他容器也申请不到,所以K8s是使用requests来计算资源的)
cpu: "0.5"
memory: "200Mi"
limits: (限制容器使用的资源上限,即实际运行时不能超过的资源数值。这个limit命名真反差!!!)
cpu: "1"
memory: "500Mi"
超过limit上限后会根据资源类型来区分操作:
- 可压缩资源CPU:一般超过cpu会表现为限速或变得执行缓慢,不会导致容器终止
- 不可压缩资源内存:一般超过内存就会触发OOM,容器终止运行
超卖策略
测试需要结合压力测试,监控平台,扫描工具,以及rebalance(重平衡)等工具,分析出各个服务最适合的资源配额。