以下按照官网教程一步一步操作学习docker
常用命令:
删除所有容器
docker rm `docker ps -a -q`
查看所有容器
docker container ls --all
停止单个容器
docker container stop 容器id
停用全部运行中的容器
docker stop $(docker ps -q)
一条命令实现停用并删除容器
docker stop $(docker ps -q) & docker rm $(docker ps -aq)
删除所有镜像
docker rmi `docker images -q`
删除单个镜像
docker rmi 镜像id
删除无效镜像
docker image prune
或者
docker rmi `docker image ls -f dangling=true -q`
一 Dockerfile
Docker通过读取Dockerfile中的指令自动生成镜像,按我的理解就是,把整个应用环境显示的表达了出来,然后docker按照Dockerfile生成最终我们需要的运行环境。
1.1 建一个新目录,然后创建Dockerfile文件,复制黏贴一下内容
# Use an official Python runtime as a parent image
# 官网原本是这个: FROM python:2.7-slim ,但我运行不了,换成下面那个了
FROM python:3.6
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
1.2 之后再创建两个文件,requirements.txt 和 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
1.3 创建docker镜像
docker build --tag=friendlyhello .
可以使用 -t
这个时候可以查看镜像了
$ docker image ls
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
1.4 运行应用程序
docker run -p 4000:80 friendlyhello
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
172.17.0.1 - - [15/Feb/2019 06:41:44] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [15/Feb/2019 06:41:44] "GET /favicon.ico HTTP/1.1" 404 -
python内部产生的服务端口是80,但消息来自容器内部,可以设置端口为4000。访问地址:http://localhost:4000
可以看到产生如下界面。CTRL+C 退出终端
在后台以分离模式运行应用程序,这相当于隐藏在后台运行
docker run -d -p 4000:80 friendlyhello
返回长容器id
4f8862d7a00374f52cf51d3dee66ccf3b49f366ce5267a1cc929ce2de8407312
查看容器
zldeMacBook-Air-5:celery_test zl$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f8862d7a003 friendlyhello "python app.py" About a minute ago Up About a minute 0.0.0.0:4000->80/tcp quizzical_meninsky
停止容器
docker container stop 容器id
二 分享镜像
2.1 创建docker id 网址:https://hub.docker.com/
2.2 登录本地docker
docker login
zldeMacBook-Air-5:celery_test zl$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: #########
Password:
Login Succeeded
2.3 标记镜像
docker tag image username/repository:tag
例子
zldeMacBook-Air-5:celery_test zl$ docker tag friendlyhello #######/docker-com:part1
zldeMacBook-Air-5:celery_test zl$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
#########/docker-com part1 45df9f7a34e3 36 minutes ago 932MB
friendlyhello latest 45df9f7a34e3 36 minutes ago 932MB
python 3.6 e0a418687f6c 2 days ago 922MB
2.4 发布镜像
docker push username/repository:tag
2.5 从远程存储库中拉出并运行镜像
docker run -p 4000:80 username/repository:tag
无论在哪里docker run执行,它都会提取您的图像,以及Python和所有依赖项requirements.txt,并运行您的代码。它们都在一个整洁的小包中一起旅行,你不需要在主机上安装任何东西让Docker运行它。
三 docker-compose.yml
3.1 创建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。(在内部,容器本身web在短暂的端口发布到 80端口。)
- webnet使用默认设置(负载平衡的覆盖网络)定义网络。
3.2 运行新的负载均衡应用
docker swarm init
3.3 为应用程序命名。在这里,它被设置为 getstartedlab:
zldeMacBook-Air-5:celery_test zl$ docker stack deploy -c docker-compose.yml getstartedlab
Creating network getstartedlab_webnet
Creating service getstartedlab_web
3.4 查看服务
zldeMacBook-Air-5:celery_test zl$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
08zb9um5hp59 getstartedlab_web replicated 5/5 284794223/docker-com:part1 *:4000->80/tcp
在服务中运行的单个容器称为任务。任务被赋予以数字递增的唯一ID,列出服务任务
zldeMacBook-Air-5:celery_test zl$ docker service ps getstartedlab_web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l8hmq01l0jap getstartedlab_web.1 284794223/docker-com:part1 linuxkit-025000000001 Running Running 2 minutes ago
w8ttti8a2yvi getstartedlab_web.2 284794223/docker-com:part1 linuxkit-025000000001 Running Running 2 minutes ago
qeyugcp87euy getstartedlab_web.3 284794223/docker-com:part1 linuxkit-025000000001 Running Running 2 minutes ago
o65p8ajedy4q getstartedlab_web.4 284794223/docker-com:part1 linuxkit-025000000001 Running Running 2 minutes ago
92gd50jd4zv0 getstartedlab_web.5 284794223/docker-com:part1 linuxkit-025000000001 Running Running 2 minutes ago
列出容器,任务也会显示
zldeMacBook-Air-5:celery_test zl$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4a524d0c6432 284794223/docker-com:part1 "python app.py" 3 minutes ago Up 3 minutes 80/tcp getstartedlab_web.4.o65p8ajedy4q0dwai7eiicjho
b8e953ce46e5 284794223/docker-com:part1 "python app.py" 3 minutes ago Up 3 minutes 80/tcp getstartedlab_web.2.w8ttti8a2yvi8dg77pqzcm040
32a6b31905c3 284794223/docker-com:part1 "python app.py" 3 minutes ago Up 3 minutes 80/tcp getstartedlab_web.3.qeyugcp87euy0l6g0taaa70ho
6eabe10745db 284794223/docker-com:part1 "python app.py" 3 minutes ago Up 3 minutes 80/tcp getstartedlab_web.1.l8hmq01l0japzvgwxj4x3xfje
0b2d7df335ad 284794223/docker-com:part1 "python app.py" 3 minutes ago Up 3 minutes 80/tcp getstartedlab_web.5.92gd50jd4zv07c2yxml613nmx
打开 http://localhost:4000 ,多刷新几次,会按照任务id,循环刷新
查看应用程序名
zldeMacBook-Air-5:celery_test zl$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l8hmq01l0jap getstartedlab_web.1 284794223/docker-com:part1 linuxkit-025000000001 Running Running 10 minutes ago
w8ttti8a2yvi getstartedlab_web.2 284794223/docker-com:part1 linuxkit-025000000001 Running Running 10 minutes ago
qeyugcp87euy getstartedlab_web.3 284794223/docker-com:part1 linuxkit-025000000001 Running Running 10 minutes ago
o65p8ajedy4q getstartedlab_web.4 284794223/docker-com:part1 linuxkit-025000000001 Running Running 10 minutes ago
92gd50jd4zv0 getstartedlab_web.5 284794223/docker-com:part1 linuxkit-025000000001 Running Running 10 minutes ago
3.5 如果修改了docker-compose.yml里面的内容,直接重新deploy
docker stack deploy -c docker-compose.yml getstartedlab
Docker执行就地更新,无需首先拆除堆栈或杀死任何容器。
将应用程序关闭
docker stack rm getstartedlab
将群关闭
docker swarm leave --force
四 群集 Swarms
4.1 安装VirtualBox
4.2 docker-machine使用VirtualBox驱动程序创建几个VM(虚拟机)
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
查看虚拟机ip地址
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v17.06.2-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.06.2-ce
重新启动虚拟机
docker-machine start myvm1
4.3 初始化SWARM并添加节点
第一台机器充当管理器,它执行管理命令并验证工人加入群,第二台是工人
docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"
例如:
zldeMacBook-Air-5:celery_test zl$ docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377"
Swarm initialized: current node (27hhgfhiapmblns92bdq1lrw2) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5rkujt8zszmcys6u6i9rtrbr4q6g3k1376illqcwun0ayned95-2iu0aiurmi6v845cjxh0pvtxl 192.168.99.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2377是群集管理端口。docker-machine ssh以myvm2 将新群组作为工作者加入
$ docker-machine ssh myvm2 "docker swarm join --token <token> <ip>:2377"
zldeMacBook-Air-5:celery_test zl$ docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-5rkujt8zszmcys6u6i9rtrbr4q6g3k1376illqcwun0ayned95-2iu0aiurmi6v845cjxh0pvtxl 192.168.99.100:2377"
This node joined a swarm as a worker.
这样已经创建了第一个群,查看此群中的节点
zldeMacBook-Air-5:celery_test zl$ docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
27hhgfhiapmblns92bdq1lrw2 * myvm1 Ready Active Leader 18.09.2
mpt3sba1mefhue6krgeffg7hp myvm2 Ready Active 18.09.2
4.4 群集上部署您的应用程序
zldeMacBook-Air-5:celery_test zl$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/zl/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)
运行给定命令以配置要与之通信的shell
zldeMacBook-Air-5:celery_test zl$ eval $(docker-machine env myvm1)
zldeMacBook-Air-5:celery_test zl$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 * virtualbox Running tcp://192.168.99.100:2376 v18.09.2
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v18.09.2
4.5 在swarm管理器上部署应用程序
docker stack deploy -c docker-compose.yml getstartedlab
应用程序部署在一个群集中!
zldeMacBook-Air-5:celery_test zl$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zncq2tfprafa getstartedlab_web.1 284794223/docker-com:part1 myvm2 Running Preparing 51 seconds ago
mh7khank14f0 getstartedlab_web.2 284794223/docker-com:part1 myvm1 Running Preparing 51 seconds ago
ufo2rv5gr9gs getstartedlab_web.3 284794223/docker-com:part1 myvm2 Running Preparing 51 seconds ago
kp4rud24d8xb getstartedlab_web.4 284794223/docker-com:part1 myvm1 Running Preparing 51 seconds ago
nun4umxcayfz getstartedlab_web.5 284794223/docker-com:part1 myvm2 Running Preparing 51 seconds ago
访问群集 http://192.168.99.101:4000/ 或者 http://192.168.99.100:4000/
清理应用
docker-machine ssh myvm1 "docker stack rm getstartedlab"
如果想让工作节点脱离swarm集群
docker-machine ssh myvm2 "docker swarm leave"
如果关闭管理节点
docker-machine ssh myvm1 "docker swarm leave --force"
五 堆栈
5.1 重新部署yml文件,并且重新启动
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: 284794223/docker-com:part1
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:
重启
zldeMacBook-Air-5:celery_test zl$ docker stack deploy -c docker-compose.yml getstartedlab
Updating service getstartedlab_web (id: y2nju7rfxtjmyn8zj1138wd02)
Creating service getstartedlab_visualizer
访问visualizer:http://192.168.99.101:8080/ 可以看到所有的服务都在上面
接下来添加redis服务,修改conpose文件
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:
创建一个存储数据的目录,并且重新部署
appledeMacBook-Air-92:celery_test zl$ docker-machine ssh myvm1 "mkdir ./data"
appledeMacBook-Air-92:celery_test zl$ docker stack deploy -c docker-compose.yml getstartedlab
Creating service getstartedlab_redis
Updating service getstartedlab_web (id: sjjsaahnixwrnlu6sp1tu8n3v)
Updating service getstartedlab_visualizer (id: xiwmyngfvxj828fahszzcaa7g)
访问: http://192.168.99.102/ 可以看见Visits变了
访问:http://192.168.99.101:8080/ 可以看见多了一个redis服务