1- dokcer简介
1.1- 什么是容器
- 一种虚拟化方案
- 操作系统级别的虚拟化
- 只能运行相同或者相似内核的操作系统
- 依赖于linux内核特性: Namespace和Cgroups( Control Group)
1.2- 什么是docker
- 将应用程序自动部署到容器
- Go 语言开源引擎
- 基于Apache2.0开源协议发行
1.3- docker目标
- 提供简单轻量的建模方式-
- 职责与逻辑分离
- 快速高效的开发生命周期
- 鼓励使用面向服务的架构
1.4- 特点
- 高内聚,低耦合
- 避免同一容器内部不同服务之间的相互影响,出现问题也比较容易定位问题的所在。
【建议】:一个docker容器只运行一种应用程序或者服务
1.5- 使用场景
- 使用Docker容器开发、测试、部署服务
- 创建隔离的运行环境
- 搭建测试环境
- 构建多用户的平台即服务(PaaS)基础设施
- 提供软件即服务(SaaS)应用程序
- 高性能、超大规模的宿主机部署
2- Docker基本组成
- Docker Client #客户端
- Docker Daemon #守护进程
- Docker Image #镜像
- Docker Container #容器
- Docker Registry #仓库
2.1- Docker客户端/守护进程
- C/S架构
- 本地/远程
2.2- Docker Image镜像
- 容器的基石
- 层叠的只读文件系统
- 联合加载(union mount)
Bootfs: 在容器启动后,加载到内存中
Rootfs: 永远只读的基础镜像
特点: 各层永远只读。
2.3- Docker Container
- 通过镜像启动
- 在启动和执行阶段
- 写时复制(copy on write)
特点: 容器启动时,可写层为空,需要修改只读层时,先把只读层复制一份到可写层,然后在可写层修改。
2.4: Docker Registry 仓库
- 公用镜像(Docker hub等)
- 私有镜像
3- Docker实现原理
3.1- Docker依赖的linux内核特性
- Namespaces 命名空间
- Control groups (Cgroups) 控制组
3.1.1- Namespaces 命名空间
类似于编程语言的封装特性。 封装----->代码隔离
Linux namespace:为了实现轻量级虚拟化服务。
Docker使用了五种namespace:
- PID (Process ID) 进程隔离
- NET (Network) 管理网络接口
- IPC (InterProcess Communication) 管理跨进程通信的访问
- MNT (Mount) 管理挂载点
- UTS (Unix Timesharing System) 隔离内核和版本标识
以上隔离的资源通过cgroup管理起来
3.1.2- Cgroup
Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。最初由google的工程师提出,后来被整合进Linux内核。Cgroups也是LXC为实现虚拟化所使用的资源管理手段,可以说没有cgroups就没有LXC。
特点:
- 用来分配资源
- 来源于google
- Linux kernel 2.6.24@2007
- 为容器而生
作用:
- 资源限制
- 优先级设定
- 资源计量
- 资源控制
3.2- Docker容器的能力
Namespace和cgroup带给docker的能力:
- 文件系统隔离: 每个容器都有自己的root文件系统
- 进程隔离: 每个容器都运行在自己的进程环境中
- 网络隔离: 容器间的虚拟网络接口和IP地址都是分开的
- 资源隔离和分组: 使用cgroups将cpu和内存之类的资源独立分配给每个Docker容器
4- Docker服务
4.1- 服务模式
-
c/s模式
-
Remote API
- RESTfull 风格 API
- STDIN STDOUT STDERR
-
** socket**
总结:
- unix:///var/run/docker.sock #默认
- tpc://host:port
- fd://socketfd
4.2- 守护进程配置和操作
4.2.1- Docker启动选项
-d # 以守护进程方式
运行相关:
-D, --debug=false
-e, --exec-driver="native"
-g, graph="var/lib/docker"
--icc=true
-l, log-level="info"
--label=[]
-p, pidfile="var/run/docker.pid"
服务器连接相关:
-G, --group="docker"
-H, --host=[]
--tls=false
--tlscacert="/home/docker/.docker/ca.pem"
--tlscert="/home/docker/.docker/cert.pem"
--tlskey="/home/docker/.docker/key.pem"
--tlsverify=false
RemoteAPI相关:
--api-enable-cors=false
存储相关:
-S, --storage-driver=""
--selinux-enabled=false
--storage-opt=[]
Registry相关:
--insecure-registry=[]
--registry-mirror=[]
网络设置相关:
-b,--bridge=""
-bip=""
--fixed-cidr=""
--fixed-cidr-v6=""
--dns=[]
--dns-search=[]
--ip=0.0.0.0
--ip-forward=true
--ip-masq=true
--iptables=true
--ipv6=false
--mtu=0
4.2.2- 启动配置文件
/etc/defaule/docker
启动参数:
在DOCKER_OPT=""
里面增加参数。
默认端口: 2375
4.2.3- 使用环境变量远程访问docker服务
DOCKER_HOST
export DOCKER_HOST="tcp://10.0.0.1:2375"
#如需恢复默认: export DOCKER_HOST=""
5- 容器操作
5.1- 交互式容器
docker run -i -t IMAGES /bin/bash
-i, --interactive=true|false #默认是false
-t, --tty=true|false #默认是false
【PS】:交互式容器,退出tty后容器会停止。
docker start -i container_name|id #以默认交互的方式启动容器
docker rm container_name|id #删除已经停止的容器、 加-f, 强制删除容器
5.2- 守护式容器
- 能够长期运行
- 没有交互式回话
- 适合运行应用程序和服务
【ps】: 退出tty后不停止
5.2.1- 以守护式形式运行容器
docker run -i -t image /bin/bash
Ctrl+p | ctrl + q
# docker attach container_name|id 才能重新进入容器
或者:
docker -d #启动时不进入容器内部
# 此时进入容器 docker exec -it container_name|id bash|sh
5.2.2- 容器日志
docker logs [-f][-t][--tail] container_name|id
-f, --follows=true|false #默认false
-t, --timestamps=true|false #默认false
-tail="all"
【ps】: 不使用参数则默认返回所有日志。
5.2.3- 容器内进程
docker top container_name|id
5.2.4- 启动新进程
docker exec [-d][-i][-t] container_name [command][arg..]
docker exec container_name command #直接后台运行。不进入容器内部
5.2.5- 停止容器
docker stop container_name # 发送信号等待容器停止
docker kill container_name #直接停止容器
5.2.6- docker帮助文件
man docker-run
man docker-logs
man docker-top
man docker-exec
5.2.7- 容器端口映射
-p, --publish=[]
用法:
- containerPort # docker run -p 80 -i -t centos /bin/bash
- hostPort:containerPort # docker run -p 8080:80 -i -t centos /bin/bash
- ip::containerPort # docker run -p 0.0.0.0:80 -i -t centos /bin/bash
- ip:hostPort:containerPort # docker run -p 0.0.0.0:80 -it centos /bin/bash
【PS】: docker port container_name|id #查看已经映射的端口
5.3- 镜像
5.3.1- 镜像存放位置
docker info
Strorage Driver: aufs
**Root Dir : /var/lib/docker/aufs**
5.3.2- 镜像
docker images [OPTSIONS] [REPOSITORY]
-a,--all=false
-f --filter=[]
--no-trunc=false
-q, --quitet=false
5.3.3- 构建镜像
- docker commit //通过容器构建
- docker build //通过Dockerfile 文件构建
5.4- Dockerfile
FROM ubuntu
MAINTAINER Leman
RUN apt-get update
RUN apt-get install -y apache2
EXPOSE 80
5.4.1- run
每一个run就是一层只读镜像层,定义构建时内部执行的命令
5.4.2- CMD
运行容器时的默认命令。
- CMD ["command","param1","param2"] (exec模式)
- CMD command param1 param2 (shell 模式)
【ps】: 启动镜像时, doceker run 后面的命令会覆盖cmd的命令,但不会覆盖entrypoint的命令
5.4.3- ADD
- ADD
// src 可以是本地地址或者远程url文件 - ADD ["
" " ">] // 适用于文件路径中有空格的情况
5.4.4- copy
- copy
- copy ["
" " "]
5.4.5- add vs copy
ADD 包含类似tar的解压功能,如果是单纯复制文件,推荐使用copy
5.4.5- onbuild
镜像触发器:当一个镜像被其他镜像作为基础镜像执行时,会在构建过程中插入指令
5.4.6- 总结
Dockerfile所有命令:
CMD WORKDIR ENTERPOINT ENV ADD USER COPY
ONBUILD VOLUME FROM RUN EXPOSE MAINTAINER
5.5- Dockerfile构建过程
5.5.1- 构建过程
- 从基础镜像运行一个容器
- 执行一条指令。对容器做出修改
- 执行docker commit操作,提交一个新的镜像层
- 基于刚提交的镜像运行一个新的容器
- 执行Dockerfile 的下一条指令,直至所有指令执行完毕
简化说明:
- 利用base镜像运行一个容器1
- 这个容器1里面执行一个run,
- 容器1提交成一个镜像2
- 删除容器1
- 利用镜像2,运行容器2
- 容器2,执行下一个run
- 容器2提交成镜像3.删除容器2
- 依次类推,直到最后镜像
【ps】: 镜像2,3就称为中间层镜像,此时可使用中间层镜像进行调试,查找错误。
中间层镜像,会使用上一层镜像作为缓存(默认。
不使用缓存构建 docker build --no-cache
5.5.2- 查看构建过程
docker history [images]