Docker 使用
Docker 是一个开源的应用容器引擎, 基于 Go 语言 并遵从 Apache2.0 协议开源.
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级, 可移植的容器中, 然后发布到任何流行的 Linux 机器上, 也可以实现虚拟化.
容器是完全使用沙箱机制, 相互之间不会有任何接口 (类似 iPhone 的 app), 更重要的是容器性能开销极低.
安装
Linux
- 卸载旧版本bash
$ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
- 安装依赖bash
$ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
- 设置仓库bash
# 官方 $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 或者选择 阿里源 # sudo yum-config-manager \ # --add-repo \ # http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装 Docker Engine-Communitybash
sudo yum install docker-ce docker-ce-cli containerd.io
默认安装的 docker-ce 是最新版, 如果想要安装其他版本的话可以:
- 先使用
yum list docker-ce --showduplicates | sort -r
命令找出所有可用版本 - 然后使用
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
安装具体版本
- 先使用
- 启动 Dockerbash
sudo systemctl start docker
- 运行 hello-world 来验证是否正确安装了 Docker Engine-Communitybash
sudo docker run hello-world
MacOS
brew cask install docker
命令使用
sudo service docker status
sudo service docker start
docker network
: 管理 docker 网络docker image
: 管理 docker 镜像docker container
: 管理 docker 容器
docker login
: 登录 docker 账户, 需在 Hub Docker 提前注册账户, 登录后能拉取账号下的所有镜像docker logout
:: 退出登录docker run [options] <id/name> [command]
: 运行一个镜像 (也是创建一个新的容器)-b
:-d
: 在后台运行-i
: 进入交互式操作-t
: 终端-v /minio/data:/mnt/data
: 将主机上的minio/data
目录挂载到容器内的/mnt/data
, 用于持久化存储数据-e "MINIO_CONFIG_ENV_FILE=/etc/config.env"
: 设置环境变量--name "minio_local"
: 指定容器名称为 minio_local-P
: 将容器内部使用的网络端口以 随机 方式映射到我们使用的主机上bash$ docker run -d -P training/webapp python app.py $ docker ps 2a8df02af645 training/webapp "python app.py" 2 hours ago Up 2 hours 0.0.0.0:32768->5000/tcp hanley
-p
: 将容器内部使用的网络端口 指定 映射到我们使用的主机上bash$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py $ docker ps 2e8a12599649 training/webapp "python app.py" 2 hours ago Up 2 hours 127.0.0.1:5001->5000/tcp kind_bassi
bashdocker run -i -t ubuntu:15.10 /bin/bash # 进入 ubuntun 的 15.10 版本镜像 (需提前 pull), 并指定 shell 为 /bin/bash, 并进入交互模式 docker run -itd --name ubuntu-hanley ubuntu:15.10 /bin/bash # 以后台, 终端, 交互式方式运行 ubuntu 这个镜像的 15.10 版本, 并将其命名为 ubuntu-hanley
exit
: 在既然怒容器后的环境中执行, 退出一个容器docker stop <id/name>
: 停止一个正在运行的容器docker start <id/name>
: 启动一个已停止的容器docker restart <id/name>
: 重启一个容器docker kill <id/name>
: 停止一个容器docker ps
: 查看当前正在运行的容器, 等价于docker container ls
, 如果需要列出所有的 (含已经被 exit 的) 容器需要使用docker ps -a
bash$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 31e46c0aad34 ubuntu "/bin/bash" 2 hours ago Up 2 hours test1 2e8a12599649 training/webapp "python app.py" 2 hours ago Up 2 hours 127.0.0.1:5001->5000/tcp kind_bassi $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 31e46c0aad34 ubuntu "/bin/bash" 2 hours ago Up 2 hours test1 2e8a12599649 training/webapp "python app.py" 2 hours ago Up 2 hours 127.0.0.1:5001->5000/tcp kind_bassi 62b13f6c9b2f training/webapp "python app.py" 2 hours ago Exited (137) 2 hours ago keen_jackson $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 31e46c0aad34 ubuntu "/bin/bash" 2 hours ago Up 2 hours test1
docker images
: 列出所有的位于本地的镜像docker attach <id/name>
: 运行容器使用-d
参数后会在后台运行, 使用attach
可以进入此容器docker exec
: 与 attach 类似, 但是在此命令下使用 exit 并不会导致容器停止运行, 因此这种方式更好.bashdocker exec -it
docker rm <id/name>
: 删除某个容器,docker rm -f 1e560fca3906
docker container ls -a
: 查看所有容器 (包括运行的与停止的, 等价于docker ps -a
)docker container prune
: 删除所有不在运行的容器docker rmi <image name>
: 删除某个镜像docker port <id/name>
: 查看某个容器的映射端口详情bash$ docker port 1e560fca3906 5000/tcp -> 0.0.0.0:5000 $ docker port wizardly_chandrasekhar 5000/tcp -> 0.0.0.0:5000
docker logs <id/name>
: 查看某个容器的内部标准输出,-f
像使用tail -f
一样来输出容器内部的标准输出docker top <id/name>
: 查看某个容器的内部运行的进程信息bash$docker top 1e560fca3906 UID PID PPID C STIME TTY TIME CMD root 14019 14002 0 May23? 00:00:01 python app.py
docker inspect <id/name>
: 查看容器的底层信息, 会返回一个 json 文件记录 docker 容器的配置与状态信息docker export <id/name> > <name>
: 导出一个容器快照到本地,docker export 1e560fca3906 > ubuntu.tar
docker import
: 从本地导入容器快照,cat docker/ubuntu.tar | docker import - test/ubuntu:v1
, 另外也可以通过指定 URL 或者某个目录来导入docker import http://example.com/exampleimage.tgz example/imagerepo
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
: 将容器的改变更新到镜像-a
: Author (e.g., “John Hannibal Smith hannibal@a-team.com”)-c
: Apply Dockerfile instruction to the created image-m
: Commit message-p
: Pause container during commit (default true)docker commit -m="has update" -a="hanleylee" e218edb10161 hanleylee/ubuntu:v2
docker tag <id/name> <new name>
: 为镜像添加一个新的标签,new name
格式为用户名 / 镜像名:tag
bash$ docker tag 860c279d2fec hanleylee/ubuntu:v3 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hanleylee/ubuntu 6.7 860c279d2fec 5 hours ago 190.6 MB hanleylee/ubuntu dev 860c279d2fec 5 hours ago 190.6 MB
docker rename
docker search <image name>
: 根据 name 搜索一个镜像docker pull <image name>
: 从远程仓库载入镜像,docker pull ubuntu
; 也可以指定版本:docker pull ubuntu:15.10
docker push <image name>
: 推送本地创建或更新的镜像到远程自己的仓库中,docker push hanlyelee/ubuntu:18.04
docker history
--help
: 使用帮助查看具体命令的使用,docker image --help
--name
: 以现有镜像创建自定义名称的容器,docker run -itd --name test1 --network test-net ubuntu /bin/bash
--network
: 以现有镜像创建使用自定义网络的容器
容器属性
使用 docker ps -a
可列出所有存在的容器
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8e7f63c63e6b ubuntu "/bin/bash" 2 hours ago Up 2 hours test2
31e46c0aad34 ubuntu "/bin/bash" 2 hours ago Up 2 hours test1
2a8df02af645 training/webapp "python app.py" 2 hours ago Up 2 hours 0.0.0.0:32768->5000/tcp hanley
2e8a12599649 training/webapp "python app.py" 2 hours ago Up 2 hours 127.0.0.1:5001->5000/tcp kind_bassi
dc33b04b866b training/webapp "python app.py" 2 hours ago Created cranky_hawking
62b13f6c9b2f training/webapp "python app.py" 2 hours ago Exited (137) 2 hours ago keen_jackson
容器有以下属性:
CONTAINER ID
: 容器 ID.IMAGE
: 使用的镜像.COMMAND
: 启动容器时运行的命令.CREATED
: 容器的创建时间.STATUS
: 容器状态.created
: 已创建restarting
: 重启中running
: 运行中removing
: 迁移中paused
: 暂停exited
: 停止dead
: 死亡
PORTS
: 容器的端口信息和使用的连接类型 (tcp\udp).NAMES
: 自动分配的容器名称.
镜像属性
使用 docker images
可列出所有存在的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB
php 5.6 f40e9e0f10c8 9 days ago 444.8 MB
nginx latest 6f8d099c3adc 12 days ago 182.7 MB
mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB
httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB
ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB
hello-world latest 690ed74de00f 6 months ago 960 B
training/webapp latest 6fae60ef3446 11 months ago 348.8 MB
镜像有以下属性:
REPOSITORY
: 表示镜像的仓库源TAG
: 镜像的标签在一个仓库源中, 可能有多个 tag, tag 不同则代表不同的版本, 表示不同的镜像, 哪怕两个镜像完全一致, 只有 tag 不一致, 那也是不同的镜像
IMAGE
ID: 镜像 IDCREATED
: 镜像创建时间SIZE
: 镜像大小
实际使用
更新镜像
$ docker run -t -i ubuntu:15.10 /bin/bash # 首先创建一个容器
root@e218edb10161 apt-get update # 更新此容器
root@e218edb10161 exit
$ docker commit -m="has update" -a="hanleylee" e218edb10161 hanleylee/ubuntu:v2 # 根据更新后的容器创建新镜像 hanleylee/ubuntu:v2
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hanleylee/ubuntu v2 70bf1840fd7c 15 seconds ago 158.5 MB
ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB
mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB
httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB
hello-world latest 690ed74de00f 6 months ago 960 B
training/webapp latest 6fae60ef3446 12 months ago 348.8 MB
容器互联
$ docker run -d -P --name hanley training/webapp python app.py
$ docker ps -l
CONTAINER ID IMAGE COMMAND... PORTS NAMES
43780a6eabaa training/webapp "python app.py"... 0.0.0.0:32769->5000/tcp hanley
$ docker network create -d bridge test-net # 创建网络, -d: 参数指定 Docker 网络类型, 有 bridge, overlay.
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash # 运行一个容器并连接到新建的 test-net 网络
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash # 打开新的终端, 再运行一个容器并加入到 test-net 网络
$ docker exec -it test1 /bin/bash
root@ed123dfvcxd: ping test2
64 bytes from test2. test-net...... # 正确接收到来自 test2 的信息
root@ed123dfvcxd: exit
$ docker exec -it test2 /bin/bash
root@1sdaf124232: ping test1
64 bytes from test1. test-net...... # 正确接收到来自 test1 的信息
获取容器创建时的参数
使用 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike <container_id>
ref: https://stackoverflow.com/a/32774347/11884593
docker-compose
Docker Compose 使用 YAML 格式的配置文件 docker-compose.yaml
, 该文件中定义了应用程序的各个组件, 每个组件对应的 Docker 镜像, 相应的服务, 网络等.
使用 Docker Compose 可以更加方便地在本地或生产环境中管理多个 Docker 容器. 通过定义 Compose 文件, 您可以轻松地启动, 停止, 重新构建, 扩展和升级整个应用程序的不同组件.
编写 Compose 文件
Docker Compose 使用 YAML 文件来定义应用程序的组件和它们之间的联系. 下面是一个使用 Docker Compose 启动 web 应用程序的样例文件:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
该文件定义了两个服务:
web
: Dockerfile 位于当前目录下, 端口映射为 5000.redis
: 使用 Redis 的官方 Docker 镜像, 并以 Alpine Linux 为基础镜像.
我们可以在 Compose 文件中定义其他组件, 例如数据库, 缓存服务器和消息队列等.
Compose 文件使用 YAML 格式定义应用程序的组件, 服务, 网络和卷等. 以下是 Compose 文件的一些常见选项:
version
: 指定 Compose 文件格式的版本.services
: 定义要启动的服务列表及每个服务的配置.image
: 指定要使用的 Docker 镜像名称. 如果不存在, 则自动从 Docker Hub 下载.build
: 指定 Dockerfile 的路径或 URL, 用于构建自定义 Docker 镜像.ports
: 指定端口映射规则, 将主机的端口映射到容器中的端口.volumes
: 指定挂载的卷目录, 将主机的目录和容器中的目录进行映射.restart
: 指定容器的自动启动策略cpus
: 指定容器最大可使用的 cpu 资源, 0.5 代表 0.5 个 cpu 核心environment
: 可指定多个环境变量
version: '3.3'
services:
qinglong_app:
image: whyour/qinglong:latest
container_name: qinglong
volumes:
- ./data:/ql/data
ports:
- "0.0.0.0:35700:5700"
environment:
# 部署路径非必须,以斜杠开头和结尾,比如 /test/
QlBaseUrl: '/'
restart: unless-stopped
cpus: 0.5
一些常用的 Docker Compose 命令
我们可以在包含 docker-compose.yaml
文件的目录下直接执行 docker-compose up -d
来创建并启动相关服务, 常用的 docker-compose
命令如下:
docker-compose up -d
: 创建并启动容器, 后台运行docker-compose down
: 停止并移除相关资源(会移除已创建的 container)docker-compose stop
: 停止所有服务docker-compose start
: 启动所有服务docker-compose restart
重启所有服务docker-compose build
: 构建 Compose 文件中定义的服务docker-compose build <service_name>
: 只构建 Compose 文件中的某个服务docker-compose up --build
: 重新构建服务并强制重新生成镜像docker-compose up --force-recreate --build
: 在需要升级服务时, 使用此命令强制重新构建并启动服务(将删除并重新创建所有容器)docker-compose -f docker-compose.yml up -d
参考
本博客文章采用 CC 4.0 协议,转载需注明出处和作者。