配置
8. Maven
如果你想覆盖特定的 Maven 配置属性(远程仓库、代理等),或者在代理后面运行 Data Flow Server, 你需要在启动 Data Flow Server 时将这些属性指定为命令行参数,如下例所示:
$ java -jar spring-cloud-dataflow-server-2.8.3.jar --spring.config.additional-location=/home/joe/maven.yml
上述命令假定存在一个类似于以下内容的 maven.yaml 文件:
maven:
localRepository: mylocal
remote-repositories:
repo1:
url: https://repo1
auth:
username: user1
password: pass1
snapshot-policy:
update-policy: daily
checksum-policy: warn
release-policy:
update-policy: never
checksum-policy: fail
repo2:
url: https://repo2
policy:
update-policy: always
checksum-policy: fail
proxy:
host: proxy1
port: "9010"
auth:
username: proxyuser1
password: proxypass1
默认情况下,协议设置为 http。如果代理不需要用户名和密码,可以省略认证属性。此外,默认情况下,Maven 的 localRepository 被设置为 ${user.home}/.m2/repository/。
如上例所示,您可以指定远程仓库及其认证信息(如果需要)。如果远程仓库位于代理之后,您可以像上例那样指定代理属性。
您可以为每个远程仓库配置指定仓库策略,如上例所示。
关键字 policy 同时适用于 snapshot 和 release 仓库策略。
请参阅仓库策略主题,以获取支持的仓库策略列表。
由于这些是 Spring Boot 的 @ConfigurationProperties,你需要通过将它们添加到 SPRING_APPLICATION_JSON 环境变量中来指定。以下示例展示了 JSON 的结构:
$ SPRING_APPLICATION_JSON='
{
"maven": {
"local-repository": null,
"remote-repositories": {
"repo1": {
"url": "https://repo1",
"auth": {
"username": "repo1user",
"password": "repo1pass"
}
},
"repo2": {
"url": "https://repo2"
}
},
"proxy": {
"host": "proxyhost",
"port": 9018,
"auth": {
"username": "proxyuser",
"password": "proxypass"
}
}
}
}
'
8.1. Wagon
对在 Maven 中使用 Wagon 传输的支持有限。目前,此功能仅用于支持基于 http 的仓库的预先身份验证,并且需要手动启用。
通过将 http 属性设置为 maven.use-wagon,即可启用基于 Wagon 的 true 传输方式。然后,您可以为每个远程仓库启用抢先式(preemptive)认证。其配置大致遵循与HttpClient HTTP Wagon中类似的模式。
在本文撰写之时,Maven 官方网站上的文档略显误导,并且缺少了大部分可用的配置选项。
maven.remote-repositories.<repo>.wagon.http 命名空间包含所有与 Wagon http 相关的设置,其下的直接键对应于 Maven 自身配置中支持的 http 方法——即 all、put、get 和 head。
在这些方法配置下,您可以设置各种选项,例如 use-preemptive。以下示例展示了一个简单的preemptive(抢先式)配置,用于在向指定远程仓库发送的所有请求中附带认证头信息:
maven:
use-wagon: true
remote-repositories:
springRepo:
url: https://repo.example.org
wagon:
http:
all:
use-preemptive: true
auth:
username: user
password: password
你可以仅针对 all 和 get 请求调整设置,而不是配置 head 方法,如下所示:
maven:
use-wagon: true
remote-repositories:
springRepo:
url: https://repo.example.org
wagon:
http:
get:
use-preemptive: true
head:
use-preemptive: true
use-default-headers: true
connection-timeout: 1000
read-timeout: 1000
headers:
sample1: sample2
params:
http.socket.timeout: 1000
http.connection.stalecheck: true
auth:
username: user
password: password
有用于 use-default-headers、connection-timeout、
read-timeout、请求 headers 以及 HttpClient params 的设置。有关参数的更多信息,
请参阅 Wagon ConfigurationUtils。
9. 安全
默认情况下,Data Flow 服务器未启用安全保护,并通过未加密的 HTTP 连接运行。 您可以通过启用 HTTPS 并要求客户端使用 OAuth 2.0 进行身份验证, 来保护您的 REST 端点以及 Data Flow 仪表板。
|
附录 Azure 包含了有关如何设置Azure Active Directory集成的更多信息。 |
|
默认情况下,REST 端点(管理、运维和健康检查)以及仪表板 UI 不需要身份验证即可访问。 |
虽然理论上你可以选择任意 OAuth 提供商与 Spring Cloud Data Flow 配合使用,但我们推荐使用 CloudFoundry 用户账户与认证(UAA)服务器。
UAA 不仅通过了 OpenID 认证并被 Cloud Foundry 所采用,而且您也可以在本地独立部署的场景中使用它。此外,UAA 不仅提供自身的用户存储,还提供了全面的 LDAP 集成。
9.1. 启用 HTTPS
默认情况下,仪表盘、管理和健康端点使用 HTTP 作为传输协议。
您可以通过在 application.yml 中添加证书来切换到 HTTPS,如下例所示:
server:
port: 8443 (1)
ssl:
key-alias: yourKeyAlias (2)
key-store: path/to/keystore (3)
key-store-password: yourKeyStorePassword (4)
key-password: yourKeyPassword (5)
trust-store: path/to/trust-store (6)
trust-store-password: yourTrustStorePassword (7)
| 1 | 由于默认端口是 9393,您可以选择将其更改为更常见的 HTTPS 典型端口。 |
| 2 | 密钥在密钥库中存储时所使用的别名(或名称)。 |
| 3 | 密钥库文件的路径。您也可以通过使用 classpath 前缀来指定类路径资源,例如:classpath:path/to/keystore。 |
| 4 | 密钥库的密码。 |
| 5 | 密钥的密码。 |
| 6 | 信任库文件的路径。您也可以通过使用 classpath 前缀来指定类路径资源,例如:classpath:path/to/trust-store |
| 7 | 信任库的密码。 |
| 如果启用了 HTTPS,它将完全取代 HTTP,成为 REST 端点与 Data Flow 控制台之间交互的协议。普通的 HTTP 请求将失败。因此,请确保您相应地配置您的 Shell。 |
使用自签名证书
出于测试目的或在开发过程中,创建自签名证书可能非常方便。 要开始操作,请执行以下命令以创建证书:
$ keytool -genkey -alias dataflow -keyalg RSA -keystore dataflow.keystore \
-validity 3650 -storetype JKS \
-dname "CN=localhost, OU=Spring, O=Pivotal, L=Kailua-Kona, ST=HI, C=US" (1)
-keypass dataflow -storepass dataflow
| 1 | CN 是此处的重要参数。它应与您尝试访问的域名相匹配——例如,localhost。 |
然后将以下内容添加到您的 application.yml 文件中:
server:
port: 8443
ssl:
enabled: true
key-alias: dataflow
key-store: "/your/path/to/dataflow.keystore"
key-store-type: jks
key-store-password: dataflow
key-password: dataflow
这就是您为 Data Flow Server 所需做的全部配置。一旦启动服务器,
您应该可以通过 localhost:8443/ 访问它。
由于这是自签名证书,您的浏览器会提示一个警告,
您需要忽略该警告。
| 切勿在生产环境中使用自签名证书。 |
自签名证书与 Shell
默认情况下,自签名证书会对 Shell 造成问题,需要执行额外的步骤才能使 Shell 与自签名证书协同工作。有两种选项可用:
-
将自签名证书添加到 JVM 信任库中。
-
跳过证书验证。
将自签名证书添加到 JVM 信任库
为了使用 JVM 信任库(truststore)选项,您需要按如下方式从密钥库(keystore)中导出之前创建的证书:
$ keytool -export -alias dataflow -keystore dataflow.keystore -file dataflow_cert -storepass dataflow
接下来,你需要创建一个信任库(truststore)供 shell 使用,步骤如下:
$ keytool -importcert -keystore dataflow.truststore -alias dataflow -storepass dataflow -file dataflow_cert -noprompt
现在,您可以使用以下 JVM 参数启动 Data Flow Shell:
$ java -Djavax.net.ssl.trustStorePassword=dataflow \
-Djavax.net.ssl.trustStore=/path/to/dataflow.truststore \
-Djavax.net.ssl.trustStoreType=jks \
-jar spring-cloud-dataflow-shell-2.8.3.jar
|
如果在通过 SSL 建立连接时遇到问题,可以通过设置 JVM 参数 |
不要忘记使用以下命令指定 Data Flow Server:
dataflow:> dataflow config server https://localhost:8443/
跳过证书验证
或者,你也可以通过提供可选的命令行参数 --dataflow.skip-ssl-validation=true 来跳过证书验证。
如果设置了此命令行参数,shell 将接受任何(自签名)SSL 证书。
|
如果可能的话,您应避免使用此选项。禁用信任管理器会破坏 SSL 的目的,并使您的应用程序容易受到中间人攻击。 |
9.2. 使用 OAuth 2.0 进行身份验证
为了支持身份认证和授权,Spring Cloud Data Flow 使用 OAuth 2.0。 它允许您将 Spring Cloud Data Flow 集成到单点登录(SSO)环境中。
| 从 Spring Cloud Data Flow 2.0 起,OAuth2 是提供身份认证和授权的唯一机制。 |
使用了以下 OAuth2 授权类型:
-
授权码:用于 GUI(浏览器)集成。访问者将被重定向到您的 OAuth 服务进行身份验证
-
密码:由 Shell(以及 REST 集成)使用,以便访客可以使用用户名和密码登录
-
客户端凭证:直接从您的 OAuth 提供商获取访问Tokens,并通过 Authorization HTTP 请求头将其传递给 Data Flow 服务器
| 目前,Spring Cloud Data Flow 使用的是不透明Tokens(opaque tokens),而非透明Tokens(JWT)。 |
您可以通过两种方式访问 REST 端点:
-
基本身份验证,它使用密码授权类型与您的 OAuth2 服务进行身份验证
-
访问Tokens,使用客户端凭证授权类型
| 在设置身份验证时,您确实也应该同时启用 HTTPS,尤其是在生产环境中。 |
你可以通过在 application.yml 中添加以下内容,或通过设置环境变量来启用 OAuth2 认证。以下示例展示了使用 CloudFoundry 用户账户与认证(UAA)服务器所需的最小配置:
spring:
security:
oauth2: (1)
client:
registration:
uaa: (2)
client-id: myclient
client-secret: mysecret
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
authorization-grant-type: authorization_code
scope:
- openid (3)
provider:
uaa:
jwk-set-uri: http://uaa.local:8080/uaa/token_keys
token-uri: http://uaa.local:8080/uaa/oauth/token
user-info-uri: http://uaa.local:8080/uaa/userinfo (4)
user-name-attribute: user_name (5)
authorization-uri: http://uaa.local:8080/uaa/oauth/authorize
resourceserver:
opaquetoken:
introspection-uri: http://uaa.local:8080/uaa/introspect (6)
client-id: dataflow
client-secret: dataflow
| 1 | 提供此属性将激活 OAuth2 安全功能。 |
| 2 | 提供者 ID。您可以指定多个提供者。 |
| 3 | 由于 UAA 是一个 OpenID 提供商,您至少必须指定 openid 范围。
如果您的提供商还提供额外的范围以控制角色分配,
也必须在此处指定这些范围。 |
| 4 | OpenID 端点。用于检索用户信息,例如用户名。必填项。 |
| 5 | 响应中包含用户名的 JSON 属性。 |
| 6 | 用于内省和验证直接传入的Tokens。必填项。 |
你可以使用 curl 来验证基本身份验证是否正常工作,如下所示:
curl -u myusername:mypassword http://localhost:9393/ -H 'Accept: application/json'
因此,你应该会看到一份可用的 REST 端点列表。
当你在启用安全机制的情况下,使用网页浏览器访问根 URL 时,会被重定向到 Dashboard 用户界面。若要查看 REST 端点列表,请指定 application/json 的 Accept 请求头。同时,请确保使用诸如 Postman(Chrome)或 RESTClient(Firefox)之类的工具来添加 https://addons.mozilla.org/en-GB/firefox/addon/restclient/ 请求头。 |
除了基本认证(Basic Authentication)之外,您还可以提供一个访问Tokens(access token)来访问 REST API。为此,请从您的 OAuth2 提供商获取一个 OAuth2 访问Tokens,并通过 Authorization HTTP 请求头将该访问Tokens传递给 REST API,如下所示:
$ curl -H "Authorization: Bearer <ACCESS_TOKEN>" http://localhost:9393/ -H 'Accept: application/json'
9.3. 自定义授权
前面的内容主要涉及身份验证(authentication)——即如何确认用户的身份。在本节中,我们将讨论可用的授权(authorization)选项——即谁可以做什么。
授权规则在 dataflow-server-defaults.yml(属于 Spring Cloud Data Flow 核心模块的一部分)中定义。
由于安全角色的确定与具体环境相关,
Spring Cloud Data Flow 默认会为所有经过身份验证的 OAuth2 用户分配全部角色。
为此目的,使用了 DefaultDataflowAuthoritiesExtractor 类。
或者,你可以通过将你的提供程序的布尔属性 map-oauth-scopes 设置为 true(默认值为 false),让 Spring Cloud Data Flow 将 OAuth2 作用域映射到 Data Flow 角色。
例如,如果你的提供程序 ID 是 uaa,则该属性应为
spring.cloud.dataflow.security.authorization.provider-role-mappings.uaa.map-oauth-scopes。
有关更多详细信息,请参阅角色映射章节。
您还可以通过提供一个自定义的 Spring Bean 定义来扩展 Spring Cloud Data Flow 的 AuthorityMapper 接口,从而定制角色映射行为。在这种情况下,自定义的 Bean 定义将优先于 Spring Cloud Data Flow 提供的默认定义。
默认方案使用七个角色来保护 Spring Cloud Data Flow 所暴露的REST 端点:
-
ROLE_CREATE:用于任何涉及创建的操作,例如创建流或任务
-
ROLE_DEPLOY:用于部署流或启动任务
-
ROLE_DESTROY:用于涉及删除流、任务等任何操作。
-
ROLE_MANAGE:用于 Boot 管理端点
-
ROLE_MODIFY:用于涉及修改系统状态的任何操作
-
ROLE_SCHEDULE:用于调度相关操作(例如调度任务)
-
ROLE_VIEW:用于任何与检索状态相关的内容
如本节前面所述,所有与授权相关的默认设置均在 dataflow-server-defaults.yml 中指定,该文件属于 Spring Cloud Data Flow 核心模块。不过,如有需要,您也可以覆盖这些设置——例如,在 application.yml 中进行配置。该配置采用 YAML 列表的形式(因为某些规则可能优先于其他规则)。因此,您需要复制并粘贴整个列表,并根据自身需求进行调整(因为无法对列表进行合并)。
请始终参考您所使用的 application.yml 文件版本,因为以下代码片段可能已过时。 |
默认规则如下:
spring:
cloud:
dataflow:
security:
authorization:
enabled: true
loginUrl: "/"
permit-all-paths: "/authenticate,/security/info,/assets/**,/dashboard/logout-success-oauth.html,/favicon.ico"
rules:
# About
- GET /about => hasRole('ROLE_VIEW')
# Audit
- GET /audit-records => hasRole('ROLE_VIEW')
- GET /audit-records/** => hasRole('ROLE_VIEW')
# Boot Endpoints
- GET /management/** => hasRole('ROLE_MANAGE')
# Apps
- GET /apps => hasRole('ROLE_VIEW')
- GET /apps/** => hasRole('ROLE_VIEW')
- DELETE /apps/** => hasRole('ROLE_DESTROY')
- POST /apps => hasRole('ROLE_CREATE')
- POST /apps/** => hasRole('ROLE_CREATE')
- PUT /apps/** => hasRole('ROLE_MODIFY')
# Completions
- GET /completions/** => hasRole('ROLE_VIEW')
# Job Executions & Batch Job Execution Steps && Job Step Execution Progress
- GET /jobs/executions => hasRole('ROLE_VIEW')
- PUT /jobs/executions/** => hasRole('ROLE_MODIFY')
- GET /jobs/executions/** => hasRole('ROLE_VIEW')
- GET /jobs/thinexecutions => hasRole('ROLE_VIEW')
# Batch Job Instances
- GET /jobs/instances => hasRole('ROLE_VIEW')
- GET /jobs/instances/* => hasRole('ROLE_VIEW')
# Running Applications
- GET /runtime/streams => hasRole('ROLE_VIEW')
- GET /runtime/streams/** => hasRole('ROLE_VIEW')
- GET /runtime/apps => hasRole('ROLE_VIEW')
- GET /runtime/apps/** => hasRole('ROLE_VIEW')
# Stream Definitions
- GET /streams/definitions => hasRole('ROLE_VIEW')
- GET /streams/definitions/* => hasRole('ROLE_VIEW')
- GET /streams/definitions/*/related => hasRole('ROLE_VIEW')
- POST /streams/definitions => hasRole('ROLE_CREATE')
- DELETE /streams/definitions/* => hasRole('ROLE_DESTROY')
- DELETE /streams/definitions => hasRole('ROLE_DESTROY')
# Stream Deployments
- DELETE /streams/deployments/* => hasRole('ROLE_DEPLOY')
- DELETE /streams/deployments => hasRole('ROLE_DEPLOY')
- POST /streams/deployments/** => hasRole('ROLE_MODIFY')
- GET /streams/deployments/** => hasRole('ROLE_VIEW')
# Stream Validations
- GET /streams/validation/ => hasRole('ROLE_VIEW')
- GET /streams/validation/* => hasRole('ROLE_VIEW')
# Stream Logs
- GET /streams/logs/* => hasRole('ROLE_VIEW')
# Task Definitions
- POST /tasks/definitions => hasRole('ROLE_CREATE')
- DELETE /tasks/definitions/* => hasRole('ROLE_DESTROY')
- GET /tasks/definitions => hasRole('ROLE_VIEW')
- GET /tasks/definitions/* => hasRole('ROLE_VIEW')
# Task Executions
- GET /tasks/executions => hasRole('ROLE_VIEW')
- GET /tasks/executions/* => hasRole('ROLE_VIEW')
- POST /tasks/executions => hasRole('ROLE_DEPLOY')
- POST /tasks/executions/* => hasRole('ROLE_DEPLOY')
- DELETE /tasks/executions/* => hasRole('ROLE_DESTROY')
# Task Schedules
- GET /tasks/schedules => hasRole('ROLE_VIEW')
- GET /tasks/schedules/* => hasRole('ROLE_VIEW')
- GET /tasks/schedules/instances => hasRole('ROLE_VIEW')
- GET /tasks/schedules/instances/* => hasRole('ROLE_VIEW')
- POST /tasks/schedules => hasRole('ROLE_SCHEDULE')
- DELETE /tasks/schedules/* => hasRole('ROLE_SCHEDULE')
# Task Platform Account List */
- GET /tasks/platforms => hasRole('ROLE_VIEW')
# Task Validations
- GET /tasks/validation/ => hasRole('ROLE_VIEW')
- GET /tasks/validation/* => hasRole('ROLE_VIEW')
# Task Logs
- GET /tasks/logs/* => hasRole('ROLE_VIEW')
# Tools
- POST /tools/** => hasRole('ROLE_VIEW')
每一行的格式如下:
HTTP_METHOD URL_PATTERN '=>' SECURITY_ATTRIBUTE
其中:
-
HTTP_METHOD 是一个 HTTP 方法(例如 PUT 或 GET),使用大写字母。
-
URL_PATTERN 是一种 Ant 风格的 URL 模式。
-
SECURITY_ATTRIBUTE 是一个 SpEL 表达式。请参阅基于表达式的访问控制。
-
其中每一项都由一个或多个空白字符(空格、制表符等)分隔。
请注意,上述内容是一个 YAML 列表,而非映射(因此每行开头使用了 '-' 破折号),它位于 spring.cloud.dataflow.security.authorization.rules 键下。
授权 —— Shell 与仪表板行为
启用安全功能后,仪表盘和 Shell 将具备角色感知能力, 这意味着根据所分配的角色,某些功能可能不会显示。
例如,用户没有必要角色的 shell 命令将被标记为不可用。
|
目前,shell 的 |
相反,对于仪表板(Dashboard),用户界面不会显示用户未被授权访问的页面或页面元素。
保护 Spring Boot 管理端点的安全
启用安全功能后,
Spring Boot HTTP 管理端点
将与其他 REST 端点采用相同的方式进行保护。管理 REST 端点位于 /management 路径下,并需要 MANAGEMENT 角色。
dataflow-server-defaults.yml 中的默认配置如下:
management:
endpoints:
web:
base-path: /management
security:
roles: MANAGE
| 目前,您不应自定义默认的管理路径。 |
9.4. 配置 UAA 认证
对于本地部署场景,我们推荐使用CloudFoundry 用户账户与认证(UAA)服务器,该服务器已通过OpenID 认证。 虽然 UAA 被Cloud Foundry 所采用, 但它本身也是一个功能完备的独立 OAuth2 服务器,并具备企业级特性, 例如LDAP 集成。
要求
你需要检出、构建并运行 UAA。为此,请确保你:
如果在安装 uaac 时遇到问题,您可能需要设置 GEM_HOME 环境变量:
export GEM_HOME="$HOME/.gem"
你还应确保已将 ~/.gem/gems/cf-uaac-4.2.0/bin 添加到你的路径(PATH)中。
为 JWT 准备 UAA
由于 UAA 是一个 OpenID 提供商,并使用 JSON Web Token(JWT),因此它需要一个私钥来对这些 JWT 进行签名:
openssl genrsa -out signingkey.pem 2048
openssl rsa -in signingkey.pem -pubout -out verificationkey.pem
export JWT_TOKEN_SIGNING_KEY=$(cat signingkey.pem)
export JWT_TOKEN_VERIFICATION_KEY=$(cat verificationkey.pem)
稍后,一旦 UAA 启动,您可以通过访问 uaa:8080/uaa/token_keys 查看密钥。
此处,URL uaa 中的 uaa:8080/uaa/token_keys 是主机名。 |
下载并启动 UAA
要下载并安装 UAA,请运行以下命令:
git clone https://github.com/pivotal/uaa-bundled.git
cd uaa-bundled
./mvnw clean install
java -jar target/uaa-bundled-1.0.0.BUILD-SNAPSHOT.jar
UAA 的配置由一个 YAML 文件 uaa.yml 驱动,或者您也可以使用 UAA 命令行客户端来编写配置脚本:
uaac target http://uaa:8080/uaa
uaac token client get admin -s adminsecret
uaac client add dataflow \
--name dataflow \
--secret dataflow \
--scope cloud_controller.read,cloud_controller.write,openid,password.write,scim.userids,sample.create,sample.view,dataflow.create,dataflow.deploy,dataflow.destroy,dataflow.manage,dataflow.modify,dataflow.schedule,dataflow.view \
--authorized_grant_types password,authorization_code,client_credentials,refresh_token \
--authorities uaa.resource,dataflow.create,dataflow.deploy,dataflow.destroy,dataflow.manage,dataflow.modify,dataflow.schedule,dataflow.view,sample.view,sample.create\
--redirect_uri http://localhost:9393/login \
--autoapprove openid
uaac group add "sample.view"
uaac group add "sample.create"
uaac group add "dataflow.view"
uaac group add "dataflow.create"
uaac user add springrocks -p mysecret --emails [email protected]
uaac user add vieweronly -p mysecret --emails [email protected]
uaac member add "sample.view" springrocks
uaac member add "sample.create" springrocks
uaac member add "dataflow.view" springrocks
uaac member add "dataflow.create" springrocks
uaac member add "sample.view" vieweronly
上述脚本设置了数据流客户端以及两个用户:
-
用户 springrocks 同时拥有以下两个作用域:
sample.view和sample.create。 -
用户 vieweronly 只有一个作用域:
sample.view。
添加完成后,您可以快速再次确认 UAA 中是否已创建了这些用户:
curl -v -d"username=springrocks&password=mysecret&client_id=dataflow&grant_type=password" -u "dataflow:dataflow" http://uaa:8080/uaa/oauth/token -d 'token_format=opaque'
上述命令应生成类似于以下的输出:
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to uaa (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'dataflow'
> POST /uaa/oauth/token HTTP/1.1
> Host: uaa:8080
> Authorization: Basic ZGF0YWZsb3c6ZGF0YWZsb3c=
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 97
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 97 out of 97 bytes
< HTTP/1.1 200
< Cache-Control: no-store
< Pragma: no-cache
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 31 Oct 2019 21:22:59 GMT
<
* Connection #0 to host uaa left intact
{"access_token":"0329c8ecdf594ee78c271e022138be9d","token_type":"bearer","id_token":"eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAvdWFhL3Rva2VuX2tleXMiLCJraWQiOiJsZWdhY3ktdG9rZW4ta2V5IiwidHlwIjoiSldUIn0.eyJzdWIiOiJlZTg4MDg4Ny00MWM2LTRkMWQtYjcyZC1hOTQ4MmFmNGViYTQiLCJhdWQiOlsiZGF0YWZsb3ciXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDkwL3VhYS9vYXV0aC90b2tlbiIsImV4cCI6MTU3MjYwMDE3OSwiaWF0IjoxNTcyNTU2OTc5LCJhbXIiOlsicHdkIl0sImF6cCI6ImRhdGFmbG93Iiwic2NvcGUiOlsib3BlbmlkIl0sImVtYWlsIjoic3ByaW5ncm9ja3NAc29tZXBsYWNlLmNvbSIsInppZCI6InVhYSIsIm9yaWdpbiI6InVhYSIsImp0aSI6IjAzMjljOGVjZGY1OTRlZTc4YzI3MWUwMjIxMzhiZTlkIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImNsaWVudF9pZCI6ImRhdGFmbG93IiwiY2lkIjoiZGF0YWZsb3ciLCJncmFudF90eXBlIjoicGFzc3dvcmQiLCJ1c2VyX25hbWUiOiJzcHJpbmdyb2NrcyIsInJldl9zaWciOiJlOTkyMDQxNSIsInVzZXJfaWQiOiJlZTg4MDg4Ny00MWM2LTRkMWQtYjcyZC1hOTQ4MmFmNGViYTQiLCJhdXRoX3RpbWUiOjE1NzI1NTY5Nzl9.bqYvicyCPB5cIIu_2HEe5_c7nSGXKw7B8-reTvyYjOQ2qXSMq7gzS4LCCQ-CMcb4IirlDaFlQtZJSDE-_UsM33-ThmtFdx--TujvTR1u2nzot4Pq5A_ThmhhcCB21x6-RNNAJl9X9uUcT3gKfKVs3gjE0tm2K1vZfOkiGhjseIbwht2vBx0MnHteJpVW6U0pyCWG_tpBjrNBSj9yLoQZcqrtxYrWvPHaa9ljxfvaIsOnCZBGT7I552O1VRHWMj1lwNmRNZy5koJFPF7SbhiTM8eLkZVNdR3GEiofpzLCfoQXrr52YbiqjkYT94t3wz5C6u1JtBtgc2vq60HmR45bvg","refresh_token":"6ee95d017ada408697f2d19b04f7aa6c-r","expires_in":43199,"scope":"scim.userids openid sample.create cloud_controller.read password.write cloud_controller.write sample.view","jti":"0329c8ecdf594ee78c271e022138be9d"}
通过使用 token_format 参数,您可以请求Tokens采用以下任一格式:
-
不透明
-
jwt
10. 配置 - 本地
10.1. 功能开关
Spring Cloud Data Flow 服务器在启动时提供了一组特定的功能,这些功能可以启用或禁用。这些功能包括以下各项的全部生命周期操作和 REST 端点(服务器和客户端实现,包括 Shell 和 UI):
-
流(需要 Skipper)
-
任务
-
任务调度器
可以通过在启动 Data Flow 服务器时设置以下布尔属性来启用或禁用这些功能:
-
spring.cloud.dataflow.features.streams-enabled -
spring.cloud.dataflow.features.tasks-enabled -
spring.cloud.dataflow.features.schedules-enabled
默认情况下,流(需要 Skipper)和任务是启用的,而任务调度器默认是禁用的。
REST /about 端点提供有关已启用和已禁用功能的信息。
10.2. 数据库
关系型数据库用于存储流(stream)和任务(task)的定义,以及已执行任务的状态。 Spring Cloud Data Flow 为 H2、MySQL、Oracle、PostgreSQL、Db2 和 SQL Server 提供了数据库模式(schema)。当服务器启动时,该模式会自动创建。
默认情况下,Spring Cloud Data Flow 提供了一个嵌入式的 H2 数据库实例。H2 数据库适用于开发用途,但不建议用于生产环境。
| H2 数据库不支持以外部模式运行。 |
MySQL(通过 MariaDB 驱动)、PostgreSQL、SQL Server 以及嵌入式 H2 的 JDBC 驱动无需额外配置即可使用。 如果您使用的是其他任何数据库,则需要将相应的 JDBC 驱动 JAR 文件放入服务器的类路径(classpath)中。
数据库属性可以作为环境变量或命令行参数传递给 Data Flow Server。
10.2.1. MySQL
以下示例展示了如何使用 MariaDB 驱动程序定义 MySQL 数据库连接。
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:mysql://localhost:3306/mydb \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
MySQL 版本最高至 5.7 可使用 MariaDB 驱动程序。从 8.0 版本开始,必须使用 MySQL 自带的驱动程序。
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:mysql://localhost:3306/mydb \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=com.mysql.jdbc.Driver
| 由于许可限制,我们无法将 MySQL 驱动程序打包在一起。您需要自行将其添加到服务器的类路径中。 |
10.2.2. MariaDB
以下示例展示了如何通过命令行参数定义一个 MariaDB 数据库连接。
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:mariadb://localhost:3306/mydb?useMysqlMetadata=true \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
从 MariaDB v2.4.1 连接器版本开始,还需要在 JDBC URL 中添加 useMysqlMetadata=true。
在 MySQL 和 MariaDB 完全作为两个不同的数据库进行切换之前,这是一个必需的临时解决方案。
MariaDB 版本 10.3 引入了对真实数据库序列的支持,这又是一个破坏性变更,因为围绕这些数据库的工具仍将 MySQL 和 MariaDB 视为不同的数据库类型。解决方法是使用较旧的 Hibernate 方言,该方言不会尝试使用序列。
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:mariadb://localhost:3306/mydb?useMysqlMetadata=true \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB102Dialect \
--spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
10.2.3. PostgreSQL
以下示例展示了如何通过命令行参数定义 PostgreSQL 数据库连接:
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:postgresql://localhost:5432/mydb \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=org.postgresql.Driver
10.2.4. SQL Server
以下示例展示了如何通过命令行参数定义 SQL Server 数据库连接:
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url='jdbc:sqlserver://localhost:1433;databaseName=mydb' \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
10.2.5. Db2
以下示例展示了如何通过命令行参数定义一个 Db2 数据库连接:
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:db2://localhost:50000/mydb \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
| 由于许可限制,我们无法将 Db2 驱动程序打包在一起。您需要自行将其添加到服务器的类路径中。 |
10.2.6. Oracle
以下示例展示了如何通过命令行参数定义一个 Oracle 数据库连接:
java -jar spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.8.3.jar \
--spring.datasource.url=jdbc:oracle:thin:@localhost:1521/MYDB \
--spring.datasource.username= \
--spring.datasource.password= \
--spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
| 由于许可限制,我们无法将 Oracle 驱动程序打包在一起。您需要自行将其添加到服务器的 classpath 中。 |
10.2.7. 添加自定义 JDBC 驱动程序
要为数据库(例如 Oracle)添加自定义驱动程序,您需要重新构建 Data Flow Server,并将依赖项添加到 Maven 的 pom.xml 文件中。
您需要修改 pom.xml 模块的 Maven spring-cloud-dataflow-server 文件。
GitHub 代码仓库中提供了 GA(正式发布)版本的标签,因此您可以切换到所需的 GA 标签,在已可用于生产环境的代码基础上添加驱动程序。
为 Spring Cloud Data Flow 服务器添加自定义 JDBC 驱动程序依赖项:
-
选择与您要重建的服务器版本对应的标签,并克隆 GitHub 仓库。
-
编辑 spring-cloud-dataflow-server/pom.xml 文件,并在
dependencies部分添加所需数据库驱动的依赖项。在以下示例中,选择了 Oracle 驱动:
<dependencies>
...
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
...
</dependencies>
-
按照构建 Spring Cloud Data Flow中描述的方式构建应用程序
在重建服务器时,您也可以通过将必要的属性添加到 dataflow-server.yml 文件中来提供默认值, 如下例所示(以 PostgreSQL 为例):
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: myuser
password: mypass
driver-class-name:org.postgresql.Driver
-
或者,您可以使用自己的构建文件来构建一个自定义的 Spring Cloud Data Flow 服务器。 如果需要添加驱动程序 JAR 包,我们的示例仓库中提供了自定义服务器构建的示例。
10.2.8. 模式处理
默认情况下,数据库模式由 Flyway 管理,如果可以为数据库用户授予足够权限,这种方式非常方便。
以下是启动 Skipper 服务器时所发生情况的说明:
-
Flyway 会检查
flyway_schema_history表是否存在。 -
如果 schema 非空,则执行基线操作(至版本 1),因为如果使用了共享数据库,Dataflow 表可能已经存在。
-
如果 schema 为空,Flyway 会假定从零开始。
-
执行所有必需的数据库模式迁移。
以下是启动Dataflow服务器时发生的情况的描述:
-
Flyway 会检查
flyway_schema_history_dataflow表是否存在。 -
如果 schema 非空,则执行基线操作(到版本 1),因为如果使用了共享数据库,Skipper 表可能已经存在。
-
如果 schema 为空,Flyway 会假定从零开始。
-
执行所有必需的数据库模式迁移。
-
由于历史原因,如果我们检测到 schema 来自 1.7.x 版本系列, 我们会将其转换为 2.0.x 及更高版本所需的结构,并完全继续使用 Flyway。
|
我们的源代码中包含 schema 的 DDL 文件
schemas,
如果通过配置 |
10.3. 部署器属性
您可以使用本地部署器(Local deployer)的以下配置属性来自定义流(Streams)和任务(Tasks)的部署方式。
当使用 Data Flow Shell 进行部署时,可以使用语法 deployer.<appName>.local.<deployerPropertyName>。请参见下面的 Shell 使用示例。
在 Data Flow 服务器中配置本地任务平台(Local Task Platforms)以及在 Skipper 中配置用于部署流的本地平台时,也会用到这些属性。
| 部署器属性名称 | 描述 | 默认值 |
|---|---|---|
工作目录根路径 |
所有创建的进程将在此目录中运行并生成日志文件。 |
java.io.tmpdir |
要继承的环境变量 |
传递给已启动应用程序的环境变量的正则表达式模式数组。 |
<\"TMP\", \"LANG\", \"LANGUAGE\", \"LC_.*\", \"PATH\", \"SPRING_APPLICATION_JSON\"> 在 Windows 上和 <\"TMP\", \"LANG\", \"LANGUAGE\", \"LC_.*\", \"PATH\"> 在 Unix 上 |
退出时删除文件 |
是否在 JVM 退出时删除已创建的文件和目录。 |
true |
javaCmd |
运行 Java 的命令 |
Java |
关闭超时时间 |
应用关闭时等待的最长时间(秒)。 |
30 |
javaOpts |
要传递给 JVM 的 Java 选项,例如 -Dtest=foo |
<none> |
继承日志记录 |
允许将日志记录重定向到触发子进程的进程的输出流。 |
false |
debugPort |
远程调试端口 |
<none> |
例如,要为 ticktock 流中的 time 应用程序设置 Java 选项,请使用以下流部署属性。
dataflow:> stream create --name ticktock --definition "time --server.port=9000 | log"
dataflow:> stream deploy --name ticktock --properties "deployer.time.local.javaOpts=-Xmx2048m -Dtest=foo"
为方便起见,您可以设置 deployer.memory 属性来配置 Java 选项 -Xmx,如下例所示:
dataflow:> stream deploy --name ticktock --properties "deployer.time.memory=2048m"
在部署时,如果您在 -Xmx 属性中指定了 deployer.<app>.local.javaOpts 选项,同时又设置了 deployer.<app>.local.memory 选项的值,则 javaOpts 属性中的值优先。此外,部署应用程序时设置的 javaOpts 属性优先于 Data Flow Server 的 spring.cloud.deployer.local.javaOpts 属性。
10.4. 日志记录
Spring Cloud Data Flow 的 local 服务器会自动配置为使用 RollingFileAppender 进行日志记录。
日志配置位于类路径下,包含在一个名为 logback-spring.xml 的文件中。
默认情况下,日志文件配置为使用:
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring-cloud-dataflow-server}"/>
配合 RollingPolicy 的 logback 配置:
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- daily rolling -->
<fileNamePattern>${LOG_FILE}.${LOG_FILE_ROLLING_FILE_NAME_PATTERN:-%d{yyyy-MM-dd}}.%i.gz</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-100MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
<totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP:-500MB}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
要检查当前 Spring Cloud Data Flow Server java.io.tmpdir 服务器的 local,
jinfo <pid> | grep "java.io.tmpdir"
如果你想更改或覆盖任意属性 LOG_FILE、LOG_PATH、LOG_TEMP、LOG_FILE_MAX_SIZE、LOG_FILE_MAX_HISTORY 和 LOG_FILE_TOTAL_SIZE_CAP,请将它们设置为系统属性。
10.5. 流
Data Flow Server 将流(Stream)生命周期的管理委托给 Skipper 服务器。请将配置属性 spring.cloud.skipper.client.serverUri 设置为 Skipper 的位置,例如:
$ java -jar spring-cloud-dataflow-server-2.8.3.jar --spring.cloud.skipper.client.serverUri=https://192.51.100.1:7577/api
展示流(show streams)的配置、部署以及所使用的平台,是通过在 Skipper 服务器上配置platform accounts来完成的。
更多信息请参阅平台(platforms)相关文档。
10.6. 任务
Data Flow 服务器负责部署任务(Tasks)。
由 Data Flow 启动的任务会将其状态写入 Data Flow 服务器所使用的同一数据库中。
对于作为 Spring Batch 作业的任务,其作业和步骤的执行数据也会存储在该数据库中。
与由 Skipper 启动的流(streams)类似,任务也可以被部署到多个平台。
如果未定义平台,则会使用 LocalDeployerProperties 类的默认值创建一个名为 https://github.com/spring-cloud/spring-cloud-deployer-local/blob/master/spring-cloud-deployer-local/src/main/java/org/springframework/cloud/deployer/spi/local/LocalDeployerProperties.java 的平台,该类的默认值汇总于表格 本地部署器属性(Local Deployer Properties) 中。
要为本地平台配置新的平台账户,请在您的 spring.cloud.dataflow.task.platform.local 文件中的 application.yaml 部分下添加相应条目,或通过其他 Spring Boot 支持的机制进行配置。
在以下示例中,创建了两个名为 localDev 和 localDevDebug 的本地平台账户。
其中,shutdownTimeout 和 javaOpts 等键是本地部署器属性。
spring:
cloud:
dataflow:
task:
platform:
local:
accounts:
localDev:
shutdownTimeout: 60
javaOpts: "-Dtest=foo -Xmx1024m"
localDevDebug:
javaOpts: "-Xdebug -Xmx2048m"
通过将一个平台定义为 default,您可以在原本必须使用 platformName 的地方省略它。 |
启动任务时,请使用任务启动选项 --platformName 传递平台账户名称的值。如果您未为 platformName 传递值,则将使用默认值 default。
| 将任务部署到多个平台时,该任务的配置需要连接到与 Data Flow Server 相同的数据库。 |
您可以配置本地运行的 Data Flow 服务器,以将任务部署到 Cloud Foundry 或 Kubernetes。更多信息请参阅Cloud Foundry 任务平台配置和Kubernetes 任务平台配置部分。
有关在多个平台上启动和调度任务的详细示例,请参见本节任务的多平台支持,位于dataflow.spring.io。
启动 Skipper
git clone https://github.com/spring-cloud/spring-cloud-skipper.git
cd spring-cloud/spring-cloud-skipper
./mvnw clean package -DskipTests=true
java -jar spring-cloud-skipper-server/target/spring-cloud-skipper-server-2.2.0.BUILD-SNAPSHOT.jar
启动 Spring Cloud Data Flow
git clone https://github.com/spring-cloud/spring-cloud-dataflow.git
cd spring-cloud-dataflow
./mvnw clean package -DskipTests=true
cd ..
创建一个名为 scdf.yml 的 YAML 文件,内容如下:
spring:
cloud:
dataflow:
security:
authorization:
provider-role-mappings:
uaa:
map-oauth-scopes: true
role-mappings:
ROLE_CREATE: foo.create
ROLE_DEPLOY: foo.create
ROLE_DESTROY: foo.create
ROLE_MANAGE: foo.create
ROLE_MODIFY: foo.create
ROLE_SCHEDULE: foo.create
ROLE_VIEW: foo.view
security:
oauth2:
client:
registration:
uaa:
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
authorization-grant-type: authorization_code
client-id: dataflow
client-secret: dataflow
scope: (1)
- openid
- foo.create
- foo.view
provider:
uaa:
jwk-set-uri: http://uaa:8080/uaa/token_keys
token-uri: http://uaa:8080/uaa/oauth/token
user-info-uri: http://uaa:8080/uaa/userinfo (2)
user-name-attribute: user_name
authorization-uri: http://uaa:8080/uaa/oauth/authorize
resourceserver:
opaquetoken: (3)
introspection-uri: http://uaa:8080/uaa/introspect
client-id: dataflow
client-secret: dataflow
| 1 | 如果您使用作用域(scopes)来标识角色,请确保同时请求相关的 scope,例如 dataflow.view、dataflow.create,并且不要忘记请求 openid scope。 |
| 2 | 用于检索个人资料信息,例如用于显示的用户名(必填) |
| 3 | 用于Tokens内省和验证(必填) |
introspection-uri 属性在将外部获取的(不透明的)OAuth 访问Tokens传递给 Spring Cloud Data Flow 时尤为重要。在这种情况下,Spring Cloud Data Flow 会使用该 OAuth 访问Tokens,并通过 UAA 的Tokens自省端点(Introspect Token Endpoint)来验证Tokens的有效性,同时从 UAA 获取关联的 OAuth 作用域。
最后启动 Spring Cloud Data Flow:
java -jar spring-cloud-dataflow/spring-cloud-dataflow-server/target/spring-cloud-dataflow-server-2.4.0.BUILD-SNAPSHOT.jar --spring.config.additional-location=scdf.yml
角色映射
默认情况下,所有角色都会分配给登录到 Spring Cloud Data Flow 的用户。 不过,您可以设置以下属性:
spring.cloud.dataflow.security.authorization.provider-role-mappings.uaa.map-oauth-scopes: true
这将指示底层的DefaultAuthoritiesExtractor将OAuth作用域映射到相应的权限。支持以下作用域:
-
作用域
dataflow.create对应于CREATE角色 -
作用域
dataflow.deploy对应于DEPLOY角色 -
作用域
dataflow.destroy对应于DESTROY角色 -
作用域
dataflow.manage对应于MANAGE角色 -
作用域
dataflow.modify对应于MODIFY角色 -
作用域
dataflow.schedule对应于SCHEDULE角色 -
作用域
dataflow.view对应于VIEW角色
此外,您还可以将任意作用域映射到每个 Data Flow 角色:
spring:
cloud:
dataflow:
security:
authorization:
provider-role-mappings:
uaa:
map-oauth-scopes: true (1)
role-mappings:
ROLE_CREATE: dataflow.create (2)
ROLE_DEPLOY: dataflow.deploy
ROLE_DESTROY: dataflow.destoy
ROLE_MANAGE: dataflow.manage
ROLE_MODIFY: dataflow.modify
ROLE_SCHEDULE: dataflow.schedule
ROLE_VIEW: dataflow.view
| 1 | 启用从 OAuth 范围到 Data Flow 角色的显式映射支持 |
| 2 | 启用角色映射支持后,您必须为全部 7 个 Spring Cloud Data Flow 角色提供映射:ROLE_CREATE、ROLE_DEPLOY、ROLE_DESTROY、ROLE_MANAGE、ROLE_MODIFY、ROLE_SCHEDULE、ROLE_VIEW。 |
|
您可以将一个 OAuth 范围分配给多个 Spring Cloud Data Flow 角色,从而在授权配置的粒度方面获得更大的灵活性。 |
10.6.4. LDAP 认证
LDAP 认证(轻量级目录访问协议)由 Spring Cloud Data Flow 通过 UAA 间接提供。UAA 本身提供了全面的 LDAP 支持。
|
虽然您可以使用自己的 OAuth2 认证服务器,但此处文档所述的 LDAP 支持要求使用 UAA 作为认证服务器。对于其他任何提供商,请参阅该特定提供商的文档。 |
UAA 支持通过以下模式对 LDAP(轻量级目录访问协议)服务器进行身份验证:
|
在与外部身份提供商(例如 LDAP)集成时,UAA 中的身份验证会变为链式。UAA 首先尝试使用用户的凭据在 UAA 用户存储中进行身份验证,然后再尝试外部提供商 LDAP。有关更多信息,请参阅 GitHub 文档《User Account and Authentication LDAP Integration》中的链式身份验证。 |
LDAP 角色映射
OAuth2 认证服务器(UAA)提供了对将 LDAP 组映射到 OAuth 作用域的全面支持。
存在以下选项:
-
ldap/ldap-groups-null.xml不会映射任何组 -
ldap/ldap-groups-as-scopes.xml组名称将从 LDAP 属性中获取,例如CN -
ldap/ldap-groups-map-to-scopes.xml将使用 external_group_mapping 表将群组映射到 UAA 群组
这些值通过配置属性 ldap.groups.file controls 指定。在底层,这些值引用了一个 Spring XML 配置文件。
|
在测试和开发过程中,可能需要频繁修改 LDAP 组和用户,并希望这些更改能立即在 UAA 中生效。然而,用户信息会在登录期间被缓存。以下脚本有助于快速获取更新后的信息:
|
LDAP 安全性与 UAA 示例应用程序
为了帮助您快速上手并理解安全架构,我们在 GitHub 上提供了LDAP 安全与 UAA 示例。
|
这仅是一个演示/示例应用程序,不得用于生产环境。 |
设置包括:
-
Spring Cloud Data Flow 服务器
-
Skipper 服务器
-
CloudFoundry 用户账户与认证(UAA)服务器
-
轻量级目录访问协议(LDAP)服务器(由Apache Directory Server(ApacheDS)提供)
最终,在本示例中,您将学习如何使用此安全设置来配置和启动一个组合任务(Composed Task)。
10.6.5. Spring Security OAuth2 资源服务器/授权服务器示例
对于本地测试和开发,您也可以使用由 Spring Security OAuth 提供的资源服务器和授权服务器支持。它允许您通过以下简单的注解轻松创建自己的(非常基础的)OAuth2 服务器:
-
@EnableResourceServer -
@EnableAuthorizationServer
| 事实上,UAA 在底层使用了 Spring Security OAuth2,因此基本的端点是相同的。 |
可在以下位置找到一个可运行的示例应用程序: https://github.com/ghillert/oauth-test-server/
克隆项目并使用相应的客户端 ID 和客户端密钥配置 Spring Cloud Data Flow:
security:
oauth2:
client:
client-id: myclient
client-secret: mysecret
access-token-uri: http://127.0.0.1:9999/oauth/token
user-authorization-uri: http://127.0.0.1:9999/oauth/authorize
resource:
user-info-uri: http://127.0.0.1:9999/me
token-info-uri: http://127.0.0.1:9999/oauth/check_token
| 此示例应用程序不适用于生产环境使用 |
10.6.6. Data Flow Shell 认证
使用 Shell 时,凭证可以通过用户名和密码提供, 或者通过指定 credentials-provider 命令来提供。如果你的 OAuth2 提供商支持 Password 授权类型,你可以使用以下方式启动 Data Flow Shell:
$ java -jar spring-cloud-dataflow-shell-2.8.3.jar \
--dataflow.uri=http://localhost:9393 \ (1)
--dataflow.username=my_username \ (2)
--dataflow.password=my_password \ (3)
--skip-ssl-validation true \ (4)
| 1 | 可选,默认值为 localhost:9393。 |
| 2 | Mandatory. |
| 3 | 如果未提供密码,系统会提示用户输入。 |
| 4 | 可选,默认值为 false,用于忽略证书错误(使用自签名证书时)。请谨慎使用! |
| 请记住,当启用了 Spring Cloud Data Flow 的认证功能时, 如果希望通过用户名/密码认证方式使用 Shell, 底层的 OAuth2 提供商必须支持Password(密码)OAuth2 授权类型。 |
在 Data Flow Shell 中,您也可以通过使用以下命令来提供凭据:
server-unknown:>dataflow config server \
--uri http://localhost:9393 \ (1)
--username myuser \ (2)
--password mysecret \ (3)
--skip-ssl-validation true \ (4)
| 1 | 可选,默认值为 localhost:9393。 |
| 2 | Mandatory.. |
| 3 | 如果启用了安全功能且未提供密码,系统将提示用户输入密码。 |
| 4 | 可选,忽略证书错误(使用自签名证书时)。请谨慎使用! |
下图展示了一个典型的 shell 命令,用于连接并认证 Data Flow 服务器:
一旦成功定位,您应该会看到以下输出:
dataflow:>dataflow config info
dataflow config info
╔═══════════╤═══════════════════════════════════════╗
║Credentials│[username='my_username, password=****']║
╠═══════════╪═══════════════════════════════════════╣
║Result │ ║
║Target │http://localhost:9393 ║
╚═══════════╧═══════════════════════════════════════╝
或者,您可以指定 credentials-provider 命令,直接传入一个 Bearer Token,而不必提供用户名和密码。
这可以在 Shell 内部使用,也可以在启动 Shell 时通过提供命令行参数
--dataflow.credentials-provider-command 来实现。
|
使用 credentials-provider 命令时,请注意您指定的命令必须返回一个 Bearer token(即以 Bearer 为前缀的访问Tokens)。 例如,在 Unix 环境中,可以使用以下简单的命令:
|
10.7. 关于配置
Spring Cloud Data Flow 的 About Restful API 返回结果包含构成 Spring Cloud Data Flow 的每个主要依赖项的显示名称、版本,以及(如果指定)其对应的 URL。该结果(若已启用)还包含 shell 依赖项的 sha1 和/或 sha256 校验和值。通过设置以下属性,可以配置为每个依赖项返回的信息:
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-core.name:用于核心的名称。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-core.version: 用于核心组件的版本。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-dashboard.name:用于仪表板的名称。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-dashboard.version: 用于仪表板的版本。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-implementation.name:用于实现的名称。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-implementation.version: 用于实现的版本。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.name:用于指定 shell 的名称。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.version: 用于 Shell 的版本。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.url: 用于下载 Shell 依赖项的 URL。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha1:与 shell 依赖信息一同返回的 SHA1 校验和值。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha256: 随 Shell 依赖信息返回的 SHA256 校验和值。
-
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha1-url: 如果未指定
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha1, SCDF 将使用此 URL 所指定文件的内容作为校验和。 -
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha256-url: 如果未指定
spring.cloud.dataflow.version-info.spring-cloud-dataflow-shell.checksum-sha256, SCDF 将使用此 URL 所指定文件的内容作为校验和。
10.7.1. 启用 Shell 校验和值
默认情况下,shell 依赖项不会显示校验和值。如果需要启用此功能,请将
spring.cloud.dataflow.version-info.dependency-fetch.enabled 属性设置为 true。
10.7.2. URL 的保留值
有一些保留值(用花括号包围),您可以将它们插入到 URL 中,以确保链接始终保持最新:
-
repository:如果使用的是 Data Flow 的构建快照(build-snapshot)、里程碑版本(milestone)或发布候选版本(release candidate),则 repository 指的是 repo-spring-io 仓库;否则,它指的是 Maven Central。
-
version:插入 jar/pom 的版本。
例如,
myrepository/org/springframework/cloud/spring-cloud-dataflow-shell/{version}/spring-cloud-dataflow-shell-{version}.jar
会生成
myrepository/org/springframework/cloud/spring-cloud-dataflow-shell/1.2.3.RELEASE/spring-cloud-dataflow-shell-1.2.3.RELEASE.jar
如果你使用的是 Spring Cloud Data Flow Shell 的 1.2.3.RELEASE 版本。
11. 配置 - Cloud Foundry
本节介绍如何配置 Spring Cloud Data Flow 服务器的功能,例如安全性以及使用哪种关系型数据库。 同时还介绍了如何配置 Spring Cloud Data Flow Shell 的功能。
11.1. 功能开关
Data Flow 服务器在启动时提供了一组特定的功能,您可以选择启用或禁用这些功能。这些功能包括以下各项的完整生命周期操作和 REST 端点(服务器、客户端实现,包括 Shell 和 UI):
-
流
-
任务
您可以在启动 Data Flow 服务器时,通过设置以下布尔属性来启用或禁用这些功能:
-
spring.cloud.dataflow.features.streams-enabled -
spring.cloud.dataflow.features.tasks-enabled
默认情况下,所有功能均已启用。
REST 端点(/features)提供有关已启用和已禁用功能的信息。
11.2. 部署器属性
您可以使用 Data Flow 服务器的Cloud Foundry 部署器的以下配置属性来自定义应用程序的部署方式。
使用 Data Flow Shell 进行部署时,可以使用语法 deployer.<appName>.cloudfoundry.<deployerPropertyName>。下方提供了一个 Shell 使用示例。
在 Data Flow 服务器中配置Cloud Foundry 任务平台以及在 Skipper 中配置 Kubernetes 平台以部署流(Streams)时,也会用到这些属性。
| 部署器属性名称 | 描述 | 默认值 |
|---|---|---|
服务 |
要绑定到已部署应用程序的服务名称。 |
<none> |
主机 |
用作路由一部分的主机名。 |
由 Cloud Foundry 派生的主机名 |
域 |
应用程序映射路由时使用的域。 |
<none> |
路由 |
应用程序应绑定的路由列表。与 host 和 domain 互斥。 |
<none> |
构建包 |
用于部署应用程序的 buildpack。已弃用,请改用 buildpacks。 |
|
构建包 |
用于部署应用程序的构建包列表。 |
|
内存 |
要分配的内存量。默认单位为兆字节(mebibytes),支持 'M' 和 'G' 后缀。 |
1024m |
磁盘 |
要分配的磁盘空间大小。默认单位为兆字节(mebibytes),支持 'M' 和 'G' 后缀。 |
1024m |
健康检查 |
对已部署应用程序执行的健康检查类型。可选值包括 HTTP、NONE、PROCESS 和 PORT。 |
端口 |
healthCheckHttpEndpoint |
HTTP 健康检查将使用的路径, |
/health |
healthCheckTimeout |
健康检查的超时时间(以秒为单位)。 |
120 |
实例 |
要运行的实例数量。 |
1 |
启用随机应用名称前缀 |
用于启用在应用名称前添加随机前缀的标志。 |
true |
api超时 |
阻塞式 API 调用的超时时间,单位为秒。 |
360 |
状态超时 |
状态 API 操作的超时时间(以毫秒为单位) |
5000 |
useSpringApplicationJson |
用于指示应用程序属性是传入 |
true |
stagingTimeout |
为应用程序暂存分配的超时时间。 |
15 分钟 |
启动超时时间 |
为启动应用程序分配的超时时间。 |
5 分钟 |
appNamePrefix |
用作已部署应用程序名称前缀的字符串 |
使用部署器(deployer)库的应用程序的 Spring Boot 属性 |
删除路由 |
在取消部署应用程序时,是否同时删除路由。 |
true |
javaOpts |
要传递给 JVM 的 Java 选项,例如 -Dtest=foo |
<none> |
pushTasksEnabled |
是推送任务应用程序,还是在启动时假定应用程序已存在。 |
true |
自动删除 Maven 构件 |
在部署时是否自动从本地仓库中删除 Maven 工件。 |
true |
env.<key> |
定义一个顶层环境变量。这对于自定义Java buildpack 配置非常有用,因为该配置必须作为顶层环境变量包含在应用程序清单中,而 Java buildpack 无法识别 |
部署器会判断应用程序的类路径中是否包含Java CfEnv。如果是,则应用所需的配置。 |
以下是一些使用 Cloud Foundry 部署属性的示例:
-
您可以设置用于部署每个应用程序的构建包。例如,要使用 Java 离线构建包,请设置以下环境变量:
cf set-env dataflow-server SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_BUILDPACKS java_buildpack_offline
-
现在已弃用设置
buildpack,推荐使用buildpacks,以便在需要时传入多个构建包。更多相关信息请参见构建包的工作原理。 -
您可以通过使用
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_HEALTH_CHECK环境变量,来自定义 Cloud Foundry 用于判断应用程序是否正在运行的健康检查机制。当前支持的选项包括http(默认值)、port和none。
你还可以设置环境变量来指定基于 HTTP 的健康检查端点和超时时间,分别是:SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_HEALTH_CHECK_ENDPOINT 和 SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_HEALTH_CHECK_TIMEOUT。它们的默认值分别为 /health(Spring Boot 的默认位置)和 120 秒。
-
你也可以使用 DSL 来指定部署属性。例如,如果你想将
http应用的分配内存设置为 512m,并且还将一个 MySQL 服务绑定到jdbc应用,可以运行以下命令:
dataflow:> stream create --name mysqlstream --definition "http | jdbc --tableName=names --columns=name"
dataflow:> stream deploy --name mysqlstream --properties "deployer.http.memory=512, deployer.jdbc.cloudfoundry.services=mysql"
|
您可以分别为流应用(stream apps)和任务应用(task apps)配置这些设置。要修改任务应用的设置,请在属性名称中将
|
11.3. 任务
Data Flow 服务器负责部署任务(Tasks)。
由 Data Flow 启动的任务会将其状态写入与 Data Flow 服务器所使用的同一个数据库中。
对于作为 Spring Batch 作业的任务,其作业(job)和步骤(step)的执行数据也会存储在此数据库中。
与 Skipper 类似,任务可以被部署到多个平台。
当 Data Flow 在 Cloud Foundry 上运行时,必须定义一个任务平台。
要配置指向 Cloud Foundry 的新平台账户,您可以在 spring.cloud.dataflow.task.platform.cloudfoundry 文件中的 application.yaml 部分添加相应条目,或者通过其他 Spring Boot 支持的机制进行配置。
在以下示例中,创建了两个名为 dev 和 qa 的 Cloud Foundry 平台账户。
其中诸如 memory 和 disk 等键是Cloud Foundry 部署器属性。
spring:
cloud:
dataflow:
task:
platform:
cloudfoundry:
accounts:
dev:
connection:
url: https://api.run.pivotal.io
org: myOrg
space: mySpace
domain: cfapps.io
username: [email protected]
password: drowssap
skipSslValidation: false
deployment:
memory: 512m
disk: 2048m
instances: 4
services: rabbit,mysql
appNamePrefix: dev1
qa:
connection:
url: https://api.run.pivotal.io
org: myOrgQA
space: mySpaceQA
domain: cfapps.io
username: [email protected]
password: drowssap
skipSslValidation: true
deployment:
memory: 756m
disk: 724m
instances: 2
services: rabbitQA,mysqlQA
appNamePrefix: qa1
通过将一个平台定义为 default,您可以在原本必须使用 platformName 的地方省略它。 |
启动任务时,请使用任务启动选项 --platformName 传递平台账户名称的值。如果您未为 platformName 传递值,则将使用默认值 default。
| 将任务部署到多个平台时,该任务的配置需要连接到与 Data Flow Server 相同的数据库。 |
您可以将部署在 Cloud Foundry 上的 Data Flow 服务器配置为向 Cloud Foundry 或 Kubernetes 部署任务。有关更多信息,请参阅Kubernetes 任务平台配置部分。
有关在多个平台上启动和调度任务的详细示例,请参见本节任务的多平台支持,位于dataflow.spring.io。
11.4. 应用程序名称和前缀
为了帮助避免 Cloud Foundry 中不同空间(spaces)之间的路由冲突,系统提供了一种命名策略,可为已部署的应用程序添加随机前缀,该策略默认启用。您可以通过 https://github.com/spring-cloud/spring-cloud-deployer-cloudfoundry#application-name-settings-and-deployments 命令覆盖默认配置并设置相应的属性。
例如,如果你想禁用随机化,可以通过使用以下命令来覆盖它:
cf set-env dataflow-server SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_ENABLE_RANDOM_APP_NAME_PREFIX false
11.5. 自定义路由
作为使用随机名称的替代方案,或者为了对部署应用程序所使用的主机名进行更精细的控制,您可以使用自定义部署属性,如下例所示:
dataflow:>stream create foo --definition "http | log"
sdataflow:>stream deploy foo --properties "deployer.http.cloudfoundry.domain=mydomain.com,
deployer.http.cloudfoundry.host=myhost,
deployer.http.cloudfoundry.route-path=my-path"
前面的示例将 http 应用绑定到 myhost.mydomain.com/my-path URL。请注意,此示例展示了所有可用的自定义选项。在实际使用中,您可以只选用其中的一到两项。
11.6. Docker 应用程序
从 1.2 版本开始,可以使用 Cloud Foundry 版 Data Flow 将基于 Docker 的应用注册并部署为流(streams)和任务(tasks)的一部分。
如果你使用 Spring Boot 和基于 RabbitMQ 的 Docker 镜像,可以提供一个通用的部署属性,
以便简化将应用程序绑定到 RabbitMQ 服务的过程。假设你的 RabbitMQ 服务名为 rabbit,你可以提供以下内容:
cf set-env dataflow-server SPRING_APPLICATION_JSON '{"spring.cloud.dataflow.applicationProperties.stream.spring.rabbitmq.addresses": "${vcap.services.rabbit.credentials.protocols.amqp.uris}"}'
对于 Spring Cloud Task 应用,如果你使用了一个名为 mysql 的数据库服务实例,可以采用类似以下的方式:
cf set-env SPRING_DATASOURCE_URL '${vcap.services.mysql.credentials.jdbcUrl}'
cf set-env SPRING_DATASOURCE_USERNAME '${vcap.services.mysql.credentials.username}'
cf set-env SPRING_DATASOURCE_PASSWORD '${vcap.services.mysql.credentials.password}'
cf set-env SPRING_DATASOURCE_DRIVER_CLASS_NAME 'org.mariadb.jdbc.Driver'
对于非 Java 或非 Boot 应用程序,您的 Docker 应用必须解析 VCAP_SERVICES 变量,以便绑定到任何可用的服务。
|
传递应用程序属性
在使用非 Spring Boot 应用程序时,您很可能希望使用传统的环境变量来传递应用程序属性,而不是使用特殊的
|
11.7. 应用级服务绑定
在 Cloud Foundry 中部署流应用时,您可以利用特定于应用程序的服务绑定,因此并非所有服务都需要为 Spring Cloud Data Flow 编排的所有应用进行全局配置。
例如,如果你只想在以下流定义中为 mysql 应用程序提供 jdbc 服务绑定,你可以将该服务绑定作为部署属性传递:
dataflow:>stream create --name httptojdbc --definition "http | jdbc"
dataflow:>stream deploy --name httptojdbc --properties "deployer.jdbc.cloudfoundry.services=mysqlService"
其中 mysqlService 是专门绑定到 jdbc 应用程序的服务名称,而 http 应用程序不会通过此方法获得该绑定。
如果你有多个服务需要绑定,可以将它们以逗号分隔的形式传入
(例如:deployer.jdbc.cloudfoundry.services=mysqlService,someService)。
11.8. 配置服务绑定参数
CloudFoundry API 支持在绑定服务实例时提供配置参数。某些服务代理(service broker)要求或建议提供绑定配置。 例如,使用 CF CLI 绑定 Google Cloud Platform 服务 的命令大致如下:
cf bind-service my-app my-google-bigquery-example -c '{"role":"bigquery.user"}'
同样,NFS 卷服务也支持如下绑定配置:
cf bind-service my-app nfs_service_instance -c '{"uid":"1000","gid":"1000","mount":"/var/volume1","readonly":true}'
从 2.0 版本开始,Cloud Foundry 的 Data Flow 允许您在应用级别或服务器级别的 cloudfoundry.services 部署属性中提供绑定配置参数。例如,要绑定到上述的 nfs 服务:
dataflow:> stream deploy --name mystream --properties "deployer.<app>.cloudfoundry.services='nfs_service_instance uid:1000,gid:1000,mount:/var/volume1,readonly:true'"
该格式旨在与 Data Flow DSL 解析器兼容。
通常,cloudfoundry.services 部署属性接受以逗号分隔的值。
由于逗号也用于分隔配置参数,并且为了避免空格问题,任何包含配置参数的项都必须用单引号括起来。有效值包括如下内容:
rabbitmq,'nfs_service_instance uid:1000,gid:1000,mount:/var/volume1,readonly:true',mysql,'my-google-bigquery-example role:bigquery.user'
单引号内允许包含空格,并且可以使用 = 代替 : 来分隔键值对。 |
11.9. 用户提供的服务
除了市场服务外,Cloud Foundry 还支持用户自定义服务(User-provided Services,简称 UPS)。在本参考手册中,我们提到了常规服务,但同样也可以使用用户自定义服务,无论是用作消息中间件(例如,如果您想使用外部的 Apache Kafka 安装),还是供某些流应用程序使用(例如 Oracle 数据库)。
现在我们回顾一个从 UPS 中提取并提供连接凭据的示例。
以下示例展示了 Apache Kafka 的一个 UPS 配置示例:
cf create-user-provided-service kafkacups -p '{”brokers":"HOST:PORT","zkNodes":"HOST:PORT"}'
UPS 凭据被封装在 VCAP_SERVICES 中,可以直接在流定义中提供,如下例所示。
stream create fooz --definition "time | log"
stream deploy fooz --properties "app.time.spring.cloud.stream.kafka.binder.brokers=${vcap.services.kafkacups.credentials.brokers},app.time.spring.cloud.stream.kafka.binder.zkNodes=${vcap.services.kafkacups.credentials.zkNodes},app.log.spring.cloud.stream.kafka.binder.brokers=${vcap.services.kafkacups.credentials.brokers},app.log.spring.cloud.stream.kafka.binder.zkNodes=${vcap.services.kafkacups.credentials.zkNodes}"
11.10. 数据库连接池
从 Data Flow 2.0 开始,不再使用 Spring Cloud Connector 库来创建 DataSource。 现在改用 java-cfenv 库,它允许你通过设置 Spring Boot 属性 来配置连接池。
11.11. 最大磁盘配额
默认情况下,Cloud Foundry 中的每个应用程序启动时都带有 1GB 的磁盘配额,此配额最多可调整至默认最大值 2GB。通过使用 Pivotal Cloud Foundry(PCF)的 Ops Manager 图形用户界面,还可将该默认最大值进一步覆盖提升至 10GB。
此配置与 Spring Cloud Data Flow 相关,因为每个任务部署都由应用程序(通常是 Spring Boot 的 uber-jar)组成,而这些应用程序是从远程 Maven 仓库解析获取的。解析完成后,应用程序制品会被下载到本地 Maven 仓库中,以便缓存和重复使用。由于这一过程在后台进行,默认磁盘配额(1GB)可能会迅速被占满,尤其是在我们试验由多个不同应用程序组成的流时更是如此。为了克服这一磁盘限制,并根据您的扩展需求,您可能希望将默认的最大配额从 2GB 调整为 10GB。接下来,让我们回顾一下更改默认最大磁盘配额分配的步骤。
11.11.1. PCF 的 Operations Manager
在 PCF 的 Ops Manager 中,选择“Pivotal Elastic Runtime”磁贴,然后导航到“应用程序开发者控制”选项卡。 将“每个应用的最大磁盘配额(MB)”设置从 2048(2G)更改为 10240(10G)。保存磁盘配额更新,然后点击 “应用更改”以完成配置覆盖。
11.12. 扩展应用程序
一旦磁盘配额更改已成功应用,并且假设您已有一个正在运行的应用程序,
您可以通过 CF CLI 使用新的 disk_limit 来扩展该应用程序,如下例所示:
→ cf scale dataflow-server -k 10GB
Scaling app dataflow-server in org ORG / space SPACE as user...
OK
....
....
....
....
state since cpu memory disk details
#0 running 2016-10-31 03:07:23 PM 1.8% 497.9M of 1.1G 193.9M of 10G
然后,您可以列出应用程序并查看新的最大磁盘空间,如下例所示:
→ cf apps
Getting apps in org ORG / space SPACE as user...
OK
name requested state instances memory disk urls
dataflow-server started 1/1 1.1G 10G dataflow-server.apps.io
11.13. 管理磁盘使用
即使将 Data Flow 服务器配置为使用 10GB 的空间,仍有可能耗尽本地磁盘上的可用空间。为防止这种情况,从外部来源下载的 jar 构件,即e.注册为http或maven资源的应用程序,在应用程序部署时会自动删除,无论部署请求是否成功。这种行为在生产环境中是最优的,因为在这些环境中,容器运行时的稳定性比部署期间产生的 I/O 延迟更为关键。在开发环境中,部署发生的频率更高。此外,jar 构件(或更轻量的 metadata JAR)包含描述应用程序配置属性的元数据,这些属性被用于与应用程序配置相关的各种操作,在预生产活动中更为频繁地进行(参见应用程序元数据以获取详细信息)。为了在预生产环境中提供更响应式的交互式开发体验(以牺牲更多的磁盘使用空间为代价),您可以将CloudFoundry部署属性autoDeleteMavenArtifacts设置为false。
如果你使用默认的 port 健康检查类型部署 Data Flow 服务器,则必须显式监控服务器上的磁盘空间,以避免磁盘空间耗尽。
如果你使用 http 健康检查类型部署服务器(参见下一个示例),当磁盘空间不足时,Data Flow 服务器将自动重启。
这是由于 Spring Boot 的 磁盘空间健康指示器(Disk Space Health Indicator) 所致。
你可以通过使用以 https://docs.spring.io/spring-boot/docs/1.5.14.RELEASE/reference/htmlsingle/#common-application-properties 为前缀的属性来配置磁盘空间健康指示器的相关设置。
对于 1.7 版本,我们正在研究使用卷服务(Volume Services),以便 Data Flow 服务器在将 .jar 工件推送到 Cloud Foundry 之前进行存储。
以下示例展示了如何将 http 健康检查类型部署到名为 /management/health 的端点:
---
...
health-check-type: http
health-check-http-endpoint: /management/health
11.14. 应用程序解析的替代方案
尽管我们建议使用 Maven 仓库来注册应用注册流应用, 但在某些情况下,采用以下替代方法之一可能更为合适。
-
我们定制开发并维护了一个SCDF APP 工具, 它可以在 Cloud Foundry 中作为普通的 Spring Boot 应用程序运行,但在运行时会托管并提供 SCDF 所需的应用程序 JAR 文件。
-
借助 Spring Boot,我们可以在 Cloud Foundry 上提供静态内容。一个简单的 Spring Boot 应用程序可以打包所有所需的流应用和任务应用。通过在 Cloud Foundry 上运行该应用,这个静态应用便可以提供这些“超级 JAR”(über-jar)。例如,从 Shell 中,你可以使用
http-source.jar将名为--uri=http://<Route-To-StaticApp>/http-source.jar的应用程序注册到系统中。 -
这种超级 JAR 文件可以托管在任何可通过 HTTP 访问的外部服务器上,也可以通过原始 GitHub URI 进行解析。例如,在 Shell 中,你可以使用
http-source.jar将该应用注册为名称--uri=http://<Raw_GitHub_URI>/http-source.jar。 -
静态 Buildpack 在 Cloud Foundry 中是另一种选择。类似的 HTTP 解析方式在此模型中也同样适用。
-
Volume Services 是另一个绝佳的选择。 所需的 über-jar 可以托管在外部文件系统中。借助 Volume Services,例如,你可以使用
http-source.jar将应用程序注册为名称--uri=file://<Path-To-FileSystem>/http-source.jar。
11.15. 安全
默认情况下,Data Flow 服务器未启用安全保护,并通过未加密的 HTTP 连接运行。您可以通过启用 HTTPS 并要求客户端进行身份验证,来保护您的 REST 端点(以及 Data Flow 仪表板)。
有关保护 REST 端点以及配置针对 OAuth 后端(在 Cloud Foundry 上运行的 UAA 和 SSO)进行身份验证的更多详细信息,请参阅核心文档中的[configuration-local-security]安全章节。您可以在 dataflow-server.yml 中配置安全详情,也可以通过 cf set-env 命令以环境变量的形式传入这些配置。
11.15.1. 身份验证
Spring Cloud Data Flow 可以与 Pivotal 单点登录服务(例如在 PWS 上)或 Cloud Foundry 用户账户与身份验证(UAA)服务器集成。
Pivotal 单点登录服务
将 Spring Cloud Data Flow 部署到 Cloud Foundry 时,您可以将应用程序绑定到 Pivotal 单点登录(Single Sign-On)服务。通过这种方式,Spring Cloud Data Flow 可以利用 Java CFEnv, 它为 OAuth 2.0 提供了 Cloud Foundry 特定的自动配置支持。
为此,请将 Pivotal 单点登录服务绑定到您的 Data Flow Server 应用程序,并提供以下属性:
SPRING_CLOUD_DATAFLOW_SECURITY_CFUSEUAA: false (1)
SECURITY_OAUTH2_CLIENT_CLIENTID: "${security.oauth2.client.clientId}"
SECURITY_OAUTH2_CLIENT_CLIENTSECRET: "${security.oauth2.client.clientSecret}"
SECURITY_OAUTH2_CLIENT_ACCESSTOKENURI: "${security.oauth2.client.accessTokenUri}"
SECURITY_OAUTH2_CLIENT_USERAUTHORIZATIONURI: "${security.oauth2.client.userAuthorizationUri}"
SECURITY_OAUTH2_RESOURCE_USERINFOURI: "${security.oauth2.resource.userInfoUri}"
| 1 | 属性 spring.cloud.dataflow.security.cf-use-uaa 必须设置为 false。 |
同样支持非 Cloud Foundry 安全场景下的授权。 请参阅核心 Data Flow 的安全章节[configuration-local-security]。
由于角色的配置在不同环境中可能存在很大差异,默认情况下,我们会为用户分配所有 Spring Cloud Data Flow 角色。
您可以通过提供您自己的 AuthoritiesExtractor 来自定义此行为。
以下示例展示了一种可能的方法,用于在 AuthoritiesExtractor 上设置自定义的 UserInfoTokenServices:
public class MyUserInfoTokenServicesPostProcessor
implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof UserInfoTokenServices) {
final UserInfoTokenServices userInfoTokenServices == (UserInfoTokenServices) bean;
userInfoTokenServices.setAuthoritiesExtractor(ctx.getBean(AuthoritiesExtractor.class));
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
然后你可以在你的配置类中按如下方式声明它:
@Bean
public BeanPostProcessor myUserInfoTokenServicesPostProcessor() {
BeanPostProcessor postProcessor == new MyUserInfoTokenServicesPostProcessor();
return postProcessor;
}
Cloud Foundry UAA
Cloud Foundry 用户账户与认证(UAA)的可用性取决于 Cloud Foundry 环境。
为了提供 UAA 集成,您必须提供必要的
OAuth2 配置属性(例如,通过设置 SPRING_APPLICATION_JSON
属性)。
以下 JSON 示例展示了如何创建安全配置:
{
"security.oauth2.client.client-id": "scdf",
"security.oauth2.client.client-secret": "scdf-secret",
"security.oauth2.client.access-token-uri": "https://login.cf.myhost.com/oauth/token",
"security.oauth2.client.user-authorization-uri": "https://login.cf.myhost.com/oauth/authorize",
"security.oauth2.resource.user-info-uri": "https://login.cf.myhost.com/userinfo"
}
默认情况下,spring.cloud.dataflow.security.cf-use-uaa 属性被设置为 true。此属性会激活一个特殊的
AuthoritiesExtractor,称为 CloudFoundryDataflowAuthoritiesExtractor。
如果您不使用 CloudFoundry UAA,应将 spring.cloud.dataflow.security.cf-use-uaa 设置为 false。
在底层,此 AuthoritiesExtractor 会调用
Cloud Foundry
Apps API,并确保用户确实是空间开发者(Space Developers)。
如果经过身份验证的用户被确认为“空间开发者”(Space Developer),则将分配所有角色。
11.16. 配置参考
您必须提供若干配置项。这些是 Spring Boot 的 @ConfigurationProperties,因此您可以将它们设置为环境变量,或使用 Spring Boot 支持的任何其他方式进行配置。以下列表采用环境变量格式,因为这是在 Cloud Foundry 中开始配置 Boot 应用程序的简便方式。
请注意,未来您将能够将任务部署到多个平台,但在 2.0.0.M1 版本中,您只能部署到单个平台,且该平台名称必须为 default。
# Default values appear after the equal signs.
# Example values, typical for Pivotal Web Services, are included as comments.
# URL of the CF API (used when using cf login -a for example) - for example, https://api.run.pivotal.io
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL=
# The name of the organization that owns the space above - for example, youruser-org
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG=
# The name of the space into which modules will be deployed - for example, development
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE=
# The root domain to use when mapping routes - for example, cfapps.io
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_DOMAIN=
# The user name and password of the user to use to create applications
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME=
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD
# The identity provider to be used when accessing the Cloud Foundry API (optional).
# The passed string has to be a URL-Encoded JSON Object, containing the field origin with value as origin_key of an identity provider - for example, {"origin":"uaa"}
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_LOGIN_HINT=
# Whether to allow self-signed certificates during SSL validation (you should NOT do so in production)
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SKIP_SSL_VALIDATION
# A comma-separated set of service instance names to bind to every deployed task application.
# Among other things, this should include an RDBMS service that is used
# for Spring Cloud Task execution reporting, such as my_postgres
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES
spring.cloud.deployer.cloudfoundry.task.services=
# Timeout, in seconds, to use when doing blocking API calls to Cloud Foundry
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_API_TIMEOUT=
# Timeout, in milliseconds, to use when querying the Cloud Foundry API to compute app status
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_STATUS_TIMEOUT
请注意,您可以通过使用 spring.cloud.deployer.cloudfoundry.services 快捷方式,在单个部署请求中设置 spring.cloud.deployer.cloudfoundry.buildpacks、
spring.cloud.deployer.memory,或 Spring Cloud Deployer 标准属性
spring.cloud.deployer.disk 和 deployer.<app-name>,如下例所示:
stream create --name ticktock --definition "time | log"
stream deploy --name ticktock --properties "deployer.time.memory=2g"
上例中的命令以 2048MB 内存部署了 time 源,而 log 接收器则使用默认的 1024MB 内存。
部署流时,你还可以将 JAVA_OPTS 作为部署属性传递,如下例所示:
stream deploy --name ticktock --properties "deployer.time.cloudfoundry.javaOpts=-Duser.timezone=America/New_York"
11.17. 调试
如果你想更深入地了解在部署流(streams)和任务(tasks)时系统内部发生了什么,可以启用以下功能:
-
Reactor 的“堆栈跟踪”(stacktraces),用于显示在错误发生前涉及了哪些操作符。此功能非常有用,因为部署者依赖 Project Reactor,而常规的堆栈跟踪并不总能清晰地展示错误发生前的数据流。 请注意,此功能会带来性能开销,因此默认处于禁用状态。
spring.cloud.dataflow.server.cloudfoundry.debugReactor == true
-
部署器和 Cloud Foundry 客户端库的请求与响应日志。此功能可用于查看 Data Flow 服务器与 Cloud Foundry Cloud Controller 之间的详细通信内容。
logging.level.cloudfoundry-client == DEBUG
11.18. Spring Cloud 配置服务器
您可以使用 Spring Cloud Config Server 来集中管理 Spring Boot 应用程序的配置属性。同样,Spring Cloud Data Flow 及其编排的应用程序也可以与配置服务器集成,以使用相同的功能。
11.18.1. Stream、Task 和 Spring Cloud Config Server
与 Spring Cloud Data Flow 服务器类似,您可以配置流(stream)和任务(task)应用程序,以从配置服务器解析集中式的属性。
为已部署的应用程序设置 spring.cloud.config.uri 属性是一种绑定到配置服务器的常用方式。
更多信息请参阅 Spring Cloud Config 客户端 参考指南。
由于该属性很可能被 Data Flow 服务器部署的所有应用程序所共用,因此可以使用 Data Flow 服务器的 spring.cloud.dataflow.applicationProperties.stream 属性(用于流应用程序)和 spring.cloud.dataflow.applicationProperties.task 属性(用于任务应用程序),将配置服务器的 uri 传递给每个已部署的流或任务应用程序。更多详情请参见通用应用程序属性一节。
请注意,如果您使用来自App Starters 项目的应用程序,这些应用程序已经内置了 spring-cloud-services-starter-config-client 依赖项。
如果您从零开始构建应用程序,并希望添加对配置服务器的客户端支持,可以添加对配置服务器客户端库的依赖引用。以下代码片段展示了一个 Maven 示例:
...
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-starter-config-client</artifactId>
<version>CONFIG_CLIENT_VERSION</version>
</dependency>
...
其中 CONFIG_CLIENT_VERSION 可以是面向 Pivotal Cloud Foundry 的 Spring Cloud Config Server 客户端的最新发布版本。
如果使用此库的应用程序在启动时或每次访问 WARN 端点时无法连接到配置服务器,您可能会看到一条 /health 级别的日志消息。
如果您确定未使用配置服务器功能,可以通过将环境变量 SPRING_CLOUD_CONFIG_ENABLED 设置为 false 来禁用该客户端库。 |
11.18.2. 示例清单模板
以下的 SCDF 和 Skipper manifest.yml 模板包含了 Skipper 和 Spring Cloud Data Flow 服务器以及所部署的应用程序和任务在 Cloud Foundry 上成功运行所需的环境变量,并能在运行时自动从 my-config-server 解析集中管理的属性:
---
applications:
- name: data-flow-server
host: data-flow-server
memory: 2G
disk_quota: 2G
instances: 1
path: {PATH TO SERVER UBER-JAR}
env:
SPRING_APPLICATION_NAME: data-flow-server
MAVEN_REMOTE_REPOSITORIES_REPO1_URL: https://repo.spring.io/libs-snapshot
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: https://api.sys.huron.cf-app.com
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: sabby20
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: sabby20
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_DOMAIN: apps.huron.cf-app.com
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: admin
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: ***
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SKIP_SSL_VALIDATION: true
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: mysql
SPRING_CLOUD_SKIPPER_CLIENT_SERVER_URI: https://<skipper-host-name>/api
services:
- mysql
- my-config-server
---
applications:
- name: skipper-server
host: skipper-server
memory: 1G
disk_quota: 1G
instances: 1
timeout: 180
buildpack: java_buildpack
path: <PATH TO THE DOWNLOADED SKIPPER SERVER UBER-JAR>
env:
SPRING_APPLICATION_NAME: skipper-server
SPRING_CLOUD_SKIPPER_SERVER_ENABLE_LOCAL_PLATFORM: false
SPRING_CLOUD_SKIPPER_SERVER_STRATEGIES_HEALTHCHECK_TIMEOUTINMILLIS: 300000
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: https://api.local.pcfdev.io
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: pcfdev-org
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: pcfdev-space
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_DOMAIN: cfapps.io
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: admin
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: admin
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SKIP_SSL_VALIDATION: false
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_DELETE_ROUTES: false
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: rabbit, my-config-server
services:
- mysql
my-config-server
其中 my-config-server 是在 Cloud Foundry 上运行的 Spring Cloud Config Service 实例的名称。
通过将该服务绑定到 Spring Cloud Data Flow 服务器、Spring Cloud Task,以及通过 Skipper 分别绑定到所有 Spring Cloud Stream 应用程序,我们现在可以解析由该服务支持的集中式属性。
11.18.3. 自签名 SSL 证书与 Spring Cloud 配置服务器
在开发环境中,我们通常可能没有有效的证书来启用客户端与后端服务之间的 SSL 通信。 然而,Pivotal Cloud Foundry 的配置服务器对所有客户端到服务的通信都使用 HTTPS,因此在没有有效证书的环境中,我们需要添加一个自签名的 SSL 证书。
通过使用上一节中为服务器列出的相同 manifest.yml 模板,我们可以通过设置 TRUST_CERTS: <API_ENDPOINT> 来提供自签名 SSL 证书。
然而,已部署的应用程序还需要将 TRUST_CERTS 作为一个扁平的环境变量(而不是包装在 SPRING_APPLICATION_JSON 内部),因此我们必须通过另一组配置项(SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_USE_SPRING_APPLICATION_JSON: false)来指示服务器处理任务。
通过此设置,应用程序将以常规环境变量的形式接收其应用属性。
以下清单展示了经过必要修改后的 manifest.yml 文件。Data Flow 服务器和已部署的应用程序均从 my-config-server Cloud Config 服务器(作为 Cloud Foundry 服务部署)获取其配置。
---
applications:
- name: test-server
host: test-server
memory: 1G
disk_quota: 1G
instances: 1
path: spring-cloud-dataflow-server-VERSION.jar
env:
SPRING_APPLICATION_NAME: test-server
MAVEN_REMOTE_REPOSITORIES_REPO1_URL: https://repo.spring.io/libs-snapshot
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: https://api.sys.huron.cf-app.com
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: sabby20
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: sabby20
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_DOMAIN: apps.huron.cf-app.com
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: admin
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: ***
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SKIP_SSL_VALIDATION: true
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: mysql, config-server
SPRING_CLOUD_SKIPPER_CLIENT_SERVER_URI: https://<skipper-host-name>/api
TRUST_CERTS: <API_ENDPOINT> #this is for the server
SPRING_CLOUD_DATAFLOW_APPLICATION_PROPERTIES_TASK_TRUST_CERTS: <API_ENDPOINT> #this propagates to all tasks
services:
- mysql
- my-config-server #this is for the server
还需将 my-config-server 服务添加到 Skipper 的清单环境(manifest environment)中
---
applications:
- name: skipper-server
host: skipper-server
memory: 1G
disk_quota: 1G
instances: 1
timeout: 180
buildpack: java_buildpack
path: <PATH TO THE DOWNLOADED SKIPPER SERVER UBER-JAR>
env:
SPRING_APPLICATION_NAME: skipper-server
SPRING_CLOUD_SKIPPER_SERVER_ENABLE_LOCAL_PLATFORM: false
SPRING_CLOUD_SKIPPER_SERVER_STRATEGIES_HEALTHCHECK_TIMEOUTINMILLIS: 300000
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: <URL>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: <ORG>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: <SPACE>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_DOMAIN: <DOMAIN>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: <USER>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: <PASSWORD>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: rabbit, my-config-server #this is so all stream applications bind to my-config-server
services:
- mysql
my-config-server
11.19. 配置调度
本节讨论如何配置 Spring Cloud Data Flow,使其连接到 PCF-Scheduler 作为其代理来执行任务。
|
在执行以下说明之前,请确保您的 Cloud Foundry 空间中已有一个 PCF-Scheduler 服务实例正在运行。
要在您的空间中创建一个 PCF-Scheduler(假设它已在您的 Marketplace 中),请从 CF CLI 执行以下命令: |
对于调度任务,您必须在环境中添加(或更新)以下环境变量:
-
通过将
spring.cloud.dataflow.features.schedules-enabled设置为true,启用 Spring Cloud Data Flow 的调度功能。 -
通过将 PCF-Scheduler 服务名称添加到
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES环境变量,将任务部署器绑定到您的 PCF-Scheduler 实例。 -
通过设置
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_SCHEDULER_SCHEDULER_URL环境变量来指定 PCF-Scheduler 的 URL。
|
在创建上述配置之后,您必须创建所有需要被调度的任务定义。 |
以下示例清单同时配置了环境属性(假设您有一个名为 myscheduler 的 PCF-Scheduler 服务可用):
---
applications:
- name: data-flow-server
host: data-flow-server
memory: 2G
disk_quota: 2G
instances: 1
path: {PATH TO SERVER UBER-JAR}
env:
SPRING_APPLICATION_NAME: data-flow-server
SPRING_CLOUD_SKIPPER_SERVER_ENABLE_LOCAL_PLATFORM: false
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_URL: <URL>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_ORG: <ORG>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_SPACE: <SPACE>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_DOMAIN: <DOMAIN>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_USERNAME: <USER>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_CONNECTION_PASSWORD: <PASSWORD>
SPRING_CLOUD_SKIPPER_SERVER_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_DEPLOYMENT_SERVICES: rabbit, myscheduler
SPRING_CLOUD_DATAFLOW_FEATURES_SCHEDULES_ENABLED: true
SPRING_CLOUD_SKIPPER_CLIENT_SERVER_URI: https://<skipper-host-name>/api
SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]_SCHEDULER_SCHEDULER_URL: https://scheduler.local.pcfdev.io
services:
- mysql
其中 SPRING_CLOUD_DATAFLOW_TASK_PLATFORM_CLOUDFOUNDRY_ACCOUNTS[default]SCHEDULER_SCHEDULER_URL 的格式如下: scheduler.<Domain-Name>(例如,scheduler.local.pcfdev.io)。请从您的 _PCF 环境中检查实际地址。
| 有关在多个平台上启动和调度任务的详细示例,请参见本节任务的多平台支持,位于dataflow.spring.io。 |
12. 配置 - Kubernetes
本节介绍如何配置 Spring Cloud Data Flow 的各项功能,例如部署器属性、任务以及所使用的关系型数据库。
12.1. 功能开关
Data Flow 服务器在启动时提供了一组特定的功能,这些功能可以启用或禁用。这些功能包括所有生命周期操作,以及用于以下方面的 REST 端点(包括服务器和客户端实现,涵盖 Shell 和 UI):
-
流
-
任务
-
调度
您可以在启动 Data Flow 服务器时,通过设置以下布尔型环境变量来启用或禁用这些功能:
-
SPRING_CLOUD_DATAFLOW_FEATURES_STREAMS_ENABLED -
SPRING_CLOUD_DATAFLOW_FEATURES_TASKS_ENABLED -
SPRING_CLOUD_DATAFLOW_FEATURES_SCHEDULES_ENABLED
默认情况下,所有功能都是启用的。
/features REST 端点提供有关已启用和已禁用功能的信息。
12.2. 部署器属性
您可以使用以下配置属性来定制 Kubernetes 部署器 部署 Streams 和 Tasks 的方式。
当使用 Data Flow Shell 进行部署时,可以使用语法 deployer.<appName>.kubernetes.<deployerPropertyName>。
在 Data Flow 服务器中配置 Kubernetes 任务平台 以及在 Skipper 中配置 Kubernetes 平台以部署 Streams 时,也会使用这些属性。
| 部署器属性名称 | 描述 | 默认值 |
|---|---|---|
命名空间 |
要使用的命名空间 |
环境变量 |
deployment.nodeSelector |
以 |
<none> |
imagePullSecret |
用于访问私有注册表以拉取镜像的密钥。 |
<none> |
镜像拉取策略 |
拉取镜像时要应用的镜像拉取策略。有效选项为 |
如果不存在 |
存活探针延迟 |
应用程序容器的 Kubernetes 存活探针(liveness check)开始检查其健康状态前的延迟秒数。 |
10 |
livenessProbePeriod |
应用程序容器执行 Kubernetes 存活检查的周期(以秒为单位)。 |
60 |
存活探针超时时间 |
应用容器的 Kubernetes 存活检查超时时间(以秒为单位)。如果健康检查的返回时间超过此值,则认为该应用“不可用”。 |
2 |
存活探针路径 |
应用容器必须响应以进行存活检查的路径。 |
<none> |
存活探针端口 |
应用程序容器必须响应存活检查的端口。 |
<none> |
就绪探针延迟 |
应用程序容器的就绪检查应在模块完全启动并运行后,延迟若干秒开始检查。 |
10 |
就绪探针周期 |
用于执行应用程序容器就绪检查的周期(以秒为单位)。 |
10 |
就绪探针超时时间 |
就绪检查期间,应用容器必须在指定的秒数内响应其健康状态,否则将超时。 |
2 |
就绪探针路径 |
应用程序容器必须响应以进行就绪性检查的路径。 |
<none> |
就绪探针端口 |
应用程序容器必须响应就绪检查的端口。 |
<none> |
probeCredentialsSecret |
包含用于访问受保护探针端点时所用凭据的密钥名称。 |
<none> |
limits.memory |
内存限制,分配一个 Pod 所需的最大值,默认单位为兆字节(mebibytes),支持 'M' 和 'G' 后缀 |
<none> |
limits.cpu |
CPU 限制,分配一个 Pod 所需的最大值 |
<none> |
requests.memory |
内存请求,即分配一个 Pod 所需保证的内存值。 |
<none> |
requests.cpu |
CPU 请求量,即分配一个 Pod 所需保证的资源值。 |
<none> |
statefulSet.volumeClaimTemplate.storageClassName |
有状态集的存储类名称 |
<none> |
statefulSet.volumeClaimTemplate.storage |
存储容量。默认单位为兆字节(mebibytes),支持 'M' 和 'G' 后缀。 |
<none> |
环境变量 |
为任何已部署的应用容器设置的环境变量列表 |
<none> |
entryPointStyle |
用于 Docker 镜像的入口点样式。用于确定如何传入属性。可以是 |
|
创建负载均衡器 |
为每个应用创建的“LoadBalancer”服务。这有助于为应用分配外部 IP。 |
false |
服务注解 |
为每个应用程序创建的服务所设置的服务注解。格式为 |
<none> |
Pod 注解 |
为每个部署所创建的 Pod 设置的注解。格式为字符串: |
<none> |
jobAnnotations |
为作业所创建的 Pod 或 Job 设置的注解。格式为字符串: |
<none> |
等待负载均衡器的分钟数 |
在尝试删除服务之前,等待负载均衡器可用的时间(以分钟为单位)。 |
5 |
maxTerminatedErrorRestarts |
因错误或资源使用过多而失败的应用程序所允许的最大重启次数。 |
2 |
maxCrashLoopBackOffRestarts |
处于 CrashLoopBackOff 状态的应用程序允许的最大重启次数。可选值为 |
|
卷挂载 |
以 YAML 格式表示的卷挂载。例如: |
<none> |
卷 |
Kubernetes 实例支持的卷,以 YAML 格式指定。例如: |
<none> |
hostNetwork |
部署的 hostNetwork 设置,请参见 kubernetes.io/docs/api-reference/v1/definitions/#_v1_podspec |
false |
createDeployment |
创建一个带有“副本集”(Replica Set)的“部署”(Deployment),而不是使用“复制控制器”(Replication Controller)。 |
true |
创建作业 |
启动任务时创建一个“Job”,而不仅仅是一个“Pod”。 |
false |
containerCommand |
使用提供的命令和参数覆盖默认的入口点命令。 |
<none> |
容器端口 |
在容器上添加要暴露的额外端口。 |
<none> |
创建NodePort |
当 |
<none> |
deploymentServiceAccountName |
应用程序部署中使用的服务账户名称。注意:用于应用程序部署的服务账户名称源自 Data Flow 服务器的部署。 |
<none> |
部署标签 |
以 |
<none> |
bootMajorVersion |
要使用的 Spring Boot 主版本号。目前仅用于自动配置特定于 Spring Boot 版本的探测路径。有效选项为 |
2 |
tolerations.key |
用于容忍度的键。 |
<none> |
tolerations.effect |
容忍效果。有关有效选项,请参阅 kubernetes.io/docs/concepts/configuration/taint-and-toleration。 |
<none> |
tolerations.operator |
容忍操作符。有关有效选项,请参阅 kubernetes.io/docs/concepts/configuration/taint-and-toleration/。 |
<none> |
tolerations.tolerationSeconds |
定义在添加污点(taint)后,Pod 将继续绑定到节点上的秒数。 |
<none> |
tolerations.value |
要应用的容忍值,与 |
<none> |
secretRefs |
用于将整个数据内容加载为独立环境变量的密钥(secret)名称。多个密钥可用逗号分隔。 |
<none> |
secretKeyRefs.envVarName |
用于保存密钥数据的环境变量名称 |
<none> |
secretKeyRefs.secretName |
用于访问的密钥名称 |
<none> |
secretKeyRefs.dataKey |
用于从密钥名称获取机密数据 |
<none> |
configMapRefs |
要将整个数据内容加载为独立环境变量的 ConfigMap 名称。多个 ConfigMap 可用逗号分隔。 |
<none> |
configMapKeyRefs.envVarName |
用于保存 ConfigMap 数据的环境变量名称 |
<none> |
configMapKeyRefs.configMapName |
要访问的 ConfigMap 名称 |
<none> |
configMapKeyRefs.dataKey |
用于从 ConfigMap 获取数据的键名 |
<none> |
maximumConcurrentTasks |
此平台实例允许的最大并发任务数。 |
20 |
podSecurityContext.runAsUser |
用于运行 Pod 容器进程的数字用户 ID |
<none> |
podSecurityContext.fsGroup |
用于运行 Pod 容器进程的数字组 ID |
<none> |
affinity.nodeAffinity |
以 YAML 格式表示的节点亲和性。例如: |
<none> |
affinity.podAffinity |
以 YAML 格式表示的 Pod 亲和性。例如: |
<none> |
affinity.podAntiAffinity |
以 YAML 格式表示的 Pod 反亲和性。例如: |
<none> |
statefulSetInitContainerImageName |
用于 StatefulSet Init 容器的自定义镜像名称 |
<none> |
initContainer |
以 YAML 格式表示的 Init 容器,将应用于 Pod。例如: |
<none> |
additionalContainers |
以 YAML 格式表示的、要应用到 Pod 的额外容器。例如: |
<none> |
12.3. 任务
Data Flow 服务器负责部署任务(Tasks)。
由 Data Flow 启动的任务会将其状态写入 Data Flow 服务器所使用的同一数据库中。
对于作为 Spring Batch 作业的任务,其作业和步骤执行数据也存储在此数据库中。
与 Skipper 类似,任务可以被启动到多个平台。
当 Data Flow 在 Kubernetes 上运行时,必须定义一个任务平台。
要配置指向 Kubernetes 的新平台账户,您可以在 spring.cloud.dataflow.task.platform.kubernetes 文件中的 application.yaml 部分添加配置项,或者通过其他 Spring Boot 支持的机制进行配置。
在以下示例中,创建了两个名为 dev 和 qa 的 Kubernetes 平台账户。
其中诸如 memory 和 disk 等键是Cloud Foundry 部署器属性。
spring:
cloud:
dataflow:
task:
platform:
kubernetes:
accounts:
dev:
namespace: devNamespace
imagePullPolicy: Always
entryPointStyle: exec
limits:
cpu: 4
qa:
namespace: qaNamespace
imagePullPolicy: IfNotPresent
entryPointStyle: boot
limits:
memory: 2048m
通过将一个平台定义为 default,您可以在原本必须使用 platformName 的地方省略它。 |
启动任务时,请使用任务启动选项 --platformName 传递平台账户名称的值。如果您未为 platformName 传递值,则将使用默认值 default。
| 将任务部署到多个平台时,该任务的配置需要连接到与 Data Flow Server 相同的数据库。 |
您可以将 Kubernetes 上的 Data Flow 服务器配置为向 Cloud Foundry 和 Kubernetes 部署任务。更多信息请参阅Cloud Foundry 任务平台配置一节。
有关在多个平台上启动和调度任务的详细示例,请参见本节任务的多平台支持,位于dataflow.spring.io。
12.4. 通用配置
Spring Cloud Data Flow 的 Kubernetes 服务器使用 spring-cloud-kubernetes 模块来处理挂载在 /etc/secrets 下的密钥。ConfigMaps 必须作为 application.yaml 挂载到由 Spring Boot 处理的 /config 目录中。为了避免访问 Kubernetes API 服务器,SPRING_CLOUD_KUBERNETES_CONFIG_ENABLE_API 和 SPRING_CLOUD_KUBERNETES_SECRETS_ENABLE_API 被设置为 false。
12.4.1. 使用 ConfigMap 和 Secrets
以下示例展示了一种可能的配置,该配置启用了 MySQL 并设置了内存限制:
apiVersion: v1
kind: ConfigMap
metadata:
name: scdf-server
labels:
app: scdf-server
data:
application.yaml: |-
spring:
cloud:
dataflow:
task:
platform:
kubernetes:
accounts:
default:
limits:
memory: 1024Mi
datasource:
url: jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT}/mysql
username: root
password: ${mysql-root-password}
driverClassName: org.mariadb.jdbc.Driver
testOnBorrow: true
validationQuery: "SELECT 1"
前面的示例假设 MySQL 已部署,且服务名称为 mysql。Kubernetes 会将这些服务的主机和端口值作为环境变量发布出来,我们在配置所部署的应用程序时可以使用这些环境变量。
我们更倾向于在 Secrets 文件中提供 MySQL 连接密码,如下例所示:
apiVersion: v1
kind: Secret
metadata:
name: mysql
labels:
app: mysql
data:
mysql-root-password: eW91cnBhc3N3b3Jk
密码是一个经过 Base64 编码的值。
12.5. 数据库配置
Spring Cloud Data Flow 为 H2、HSQLDB、MySQL、Oracle、PostgreSQL、DB2 和 SQL Server 提供了数据库模式。当服务器启动时,只要类路径中包含正确的数据库驱动程序和相应的凭据,就会自动创建合适的模式。
MySQL(通过 MariaDB 驱动)、HSQLDB、PostgreSQL 和嵌入式 H2 的 JDBC 驱动程序开箱即用。 如果您使用其他任何数据库,则需要将相应的 JDBC 驱动程序 JAR 文件放入服务器的类路径中。
例如,如果你除了在 secrets 文件中使用密码外还使用 MySQL,则可以在 ConfigMap 中提供以下属性:
data:
application.yaml: |-
spring:
datasource:
url: jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT}/mysql
username: root
password: ${mysql-root-password}
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT}/test
driverClassName: org.mariadb.jdbc.Driver
对于 PostgreSQL,您可以使用以下配置:
data:
application.yaml: |-
spring:
datasource:
url: jdbc:postgresql://${PGSQL_SERVICE_HOST}:${PGSQL_SERVICE_PORT}/database
username: root
password: ${postgres-password}
driverClassName: org.postgresql.Driver
对于 HSQLDB,您可以使用以下配置:
data:
application.yaml: |-
spring:
datasource:
url: jdbc:hsqldb:hsql://${HSQLDB_SERVICE_HOST}:${HSQLDB_SERVICE_PORT}/database
username: sa
driverClassName: org.hsqldb.jdbc.JDBCDriver
以下来自 Deployment 的 YAML 片段示例展示了如何将一个 ConfigMap 挂载为 application.yaml 目录下的 /config 文件(Spring Boot 会自动处理该文件),以及如何将一个 Secret 挂载到 /etc/secrets 目录下(由于设置了环境变量 SPRING_CLOUD_KUBERNETES_SECRETS_PATHS 为 /etc/secrets,spring-cloud-kubernetes 库会自动读取该目录下的 Secret)。
...
containers:
- name: scdf-server
image: springcloud/spring-cloud-dataflow-server:2.5.0.BUILD-SNAPSHOT
imagePullPolicy: Always
volumeMounts:
- name: config
mountPath: /config
readOnly: true
- name: database
mountPath: /etc/secrets/database
readOnly: true
ports:
...
volumes:
- name: config
configMap:
name: scdf-server
items:
- key: application.yaml
path: application.yaml
- name: database
secret:
secretName: mysql
您可以在 spring-cloud-task 仓库中找到特定数据库类型的迁移脚本。
12.6. 监控与管理
我们建议使用 kubectl 命令来排查流(streams)和任务(tasks)的问题。
您可以使用以下命令列出所有使用的构件和资源:
kubectl get all,cm,secrets,pvc
你可以使用标签来选择资源,从而列出特定应用程序或服务所使用的所有资源。以下命令列出了 mysql 服务使用的所有资源:
kubectl get all -l app=mysql
你可以通过执行以下命令来获取特定 Pod 的日志:
kubectl logs pod <pod-name>
如果 Pod 持续被重启,你可以添加 -p 选项来查看之前的日志,如下所示:
kubectl logs -p <pod-name>
你也可以通过添加 -f 选项来实时跟踪或持续查看日志,如下所示:
kubectl logs -f <pod-name>
在排查问题时(例如容器在启动时发生致命错误),一个有用的命令是使用 describe 命令,如下例所示:
kubectl describe pod ticktock-log-0-qnk72
12.6.1. 检查服务器日志
你可以使用以下命令访问服务器日志:
kubectl get pod -l app=scdf=server
kubectl logs <scdf-server-pod-name>
12.6.2. 流
流应用程序的部署方式为:流名称后接应用程序名称。对于处理器(processor)和接收器(sink),还会附加一个实例索引。
要查看由 Spring Cloud Data Flow 服务器部署的所有 Pod,您可以指定 role=spring-app 标签,如下所示:
kubectl get pod -l role=spring-app
要查看特定应用程序部署的详细信息,您可以使用以下命令:
kubectl describe pod <app-pod-name>
要查看应用程序日志,您可以使用以下命令:
kubectl logs <app-pod-name>
如果你想实时查看日志(tail 日志),可以使用以下命令:
kubectl logs -f <app-pod-name>
12.6.3. 任务
任务以裸 Pod 的形式启动,不使用复制控制器。任务完成后,Pod 会保留下来,以便您有机会查看日志。
要查看特定任务的所有 Pod,请使用以下命令:
kubectl get pod -l task-name=<task-name>
要查看任务日志,请使用以下命令:
kubectl logs <task-pod-name>
你有两种方式来删除已完成的 Pod。你可以在它们不再需要时手动删除,也可以使用 Data Flow Shell 的 task execution cleanup 命令来移除某次任务执行所对应的已完成 Pod。
要手动删除任务 Pod,请使用以下命令:
kubectl delete pod <task-pod-name>
要使用 task execution cleanup 命令,您必须首先确定任务执行的 ID。为此,请使用 task execution list 命令,如下例(包含输出)所示:
dataflow:>task execution list
╔═════════╤══╤════════════════════════════╤════════════════════════════╤═════════╗
║Task Name│ID│ Start Time │ End Time │Exit Code║
╠═════════╪══╪════════════════════════════╪════════════════════════════╪═════════╣
║task1 │1 │Fri May 05 18:12:05 EDT 2017│Fri May 05 18:12:05 EDT 2017│0 ║
╚═════════╧══╧════════════════════════════╧════════════════════════════╧═════════╝
一旦你获得了该 ID,就可以发出命令来清理执行产物(即已完成的 Pod),如下例所示:
dataflow:>task execution cleanup --id 1
Request to clean up resources for task execution 1 has been submitted
任务的数据库凭据
默认情况下,Spring Cloud Data Flow 在任务启动时会将数据库凭据作为属性传递给 Pod。
如果使用 exec 或 shell 入口点样式,当用户对任务的 Pod 执行 kubectl describe 命令时,数据库凭据将可见。
要配置 Spring Cloud Data Flow 使用 Kubernetes Secrets,请将 spring.cloud.dataflow.task.use.kubernetes.secrets.for.db.credentials 属性设置为 true。如果使用 Spring Cloud Data Flow 提供的 YAML 文件,请更新 `src/kubernetes/server/server-deployment.yaml` 文件,添加以下环境变量:
- name: SPRING_CLOUD_DATAFLOW_TASK_USE_KUBERNETES_SECRETS_FOR_DB_CREDENTIALS
value: 'true'
如果从 SCDF 的先前版本升级,请务必验证 spring.datasource.username 和 spring.datasource.password 环境变量是否已包含在 server-config.yaml 文件的 secretKeyRefs 中。如果未包含,请按照下面示例所示进行添加:
...
task:
platform:
kubernetes:
accounts:
default:
secretKeyRefs:
- envVarName: "spring.datasource.password"
secretName: mysql
dataKey: mysql-root-password
- envVarName: "spring.datasource.username"
secretName: mysql
dataKey: mysql-root-username
...
同时,请验证关联的密钥(dataKey)也已存在于 secrets 中。SCDF 在此处为 MySQL 提供了一个示例:src/kubernetes/mysql/mysql-svc.yaml。
| 默认情况下,通过属性传递数据库凭据是为了保持向后兼容性。此功能将在未来的版本中移除。 |
12.7. 调度
本节介绍如何自定义调度任务的配置方式。在 Spring Cloud Data Flow Kubernetes 服务器中,任务调度功能默认是启用的。可以通过属性来调整调度任务的相关设置,并且这些属性可以全局配置,也可以针对每个调度任务单独配置。
| 除非另有说明,针对每个调度单独设置的属性始终优先于服务器配置中设置的属性。这种安排允许为特定调度覆盖全局服务器级别的属性。 |
查看 KubernetesSchedulerProperties 了解更多支持的选项。
12.7.1. 入口点样式
入口点样式(Entry Point Style)会影响如何将应用程序属性传递给待部署的任务容器。目前支持三种样式:
-
exec:(默认)将所有应用程序属性作为命令行参数传递。 -
shell:将所有应用程序属性作为环境变量传递。 -
boot:创建一个名为SPRING_APPLICATION_JSON的环境变量,其中包含所有应用程序属性的 JSON 表示形式。
您可以按如下方式配置入口点样式:
deployer.kubernetes.entryPointStyle=<Entry Point Style>
将 <Entry Point Style> 替换为您所需的入口点样式。
您还可以在部署 YAML 文件的容器 env 部分中,在服务器级别配置入口点样式,如下例所示:
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_ENTRY_POINT_STYLE
value: entryPointStyle
将 entryPointStyle 替换为所需的入口点样式。
您应选择 exec 或 shell 其中一种入口点(Entry Point)风格,以对应容器 ENTRYPOINT 中 Dockerfile 语法的定义方式。有关 exec 与 shell 的更多信息及使用场景,请参阅 Docker 文档中的ENTRYPOINT部分。
使用 boot 入口点样式相当于使用 exec 样式的 ENTRYPOINT。来自部署请求的命令行参数将传递给容器,同时将应用程序属性映射到 SPRING_APPLICATION_JSON 环境变量中,而不是作为命令行参数传递。
12.7.2. 环境变量
为了影响特定应用程序的环境设置,您可以利用 spring.cloud.deployer.kubernetes.environmentVariables 属性。
例如,在生产环境中,一个常见的需求是调整 JVM 的内存参数。
您可以通过使用 JAVA_TOOL_OPTIONS 环境变量来实现这一点,如下例所示:
deployer.kubernetes.environmentVariables=JAVA_TOOL_OPTIONS=-Xmx1024m
在部署流应用程序或启动任务应用程序时,如果某些属性可能包含敏感信息,请将 shell 设置为 boot 或 entryPointStyle。这是因为默认的 exec 方式会将所有属性转换为命令行参数,因此在某些环境中可能不安全。 |
此外,您还可以在部署 YAML 文件的容器 env 部分中配置服务器级别的环境变量,如下例所示:
| 在服务器配置中以及按计划任务分别指定环境变量时,这些环境变量将会被合并。这样就可以在服务器配置中设置通用的环境变量,同时在具体的计划任务级别设置更特定的环境变量。 |
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_ENVIRONMENT_VARIABLES
value: myVar=myVal
将 myVar=myVal 替换为您所需的环境变量。
12.7.3. 镜像拉取策略
镜像拉取策略定义了何时应将 Docker 镜像拉取到本地注册表。目前,支持以下三种策略:
-
IfNotPresent:(默认)如果镜像已存在,则不拉取。 -
Always:无论镜像是否已存在,始终拉取该镜像。 -
Never:从不拉取镜像。仅使用已存在的镜像。
以下示例展示了如何单独配置容器:
deployer.kubernetes.imagePullPolicy=Always
将 Always 替换为您所需的镜像拉取策略。
您可以在部署 YAML 文件的容器 env 部分中,在服务器级别配置镜像拉取策略,如下例所示:
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_IMAGE_PULL_POLICY
value: Always
将 Always 替换为您所需的镜像拉取策略。
12.7.4. 私有 Docker 仓库
需要身份验证的私有 Docker 镜像可以通过配置一个 Secret 来拉取。首先,您必须在集群中创建一个 Secret。请按照从私有注册表拉取镜像指南来创建该 Secret。
创建密钥后,请使用 imagePullSecret 属性来设置要使用的密钥,如下例所示:
deployer.kubernetes.imagePullSecret=mysecret
将 mysecret 替换为你之前创建的密钥名称。
您还可以在部署 YAML 文件的容器 env 部分中,在服务器级别配置镜像拉取密钥(image pull secret),如下例所示:
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_IMAGE_PULL_SECRET
value: mysecret
将 mysecret 替换为你之前创建的密钥名称。
12.7.5. 命名空间
默认情况下,用于定时任务的命名空间为 default。该值可在部署 YAML 文件的容器 env 部分中进行服务器级别的配置,如下例所示:
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_NAMESPACE
value: mynamespace
12.7.6. 服务账号
你可以通过属性配置为定时任务指定一个自定义的服务账户。可以使用现有的服务账户,也可以创建一个新的服务账户。创建服务账户的一种方法是使用 kubectl,如下例所示:
$ kubectl create serviceaccount myserviceaccountname
serviceaccount "myserviceaccountname" created
然后,您可以按每个调度任务分别配置要使用的服务账户,如下所示:
deployer.kubernetes.taskServiceAccountName=myserviceaccountname
将 myserviceaccountname 替换为您的服务账号名称。
您也可以在部署 YAML 文件的容器 env 部分中,在服务器级别配置服务账户名称,如下例所示:
env:
- name: SPRING_CLOUD_SCHEDULER_KUBERNETES_TASK_SERVICE_ACCOUNT_NAME
value: myserviceaccountname
将 myserviceaccountname 替换为要应用于所有部署的服务账户名称。
有关调度任务的更多信息,请参阅调度任务。
12.8. 调试支持
通过Java 调试线协议(JDWP),支持对 Spring Cloud Data Flow Kubernetes 服务器及其包含的组件(例如Spring Cloud Kubernetes 部署器)进行调试。本节概述了一种手动启用调试的方法,以及另一种使用 Spring Cloud Data Flow Server Kubernetes 提供的配置文件对正在运行的部署进行“修补”的方法。
| JDWP 本身不使用任何身份验证。本节假定调试是在本地开发环境(例如 Minikube)中进行的,因此未提供有关保护调试端口的指导。 |
12.8.1. 手动启用调试
要手动启用 JDWP,请先编辑 src/kubernetes/server/server-deployment.yaml,并在 spec.template.spec.containers.ports 下添加一个值为 5005 的额外 containerPort 条目。此外,请按照以下示例所示,在 spec.template.spec.containers.env 下添加 JAVA_TOOL_OPTIONS 环境变量:
spec:
...
template:
...
spec:
containers:
- name: scdf-server
...
ports:
...
- containerPort: 5005
env:
- name: JAVA_TOOL_OPTIONS
value: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'
前面的示例使用了端口 5005,但可以是任何不与其他端口冲突的数字。所选的端口号还必须与添加的 containerPort 值以及 address 的 JAVA_TOOL_OPTIONS 标志中的 -agentlib 参数保持一致,如前面示例所示。 |
现在你可以启动 Spring Cloud Data Flow Kubernetes 服务器了。一旦服务器启动成功,你可以通过以下示例(含输出)验证 scdf-server 部署中的配置更改:
kubectl describe deployment/scdf-server
...
...
Pod Template:
...
Containers:
scdf-server:
...
Ports: 80/TCP, 5005/TCP
...
Environment:
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
...
服务器已启动并启用 JDWP,您需要配置对端口的访问。在本示例中,我们使用 kubectl 的 port-forward 子命令。以下示例(含输出)展示了如何使用 port-forward 将本地端口暴露给调试目标:
$ kubectl get pod -l app=scdf-server
NAME READY STATUS RESTARTS AGE
scdf-server-5b7cfd86f7-d8mj4 1/1 Running 0 10m
$ kubectl port-forward scdf-server-5b7cfd86f7-d8mj4 5005:5005
Forwarding from 127.0.0.1:5005 -> 5005
Forwarding from [::1]:5005 -> 5005
你现在可以通过将调试器指向主机 127.0.0.1 和端口 5005 来附加一个调试器。port-forward 子命令会持续运行,直到被停止(例如按下 CTRL+c)。
您可以通过还原对 src/kubernetes/server/server-deployment.yaml 文件所做的更改来移除调试支持。还原后的更改将在下一次部署 Spring Cloud Data Flow Kubernetes 服务器时生效。如果希望每次部署服务器时都默认启用调试功能,手动将调试支持添加到配置中会非常有用。
12.8.2. 通过打补丁启用调试
与其手动修改 server-deployment.yaml 文件,不如直接对 Kubernetes 对象进行“打补丁”(patch)操作。为方便起见,文档中已包含与手动方式实现相同配置的补丁文件。要通过打补丁的方式启用调试功能,请使用以下命令:
kubectl patch deployment scdf-server -p "$(cat src/kubernetes/server/server-deployment-debug.yaml)"
运行上述命令会自动添加 containerPort 属性和 JAVA_TOOL_OPTIONS 环境变量。以下示例(包含输出)展示了如何验证对 scdf-server 部署所做的更改:
$ kubectl describe deployment/scdf-server
...
...
Pod Template:
...
Containers:
scdf-server:
...
Ports: 5005/TCP, 80/TCP
...
Environment:
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
...
要启用对调试端口的访问,您可以直接修改 port-forward Kubernetes 服务对象,而不必使用 kubectl 的 scdf-server 子命令。您必须首先确保 scdf-server Kubernetes 服务对象具有正确的配置。以下示例(包含输出)展示了如何进行此操作:
kubectl describe service/scdf-server
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30784/TCP
如果输出包含<unset>,您必须修补该服务,为此端口添加一个名称。以下示例展示了如何操作:
$ kubectl patch service scdf-server -p "$(cat src/kubernetes/server/server-svc.yaml)"
只有在目标集群是在调试功能添加之前创建的情况下,端口名称才可能缺失。由于多个端口被添加到 scdf-server Kubernetes 服务对象中,每个端口都需要拥有自己的名称。 |
现在你可以添加调试端口,如下例所示:
kubectl patch service scdf-server -p "$(cat src/kubernetes/server/server-svc-debug.yaml)"
以下示例(含输出)展示了如何验证映射:
$ kubectl describe service scdf-server
Name: scdf-server
...
...
Port: scdf-server-jdwp 5005/TCP
TargetPort: 5005/TCP
NodePort: scdf-server-jdwp 31339/TCP
...
...
Port: scdf-server 80/TCP
TargetPort: 80/TCP
NodePort: scdf-server 30883/TCP
...
...
输出显示容器端口 5005 已被映射到 NodePort 31339。以下示例(含输出)展示了如何获取 Minikube 节点的 IP 地址:
$ minikube ip
192.168.99.100
利用这些信息,您可以使用主机地址 192.168.99.100 和端口 31339 创建一个调试连接。
以下示例展示了如何禁用 JDWP:
$ kubectl rollout undo deployment/scdf-server
$ kubectl patch service scdf-server --type json -p='[{"op": "remove", "path": "/spec/ports/0"}]'
Kubernetes 部署(Deployment)对象将回滚到打补丁之前的状态。随后,Kubernetes 服务(Service)对象会通过一个 remove 操作进行修补,从 containerPorts 列表中移除端口 5005。
kubectl rollout undo 会强制 Pod 重启。修补 Kubernetes 服务对象不会重新创建该服务,且到 scdf-server 部署的端口映射保持不变。 |
有关部署回滚的更多信息,包括历史记录管理,请参见回滚部署,以及使用 kubectl Patch 就地更新 API 对象。