使用Docker Stack部署应用( 二 )


2.密钥密钥属于顶级对象,在当前Stack文件中定义了4个 。
secrets:postgres_password:external: truestaging_token:external: truerevprox_key:external: truerevprox_cert:external: true注意,4个密钥都被定义为external 。这意味着在Stack部署之前,这些密钥必须存在 。
当然在应用部署时按需创建密钥也是可以的,只需要将file: <filename>替换为external: true 。但该方式生效的前提是,需要在主机文件系统的对应路径下有一个文本文件,其中包含密钥所需的值,并且是未加密的 。这种方式存在明显的安全隐患 。
稍后会展示在部署的时候究竟是如何创建这些密钥的 。现在,读者只需知道应用定义了4个密钥,并且需要提前创建即可 。
下面对服务逐一进行分析 。
3.服务部署中的主要操作都在服务这个环节 。
每个服务都是一个JSON集合(字典),其中包含了一系列关键字 。本书会依次介绍每个关键字,并解释操作的具体内容 。
(1)reverse_proxy服务
正如读者所见,reverse_proxy服务定义了镜像、端口、密钥以及网络 。
reverse_proxy:image: dockersamples/atseasampleshopapp_reverse_proxyports:- "80:80"- "443:443"secrets:- source: revprox_certtarget: revprox_cert- source: revprox_keytarget: revprox_keynetworks:- front-tierimage关键字是服务对象中唯一的必填项 。顾名思义,该关键字定义了将要用于构建服务副本的Docker镜像 。
Docker是可选项,除非指定其他值,否则镜像会从Docker Hub拉取 。读者可以通过在镜像前添加对应第三方镜像仓库服务API的DNS名称的方式,来指定某个镜像从第三方服务拉取 。例如google的容器服务的DNS名称为gcr.io 。
Docker Stack和Docker Compose的一个区别是,Stack不支持构建 。这意味着在部署Stack之前,所有镜像必须提前构建完成 。
ports关键字定义了两个映射 。

  • 80:80将Swarm节点的80端口映射到每个服务副本的80端口 。
  • 443:443将Swarm节点的443端口映射到每个服务副本的443端口 。
默认情况下,所有端口映射都采用Ingress模式 。这意味着Swarm集群中每个节点的对应端口都会映射并且是可访问的,即使是那些没有运行副本的节点 。另一种方式是Host模式,端口只映射到了运行副本的Swarm节点上 。但是,Host模式需要使用完整格式的配置 。例如,在Host模式下将端口映射到80端口的语法如下所示 。
ports:- target: 80published: 80mode: host推荐使用完整语法格式,这样可以提高易读性,并且更灵活(完整语法格式支持Ingress模式和Host模式) 。但是,完整格式要求Compose文件格式的版本至少是3.2 。
secret关键字中定义了两个密钥:revprox_cert以及revprox_key 。这两个密钥必须在顶级关键字secrets下定义,并且必须在系统上已经存在 。
密钥以普通文件的形式被挂载到服务副本当中 。文件的名称就是stack文件中定义的target属性的值,其在linux下的路径为/run/secrets,在windows下的路径为C:ProgramDataDockersecrets 。Linux将/run/secrets作为内存文件系统挂载,但是Windows并不会这样 。
本服务密钥中定义的内容会在每个服务副本中被挂载,具体路径为/run/secrets/revprox_cert和/run/secrets/revprox_key 。若将其中之一挂载为/run/secrets/uber_secret,需要在stack文件中定义如下内容 。
secrets:- source: revprox_certtarget: uber_secretnetworks关键字确保服务所有副本都会连接到front-tier网络 。网络相关定义必须位于顶级关键字networks之下,如果定义的网络不存在,Docker会以Overlay网络方式新建一个网络 。
(2)database服务
数据库服务也在Stack文件中定义了,包括镜像、网络以及密钥 。除上述内容之外,数据库服务还引入了环境变量和部署约束 。
database:image: dockersamples/atsea_dbenvironment:POSTGRES_USER: gordonuserPOSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_passwordPOSTGRES_DB: atseanetworks:- back-tiersecrets:- postgres_passworddeploy:placement:constraints:- 'node.role == worker'environment关键字允许在服务副本中注入环境变量 。在该服务中,使用了3个环境变量来定义数据库用户、数据库密码的位置(挂载到每个服务副本中的密钥)以及数据库服务的名称 。
environment:POSTGRES_USER: gordonuserPOSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_passwordPOSTGRES_DB: atsea注:

将三者作为密钥传递会更安全,因为这样可以避免将数据库名称和数据库用户以明文变量的方式记录在文件当中 。


推荐阅读