Docker初步了解
简介
什么是docker
Docker从狭义上来讲就是一个进程,从广义上来讲是一个虚拟容器,其实更专业的叫法是应用容器( Application Container ),Docker进程和普通的进程没有任何区别,它就是一个普通的应用进程。不过是用来操作镜像文件的。所以Docker进程+构建的应用镜像文件就等于Docker容器。
docker images
Docker containers
Docker生命周期
1、 开发构建镜像并将镜像push到Docker仓库
2、 测试或者运维从Docker仓库拷贝一份镜像到本地
3、 通过镜像文件开启Docker容器并提供服务
docker 的作用
- 构建容易分发简单
- 隔离应用解除依赖
- 快速部署测完就销
docker 与虚拟机的区别
docker架构
- namespaces充当隔离的第一级,是对Docker容器进行隔离,让容器拥有独立的hostname,ip,pid,同时确保一个容器中运行一个进程而且不能看到或影响容器外的其它进程;
- Cgroups是容器对使用的宿主机资源进行核算并限制的关键功能。比如CPU,内存,磁盘等;
- union FS主要是对镜像也就是image这一块作支持,采用copy-on-write技术,让大家可以共用某一层,对于某些差异层的话就可以在差异的内存存储;
- Libcontainer是一个库,是对上面这三项技术做一个封装。
- Docker engine 用来控制容器container的运行,以及镜像文件的拉取。
安装
该安装针对Ubuntu18.06LTS系统
卸载旧版本
旧版本的 Docker 称为docker或者docker-engine,使用以下命令卸载旧版本:
1 |
|
使用APT安装
由于 apt 源使用 HTTPS以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。
1 |
|
鉴于国内网络问题,强烈建议使用国内源,官方源请在注释中查看。为了确认所下载软件包的合法性,需要添加软件源的 GPG 密钥。
1 |
|
然后,我们需要向 source.list 中添加 Docker 软件源
1 |
|
以上命令会添加稳定版本的 Docker CE APT镜像源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。
安装 Docker CE
更新 apt 软件包缓存,并安装 docker-ce:
1 |
|
启动Docker CE
1 |
|
建立 docker 用户组
默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。
建立 docker 组:
1 |
|
将当前用户加入 docker 组:
1 |
|
退出当前终端并重新登录,进行如下测试。
测试 Docker 是否安装正确
1 |
|
镜像加速
国内从 Docker Hub拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
1.Docker 官方提供的中国 registry mirror https://registry.docker-cn.com
2.七牛云加速器 https://reg-mirror.qiniu.com/
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
1 |
|
检测加速器是否生效
1 |
|
docker info
的时候会抛出异常,vim/etc/default/grub
找到GRUB_CMDLINE_LINUX=""
,在双引号里面输入cgroup_enable=memory swapaccount=1
,然后执行: sudo update-grub
,reboot
搞定。
镜像
获取镜像
1 |
|
运行
1 |
|
列出镜像
1 |
|
虚悬镜像
镜像既没有仓库名,也没有标签,均为
这类无标签镜像也被称为 ==虚悬镜像(dangling image)== ,可以用下面的命令专门显示这类镜像:
1 |
|
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
1 |
|
列出部分镜像
1 |
|
以特定格式显示镜像
删除本地镜像
1 |
|
Dockerfile定制镜像
1 |
|
镜像构建上下文
docker运行原理
Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计。
docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。
实际上 Dockerfile 的文件名并不要求必须为 Dockerfile,而且并不要求必须位于上下文目录中,比如可以用 -f ../Dockerfile.php 参数指定某个文件作为 Dockerfile。
当然,一般大家习惯性的会使用默认的文件名 Dockerfile,以及会将其置于镜像构建上下文目录中。
其他docker bulid构建方式
1 |
|
Dockerfile 指令
1 |
|
容器
新建并启动
1 |
|
当用docker run 创建一个容器的时候,Docker在后台运行的标准操作包括:
- 检查本地是否存在指定镜像,不存在就从共有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层面挂载一层可读写层。
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池中分配一个ip地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
启动已经终止的容器
1 |
|
容器后台运行
1 |
|
终止容器
1 |
|
重启容器
1 |
|
进入容器
docker进入一个后台运行的容器有两种方式
docker attach 命令
docker attach是Docker 自带的命令。 如果从容器的stdin中退出的话,该容器会停止。
exec (推荐)
用该命令进入stdin中的然后exit,容器不会停止
1 |
|
导入容器快照
1 |
|
导出容器快照
1 |
|
删除容器
1 |
|
清理所有处于终止状态的容器
1 |
|
Docker Compose 编排
通过单独的docker-compose.yml模板文件(YAML格式)定义一组相关联的应用容器为一个项目。
compose中有两个重要的概念:
- 服务(service):一个应用的容器,实际上可以包括若干个运行相同镜像的容器实例。
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compser.yml文件中定义。
安装
1 |
|
docker-compose.yml 属性详解
一份标准的配置文件包括version、services、networks三大部分,其中最关键的是services和networks两个部分。
1 |
|
version
docker-compose.yml语法版本.单引号和双引号都行。
Compose区分Version 1和Version 2,还有version 3。Version 1将来会被弃用。
版本1指的是忽略version关键字的版本;版本2必须在行首添加version: ‘2’。
Version 1
未声明版本的组合文件被视为“版本1”。
在这些文件中,所有服务都在文档的根目录处声明。
版本1由Compose到1.6.x支持。 它将在未来的Compose版本中被弃用。
版本1文件无法声明命名卷,网络或构建参数。
Version 2
使用版本2语法的撰写文件必须指示文档根目录下的版本号。 所有服务必须在服务键下声明。
Compose 1.6.0+支持版本2文件,并需要版本1.10.0+的Docker引擎。
可以在volumes键下声明命名卷,并且可以在networks关键字下声明网络。
services
image
1
2
3services:
web:
images: hello-world在services标签下的第二级标签是web,这个是自己定义的,指的是服务的名称。
image是指定的服务镜像的名称或者镜像id,如果本地不存在,compose会尝试pull这个镜像.支持下面写法。1
2
3
4
5image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fdbulid
服务除了可以基于指定的镜像,还可以基于一份 Dockerfile,在使用 up 启动之时执行构建任务,这个构建标签就是 build,它可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。
如果你同时指定了 image 和 build 两个标签,那么 Compose 会构建镜像并且把镜像命名为 image 后面的那个名字。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18build: /path/to/build/dir
#也可以是相对路径
build: ./dir
#设定上下文根目录,然后以该目录为准指定 Dockerfile。
build:
context: ../
dockerfile: path/of/Dockerfile
# 指定环境变量 (该环境变量是构建时候的环境变量)
build:
context: .
args:
- buildno=1
- password=secret
# 允许空值
args:
- buildno
- password注意:YAML 的布尔值(true, false, yes, no, on, off)必须要使用引号引起来(单引号、双引号均可),否则会当成字符串解析。
command
使用 command 可以覆盖容器启动后默认执行的命令。1
2
3command: bundle exec thin -p 3000
#或者
command: [bundle, exec, thin, -p, 3000]container_name
指定容器名称1
container_name: app
depends_on
解决了容器的依赖、启动先后的问题。1
2
3
4
5
6
7
8
9
10
11
12
13
14# 该服务先启动db和redis服务 最后才启动web服务
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
# 默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。dns
配置 dns 服务器1
2
3
4
5
6
7
8
9
10dns: 8.8.8.8
#或者
dns:
- 8.8.8.8
- 9.9.9.9
#dns_search 的配置也类似 dns_search 配置 DNS 搜索域
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.comtmpls
挂载临时目录到容器内部,与 run 的参数一样效果:1
2
3
4tmpfs: /run
tmpfs:
- /run
- /tmpentrypoint
用于指定接入点1
2
3
4
5
6
7
8
9entrypoint: /code/entrypoint.sh
#或者
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunitenv_file
专门存放变量的文件(这个环境变量是对宿主compose而言,如果在配置文件中有 build 操作,这些变量并不会进入构建过程中,如果要在构建中使用变量还是首选arg标签).1
2
3
4
5
6env_file: .env
# 或者
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.envenvironment
该标签的作用是设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置。
一般 arg 标签的变量仅用在构建过程中。而 environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。1
2
3
4
5
6
7
8
9environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRETexpose
与Dockerfile中的EXPOSE指令一样,用于指定暴露的端口,但是只是作为一种参考,实际上docker-compose.yml的端口映射还得ports这样的标签。1
2
3expose:
- "3000"
- "8000"external_links
在使用docker时,会有许多单独使用docker run启动的容器,为了使Compose能够连接这些不在docker-compose.yml中定义的容器,需要一个特殊的标签,就是external_links,它可以让Compose项目里面的容器连接到那些项目配置外部的容器(前提是外部容器中必须至少有一个容器是连接到与项目内的服务的同一个网络里面)。1
2
3
4external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresqlextra_hosts
添加主机名的标签,就是往/etc/hosts文件中添加一些记录,与Docker client的–add-host类似:1
2
3
4
5
6extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
// 启动之后查看容器内部hosts:
162.242.195.82 somehost
50.31.209.229 otherhostlabels
向容器添加元数据,和Dockerfile的LABEL指令一个意思:1
2
3
4
5
6
7
8labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"links
解决的是容器连接问题,与Docker client的–link一样效果,会连接到其它服务中的容器。
1 |
|
- ports
映射端口的标签。1
2
3
4
5ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001" - volumes
挂载一个目录或者一个已存在的数据卷容器.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18volumes:
// 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
- /var/lib/mysql
// 使用绝对路径挂载数据卷
- /opt/data:/var/lib/mysql
// 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
- ./cache:/tmp/cache
// 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
// 已经存在的命名的数据卷。
- datavolume:/var/lib/mysql
//如果你不使用宿主机的路径,你可以指定一个volume_driver。
volume_driver: mydriver - restart
默认值为 no ,即在任何情况下都不会重新启动容器;当值为 always 时,容器总是重新启动;当值为 on-failure 时,当出现 on-failure 报错容器退出时,容器重新启动。1
2
3
4restart: "no" //默认
restart: always //总是重新启动
restart: on-failure
restart: unless-stopped
docker composer安装包
1 |
|