[TOC]
使用 Docker 镜像
下载镜像
# docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
# [Docker Registry地址]: 默认地址是Docker Hub
# <仓库名>: <用户名>/<软件名>, 如果不给出用户名,则默认为 library
docker pull mongo:3.2
docker pull --help
列出镜像
➜ ~ docker images
# 默认的 docker images 列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加-a参数。
➜ ~ docker images -a
# 列出部分镜像
# --filter ,或者简写-f
# 这类无标签镜像也被称为 虚悬镜像(dangling image)
# 列出虚悬镜像
➜ ~ docker images -f dangling=true
# 想查看某个位置之前的镜像也可以,只需要把since换成before
docker images -f since=ubuntu
# 如果镜像构建时,定义了LABEL ,还可以通过LABEL来过滤
docker images -f label=com.example.version=0.1
构建镜像
docker build -t nginx:v3 .
# 直接用 Git repo 进行构建
docker build https://github.com/twang2218/gitlab-ce-zh.git
# 用给定的 tar 压缩包构建
# Docker 引擎会下载这个包,并自动解压缩,以其作为上下文,开始构建
docker build http://server/context.tar.gz
# 从标准输入中读取上下文压缩包进行构建
docker build - < context.tar.gz
删除本地镜像
# docker rmi [选项] <镜像1> [<镜像2> ...]
# 注意docker rm命令是删除容器
# 用 短ID 来删除镜像。
# docker images 默认列出的就已经是 短ID 了
# 一般取前3个字符以上,只要足够区分于别的镜像就可以了。
docker rmi 4a68
# 用镜像名,也就是<仓库名>:<标签> ,来删除镜像
docker rmi nginx:v3
# 使用 镜像摘要 删除镜像
docker images --digests
docker rmi node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228
# 删除所有仓库名为 redis 的镜像
docker rmi $(docker images -q redis)
# 删除虚悬镜像
docker rmi $(docker images -q -f dangling=true)
操作 Docker 容器
容器是独立运行的一个或一组应用,以及它们的运行态环境
虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用
启动容器
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
启动容器有两种方式:
- 一种是基于镜像新建一个容器并启动,
- 一种是将在终止 状态(stopped)的容器重新启动
# 基于镜像新建一个容器并启动
docker run ubuntu /bin/echo 'Hello world'
# run = create 容器+ start 容器
# -i 交互式操作,让容器的标准输入保持打开
# -t 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
docker run -t -i ubuntu /bin/bash
# 启动已终止容器
docker start e38f93a50fff
# 命令会将一个运行态的容器终止,然后再重新启动它
docker restart e38f93a50fff
# 后台(background)运行: -d
docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
# 使用 -d 参数启动后会返回一个唯一的 id,
# 也可以通过 docker ps 命令来查看容器信息
docker ps
# 在后台运行并不会把输出的结果(STDOUT)打印到宿主机上面
# (输出结果 可以用docker logs 查看)。
docker logs [container ID or NAMES]
注: 容器是否会长久运行,是和docker run指定的命令有关,和 -d 参数无关
终止容器
# 使用 docker stop 来终止一个运行中的容器
docker stop 9f4399508d4f
# 终止状态的容器可以用 docker ps -a 命令看到
docker ps -a
当Docker容器中指定的应用终结时,容器也自动终止
进入容器
# 进入容器进行操作, 有很多种方法,包括使用 docker attach 命令或 nsenter 工具等。
➜ ~ docker restart 9f4399508d4f
9f4399508d4f
➜ ~ docker attach 9f4399508d4f
hello world
hello world
# 当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。
# 当某个窗口因命令阻塞时,其他窗口也无法执行操作 了
导出和导入容器
# 导出容器
# 导出本地某个容器,可以使用docker export命令
docker export 9f4399508d4f > ubuntu.tar
# 导入容器快照
# 使用docker import从容器快照文件中再导入为镜像
cat ubuntu.tar | sudo docker import - test/ubuntu:v1.0
# docker images
# 也可以通过指定 URL 或者某个目录来导入
docker import http://example.com/exampleimage.tgz example/imagerepo
删除容器
# 使用docker rm来删除一个处于终止状态的容器
docker rm 9f4399508d4f
# 清理所有处于终止状态的容器
docker rm $(docker ps -a -q)
如果要删除一个运行中的容器,可以添加-f参数。Docker会发送SIGKILL信号给容器
访问仓库
Docker Hub
执行 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。
注册成功后,本地用户目录的 .dockercfg 中将保存用户的认证信息
通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地
在查找的时候通过 -s N 参数可以指定仅显示评价为N星以上的镜像
➜ ~ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 4857 [OK]
ansible/centos7-ansible Ansible on Centos7 118 [OK]
根据是否是官方提供,可将镜像资源分为两类。
一种是类似 centos 这样的基础镜像,被称为基础或根镜像。
这些基础镜像是由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
还有一种类型,比如 tianon/centos 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。
用户也可以在登录后通过 docker push 命令来将镜像推送到 Docker Hub
自动创建
自动创建允许用户通过 Docker Hub 指定跟踪一个目标网站(目前支持 GitHub 或 BitBucket)上的项目,一旦项目发生新的提交,则自动执行创建
要配置自动创建,包括如下的步骤:
- 创建并登录 Docker Hub,以及目标网站
- 在目标网站中连接帐户到 Docker Hub
- 在 Docker Hub 中 配置一个自动创建
- 选取一个目标网站中的项目(需要含 Dockerfile)和分支
- 指定 Dockerfile 的位置,并提交创建
私有仓库
docker-registry是官方提供的工具,可以用于构建私有的镜像仓库
容器运行 安装docker-registry
sudo docker run -d -p 5000:5000 registry
# 这将使用官方的 registry 镜像来启动本地的私有仓库
# 用户可以通过指定参数来配置私有仓库位置,例如配置镜像存储到 Amazon S3 服务。
$ sudo docker run \
-e SETTINGS_FLAVOR=s3 \
-e AWS_BUCKET=acme-docker \
-e STORAGE_PATH=/registry \
-e AWS_KEY=AKIAHSHB43HS3J92MXZ \
-e AWS_SECRET=xdDowwlK7TJajV1Y7EoOZrmuPEJlHYcNP2k4j49T \
-e SEARCH_BACKEND=sqlalchemy \
-p 5000:5000 \
registry
# 还可以指定本地路径(如 /home/user/registry-conf)下的配置文件
sudo docker run \
-d -p 5000:5000 \
-v /home/user/registry-conf:/registry-conf \
-e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml \
registry
本地安装
对于 Ubuntu 或 CentOS 等发行版,可以直接通过源安装
sudo apt-get install -y build-essential python-dev libevent-dev python-pip liblzma-dev
sudo pip install docker-registry
# 修改配置文件,主要修改 dev 模板段的 路径
cp config/config_sample.yml config/config.yml
# 启动 Web 服务
sudo gunicorn -c contrib/gunicorn.py docker_registry.wsgi:application
在私有仓库上传、下载、搜索镜像
使用 docker tag 来标记一个镜像,然后推送它到仓库
# docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
sudo docker tag ba58 192.168.7.26:5000/test
sudo docker push 192.168.7.26:5000/test
# 到另外一台机器去下载这个镜像
sudo docker pull 192.168.7.26:5000/test
使用网络
外部访问容器
# -p 指定端口映射
# -p 标记可以多次使用来绑定多个端口
# -P Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口
# ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
sudo docker run -d -p 5000:5000 training/webapp python app.py
sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
sudo docker run -d -P training/webapp python app.py
# 使用 docker ps 可以看到,本地主机的 32768 被映射到了容器的 5000 端口
sudo docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
42ec45ea0944 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32768->5000/tcp clever_mayer
# 查看映射端口配置
docker port clever_mayer 5000
0.0.0.0:32768
# 映射到指定地址的指定端口
sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
# 映射到指定地址的任意端口
sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
# 还可以使用 udp 标记来指定 udp 端口
sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
容器互联
# 使用 --name 标记可以为容器自定义命名
docker run -d --name db training/postgres
# 使用 --link 参数可以让容器之间安全的进行交互
# --link 参数的格式为 --link name:alias
# 其中name是要链接的容器的
# alias 是这个连接的别名
docker run --rm --name web --link db:db training/webapp
# 此时,db 容器和 web 容器建立互联关系
# 使用 docker ps 来查看容器的连接
# Docker 通过 2 种方式为容器公开连接信息
# 1. 环境变量 2. 更新 /etc/hosts 文件
➜ ~ docker run --rm --name web --link db:db training/webapp env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=73cdd64cd2e5
DB_PORT=tcp://172.17.0.2:5432
DB_PORT_5432_TCP=tcp://172.17.0.2:5432
DB_PORT_5432_TCP_ADDR=172.17.0.2
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_NAME=/web/db
DB_ENV_PG_VERSION=9.3
HOME=/root
# 其中 DB_ 开头的环境变量是供 web 容器连接 db 容器使用
注意: 容器的名称是唯一的
注意: --rm和-d参数不能同时使用
Docker Machine
Machine 项目主要由 Go 编写,用户可以在本地任意指定被 Machine管理的 Docker 主机,并对其进行操作。
Machine定位是“在本地或者云环境中创建 Docker主机(Create Docker hosts on your computer,on cloud providers,and inside your own data center.)”。
其基本功能包括:
- 在指定节点上安装Docker引擎,配置其为Docker主机
- 集中管理所有Docker主机
- 虚拟化平台
# Machine 连接不同类型的节点是通过不同驱动指定的,
# 启动一个全新的虚拟机,并安装 Docker引擎。
docker-machine create --driver=virtualbox vbox-instance
- 本地主机
这种驱动适合主机操作系统和 SSH 服务都已经安装好,需要对其安装 Docker引擎
# 注册一台 Docker 主机,命名为test
docker-machine create -d generic --generic-ip-address=10.0.100.102 --genericssh-user=user test
Docker Swarm
# 在192.168.205.10运行如下命令
docker swarm init --advertise-addr=192.168.205.10
# 在其它节点上运行如下命令
docker swarm join --token SWMTKN-1-43wefb0h66twxunqa1ad0w1cjaf3hnliv2n04biqq80tgnxw35-1v9jtk8m5iuhzccomeuvj5w0s 192.168.205.10:2377
# 在192.168.205.10运行如下命令
docker node ls
# 在192.168.205.10运行如下命令
docker service create --name demo busybox sh -c "while true;do sleep 3600;done"
# 在192.168.205.10运行如下命令
docker service scale demo=5
docker service ps demo
docker service rm demo
docker network create -d overlay demo
docker service create --name mysql \
--env MYSQL_ROOT_PASSWORD=root \
--env MYSQL_DATABASE=wordpress \
--mount type=volume,source=mysql-data,destination=/var/lib/mysql \
--network demo \
mysql
docker service create --name wordpress \
-p 80:80 \
--env WORDPRESS_DB_PASSWORD=root \
--env WORDPRESS_DB_HOST=mysql \
--network demo \
wordpress