容器化
时代演进
-
物理机时代
- 多个程序在一台机器上运行
-
虚拟机时代
- 一台物理机安装多个虚拟机(VM),一个虚拟机跑多个程序。
-
容器化时代
- 一台物理机安装多个容器实例(container),一个容器跑多个程序。
容器化解决了“环境”的问题。
它将软件程序和运行的基础环境分开。开发人员编码完成后将程序打包到一个容器镜像中,镜像中详细列出了所依赖的环境,在不同的容器中运行标准化的镜像,从根本上解决了环境不一致的问题。
容器化特点
-
可移植性
- 不依赖具体的操作系统或云平台,比如在阿里云或腾讯云直接随意迁移。
-
占地小
- 容器只需要其应用程序以及它需要运行的所有容器和库的依赖清单,不需要将所有的依赖库都打包在一起。
-
共享bin和lib
- 不同的容器可以共享
bin和lib,进一步节省了空间。
- 不同的容器可以共享
Docker
2010年,dotCloud公司,开发了Docker的核心技术;
后来dotCloud公司将自己的容器技术进行了简化和标准化,取名为docker。
2013年dotCloud 公司宣布将 Docker 开源,随着越来越多的工程师发现了它的优点, Docker 的人气迅速攀升,成为当时最火爆的开源技术之一。
Docker怎么用
其实大多数人谈论 Docker 时说的是 Docker Engine,这只是一个构建和运行的容器。
在运行容器前需要编写Docker File,通过 dockerFile 生成镜像,然后才能运行 Docker 容器。
Docker File 定义了运行镜像(image)所需的所有内容,包括操作系统和软件安装位置。一般情况下都不需要从头开始编写 Docker File,在 Docker Hub 中有来自世界各地的工程师编写好的镜像,你可以基于此修改。
常用命令
镜像
-
查看镜像
docker images-
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE php 7-fpm f214b5c48a25 9 days ago 368MB redis 3.2 2fef532eadb3 11 days ago 76MB redis 4.0 e1a73233e3be 11 days ago 83.4MB cogset/cron latest c01d5ac6fc8a 15 months ago 125MB
-
镜像命名
username/repository:tag-
例如:
cogest/lets-encrypt:0.14.2
-
从镜像仓库获得image
docker pull-
# 通过镜像名 $ sudo docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu 124c757242f8: Downloading [==========================> ] 30.19MB/31.76MB 9d866f8bde2a: Download complete fa3f2f277e67: Download complete 398d32b153e8: Download complete afde35469481: Download complete # 完整镜像名 $ sudo docker pull openresty/openresty:1.13.6.2-alpine 1.13.6.2-alpine: Pulling from openresty/openresty ff3a5c916c92: Pull complete ede0a2a1012b: Pull complete 0e0a11843023: Pull complete 246b2c6f4992: Pull complete Digest: sha256:23ff32a1e7d5a10824ab44b24a0daf86c2df1426defe8b162d8376079a548bf2 Status: Downloaded newer image for openresty/openresty:1.13.6.2-alpine
-
获取image的详细信息
docker inspect-
$ sudo docker inspect redis:3.2 [ { "Id": "sha256:2fef532eadb328740479f93b4a1b7595d412b9105ca8face42d3245485c39ddc", "RepoTags": [ "redis:3.2" ], "RepoDigests": [ "redis@sha256:745bdd82bad441a666ee4c23adb7a4c8fac4b564a1c7ac4454aa81e91057d977" ], ## ...... } ] - 查看指定image
-
$ sudo docker inspect redis:4.0 $ sudo docker inspect 2fef532e
-
删除镜像
docker rmi-
$ sudo docker rmi ubuntu:latest Untagged: ubuntu:latest Untagged: ubuntu@sha256:de774a3145f7ca4f0bd144c7d4ffb2931e06634f11529653b23eba85aef8e378 Deleted: sha256:cd6d8154f1e16e38493c3c2798977c5e142be5e5d41403ca89883840c6d51762 Deleted: sha256:2416e906f135eea2d08b4a8a8ae539328482eacb6cf39100f7c8f99e98a78d84 Deleted: sha256:7f8291c73f3ecc4dc9317076ad01a567dd44510e789242368cd061c709e0e36d Deleted: sha256:4b3d88bd6e729deea28b2390d1ddfdbfa3db603160a1129f06f85f26e7bcf4a2 Deleted: sha256:f51700a4e396a235cee37249ffc260cdbeb33268225eb8f7345970f5ae309312 Deleted: sha256:a30b835850bfd4c7e9495edf7085cedfad918219227c7157ff71e8afe2661f63 - 空格,删除多个镜像
-
$ sudo docker rmi redis:3.2 redis:4.0 Untagged: redis:3.2 Untagged: redis@sha256:745bdd82bad441a666ee4c23adb7a4c8fac4b564a1c7ac4454aa81e91057d977 Deleted: sha256:2fef532eadb328740479f93b4a1b7595d412b9105ca8face42d3245485c39ddc # # ...... Untagged: redis:4.0 Untagged: redis@sha256:b77926b30ca2f126431e4c2055efcf2891ebd4b4c4a86a53cf85ec3d4c98a4c9 Deleted: sha256:e1a73233e3beffea70442fc2cfae2c2bab0f657c3eebb3bdec1e84b6cc778b75 # # ......
容器
-
创建容器
docker create-
$ sudo docker create nginx:1.12 34f277e22be252b51d204acbb32ce21181df86520de0c337a835de6932ca06c3 docker create --name-
$ sudo docker create --name nginx nginx:1.12
-
启动容器
docker start-
$ sudo docker start nginx
-
创建+启动
docker run --name 容器名 -d/--detach(后台运行) 镜像名-
$ sudo docker run --name nginx -d nginx:1.12 89f2b769498a50f5c35a314ab82300ce9945cbb69da9cda4b022646125db8ca7
-
列出 Docker 中的容器
docker ps列出运行中的容器-
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89f2b769498a nginx:1.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp nginx docker ps -a列出所有的容器docker ps --all-
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 425a0d3cd18b redis:3.2 "docker-entrypoint.s…" 2 minutes ago Created redis 89f2b769498a nginx:1.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp nginx
-
停止容器
docker stop-
$ sudo docker stop nginx
-
删除容器
docker rm-
$ sudo docker rm nginx
-
控制容器让其运行给出的命令
docker exec-
让nginx容器运行more命令
-
$ sudo docker exec nginx more /etc/hostname :::::::::::::: /etc/hostname :::::::::::::: 83821ea220ed -
-i/--interactive保持输入流-t`` / ``--tty启动一个伪终端二者可以合并为
-it,以交互模式运行容器 -
$ sudo docker exec -it nginx bash root@83821ea220ed:/#
-
衔接到容器
docker attach用于将当前的输入输出流连接到指定的容器上-
$ sudo docker attach nginx
网络
针对容器的网络配置
网络相关的命令,都是以
docker network开头
-
容器互联
docker create --linkdocker run --link-
$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql $ sudo docker run -d --name webapp --link mysql webapp:latest - 通过别名连接
-
$ sudo docker run -d --name webapp --link mysql:database webapp:latest
-
暴露端口
--expose-
在创建时使用
-
$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7 -
暴露了13306和23306端口
-
查看网络信息
- 使用
docker inspect
- 使用
-
创建网络
docker network create-d:为新的网络指定驱动的类型-
默认是
Bridge Driver -
$ sudo docker network create -d bridge individual
-
在创建容器时,直接指定容器所加入的网络
-
不同网络之间,不能进行link
--network-
$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
-
-
查看已存在的网络
docker network lsdocker network list-
$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE bc14eb1da66b bridge bridge local 35c3ef1cc27d individual bridge local
-
端口映射
-
-p -
--publish -
-p <ip>:<host-port>:<container-port>- ip 是宿主操作系统的监听 ip,可以用来控制监听的网卡,默认为 0.0.0.0,也就是监听所有网卡。
- host-port 和 container-port 分别表示映射到宿主操作系统的端口和容器的端口。
-
这两者是可以不一样的。
我们可以将容器的 80 端口映射到宿主操作系统的 8080 端口,传入
-p 8080:80即可。
-
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc79fc5d42a6 nginx:1.12 "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx
-
文件
- 三种文件挂载方式
- Bind Mount 能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中,通过指定容器外的路径和容器内的路径,就可以形成挂载映射关系,在容器内外对文件的读写,都是相互可见的。
- Volume 也是从宿主操作系统中挂载目录到容器内,只不过这个挂载的目录由 Docker 进行管理,我们只需要指定容器内的目录,不需要关心具体挂载到了宿主操作系统中的哪里。
- Tmpfs Mount 支持挂载系统内存中的一部分到容器的文件系统里,不过由于内存和容器的特征,它的存储并不是持久的,其中的内容会随着容器的停止而消失。
-
挂载文件到容器
-v--volume--volume <host-path>:<container-path>-
把本机的
/webapp/html:/usr/share/nginx/html文件夹挂载到nginx中 -
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12 - 在挂载选项
-v后再接上:ro就可以只读挂载 -
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12
-
挂载临时文件
--tmpfs-
$ sudo docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
-
使用数据卷
-
数据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在 Docker 内部,接受 Docker 的管理。
- 使用
-v或--volume -
$ sudo docker run -d --name webapp -v /webapp/storage webapp:latest
-
-
命名数据卷
-v <name>:<container-path>-
$ sudo docker run -d --name webapp -v appdata:/webapp/storage webapp:latest -v在定义绑定挂载时必须使用绝对路径,其目的主要是为了避免与数据卷挂载中命名这种形式的冲突。
-
共用数据卷
- 多个容器挂载同一个数据卷
-
$ sudo docker run -d --name webapp -v html:/webapp/html webapp:latest $ sudo docker run -d --name nginx -v html:/usr/share/nginx/html:ro nginx:1.12
-
使用
docker volume操作数据卷 -
创建数据卷
docker volume create-
$ sudo docker volume create appdata
-
列出当前已经创建的数据卷
docker volume ls-
$ sudo docker volume ls DRIVER VOLUME NAME local html local appdata
-
删除数据卷
docker volume rm-
$ sudo docker volume rm appdata
-
删除容器关联的数据卷
docker rm -v-
$ sudo docker rm -v webapp
-
删除未被容器引用的数据卷
docker volume prune-
$ sudo docker volume prune -f Deleted Volumes: af6459286b5ce42bb5f205d0d323ac11ce8b8d9df4c65909ddc2feea7c3d1d53 0783665df434533f6b53afe3d9decfa791929570913c7aff10f302c17ed1a389 65b822e27d0be93d149304afb1515f8111344da9ea18adc3b3a34bddd2b243c7 ## ......
-
数据卷容器
定义一个或多个数据卷并持有它们的引用
-
创建数据卷容器
$sudo docker create --name appdata -v /webapp/storage ubuntu
-
引入数据卷容器
--volumes-from$sudo docker run -d --name webapp --volumes-from appdata webapp:latest
-
备份迁移数据卷
- 建立临时容器,将备份的目录和数据卷挂载到该容器上
-
以/back目录为例
-
$ sudo docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage tar cvf /backup/backup.tar /webapp/storage- 将数据打包
-
恢复数据卷
-
$ docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar xvf /backup/backup.tar -C /webapp/storage --strip - 解包
-