Docker的安装
Docker容器的存储空间:保存层叠的镜像层和挂载的文件系统。
Docker of Linux的存储驱动:AUFS、Overlay2、Device Mapper、Btrfs、ZFS
///etc/docker/daemon.json
{
"storage-driver": "overlay2"
}
# 查询docker系统配置
$ docker system info
纵观Docker
查询版本信息
$ docker version
镜像
# 遍历所有镜像
$ docker image ls
# 拉取镜像
$ docker image pull ubuntu:latest
# 新建镜像
$ docker image build -t test:latest
# 删除镜像
$ docker image rm xxxx
容器
# Linux启动容器
$ docker (container) run -it ubuntu:latest /binbash
# Windows启动容器
$ docker (container) run -it microsoft/powershell:nanoserver pwsh.exe
# 遍历容器
$ docker (container) ls
# 运行容器
$ docker run -d \
--name web1 \
--publish 8080:8080 \
test:lastest
Docker引擎
Docker引擎:运行管理容器
- Docker Client: 客户端
- Docker Daemon: 守护进程
- containerd: 容器执行逻辑
- runc: 创建容器
shim:运行的容器与daemon解耦,在容器创建后,runc退出,containerd-shim进程作为容器的父进程。
Docker镜像
# --filter参数过滤docker image ls的内容(filter支持dangling/before/since/label)
$ docker image ls --filter dangling=true
# 其他参数可以使用reference
$ docker image ls --filter=reference="*:latest"
# --format 参数通过Go模板对输出进行格式化
$ docker image ls --format "{{.Repository}}: {{.Tag}}: {{.size}}"
# 移除悬虚镜像
$ docker image prune
# 移除目前没有被使用的镜像
$ docker image prune -a
# 通过CLI方式搜索Docker Hub
$ docker search xxxx --filter "is-official=true" --limit 100
Docker镜像由一些松耦合的只读镜像层组成。
镜像始终保持当前所有镜像层的组合。
多个镜像层之间可以共享镜像层。
# 查看镜像分层
$ docker image inspect xxxx
Docker容器
# Linux启动容器
$ docker (container) run -it ubuntu:latest /binbash
# Windows启动容器
$ docker (container) run -it microsoft/powershell:nanoserver pwsh.exe
# 遍历容器
$ docker (container) ls
# 停止并删除容器
$ docker (container) stop
$ docker (container) rm
# 重启容器
$ docker (container) start
# 在运行状态的容器中启动一个新进程
$ docker (container) exec
# 容器的配置细节和运行时信息
$ docker (container) inspect
启动Ubuntu容器时,让容器运行Bash Shell,成为容器中唯一运行的进程,如果关闭Bash Shell,容器也会终止。
重启策略(–restart): always/unless-stopped/on-failure。
unless-stopped并处于停止状态的容器不会在Docker Daemon重启时被重启。
on-failure容器非正常退出时重启。
应用的容器化
Dockerfile: 包含对当前应用的描述,并且能指导Docker完成镜像的构建。
FROM: 指定镜像作为基础镜像层,剩余内容作为新增镜像层添加到基础镜像层上。
LABEL: 标签
RUN: 执行命令并创建新的镜像层,通常用于安装软件包
CMD: 设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换( docker run -it [image] 可执行)
COPY: 复制相关文件到指定的目录上
WORKDIR: 为尚未执行的命令指定工作目录
EXPOSE: 完成相应端口的设置
ENTRYPOINT: 指定当前镜像的入口程序
ENV: 设置环境变量
# .表示当前目录作为构建上下文
$ docker image build -t web:lastest .
# 推送到镜像仓库服务
$ docker image push
# 多阶段构建种,从之前的阶段构建的镜像种仅复制生产环境相关的应用代码,而不会复制生产环境不需要的构建
COPY --from=appserver /xxx/xxx/xxx
使用Docker Compose部署应用
多应用部署
version: "3" # 定义Compose文件格式版本
services: # 定义不同的应用服务
web-fe:
build: . # 基于当前目录下的Dockerfile定义的指令来构建新镜像
command: python app.py # 指定执行脚本作为主程序
ports: # target 容器内端口 published 主机端口
- target: 5000
- published: 5000
networks: # 将服务连接到指定网络上
- counter-net
volumes: # 指定Docker将counter-vol卷挂载到容器内的/code目录下。
- type: volume
source: counter-vol
target: /code
redis:
imgae: "redis:alpine" # 基于镜像启动容器
networks: # 配置redis容器连接到counter-net网络
- counter-net
networks: # 指引Docker创建新的网络
counter-net:
volumes: # 指定Docker创建新的卷
counter-vol:
# 使用docker-compose启动应用 -d 表示在后台启动
$ docker-compose up -d
# 查看应用状态
$ docker-compose ps
# 查看各个服务内运行的进程
$ docker-compose top
# 停止应用
$ docker-compose stop
# 删除应用
$ docker-compose rm
# 重启应用
$ docker-compose restart
# 查看卷
$ docker volume ls
# 停止并删除应用,但不会删除卷和镜像
$ docker-compose down
Docker Swarm
Swarm包含两个核心组件:安全集群、编排引擎。
默认内置:加密的分布式集群存储、加密网络、公用TLS、安全集群接入令牌、简化数字证书管理PKI。
节点类型:管理节点(Manager)工作节点(Worker)。
Swarm的配置和状态信息保存在一套位于所有管理节点上的分布式etcd数据库中。
在网络方面需要在路由器和防火墙开放端口:
- 2377/TCP:用于客户端与Swarm进行安全通信。
- 7946/TCP与7946/UDP:用于控制面gossip分发。
- 4789/UDP:用于基于VXLAN的覆盖网络。
在单引擎模式下的Docker主机上运行docker swarm init会将其切换到Swarm模式。
# mgr1初始化一个新Swarm
$ docker swarm init \ # 初始化一个新Swwarm,并将自身设置为第一个管理节点
--advertise-addr 10.0.0.1:2377 \ # 指定其他节点用来连接到当前管理节点的IP和端口
--listen-addr 10.0.0.1:2377 # 指定用于承载Swarm流量的IP和端口
# 列出Swarm节点
$ docker node ls
# mgr1执行命令获取添加新的工作节点和管理节点到Swarm的命令和Token
$ docker swarm join-token worker
docker swarm join \
--token SWMTKN-1-XXX...XXX \
10.0.0.1:2377
$ docker swarm join-token manager
docker swarm join \
--token SWMTKN-1-XXX...XXX \
10.0.0.1:2377
# 登录wrk1 wrk2 wrk3 使用包含工作节点token接入Swarm
$ docker swarm join \
--token SWMTKN-1-XXX...XXX \
10.0.0.1:2377 \
--advertise-addr 10.0.0.4/5/6:2377 \
--listen-addr 10.0.0.4/5/6:2377
# 登录到mgr2 mgr3 使用包含管理节点token接入Swarm
$ docker swarm join \
--token SWMTKN-1-XXX...XXX \
10.0.0.1:2377 \
--advertise-addr 10.0.0.2/3:2377 \
--listen-addr 10.0.0.2/3:2377
主从方式的多管理节点的HA,仅有一个管理节点处于活动状态(leader)。
# 创建服务
$ docker survice create --name web-fe \
-p 8080:8080 \
--replicas 5 \ --model global全局模式只有一个副本
nigelpoulton/xxxxxxxx
# 查看所有运行中的服务
$ docker survice ls
# 查看服务副本列表和状态
$ docker survice ps
# 详细信息
$ docker survice inspect -pretty web-fe
# 扩缩容
$ docker service scale web-fe=10
# 删除服务
$ docker service rm web-re
# 更新
$ docker service update
# 日志
$ docker service logs
Docker网络
# 网络配置信息
$ docker network inspect
# 遍历网络
$ docker network ls
# 创建新的单机桥接网络
$ docker network create -d bridge localhost
# Linux中查看系统网桥
$ brctl show
# 删除所有未使用的网络
$ docker network prune
# 删除指定网络
$ docker network rm
Docker网络架构源自一种叫做容器网络模型CNM的方案,该方案是开源的并且支持插接式连接。
Docker网络架构由三个主要部分构成:CNM(设计标准,规定了网络架构的基本组成要素)、Libnetwork(CNM的具体实现,通过Go语言实现)和驱动(通过实现特定网络拓扑的方式来拓展该模型的能力)。
CNM定义了三个基本要素:沙盒Sandbox(独立的网络栈,包括以太网接口、端口、路由表以及DNS配置)、终端Endpoint(虚拟网络接口,负责创建连接,将沙盒连接到网络,同时只能接入一个网络,若要同时接入多个网络,可以加入多个终端)和网络Network(802.1d网桥的软件实现,是需要交互的终端的集合)。
Docker覆盖网络
卷与持久化数据
持久化数据需要将数据存储在卷上,非持久化数据属于容器的一部分,与容器的生命周期一致。
非持久化数据存储目录:/var/lib/docker/<storage-driver>/
# 创建名为myvol的卷
$ docker volume create myvol
# 遍历/查看详情
$ docker volume ls
$ docker volume inspect
# docker运行时挂载卷
$ docker container run -idt --name voltainer \
--mount source=myvol,target=/vol \
alpine
# 删除卷
$ docker volume prune/rm
# 检查卷数据
$ ls -l /var/lib/docker/volumes/myvol/_data/
使用Docker Stack部署应用
Docker安全
Linux安全技术
内核命名空间(Namespace)
利用命名空间对OS进行拆分。
利用了内核命名空间:PID(进程ID)、网络(NET)、文件系统/挂载(MNT)、进程内通信(IPC)、用户(USER)、UTS。
控制组(Control Group)
用户通过控制组限制容器使用OS资源额度。
系统权限(Capability)
实现用户以root身份运行容器的同时,还能移除非必须的root能力。
强制访问控制(MAC)
用户根据需求配置合适策略
安全计算(Seccomp)
限制容器对宿主机内核发起系统调用。
Docker平台安全技术
Swarm模式
包含部分安全特性:
- 加密节点ID
- 基于TLS的认证机制
- 安全准入令牌
- 支持周期性证书自动更新的CA配置
- 加密集群网络
- 加密网络
Docker安全扫描
基于二进制代码级别的扫描,根据CVE进行检查生成报告。
Docker内容信任
检查Docker服务中拉取的镜像。
Docker密钥
# 管理密钥
$ docker secret