刚接触Docker的时候,觉得只是用来作运维。后来真正用的时候才发觉,这个Docker简直是个神器。无论什么开发场景都能轻松应付。想要什么环境都能随意生成,并且灵活性更高,更轻量,完美实现微服务
的概念。python
Docker
Docker
是一个开源的应用容器引擎,基于Go
语言 并听从Apache2.0协议开源。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操做系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有本身的内核,并且也没有进行硬件虚拟。它占用的资源更少,能作到的事更多。linux
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘启动 | 通常为MB | 通常为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 通常几十个 |
Docker
安装的方法都挺简单的,我用的是mac,直接经过Docker官网下载软件安装,全程无障碍。nginx
Docker
概念images
):Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建以后也不会被改变。(直白点能够理解为系统安装包)container
):镜像和容器的关系,就像是面向对象程序设计中的类
和实例
同样,镜像是静态的定义,容器是镜像运行时的实体。容器能够被建立、启动、中止、删除、暂停等。(能够理解为安装好的系统)大概了解了Docker的概念之后,咱们就尝试拉取flask镜像使用一下。 查找镜像能够经过hub.docker.com/网站来搜索,或者经过命令搜索。web
docker search flask
复制代码
alpine
是精简版的linux,体积更小、运行的资源消耗更少。
# 拉取镜像
docker pull tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
# 下载好可查看镜像列表是否存在
docker images
复制代码
下载镜像之后,就开始运行下试试,感觉一下Docker的轻量、快捷。 首先建立个flask运行文件来,在这里,我建立了/docker/flask
做为项目文件,而后在根目录下再建立个app
文件夹来存放main.py
文件,代码以下:redis
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World from Flask!"
if __name__ == "__main__":
# 测试环境下才开启debug模式
app.run(host='0.0.0.0', debug=True, port=80)
复制代码
如今的文件结构:docker
flask
└── app
└── main.py
复制代码
运行命令数据库
docker run -it --name test -p 8080:80 -v /docker/flask/app:/app -w /app tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8 python main.py
复制代码
这里说明一下命令的参数含义: -it
是将-i -t合并起来,做用是能够用指定终端对容器执行命令交互。 --name
对容器进行命名。 -p
将主机的8080端口映射到容器的80端口。 -v
将主机的/docker/flask/app文件挂载到容器的/app文件,若是容器内没有的话会自动建立。 -w
将/app文件做为工做区,后面的执行命令都默认在该文件路径下执行。 tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
镜像名跟标签。 python main.py
经过python来运行工做区的main.py文件。 运行结果:flask
在使用别人定制的镜像时老是不能尽善尽美的,若是在本身项目里面,不能每次都是拉取下来从新配置一下。像上面的镜像,我可不喜欢这么长的名字,想一想每次要敲这么长的名字都头疼(tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8)。vim
打开咱们刚才的/docker/flask路径,在根目录下建立Dockerfile文件,内容以下。浏览器
# 基础镜像
FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
# 没有vim来查看文件很不习惯,利用alpine的包管理安装一个来
RUN apk add vim
# 顺便用pip安装个redis包,后面用得上
RUN pip3 install redis
# 将咱们的app文件加入到自定义镜像里面去
COPY ./app /app 复制代码
如今咱们的文件结构是:
flask
├── app
│ └── main.py
└── Dockerfile
复制代码
剩下的就跑一遍就OK啦!记得必定要在Dockerfile
文件同级目录下执行build命令。
docker build -t myflask .
Sending build context to Docker daemon 4.608kB
Step 1/4 : FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
---> c69984ff0683
Step 2/4 : RUN apk add vim
---> Using cache
---> ebe2947fcf89
Step 3/4 : RUN pip3 install redis
---> Running in aa774ba9030e
Collecting redis
Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB)
Installing collected packages: redis
Successfully installed redis-3.0.1
Removing intermediate container aa774ba9030e
---> 47a0f1ce8ea2
Step 4/4 : COPY ./app /app
---> 50908f081641
Successfully built 50908f081641
Successfully tagged myflask:latest
复制代码
-t
指定要建立的目标路径。 .
这里有个点记住啦,表示是当前路径下的Dockerfile文件,能够指定为绝对路径。 编译完后就经过docker images
查看一下,就能看到myflask镜像了,里面能直接运行python main.py
来启动flask,而且内置了vim和redis包。
Docker Compose
让多容器成为一个总体咱们的每一个容器都负责一个服务,这样容器多的时候一个个手动启动的话是不现实的。在这种状况咱们能够经过Docker Compose
来关联每一个容器,组成一个完整的项目。
Compose
项目由Python
编写,实现上调用了Docker
服务提供的 API 来对容器进行管理。
# 安装docker-compose
sudo pip3 install docker-compose
复制代码
在这里,咱们经过docker-compose.yml
文件来启动flask
容器和redis
容器,并将两个不一样容器相互关联起来。 首先在/docker/flask目录下建立docker-compose.yml
文件,内容以下:
version: '3'
services:
flask:
image: myflask
container_name: myflask
ports:
- 8080:80
volumes:
- /docker/flask/app:/app
working_dir: /app
# 运行后执行的命令
command: python main.py
redis:
# 若是没有这个镜像的话会自动下载
image: "redis:latest"
container_name: myredis
复制代码
而后咱们把上面的main.py
代码修改一下,链接redis数据库并记录网站访问次数。main.py
修改后内容以下:
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route("/")
def hello():
count = redis.incr('visit')
return f"Hello World from Flask! 该页面已被访问{count}次。"
if __name__ == "__main__":
# Only for debugging while developing
app.run(host='0.0.0.0', debug=True, port=80)
复制代码
目前的文件结构是:
flask
├── app
│ └── main.py
└── Dockerfile
└── docker-compose.yml
复制代码
这些编排的文件参数都是取自于Docker
,基本都能看懂,其它就没啥啦,直接命令行跑起来:
docker-compose up
复制代码
就辣么简单!如今咱们在浏览器上访问http://localhost:8080/
就能看到结果了,而且每访问一次这页面都会自动增长访问次数.
docker ps
命令查看运行中的容器:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66133318452d redis:latest "docker-entrypoint.s…" 13 seconds ago Up 12 seconds 6379/tcp myredis
0956529c3c9c myflask "/entrypoint.sh pyth…" 13 seconds ago Up 11 seconds 443/tcp, 0.0.0.0:8080->80/tcp myflask
复制代码
有了Docker Compose
的Docker
才是完整的Docker
,有了这些之后开发简直不要太爽,每一个容器只要维护本身的服务环境就ok了。
# 下载镜像
docker pull name
# 列出本地镜像
docker images
# 使用镜像运行生成容器
docker run name:tag
# 删除镜像
docker rmi id/name
复制代码
能够经过容器的id或者容器别名来启动、中止、重启。
# 查看运行中的容器
docker ps
# 查看全部生成的容器
docker ps -a
# 开始容器
docker start container
# 中止容器
docker stop container
# 重启容器
docker restart container
# 移除不须要的容器(移除前容器必需要处于中止状态)
docker rm container
# 进入后台运行的容器
docker exec -it container /bin/sh
# 打印容器内部的信息(-f参数能实时观察内部信息)
docker logs -f container
复制代码
经过-i -t
进来容器的,能够先按ctrl + p
, 而后按ctrl + q
来退出交互界面组,这样退出不会关闭容器。
# 自动完成包括构建镜像,(从新)建立服务,启动服务,并关联服务相关容器的一系列操做。
docker-compose up
# 此命令将会中止 up 命令所启动的容器,并移除网络
docker-compose down
# 启动已经存在的服务容器。
docker-compose start
# 中止已经处于运行状态的容器,但不删除它。经过start能够再次启动这些容器。
docker-compose stop
# 重启项目中的服务
docker-compose restart
复制代码
默认状况,docker-compose up
启动的容器都在前台,控制台将会同时打印全部容器的输出信息,能够很方便进行调试。当经过Ctrl-C
中止命令时,全部容器将会中止。
此次接触Docker
的时间虽然不长,可是这种微服务细分的架构真的是惊艳到我了。之前玩过VM虚拟机,那个使用成本过高,不够灵活,用过一段时间就放弃了,老老实实维护本身的本机环境。有了这个Docker
之后,想要什么测试环境都行,直接几行代码生成就好,一种为所欲为的自由。 上面写的那些都是平常使用的命令,能应付基本的需求了,真要深刻的话建议去找详细的文档,我就不写太累赘了,但愿你们都能去接触一下这个Docker
,怎么都不亏,大家也会喜欢上这小鲸鱼的。