基本命令
## 列出 docker 命令
docker
docker container --help
## 显示 Docker 版本和信息
docker --version
docker version
docker info
## 运行Docker 镜像
docker run hello-world
## 列出 Docker 镜像
docker image ls
## 列出Docker容器(运行,全部,全部处于安静模式)
docker container ls
docker container ls --all
docker container ls -aq
docker build -t imagename . # 使用当前目录下的 Dockerfile 创建镜像
docker run -p 4000:80 imagename # 运行镜像,并映射端口4000到80
docker run -d -p 4000:80 friendlyhello # 后台运行
docker container ls # 列出所有正在运行的容器
docker container ls -a # 列出所有容器
docker container stop <hash> # 停止指定的容器
docker container kill <hash> # 强制关闭指定的容器
docker container rm <hash> # 删除指定的容器
docker container rm $(docker container ls -a -q) # 删除所有容器
docker image ls -a # 列出本机上的所有镜像
docker image rm <image id> # 删除指定的镜像
docker image rm $(docker image ls -a -q) # 删除所有镜像
docker login # 登录存储库 注册表
docker tag <image> username/repository:tag # 标记上传到存储库 注册表
docker push username/repository:tag # 推送到存储库 注册表
docker run username/repository:tag # 从 存储库 注册表 运行
测试Docker版本
- 运行
docker --version
查看您拥有的Docker版本:
$ sudo docker --version
Docker version 17.12.0-ce, build c97c6d6
- 运行
docker info
或docker version
查看有关docker的详细信息:
$ sudo docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: overlay2
...
- 要避免权限错误(以及使用
sudo
),请创建docker组并添加您的用户:
- 创建docker组。
$ sudo groupadd docker
- 将您的用户添加到该docker组。
$ sudo usermod -aG docker $USER
使用 Dockerfile 定义容器
Dockerfile 文件定义容器内的环境。对环境中的资源进行虚拟化,该环境与系统的其他部分隔离,并具体说明要“复制”哪些文件到那个环境。在执行此操作之后,您可以预期 Dockerfile 在此处定义构建的应用程序,在其它的任何位置构建都完全相同。
# Dockerfile
# 使用官方 Python 运行时作为父镜像
FROM python:3.6
# 将工作目录设置为 /app
WORKDIR /app
# 将当前目录内容复制到容器中 /app
COPY . /app
# 安装 requirements.txt 中指定的所需包
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 使 80 端口对外开放
EXPOSE 80
# 设置代理服务器,将host:port替换为服务器的值
ENV http_proxy host:port
ENV https_proxy host:port
# 定义环境变量
ENV NAME World
# 在容器启动时运行app.py
CMD ["python", "app.py"]
构建应用程序
在 Dockerfile 文件所在目录下,运行build命令。将创建一个 Docker 镜像,使用 --tag 选项命名(-t,短选项)。构建的镜像在本地 Docker 镜像注册表中:
$ sudo docker build --tag=imagename . # 最后面有个点,从当前目录构建
$ sudo docker image ls # 查看镜像
运行应用程序
运行应用程序,使用 -p 选项将计算机的端口4000映射到容器的端口80:
$ sudo docker run -p 4000:80 imagename
$ sudo docker run -d -p 4000:80 imagename # -d 选项为后台运行
使用 Docker Hub
如果没有 Docker 帐户,请在hub.docker.com 注册 。记下用户名。
- 登录本地的 Docker 公共注册表
$ sudo docker login
- 标记镜像
将本地镜像与注册表上的存储库相关联的表示法是 username/repository:tag。标签是可选的,但建议使用,因为它是注册管理机构用来为 Docker 镜像提供版本的机制。
把本地镜像与存储库关联标记,以便将图像推送到所需的目标位置:
$ sudo docker tag imagename username/repository:tag
$ sudo docker image ls # 查看镜像
- 发布镜像
将标记的镜像上传到 Docker Hub 存储库:
$ sudo docker push username/repository:tag
完成后,上传的存储库是公开的。登录到 Docker Hub,会看到其中的镜像及 pull 命令。
- 从 Docker Hub 存储库中拉取并运行镜像
可以使用 docker run 命令在任何地方使用和运行应用程序:
docker run -p 4000:80 username/repository:tag
如果镜像在本地不可用,则会从存储库中提取映像。
搭建应用服务集群
编写一个 docker-compose.yml 文件
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:
该 docker-compose.yml 文件告诉 Docker 执行以下操作:
- 从注册表拉取镜像。
- 将该镜像的5个实例作为调用的服务运行web应用,限制每个实例使用最多10%的CPU(跨所有内核)和50MB的RAM。
- 如果一个实例失败,立即重启容器。
- 将主机上的端口4000映射到web端口80。
- 指示web容器通过称为负载均衡的网络共享端口80
- webnet 使用默认设置(负载均衡的覆盖网络)定义网络。
了解Swarm集群
是一组运行 Docker 并加入集群的计算机。在此之后,您继续运行您习惯使用的 Docker 命令,但现在它们由群集管理器在集群上执行。集群中的机器可以是物理的或虚拟的。加入群组后,它们被称为节点。Swarm管理器可以使用多种策略来运行容器。指示swarm管理器在Compose文件中使用这些策略,就像您已经使用的那样。
群集管理器是群中唯一可以执行命令的机器,或者授权其他机器作为工作者加入集群。工人只是在那里提供能力,没有权力告诉任何其他机器它能做什么和不能做什么。
运行docker swarm init以启用swarm模式并使当前计算机成为一个swarm管理器,然后docker swarm join在其他计算机上运行 以使它们作为worker加入swarm。
初始化集群管理
$ sudo docker swarm init
运行新的负载均衡应用
$ sudo docker stack deploy -c docker-compose.yml getstartedlab # 为应用程序命名
其它命令
docker stack ls # 列出应用程序
docker stack deploy -c <composefile> <appname> # 运行指定的Compose文件
docker service ls # 列出与应用程序关联的运行服务
docker service ps <service> # 列出与应用关联的任务
docker inspect <task or container> # 检查任务或容器
docker container ls -q # 列出容器ID
docker stack rm <appname> # 停止应用程序
docker swarm leave --force # 从管理器中删除单个节点群
设置集群
现在,使用VirtualBox创建几个VM , 并获取虚拟机其IP地址:
machine01$ ifconfig
192.168.1.27
machine02$ ifconfig
192.168.1.28
初始化SWARM并添加节点
第一台机器充当管理器,它执行管理命令并验证工人加入群,第二台是工人。
machine01$ sudo docker swarm init --advertise-addr 192.168.1.27
Swarm initialized: current node <node ID> is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token <token> <myvm ip>:<port>
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
将第二台机器加入集群:
复制此命令 docker swarm join --token <token> <myvm ip>:<port>
,在要添加的任何节点上运行该命令。
machine02$ sudo docker swarm join --token <token> <myvm ip>:<port>
This node joined a swarm as a worker.
恭喜,你已经创建了一个群!
在管理器上运行以查看此群中的节点:
machine01$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
brtu9urxwfd5j0zrmkubhpkbd machine02 Ready Active
rihwohkh3ph38fhillhhb84sk * machine01 Ready Active Leader
在swarm管理器上部署应用程序
运行以下命令以部署应用程序:
machine01$ sudo docker stack deploy -c docker-compose.yml hellolab
服务(和相关容器)已经在所有节点之间分布:
machine01$ docker stack ps hellolab
ID NAME IMAGE NODE DESIRED STATE
jq2g3qp8nzwx hellolab_web.1 hello:part2 machine01 Running
88wgshobzoxl hellolab_web.2 hello:part2 machine02 Running
vbb1qbkb0o2z hellolab_web.3 hello:part2 machine02 Running
ghii74p9budx hellolab_web.4 hello:part2 machine01 Running
现在可以从所有节点的IP地址来访问应用程序。
其它命令
docker-machine create --driver virtualbox myvm1 # 创建一个VM
docker-machine env myvm1 # 查看有关节点的基本信息
docker-machine ssh myvm1 "docker node ls" # 列出swarm中的节点
docker-machine ssh myvm1 "docker node inspect <node ID>" # 检查节点
docker-machine ssh myvm1 "docker swarm join-token -q worker" # 查看连接令牌
docker-machine ssh myvm1 # 打开与VM的SSH会话; 输入“exit”结束
docker node ls # 查看swarm中的节点
docker-machine ssh myvm2 "docker swarm leave" # 离开群
docker-machine ssh myvm1 "docker swarm leave -f" # 杀死群
docker-machine ls # 列出虚拟机,星号显示此shell正在与之通信的虚拟机
docker-machine start myvm1 # 启动当前未运行的VM
docker-machine env myvm1 # 显示myvm1的环境变量和命令
eval $(docker-machine env myvm1) # 命令将shell连接到myvm1
docker stack deploy -c <file> <app> # 部署应用程序;使用本地Compose文件
docker-machine scp docker-compose.yml myvm1:~ # 将文件复制到节点的主目录
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # 使用ssh部署应用程序
eval $(docker-machine env -u) # 从VM断开shell,使用本机docker
docker-machine stop $(docker-machine ls -q) # 停止所有正在运行的VM
docker-machine rm $(docker-machine ls -q) # 删除所有虚拟机及其磁盘映像
堆栈。
堆栈是一组相互关联的服务,它们共享依赖关系,并且可以协调和缩放在一起。单个堆栈能够定义和协调整个应用程序的功能。
添加新服务并重新部署
将服务添加到 docker-compose.yml 文件很容易。
添加一个免费的可视化服务,看看swarm如何调度容器。
- 编辑 docker-compose.yml 用以下内容替换其内容。
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "80:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
networks:
webnet:
这里唯一新的是对等服务web,名为visualizer。注意这里有两个新东西:一个volumes键,让可视化工具访问Docker的主机套接字文件,以及一个placement密钥,确保这个服务只能在一个swarm管理器上运行。
更新需要更新的任何服务:
machine01$ sudo docker stack deploy -c docker-compose.yml hellolab
Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
Creating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
看看可视化工具。
在 Compose 文件中看到 visualizer 在端口8080上运行。通过其中一个节点转到端口8080的IP地址,您可以看到运行的可视化工具:
- 现在让我们创建一个服务不会有依赖性:Redis的服务,提供访客计数器。
- 保存这个新 docker-compose.yml 文件,添加一个 Redis 服务。
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: username/repo:tag
deploy:
replicas: 5
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "80:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis
ports:
- "6379:6379"
volumes:
- "/home/docker/data:/data"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet: