一、容器发展之路
-
vmware:提供虚拟机 不足:依赖专用的操作系统os,会占用额外的cpu、ram和存储。这些资源本可以运行更多的应用,并且重启通常比较慢,可移植性比较差,不同的虚拟机管理和云平台之间迁移很困难,每个虚拟机都需要独立的许可,独立存储空间,每个操作系统都占用一定资源。
-
hypervisor: 虚拟机监视器-硬件虚拟化-docker是系统级别虚拟化
-
-
engine:引擎
-
-
现在容器技术起源于linux系统
-
docker公司:起初dotcloud更名为docker(300-400名员工)目前项目开源:github.com/moby/moby
-
容器共享一个操作系统/内核,只有一个操作系统消耗cpu,ram和存储资源,只有一个系统需要授权和升级补丁和承担受攻击的风险。
-
企业版社区版,区别
二、docker引擎
- docker daemon(守护进程):最开始-单一二进制文件包含docker客户端,api,容器运行,构建等 (后被逐渐拆解)-目前保留部分【api+安全特性+身份认证+镜像管理+卷功能】
- LXC:基于linux的,提供对【namespace和cGroup】等操作能力的模块,最开始就是由以上两个模块构成docker (后被替换)
- Libcontainer:但是docker公司致力于【跨平台】的容器工具,而以上引擎两大核心是基于linux的,所以在docker0.9+版本以后由Libcontainer替代以上LXC模块
- runc:在基于Libcontainer和OCI规范实现的轻量级针对Libcontainer包装的独立运行命令行工具,只有一个功能-创建容器-与操作系统内核接口进行通信、基于所有必要的工具ns、cg等来【创建容器】。容器进程作为runc的子进程启动,启动完毕runc将会退出。
- contained:docker daemon拆解之后将生命周期管理。start,pull,stop和镜像管理-重新构建到一个叫contained的【工具】-接受来自daemon的指令后发送OCI 镜像等指令,调用runc。
- shim:每次runc创建新容器都会fock一个新的runc实例,创建完毕runc进程会退出然后相关的contanin-shim会【接管】容器成为容器的父进程。职责如下:1.保持所有的stdin和stdout(标准输入和输出流是开启状态),所以当daemon在重启的时候容器不会因为pipe(管道)关闭而终止。2.将容器的退出状态反馈给daemon

- 该模型的优势:管理容器的逻辑从daemon中移除(无守护进程容器),对【docker的维护升级不会影响到运行中的容器】,在旧的模型中启动停止都在daemon中操作停止会导致宿主机所有的运行中容器被杀掉。
三、镜像内容寻址存储模型
镜像分层-只读镜像层-共享镜像层-补丁镜像层
-
通过标签区分镜像看似没啥问题,但是如果某个标签镜像有bug,修复之后使用同样的标签重新推送到仓库,原镜像被覆盖,但是生产环境又遗留大量运行中的容器,有什么办法区分镜像版本是修复前还是修复后的呢?
-
镜像内容寻址存储:镜像唯一标识id而每个镜像层又一个加密id,意味着每个镜像层变动引起,整体镜像的散列值变动-内容散列
-
在推送和拉镜像的时候都会节省带宽对镜像进行压缩节省二进制存储空间。但是压缩会改变镜像内容,导致散列id也会被篡改或者传输镜像过程中被恶意串改之后校验镜像散列值也会失败。
-
为了避免这种问题,每个镜像层会再生成一个分发散列值,这是一个压缩版本的散列值,拉去到镜像后通过对比压缩镜像散列值比对是否被篡改。
-
问题1: 不同的系统如何确定该镜像是否与该环境匹配?
四、docker的compose用法
-
现在应用是通过多个服务来互相协同组成完整应用。比如web+订单+品类+后台等,那没发布一个docker 容器都通过脚本和各种冗长的docker命令去管理和部署。而是通过一个配置文件描述整个应用,从而使用一条命令完成部署
-
背景 docker compose前身是fig是一个python工具给予yaml文件定义多容器管理最佳方案,fig会解析yaml,通过docker api进行应用的管理和部署。 docker公司收购orchard公司将fig更名为docker-compose。他是在脱离docker引擎之外应用层的外部工具。
-
命令 docker-compose up / docker-compose ps / top / down 等
# api版本
version: "2"
services:
web-server:
build:
# Dockerfile 所在目录
context: ./images/console
# Dockerfile 在 build 过程中需要的参数
args:
- USERPASS=root
- GIT_NAME=xxxxxx
# 启动后执行
command: python app.py
volumes:
- ./ssh:/home/www-data/.ssh
networks:
# 调用下面 networks 定义的 app_net 网络
app_net:
ipv4_address: 172.16.238.10
nginx:
image: nginx
ports:
- "8081:80"
volumes:
- ./logs/nginx/:/var/log/nginx/
- ./images/nginx/sites:/etc/nginx/conf.d/
mysql:
image: mysql
ports:
- "7706:3306"
environment:
MYSQL_ROOT_PASSWORD: "123"
MYSQL_DATABASE: "test"
volumes:
- ./data/mysql:/var/lib/mysql
redis:
image: redis
ports:
- "6379:6379"
volumes:
- ./data/redis:/data
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
#默认情况下,docker会创建bridge的单主机网络,也可以自己定义网络链接
五、docker的swarm和k8s的关系
-
Docker Swarm已经在这场与Kubernetes竞争中已经逐渐失势
-
Docker Swarm: 是由一个或者多个docker节点组成。这些节点要求通过一个可靠的网络相连接点会被分配管理节点【manager和工作节点worker】。管理节点负责控制集群的控制面,进行诸如监控和集群状态和分发任务至工作节点等操作。工作节点接受来自管理节点的任务并且执行。
-
swarm的配置和状态信息保存在位于管理节点之上的分布书数据库中,运行于内存中,并且保持最新状态。
-
安全性使用了TLS进行认证授权,通信加密,自动密钥轮换
-
编排基于服务,一个任务或者一个副本服务中增加诸如扩索容和回滚升级等特性
-
命令查看服务 docker service ls查看swarm集群的所有服务
-
命令扩索容 【docker service scale web-fe=10】 该命令会自动将副本均匀分配到工作节点上
-
docker的stack stack是基于docker swarm上来完成应用部署的,提供期望状态、简单易用、扩缩容、健康检查等特性-通过componse定义应用-docker stack deploy 完成部署和管理相当于集群版本的componse
-
命令 docker stack deploy
-
Kubernetes: 它本身的角色定位是和Docker Swarm 是一样的,也就是说他们负责的工作在容器领域来说是相同的部分,都是一个跨主机的容器管理平台,当然也有自己一些不一样的特点,【k8s是谷歌公司根据自身的多年的运维经验研发的一款容器管理平台】。而Docker Swarm则是由Docker 公司研发的。 这两年Kubernetes已经成为了很多大公司的默认使用的容器管理技术-所以容器管理平台首选k8s
六、docker的安全技术
- docker的安全是基于分层隔离的

以上每种技术,docker都设置了默认值,实现了流畅并且适应度安全的开箱即用的体验。docker也允许用户根据特定的需求自定义调整每项安全配置
- 例如:docker swarm 模式默认是开启安全功能,加密节点,双向认证,自动化ca配置,自动证书更新,加密集群存储,加密网络安全等功能。
- namespace:pid、net、MNT(挂载点命令空间目录)、ipc(进程内通信命令空间)、uts(主机名称)-本质就是命令空间的有机组合
- control group ns用于隔离,cg用于限额-cpu、ram运行内存、i/o
- capability 允许用户以root身份运行容器,启动成功移除全部root能力
- MAC 允许用户在启动容器不设置策略、也允许用户需求自己配置策略
- seccomp 限制容器对宿主机内核调用

- docker swarm安全认证 - 命令- 管理集群节点ca认证,工作节点和其余管理者节点 - 命令 - 准入令牌(管理者准入令牌+工作者准入令牌)
- docker swarm 安全扫描 对镜像包进行二进制代码级别的扫描-生成详细报告
- docker 内容信任(镜像传输签名)和密钥管理docker1.13版本新增
七、docker网络
- 1.CNM协议 2.Libnetwork实现 3.驱动网络三部分组成
- cnm 独立网络栈(以太网、端口、路由表、dns配置)、虚拟网络接口、虚拟交换机


- Libnetwork 对cnm的实现,之前在daemon中后来拆解出来,重构成了这个外部类库,组成网络部分的核心代码。
- 驱动 创建网络对象、实现数据层、

- 2.单桥接网络
解决办法现成的 - 启动容器加端口映射。当然内部单机通信也有其他的解决方案,建立新的桥接和dns解析。
- 3.多机器覆盖网络
- 命令 之前的compose文件配置服务网络或者命令 docker network create -d overlay
- 4.服务发现 底层实现利用docker内置的dns的服务器,为每个容器提供dns极细功能

- 简单来说就是没个容器注册到dns服务上,当发起指令时会先去本地的dns解析找,找不到就去docker dns服务器找,然后找到对应的ip地址。要求是在同一个网络中服务才能生效
八、卷与持久化数据
非持久话数据:于自身生命周期相同 持久化数据:如果有对各服务 - 共享一个持久化存储卷的话,需要在应用程序中进行控制。