公司要新招美女跟我学docker,你来吗?(3)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 公司要新招美女跟我学docker,你来吗?(3)

12. 容器运行策略

Docker认为任何带有非零退出代码的容器都崩溃了。默认情况下,崩溃的容器将保持停止状态。

我们已经创建了一个特殊的容器,它输出一条消息,然后使用代码1退出,以模拟崩溃。

docker run -d --name restart-default scrapbook/docker-restart-example

如果列出所有的容器,包括stopped,您将看到容器已经崩溃

$ docker ps -a
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS                     PORTS               NAMES
39ef0a052236        scrapbook/docker-restart-example   "/bin/sh -c ./launch…"   5 seconds ago       Exited (1) 2 seconds ago                       restart-default

而日志将输出我们的消息,这在现实生活中可能会提供帮助我们诊断问题的信息。

$ docker logs restart-default
Tue Sep 28 13:41:39 UTC 2021 Booting up...

根据您的场景,重新启动失败的进程可能会纠正这个问题。Docker可以在停止尝试之前自动重试启动Docker特定次数。

他的选项--restart=on-failure:#允许你说Docker应该重试多少次。在下面的示例中,Docker将在停止之前重新启动容器三次。

$ docker run -d --name restart-3 --restart=on-failure:3 scrapbook/docker-restart-example
$ docker logs restart-3
Tue Sep 28 13:42:44 UTC 2021 Booting up...
Tue Sep 28 13:42:46 UTC 2021 Booting up...
Tue Sep 28 13:42:50 UTC 2021 Booting up...
Tue Sep 28 13:42:53 UTC 2021 Booting up...

最后,Docker总是可以重新启动失败的容器,在这种情况下,Docker将一直尝试,直到容器被明确告知停止。

例如,当容器崩溃时,使用always标志自动重新启动容器

$ docker run -d --name restart-always --restart=always scrapbook/docker-restart-example
$ docker logs restart-always

13. 容器元数据与标签

当容器通过docker运行启动时,标签可以被附加到容器上。一个容器可以在任何时候有多个标签。


注意,在这个例子中,因为我们使用的标签是用于CLI,而不是一个自动化的工具,所以我们没有使用DNS表示法格式。


要添加单个标签,可以使用l =<value>选项。下面的示例为容器分配了一个名为user的带有ID的标签。这将允许我们查询与该特定用户相关的所有正在运行的容器。

docker run -l user=12345 -d redis

如果您正在添加多个标签,那么这些标签可以来自外部文件。文件的每一行都需要有一个标签,然后这些标签将被附加到正在运行的容器上。

这一行在文件中创建了两个标签,一个用于用户,另一个用于分配角色。

echo 'user=123461' >> labels && echo 'role=cache' >> labels

The --label-file=<filename> option will create a label for each line in the file.

docker run --label-file=labels -d redis

标签镜像的工作方式与容器相同,但在构建镜像时在Dockerfile中设置。当容器启动时,镜像的标签将应用到容器实例。

在一个Dockerfile中,你可以使用label指令分配一个标签。在标签下面创建名为“剪贴簿”的供应商。

LABEL vendor=Katacoda

如果我们想要分配多个标签,可以使用下面的格式,每行都有一个标签,使用反斜杠(“”)连接。注意,我们使用的是与第三方工具相关的DNS标记格式。

LABEL vendor=Katacoda \ 
com.katacoda.version=0.0.5 \
com.katacoda.build-date=2016-07-01T10:47:29Z \
com.katacoda.course=Docker

标签和元数据只有在您可以稍后查看/查询它们时才有用。查看特定容器或镜像的所有标签的第一种方法是使用docker inspect

环境已经为您创建了一个名为rd的容器和一个名为katacoda-label-example的映像。

通过提供运行容器的友好名称或哈希id,您可以查询它的所有元数据。

docker inspect rd

使用-f选项,您可以过滤JSON响应,只针对我们感兴趣的标签部分。

$ docker inspect -f "{{json .Config.Labels }}" rd
{"com.katacoda.created":"automatically","com.katacoda.private-msg":"magic","user":"scrapbook"}

这些标签将保留,即使镜像已被取消标记。当镜像未被标记时,它的名称将为<none>.


虽然检查单个容器和映像可以为您提供更多的上下文,但在运行数千个容器的生产中,限制对您感兴趣的容器的响应是很有用的。


docker ps命令允许您根据标签名称和值指定一个过滤器。例如,下面的查询将返回所有具有值katacoda的用户标签键的容器。

$ docker ps --filter "label=user=scrapbook"
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
0c0d9b5b90ed        redis               "docker-entrypoint.s…"   8 minutes ago       Up 8 minutes        6379/tcp            rd

基于构建镜像时使用的标签,可以对镜像应用相同的过滤方法。

$ docker images --filter "label=vendor=Katacoda"
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
katacoda-label-example   latest              33a1689f8704        8 minutes ago       112MB

标签不仅适用于图像和容器,也适用于Docker Daemon本身。当您启动守护进程的实例时,可以为它分配标签,以帮助确定应该如何使用它,例如,它是开发服务器还是生产服务器,或者它是否更适合运行数据库等特定角色。

docker -d \
  -H unix:///var/run/docker.sock \
  --label com.katacoda.environment="production" \
  --label com.katacoda.storage="ssd"

14. 负载平衡的容器

14.1 NGINX Proxy

在这个场景中,我们希望运行一个NGINX服务,它可以在加载新容器时动态发现和更新它的负载平衡配置。我们已经创建了nginx-proxy。


Nginx-proxy接受HTTP请求,并根据请求主机名将请求代理到相应的容器。这对用户是透明的,不会产生任何额外的性能开销。


在启动代理容器时,需要配置三个键属性。


第一种方法是使用-p 80:80将容器绑定到主机上的80端口。这确保了所有HTTP请求都由代理处理。

第二步是挂载docker.sock文件。这是一个与运行在主机上的Docker守护进程的连接,允许容器通过API访问它的元数据。NGINX-proxy使用这个来监听事件,然后根据容器的IP地址更新NGINX配置。挂载文件的工作方式与使用-v /var/run/docker.sock:/tmp/docker.sock:ro的目录相同。指定:ro将访问限制为只读。

最后,我们可以设置一个可选的-e DEFAULTHOST=<domain>。如果传入的请求没有生成任何指定的主机,则该容器将处理请求。这使您能够在一台机器上运行多个具有不同域的网站,并可返回到一个已知的网站。

使用下面的命令启动nginx-proxy。

docker run -d -p 80:80 -e DEFAULT_HOST=proxy.example -v /var/run/docker.sock:/tmp/docker.sock:ro --name n

:因为我们使用的是DEFAULT_HOST,所以任何传入的请求都将被定向到已经分配了HOST代理的容器。

您可以使用curl http://ip向web服务器发出请求。由于我们没有容器,它将返回一个503错误。

$ curl http://ip
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>

14.2 单机

Nginx-proxy现在正在监听Docker在启动/停止时引发的事件。一个名为katacoda/docker-http-server的示例网站已经创建,它将返回运行它的机器名。这允许我们测试我们的代理是否按照预期工作。它的内部是一个PHP和Apache2应用程序,侦听端口80。


为了让Nginx-proxy开始向容器发送请求,你需要指定VIRTUAL_HOST环境变量。这个变量定义了请求来自的域,并且应该由容器处理。在这个场景中,我们将把我们的HOST设置为与DEFAULT_HOST匹配,这样它将接受所有请求。

docker run -d -p 80 -e VIRTUAL_HOST=proxy.example katacoda/docker-http-server

有时,NGINX需要几秒钟的时间来重新加载,但如果我们使用curl http://ip执行一个请求到我们的代理,那么请求将由我们的容器处理。

$ curl http://ip
<h1>This request was processed by host: a6b180c03df3</h1>

14.3 集群

现在,我们已经成功地创建了一个容器来处理HTTP请求。如果我们用相同的VIRTUAL_HOST启动第二个容器,那么nginx-proxy将在一个循环负载平衡的场景中配置系统。这意味着第一个请求将发送到一个容器,第二个请求将发送到第二个容器,然后循环重复。您可以运行的节点数量没有限制。

使用与前面相同的命令启动第二个容器或者第三个

 docker run -d -p 80 -e VIRTUAL_HOST=proxy.example katacoda/docker-http-server
 docker run -d -p 80 -e VIRTUAL_HOST=proxy.example katacoda/docker-http-server

如果使用curl http://ip执行对代理的请求,则请求将由第一个容器处理。第二个HTTP请求将返回不同的机器名,这意味着它是由第二个容器处理的。

$ curl http://ip
<h1>This request was processed by host: ac2c0ef08655</h1>
$ curl http://ip
<h1>This request was processed by host: a6b180c03df3</h1>

当NGINX -proxy为我们自动创建和配置NGINX时,如果你对最终的配置感兴趣,你可以使用docker exec输出完整的配置文件,如下所示。

docker exec nginx cat /etc/nginx/conf.d/default.conf

关于何时重新加载配置的附加信息可以在使用

docker logs nginx

15. 编排docker-compose

Docker Compose是基于docker-compose.yml文件。该文件定义启动集群集所需的所有容器和设置。属性映射到您如何使用docker运行命令.

格式yaml:

container_name:
  property: value
    - or options

在这个场景中,我们有一个需要连接到Redis的Node.js应用程序。首先,我们需要定义docker-compose.yml文件来启动Node.js应用程序。


根据上面的格式,文件需要将容器命名为“web”,并将构建属性设置为当前目录。我们将在以后的步骤中介绍其他属性。


将下列yaml复制到编辑器中。这将定义一个名为web的容器,它基于当前目录的构建。

web:
  build: .

Docker Compose支持所有可以使用Docker run定义的属性。将两个容器链接在一起以指定links属性并列出所需连接。例如,下面将链接到相同文件中定义的redis源容器,并将相同的名称分配给别名。

  links:
    - redis

同样的格式用于端口等其他属性,有关选项的其他文档可在以下网址找到

https://docs.docker.com/compose/compose-file/


更新我们的web容器,以暴露3001端口,并创建一个链接到我们的Redis容器。


在上一步中,我们使用当前目录中的Dockerfile作为容器的基础。在此步骤中,我们希望使用来自Docker Hub的现有映像作为第二个容器。


要找到第二个容器,只需在新行上使用与前面相同的格式。YAML格式非常灵活,可以在同一个文件中定义多个容器。


定义第二个名称为redis的容器,它使用镜像redis。按照YAML格式,容器的详细信息如下:

redis:
  image: redis:alpine
  volumes:
    - /var/redis/data:/data

使用创建的docker-compose.yml文件就绪后,您可以使用一个up命令启动所有应用程序。如果您想调出单个容器,那么您可以使用<name>

参数-d表示在后台运行容器,类似于与docker run一起使用。

$ ls
Dockerfile  Makefile  docker-compose.yml  node_modules  package.json  server.js
$ cat Dockerfile 
FROM ocelotuproar/alpine-node:5.7.1-onbuild
EXPOSE 3000
$ cat docker-compose.yml 
web:
  build: .
  links:
    - redis
  ports:
    - "3000"
    - "8000"
redis:
  image: redis:alpine
  volumes:
    - /var/redis/data:/data
启动部署运行
$ docker-compose up -d
$ docker-compose ps
      Name                    Command               State                        Ports                      
------------------------------------------------------------------------------------------------------------
tutorial_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp                                        
tutorial_web_1     npm start                        Up      0.0.0.0:32769->3000/tcp, 0.0.0.0:32768->8000/tcp
#查看日志
$ docker-compose logs

由于Docker Compose理解如何启动应用程序容器,所以它还可以用于扩展正在运行的容器数量。scale选项允许指定服务,然后指定所需的实例数量。如果数量大于已经运行的实例,那么它将启动额外的容器。如果数量较少,那么它将停止不需要的容器。


使用该命令扩展正在运行的web容器的数量

$ docker-compose scale web=3
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting tutorial_web_1 ... done
Creating tutorial_web_2 ... done
Creating tutorial_web_3 ... done

你可以减少使用

$ docker-compose scale web=1
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Stopping and removing tutorial_web_2 ... done
Stopping and removing tutorial_web_3 ... done

与启动应用程序时一样,要停止一组容器,可以使用该命令

$ docker-compose stop

要删除所有容器,请使用此命令

$ docker-compose rm
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
Docker 容器
《Docker公司在金融行业落地实践》电子版地址
Docker公司在金融行业落地实践
101 1
《Docker公司在金融行业落地实践》电子版地址
|
缓存 JSON NoSQL
公司要新招美女跟我学docker,你来吗?(1)
公司要新招美女跟我学docker,你来吗?(1)
|
Docker 容器
|
Kubernetes 供应链 安全
Docker Desktop 向大公司宣告收费,网友大呼:是时候弃用了
在容器引擎 Docker 诞生的 8 年间,其与开源的容器编排 Kubernetes 共同推动容器技术在云计算领域的应用,也让自身在全球范围内受到了广泛的关注。可以说,做过云计算开发的程序员,十有八有学过 Docker 技术。 不过,近日 Docker 官方宣布一项新的动作,即将产品订阅划分为个人、专业、团队和商业不同版本,对于这样做的原因,官方称是为开发者所依赖的生产力和协作提供了业务所需的规模、安全性和可信内容,由此以可持续性的方式为 Docker 提供服务。
|
Ubuntu 应用服务中间件 Go
公司要新招美女跟我学docker,你来吗?(4)
公司要新招美女跟我学docker,你来吗?(4)
|
存储 NoSQL 网络协议
公司要新招美女跟我学docker,你来吗?(2)
公司要新招美女跟我学docker,你来吗?(2)
|
关系型数据库 MySQL 数据库
公司mysql docker容器挂了,数据丢失,老板要起诉我。。
公司mysql docker容器挂了,数据丢失,老板要起诉我。。
513 0
公司mysql docker容器挂了,数据丢失,老板要起诉我。。
|
运维 Kubernetes 网络协议
Docker容器基础(二) - Docker公司的入场
Docker容器基础(二) - Docker公司的入场
137 0
Docker容器基础(二) - Docker公司的入场
|
Kubernetes Cloud Native 网络协议
Docker 容器实战 (二) :“ 鲸鱼” 公司粉墨登场
随着 PaaS 深入人心,Cloud Foundry 为首的传统 PaaS,开始蓄力基础设施领域的平台化和 PaaS 化,于是发现了 PaaS 中的问题 。本文将为大家讲解 Docker 的崛起之路。
941 0
Docker 容器实战 (二) :“ 鲸鱼” 公司粉墨登场
|
Devops 容器 Docker
Docker公司DevOps领军人物John Willis:DevOps最佳实践
本文主要从为什么要用DevOps开始谈起,接着分享DevOps的三种方式,着重分析第一种方式,包括Immutable Service Delivery的Devops (Faster)、Docker (Effective) 、Supply Chain (Reliable),最后浅谈了第二种方式。
587 0