百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Docker入门详解(上)

toyiye 2024-06-21 12:32 10 浏览 0 评论

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。

上述配置表明:

  1. 服务加载的镜像是<dockerid>/get-started:part2
  2. 启动5个容器实例来组成一个服务。服务的名称为"web"。
  3. 每个容器最多使用一个CPU内核的10%,以及50MB内存。
  4. 容器在失败状态下自动重启。
  5. 映射实体机端口4000到容器的端口80。
  6. 服务使用的网络名为"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

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码