Rancher之八--Cattle
  it2nV7RK7uw1 2023年11月28日 18 0

Rancher Compose

Rancher Compose是一个多主机版本的Docker Compose。它运行于Rancher UI里属于一个环境多个主机应用里。Rancher Compose启动的容器会被部署在满足调度规则的同一环境中的任意主机里。如果没有设置调度规则,那么这些服务容器会被调度至最少容器运行的主机上运行。这些被Rancher Compose启动的容器的运行效果是和在UI上启动的效果是一致的.

Rancher Compose工具的工作方式是跟Docker Compose的工作方式是相似的,并且兼容版本V1和V2的 docker-compose.yml 文件。为了启用Rancher的特性,您需要额外一份rancher-compose.yml文件,这份文件扩展并覆盖了docker-compose.yml文件。例如,服务缩放和健康检查这些功能就会在rancher-compose.yml中体现。

在阅读这份Rancher Compose文档之前,我们希望您已经懂得 Docker Compose 了。如果您还不认识 Docker Compose,请先阅读 Docker Compose文档。

安装

Rancher Compose的可执行文件下载链接可以在UI的右下角中找到,我们为您提供了Windows, Mac以及Linux版本供您使用。

另外,您也可以到Rancher Compose的发布页找到可执行二进制文件的下载链接。

为 Rancher Compose设置Rancher Server

为了让Rancher Compose可以在Rancher实例中启动服务,您需要设置一些环境变量或者在Rancher Compose命令中送一些参数。必要的环境变量分别是 RANCHER_URLRANCHER_ACCESS_KEY, 以及 RANCHER_SECRET_KEY。 access key和secret key是一个环境API Keys, 可以在API -> 高级选项菜单中创建得到。

注意: 默认情况下,在API菜单下创建的是账号API Keys, 所以您需要在高级选项中创建环境API Keys.

# Set the url that Rancher is on
 $ export RANCHER_URL=http://server_ip:8080/
 # Set the access key, i.e. username
 $ export RANCHER_ACCESS_KEY=<username_of_environment_api_key>
 # Set the secret key, i.e. password
 $ export RANCHER_SECRET_KEY=<password_of_environment_api_key>

如果您不想设置环境变量,那么您需要在Rancher Compose 命令中手动送入这些变量:

$ rancher-compose --url http://server_ip:8080 --access-key <username_of_environment_api_key> --secret-key <password_of_environment_api_key> up

现在您可以使用Rancher Compose 配合docker-compose.yml文件来启动服务了。这些服务会在环境API keys对应的环境中启动服务的。

就像Docker Compose,您可以在命令后面加上服务名称来选择启动全部或者仅启动指定某些docker-compose.yml中服务

$ rancher-compose up servicename1 servicename2
$ rancher-compose stop servicename2

调试 Rancher Compose

您可以设置环境变量RANCHER_CLIENT_DEBUG的值为true来让Rancher Compose输出所有被执行的CLI命令。

# Print verbose messages for all CLI calls
 $ export RANCHER_CLIENT_DEBUG=true

如果您不需要所有的 CLI 命令信息,您可以在命令后上—debug来指定输出哪些可视化CLI命令。

$ rancher-compose --debug up -d

删除服务或容器

在缺省情况下,Rancher Compose不会删除任何服务或者容器。这意味着如果您在一行命令里执行两次 up 命令,那么第二个 up 命令不会起任何作用。这是因为第一个 up 命令会创建出所有东西后让他们自己运行。即使您没有在 up 中使用 -d 参数,Rancher Compose 也不会删除您任何服务。为了删除服务,您只能使用 rm 命令。

构建

构建docker镜像可以有两种方法。第一种方法是通过给build命令一个git或者http URL参数来利用远程资源构建,另一种方法则是让 build 利用本地目录,那么会上传构建上下文到 S3 并在需要时在各个节点执行

为了可以基于S3来创建,您需要设置 AWS 认证。我们提供了一个说明怎样利用在Rancher Compose 里使用S3详细例子供您参考

利用AWS S3构建

构建 docker 镜像可以有两种方法。第一种方法是通过给 build 命令一个 git 或者 http URL参数来利用远程资源构建,另一种方法则是让 build 利用本地目录,那么会上传构建上下文到 S3 并在需要时在各个节点执行

前置条件

  • Docker
  • Rancher Compose
  • AWS 账户
  • Rancher Server和1台主机在我们这个例子里,我们会在docker-compose.yml里定义我们的应用,并且把这个文件放在composetest下。这个compose文件会定义个web服务,它会打开5000端口并映射到主机上,还会链接redis服务,这样可以让在web中运行的服务可以通过redis这个主机名来访问redis容器
version: '2'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    links:
      - redis

  redis:
    image: redis

我们还会添加一个 rancher-compose.yml 到同一个 composetest 目录下来使用Rancher的缩放能力。缺省情况下,如果没有rancher-compose.yml文件或者服务在rancher-compose.yml中没有定义,那么容器数量默认为1个。

version: '2'
services:
  web:
    scale: 3

当提供给 Rancher Compose 的这些文件准备好后,下一步就是实现这个程序并按照步骤来构建它。

使用docker-compose文档中的例子,我们会创建一个名为app.py的文件。这个应用会访问一个名为redis的主机,这个主机会运行 redis KV 存储服务。它会递增redis 中的键为 hits 的键值,然后取回这个值。

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

这个应用会依赖两个库,所以我们同时会创建一个名为 requirements.txt 的文件。

flask
redis

现在我们会在Dockerfile文件中定义应用的构建步骤。在Dockerfile文件里的指令会定义出要怎么构建出这个应用容器。

FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py

因为您已经运行着Rancher Server了,所以您只需要配置好您 AWS 认证信息,然后用您的 Rancher Server URL 和API key来运行 Rancher Compose 。

# Set up your AWS credentials
$ aws configure
AWS Access Key ID []: AWS_ACCESS_KEY
AWS Secret Access Key []: AWS_SECRET_KEY
Default region name []: NOT_NEEDED_FOR_S3
Default output format [None]:
# Run rancher-compose in your composetest directory where all the files are created
$ rancher-compose --url URL_of_Rancher --access-key username_of_API_key --secret-key password_of_API_key up

根据上面的指令,这个 web 容器会在一台 Rancher Server 管理的主机上运行起来。rancher-compose 会先上传当前目录到 S3,而您可以到 S3的 UI 上检索到这个目录。当镜像上传成功后,它会下载这个些文件到主机上构建起一个容器。

问题解答

如果您在利用 S3构建时出现了一些问题,您可以先在本机测试是否可以构建并运行。在您运行rancher-compose的同一目录下,使用下面的命令来校验是否在 docker 中可以正常工作。

# Test building locally to see if works
$ docker build -t test .
# Test running the newly built image
$ docker run test

命令参数

Rancher Compose 工具的工作方式是跟 Docker Compose 的工作方式是相似的,并且支持版本V1的 docker-compose.yml 文件。为了启用 Rancher 的特性,您需要额外一份rancher-compose.yml文件,这份文件扩展并覆盖了docker-compose.yml文件。例如,服务缩放和健康检查这些特性就会在rancher-compose.yml中体现。

Rancher-Compose 命令

Rancher Compose 支持所有 Docker Compose 支持的命令。

Name

Description

create

创建所有服务但不启动

up

启动所有服务

start

启动服务

logs

输出服务日志

restart

重启服务

stopdown

停止服务

scale

缩放服务

rm

删除服务

pull

拉取所有服务的镜像

upgrade

服务之间进行滚动升级

helph

输出命令列表或者指定命令的帮助列表

Rancher Compose 选项

无论何时您使用 Rancher Compose 命令,这些不同的选项您都可以使用

Name

Description

—verbose—debug

—file-f [–file option –file option]

指定一个compose 文件 (默认: docker-compose.yml) [$COMPOSE_FILE]

—project-name-p

指定一个项目名称 (默认: directory name)

—url

执行 Rancher API接口 URL [$RANCHER_URL]

—access-key

指定 Rancher API access key [$RANCHER_ACCESS_KEY]

—secret-key

指定 Rancher API secret key [$RANCHER_SECRET_KEY]

—rancher-file-r

指定一个 Rancher Compose 文件 (默认: rancher-compose.yml)

—env-file-e

指定一个环境变量配置文件

—help-h

输出帮助文本

—version-v

输出 Rancher Compose 版本

例子

准备开始后,您需要创建一个 docker-compose.yml 文件和一个可选的 rancher-compose.yml 文件,如果没有 rancher-compose.yml 文件,那么所有服务默认只分配1个容器

样例文件 docker-compose.yml
version: '2'
 services:
   web:
     image: nginx
   db:
     image: mysql
     environment:
       MYSQL_ROOT_PASSWORD: test
样例文件 rancher-compose.yml
# Reference the service that you want to extend
 version: '2'
 services:
   web:
     scale: 2
   db:
     scale: 1

当您的这些文件创建好后,您就可以启动这些服务到 Rancher 服务了

# Creating and starting services without environment variables and selecting a stack
 # If the stack does not exist in Rancher, it will be created in Rancher
 $ rancher-compose --url URL_of_Rancher --access-key <username_of_environment_api_key> --secret-key <password_of_environment_api_key> -p stack1 up
  
 # Creating and starting services with environment variables already set
 $ rancher-compose -p stack1 up
  
 # To change the scale of an existing service
 $ rancher-compose -p stack1 scale web=3
  
 # To launch a specific service in the docker-compose.yml
 $ rancher-compose -p stack1 up web

注意: 如果您没有传入 -p <STACK_NAME>,应用名就是您执行Rancher Compose命令所在的文件夹名称。

使用 —env-file 选项

当您运行 Rancher Compose 命令时,可以使用—env-file 选项传入一个环境变量配置文件。

样例 secrets 文件
MYSQL_ROOT_PASSWORD=test
样例文件 docker-compose.yml
version: '2'
 services:
   db:
     image: mysql
     environment:
     # Just like Docker Compose, if there is only a key, Rancher Compose will resolve to
     # the values on the machine or the file passed in using --env-file
       MYSQL_ROOT_PASSWORD:

您可以启动服务时传入 secrets 文件

$ rancher-compose --env-file secrets up -d

在传入一个文件并一个环境变量只含一个key,Rancher Compose 将从这个文件或者从运行 Rancher Compose 命令的机器中的系统环境变量中提取这个值。当在文件和系统环境变量中同时存在同一个变量时,Rancher Compose 使用文件中的值。

命令选项

up命令

Name

Description

—pull-p

升级前先在各个已有这个镜像的主机拉取最新镜像

-d

不要阻塞或输出日志

—upgrade-u—recreate

当服务改变时升级

—force-upgrade—force-recreate

强制升级服务,不管服务是否改变

—confirm-upgrade-c

确认升级成功并删除老容器

—rollback-r

回滚到上一个已部署的版本

—batch-size "2"

每次升级多少个容器

—interval "1000"

升级间隔

当您运行 Rancher Compose 的 up 命令时,在所有任务完成后进程会继续运行。如果您希望任务完成后进程退出,那么您需要传入 -d 选项,防止阻塞和输出日志。

# If you do not use the -d flag, Rancher Compose will continue to run until you Ctrl+C to quit
 $ rancher-compose up
  
 # Use the -d flag for rancher-compose to exit after running
 $ rancher-compose up -d

阅读更多关于 利用Rancher Compose升级服务.

start命令

Name

Description

-d

防止阻塞或输出日志

如果您希望任务完成后进程退出,那么您需要传入 -d 选项,防止阻塞和输出日志。

logs命令

Name

Description

—follow

持续输出日志

restart命令

Name

Description

—batch-size "1"

每次重启多少个容器

—interval "0"

重启间隔

缺省情况下,Rancher Compose 会顺序地逐个重启服务。您可以设置批量大小和重启间隔。

stop 与 scale

Name

Description

—timeout-t "10"

指定停止超时秒数

# To change the scale of an existing service
 $ rancher-compose -p stack1 scale service1=3

rm 命令

Name

Description

—force-f

允许删除所有服务

-v

同时移除关联的容易

当移除服务时,Rancher Compose 仅移除在 docker-compose.yml 文件中出现的服务。如果有其他的服务在Rancher 的 stack 里,他们不会被移除,因为 Rancher Compose 不知道他们的存在。

所以 stack 不会被移除,因为 Rancher Compose 不知道stack 里是否还有其他容器。

缺省情况下,附加到容器的卷不会被移除。您可以通过 docker volume ls 查看所有的卷。

pull 命令

Name

Description

—cached-c

只更新存在该镜像缓存的主机,不要拉取新的

# Pulls new images for all services located in the docker-compose.yml file on ALL hosts in the environment
 $ rancher-compose pull
  
 # Pulls new images for all services located in docker-compose.yml file on hosts that already have the image
 $ rancher-compose pull --cached

注意: 不同于 docker-compose pull, 您不可以指定拉取哪些服务的镜像,Rancher Compose 会拉取所有在 docker-compose.yml 里的服务镜像。

upgrade 命令

您可以使用 Rancher Compose 升级在 Rancher 里的服务。请阅读更多关于在何时和怎样更新您的服务.

删除服务/容器

默认情况下,Rancher Compose 不会删除任何东西。 这意味着如果您在一行里有两个 up 命令,第二个 up 是不会做任何事情的。这是因为第一个 up 会创建所有东西并保持运行。甚至您没有传 -d 给 up,Rancher Compose 也不会删除您的服务。要删除服务,您只能使用 rm 。

环境插值

在使用 Rancher Compose 时,docker-compose.yml 和 rancher-compose.yml 文件中可以使用运行 Rancher Compose 的机器中的环境变量。这个特性只在 Rancher Compose 命令中有效,在 Rancher UI 中是没有这个特性的。

怎么使用

在 docker-compose.yml 和 rancher-compose.yml 文件中,您可以引用您机器中的环境变量。如果没有该环境变量,它的值会被替换为空字符串,请注意的是 Rancher Compose 不会自动去除 : 两侧的空字符来适配相近的镜像。例如 <imagename>: 是一个非法的镜像名称,不能部署出容器。它需要用户自己来保证环境变量在该机器上是存在并有效的。

例子

在我们运行 Rancher Compose 的机器上有一个这样的环境变量,IMAGE_TAG=14.04 。

# Image tag is set as environment variable
 $ env | grep IMAGE
 IMAGE_TAG=14.04
 # Run Rancher Compose
 $ rancher-compose up

样例文件 docker-compose.yml

version: '2'
 services:
   ubuntu:
     tty: true
     image: ubuntu:$IMAGE_TAG
     stdin_open: true

在 Rancher 里,一个 ubuntu 服务会使用镜像 ubuntu:14.04 部署。

环境插值格式

Rancher Compose 支持和 Docker Compose 一样的格式。

复制代码version: '2'
 services:
   web:
     # unbracketed name
     image: "$IMAGE"
  
     # bracketed name
     command: "${COMMAND}"
  
     # array element
     ports:
     - "${HOST_PORT}:8000"
  
     # dictionary item value
     labels:
       mylabel: "${LABEL_VALUE}"
  
     # unset value - this will expand to "host-"
     hostname: "host-${UNSET_VALUE}"
  
     # escaped interpolation - this will expand to "${ESCAPED}"
     command: "$${ESCAPED}"

Webhooks

在 Rancher 中,您可以创建接收器钩子。 这些钩子提供了一个可以在Rancher 中触发事件的 URL。比如,接收器钩子可以和监控系统整合来增加或减少服务的容器数量。 在 API -> Webhooks 页面, 您可以查看或创建一个接收钩子。

添加接收器钩子

要创建一个接收器钩子,导航到,API -> Webhooks,点击 添加接收器

  • 填写接收器 名称 以方便识别。
  • 选择您要创建的接收器 类型
  • 基于接收器的类型确定接收器事件。点击 创建。创建成功后,就可以在新创建接收器钩子旁边看到相应的URL。

使用接收器钩子

要使用触发 URL,您需要先发一个 POST 请求到这个 URL。向这个 URL POST 请求不需要在验证头和 body 信息。

接收器钩子的类型

服务扩缩容

要扩缩容一个服务,您必须先配置您的 webhook:

  • 扩大/缩小一个服务(即,添加或移除一个服务中的容器)
  • 在环境中选择服务
  • 一次投放/移除多少容器
  • 服务的最大/最小容器数量
一个用接收器钩子来自动扩缩服容务的示例

使用接收器钩子来扩缩容服务,您可以通过整合外界服务来实现自动扩缩容。在这个示例中,我们使用 Prometheus (普罗米修斯) 来监控服务,通过报警管理程序来发送 POST 请求到触发 URL.

安装 Prometheus

Rancher 应用商店 提供了 Prometheus 监控服务,在 应用商店 中可以找到这个服务。选中Prometheus 然后启动应用商店入口。 在 Prometheus 应用中找到一个名为 prometheus 的服务,这个服务暴露了 9090 端口。在容器中找到 /etc/prom-conf。 Prometheus 的配置文件prometheus.yml 就在 /etc/prom-conf 目录。为了添加告警, 单独创建一个告警文件,在 prometheus.yml 中提供文件的路径。 比如,如果您创建了一个名为 rules.conf 的告警文件,把它加入到 prometheus.yml,在 prometheus.yml 末尾加入如下两行:

rule_files:
  - rules.conf

rules.conf 可以有多个报警配置,下面就是一个报警的配置

/etc/prom-conf/rules.conf 中的告警配置例子
ALERT CpuUsageSpike
IF rate(container_cpu_user_seconds_total{container_label_io_rancher_container_name="Demo-testTarget-1"}[30s]) * 100 > 70
LABELS {
  severity="critical",
  action="up"
}
ANNOTATIONS {
  summary = "ADDITIONAL CONTAINERS NEEDED",
  description = "CPU usage is above 70%"
}

加入报警配置后,重启服务。

添加报警管理程序

要调用接受器钩子, 报警管理程序需要先启用。 您可以把它加入到 Prometheus 应用. 在 Prometheus 应用中点击 添加服务。用 prom/alertmanager 添加服务。添加服务的时记得映射端口9093:9093。服务启动后,在容器中执行命令,更新 etc/alertmanager/config.yml。 在 etc/alertmanager/config.yml 中添加 webhook 的 URL 。这样,当告警被触发时报警管理程序就会向这个 URL 发送 POST 请求。在 etc/alertmanager/config.yml 添加 URL 信息后需要重启服务。

示例 etc/alertmanager/config.yml
route:
  repeat_interval: 5h
  routes:
  - match:
      action: up
    receiver: "webhook-receiver-up"
  - match:
      action: down
    receiver: "webhook-receiver-down"
receivers:
- name: "webhook-receiver-up"
  webhook_configs:
  - url: <WEBHOOK_URL>
    send_resolved: true
- name: "webhook-receiver-down"
  webhook_configs:
  - url: <WEBHOOK_URL>
    send_resolved: true
自动扩缩容

Prometheus和告警管理程序随告警钩子更新后,重启服务器,以确保配置处于最新的激活状态。对于已经添加了告警的服务,服务会自动根据创建的更新器钩子自动扩容或缩容。

主机弹性伸缩

Rancher 可以通过克隆用 Rancherc 创建的, 并且已经存在的主机来增加主机的数量。(即 Docker Machine)。这意味这通过 自定义命令 添加的主机不能进行伸缩。

使用 主机上的标签,主机可以被分组到一起组成一个弹性伸缩组。我们推荐在主机上使用唯一的标签来方便区分弹性伸缩组。任何标签相同的主机,不管它是如何被添加到Rancher的,都会被当作是同一个弹性伸缩组的一部分。创建 webhook 时, 主机上不要求有标签,但是当在弹性伸缩组中使用webhook时,至少要有一个主机带有标签,这样 webhook 才能有一个可以克隆的主机。总之, Rancher 会选择一台在弹性伸缩组中的可克隆主机

要弹性伸缩主机,您必须配置您的 webhook:

  • 扩增/减少主机(即,添加或移除主机)
  • 添加一个主机选择器标签。这个标签是用来把主机分组成一个弹性伸缩组的标签。
  • 选择单次要伸缩的主机数量。
  • 选择主机数量伸缩的上下限。添加主机时,主机数量不能超过上线, 减少时不能低于下限。
  • 如果您创建了一个 webhook 来缩小主机的数量,您可以选者移除主机的优先顺序。
主机弹性伸缩注意事件
  • 主机标签: 标签被用把主机划分为不同的弹性伸缩组。因为这些标签是由用户添加的,在选择,添加,编辑,标签时必须要非常小心。任何添加在主机上的标签都会自动地把这台主机到添加到一个弹性伸缩组。如果这台主机是可克隆的,它可能会被用于克隆出更多主机。任何主机标签的移除都会自动地把相应的主机从弹性伸缩组移除,这台主机也将不再能够被 webhook 服务克隆或移除。
  • 自定义主机: 任何类型的主机都可以被添加到弹性伸缩组中,您只需要在主机上添加一个标签。Rancher 不能用这些主机来克隆或创建出更多主机。
  • 主机克隆: 因为主机扩增既是主机克隆,所有配置,包括资源分配,Docker 引擎等都会在新主机被复制。Rancher 总是会用克隆最旧的主机。
  • 处于错误状态的主机: 任何处于 Error 状态的主机都不会被添加到弹性伸缩组中.
  • 移除主机的顺序: 从 Rancher 中删除主机时,Rancher会根据主机的状态,按以下顺序删除弹性伸缩组中的主机(Inactive, DeactivatingReconnecting 或 Disconnected),最后才会删除处于 active 状态的主机

基于 Docker Hub Webhooks 升级服务

利用 Docker Hub 的 webhooks, 您可以加入 Rancher 的接收器钩子。这样,每当push一个镜像,一个 POST 请求就会被发送到 Rancher 来触发这个触发器钩子。使用这种 webhooks 组合, 您可以实现自治。 这样,每当在 Docker Hub push一个 image:tag, 所有使用了匹配这个镜像版本的服务都会自动被升级。您需要用一个选择器标签来选择匹配的服务,然后再升级选中的服务。标签应该在服务创建时添加。如果服务没有标签,您需要在Rancher中升级服,然后添加供 webhook 使用的标签。

为了升级服务,您必须配置自己的 webhook:

  • 选择要升级的标签
  • 选择标签来找到要升级的服务
  • 确定单次要升级的容器数量(即,批量大小)
  • 确定在升级期间启动下一个容器的秒数(即,批量间歇)
  • 选择是否新容器应该在旧容器停止前启动。创建接受器钩子后,您需要在您的 Docker Hub webhook 中使用触发 URL。当Docker Hub 触发自己的 webhook, 被 Rancher 触发器钩子选中的服务会被升级。Rancher 触发器钩子默认需要 Docker Hub webhook 提供的特定信息。同时使用 Rancher’s 接受器钩子和其它webhook,POST 请求中需要包含以下字段:
{
    "push_data": {
        "tag": <pushedTag>
    },
    "repository": {
        "repo_name": <image>
    }
}

健康检查

Cattle环境中,Rancher通过运行一个叫healthcheck的基础设施服务部署了一套健康检查系统,其原理为在每台主机上部署了healthcheck的容器来实现分布式的健康检查。这些容器在内部利用HAProxy来检查应用的健康状态。一旦容器或服务上启用了健康检查,每个容器将最多被三个运行在不同主机上的healthcheck 容器监控起来。只要有一个HAProxy实例认为其状态正常,该容器将被视为正常。如果所有HAProxy实例都认为其状态不正常,该容器将被视为状态异常。

注意: 该模式下唯一的例外为您的环境中只有一台主机,这种情况下健康检查将在同一台主机上被执行。

Rancher利用了不同网络位置的主机进行健康检查,这种方式比基于客户端的健康检查更高效。利用HAProxy来进行健康检查,Rancher使用户可以在服务和负载均衡上使用相同的健康检查策略。

注意: 健康检查将只能在使用托管网络的服务上生效。如果您选择了其他的网络类型,该服务将不会被监控。

配置

可以通过如下选项来配置健康检查:

检查类型: 有两种检查方式 - TCP连接 (只验证端口是否打开) 以及 HTTP响应2xx/3xx (进行HTTP请求并确保收到正确的回复)。

HTTP 请求: 如果检查类型是 HTTP响应2xx/3xx, 您必须制定一个可以接受查询的URL。 您可以选择方法 (GETPOST, etc) 以及HTTP版本 (HTTP/1.0HTTP/1.1).

端口: 需要进行检查的端口

初始化超时: 在退出初始化之前等待的毫秒数。

重新初始化超时: 在退出重新初始化之前等待的毫秒数。

检查间隔: 在每次检查之间的时间间隔(毫秒)。

检查超时: 在检查未得到回复并超时之前等待的毫秒数。

健康阈值: 在一个不健康容器被标记为健康之前需要收到的健康检查回复的次数。

不健康阈值: 在健康容器被标记为不健康之前需要收到的健康检查回复的次数。

不健康门槛: T当容器被认为是不健康时,有3种选择。不进行操作意味着容器将保持不健康状态。重新创建意味着Rancher会破坏不健康的容器并为服务创建一个新的容器。 重新创建,仅当至少X个容器健康时意味着如果有X多个容器健康,不健康的容器将被破坏并重新创建。

在UI中添加Health Checks

对于服务负载均衡,可以通过导航到Health Check选项卡来添加Health check服务。您可以检查服务的TCP连接或HTTP响应,并更改health check配置的默认值。

通过Rancher Compose添加 Health Checks

使用Rancher Compose,health checks能添加在rancher-compose.yml文件中。

在我们的示例中,如果容器发现不健康,我们会显示三种不同策略的健康检查配置。

version: '2'
 services:
   service1:
     scale: 1
     health_check:
       # Which port to perform the check against
       port: 80
       # For TCP, request_line needs to be '' or not shown
       # TCP Example:
       # request_line: ''
       request_line: GET /healthcheck HTTP/1.0
       # Interval is measured in milliseconds
       interval: 2000
       initializing_timeout: 60000
       unhealthy_threshold: 3
       # Strategy for what to do when unhealthy
       # In this service, no action will occur when a container is found unhealthy
       strategy: none
       healthy_threshold: 2
       # Response timeout is measured in milliseconds
       response_timeout: 2000
   service2:
     scale: 1
     health_check:
       # Which port to perform the check against
       port: 80
       # Interval is measured in milliseconds
       interval: 2000
       initializing_timeout: 60000
       reinitializing_timeout: 60000
       unhealthy_threshold: 3
       # Strategy for what to do when unhealthy
       # In this service, Rancher will recreate any unhealthy containers
       strategy: recreate
       healthy_threshold: 2
       # Response timeout is measured in milliseconds
       response_timeout: 2000
   service3:
     scale: 1
     health_check:
       # Which port to perform the check against
       port: 80
       # Interval is measured in milliseconds
       interval: 2000
       initializing_timeout: 60000
       unhealthy_threshold: 3
       # Strategy for what to do when unhealthy
       # In this service, Rancher will recreate any healthy containers only if there   is at least 1 container
       # that is healthy
       strategy: recreateOnQuorum
       recreate_on_quorum_strategy_config:
         quorum: 1
       healthy_threshold: 2
       # Response timeout is measured in milliseconds
       response_timeout: 2000

故障情况

状况

响应

被监测的容器停止响应Health check。

所有的HAProxy实例将检测到故障,并将容器标记为“不健康”。如果容器是服务的一部分,则Rancher通过其服务HA功能将服务恢复到其预定义的规模。

运行启用来健康检查的容器的主机失去了网络连接或该主机上的代理失去了网络链接。

当主机丢失网络连接时,与Rancher服务连接的Rancher代理也会丢失网络连接。 由于代理不可访问,主机被标记为“重新连接”。这样我们知道了Rancher Server无法连接到该主机的主机代理。对Rancher的健康检查是针对容器本身而不是主机完成的; 因此,容器将无法被所有活动的HAProxy实例访问。如果容器是服务的一部分,则Rancher通过其服务HA功能将服务恢复到其预定义的规模。

运行启用了健康检查的容器的主机完全故障。

当主机遇到完全故障(如断电)时,与Rancher服务连接的Rancher代理也会丢失网络连接。 由于代理不可访问,主机被标记为“重新连接”。这样我们知道了Rancher Server无法连接到该主机的主机代理。对Rancher的健康检查是针对容器本身而不是主机完成的; 因此,容器将无法被所有活动的HAProxy实例访问。如果容器是服务的一部分,则Rancher通过其服务HA功能将服务恢复到其预定义的规模。

主机的代理失败,但主机保持在线,容器正在运行,并且正在进行健康检查。

在这种情况下,与Rancher服务连接的Rancher代理也会丢失网络连接。 由于代理不可访问,主机被标记为“重新连接”。这样我们知道了Rancher Server无法连接到该主机的主机代理。对Rancher的健康检查是针对容器本身而不是主机完成的; 因此,容器将无法被所有活动的HAProxy实例访问。如果容器是服务的一部分,则Rancher通过其服务HA功能将服务恢复到其预定义的规模。

根据health check的结果容器会被标记成绿色或红色状态,根据健康检查的结果,会判断容器是处于绿色或红色状态。如果运行该服务的所有容器处于绿色状态,该服务就处于绿色(或“运行”)的状态。如果运行该服务所有容器都处于红色状态,则服务处于红色(或“停止”)状态。如果Rancher检测到至少一个容器是处于红色状态或正在要变为绿色状态,该服务会处于黄色(或“退化”)的状态。

检测故障所用的时间是通过“间隔”值进行控制的,该值是通过compose或UI创建健康检查时定义的。

注意: 故障恢复操作仅在容器状态变为绿色后执行。也就是说,如果服务的启动时间很长,则容器将不会立即重新启动,因为服务需要超过2000ms才能启动。健康检查首先需要在采取任何其他行动之前将容器变绿。

内部DNS服务

在Rancher中,我们拥有自己的内部DNS服务,允许同一个环境中的任何服务都可以解析环境中的任何其他服务.

应用中的所有服务都可以通过<服务名称>解析,并且不需要在服务之间设置服务链接。 创建服务时,您可以定义服务链接以将服务链接在一起。 对于任何不同应用的服务,您可以通过<服务名称>.<应用名称>而不是<服务名称>来解析。 如果您想以不同的名称解析服务,您可以设置服务链接,以便服务可以由服务别名解析.

通过链接设置服务别名

在UI中,添加服务时,展开服务链接部分,选择服务,并提供别名.

如果您使用Rancher Compose添加服务docker-compose.yml将使用linksexternal_links指令.

version: '2'
 services:
   service1:
     image: wordpress
     # 如果其他服务在同一个应用中
     links:
     # <service_name>:<service_alias>
     - service2:mysql
     # 如果另一个服务是不同的应用
     external_links:
     # <stackname>/<service_name>:<service_alias>
     - Default/service3:mysql

从容器和服务连接

在启动服务时,您可能需要指定只在同一台主机上一起启动服务。 具体的用例包括尝试使用另一个服务中的volume_fromnet时。 当添加一个从容器时,这些服务可以通过他们的名字自动地相互解析。 我们目前不支持通过从容器中的links/external_links来创建服务别名。

当添加一个从容器时,总是有一个主服务和从容器。 它们一起被认为是单个启动配置。 此启动配置将作为一组容器部署到主机上,1个来自主服务器,另一个从每个从容器中定义。 在启动配置的任何服务中,您可以按其名称解析主服务和从容器。 对于启动配置之外的任何服务,主服务可以通过名称解析,但是从容器只能通过<从容器名称>.<主服务名称>来解析。

容器名称

所有容器都可以通过其名称来全局解析,因为每个服务的容器名称在每个环境中都是唯一的。 没有必要附加服务名称或应用名称。

例子

ping同一应用中的服务

如果您执行一个容器的命令行,您可以通过服务名称ping同一应用中的其他服务.

在我们的例子中,有一个名为stackA的应用,有两个服务,foobar.

在执行foo服务中的一个容器之后,您可以ping通bar服务.

$ ping bar
 PING bar.stacka.rancher.internal (10.42.x.x) 58(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.63 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.13 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.07 ms
ping不同应用中的服务

对于不同应用的服务,您可以使用<服务名称>.<应用名称>在不同的应用中ping服务.

在这个例子中,我们有一个名为stackA的应用,它包含一个名为foo的服务,我们有另一个名为stackB的应用,它包含一个名为bar的服务.

如果我们执行foo服务中的一个容器,您可以用bar.stackb来ping.

$ ping bar.stackb
 PING bar.stackb (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.43 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.15 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.27 ms
ping服务中的从容器

取决于您从哪个服务ping,您可以通过<从容器名称><从容器名称>.<主服务名称>来访问从容器服务。

在我们的例子中,我们有一个名为stackA的应用,它包含一个名为foo的服务,它有一个从容器bar和一个名为hello的服务。 我们也有一个应用叫stackB,它包含一个服务world

如果我们执行foo服务中的一个容器,您可以直接用`bar’命令ping它。

# 在`foo`服务中的一个容器中,`bar`是一个从容器。
 $ ping bar
 PING bar.foo.stacka.rancher.internal (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=64 time=0.060 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=64 time=0.111 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=64 time=0.114 ms

如果我们执行在同一个应用中的hello服务的一个容器,您可以通过foo来pingfoo服务和bar.foo来pingbar服务.

# 在`hello`服务中的一个容器内部,这不是服务/从容器的一部分
 # Ping主服务(i.e. foo)
 $ ping foo
 PING foo.stacka.rancher.internal (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.04 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.40 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.07 ms
 # Ping从容器(i.e. bar)
 $ ping bar.foo
 PING bar.foo (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.01 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.12 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.05 ms

如果我们执行world服务中的一个容器,它是不同的应用,您可以通过foo.stacka来pingfoo服务和bar.foo.stacka来ping从容器bar.

# 在`world`服务中的一个容器内,它们位于不同的应用中
 # Ping另一个应用`stacka`中的主服务(i.e. foo)
 $ ping foo.stacka
 PING foo.stacka (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.13 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.05 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.29 ms
 # Ping另一个应用`stacka`中的从容器(i.e. bar)
 $ ping bar.foo.stacka
 PING bar.foo.stacka (10.42.x.x) 56(84) bytes of data.
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.23 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.00 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=0.994 ms
Ping容器名称

从同一个环境下的任何一个容器中,无论它们是否在相同的应用或服务中,您都可以用容器名称来ping其他容器,

在我们的示例中,我们有一个名为stackA的应用,它包含一个名为foo的服务。 我们还有另一个应用叫stackB,它包含一个名为“bar”的服务。 容器的名称是<stack_name>-<service_name>-<number>

如果我们执行foo服务中的一个容器,您可以通过ping来访问bar服务中的相关容器.

复制代码$ ping stackB-bar-1
 PING stackB-bar-1.rancher.internal (10.42.x.x): 56 data bytes
 64 bytes from 10.42.x.x: icmp_seq=1 ttl=62 time=1.994 ms
 64 bytes from 10.42.x.x: icmp_seq=2 ttl=62 time=1.090 ms
 64 bytes from 10.42.x.x: icmp_seq=3 ttl=62 time=1.100 ms

外部DNS服务

应用商店中,Rancher提供了多种的DNS服务并且这些服务可以监听rancher-metadata的事件,并根据metadata的更变生成DNS记录。我们会以Route53作为例子说明外部DNS是如何工作的,但Rancher还有其他由其他DNS服务商提的供社区版服务。

最佳实践

  • 在每个您启动的Rancher环境中,应该有且只有1个 route53 服务的实例。
  • 多个Rancher实例不应该共享同一个 hosted zone

需要配置AWS IAM权限

下面的IAM权限是Route53 DNS所需要的最小权限。请确保您设置的主机AWS安全密钥(Access Key ID / Secret Access Key)或者主机IAM权限至少被配置了如下权限。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:GetHostedZone",
                "route53:GetHostedZoneCount",
                "route53:ListHostedZonesByName",
                "route53:ListResourceRecordSets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource": [
                "arn:aws:route53:::hostedzone/<HOSTED_ZONE_ID>"
            ]
        }
    ]
}

注意: 当使用这个JSON文档在AWS中创建自定义IAM规则时,请使用Route53所在区域或者通配符(’*‘)来替换<HOSTED_ZONE_ID>

启动 Route53 服务

在 应用商店 标签页中,您可以选择 Route53 DNS Stack

为您的应用栈填写 名称,并填写必要的 描述

在 配置选项 中,您需要提供以下信息:

名称


AWS Access Key

访问AWS API的Access key

AWS Secret Key

访问AWS API的Secret key

AWS Region

在AWS中的区域名称。我们建议您填写一个与您服务器相近的区域。他会转换成Rancher Route53发送DNS更新请求的地址。

Hosted Zone

Route53 hosted zone。这个必须在您的Route53实例上预创建。

在完成表单后,点击 创建。一个带有 route53 服务的应用栈将会被创建,您只需要启动这个服务。

使用Route53的服务

route53服务只会为在Host上映射端口的服务生成DNS记录,每一个Rancher生成的DNS记录,他使用以下格式为服务创建一个fqdn:

fqdn=<serviceName>.<stackName>.<environmentName>.<yourHostedZoneName>

在AWS的Route 53中,他会以name=fqdn,value=[服务所在的host的ip地址列表]的一个记录集合呈现。Rancher route53 服务只会管理以.结尾的记录集合。当前TTL的时间为300秒。

一旦DNS记录被设置在AWS的Route 53上,生成的fqdn会返回到Rancher,并会设置 服务.fqdn 字段。您可以在服务下拉菜单的 在API中查看 并查询 fqdn 找到fqdn字段。

当在浏览器使用fqdn,他会被指向到服务中的其中一个容器。如果服务中容器的IP地址发生了变化,这些变化会在AWS的Route 53服务同步更新。由于用户一直在使用fqdn,所有这些更变对用户是透明的。

注意: 在 route53 服务被启动后,任何已经部署并使用了host端口的服务都会获得一个fqdn。

删除 Route53 服务

当 route53 从Rancher被移除,在AWS Route 53服务中的记录并不会被移除。这些记录需要在AWS中手工移除。

为外部DNS使用特定的IP

在默认下,Rancher DNS选择注册在Rancher Server中的主机IP去暴露服务。其中会有一个应用场景是主机在一个私有网络中,但主机将需要使用外部DNS在公网中暴露服务。您需要在启动外部DNS服务前添加一个主机标签,来指定在外部DNS中使用的IP地址。

在启动外部服务前,需要添加以下标签到主机上。标签的值需要是Rancher的Route53 DNS服务上要用到的IP。如果这个标签没有设置在主机上,Rancher的Route53服务将会默认使用主机注册在Rancher上的IP的地址。

io.rancher.host.external_dns_ip=<IP_TO_BE_USED_FOR_EXTERNAL_DNS>

外部服务

您可能会有一些部署在Rancher之外的服务想要整合进Rancher。您可以通过添加一个外部服务的功能将它添加到Rancher集群中。

在UI上添加外部服务

在您的应用上,您可以通过 添加服务 旁边的下拉菜单按钮添加外部服务。选择 外部服务。 或者您在应用层级的页面查看您的应用,同样存在相同的 添加服务 下拉菜单。

您将需要提供一个外部服务的 名称,如果需要的话,提供这个服务的 描述

添加您想要的目标。您可以选择外部的IP或者域名。最后点击 添加

外部服务的IP和域名会在服务中呈现。和Rancher的服务一样,您需要去启动一个外部服务。

添加/删除外部服务目标

在任何时候您都可以编辑您外部服务中的服务目标。在外部服务的下拉菜单中点击 编辑,您可以添加或者移除目标。

使用Rancher Compose添加外部服务

在外部服务中,您可以设置外部IP地址 或者 域名。rancher/external-service 并不是一个真实的镜像,但在 docker-compose.yml 中是必要的。Rancher不会为外部服务创建容器。

docker-compose.yml例子

version: '2'
 services:
   db:
     image: rancher/external-service
   redis:
     image: redis

rancher-compose.yml 使用外部IP的例子

version: '2'
 services:
   db:
     external_ips:
     - 1.1.1.1
     - 2.2.2.2
  
   # Override any service to become an external service
   redis:
     image: redis
     external_ips:
     - 1.1.1.1
     - 2.2.2.2

rancher-compose.yml 使用域名的例子

复制代码version: '2'
 services:
   db:
     hostname: example.com

容器

添加容器

通常,我们建议人们使用services(服务) 添加容器,因为它为用户提供了一些更大的灵活性,但有时我们理解您可能需要升级一个容器。

Infrastructure(基础设施) -> Container(容器)页面中,单击Add Container(添加容器)。任何docker run 支持的参数,同样的Rancher也支持。

  • 提供Name(名称),如果需要,也可提供容器的Description(描述)
  • 提供Image(镜像)使用。您可以使用DockerHub上的任何镜像以及已添加到Rancher的registries 。镜像名称的语法与任何docker run命令相匹配。

镜像名称的语法。默认情况下,我们从docker register中拉取。如果没有指定标签,我们将拉取标签为tag的镜像。

[registry-name]/[namespace]/[imagename]:[version]

  • 如果需要,设置端口映射,这提供了通过主机IP访问容器上暴露端口的方法。在Port Map(端口映射) 部分中,您可以定义用于与容器进行通信的公共端口。您还可以定义用于连接到容器的暴露端口的私有端口。

随机端口映射

如果您想要利用Rancher的随机端口映射,公共端口可以留空,您只需要定义私有端口。私有端口通常是容器上的暴露端口之一。

注意: 当在Rancher中显示端口时,它只会在创建时显示端口。如果端口映射有任何编辑,它不会在docker ps中更新,因为Rancher通过管理iptable规则,使端口完全动态。

  • 在各种选项卡中,Docker中可用的所有选项均可用于Rancher。默认情况下,我们设置了-i -t

如果您选择从Infrastructure(基础设施) -> Containers(容器)页面添加容器,则Rancher会自动为您选择一个主机。否则,如果您选择了一个主机来添加容器,主机将被安装在Security/Host选项卡中。

您还可以向容器添加标签以及应用调度规则。有关标签和调度的更多细节参考这里

  • 当您的填写容器选项完成后,单击Create(创建)

编辑容器


从容器的下拉列表中,您可以选择不同的操作来在容器上执行。在主机或服务器上查看容器时,可以通过将鼠标悬停在容器名称上来查找下拉图标。在Infrastructure(基础设施) -> Containers(容器)中,仅在主机上创建的容器才可以看到下拉图标。通过服务创建的任何容器都不会显示其下拉图标。

您可以随时点击容器名称,这将带您进入容器详细信息页面。在该页面上,下拉菜单位于容器状态旁边的右上角。

当您从下拉菜单中选择Edit(编辑)时,您只能更改容器的名称和说明。Docker容器在创建后是不可变的。唯一可以编辑的是我们存储的东西,但这些不是Docker容器的一部分。这包括重新启动,即使停止并启动它,它仍然是同一个容器。您将需要删除并重新创建一个容器来更改任何其他内容。

注意: 当Rancher暴露端口时,它不会出现在docker ps中,因为Rancher管理iptable规则以使端口完全动态。

您可以克隆,这将预先填充添加容器屏幕与现有容器的所有设置。如果您忘记了某些东西,您可以克隆容器,更改它,然后删除旧的容器。

Changing the Container States

When a container is in a Running state, you can Stop the container. This will stop the container on the host, but will not remove it. After the container is in the Stopped state, you can select Start to have the container start running again. Another option is to Restart the container, which will stop and start the container in one step.

You can Delete a container and have it removed from the host.

当容器处于Running(运行)状态时,您可以Stop(停止)容器。这将停止主机上的容器,但不会将其移除。容器处于暂停状态后,可以选择Start(开始)以使容器再次开始运行。另一个选项是Restart(重新启动)容器,该容器将在一个步骤中停止并启动容器。

您可以使用Delete(删除)使容器从主机中删除。

执行Shell

When you select Execute Shell, it brings you into the container shell prompt.当您选择执行Shell,它将带您进入容器shell提示符。

查看日志

It’s always useful to see what is going on with the logs of a container. Clicking View Logs provides the equivalent of docker logs <CONTAINER_ID> on the host.通过查看日志去查看容器发生的情况是非常有帮助的。单击View Logs(查看日志)相当于docker logs 在主机上。

密文功能

Rancher支持创建密文并在容器中使用该密文(在容器中使用该密文需要部署应用商店里的Rancher Secrets服务)。Rancher通过对接加密后台来保障密文的安全。加密后台可以使用本地的AES密钥或者使用Vault Transit

加密后台设置

默认情况下,Rancher Server会使用本地的AES256密钥来对密文进行加密。加密的密文存储在MySQL数据库里。

使用Vault Transit

如果不想使用本地密钥加密,您可以通过配置Vault Transit来进行密文加密。

在Rancher中配置Vault Transit

在安装Rancher Server之前,需要进行如下Vault Transit相关的配置。

  • 在要运行Rancher Server的主机上安装Vault transit后台。
  • 通过Vault命令行或者API,创建一个叫rancher的加密密钥。
  • 通过Vault命令行或者API,创建一个Vault访问口令,这个访问口令可以通过rancher加密密钥进行加密和解密。
  • 这个访问口令必须具有一个给Rancher Server使用的安全策略,来限制Rancher Server的访问权限。下面列表中的<KEY>就是之前创建的rancher加密密钥
path "transit/random/*" {
     capabilities = ["create", "update"]
   }
  
   path "transit/hmac/*" {
     capabilities = ["create", "update"]
   }
  
   path "transit/encrypt/rancher" {
     capabilities = ["create", "update"]
   }
  
   path "transit/decrypt/rancher" {
     capabilities = ["create", "update"]
   }
  
   path "transit/verify/rancher/*" {
     capabilities = ["create", "update", "read"]
   }
  
   path "transit/keys/*" {
     capabilities = ["deny"]
   }
  
   path "sys/*" {
     capabilities = ["deny"]
   }
  • 启动Rancher Server,并加入相关环境变量来连接Vault。
$ docker run -d --restart=unless-stopped -p 8080:8080 \
       -e VAULT_ADDR=https://<VAULT_SERVER> -e VAULT_TOKEN=<TOKEN_FOR_VAULT_ACCCESS> rancher/server
> **注意:** 请检查运行的[Rancher Server版本](https://www.cnrancher.com/docs/rancher/v1.x/cn/installing-rancher/installing-server/#rancher-server-标签)是否是您想要的。
  • 在Rancher服务启动成功之后,您需要修改Rancher中的service-backend设置。在系统管理 -> 系统设置 -> 高级设置中,找到secrets.backend。它的默认值是localkey,您可以把它修改为vault

注意: 目前Rancher不支持对不同加密后台之间进行切换。

创建密文

您可以在每个Rancher环境里创建密文。这也意味着,密文名称在环境中是唯一的。同一个环境下的任何容器都可以通过配置来共享密文。例如,一个数据库的密码db_password可以被用在数据库容器里,也可以被用在Wordpress容器里。一旦这个密文被创建了,这个密文的密文值就不能被修改了。如果您需要修改一个现有的密文,唯一的方法就是删除这个密文,然后再创建一个新密文。新密文被创建后,使用这个密文的服务需要重新部署。这样容器才能使用新的密文值。

通过Rancher命令行创建密文

在命令行当中有两种方法来创建密文。一种是在标准输入中(stdin)输入密文值,另一种是给命令行传递含有密文的文件名称。

通过标准输入(stdin)创建密文
$ rancher secrets create name-of-secret - <<< secret-value
通过传递密文所在的文件名称来创建密文
$ echo secret-value > file-with-secret
 $ rancher secrets create name-of-secret file-with-secret

通过UI创建密文

点击基础架构 -> 密文。点击添加密文。输入名称密文值然后点击保存

删除密文

备注: 目前Rancher命令行不支持删除密文。

您可以在UI里把密文从Rancher中删除,但是这并不会在已使用该密文的容器中删除该密文文件。如果一台主机上运行着使用该密文的容器,Rancher也不会在该主机上删除该密文文件。

在Rancher中启用密文

为了在容器中使用密文,您要先部署Rancher Secrets服务。您可以把这个服务加到环境模版中,在添加该服务之后部署的新环境里都会含有Rancher Secrets服务。您也可以直接通过应用商店部署该服务。如果您想在现有的环境中部署Rancher Secrets服务,您可以通过应用商店 -> 官方认证,然后搜索Rancher Secrets找到Rancher Secrets服务。如果不部署Rancher Secrets服务的话,您仅仅可以创建密文,但是不能在您的容器里使用这些密文。

向服务/容器中添加密文

当密文被添加到容器中时,密文会被写到一个tmpfs卷中。您可以在容器里和主机上访问这个卷。

  • 在使用该密文的容器中:这个卷被挂载在/run/secrets/.
  • 在运行使用该密文的容器所在的主机上:这个卷被挂载在/var/lib/rancher/volumes/rancher-secrets/.

通过Rancher命令行添加密文到服务中

注意: 密文是在compose文件版本3中被引入的。由于Rancher不支持compose文件版本,所以我们在版本2中加入了密文功能。

您可以在docker-compose.yml里,通过配置服务的secrets值来指定一个或者多个密文。密文文件的名称与在Rancher中加入的密文名称相同。在默认情况下,将使用用户ID0和组ID0创建该密文文件,文件权限为0444。在secrets里将external设置为true确保Rancher知道该密文已经被创建成功了。

基础示例docker-compose.yml
version: '2'
 services:
   web:
     image: sdelements/lets-chat
     stdin_open: true
     secrets:
     - name-of-secret
     labels:
       io.rancher.container.pull_image: always
 secrets:
   name-of-secret:
     external: true

如果您想要修改密文的默认配置,您可以用target来修改文件名,uidgid来设置用户ID和组ID,mode来修改文件权限。

修改密文文件配置示例docker-compose.yml
version: '2'
 services:
   web:
     image: sdelements/lets-chat
     stdin_open: true
     secrets:
     - source: name-of-secret
       target: different-target-filename
       uid: "1"
       gid: "1"
       mode: 0400
     labels:
       io.rancher.container.pull_image: always
 secrets:
   name-of-secret:
     external: true

Racnher可以在创建应用的时候创建密文。您可以通过指定file参数,使Rancher在创建应用并启动服务之前创建密文。该密文值来自您指定的文件内容。

指定多个密文并且在启动服务前创建密文的示例docker-compose.yml
version: '2'
 services:
   web:
     image: sdelements/lets-chat
     stdin_open: true
     secrets:
     - name-of-secret
     - another-name-of-secret
     labels:
       io.rancher.container.pull_image: always
 secrets:
   name-of-secret:
     external: true
   another-name-of-secret:
     file: ./another-secret

通过Rancher UI添加密文到服务中

您可以在创建服务/容器页面的密文页里,向服务/容器中添加密文。

  • 点击添加密文
  • 下拉列表中会列出,已经加入到Rancher中的全部可用密文。您可以选择一个您想要使用的密文。
  • (可选操作) 默认情况下,挂载到容器内的密文文件的名称为密文名。您可以在映射名称栏,给容器中的密文文件设置一个不同的文件名。
  • (可选操作) 如果您想要修改默认的文件所有者和文件权限。您可以点击自定义文件所有者及权限链接来更新配置。您可以修改用户ID,组ID和文件权限。用户ID的默认值为0,组ID的默认值为0,文件权限的默认值为0444
  • 点击 创建.

Docker Hub镜像

Docker在很多自己的官方镜像中都支持通过文件来传递密文。您可以添加以_FILE结尾的环境变量名并且以/run/secrets/NAME>为值的环境变量,来达到这一效果。当在容器启动时,文件中的密文值将会被赋给去掉_FILE的环境变量里。

例如,当您部署一个MySQL容器的时候,您可以配置如下环境变量。

-e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_password

MYSQL_ROOT_PASSWORD环境变量的值,就是您所指定这个文件的内容。这个文件就是我们在Rancher中添加的密文。这样您就可以很方便的从环境变量中获取在Rancher中配置的密文,而不用自己去读取密文文件。但并不是所有镜像都支持这个功能。

已知的安全隐患

被入侵的Rancher Server容器

存储在Rancher中的密文和存储在CI系统(如Travis CI和Drone)中的密文安全程度是一样。由于加密密钥直接存储在Rancher Server容器中,所以如果Rancher Server容器被入侵,全部的密文都能被黑客获取到。Rancher将在以后的版本中努力降低这种情况的安全隐患。

注意: 如果您使用Vault进行加密,您需要创建一个策略来限制Rancher Server所用的token的访问权限。

被入侵的主机

如果一台主机被入侵了,这台主机上所运行的容器中使用到的全部密文,都可以被读取。 但是黑客获取不到其他主机上的额外密文。

容器访问

如果一个用户可以exec进入到容器中,该用户可以通过容器中挂载的卷查看到密文值。可以通过如下方式访问容器:

  • UI点击”执行命令行”
  • Rancher命令行工具
  • Docker原生命令

应用栈

应用包含了一组服务。您可以把多个服务放在一起组成一个应用。

添加应用

应用页,点击添加应用。您需要输入一个名称然后点击创建.

之后会进到这个刚创建的应用页面里。您可以开始在应用里添加服务添加负载均衡添加服务别名,或者添加外部服务

注意: 在启动服务之前,您需要至少向Rancher环境添加一台主机。更多添加主机的内容,请查看文档

您也可以通过导入compose文件来创建应用。在应用创建页面可以导入docker-compose.ymlrancher-compose.yml文件。您可以在创建应用页面里直接上传文件,也可以把文件中的内容通过复制粘贴输入到创建页面上。当您点击创建之后,一个由相关服务组成的应用就创建成功了。通过docker-compose.yml文件来创建的服务,仅会被创建但并不会被启动。您需要手动启动他们。

查看应用中的服务

在应用列表页面,您可以轻松的监控该环境内所有应用的状态。您可以点击应用左侧的加号来展开应用,并查看应用里面的每个服务。 您也可以点击应用名称,进入应用详情页面。

应用详情页面展示了应用内的全部服务。您可以点击服务名称,进入服务详情页面。在服务详情页面,可以点击容器名称,进入容器详情页面。

应用配置

当应用被创建时,Rancher同事生成了docker-compose.yml文件和rancher-compose.yml文件。docker-compose文件可以用在Rancher之外。您可以通过原生的docker-compose命令来启动服务。更多文档请查看docker-compose.

rancher-compose.yml文件包含了Rancher启动服务时所需的额外信息。docker-compose文件内并不支持这些参数。

有了这两个文件,您也用可以用Rancher Compose命令行来启动服务。

查看配置

在应用的下拉列表里,您可以选择查看配置或者点击应用详情页右上角的文件图标

导出配置

下面是导出应用配置的两种方法。

方法一:在应用的下拉菜单里点击导出配置按钮,可以下载一个zip包,包里包括docker-compose.ymlrancher-compose.yml文件。

方法二:在应用的下拉菜单里点击查看配置按钮,可以看到配置详情,点击docker-compose.ymlrancher-compose.yml旁边的按钮,可以将文件内容复制到剪贴板。

查看图形

您可以用另一种方法来查看应用。点击查看图形按钮,您可以通过可视化图形的方式,查看服务之间的关系。存在连接的两个服务,在图中会被用线连起来。

修改服务

可能您创建了不同的Rancher服务。但是在创建完成之后,所有服务的操作下拉菜单都是相同的。例如,服务与负载均衡的下拉菜单是相同的。

容器数量

对服务和负载均衡来说,您可以点击服务详情页面的加号快速对其进行扩容。扩容后,新的容器将会被添加到服务中。

注意: 对于负载均衡,如果您对其扩容的最终数量超过了有可用开放端口的主机数量。负载均衡将会卡在Updating-Active状态。如果卡住了,解决方法是停掉该负载均衡,并且把容器数量修改到和可用主机数量相同。

您也可以通过点击服务下拉菜单的编辑按钮来增加或者减少服务内容器的数量。在编辑服务的弹出框内,您可以通过滑动条来修改容器数量。

修改

在这里可修改的参数是有限的,因为容器在创建之后是不可变的。这也包括重启容器,您停止和启动的都是同一个容器。您所能修改的都是Rancher存储的一些参数,而不是Docker容器本身的参数。如果您想要修改其他参数,您可以通过升级或者克隆这个服务来进行修改。

您可以点击服务下拉菜单中的编辑按钮,来查看您可以修改的参数。您可以修改服务名称,服务描述和服务中容器的数量。如果您在创建服务的时候,忘了增加相关连接。您可以在编辑页面设置连接。

对服务来说,大多数参数都不能被修改,因为容器在创建之后是不可变的。为了摆脱这个限制,您可以克隆一个服务。克隆会创建一个和该服务全部参数都相同的新的服务,您可以在点击创建之前修改您想要更新的参数。

克隆

您可以克隆任何服务,克隆的服务包含原服务的全部配置。但是其他服务里指向到原服务的连接并不会被克隆。您需要通过修改那些服务,把指向原服务的连接指向克隆出来的服务上。

例如:

服务A连接到了服务B。如果克隆服务B,得到服务C。这时服务A并不会连接到服务C。让服务A建立与服务C的连接的唯一方法就是修改服务A,添加指向服务C的连接。

停止

您可以停止某个服务,也可以一键停止应用内全部的服务。如果您想要停掉某个服务,可以点击服务下拉列表里的停止按钮。如果您想要停掉应用里的全部服务,可以点击应用下拉菜单里的停止服务按钮。

删除

您可以单独删除服务也可以删除整改应用。当您选择删除某个服务的时候,这个服务中的容器将会先被停止,然后被从主机上删除。这可能会稍微有些延迟,因为Rancher会先清理主机上的容器,然后才会在UI上显示容器已删除。

数据卷

持久化卷是有状态应用中非常重要的一部分。Rancher使您在多主机环境下使用卷变得非常容易。

术语

卷插件卷驱动同时在Docker和Rancher中使用。他们代表的是同一个东西: 一个Docker卷插件 可以给一个Docker容器提供本地卷或者共享的持久化卷的支持。Rancher卷插件(驱动)目前是以Docker卷插件的形式实现的。并且可以通过docker volume命令行来进行操作,但是这取决于存储技术。卷可以被环境中的某个主机,某些主机或者全部主机访问。Rancher对跨主机使用共享卷的复杂过程进行了封装。例如:rancher-nfs, rancher-ebs 和 pxd (portworx)。

存储驱动是关于容器和镜像是如何在Docker主机上被存储的。例如:aufs, btrfs, zfs, devicemapper等。这些驱动在Rancher的管控范围之外。Rancher UI混合了这个术语,但实际上指的是卷插件卷驱动。更多关于存储驱动的插件信息信息,请查看这里

管理卷

在这一部分,您将会了解如何创建一个可以被容器之间共享的持久化卷。在这里我们将专门使用Rancher命令行

注意: UI可以用来管理除了由local卷驱动创建的卷。

创建卷

您可以通过rancher volume create命令创建一个卷。

$ rancher volume create --driver local app-data

这将创建一个新的名为app-data的本地卷。名称必须由字母数字开头,后面可以接a-z0-9_ (下划线), . (点) 或者- (横杠)。

—driver参数用来指定使用哪个卷驱动。Docker提供了一个local卷驱动。使用这个驱动的卷会将数据保存在主机的文件系统上,并且同一台主机上的任何容器都可以访问该数据。当使用local卷驱动时,其他主机上的任何容器都无法共享这个数据卷。

列出卷

您可以列出环境中的卷。

$ rancher volume ls

如果您创建了一个app-data卷,您可能想知道为什么这个卷没有被列出来。您可以通过添加—all或者-a参数,来查看inactive的卷。

$ rancher volume ls --all

删除卷

您可以通过rancher volume rm命令删除一个卷。

$ rancher volume rm app-data

卷状态

卷有七个不同的状态:inactiveactivatingactivedeactivatingdetachedremoving 和 removed

一个刚刚建好的卷的状态是inactive,直到有容器尝试挂载这个卷。

当容器创建时,关联的卷进入activating状态。一旦容器进入了running阶段,它等容器就会进入active状态。如果容器去挂载一个已经是active状态的卷,这并不会对该卷的状态产生影响。

当全部挂载了这个卷的容器都被开始删除了,这个卷进入deactivating状态。一旦容器被删除成功,卷进入detached状态。

当卷被标记为删除时,它进入一个removing状态。一旦数据被从主机上删除成功,它进入removed状态。被删除的卷不会出现在列出卷的结果里。但是它们将会继续在Rancher API里存在一段时间,这是为了调试和审计的目的。

卷作用域

卷可以有不同的作用域。这指的是Rancher管理卷的不同级别。

目前,您可以通过Rancher Compose文件来创建不同类型的卷。有作用域的卷必须定义在docker-compose.yml文件中最顶层的volumes部分。默认情况下,将创建应用栈级别的卷,但是您可以通过修改其值来创建不同作用域的卷。

如果最顶层的定义被遗漏了,卷的行为将会有所不同。请查看更多详情。

通过UI您只能创建环境级别的卷。

应用级别的卷

应用级别的卷是由创建它的应用来管理的。主要的好处是这种卷的生命周期是其应用生命周期的一部分,将由Rancher自动管理。

应用级别的存储卷,应用中的服务如果引用了相同的卷都将共享同一个存储卷。不在该应用内的服务则无法使用此存储卷。

Rancher中,应用级别的存储卷的命名规则为使用应用名称为前缀来表明该卷为此应用独有,且会以随机生成的一组数字结尾以确保没有重名。在引用该存储卷时,您依然可以使用原来的卷名称。比如,如果您在应用 stackA中创建了一个名为foo 的卷, 您的主机上显示的卷名称将为stackAfoo<randomNumber>,但在您的服务中,您依然可以使用foo

创建示例

下面的例子中,将会创建应用级别的卷data

注意: 因为在文件中最顶层的volumes部分不存在其他配置值,所以这个卷的级别为应用级。

version: '2'
 services:
   redis:
     image: redis:3.0.7
     volumes:
     - data:/data
 volumes:
   data:
     driver: local

在上面的例子中,我们特意指定了卷驱动为local。默认情况下,卷驱动的值就是local。最简洁的定义data的方法是设置一个空值{}。请看下面的例子。

volumes:
  data: {}

在通过Rancher命令行创建应用之后,您可以列出卷来确认data卷已经创建成功。这个卷的名称将为<STACKNAME>_data<RANDOM_NUMBER>

注意: 应用级别的卷可以被其他应用挂载。应用级别的卷并不是一种安全的机制。仅是为了管理卷的生命周期。

环境级别的卷

环境级别的卷可能需要被环境中的全部容器共享。Rancher会把容器调度到卷所在的主机,从而保证容器可以挂载这个卷。

环境级别的卷并不能在某个环境中的全部的主机上自动共享。您需要借助一个共享驱动(例如:rancher-nfs)来实现跨主机共享。这意味着一个由local卷驱动创建的环境级别卷只能在一台主机上被访问到,所以使用该卷的容器都会被调度到这台主机上。

您在创建一个使用环境级别卷的服务之前,Rancher需要您先创建这个环境级别的卷。您可以使用任何配置好的卷驱动来创建卷。

环境级别卷的主要好处是,您可以轻松的在不同的服务应用之间共享数据。尤其是当这些应用和服务有着不同的生命周期需要被独立管理。用户可以对卷进行完全的管控

共享的环境级别卷示例

首选,创建一个环境级别的卷从而使其他应用共享这个卷。

$ rancher volume create --driver local redis-data-external

为了创建一个环境级别的卷,在最顶层的volume部分,您需要添加external: true

version: '2'
 services:
   redis:
     image: redis:3.0.7
     volumes:
     - redis-data-external:/data
 volumes:
   redis-data-external:
     driver: local
     external: true  # 如果没有这个定义,将会创建一个应用级别的卷。

注意: 如果在volume中没有定义external: true,这个卷将会被创建为一个应用级别的卷.

在通过Rancher命令行创建应用之后,您可以列出卷来确认redis-data-external卷已经创建成功并且状态为active

注意: 对一个服务进行扩容和缩容的时候,将会挂载或卸载同一个共享的卷。

任何新的应用都可以挂载同一个redis-data-external卷。最简单的方法就是复制compose文件中最顶层的volume部分。

volumes:
   redis-data-external:
     driver: local
     external: true

V1与V2版本的Compose对比

直到这里,我们讨论的一直是Docker V2 Compose的卷。如果您没有在V2 compose文件中的最顶层定义volumes,它将会按照Docker V1 Compose的方式来处理卷。

您也可能用到了Docker V1 Compose。在V1 compose文件中,不支持最顶层的volume部分。所以这时卷只能被定义在服务里。Rancher会把V1的卷定义直接传递给Docker。所以,卷不会被自动删除同时也无法确保可以正常调度到卷所在的主机。为了解决这个在V1卷下的调度问题,您需要使用调度标签

注意: 请尽可能不要使用V1版本的Compose。

V1版本的Compose示例

注意这里没有volumes部分;这个配置在V1中不存在。

etcd:
   image: rancher/etcd:v2.3.7-11
   volumes:
   - etcd:/pdata

V1和V2版本的Compose文件

Docker compose的V2版本是V1版本的超集;两个格式都可以被使用。我们先创建一个环境级别的卷。

$ rancher volume create --driver local etcd_backup

这个例子中,etcd_backup是一个V2的环境级别的卷,etcd是一个V1的卷。因为没有定义volume,这隐式的将etcd设置为了V1的卷。

version: '2'
 services:
   etcd:
     image: rancher/etcd:v2.3.7-11
     environment:
       EMBEDDED_BACKUPS: 'true'
       BACKUP_PERIOD: 5s
       BACKUP_RETENTION: 15s
     volumes:
     - etcd:/pdata
     - etcd_backup:/data-backup
 volumes:
   etcd_backup:
     driver: local
     external: true

最后,如果您定义了一个空的volumes,这个卷将会被视为一个V1卷。这等同于yaml中完全没有volumes这部分。

复制代码version: '2'
 volumes: {}

服务

  • Cattle对服务采用标准Docker Compose术语,并将基本服务定义为从同一Docker镜像创建的一个或多个容器。一旦服务(消费者)链接到同一个应用中的另一个服务(生产者)相关的DNS记录 会被自动创建,“消费”服务的容器可以发现这些容器。在Rancher创建服务的其他好处包括:
  • 服务高可用性(HA):Rancher会不断监控服务中的容器状态,并主动管理以确保所需的服务实例规模。当健康的容器小于(或者多于)正常服务所需容器规模,主机不可用,容器故障或者不能满足健康检查就会被触发。
  • 健康检查: Rancher通过在主机上运行healthcheck的基础设施服务,从而实现了容器和服务的分布式健康检查系统。这个healthcheck服务内部使用HAProxy来检查应用程序的运行状况。当在单个容器或服务上启用健康检查时,Rancher将监控每个容器。

用户界面中的服务选项

在以下示例中,我们假设您已经创建了一个应用, 设置了您的主机,并准备好开始构建应用程序来。

我们将在添加服务的过程中了解一些服务的选项,最后将介绍如何创建一个连接到Mongo数据库的LetsChat应用程序。

应用中,您可以通过单击添加服务按钮添加服务。也可以在应用列表中添加服务 ,每个单个应用都可以看到添加服务按钮。

数量部分,您可以使用滑块来指定要为服务启动的容器的数量。或者,您可以选择总是在每台主机上运行一个此容器的实例。使用此选项时,您的服务将被部署到该环境中的任何主机上。如果您在调度选项卡中创建了调度规则,则Rancher将仅在符合调度规则的主机上启动容器。

您还需要输入名称,如果需要,还可以输入服务描述

为服务设置所需的镜像。您可以使用DockerHub上的任何镜像,以及已添加到您的环境中的任何镜像仓库。镜像名称的语法与docker run命令中使用的语法相同。

镜像名称的语法。默认情况下,我们从Dockerhub中拉取。如果没有指定标签,我们将拉取标签为tag的镜像。

[registry-name]/[namespace]/[imagename]:[version]

在镜像名称下方,有一个复选框创建前总是拉取镜像。默认情况下,这是被勾选的。选择此选项后,每次在主机上启动容器的时候,都将始终尝试拉取镜像,即使该镜像已被缓存在了该主机上。

选项

Rancher努力与Docker保持一致,我们的目标是,支持任何docker run所支持的选项。端口映射和服务链接显示在主页面上,但所有其他选项都在不同的选项卡中。

默认情况下,服务中的所有容器都以分离模式运行,例如:docker run命令中的-d

端口映射

当配置了映射端口后,您可以通过主机上的公共端口访问容器暴露的端口。在端口映射部分中,需要设置暴露在主机上的端口。该端口将流量指向您设置的私有端口。私有端口通常是容器上暴露的端口(例如:镜像的Dockerfile中的EXPOSE)。当您映射一个端口时,Rancher将会在启动容器之前检查主机是否有端口冲突。

当使用端口映射时,如果服务的容器规模大于具有可用端口的主机数量时,您的服务将被阻塞在正在激活状态。如果您查看服务的详细信息,您将可以看到Error状态的容器,这表明容器由于无法在主机上找到未被占用的端口而失败。该服务将继续尝试,如果发现有主机/端口可用,则该服务将在该主机上启动一个容器。

注意: 当在Rancher中暴露端口时,它只会显示创建时暴露端口。如果端口映射有任何改变,它不会在docker ps中更新,因为Rancher通过管理iptable规则,来实现端口动态变更的。

随机端口映射

如果您想要利用Rancher的随机端口映射,公共端口可以留空,您只需要定义私有端口。

链接服务

如果您的环境中已经创建了其他服务,则可以将已有服务链接到您正在创建的服务。正在创建的服务中的所有容器都会链接到目标服务中的所有容器。链接就像docker run命令中的—link功能一样。

链接是基于Rancher内部DNS的附加功能,当您不需要按服务名称解析服务时,可以使用链接。

Rancher 选项

除了提供docker run支持的所有选项之外,Rancher还通过UI提供了额外选项。

健康检查

如果Rancher中主机不能正常工作来(例如:处于reconnectinginactive状态),您需要配置健康检查,以使Rancher将服务中的容器调度到其他的主机上。

注意: 健康检查仅适用于托管网络的服务。如果您选择任何其他网络,则不能被监察到。

健康检查选项卡中,您可以选择检查服务的TCP连接或HTTP响应。

阅读有关Rancher如何处理健康检查的更多详细信息。

标签/调度

标签选项卡中,Rancher允许将任何标签添加到服务的容器中。标签在创建调度规则时非常有用。在调度选项卡中,您可以使用主机标签,容器/服务标签,和容器/服务名称来创建您服务需要的调度规则。

阅读有关标签与调度的更多细节。

在UI中添加服务

首先,我们通过设置数量为1个容器的服务来创建我们的数据库,给它设置名称database,并使用mongo:latest镜像。不需要其他的配置,点击创建。该服务将立即启动。

现在我们已经启动了我们的数据库服务,我们将把web服务添加到我们的应用中。这一次,我们将服务规模设置为2个容器,创建一个名称为web并使用sdelements/lets-chat作为镜像的服务。我们没有暴露Web服务中的任何端口,因为我们将添加负载均衡来实现服务访问。我们已经创建了数据库服务,我们将在服务链接目标服务选择数据库服务,在名称中填写mongo。点击创建,我们的LetsChat应用程序已准备好了,我们马上可以用负载均衡服务来暴露端口了。

Rancher Compose中的服务选项

阅读更多关于配置Rancher Compose的细节。

Rancher Compose工具的工作方式和Docker Compose一样,并支持V1和V2版本的docker-compose.yml文件。要启用Rancher支持的功能,您还可以使用扩展或重写了docker-compose.yml的rancher-compose.yml文档。例如,rancher-compose.yml文档包含了服务的scalehealthcheck

如果您不熟悉Docker Compose或Rancher Compose,我们建议您使用UI来启动您的服务。您可以通过单击应用的下拉列表中的查看配置来查看整个应用的配置(例如:与您的应用等效的docker-compose.yml文件和rancher-compose.yml文件)。

链接服务

在Rancher中,环境中的所有服务都是可以通过DNS解析的,因此不需要明确设置服务链接,除非您希望使用特定的别名进行DNS解析。

注意: 我们目前不支持将从服务与主服务相关联,反之亦然。阅读更多关于Rancher内部DNS工作原理

应用中的服务都是可以通过服务名称service_name来解析的,当然,您也可以通过链接来使用其他名称进行解析。

例子 docker-compose.yml
version: '2'
 services:
   web:
     labels:
       io.rancher.container.pull_image: always
     tty: true
     image: sdelements/lets-chat
     links:
     - database:mongo
     stdin_open: true
   database:
     labels:
       io.rancher.container.pull_image: always
     tty: true
     image: mongo
     stdin_open: true

在这个例子中,mongo可以解析为database。如果没有链接,web服务需要通过服务名称database来解析数据库服务。

对于不同应用中的服务,可以使用service_name.stack_name对服务进行解析。如果您希望使用特定别名进行DNS解析,则可以在docker-compose.yml中使用external_links

例子 docker-compose.yml
version: '2'
 services:
   web:
     image: sdelements/lets-chat
     external_links:
     - alldbs/db1:mongo

在此示例中,alldbs应用中的db1服务将链接到web服务。在web服务中,mongo将可解析为db1。没有外部链接时,db1.alldbs将可解析为db1

注意: 跨应用的服务发现受环境的限制(特意设计的)。不支持应用的跨环境发现。

使用 Rancher Compose 添加服务

阅读更多关于配置Rancher Compose的详情.

我们将创建与上面通过UI创建的相同示例。首先,您将需要创建一个docker-compose.yml文件和一个rancher-compose.yml文件。使用Rancher Compose,我们可以一次启动应用程序中的所有服务。如果没有rancher-compose.yml文件,则所有服务将以1个容器的规模启动。

例子 docker-compose.yml

version: '2'
 services:
   web:
     labels:
       io.rancher.container.pull_image: always
     tty: true
     image: sdelements/lets-chat
     links:
     - database:mongo
     stdin_open: true
   database:
     labels:
       io.rancher.container.pull_image: always
     tty: true
     image: mongo
     stdin_open: true

例子 rancher-compose.yml

# 您想要拓展的效果服务
 version: '2'
 services:
   web:
     scale: 2
   database:
     scale: 1

创建文件后,可以将服务部署到Rancher Server。

#创建并启动一个没有环境变量的服务并选择一个应用
 #如果没有提供应用名称,应用的名称将是命令运行的文件夹名称
 #如果该应用没有存在于Rancher中,它将会被创建
 $ rancher-compose --url URL_of_Rancher --access-key <username_of_environment_api_key> --secret-key <password_of_environment_api_key> -p LetsChatApp up -d
  
 #创建并运行一个已经设置好环境变量的服务
 $ rancher-compose -p LetsChatApp up -d

从服务

Rancher支持通过使用从服务的概念对服务进行分组,从而使一组服务可以同时进行调度和扩缩容。通常创建具有一个或多个从服务的服务,来支持容器之间共享卷(即—volumes_from)和网络(即—net=container)。

您可能希望您的服务的使用volumes_fromnet去连接其他服务。为了实现这一点,您需要在服务直接建立一个从属关系。通过从属关系,Rancher可以将这些服务作为一个单元进行扩容和调度。例如:B是A的从服务,Rancher始终将A和B作为一对进行部署,服务的数量规模将始终保持一致。

如果您有多个服务总需要部署在同一主机上,您也可以通过定义从属关系来实现它。

当给一个服务定义一个从服务时,您不需要链接该服务,因为从服务会自动被DNS解析到。

当在服务中使用负载均衡时,而该服务又拥有从服务的时候,您需要使用主服务作为负载均衡器的目标。从服务不能成为目标。了解更多关于Rancher内部DNS的详情。

在UI中添加从服务

要设置一个从服务,您可以点击+添加从容器按钮,按钮位于页面的数量那部分。第一个服务被认为是主服务,后面每个附加的从服务都是辅助服务。

通过Rancher Compose添加从服务

要设置sidekick关系,请向其中一个服务添加标签。标签的键是io.rancher.sidekicks,该值是从服务。如果您要将多个服务添加为从服务,可以用逗号分隔。例:io.rancher.sidekicks: sidekick1, sidekick2, sidekick3

主服务

无论哪个服务包含sidekick标签都被认为是主服务,而各个sidekicks被视为从服务。主服务的数量将用作sidekick标签中所有从服务的数量。如果您的所有服务中的数量不同,则主服务的数量将用于所有服务。

当使用负载均衡器指向带有从服务的服务时,您只能指向主服务,从服务不能成为目标。

Rancher Compose里面的从容器例子:

例子docker-compose.yml

version: '2'
 services:
   test:
     tty: true
     image: ubuntu:14.04.2
     stdin_open: true
     volumes_from:
     - test-data
     labels:
       io.rancher.sidekicks: test-data
   test-data:
     tty: true
     command:
     - cat
     image: ubuntu:14.04.2
     stdin_open: true

例子 rancher-compose.yml

version: '2'
 services:
   test:
     scale: 2
   test-data:
     scale: 2
Rancher Compose里面的从服务例子:多服务使用来自同一个服务volumes_from

如果您有多个服务,他们将使用相同的容器去做一个volumes_from,您可以添加第二个服务作为主服务的从服务,并使用相同的数据容器。由于只有主服务可以作为负载均衡的目标,请确保选择了正确的服务作为主服务(即,具有sidekick标签的服务)。示例 docker-compose.yml

复制代码version: '2'
 services:
   test-data:
     tty: true
     command:
     - cat
     image: ubuntu:14.04.2
     stdin_open: true
   test1:
     tty: true
     image: ubuntu:14.04.2
     stdin_open: true
     labels:
       io.rancher.sidekicks: test-data, test2
     volumes_from:
     - test-data
   test2:
     tty: true
     image: ubuntu:14.04.2
     stdin_open: true
     volumes_from:
     - test-data

服务别名

通过添加一个服务别名,可以提供一种别名的方式而不是直接指向服务。

在UI上添加服务别名

在您的应用中,您通过 添加服务 旁边的下拉按钮,并点击服务别名去添加一个服务别名。同样的,如果您在应用层级页面,同样的 添加服务的下拉菜单也会在每个应用页面中。

您需要提供服务别名的 名称,以及填写必要的 描述名称 将是您选择服务的服务别名。

选择一个或多个您想添加到别名的目标。可用目标列表是当前应用中已经创建的服务。最后点击 创建

服务别名中生效的服务列表会在服务层级页面显示。和我们的服务一样,您需要启动这个服务别名才能生效。

添加/移除服务

在任何时候您都可以在服务别名中修改目标服务。在服务的下拉菜单中点击 编辑,您可以添加更多的服务到这个别名中,或者移除现有的服务。

通过Rancher Compose添加服务别名

一个服务别名创建了一个指向服务的指针。在以下的例子中,web[.stack-name.rancher.internal]会被解析为容器web1以及web2的IP地址。rancher/dns-service并不是一个真实的镜像,但是他需要填写在docker-compose.yaml。不会为别名服务创建额外的容器。

Example docker-compose.yml

复制代码version: '2'
 services:
   web:
     image: rancher/dns-service
     links:
     - web1
     - web2
  
   web1:
     image: nginx
  
   web2:
     image: nginx

服务升级

在部署服务之后, 您可能想要通过修改服务来升级应用。例如,镜像已经被更新了,您想要部署服务的新版本。由于Docker容器是不可变的,为了修改服务,您需要销毁旧的容器并部署新的容器。Rancher提供了两种升级服务的方法。推荐的方式是服务内升级,这种方式会停掉旧的容器并且在这个服务内启动新的容器。 RancherUI仅支持服务内升级。您也可以通过Rancher Compose命令行进行服务内升级。 另一种升级方式为替换式升级。这种升级方式会删除旧的服务并创建一个新的服务,只有通过Rancher Compose命令行才能进行替换式升级。

注意: 如果您是想对您的服务进行扩容,您可以修改服务页面的数量参数,或者也可以用过Rancher Compose命令行来进行服务扩容。 rancher-compose scale <服务名>=<新的容器数量>.

服务内升级

通过UI进行升级

任何服务都可以通过UI来进行升级。和部署服务类似,您之前选择的全部Docker参数都会被保留,您可以修改这些参数的值。额外还有一些升级专用的选项:

  • 批量大小:服务中的容器升级会被分成几批,批量大小代表每次您想要停掉的旧容器数量和启动的新容器数量。例如一共有10个容器要升级,当批量大小为2时,每次会升级2个容器,停掉2个旧的,启动2个新的,分5批完成升级。
  • 批量间隔:每次批量升级间隔的时间,例如10个容器,每次升级5个,批量时间为5秒。在完成5个容器升级后,在等待5秒后,会升级剩下的5个容器。
  • 启动行为:默认情况下,旧的容器会先停止,然后再启动新的容器。您可以选择先启动新的容器,再停止旧的容器。在配置好了新的服务参数和升级专用参数以后,点击升级

当全部旧的容器被停掉,新的容器启动成功之后,服务将会变成 Upgraded 状态。在这个阶段,您应该去测试您的新服务来确保服务可以正常工作。然后,可以通过点击升级完成来完成升级。如果您的服务出现了异常,您可以点击回滚来回退到之前的服务。

通过Rancher Compose命令行进行服务升级

通过Rancher Compose命令行进行服务内升级时,现有服务会按照docker-compose.yml中的内容进行升级,服务中旧的容器会被删除。升级相关的参数需要传递给rancher-compose up命令。如果命令加上—upgrade参数,docker-compose.yml内定义的服务如果发生了改变,这个服务会被按照文件中的配置进行升级。和在UI上进行升级操作一样,服务内升级分为两个步骤,需要用户确认来完成升级或者执行回滚。

第一步: 进行升级

升级的时候,您可以通过docker-compose.yml文件升级整个应用栈或者升级应用内指定的服务。

# 升级应用栈内的全部有变化的服务
 $ rancher-compose up --upgrade
 # 升级应用栈内指定的服务 (例如仅升级service1和service2)
 $ rancher-compose up --upgrade service1 service2
 # 强制触发服务升级,即使在docker-comopse.yml文件中未被改变的服务,也将被升级。
 $ rancher-compose up --force-upgrade

升级选项

选项

描述

—pull-p

升级前,在每台运行该容器的主机上执行docker pull操作,尝试获取新镜像

-d

在后台运行升级

—upgrade-u—recreate

仅升级在docker-compose.yml中配置有变化的服务

—force-upgrade—force-recreate

不论服务的配置是否有变化,全部进行升级

—confirm-upgrade-c

升级完成后自动确认升级成功,删除旧的容器

—rollback-r

回滚到之前的版本

—batch-size “2”

每批升级的容器个数

—interval “1000”

每批升级的时间间隔

拉取镜像

在升级时,您可能需要在部署容器之前执行docker pull,因为主机上可能已经有了该镜像的缓存。您可以通过—pull参数,在部署容器之前拉取最新的镜像。

# 在升级时,强制每台主机在部署容器之前,执行docker pull更新镜像
 $ rancher-compose up --upgrade --pull

批量大小

在默认的情况下,每批升级服务的2个容器。您可以通过—batch-size参数来设置每批所更新的镜像数量。

# 升级服务时每次会启动3个新的容器
 # 直到新的容器达到设置的数量
 $ rancher-compose up --upgrade --batch-size 3

批量间隔

在默认的情况下,每次新的容器启动和旧的容器停止之间有2秒的时间间隔。您可以通过—interval来覆盖这个时间间隔,参数后面跟着的时间间隔是以毫秒为单位的。

# 将服务的升级间隔设置为30秒。
 # service1和service2的新容器启动和他们的旧容器停止之间为30s
 $ rancher-compose up --upgrade service1 service2 --interval "30000"

在停止旧的容器前启动新的容器

在默认的情况下,服务内升级会先停掉旧的容器,再启动新的容器。如果想要先启动新的容器,再停止旧的容器,您需要在rancher-compose.yml文件中写入如下内容。

version: '2'
 services:
   myservice:
     upgrade_strategy:
       start_first: true
# 通过上面的rancher-compose.yml配置,会先启动myservice服务中的新容器,然后再停掉旧容器。
 $ rancher-compose up --upgrade myservice
第二步:确认升级

在您验证该服务升级成了并且可以正常工作了之后,您需要在Rancher里确认升级成功。这种设计是因为有时候您可能想要回滚您的服务。当您点击完成升级后,就不能再进行回滚操作了

# 下面的命令可以确认升级成功,不需要在UI上点击完成升级。
 $ rancher-compose up --upgrade --confirm-upgrade

回滚

在升级过程完成之后,您的服务可能发生了问题不能正常工作。Rancher支持回滚功能,可以把服务回滚到升级之前的状态。回滚操作只能在点击完成升级之前进行。

# 回滚到之前的版本
 $ rancher-compose up --upgrade --rollback

替换式升级

替换式升级会通过创建一个新的服务来替换旧的服务,而不是在同一个服务内停止旧的容器并启动新的容器。只有Rancher Compose命令行才支持这种升级方式,UI上不可以。替换式升级操作非常简单:

$ rancher-compose upgrade service1 service2

service2是您想要在Rancher里启动的新服务的名字。service1是您想要在Rancher里停止并替换的服务。当service2被部署之后,service1里面的容器会被删除,但是服务本身并不会从Rancher里删除,只是容器的数量会变为0。

这两个服务名都需要被定义在docker-compose.yml里面。service1只需要把服务名在yml文件中定义即可,Rancher Compose会用这个名字来找到相应的服务。service2则需要在yml文件中定义全部需要的配置,Rancher Compose命令行会根据文件中的配置来部署service2

示例 docker-compose.yml

version: '2'
 services:
   service1:
   # 这里不需要额外的参数,因为service1已经在运行中了。
   service2:
     image: wordpress
     links:
     - db:mysql

默认情况下,全部的指向service1的负载均衡或者是服务连接都会被自动更新并指向service2。如果您不想创建这些连接,您可以通过设置来禁止连接创建

注意: 升级服务时并不需要rancher-compose.yml文件。 在默认情况下,新服务中的容器数量和旧服务中的容器数量相同。您可以通过传递—scale参数来设置容器的数量。

升级过程中的容器数量

直到新的服务中的容器数量和旧的服务中的容器数量达到您设定的数量时,旧服务中的容器才会被删除。

示例:

$ rancher-compose upgrade service1 service2 --scale 5

service1中有两个容器,您想要把它升级为service2service2中想要启动5个容器。

service1

service2

备注

2

0

service1在运行中,并且有两个容器。

2

2

service2每批启动两个容器(默认批量数量)。

2

4

service2第二批时,再启动两个容器。

1

4

在上一步,新旧容器的数量总和为6个,已经超过目标数量的5个。这时会停掉service1里的一个容器,使新旧容器数量为5个。

1

5

service2再启动一个容器,达到目标的5个容器。

0

5

service1删除最后一个容器。

Upgrade命令的参数

upgrade命令,可以接受几个参数来自定义升级行为。

参数

描述

—batch-size “2”

每批升级的容器个数

—scale “-1”

最终要运行的容器数量

—interval “2000”

每批升级的时间间隔

—update-links

更新指定服务的连接

—wait-w

等待升级完成

—pull-p

升级前,在每台运行该容器的主机上执行docker pull操作,尝试获取新镜像

—cleanup-c

在升级完毕后,删除旧的服务

批量大小

在默认情况下,升级的时候每次启动2个新服务的容器。您可以通过—batch-size参数来设置每批启动的容器个数。

# 升级的过程中,每批将会启动3个service2的容器,直到service2的容器数量达到设定的值。
 $ rancher-compose upgrade service1 service2 --batch-size 3
最终数量

在默认情况下,新服务的容器数量和旧服务之前运行的容器数量相同。您可以通过传递—scale参数,来设置新服务所运行容器的数量。

#设置service2升级后的容器数量为8个
 $ rancher-compose upgrade service1 service2 --scale 8

注意: 旧服务中的容器并不根据批量大小的数量来删除。当新旧服务中的容器数量和,达到设置的最终数量时,旧服务中的容器将会被停止并删除。

批量间隔

在默认的情况下,每次新的容器启动和旧的容器停止之间有2秒的时间间隔。您可以通过—interval来覆盖这个时间间隔,参数后面跟着的时间间隔是以毫秒为单位的。

# 将服务的升级间隔设置为30秒。
 # service1和service2的新容器启动和他们的旧容器停止之间为30s
 $ rancher-compose upgrade service1 service2 --interval "30000"
更新连接

在默认情况下,全部指向旧服务的连接会被设置到新服务上。如果您不想让那些服务连接到新的服务的话,您可以通过—update-links="false"参数来禁止这些连接的创建。

# 不把指向service1中的连接设置到service2上
 $ rancher-compose upgrade service1 service2 --update-links="false"
等待升级完毕

在默认情况下,Rancher Compose命令行在向Rancher发出升级命令后就会立刻退出。退出的时候升级可能还没执行完毕。通过传递—wait或者-wupgrade命令,Rancher Compose命令行将在旧的容器被停止且新容器启动后才退出。

# 等待升级完成
 $ rancher-compose upgrade service1 service2 --wait
拉取新镜像

在升级时,您可能想在部署容器之前执行docker pull,因为主机上可能已经有了该镜像的缓存。您可以通过—pull或者-p参数,在部署容器之前拉取最新的镜像。

# 在启动容器时,先执行docker pull获取最新镜像
 $ rancher-compose upgrade service1 service2 --pull
清除旧的服务

在默认情况下,升级完成后旧的服务不会被删除,只是旧服务中容器的数量为0。如果您觉得并不需要回滚,也不需要保留旧的服务配置。您可以通过传递—cleanup或者-c参数到upgrade命令。这个参数会同时应用—wait参数,因为Rancher Compose命令行需要等待升级完成,然后才能删掉旧的服务。

# 升级完成后删除service1
 $ rancher-compose upgrade service1 service2 --cleanup

服务调度

在Rancher中,您可以根据严格或宽松的关联与斥关联规则,在特定主机上安排服务。 这些规则可以比较主机上的标签或主机上容器上的标签,以确定容器应该安排在哪个主机上。

默认情况下,Rancher将检测主机上的端口冲突,如果端口不可用,则不会将需要此端口的容器调度到这一主机上。

这个核心调度逻辑内置于Rancher,但Rancher还支持位于我们外部调度器中的其他调度能力,这是我们基础设施服务的一部分。其他调度能力包括:

标签和调度规则

不管是通过服务或者负载均衡来创建容器时,我们都提供了为容器创建标签的选项,并且可以安排您想要放置容器的主机。 对于本节的剩余部分,我们将使用服务这个术语,但这些标签也适用于负载均衡器(即特定类型的服务)

调度规则提供了让Rancher选择要使用哪个主机的灵活性。 在Rancher中,我们使用标签来帮助定义调度规则。 您可以根据需要在容器上创建任意数量的标签。 通过多个调度规则,您可以完全控制容器在哪些主机上创建。 您可以要求在具有特定主机标签,容器标签或名称或特定服务的主机上启动该容器。 这些调度规则可以帮助您创建容器对主机的黑名单和白名单。

在UI中添加标签

对于添加服务,可以在标签选项卡中添加标签。 对于添加负载均衡,也可以在标签选项卡中找到添加标签。

通过向负载均衡添加标签,每个负载均衡容器将接收该标签,该标签是一个键值对。 在Rancher中,我们使用这些容器标签来帮助定义调度规则。 您可以根据需要在负载均衡上创建任意数量的标签。 默认情况下,Rancher已经在每个容器上添加了系统相关的标签。

在UI中调度选项

对于服务负载均衡,标签可以在调度选项卡中找到。

对于 服务,我们提供了两个选项来确定在哪里启动容器。

选项1:在指定主机上运行 全部 容器

通过选择此选项,容器/服务将在特定主机上启动。 如果您的主机掉线,则容器也将离线。 如果您从容器页面创建一个容器,即使有端口冲突,容器也将被启动。 如果创建一个数量大于1且服务端口冲突的服务,则您的服务可能会停留在 Activating 状态,直到您编辑正确的服务数量为止。

选项2:为每一个容器自动选择符合调度规则的主机

通过选择此选项,您可以灵活地选择调度规则。 遵循所有规则的任何主机都是可以启动容器的主机。 您可以通过点击 + 按钮添加规则。

对于负载均衡,只有选项2可用,因为端口冲突。 您只能添加调度规则。 点击 调度 选项卡。 您可以通过点击 添加调度规则 按钮添加任意数量的调度规则。

对于每个规则,您可以选择规则的条件。 有四种不同的条件,它们定义了遵守规则的严格程度。 字段确定要应用规则的字段。 是要检查字段的值。 如果您启动了一个服务或负载均衡,Rancher将根据每个主机的负载来扩展容器在适用主机上的分发。 根据所选择的条件将确定适用的主机是什么。

注意: 对于添加服务/添加负载均衡,如果您在数量那里选择了 总是在每台主机上运行一个此容器的实例,则只有主机标签将显示为可能的字段。

条件

  • 必须 或 不能:Rancher只会使用与字段和值匹配或不匹配的主机。 如果Rancher找不到符合这些条件的所有规则的主机,您的服务可能会停留在 Activating 状态。 该服务将不断尝试找到容器的主机。 要修复此状态,您可以编辑服务的数量或添加/编辑将满足所有这些规则的其他主机。
  • 应该不应该:Rancher将尝试使用匹配字段和值的主机。 在没有匹配所有规则的主机的情况下,Rancher将逐个删除软约束(应该/不应该规则),直到主机满足剩余的约束。

字段

  • 主机标签:当选择要用于容器/服务的主机时,Rancher将检查主机上的标签,看它们是否与提供的键/值对匹配。 由于每个主机都可以有一个或多个标签,所以Rancher会将键/值对与主机上的所有标签进行比较。 将主机添加到Rancher时,可以向主机添加标签。 您还可以使用主机下拉菜单中的编辑选项来编辑主机上的标签。 活动主机上的标签列表可从关键字段的下拉列表中找到。
  • 容器标签:选择此字段时,Rancher会查找已经具有与键/值对匹配的标签的容器的主机。 由于每个容器都可以有一个或多个标签,所以Rancher会将键/值对与主机中每个容器上的所有标签进行比较。 容器标签位于容器的标签选项中。 在容器启动后,您将无法编辑容器标签。 为了创建具有相同设置的新容器,您可以克隆容器或服务,并在启动之前添加标签。 运行容器上的用户标签列表可从关键字段的下拉列表中找到。
  • 服务名称: Rancher将检查主机上是否有一个具有特定名称的服务。 如果在稍后的时间,该服务名称将更改或不活动/已删除,该规则将不再有效。 如果您选择此字段,则该值将需要以应用名称/服务名称的格式。 运行服务的列表可从值字段的下拉列表中获得。
  • 容器名称: Rancher会检查一个主机是否有一个具有特定名称的容器。 如果稍后时间,容器有名称更改或不活动/已删除,该规则将不再有效。 运行容器的列表可从值字段的下拉列表中获得。

在Rancher Compose中添加标签

Rancher根据docker-compose.yml文件中定义的labels来决定如何安排一个服务的容器。 所有带有调度的标签都将在docker-compose.yml文件中使用。 Rancher通过3个主要组件定义了调度规则:条件,字段和值。 条件决定了Rancher遵守规则的严格程度。 字段是要比较的项目。 价值是您在字段上定义的。 在介绍一些例子之前,我们将广泛讨论这些组件。

调度条件

当我们编写我们的调度规则时,我们对每个规则都有条件,这说明了Rancher如何使用规则。亲和条件是当我们试图找到一个符合我们的价值的字段。反亲和条件是当我们试图找到一个不符合我们价值的字段时。

为了区分亲和力和反亲和度,我们在标签名称中添加_ne来表示标签是符合字段和值。

规则也有硬条件和软条件。

一个硬条件相当于说必须不能。 Rancher只会使用匹配或不匹配字段和值的主机。如果Rancher找不到符合这些条件的所有规则的主机,您的服务可能会停留在 Activating 状态。该服务将不断尝试找到容器的主机。要修复此状态,您可以编辑服务的数量或添加/编辑一台主机来满足所有这些规则。

一个软条件相当于应该不应该。 Rancher将尝试使用与该字段和值相匹配的主机。在没有匹配所有规则的主机的情况下,Rancher将逐个删除软约束(应该/不应该规则),直到主机满足剩余的约束。

为了区分 must 和 should 条件,我们将“_soft”添加到我们的标签名称中,以表明标签是应该尝试匹配字段和值。

字段

Rancher能够与主机标签,容器标签,容器名称或服务名称的值进行比较。 标签前缀是Rancher用来定义哪个字段将被评估的用法。

字段

标签前缀

主机标签

io.rancher.scheduler.affinity:host_label

容器标签/服务名称

io.rancher.scheduler.affinity:container_label

容器名称

io.rancher.scheduler.affinity:container

请注意,服务名称中没有特定的前缀。 当Rancher创建服务时,会将系统标签添加到服务的所有容器中,以指示应用和服务名称。

当我们创建标签的关键字时,我们从一个字段前缀(例如io.rancher.scheduler.affinity:host_label)开始,根据我们正在寻找的条件,我们附加我们想要的条件类型。 例如,如果我们希望容器在不能等于(即_ne)主机标签值的主机上启动,则标签键将是io.rancher.scheduler.affinity:host_label_ne

您可以使用这些值来定义要检查的字段。 如果您有两个值要与同一条件和字段进行比较,则需要为标签名称使用一个标签。 对于标签的值,您需要使用逗号分隔列表。 如果有多个具有相同键的标签(例如io.rancher.scheduler.affinity:host_label_ne),则Rancher将使用与标签键一起使用的最后一个值覆盖任何先前的值。

labels:
   io.rancher.scheduler.affinity:host_label: key1=value1,key2=value2

全局服务

将服务提供到全局服务中相当于在UI中的每个主机上选择总是在每台主机上运行一个此容器的实例。 这意味着将在环境中的任何主机上启动一个容器。 如果将新主机添加到环境中,并且主机满足全局服务的主机要求,则该服务将自动启动。

目前,全局服务只支持使用硬条件的主机标签字段。 这意味着只有在调度时才会遵守与主机标签相关的标签,并且必须不能等于该值。 任何其他标签类型将被忽略。

例子 docker-compose.yml
version: '2'
 services:
   wordpress:
     labels:
       # 使wordpress成为全局服务
       io.rancher.scheduler.global: 'true'
       # 使wordpress只在具有key1 = value1标签的主机上运行容器
       io.rancher.scheduler.affinity:host_label: key1=value1
       # 使wordpress只在没有key2 = value2标签的主机上运行
       io.rancher.scheduler.affinity:host_label_ne: key2=value2
     image: wordpress
     links:
     - db: mysql
     stdin_open: true

使用主机标签查找主机

将主机添加到Rancher时,您可以添加主机标签。 调度服务时,您可以利用这些标签来创建规则来选择要部署服务的主机。

使用主机标签的示例
labels:
   # 主机必须有`key1 = value1`的标签
   io.rancher.scheduler.affinity:host_label: key1=value1
   # 主机不得有`key2 = value2`的标签
   io.rancher.scheduler.affinity:host_label_ne: key2=value2
   # 主机应该有`key3 = value3`的标签
   io.rancher.scheduler.affinity:host_label_soft: key3=value3
   # 主机应该没有`key4 = value4`的标签
   io.rancher.scheduler.affinity:host_label_soft_ne: key4=value4
自动创建的主机标签

Rancher会自动创建与主机的linux内核版本和Docker Engine版本相关的主机标签。

Key

Value

描述

io.rancher.host.linux_kernel_version

主机上的Linux内核版本 (例如3.19)

主机上运行的Linux内核的版本

io.rancher.host.docker_version

主机上的Docker版本(例如1.10.3)

主机上运行的Docker Engine版本

io.rancher.host.provider

云提供商信息

云提供商名称(目前仅适用于AWS)

io.rancher.host.region

云提供商区域

云提供商区域(目前仅适用于AWS)

io.rancher.host.zone

云提供商可用区

云提供商可用区(目前仅适用于AWS)

labels:
 # 主机必须运行Docker版本1.10.3
 io.rancher.scheduler.affinity:host_label: io.rancher.host.docker_version=1.10.3
 # 主机必须不运行Docker 1.6版
 io.rancher.scheduler.affinity:host_label_ne: io.rancher.host.docker_version=1.6

注意: Rancher不支持在具有>=特定版本的主机上调度容器的概念。 您可以使用主机调度规则来创建特定的白名单和黑名单,以确定您的服务是否需要特定版本的Docker Engine。

用容器标签查找主机

向Rancher添加容器或服务时,可以添加容器标签。 这些标签可以用于您希望规则与之进行比较的字段。 提醒:如果将全局服务设置为true,则无法使用。

注意:如果容器标签有多个值,Rancher会查看主机上所有容器上的所有标签,以检查容器标签。 多个值不需要在主机上的同一容器上。

使用容器标签的示例
labels:
   # 主机必须有一个标签为`key1=value1`的容器
   io.rancher.scheduler.affinity:container_label: key1=value1
   # 主机不能有一个标签为`key2=value2`的容器
   io.rancher.scheduler.affinity:container_label_ne: key2=value2
   #主机应该有一个标签为`key3=value3`的容器
   io.rancher.scheduler.affinity:container_label_soft: key3=value3
   # 主机应该没有一个标签为`key4=value4`的容器
   io.rancher.scheduler.affinity:container_label_soft_ne: key4=value4
服务名称

当Rancher Compose启动服务的容器时,它也会自动创建多个容器标签。 因为检查一个特定的容器标签正在寻找一个key=value,所以我们可以使用这些系统标签作为我们规则的关键。 以下是在Rancher启动服务时在容器上创建的系统标签:

标签


io.rancher.stack.name

$${stack_name}

io.rancher.stack_service.name

$${stack_name}/$${service_name}

注意: 使用io.rancher.stack_service.name时,该值必须为应用名称/服务名称的格式。

 {stack_name} {service_name}也可以在任何其他标签中的docker-compose.yml文件中使用,并在服务启动时进行评估。

使用服务名称的示例
labels:
   # Host必须有一个服务名称为`value1`的容器
   io.rancher.scheduler.affinity:container_label: io.rancher.stack_service.name=stackname/servicename

查找具有容器名称的主机

向Rancher添加容器时,可以给每个容器一个名称。 您可以使用此名称作为希望规则进行比较的字段。 提醒:如果将全局服务设置为true,则无法使用。

使用容器名称的示例
labels:
   # 主机必须有一个名为`value1`的容器
   io.rancher.scheduler.affinity:container: value1
   # 主机不能有一个名称为`value2`的容器
   io.rancher.scheduler.affinity:container_ne: value2
   # 主机应该有一个名称为`value3`的容器
   io.rancher.scheduler.affinity:container_soft: value3
   # 主机应该没有一个名为`value4`的容器
   io.rancher.scheduler.affinity:container_soft_ne: value4

示例

示例1:

典型的调度策略可能是尝试在不同的可用主机之间部署服务的容器。 实现这一点的一个方法是使用反相关性规则来关联自身:

labels:
   io.rancher.scheduler.affinity:container_label_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}

由于这是一个很强的反相关性规则,如果比例大于可用主机数量,我们可能会遇到问题。 在这种情况下,我们可能需要使用软反相关性规则,以便调度程序仍然允许将容器部署到已经具有该容器的主机。 基本上,这是一个软规则,所以如果没有更好的选择存在,它可以被忽略。

labels:
   io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}

示例2:

另一个例子可能是将所有容器部署在同一个主机上,而不考虑哪个主机。 在这种情况下,可以使用对其自身的软亲合力。

labels:
   io.rancher.scheduler.affinity:container_label_soft: io.rancher.stack_service.name=$${stack_name}/$${service_name}

如果选择了自己的硬约束规则,则第一个容器的部署将失败,因为目前没有运行该服务的主机。

调度标签表

标签

描述

io.rancher.scheduler.global

true

将此服务指定为全局服务

io.rancher.scheduler.affinity:host_label

key1=value1,key2=value2, etc…

容器必须部署到具有标签key1=value1key2 = value2的主机上

io.rancher.scheduler.affinity:host_label_soft

key1=value1,key2=value2

容器应该被部署到具有标签key1=value1key2=value2”的主机

io.rancher.scheduler.affinity:host_label_ne

key1=value1,key2=value2

容器不能被部署到具有标签key1=value1key2=value2的主机

io.rancher.scheduler.affinity:host_label_soft_ne

key1=value1,key2=value2

容器不应该被部署到具有标签key1=value1key2=value2的主机

io.rancher.scheduler.affinity:container_label

key1=value1,key2=value2

容器必须部署到具有标签key1=value1key2=value2的容器的主机上。 注意:这些标签不必在同一个容器上。 可以在同一主机内的不同容器上。

io.rancher.scheduler.affinity:container_label_soft

key1=value1,key2=value2

容器应该部署到具有运行标签key1=value1key2=value2的主机上

io.rancher.scheduler.affinity:container_label_ne

key1=value1,key2=value2

容器不能部署到具有运行标签key1=value1key2=value2的容器的主机上

io.rancher.scheduler.affinity:container_label_soft_ne

key1=value1,key2=value2

容器不应该被部署到具有标签key1=value1key2=value2的容器的主机上

io.rancher.scheduler.affinity:container

container_name1,container_name2

容器必须部署到具有名称为container_name1container_name2运行的容器的主机上

io.rancher.scheduler.affinity:container_soft

container_name1,container_name2

容器应该被部署到具有名称为container_name1container_name2运行的容器的主机上

io.rancher.scheduler.affinity:container_ne

container_name1,container_name2

容器不能部署到具有名称为container_name1container_name2运行的容器的主机上

io.rancher.scheduler.affinity:container_soft_ne

container_name1,container_name2

容器不应该被部署到具有容器名称为container_name1container_name2运行的主机

标签

Rancher在服务/容器和主机上使用标签来帮助管理Rancher的不同功能。

Rancher Compose标签使用指南

标签用于帮助Rancher启动服务并利用Rancher的功能。下列的标签索引用于帮助用户使用Rancher Compose来创建服务。 这些标签在UI上有对应关系,不需要额外添加到服务上。

Key

Value

描述

io.rancher.sidekicks

服务名称

用来定义哪些服务属于从容器

io.rancher.loadbalancer.target.SERVICENAME

REQUEST_HOST:SOURCE_PORT/REQUEST_PATH=TARGET_PORT

用于判定 L7 Load Balancing

io.rancher.container.dns

true

服务能够使用基于Rancher DNS的服务发现来解析其他服务,并能被其他服务解析。 如果您需要此DNS服务,且网络设置为主机,则此标签是必需的.

io.rancher.container.hostname_override

容器名称

用于将容器的主机名设置为容器的名称 (例如: StackName_ServiceName_CreateIndex)

io.rancher.container.start_once

true

用于设置容器只运行一次,并在容器为停止状态时显示active状态。

io.rancher.container.pull_image

always

用于在部署容器之前始终拉取新的镜像.

io.rancher.container.requested_ip

IP于10.42.0.0/16的地址空间

允许您选择容器的特定IP。从v1.6.6版本开始,服务内的容器将会使用配置的多个IP地址中的可用地址,直到这些地址全被占用。这些地址要用逗号隔开,例如10.42.100.100, 10.42.100.101。 在v1.6.6之前,只有服务中的一个容器可以使用这个特定IP。注意:如果IP在主机上不可用,则容器将以随机IP开始.

io.rancher.container.dns.priority

service_last

在服务域之前使用主机的DNS搜索路径。 保证主机将从/etc/resolv.conf搜索后再对*.rancher.internal搜索。

io.rancher.service.selector.container

[_Selector Label Values]($04f722c3643b5d22.md#选择器标签)

用于服务,以支持选择独立的容器来加入DNS服务。 注意:作为独立容器,任何服务操作都不会影响独立容器(即停用/删除/编辑服务,健康检查等)。

io.rancher.service.selector.link

Selector Label Values

用于服务以允许服务基于服务标签链接到服务。 例如: Service1具有标签io.rancher.service.selector.link:foo = bar。 任何添加到Rancher的具有foo=bar标签的服务将自动链接到Service1。

io.rancher.scheduler.global

true

用于设置全局服务

io.rancher.scheduler.affinity:hostlabel

主机标签的Key Value配对

用于根据主机标签在主机上编排容器

io.rancher.scheduler.affinity:container_label

容器标签的Key Value配对

用于根据容器标签或服务名称在主机上编排容器

io.rancher.scheduler.affinity:container

容器名称

用于根据容器名称在主机上安排容器

io.rancher.lb_service.target

[_Target Service Label Values]($04f722c3643b5d22.md#目标服务标签)

用于配置负载均衡,以便将流量转发到与负载均衡位于同一主机上的容器。

注意: 对于以io.rancher.scheduler.affinity为前缀的标签,根据您想要匹配的方式(即相等或不相等,hard或soft规则)会有轻微的变化。 更多细节可以在这里找到这里.

选择器标签

使用 选择器标签(即io.rancher.service.selector.linkio.rancher.service.selector.container),Rancher可以通过标签识别服务/容器,并将它们自动链接到服务。 将在以下两种情况下进行评估。 情景1是将 选择器标签 添加到服务时。 在情景1中,对所有现有标签进行评估,以查看它们是否与 选择器标签 匹配。 情景2是服务已经有 选择器标签 时。 在情景2中,检查添加到Rancher的任何新服务/容器,看看它是否符合链接条件。 选择器标签 可以由多个要求组成,以逗号分隔。 如果有多个要求,则必须满足所有要求,因此逗号分隔符作为 AND 逻辑运算符。

# 其中一个容器标签必须具有一个等于`foo1`的键,并且值等于`bar1`
 foo1 = bar1
 # 其中一个容器标签必须具有一个等于`foo2'的键,值不等于`bar2`
 foo2 != bar2
 #其中一个容器标签必须有一个等于`foo3`的键,标签的值不重要
 foo3
 #其中一个容器标签必须有一个等于`foo4`的键,值等于`bar1`或`bar2`
 foo4 in (bar1, bar2)
 #其中一个容器标签必须有一个等于`foo5'的键和'bar3`或`bar4`以外的值
 foo5 notin (bar3, bar4)

注意: 如果标签有中包含逗号的标签,则选择器将无法与标签匹配,因为 选择器标签 可以匹配任何没有关联值的键。 例如: io.rancher.service.selector.link: foo=bar1,bar2的标签将转换为任何服务必须具有一个标签为foo的键值,并且值等于bar1 另一个带有等于bar2的标签。 它不会选择一个键等于foo,并且值等于bar1,bar2的标签的服务。

逗号分隔列表的示例

service1:
   labels:
     # 添加选择器标签来接收其他服务
     io.rancher.service.selector.link: hello != world, hello1 in (world1, world2), foo = bar

在此示例中,将链接到service1的服务需要满足以下所有条件:

  • 具有键等于hello并且值不等于world的标签
  • 具有键等于“hello1”但值可以等于world1world2的标签
  • 具有键等于foo和值等于bar的标签以下示例,service2在部署时会自动链接到service1
service2:
    labels:
       hello: test
       hello1: world2
       foo: bar

服务上的系统标签

除了Rancher Compose可以使用的标签之外,Rancher在启动服务时还会创建一系列系统标签。

Key

描述

io.rancher.stack.name/io.rancher.project.name

根据应用名称创建

io.rancher.stack_service.name/io.rancher.project_service.name

根据服务名称创建

io.rancher.service.deployment.unit

根据部署的从容器服务创建

io.rancher.service.launch.config

基于从容器服务的配置创建。

io.rancher.service.requested.host.id

根据该服务安排在哪个主机上创建

主机标签

主机标签 可以在主机注册期间添加到主机,创建后可通过编辑在主机中添加。

Key

Value

描述

io.rancher.host.external_dns_ip

用于外部DNS的IP, 例如: a.b.c.d

用于外部DNS服务,并需要对DNS记录进行编程使用主机IP以外的IP

自动创建的主机标签

Rancher会自动创建与主机的linux内核版本和Docker Engine版本相关的主机标签。 这些标签可以用于调度.

Key

Value

描述

io.rancher.host.linux_kernel_version

主机上的Linux内核版本 (例如3.19)

主机上运行的Linux内核的版本

io.rancher.host.docker_version

主机上的Docker版本(例如1.10.3)

主机上运行的Docker Engine版本

io.rancher.host.provider

云提供商信息

云提供商名称(目前仅适用于AWS)

io.rancher.host.region

云提供商区域

云提供商区域(目前仅适用于AWS)

io.rancher.host.zone

云提供商可用区

云提供商可用区(目前仅适用于AWS)

本地Docker标签

io.rancher.container.network | true| 将此标签添加到docker run命令中,以将Rancher网络添加到容器中

目标服务标签

负载均衡可以配置为将流量优先分发于同负载均衡为同一主机的目标容器。 根据标签的值,负载均衡将被配置为将流量定向到指定的容器,或者将流量的优先级设置为某些指定的容器。 默认情况下,负载平衡器以Round-robin算法将流量分发到目标服务下的所有容器。

Key

Value

描述

io.rancher.lb_service.target

only-local

只能将流量转发到与负载均衡为相同主机的容器上。 如果同一主机上没有目标服务的容器,则不会将流量转发到该服务。

io.rancher.lb_service.target

prefer-local

将流量优先于同负载均衡容器为同一主机上的容器。 如果在同一主机上没有目标服务的容器,则流量将被路由到其他拥有目标服务容器的宿主机上。

虚拟主机

By default, launching virtual machines (VMs) in Rancher is disabled. To enable launching VMs, any admin can enable virtual machines in Rancher in the Admin -> Settings -> Virtual Machines section. Select Enabled and click Save.默认情况下,Rancher中启动虚拟机(VMs)的功能是停用的。任何admin 用户可以在Rancher的 系统管理 -> 系统设置 -> 虚拟机 下开启启动虚拟机的功能。选择 启用 的选择框并点击保存。

启动VM的主机要求

  • Ubuntu
  • RancherOS - 需要在cloud-config中开启 userland-proxy 配置
复制代码   #cloud-config
    rancher:
      docker:
        extra_args: [--userland-proxy=true]

添加VM

在 基础架构 -> 虚拟机,点击 添加虚拟机 并设置您的虚拟机配置。

在镜像名称选项中,当前Rancher只支持 rancher/vm-ubuntu。用户名/密码是ubuntu/ubuntu

点击创建

容器创建后,点击容器的下拉菜单并且点击 打开命令行 去登录虚拟机。

负载均衡

Rancher支持多种负载均衡驱动,通过在它之上建立代理规则,可以将网络及应用流量分发至指定的容器中。负载均衡的目标服务中的容器都会被Rancher自动注册为负载均衡的目标。在Rancher中,将负载均衡加入到应用中是一件非常容易的事情。

默认情况下,Rancher提供一个基于HAProxy的托管的负载均衡,它可以被手动扩容至多台主机。在接下来的例子中将会涉及到负载均衡中不同的配置项,这些配置项主要以HAProxy为参考。我们计划支持除HAProxy以外的其他负载均衡驱动,但这些配置项都会是相同的。

我们使用round robin算法分发流量至目标服务。这个算法可在自定义HAProxy.cfg中进行自定义。另外,您可以配置负载均衡来将流量分发至与负载均衡容器处于相同主机的目标容器。通过给负载均衡设置一个特定的标签,能够将负载均衡的目标限定在同一台主机中的目标容器(例如 io.rancher.lb_service.target=only-local),或者优先转发至同一台主机中的目标容器(例如: io.rancher.lb_service.target=prefer-local)。

我们将会查看在UIRancher Compose中的负载均衡的配置项,并且给出UIRancher Compose的用例。

如何在UI上新增一个负载均衡

我们将为我们在添加服务部分中创建的“letschat”应用新增一个负载均衡.

首先,我们从添加一个负载均衡服务开始,点击”添加服务“旁边的下拉图标,找到添加负载均衡并点击它。

进入添加页面后,容器数量默认是1,填入“名称”,如“LetsChatLB”。

端口规则下,访问选择默认的公开协议选择默认的HTTP。请求端口填入80目标选择letschat服务, 并且端口填入8080

点击创建

现在,让我们来实际感受一下负载均衡。在应用视图下, 有一个连接到80端口的超链接,这是负载均衡中的源端口。如果您点击它,将会在您的浏览器中自动新开一个页签,并指向负载均衡服务所在的主机。请求将会被重定向到其中一个”LetsChat“容器。如果您刷新浏览器,负载均衡服务会把新的请求重定向到“LetsChat”服务下的其他容器中。

页面上的负载均衡选项

Rancher提供一个基于HAProxy的容器来重定向流量至目标服务。

注意: 负载均衡只会在那些使用托管网络的服务中生效,其他网络模式都不会生效。

点击添加服务旁边的下拉图标,找到添加负载均衡并点击它。

您能使用滑块选择数量,就是负载均衡使用多少个容器。或者,您可以选择总是在每台主机上运行一个此容器的实例。使用这一个选项, 您的负载均衡容器数量将会随着您环境下的主机数量增减而增减。如果您在调度部分设定了调度规则,Rancher将会在满足规则的主机上启动负载均衡。如果您的环境下新增了一台不满足调度规则的主机,负载均衡容器不会在这一台主机中启动。

注意: 负载均衡容器的扩缩容不能超过环境下主机的数量,否则会造成端口冲突,负载容器服务将会被阻碍在activating状态。它会不断去尝试寻找可用的主机并开启端口,直到您修改它的数量或者添加主机.

您需要提供负载均衡的名称,如果有需要的话,您可以添加描述

接下来,您可以定义负载均衡的端口规则。有两种规则类型可供创建。用于目标为特定的已存在的服务的服务规则和用于匹配一定选择规则的选择器规则

当创建了多条服务和选择器规则的时候,请求头和路径规则将会自顶向下按显示在UI上的顺序匹配。

服务规则

服务规则指的是端口指向目标容器的规则。

访问选项栏中,您可以决定这个负载均衡端口是否可以被公网访问(就是说是否可以从主机以外访问)或者仅仅在环境内部访问。默认情况下,Rancher假定您希望被公网访问,但是如果您希望仅仅在环境内部被访问,您可以选择内部

选择协议选项栏。获取更多关于我们协议选项的信息。如果您选择了需要SSL终端(如 https or tls),您将需要在SSL终端标签页中新增您的认证信息。

接下来,您可以针对流量的来源填写请求头信息端口 和 路径

注意: 42 端口不能被用作负载均衡的源端口,因为它被用于健康检查

请求头信息/路径

请求头信息是HTTP请求头中的host的属性。请求路径可以是一段特殊的路径。您可以任意设置其中一个或者两者都设置。

例子:
domain1.com -> Service1
domain2.com -> Service2

domain3.com -> Service1
domain3.com/admin -> Service2
通配符

当基于HOST值设置路由时,Rancher支持通配符。所支持的语法如下。

*.domain.com -> hdr_end(host) -i .domain.com
domain.com.* -> hdr_beg(host) -i domain.com.
目标服务和端口

每一个服务规则,您都可以选择您想要的目标服务。这些服务列表是基于该环境下所有的服务清单的。每一个服务,您还能选择与之配套的端口。服务上的私有端口通常就是镜像所暴露的端口。

选择器规则

在选择器规则中,您需要填写一个选择器标签而不是特定的服务。选择器基于服务的标签来选择目标服务。当负载均衡被创建的时候,选择器规则将会针对环境下现有的任意一个服务来计算看是否为可匹配的服务。后面新增的服务或者对标签进行修改都会拿来与选择器标签进行匹配。

对于每一个源端口,您都可以添加相应的请求头信息路径选择器标签是基于目标的,您能指定一个特定的端口接收转发到服务上的流量。服务上的私有端口通常就是镜像所暴露的端口。

例子: 2 选择器规则
  • 源端口: 100; 选择器: foo=bar; 端口: 80
  • 源端口: 200; 选择器: foo1=bar1; 端口: 80
  • 服务A有一个 foo=bar 标签,它将会匹配第一条规则. 任何指向100的流量都会被转发到服务A。
  • 服务B有一个foo1=bar 标签,它将会匹配第二条规则. 任何指向200的流量都会被转发到服务B。
  • 服务C有foo=barfoo1=bar1两个标签,它将会匹配两条规则. 任何指向200100的流量都会被转发到服务C.

注意: 目前,如果您想要将一条选择器规则应用于多个主机名/路径上,您需要使用Rancher Compose在目标服务上去设置主机名/路径。

SSL会话终止

SSL会话终止标签提供了添加用于httpstls协议证书的能力。在证书下拉框中,您可以为负载均衡选择主证书。

添加证书前,请阅读如何添加证书.

为负载均衡添加多个证书是可以实现的。这样相应的证书会基于请求主机名(查看 服务器名称指示)展示给客户端。这个功能可能在那些不支持SNI(它会获取主要证书)的老客户端上失效。对于现代客户端,我们会在能匹配到的列表中提供证书,如果没有匹配成功,就会提供主证书。

负载均衡的会话粘性

您可以点击选择负载均衡的会话粘性。会话粘性就是您的cookie策略。

Rancher支持以下两种选项:

  • : 这个选项意味着不会设置cookie策略
  • 创建新的Cookie: 这个选项意味着在您的应用之外会创建cookie。这个cookie是由负载均衡设置在请求与响应中的。这就是会话粘性策略。

自定义haproxy.cfg

由于Rancher基于HAProxy来搭建负载均衡,所以您能自定义HAproxy的配置。您在这里定义的配置都会被添加到Rancher生成的配置的最后面。

自定义HAProxy配置的例子
global
    maxconn 4096
    maxpipes 1024

defaults
    log global
    mode    tcp
    option  tcplog

frontend 80
    balance leastconn

frontend 90
    balance roundrobin

backend mystack_foo
    cookie my_cookie insert indirect nocache postonly
    server $IP <server parameters>

backend customUUID
    server $IP <server parameters>

标签/调度负载均衡

我们支持向负载均衡添加标签并且调度负载均衡在哪启动。点击这里查看更多关于标签和调度的信息。

用Rancher Compose 添加负载均衡

在这,我们将一步步为我们之前在创建服务章节创建的”letschat”应用设置一个负载均衡。

点击这里查看更多关于如何配置一个Rancher Compose。

注意:: 在我们的例子中,我们会使用<version>作为负载均衡镜像的标签。每一个Rancher版本都有特定的,被负载均衡所支持的lb-service-haproxy版本。

我们将会建立一个和我们上面在UI中所使用到的例子一样范例。首先您需要创建一个docker-compose.yml文件和一个rancher-compose.yml文件。使用Rancher Compose,我们可以启动一个负载均衡

Example docker-compose.yml

version: '2'
services:
  letschatlb:
    ports:
    - 80
    image: rancher/lb-service-haproxy:<version>

Example rancher-compose.yml

version: '2'
services:
  letschatlb:
    scale: 1
    lb_config:
      port_rules:
      - source_port: 80
        target_port: 8080
        service: letschat
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000

Rancher Compose 中的负载均衡配置

Rancher 提供一个基于HAProxy的容器来做负载均衡。

注意: 负载均衡仅仅在使用托管网络的服务中生效。其他的网络选择都不会生效。

负载均衡可以像其他任何一个服务一样被调度。点击这里获取更多关于在Rancher Compose中使用负载均衡的例子。

负载均衡由暴露在主机上的端口和负载均衡配置组成,这些配置包括针对不同目标服务的特定端口规则,自定义配置和会话粘性策略。

当与含有从容器的服务一起使用的时候,您需要将主服务作为目标服务,就是那些含有sidekick标签的服务。

源端口

当创建一个负载均衡的时候,您可以将任意一个您想要的端口暴露在主机上。这些端口都可以被用做负载均衡的源端口。如果您想要一个内部的负载均衡,就不要暴露任何端口在负载均衡上,只需要在负载均衡配置中添加端口规则。

注意: 42 端口 不能被用作负载均衡的源端口,因为它被用于健康检查

Example docker-compose.yml

version: '2'
services:
  lb1:
    image: rancher/lb-service-haproxy:<version>
    # Any ports listed will be exposed on the host that is running the load balancer
    # To direct traffic to specific service, a port rule will need to be added.
    ports:
    - 80
    - 81
    - 90

Load Balancer configuration

所有负载均衡的配置项都被定义在rancher-compose.ymllb_config字段中

version: '2'
services:
  lb1:
    scale: 1
    # All load balancer options are configured in this key
    lb_config:
      port_rules:
      - source_port: 80
        target_port: 80
        service: web1
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000
  web1:
    scale: 2

端口规则

端口规则是定义在rancher-compose.yml中的。因为端口规则是单独定义的,会有许多不同的端口指向同一个服务。默认情况下,Rancher将会优先使用那些基于特定的优先级顺序的端口。如果您想要改变这些优先级顺序,您需要设定特定的优先级规则。

默认优先级顺序

  • 没有通配符和URL的主机名
  • 没有通配符的主机名
  • 有通配符和URL的主机名
  • 有通配符的主机名
  • URL
  • 默认(没有主机名,没有URL)
源端口

源端口是值暴露在主机上的某个端口(也就是定义在docker-compose.yml中的端口)。

如果您想要创建一个内部负载均衡,那么源端口酒不需要与docker-compose.yml中定义的任意一个匹配。

目标端口

目标端口是服务内部端口。这个端口就是用于启动您容器的镜像所暴露的端口。

协议

Rancher的负载均衡支持多种协议类型。

  • http - 默认情况下,rancher容器会将80端口上的请求重定向到443端口上。如果没有设置任何协议,负载均衡就会使用http。HAProxy 不会对流量做任何解析,仅仅是转发。
  • tcp - HAProxy 不会对流量做任何解析,仅仅是转发。
  • https - 需要设置SSL会话终结。流量将会被HAProxy使用证书解密,这个证书必须在设定负载均衡之前被添加入Rancher。被流量负载均衡所转发的流量是没有加密的。
  • tls - 需要设置SSL会话终结。流量将会被HAProxy使用证书解密,这个证书必须在设定负载均衡之前被添加入Rancher。被流量负载均衡所转发的流量是没有加密的。
  • sni - 流量从负载均衡到服务都是被加密的。多个证书将会被提供给负载均衡,这样负载均衡就能将合适的证书基于主机名展示给客户端。 点击服务器名称指示)查看更多详情。
  • udp - Rancher 的HAProxy不支持.其他的负载均衡驱动可能只支持以上的几种。
主机名路由

主机名路由只支持httphttps 和 sni,只有http 和 https同时支持路径路由。

服务

服务名就是您的负载均衡的目标。如果服务在同一个应用下,您可以使用服务名。如果服务在不同的应用下,您需要使用<应用名>/<服务名>

Example rancher-compose.yml
version: '2'
services:
  lb1:
    scale: 1
    lb_config:
      port_rules:
      - source_port: 81
        target_port: 2368
        # Service in the same stack
        service: ghost
      - source_port: 80
        target_port: 80
        # Target a service in a different stack
        service: differentstack/web1
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000
  ghost:
    scale: 2
主机名和路径

Rancher基于HAProxy的负载均衡支持七层路由,可以在端口规则下通过设定指定的主机头和路径来使用它。

Example rancher-compose.yml
version: '2'
services:
  lb1:
    scale: 1
    lb_config:
      port_rules:
      - source_port: 81
        target_port: 2368
        service: ghost
        protocol: http
        hostname: example.com
        path: /path/a
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000
  ghost:
    scale: 2
通配符

当设置基于主机名的路由规则时,Rancher支持通配符。所支持的语法如下。

*.domain.com -> hdr_end(host) -i .domain.com
domain.com.* -> hdr_beg(host) -i domain.com.
优先级

默认情况下,Rancher 针对同一个服务遵循默认优先级顺序,但是您也可以定制化您自己的优先级规则(数字越小,优先级越高)

Example rancher-compose.yml
version: '2'
services:
  lb1:
    scale: 1
    lb_config:
      port_rules:
      - source_port: 88
        target_port: 2368
        service: web1
        protocol: http
        hostname: foo.com
        priority: 2
      - source_port: 80
        target_port: 80
        service: web2
        protocol: http
        priority: 1
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000
  web1:
    scale: 2
选择器

您可以通过设定选择器)来指定多个服务。通过使用选择器,您可以在目标服务上定义服务连接和主机名路由规则,那些标签匹配了选择器的服务将成为负载均衡的目标。

当使用选择器的时候,lb_config可以设定在负载均衡和任意一个匹配选择器的服务上。

在负载均衡器中。选择器标签 设置在selector下的lb_config中。负载均衡的lb_config端口规则不能有服务,并且也不能有目标端口。目标端口是设置在目标服务的端口规则中的。如果您需要使用主机名路由,主机名和路径是设置在目标服务下的。

注意: 对于那些在v1版本yaml中使用了的选择器标签字段的负载均衡,这不会被转化成v2版本的负载均衡。因为服务上的端口规则不会更新。

Example docker-compose.yml
version: '2'
services:
  lb1:
    image: rancher/lb-service-haproxy:<version>
    ports:
    - 81
  # These services (web1 and web2) will be picked up by the load balancer as a target
  web1:
    image: nginx
    labels:
      foo: bar
  web2:
    image: nginx
    labels:
      foo: bar
Example rancher-compose.yml
version: '2'
services:
  lb1:
    scale: 1
    lb_config:
      port_rules:
      - source_port: 81
        # Target any service that has foo=bar as a label
        selector: foo=bar
        protocol: http
    health_check:
      port: 42
      interval: 2000
      unhealthy_threshold: 3
      healthy_threshold: 2
      response_timeout: 2000
  # web1 and web2 are targeted with the same source port but with the different hostname and path rules
  web1:
    scale: 1
    lb_config:
      port_rules:
      - target_port: 80
        hostname: test.com
  web2:
    scale: 1
    lb_config:
      port_rules:
      - target_port: 80
        hostname: example.com/test
后台名称

如果您想要清晰地在负载均衡配置中标明您的后台,您需要使用backend_name。如果您想要为一个某个后台自定义配置参数,这就会用得上。

证书

如果您需要使用https 或者 tls 协议, 您可以使用直接加入Rancher或者挂载在负载均衡容器中的证书。

引用在Rancher中添加的证书

证书可以在负载均衡容器的lb_config中被引用。

version: '2'
services:
  lb:
    scale: 1
    lb_config:
      certs:
      - <certName>
      default_cert: <defaultCertName>
将证书挂载进负载均衡容器

仅仅在Compose文件中支持

证书可以作为卷直接挂载进负载均衡容器。证书需要按照特定的目录结构挂载入容器。如果您使用LetsEncrypt客户端生存证书,那么它就已经满足Rancher的要求。否则,您需要手动设置目录结构,使他与LetsEncrypt客户端生成的一致。

Rancher的负载均衡将会检测证书目录来实现更新。任何对证书的新增/删除操作都将每30秒同步一次。

所以的证书都位于同一个基础的证书目录下。这个文件名将会作为负载均衡服务的一个标签,用于通知负载均衡证书的所在地。

在这个基础目录下,相同域名的证书被放置在同一个子目录下。文件名就是证书的域名。并且每一个文件夹都需要包含privkey.pemfullchain.pem。对于默认证书,可以被放置在任意一个子目录名下,但是下面的文件命名规则必须保持一致。

-- certs
   |-- foo.com
   |   |-- privkey.pem
   |   |-- fullchain.pem
   |-- bar.com
   |   |-- privkey.pem
   |   |-- fullchain.pem
   |-- default_cert_dir_optional
   |   |-- privkey.pem
   |   |-- fullchain.pem
 ...

当启动一个负载均衡的时候,您必须用标签声明证书的路径(包括默认证书的路径)。这样以来,负载均衡将忽略设置在lb_config中的证书。

注意: 您不能同时使用在Rancher中添加的证书和挂载在负载均衡容器中的证书

labels:
  io.rancher.lb_service.cert_dir: <CERTIFICATE_LOCATION>
  io.rancher.lb_service.default_cert_dir: <DEFAULT_CERTIFICATE_LOCATION>

证书可以通过绑定主机的挂载目录或者通过命名卷来挂在入负载均衡容器,命名卷可以以我们的storage drivers为驱动。

Example docker-compose.yml
version: '2'
services:
  lb:
    image: rancher/lb-service-haproxy:<TAG_BASED_ON_RELEASE>
    volumes:
    - /location/on/hosts:/certs
    ports:
    - 8087:8087/tcp
    labels:
      io.rancher.container.agent.role: environmentAdmin
      io.rancher.container.create_agent: 'true'
      io.rancher.lb_service.cert_dir: /certs
      io.rancher.lb_service.default_cert_dir: /certs/default.com
  myapp:
    image: nginx:latest
    stdin_open: true
    tty: true
Example rancher-compose.yml
version: '2'
 services:
   lb:
     scale: 1
     start_on_create: true
     lb_config:
       certs: []
       port_rules:
       - priority: 1
         protocol: https
         service: myapp
         source_port: 8087
         target_port: 80
     health_check:
       healthy_threshold: 2
       response_timeout: 2000
       port: 42
       unhealthy_threshold: 3
       interval: 2000
       strategy: recreate
   myapp:
     scale: 1
     start_on_create: true

自定义配置

高阶用户可以在rancher-compose.yml中声明自定义的配置。点击HAProxy配置文档查看更多详情。

Example rancher-compose.yml
version: '2'
 services:
   lb:
     scale: 1
     lb_config:
       config: |-
         global
             maxconn 4096
             maxpipes 1024
  
         defaults
             log global
             mode    tcp
             option  tcplog
  
         frontend 80
             balance leastconn
  
         frontend 90
             balance roundrobin
  
         backend mystack_foo
             cookie my_cookie insert indirect nocache postonly
             server $$IP <server parameters>
  
         backend customUUID
   health_check:
     port: 42
     interval: 2000
     unhealthy_threshold: 3
     healthy_threshold: 2
     response_timeout: 2000

会话粘性策略

如果您需要使用会话粘性策略,您可以更新rancher-compose.yml中的策略。

Example rancher-compose.yml
version: '2'
 services:
   lb:
     scale: 1
     lb_config:
       stickiness_policy:
         name: <policyName>
         cookie: <cookieInfo>
         domain: <domainName>
         indirect: false
         nocache: false
         postonly: false
         mode: <mode>
   health_check:
     port: 42
     interval: 2000
     unhealthy_threshold: 3
     healthy_threshold: 2
     response_timeout: 2000

Rancher Compose Examples

Load Balancer Example (L7)

Example docker-compose.yml
version: '2'
 services:
   web:
     image: nginx
   lb:
     image: rancher/lb-service-haproxy
   ports:
   - 80
   - 82
Example rancher-compose.yml
version: '2'
 services:
   lb:
     scale: 1
     lb_config:
       port_rules:
       - source_port: 80
         target_port: 8080
         service: web1
         hostname: app.example.com
         path: /foo
       - source_port: 82
         target_port: 8081
         service: web2
         hostname: app.example.com
         path: /foo/bar
   health_check:
     port: 42
     interval: 2000
     unhealthy_threshold: 3
     healthy_threshold: 2
     response_timeout: 2000

内部负载均衡例子

设置内部负载均衡不需要列举端口,但是您仍然可以设置端口规则来转发流量。

Example docker-compose.yml
version: '2'
 services:
   lb:
     image: rancher/lb-service-haproxy
   web:
     image: nginx
Example rancher-compose.yml
version: '2'
 services:
   lb:
     scale: 1
     lb_config:
       port_rules:
       - source_port: 80
         target_port: 80
         service: web
     health_check:
       port: 42
       interval: 2000
       unhealthy_threshold: 3
       healthy_threshold: 2
       response_timeout: 2000
   web:
     scale: 1

SSL会话终止 Example

rancher-compose.yml中使用的证书必须被加入到Rancher中。

Example docker-compose.yml
version: '2'
 services:
   lb:
     image: rancher/lb-service-haproxy
     ports:
     - 443
   web:
     image: nginx
Example rancher-compose.yml
复制代码version: '2'
 services:
   lb:
     scale: 1
     lb_config:
       certs:
       - <certName>
       default_cert: <defaultCertName>
       port_rules:
       - source_port: 443
         target_port: 443
         service: web
         protocol: https
   web:
     scale: 1
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月28日 0

暂无评论

推荐阅读
  eHipUjOuzYYH   2023年12月07日   14   0   0 数据乐观锁redis
  wwLZeziuqjLR   2023年12月11日   14   0   0 Dockercentos
  MCWYWqSAMsot   2023年12月11日   16   0   0 Docker
  DnoStTHsc0vp   2023年12月11日   12   0   0 Docker
  wwLZeziuqjLR   2023年12月08日   65   0   0 Dockercentosbash
  wwLZeziuqjLR   2023年12月07日   15   0   0 Dockercentos