Docker笔记

Docker基本介绍

Docker 是一个开源的应用容器引擎,基于Go 语言 并遵从Apache2.0协议开源。 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker的应用场景

  • Web应用的自动化打包和发布。
  • 自动化测试和持续集成、发布。
  • 在服务型环境中部署和调整数据库或其他的后台应用。
  • 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。

Docker的优点

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而Docker容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug并未在开发过程中被发现。而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现「这段代 码在我机器上没问题啊」这类问题。

持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。 使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration)系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment)系统进行自动部署。而且使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移

由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展

Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

Docker的一些名词术语

  • host 宿主机
  • image 镜像
  • container 容器
  • registry 仓库
  • deamon 守护进程
  • client 客户端

国内一些仓库

  • aliyun(需要登录)
  • daocloud
  • 时速云
  • 网易

Docker官方仓库

docker hub

Docker基本概念

Docker包括三个基本概念

  • 镜像(Image)
  • 容器(Container)
  • 仓库(Repository)

镜像是静态的、只读的文件,类似于面向对象编程中的类,docker镜像使用了分层存储的架构,构建时,前一层是后一层的基础,而后一层的所有改变只在该层发生作用,好处是可以对镜像进行更好的定制及复用,如使用dockerHub上下载构建好的镜像,然后根据自己的需求在该镜像基础上添加新的层,就可以定制自己的镜像。

容器是镜像运行时的实体,类似于面向对象编程中的对象,容器可以被创建、启动、停止、删除等。容器的实质是进程,而且容器有隔离的特性,容器之间是相互独立的,有属于自己的命名空间、自己的网络配置等。当每一个容器运行时,是以镜像为基础层在其上创建一层当前容器的存储层,这一层称为容器存储层,运行时他是可读写的。但是当销毁一个容器时,这一层的信息也会随着被销毁,所以容器存储层要保持无状态化,对该层的文件写入操作应该使用数据卷或者绑定宿主机目录,直接对宿主机(或网络存储)发生读写,其性能和稳定性更高。

仓库则是管理镜像的地方,可以将镜像提交到仓库,让其它用户也可以使用你的镜像,类似于管理镜像的github,docker的官方仓库是dockerHub

理解了这三个概念,就理解了Docker的整个生命周期。

Docker各种平台下的安装

1.unix & linux下安装

1
2
3
4
5
6
7
8
# Centos、Redhat
yum install -y docker
# Ubuntu、Debain
apt-get install -y docker
# 启动|关闭|重启
systemctl start|stop|restart docker
# 开机自启
systemctl enable docker

2.mac 系统安装

1
brew install docker

安装完成查看信息

1
2
3
4
5
# 查看docker信息
$ docker info
# 查看docker版本
$ docker version
# docker一般存储位置 /var/lib/docker/devicemapper/devicemapper/data

Docker基本操作

镜像基本操作

搜索镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查找镜像
docker search centos

# 从Docker仓库中获取镜像,不加标签默认latest
docker pull centos:latest

# 列出已经下载好的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest ed21b7a8aee9 12 days ago 127 MB
docker.io/php 7.2-fpm-alpine3.11 d9d4aaebe714 2 weeks ago 74.2 MB
docker.io/ubuntu 18.04 4e5021d210f6 3 weeks ago 64.2 MB
docker.io/centos latest 470671670cac 2 months ago 237 MB

删除镜像

1
2
3
4
5
6
7
8
9
# 删除镜像(可使用名称或镜像ID删除),只能删除没有容器运行的镜像,(增加-f为强制删除)
docker rmi docker.io/centos
docker rmi -f docker.io/centos

# 列出所有镜像ID
docker images -q

# 批量删除所有镜像
docker rmi (docker images -q)

过滤查询部分镜像

docker images会列出所有的顶层镜像,我们可以使用过滤器参数 --filter,或者简写 -f,用来查出部分镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查出某个指定的镜像
$ docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest ed21b7a8aee9 12 days ago 127 MB

# 查出本地仓库在ubuntu:18.04之后构建的镜像,使用since表示之后,之前可以使用before表示
$ docker images -f since=ubuntu:18.04
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest ed21b7a8aee9 12 days ago 127 MB
docker.io/php 7.2-fpm-alpine3.11 d9d4aaebe714 2 weeks ago 74.2 MB

# 自定义格式显示,使用--format参数,比如我们只想看镜像的ID、仓库名称及标签信息,需要使用GO的模板语法
$ docker images --format "{{.ID}} : {{.Repository}} : {{.Tag}}"
ed21b7a8aee9 : docker.io/nginx : latest
d9d4aaebe714 : docker.io/php : 7.2-fpm-alpine3.11
4e5021d210f6 : docker.io/ubuntu : 18.04

保存及导入镜像

1
2
3
4
5
6

# 将镜像保存成 tar 归档文件。
docker save -o testNginx.tar nginx:latest

# 将归档文件导入为镜像
docker load -i testNginx.tar

容器基本操作

运行容器

  • docker run 创建并运行一个容器的主要命令
  • -i 进行交互模式
  • -t 分配一个伪终端(tty)
  • -d 容器以守护进程运行
  • --name 为容器命名
  • /bin/bash 使用shell
  • -p : 是容器内部端口绑定到指定的主机端口。
  • -P :是容器内部端口映射到主机的随机端口。
1
2
3
4
5
6
# 创建并运行一个nginx容器,将容器内80端口映射到宿主机8080端口,容器命名为myNginx,并启动一个`/bin/bash`终端进行交互
$ docker run -it -p 8080:80 --name myNginx1 nginx:latest /bin/bash
root@400f555a8234:/#

# 创建一个容器但不运行它
docker create --name testNginx nginx:latest

当使用docker run创建容器时,后台的标准操作为:

  • 检查本地是否存在指定镜像,不存在则去公有仓库下载
  • 使用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读可写层
  • 从宿主机主机配置的桥接接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个ip地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

查看容器

1
2
3
4
# 查看运行中的容器,查看所有容器使用 -a 参数
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d66658ac8a18 nginx "/bin/bash" About an hour ago Up 49 minutes 80/tcp myNginx

操作容器状态

1
2
3
4
5
6
7
8
9
# 停止一个容器,myNginx为容器名称,也可使用容器ID
docker stop myNginx
docker kill myNginx

# 启动一个停止的容器
docker start myNginx

# 重启一个容器
docker restart myNginx

删除容器

1
2
# 删除一个停止的容器,加 -f 表示强制删除,可以删除正在运行的容器
docker rm myNginx

查看容器信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看容器中运行的进程信息
$ docker top myNginx
UID PID PPID C STIME TTY TIME CMD
root 9227 9208 0 16:46 ? 00:00:00 nginx: master process nginx -g daemon off;
101 9248 9227 0 16:46 ? 00:00:00 nginx: worker process

# 查看容器端口映射
$ docker port myNginx
80/tcp -> 0.0.0.0:8081

# 查看容器或者镜像的详细信息
docker inspect myNginx
docker inspect nginx:latest

# 输出指定容器日志信息
docker logs myNginx

进入与退出容器

1
2
3
4
5
6
7
8
9
10
# 退出容器回到宿主机(两种方式)
exit # 等同于使用快捷键ctrl+d,如容器没有使用守护进程,退出后容器也停止
ctrl+p+q # 退出不停止容器

# 进入容器(两种方式)
docker attach myNginx
docker exec -it myNginx /bin/bash
# 两者区别
# attach 直接进入容器启动命令的终端,不会启动新的进程,当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作。
# exec 是在容器打开新的终端,并且可以启动新的进程

导入导出容器快照

1
2
3
4
5
# 导出容器快照
docker export myNginx > myNginx.tar

# 导入容器快照
docker import myNginx.tar test_nginx #注意导入后镜像名称必须全部为小写

参考文献