Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
使用场景

虚拟机最大的缺点就是依赖其专用的操作系统
容器本质上就是利用了 Linux 的 cgroup 与 namespace 创建了一个进程,该进程相对于宿主机,拥有一定的资源限制及隔离,该进程可以创建子进程,这些子进程也跟父进程一样,会受到资源限制及拥有一个被限制的视角,只能看到跟父进程一样的资源视图,这是容器中进程运行起来的动态视图
另一部分,则是通过 mount namsapce 及 rootfs 创建的容器镜像,这是容器的静态视图

Docker引擎由如下主要的组件构成:Docker客户端(Docker Client)、Docker守护进程(Docker daemon)、containerd以及runc。它们共同负责容器的创建和运行

LXC提供了对诸如命名空间(Namespace)和控制组(CGroup)等基础工具的操作能力,它们是基于Linux内核的容器虚拟化技术

Docker公司开发了名为Libcontainer的自研工具,用于替代LXC
runc:
containerd:
启动容器的过程:

容器运行时与Docker daemon是解耦的,对Docker daemon的维护和升级工作不会影响到运行中的容器
shim:

docker search name
docekr pull name<:tag>
docker rmi 镜像ID
docker image rm $(docker image ls -q) -f
在镜像名后面的:xxx 代表标签
没有标签的镜像被称为悬虚镜像

docker 会复用已存在的镜像层

容器在停止后启动写入的数据仍会存在
但是volume才是持久化的首选
在指定事件或者错误后重启来完成自我修复

| 命令 | 用途 |
|---|---|
| FROM | base image |
| RUN | 执行命令 |
| ADD | 添加文件 |
| COPY | 拷贝文件 |
| CMD | 执行命令 |
| EXPOSE | 暴露端口 |
编写Dockerfile文件:
FROM ubuntu
MAINTAINER MY
RUN apt-get update
RUN apt-get install nginx -y
COPY index.html /var/www/html
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
EXPOSE 80
每一个RUN指令会新增一个镜像层。因此,通过使用&& 连接多个命令以及使用反斜杠(\ )换行的方法,将多个命令包含在一个RUN指令中,通常来说是一种值得提倡的方式
利用构建缓存:
合并镜像:

no-install-recommends:
不要安装MSI包(Windows)
CNM: 定了Docker网络架构的基础组成要素

Libnetwork是CNM标准的实现

docker network ls # 列出可用网络
docker run -d --network my-net # 指定容器网络
如果在相同网络中继续接入新的容器,那么在新接入容器中是可以通过的容器名称来进行网络通信的
主要功能是为容器提供跨主机的网络互连,使得不同主机上的容器可以直接通信,无论它们是否在同一物理网络中。它通过创建虚拟网络层来实现这一目标,并使用Overlay网络技术在物理网络之上构建虚拟网络,其有两种实现:

host-gw 模式必须要求集群宿主机之间是二层连通的

使用 UDP 实现的方案,需要经过三次用户态与内核态之间的数据拷贝:
有着严重的性能问题,已经废弃

sequenceDiagram
participant Admin as 管理员
participant FlannelAgent as Flannel代理
participant Allocator as 分配器
participant Container as 容器
Admin->>FlannelAgent: 配置Flannel
FlannelAgent->>FlannelAgent: 启动
FlannelAgent->>Allocator: 请求子网分配
loop 每个主机
FlannelAgent->>FlannelAgent: 创建虚拟网络接口
Container->>FlannelAgent: 发送网络流量
FlannelAgent->>FlannelAgent: 封装数据包到Overlay网络
end
FlannelAgent->>FlannelAgent: 路由数据包到目标主机
FlannelAgent->>Container: 解封装数据包

Felix 负责在宿主机上插入路由规则。除了对路由信息的维护方式之外,Calico 项目与 Flannel 的 host-gw 模式的另一个不同之处,就是它不会在宿主机上创建任何网桥设备
Calico 维护的网络在默认配置下,是一个被称为“Node-to-Node Mesh”的模式,即每个节点都要两两连接。另外一种模式叫做 Route Reflector,会指定一个或者几个专门的节点,来负责跟所有节点建立 BGP 连接从而学习到全局的路由规则。而其他节点,只需要跟这几个专门的节点交换路由信息,就可以获得整个集群的路由规则信息了
如果宿主机之间网络不通,即没办法通过二层网络把 IP 包发送到下一跳地址,则需要通过 IPIP 模式,其原理就是通过内核,将包直接封装在一个宿主机网络的 IP 包中。使用 IPIP 模式的时候,集群的网络性能会因为额外的封包和解包工作而下降

只要能够让宿主机之间的路由设备(也就是网关),通过 BGP 协议“学习”到 Calico 网络里的路由规则,那么从容器发出的 IP 包,可以通过这些设备路由到目的宿主机。一种做法是用一个独立的组件收集路由规则,再通过 BGP 协议同步给网关

docker network create -d bridge localnet
# 将本机8080端口映射到容器80端口
docker run -p 8080:80 <name>
# 将本机端口随机与容器端口映射
docker run -P <name>
每个Docker容器都有自己的非持久化存储。非持久化存储自动创建,从属于容器,生命周期与容器相同
持久化是将数据存储在卷上。卷与容器是解耦的

卷类型:

Docker 平台安全技术:
Docker 提供的容器环境是和 Linux 内核隔离的。想要实现这种隔离,就需要用到 Namespace 机制 Namespace的隔离并不够彻底
提供了更细粒度的授权机制,它定义了主体能够进行的某一类操作
利用 CGroups 机制来实现对容器中内存、CPU 和 IO 等的限制
守护进程,具备操控 Docker 容器的全部权限
如果守护进程提供的API接口没有认证,则很容易被入侵