安装docker
去官网上下载对应的
第一次使用
- 查看版本
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
- 查看docker信息
$ docker info
Containers: 1
Running: 0
Paused: 0
Stopped: 1
Images: 2
Server Version: 18.06.1-ce
...
- hello world
运行 hello-world 镜像,如果没有则下载并运行
$ docker run hello-world
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
- 查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 7 weeks ago 1.84kB
- 查看容器
如果容器还在运行,就不需要--all
参数
$ docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2479723dcd4 hello-world "/hello" 4 hours ago Exited (0) 4 hours ago hardcore_cori
通过Dockerfile 来定义容器
Dockerfile
创建一个目录,在此目录下新建一个Dockerfile文件
# 将官方 Python 运行时用作父镜像
FROM python:2.7-slim
# 将工作目录设置为 /app
WORKDIR /app
# 将当前目录内容复制到位于 /app 中的容器中
ADD . /app
# 安装 requirements.txt 中指定的任何所需软件包
RUN pip install -r requirements.txt
# 使端口 80 可供此容器外的环境使用
EXPOSE 80
# 定义环境变量
ENV NAME World
# 在容器启动时运行 app.py
CMD ["python", "app.py"]
其中涉及应用的文件还未创建
应用文件
- requirements.txt
Flask
Redis
- app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
构建应用
- 查看应用目录
$ ls
Dockerfile app.py requirements.txt
- 运行构建命令,创建Docker镜像,使用
-t
对镜像起别名
$ docker build -t friendlyhello
- 查看构建好的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest 4e3e33fac3e2 21 minutes ago 131MB
python 2.7-slim 99079b24ed51 7 days ago 120MB
hello-world latest fce289e99eb9 7 weeks ago 1.84kB
运行应用
正常模式
- 运行应用,使用
-p
将本机的4000端口映射到容器向外暴露的80端口
$ docker run -p 4000:80 friendlyhello
- 浏览器访问 http://localhost:4000或者使用
curl
$ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 65c750525420<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
- 终止应用
CTRL+C
分离模式
- 通过
-d
将docker启动的应用在后台运行
$ docker run -d -p 4000:80 friendlyhello
63463f542b5c6dd2aa2840a1798272d4934982b3fdc2277befe5c6221e9a6c4d
返回的是应用的容器完整ID
- 查看应用
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bfc58a8896a friendlyhello "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:4001->80/tcp heuristic_galileo
CONTAINER ID
与 页面上显示的Hostname值一致
- 终止应用
docker stop
根据 CONTAINER ID
去终止应用
$ docker stop 7bfc58a8896a
将应用推送到镜像库
- 本机登录
docker login
- 标记镜像
docker tag image username/repository:tag
$ docker tag friendlyhello zsq/hello-world:first
- 查看标记镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest 4e3e33fac3e2 2 hours ago 131MB
zsq/hello-world first 4e3e33fac3e2 2 hours ago 131MB
python 2.7-slim 99079b24ed51 7 days ago 120MB
hello-world latest fce289e99eb9 7 weeks ago 1.84kB
...
4.发布镜像
$ docker push zsq/hello-world:first
- 从远程镜像库拉取到本地并运行镜像
如果存在直接运行,否则将从远程拉取并运行
$ docker run -p 4000:80 zsq/hello-world:first
相关命令
docker build -t friendlyname .# 使用此目录的 Dockerfile 创建镜像
docker run -p 4000:80 friendlyname # 运行端口 4000 到 90 的“友好名称”映射
docker run -d -p 4000:80 friendlyname # 内容相同,但在分离模式下
docker ps # 查看所有正在运行的容器的列表
docker stop <hash> # 平稳地停止指定的容器
docker ps -a # 查看所有容器的列表,甚至包含未运行的容器
docker kill <hash> # 强制关闭指定的容器
docker rm <hash> # 从此机器中删除指定的容器
docker rm $(docker ps -a -q) # 从此机器中删除所有容器
docker images -a # 显示此机器上的所有镜像
docker rmi <imagename> # 从此机器中删除指定的镜像
docker rmi $(docker images -q) # 从此机器中删除所有镜像
docker login # 使用您的 Docker 凭证登录此 CLI 会话
docker tag <image> username/repository:tag # 标记 <image> 以上传到镜像库
docker push username/repository:tag # 将已标记的镜像上传到镜像库
docker run username/repository:tag # 运行镜像库中的镜像
服务
服务是“生产中的容器”,一般一项服务仅运行一个镜像,但是可以对该镜像启用负载均衡
docker-compose.yml
定义、运行和扩展docker,也就是定义Docker容器在生产环境中的行为
version: "3"
services:
web:
# 将 username/repo:tag 替换为您的名称和镜像详细信息
image: username/repository:tag
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
networks:
webnet:
- 将 Compose 文件设置为 version:"3"。本质上,这会使其兼容 swarm mode。
- 从镜像库中拉取指定镜像。
- 将镜像分为5个web运行,每个实例限制最多使用10%的CPU和50MB的RAM。
- 如果某个容器发生错误,立即重启容器。
- 将主机上的4000端口映射到docker(web)的80端口。
- 使用默认设置定义webnet网络(此为负载均衡的overlay网络)
运行服务
- 开启swarm管理节点
$ docker swarm init
如果没有执行过docker swarm init
,将报this node is not a swarm manager
- 运行应用
$ docker stack deploy -c docker-compose.yml getstartedlab
Creating network getstartedlab_webnet
Creating service getstartedlab_web
getstartedlab为服务的别名
- 查看服务中容器的列表
$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
kpdbgnl2p7yb getstartedlab_web.1 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
k6uqshqqfxkz getstartedlab_web.2 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
vfn8ys8cpkc3 getstartedlab_web.3 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
4wtvs8qqxnul getstartedlab_web.4 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
bb2w7co8x3br getstartedlab_web.5 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
此时,web应用已经实现负载均衡了,通过http://localhost:4000可以看到每次刷新后容器ID都会发生改变,每次请求,将以循环方式选择5个从节点之一做出响应
- 查看服务
$ docker stack services getstartedlab
ID NAME MODE REPLICAS IMAGE PORTS
tc12dkx8copc getstartedlab_web replicated 5/5 zsq/one:1 *:4001->80/tcp
- 扩展服务
可以将docker-compose.yml
中的replicas值改为2,重新运行docker stack deploy
命令来扩展,无需事先清除技术栈或者终止容器
$ docker stack deploy -c docker-compose.yml getstartedlab
Updating service getstartedlab_web (id: tc12dkx8copcgy09dmng5h7z7)
再次查看容器列表,可以看到已经移除了3个
$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
nhyp01413tb9 getstartedlab_web.1 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
1zwklq2rbkpo getstartedlab_web.2 zsq/one:1 linuxkit-025000000001 Running Running about a minute ago
42xx8qkib6hh getstartedlab_web.3 zsq/one:1 linuxkit-025000000001 Remove Running 14 seconds ago
jkua7sao1m6g getstartedlab_web.4 zsq/one:1 linuxkit-025000000001 Remove Running 14 seconds ago
8r39nv3q7dyb getstartedlab_web.5 zsq/one:1 linuxkit-025000000001 Remove Running 14 seconds ago
- 清除服务应用
$ docker stack rm getstartedlab
Removing service getstartedlab_web
Removing network getstartedlab_webnet
但是单节点swarm仍在运行
- 清除swarm
先查看下,是否在运行
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
89zkmhm6eqgjsigjzr71q4661 * linuxkit-025000000001 Ready Active Leader 18.06.1-ce
清除swarm
$ docker swarm leave --force
Node left the swarm.
相关命令
docker stack ls # 列出此 Docker 主机上所有正在运行的应用
docker stack deploy -c <composefile> <appname> # 运行指定的 Compose 文件
docker stack services <appname> # 列出与应用关联的服务
docker stack ps <appname> # 列出与应用关联的正在运行的容器
docker stack rm <appname> # 清除应用