网站首页 > 基础教程 正文
Part 1: Docker环境设置
参考Docker安装指南或快速入门手册来安装Docker Desktop。
安装成功后,使用下面的命令来验证Docker的运行状态:
docker --version
docker info 或 docker version 可以查看更加详细的信息:
docker info
docker version
通过下面的命令可以测试一下你的docker安装正确与否:
docker run hello-world
它会下载一个简单的docker镜像,并启动一个容器运行这个镜像。
使用docker image来查看本地的镜像:
docker image ls
使用docker container命令查看本地的容器。例如下面的命令会返回所有正在运行和已经停止的容器:
docker container ls --all
小结
通过Docker,你可以很轻量级的扩展你的程序。而且通过docker镜像发布程序意味着程序的安装将不再需要任何依赖组件(除了Docker Engine)。下面列出了本章节使用到的所有命令,供大家参考。
Part 2: 容器
当你按照上述步骤确认了Docker的运行环境正常之后,你可以着手创建自己的容器镜像了。首先创建一个新的目录:
Dockerfile
在此目录中新建一个文本文件,命名为Dockerfile。文件内容如下:
Dockerfile 的作用是告诉Docker,按照一定的步骤来构建打包一个镜像。在上述例子中,Docker会依次执行以下步骤来生成新的镜像:首先下载一个名为python:2.7-slim的镜像作为模板,拷贝当前目录下的文件到镜像的/app目录,运行一个pip install命令,对外开放80端口,设置环境变量NAME=World,最后运行一个python程序。
The Python application
Dockerfile 引用了2个文件: requirements.txt 和 app.py. 它们是pip指令和python程序所需的源代码。我们在同一目录下创建这两个文件。
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)
这段代码的逻辑很简单,程序会启动一个web service,监听端口80。返回的html中包含环境变量"NAME"的值(默认为world),以及socket.gethostname()的值(为当前容器的ID)。另外,由于容器中并没有运行Redis,因此程序会打印出错误消息:<i>cannot connect to Redis, counter disabled</i>
编译打包
创建容器镜像的所有文件都准备好了,下面就来编译打包。此时在当前目录中你应该有三个文件:Dockerfile, app.py, requirements.txt。
运行下面的命令来打包生成镜像:
docker build --tag=friendlyhello .
提示:不要忘记命令最末尾的小数点,它表示当前目录。
生成的镜像会保存在本地的Docker镜像注册表中(docker image registry)。运行下面的命令查看所有的本地镜像。
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE friendlyhello latest 17334977b537 13 seconds ago 131MB
在上面的例子中,--tag参数没有指明具体的版本号,因此打包的镜像TAG列默认为latest。如果要指定具体的版本号,可以使用 --tag=friendlyhello:v0.0.1。
运行容器
使用命令 docker run来运行一个容器:
docker run -p 4000:80 friendlyhello
参数 -p 4000:80 表明将你的实体机端口4000映射到容器的端口80,因此你可以使用http://localhost:4000 来访问容器中的web service。这个命令会在当前命令行窗口中运行容器,且命令不会返回,直到容器退出。如果要在后台运行容器,请使用参数 -d 开启 detached模式:
docker run -d -p 4000:80 friendlyhello
下面的截图演示了foreground运行和background运行的区别:
使用curl或浏览器来测试这个程序:
curl http://localhost:4000 <h3>Hello World!</h3><b>Hostname:</b> 6be4e1853e71<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
停止容器
在容器正在运行的命令行窗口中,点击CTRL+C会退出这个python 程序,但是Windows系统比较特殊,该操作不会停止容器。正确的做法是使用命令docker container stop来停止一个运行的容器。方法是,先执行 docker container ls 找到正在运行的容器ID。
docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6be4e1853e71 friendlyhello "python app.py" 7 minutes ago Up 7 minutes 0.0.0.0:4000->80/tcp infallible_morse
然后执行 docker container stop:
docker container stop 6be4e1853e71
发布你的docker镜像
镜像可以发布到Docker公开的镜像仓库(docker hub registry)中,这样任何人都可以在任何机器上下载并运行你的镜像。当然,你也可以把镜像发布到其他第三方维护的Docker注册表,甚至于你可以创建公司内部的私有注册表,不过这不在本指南的讨论范围内。
首先需要登录Docker ID。执行命令 docker login,并按提示输入用户名和密码。
然后给你的镜像设置一个标签。标签是对镜像的唯一标识。完整的标签格式是:<dockerid>/<repository>:<tag>
其中,<dockerid>/<repositroy> 表明镜像会上传到你id中的某个镜像仓库。例如:
docker tag friendlyhello feiandytan/get-started:part2
上述命令为镜像friendlyhello创建了一个新的标签,表明此镜像将上传到我的id feiandytan下的仓库 get-started中,并且将其version记为part2。
最后一步就是发布:
docker push <dockerid>/get-started:part
一旦发布成功,你就可以在任意一台安装了Docker的电脑上运行该容器。方法是执行下面的命令:
docker run -p 4000:80 <dockerid>/get-started:part
小结
下面列出本章用到的命令,供大家参考:
docker build -t friendlyhello . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyhello # Run "friendlyhello" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode docker container ls # List all running containers docker container ls -a # List all containers, even those not running docker container stop <hash> # Gracefully stop the specified container docker container kill <hash> # Force shutdown of the specified container docker container rm <hash> # Remove specified container from this machine docker container rm $(docker container ls -a -q) # Remove all containers docker image ls -a # List all images on this machine docker image rm <image id> # Remove specified image from this machine docker image rm $(docker image ls -a -q) # Remove all images from this machine docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry
Part 3: 服务(Services)
先来看几个概念。
- Service:当我们搭建分布式系统时,我们常常希望某一个程序可以同时运行多个副本,它们全部处在一个负载均衡器的后面。在Docker中,这种将一个镜像启动并运行在多个容器副本中的集群,就称为一个服务。描述一个Docker 服务需要指明以下内容:这个服务运行的是哪一个镜像?需要同时运行多少个容器副本?每个容器最大占用多少CPU和内存?是否需要负载均衡等等。这些描述信息都记录在docker-compose.yml文件中。
- Task: 每一个服务都会运行若干个docker 容器。一个容器就称为这个服务的一个任务。例如,如果一个服务同时运行了5个容器,我们就说这个服务包含5个任务。
docker-compose.yml
我们在任意一个目录中新建文本文件 docker-compose.yml。内容如下:
version: "3" services: web: image: <dockerid>/get-started:part2 deploy: replicas: 5 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-failure ports: - "4000:80" networks: - webnet networks: webnet:
提示:<dockerid>要替换成你的docker id。
上述配置表明:
- 服务加载的镜像是<dockerid>/get-started:part2
- 启动5个容器实例来组成一个服务。服务的名称为"web"。
- 每个容器最多使用一个CPU内核的10%,以及50MB内存。
- 容器在失败状态下自动重启。
- 映射实体机端口4000到容器的端口80。
- 服务使用的网络名为"webnet",并且定义了"webnet"网络为默认配置。
部署运行服务
接下来执行命令(关于swarm会在后面介绍):
docker swarm init
使用docker stack deploy来运行这个stack:
docker stack deploy -c docker-compose.yml getstartedlab
上面的命令将读取服务描述文件docker-compose.yml来部署一个stack,并命名该stack为getstartedlab。
可以访问http://localhost:4000 来观察返回的hostname。每次的结果都不同,说明负载均衡器已经生效。
提示:默认的负载均衡策略是依次循环访问各个容器。
查看服务的状态
使用下面的命令可以查看当前电脑上运行的所有服务:
docker service ls
例如:
C:\Users\i062893\OneDrive\code\docker-workspace\my-first-container>docker service ls ID NAME MODE REPLICAS IMAGE PORTS ypyx4ed2uzur getstartedlab_web replicated 0/10 feiandytan/get-started:part2 *:4000->80/tcp
执行命令docker stack services <stack name>查看某个stack的所有服务。例如:
C:\Users\i062893\OneDrive\code\docker-workspace\my-first-container>docker stack services getstartedlabID NAME MODE REPLICAS IMAGE PORTSypyx4ed2uzur getstartedlab_web replicated 10/10 feiandytan/get-started:part2 *:4000->80/tcp
注意上面服务的命名规则:服务的全称"getstartedlab_web"是由<stack name> + <service name> 组成。
使用下面的命令可以查看某个服务包含哪些任务:
docker service ps getstartedlab_web
使用下面的命令查看某个stack包含哪些任务:
docker stack ps getstartedlab
增加任务数
通过修改文件docker-compose.yml 中的replicas参数,可以很容易的扩展你的服务任务数量。只需要重新运行下面的命令即可:
docker stack deploy -c docker-compose.yml getstartedlab
删除stack和swarm
使用下面的命令删除stack和swarm:
docker stack rm getstartedlab docker swarm leave --force
小结
下面列出本章使用到的docker命令,供大家参考:
docker swarm init # Init this machine as a swarm manager docker stack ls # List stacks or apps docker stack deploy -c <composefile> <appname> # Run the specified Compose file docker service ls # List running services associated with an app docker service ps <service> # List tasks associated with an app docker inspect <task or container> # Inspect task or container docker container ls -q # List container IDs docker stack rm <appname> # Tear down an application docker swarm leave --force # Take down a single node swarm from the manager
猜你喜欢
- 2024-10-12 Docker扫盲级别基础操作命令 docker-cn
- 2024-10-12 docker命令讲解(二) docker 命令大全
- 2024-10-12 docker 常用命令整理 docker命令菜鸟教程
- 2024-10-12 Docker必须掌握常用命令 docker常用命令及参数
- 2024-10-12 「这些都不知道你就是个弟弟」Docker常用命令
- 2024-10-12 docker常用命令-其他常用命令 docker常用命令及参数
- 2024-10-12 聊聊 Docker 的存储 Overlay2 docker/overlay2
- 2024-10-12 Docker常用命令与构建中遇到的问题
- 2024-10-12 NVIDIA Jetson 系列文章(5):使用Docker容器的入门技巧
- 2024-10-12 一分钟学会Docker常用命令 docker常用命令大全简书
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)