Docker
概念
Docker是一种运行于 Linux 和 Windows 上的软件,用于创建、管理和编排容器。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker是CS架构,Docker的组成:
- Docker daemon: 运行在宿主机上,Docker守护进程,用户通过Docker client(Docker命令)与Docker daemon交互
- Docker client: Docker 命令行工具,是用户使用Docker的主要方式,Docker client与Docker daemon通信并将结果返回给用户,Docker client也可以通过socket或者RESTful api访问远程的Docker daemon
了解了Docker的组成,再来了解一下Docker的三个主要概念:
- Docker image:镜像是只读的,镜像中包含有需要运行的文件。镜像用来创建container,一个镜像可以运行多个container;镜像可以通过Dockerfile创建,也可以从Docker hub/registry上下载。
- Docker container:容器是Docker的运行组件,启动一个镜像就是一个容器,容器是一个隔离环境,多个容器之间不会相互影响,保证容器中的程序运行在一个相对安全的环境中。
- Docker hub/registry: 共享和管理Docker镜像,用户可以上传或者下载上面的镜像,官方地址为
https://registry.hub.docker.com/
,也可以搭建自己私有的Docker registry。注册服务器是存放仓库的地方,其上往往存放着多个仓库。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。例如存放Ubuntu操作系统镜像的仓库,称为Ubuntu仓库,其中可能包括14.04、12.04等不同版本的镜像。
镜像就相当于打包好的版本,镜像启动之后运行在容器中,仓库就是装存储镜像的地方。
镜像(image)是动态的容器的静态表示(specification),包括容器所要运行的应用代码以及运行时的配置。Docker 镜像包括一个或者多个只读层( read-only layers ),因此,镜像一旦被创建就再也不能被修改了。一个运行着的Docker 容器是一个镜像的实例( instantiation )。从同一个镜像中运行的容器包含有相同的应用代码和运行时依赖。但是不像镜像是静态的,每个运行着的容器都有一个可写层( writable layer ,也成为容器层 container layer),它位于底下的若干只读层之上。运行时的所有变化,包括对数据和文件的写和更新,都会保存在这个层中。因此,从同一个镜像运行的多个容器包含了不同的容器层。
Docker 有两种方式来创建一个容器镜像:
- 创建一个容器,运行若干命令,再使用 docker commit 来生成一个新的镜像。不建议使用这种方案。
- 创建一个 Dockerfile 然后再使用 docker build 来创建一个镜像。大多人会使用 Dockerfile 来创建镜像。
安装
使用wget命令来运行一个 Shell 脚本,完成 Docker CE 的安装。
$ curl -fsSL https://get.docker.com/ | sh
# daocloud.io 国内镜像
$ curl -sSL https://get.daocloud.io/docker | sh
该安装包适用于 Ubuntu,Debian,Centos 等大部分主流 Linux 发行版。
权限
当以普通用户身份去使用docker images
时,如果出现以下错误:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied
是因为权限问题:
$ sudo groupadd docker
$ sudo gpasswd -a ${USER} docker
$ sudo service docker restart
$ newgrp - docker
系统操作
查看Docker信息info
$ docker info
查看版本version
$ docker version
启动Dockerstart
service docker start
# 或者
systemctl start docker
修改配置daemon.json
配置docker镜像加速
$ vi /etc/docker/daemon.json
#添加后
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"live-restore": true
}
登录服务器 login
$ docker login [options] [server] # 登录到Docker registry服务器
$ docker login localhost:8080 # 登录自己主机的registry
登出服务器 logout
退出Docker镜像仓库
Usage: docker logout [SERVER]
镜像 image
搜索镜像 search
搜索官方仓库镜像
参数 | 说明 |
---|---|
NAME | 镜像名称 |
DESCRIPTION | 镜像说明 |
STARS | 点赞数量 |
OFFICIAL | 是否是官方的 |
AUTOMATED | 是否是自动构建的 |
$ docker search <image_name>
拉取镜像 pull
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Options:
-a 拉取某个镜像的所有版本
--disable-content-trust 跳过校验,默认开启
Docker 主机安装之后,本地并没有镜像。
如果本地没有某一镜像,我们可以使用 docker pull 命令来载入某一镜像
镜像从远程镜像仓库服务的仓库中下载。默认情况下,镜像会从 Docker Hub 的仓库中拉取。
$ docker pull <image_name> # 默认获取最新的
$ docker image pull alpine:latest # 从 Docker Hub 的 alpine 仓库中拉取标签为 latest 的镜像。
$ docker pull ubuntu:16.04
$ docker pull daocloud.io/library/ubuntu:16.04
# 下载镜像名称其实由三部分组成:daocloud.io/library/ubuntu:16.04
# 其中其中daocloud.io是注册服务器地址,默认是registry.hub.docker.com;ubuntu是仓库名,16.04是标签名,默认是latest。
查看镜像
Docker镜像保存在/var/lib/docker目录下中
- REPOSTITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
$ docker image ls # 查看本地所有镜像
$ docker images # 查看docker镜像
$ docker image inspect <image-name> # 查看详细信息
导出镜像 save
将一个或多个镜像保存为tar包
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Options:
-o, --output string tar包名称
$ docker save <image-name> > /opt/<image-name>.tar.gz # 导出docker镜像至本地
导入镜像 load
$ docker load < /opt/centos.tar.gz #导入本地镜像到docker镜像库
删除镜像 rmi
删除一个或多个镜像
Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
Options:
-f, --force 强制删除
$ docker image rmi <image-name>
$ docker rmi docker.io/tomcat:7.0.77-jre7
$ docker rmi b39c68b7af30
$ docker rm `docker ps -aq` # 一次性删除所有容器记录
$ docker rmi `docker images -aq` # 一次性删除所有本地的镜像记录
更新镜像 update
更新镜像之前,我们需要使用镜像来创建一个容器。
$ docker run -t -i ubuntu:15.10 /bin/bash
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时 ID 为 e218edb10161 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。
$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee9545aff8
各个参数说明:
- -m: 提交的描述信息
- -a: 指定镜像作者
- **e218edb10161:**容器 ID
- runoob/ubuntu:v2: 指定要创建的目标镜像名
构建镜像 build
通过 Dockerfile 构建镜像
Usage: docker build [OPTIONS] PATH | URL | -
Options:
-f, --file string 指定Dockerfile,默认为当前路径的Dockerfile
-q, --quiet 安静模式,构建成功后输出镜像ID
-t, --tag list 给镜像设置tag,name:tag
$ docker build
设置标签 tag
docker tag 镜像ID,这里是 860c279d2fec ,用户名称、镜像源名(repository name)和新的标签名(tag)。
$ docker tag 860c279d2fec runoob/centos:dev
提交镜像 commit
通过容器创建一个新镜像
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options:
-a, --author string 作者
-m, --message string 提交信息
上传镜像 push
将容器推送到镜像仓库
Usage: docker push [OPTIONS] NAME[:TAG]
容器 container
查看容器 ps
列出容器
Usage: docker ps [OPTIONS]
Options:
-a, --all 列出所有容器
-f, --filter filter 使用过滤器过滤
--format string 格式化输出
-n, --last int 显示最后创建的n个容器
-l, --latest 显示最后一个创建的容器
-q, --quiet 只显示容器ID
-s, --size 显示大小
$ docker ps # 正在运行的容器
$ docker ps -a # 所有容器
$ docker ps -l # 查看最近一次运行的容器
# CONTAINER ID: 容器 ID。
# IMAGE: 使用的镜像。
# COMMAND: 启动容器时运行的命令。
# CREATED: 容器的创建时间。
# STATUS: 容器状态。
# 状态有7种:
- created(已创建)
- restarting(重启中)
- running 或 Up(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
# PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
# NAMES: 自动分配的容器名称。
查看端口 port
$ docker port <container_name>/<image_name>
查看进程 top
$ docker top <image_name>
容器状态 stats
显示容器资源使用情况
Usage: docker stats [OPTIONS] [CONTAINER...]
Options:
-a, --all 显示所有容器,默认只显示正在运行的容器
容器信息 inspect
收集有关容器和镜像的底层信息
$ docker inspect <container_name>/<image_name> # 查看Docker的底层信息
# 返回一个 JSON 文件记录着 Docker 容器的配置和状态信息
$ docker inspect --format='{
{.State.Status}}' <image_name>
查看日志 logs
显示容器日志
Usage: docker logs [OPTIONS] CONTAINER
Options:
--details 显示详细日志
-f, --follow 跟随日志输出
--tail string 显示行数
-t, --timestamps 显示时间戳
在宿主主机内使用 docker logs 命令,查看容器内的标准输出
$ docker logs <container_name>/<container_id>
$ docker logs -f <container_name>/<container_id> # 不间断打印容器的日志信息
# -f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
创建容器 create
$ docker create --name web31 training/webapp python app.py #创建名字为 web31 的容器
运行容器 run
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Options:
-d, --detach 后台运行容器,并输出容器ID
-e, --env list 设置环境变量,该变量可以在容器内使用
-h, --hostname string 指定容器的hostname
-i, --interactive 以交互模式运行容器,通常与-t同时使用
-l, --label list 给容器添加标签
--name string 设置容器名称,否则会自动命名
--network string 将容器加入指定网络
-p, --publish list 设置容器映射端口
-P,--publish-all 将容器设置的所有exposed端口进行随机映射
--restart string 容器重启策略,默认为不重启
on-failure[:max-retries]:在容器非正常退出时重启,可以设置重启次数。
unless-stopped:总是重启,除非使用stop停止容器
always:总是重启
--rm 容器退出时则自动删除容器
-t, --tty 分配一个伪终端
-u, --user string 运行用户或者UID
-v, --volume list 数据挂载
-w, --workdir string 容器的工作目录
--privileged 给容器特权
$ docker run <image-name>
$ docker run -d -P centos /bin/sh -c "while true;do echo 正在运行; sleep 1;done" # 后台运行一个docker
# -d 后台运行容器 默认不会进入容器,想要进入容器需要使用指令 docker exec
# -P 将容器内部使用的网络端口随机映射到我们使用的主机上。
# -P 是容器内部端口随机映射到主机的高端口。
# -p 是容器内部端口绑定到指定的主机端口。
# Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。
# /bin/sh 指定使用centos的bash解释器
# -c 运行一段shell命令
# "while true;do echo 正在运行; sleep 1;done" 在linux后台,每秒中打印一次正在运行
$ docker run -d -p 5000:5000 training/webapp python app.py
# 容器内部的 5000 端口映射到我们本地主机的 5000 端口上
$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
# 指定容器绑定的网络地址,比如绑定 127.0.0.1
$ docker run --name mydocker -it centos /bin/bash # 启动一个bash终端,允许用户进行交互
# --name 给容器定义一个名称 可以无
# -i 让容器的标准输入保持打开
# -t 让Docker分配一个伪终端,并绑定到容器的标准输入上
# /bin/bash 指定docker容器,用shell解释器交互
当利用docker run来创建容器时,Docker在后台运行的步骤如下:
# 1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载
# 2. 利用镜像创建并启动一个容器
# 3. 分配一个文件系统,并在只读的镜像层外面挂在一层可读写层
# 4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
# 5. 从地址池配置一个ip地址给容器
# 6. 执行用户指定的应用程序
# 7. 执行完毕后容器被终止
启动容器 start
$ docker start <container_name>/<container_id>
交互界面 exec
向正在运行的容器下发命令
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Options:
-d, --detach 在后台运行命令
-e, --env list 设置环境变量
-i, --interactive 以交互模式运行
-t, --tty 分配一个伪终端
-u, --user string 执行命令的用户
-w, --workdir string 工作目录
$ docker exec -it <container_name>/<container_id> /bin/bash # 进入容器交互式界面
暂停容器 pause
$ docker pause <container_name>/<container_id>
继续容器 unpause
$ docker unpause <container_name>/<container_id>
重命名 rename
$ docker rename <old_name> <new_mame>
变化记录 diff
$ docker diff container
复制文件 cp
在容器和宿主机之间拷贝文件
Usage:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Options:
-a, --archive 保留文件权限
$ docker cp container:path hostpath # 从容器内复制文件到指定的路径上
停止容器 stop
$ docker stop <container_name>/