容器编排 -- Pod
基本概念 在Kubernetes中,Pod是一等公民 Pod是Kubernetes的原子调度单位,Kubernetes统一按照Pod(而非容器)的资源需求进行计算 容器的本质是进程 容器的单进程模型 并不是指容器里只能运行一个进程,而是指容器没有管理多个进程的能力 原因 容器里PID=1的进程是应用本身,其它进程都是PID=1进程的子进程 用户编写的应用,并不能像正常OS里面的init进程或者systemd进程那样拥有进程管理的功能 容器间具有『超亲密关系』的典型特征 互相之间会发生直接的文件交换 使用localhost或者Socket文件进行本地通信 会发生非常频繁的远程调用 需要共享某些Linux Namespace 并不是所有有关系的容器都属于同一个Pod,如Java应用容器和MySQL更适合做成两个Pod Pod在Kubernetes中的重要意义 – 容器设计模式 实现原理 Pod只是一个逻辑概念 Kubernetes真正处理的,还是宿主机上Linux容器的Namespace和Cgroups,并不存在所谓的Pod的边界或者隔离环境 Pod里的所有容器,共...
Kubernetes -- 集群搭建 & 应用容器化
kubeadm安装1$ apt-get install kubeadm 步骤12345# 创建一个Master节点$ kubeadm init# 将一个Worker节点加入到当前集群中$ kubeadm join <Master节点的IP和端口> 工作原理 直接容器化kubelet会面临很多问题,所以把kubelet直接运行在宿主机上,然后使用容器部署其它的Kubernetes组件 工作流程kubeadm initPreflight Checks 进行一系列的检查工作,确保该机器可以用来部署Kubernetes Linux内核版本 ≥ 3.10 Linux Cgroups模块可用 机器的hostname标准(符合标准的DNS命名) kubeadm与kubelet的版本匹配 机器上已经安装了Kubernetes的二进制文件 Kubernetes的工作端口(10250/10251/10252)没有被占用 ip、mount等Linux指令存在 Docker已经安装 生成证书 生成Kubernetes对外提供服务所需的各种证书和对应的目录 Kubernetes对外...
Kubernetes -- 架构 & 设计思想
容器 本质:由Linux Namespace、Linux Cgroups和rootfs三种技术构建出来的进程的隔离环境 容器的视图 静态视图(Container Image):一组联合挂载在/var/lib/docker/aufs/mnt上的rootfs 动态视图(Container Runtime):由Namespace+Cgroups构成的隔离环境 开发人员并不关心Container Runtime的差异,因为承载容器信息进行传递的,是Container Image Kubernetes架构 角色:Master(控制节点)、Node(计算节点) Master kube-apiserver:负责API服务,整个集群的持久化数据,由kube-apiserver处理后保存在Etcd中 kube-scheduler:负责调度 kube-controller-manager:负责容器编排 Node:kubelet,为最核心的组件 CRI,Container Runtime Interface 主要负责与Container Runtime打交道 只要Container Runtime能够运行标准...
容器基础 -- Docker容器
文件12# lsapp.py Dockerfile requirements.txt app.py1234567891011121314from flask import Flaskimport socketimport osapp = Flask(__name__)@app.route('/')def hello(): html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())if __name__ == "__main__": app.run(host='0.0.0.0', por...
容器基础 -- rootfs
环境12345678# cat /etc/issueUbuntu 16.04.7 LTS \n \l# uname -aLinux ubuntu1604 4.4.0-186-generic #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux# docker --versionDocker version 18.03.1-ce, build 9ee9f40 12345678910# grep aufs /proc/filesystemsnodev aufs# cat /etc/docker/daemon.json{ "storage-driver": "aufs"}# docker info | grep 'Storage Driver'Storage Driver: aufs Mount Namespace创建子进程时开启Namespace 123456789101112131415161718192021222...
容器基础 -- Namespace & Cgroups
VM vs Container Hypervisor 通过硬件虚拟化,模拟出一个操作系统所需要的各种硬件,然后在虚拟的硬件上安装Guest OS 对应用进程的隔离环境负责 额外的资源消耗和占用 使用虚拟化技术作为应用沙盒,必须由Hypervisor来负责创建VM,该VM是真实存在的且里面运行一个完整的Guest OS Docker Engine 『轻量级』虚拟化 不存在真正的『Docker容器』运行在宿主机里面,Docker只是在创建进程时,加上各种不同的Namespace参数 真正对隔离环境负责的是宿主机操作系统,而非Docker Engine 容器化后的用户应用,依然还是宿主机上的普通进程 相对于VM的优势:敏捷 + 高性能 基于Linux Namespace劣势:隔离不彻底 多个容器之间使用的还是同一个宿主机的操作系统内核 低版本的Linux宿主机不能运行高版本的Linux容器 容器给应用暴露出来的攻击面是很大的 – Seccomp(对容器内部发起的系统调用做过滤拦截,影响容器性能) 在Linux内核中,很多资源和对象是不能被Namespace化的,如时间 Namesp...
猜拳设计
需求概要用户消费若干金币后排队,N人组队成功后开始猜拳,M轮PK后决出最终胜利者 轮次分布数理预测 实际分布 概要设计用例图 部署图 状态图用户阶段 数据状态 数据模型
任务系统 - 性能调优
说明调优背景 任务系统是一个运行多年且高度抽象的核心营收系统 业务高峰期出现频繁GC,导致Kafka消息消费延迟的情况,影响线上业务 经JVM参数调优后,效果提升不明显,依然无法满足业务需求,需要专项深入优化,降低内存分配的速度 主要挑战 代码高度抽象且迭代多年,存在比较陡峭的理解曲线 调优过程不能影响线上业务,因此不能采用会触发STW的工具,如HeapDump等 调优思路 不直接关注代码架构设计等静态指标,直接采样线上系统的运行数据 从采样数据中得出剩余可调优空间的TopN问题,针对问题进行分析优化后再次上线,进入下一轮调优迭代 调优N次后,当剩余可调优空间不大或者性价比不高时(问题域趋向于收敛),即结束调优迭代 采样时间 Java Flight Recorder 均为10分钟 采样文件大小与采样时间基本是O(N)的关系,不适合长时间采样,且本案例中内存分配的Top 5基本不变 Async Profiler 调优迭代为10分钟,最后一次采样为7天 采样文件大小与采样时间基本是O(1)的关系,可以长时间采样 调优迭代采样10分钟是为了快速确定TopN问题,加速调优迭代 最后一次采样为7...
Linux性能 -- CPU -- 使用率
节拍率(HZ) 为了维护CPU时间,Linux 通过事先定义的节拍率(内核中表示为HZ) 触发时间中断,并使用全局变量Jiffies记录开机以来的节拍数 节拍率 HZ 是内核的可配选项,可设置为100、250、1000等 HZ=250,表示每秒触发250次时间中断,每发生一次时间中断,Jiffies值+1 节拍率 HZ 是内核选项,用户空间程序不能直接访问 为了方便用户空间程序,内核提供了一个空户空间节拍率USER_HZ,固定为100,即10ms 12root@ubuntu:~# grep 'CONFIG_HZ=' /boot/config-$(uname -r)CONFIG_HZ=250 /proc/stat & CPU使用率 Linux 通过 /proc 虚拟文件系统,向用户空间提供系统内部状态的信息 /proc/stat 提供的是系统的 CPU 和任务统计信息 12345# 后面10列表示不同场景下 CPU 的累计节拍数,单位是USER_HZ,即10ms,即不同场景下的 CPU 时间root@ubuntu:~# cat /...
Linux性能 -- CPU -- 上下文切换
CPU 上下文 CPU 上下文 CPU 在运行任何任务前,必须的依赖环境 CPU 寄存器 CPU 内置的容量小、但速度极快的内存 程序计数器 存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置 CPU 上下文切换 切换过程 先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来 然后加载新任务的上下文到这些寄存器和程序计数器 最后再跳转到程序计数器所指的新位置,运行新任务 保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来 CPU特权等级 & 进程运行空间 & 系统调用 进程的运行空间分为内核空间和用户空间 内核空间(Ring 0) 具有最高权限,可以直接访问所有资源 用户空间(Ring 3) 只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源 进程在用户空间运行时,被成为进程的用户态;而陷入内核空间的时候,被称为进程的内核态 从用户态到内核态的转变,需要通过系统调用来完成 系统调用的过程会发生 CPU 上下文的切换 一次系统调用,发生了两次 ...












