ECP 与 Docker
大家好!
这是关于使用 Docker 初始化 IRIS 实例的系列文章中的第三篇。 这次,我们将关注企业缓存协议(Enterprise Cache Protocol,ECP)。
ECP 允许以一种非常简单的方式将某些 IRIS 实例配置为应用程序服务器,将其他实例配置为数据服务器。 有关详细的技术信息,请参阅官方文档。
本文旨在介绍:
- 如何编写数据服务器的初始化脚本,以及如何编写一个或多个应用程序服务器的初始化脚本。
- 如何使用 Docker 在这些节点之间建立加密连接。
为此,我们通常使用我们在以前的 Web 网关中已经看到的一些工具,以及描述 OpenSSL、envsubst 和 Config-API 等工具的镜像文章。
要求
ECP 不适用于 IRIS 社区版。 因此,需要访问全球响应中心才能下载容器许可证并连接到 containers.intersystems.com 注册表。
准备系统
系统必须与容器共享一些本地文件。 需要创建特定用户和组来避免出现“访问被拒绝”错误。
sudo useradd --uid 51773 --user-group irisowner
sudo useradd --uid 52773 --user-group irisuser
sudo groupmod --gid 51773 irisowner
sudo groupmod --gid 52773 irisuser
如果您还没有“iris.key”许可证,请从 WRC 下载,并将其添加到您的主目录中。
检索示例存储库
除“iris.key”许可证外,您需要的所有其他文件都可以在公共存储库中找到,因此,首先将其克隆:
git clone https://github.com/lscalese/ecp-with-docker.git
cd ecp-with-docker
SSL 证书
为了加密应用程序服务器与数据服务器之间的通信,我们需要 SSL 证书。
可以使用现成的脚本(“gen-certificates.sh”)。 但是,您可以随意修改脚本,使证书设置与您的位置、公司等保持一致。
执行:
sh ./gen-certificates.sh
生成的证书现在位于“./certificates”目录中。
文件 | 容器 | 描述 |
---|---|---|
./certificates/CA_Server.cer | 应用程序服务器和数据服务器 | 机构服务器证书 |
./certificates/app_server.cer | 应用程序服务器 | IRIS 应用程序服务器实例证书 |
./certificates/app_server.key | 应用程序服务器 | 相关私钥 |
./certificates/data_server.cer | 数据服务器 | IRIS 数据服务器实例证书 |
./certificates/data_server.key | 数据服务器 | 相关私钥 |
构建镜像
首先,登录 Intersystems docker 注册表。 在构建期间,将从注册表中下载基础镜像:
docker login -u="YourWRCLogin" -p="YourICRToken" containers.intersystems.com
如果您不知道自己的Token,请使用您的 WRC 帐户登录 https://containers.intersystems.com/。
在此构建过程中,我们将向 IRIS 基础镜像添加一些软件实用程序:
- gettext-base:它将允许我们使用“envsubst”命令替换配置文件中的环境变量。
- iputils-arping:如果我们想要镜像数据服务器,则需要使用此实用程序。
- ZPM:ObjectScript 软件包管理器。
ARG IMAGE=containers.intersystems.com/intersystems/iris:2022.2.0.281.0
# Don't need to download the image from WRC. It will be pulled from ICR at build time.
FROM $IMAGE
USER root
# Install iputils-arping to have an arping command. It's required to configure Virtual IP.
# Download the latest ZPM version (ZPM is included only with community edition).
RUN apt-get update && apt-get install iputils-arping gettext-base && \
rm -rf /var/lib/apt/lists/*
USER ${ISC_PACKAGE_MGRUSER}
WORKDIR /home/irisowner/demo
RUN --mount=type=bind,src=.,dst=. \
iris start IRIS && \
iris session IRIS < iris.script && \
iris stop IRIS quietly
此 Dockerfile 中除最后一行外没有什么特别之处。 它将 IRIS 数据服务器实例配置为最多接受 3 个应用程序服务器。 请注意,此配置需要重新启动 IRIS。 我们在构建过程中分配此参数的值,以避免稍后编写重新启动脚本。
开始构建:
docker-compose build –no-cache
配置文件
在配置 IRIS 实例(应用程序服务器和数据服务器)时,我们使用 JSON config-api 文件格式。 您会注意到这些文件包含环境变量 "${variable_name}"。 它们的值在“docker-compose.yml”文件的“environment”部分定义,我们稍后将在本文档中看到。 这些变量将在使用“envsubst”实用程序加载文件之前被替换掉。
数据服务器
对于数据服务器,我们将:
- 启用 ECP 服务并定义授权客户端(应用程序服务器)列表。
- 创建加密通信所需的“SSL %ECPServer”配置。
- 创建“myappdata”数据库。 它将用作来自应用程序服务器的远程数据库。
(data-serer.json)[https://github.com/lscalese/ecp-with-docker/blob/master/config-files/dat...
{
"Security.Services" : {
"%Service_ECP" : {
"Enabled" : true,
"ClientSystems":"${CLIENT_SYSTEMS}",
"AutheEnabled":"1024"
}
},
"Security.SSLConfigs": {
"%ECPServer": {
"CAFile": "${CA_ROOT}",
"CertificateFile": "${CA_SERVER}",
"Name": "%ECPServer",
"PrivateKeyFile": "${CA_PRIVATE_KEY}",
"Type": "1",
"VerifyPeer": 3
}
},
"Security.System": {
"SSLECPServer":1
},
"SYS.Databases":{
"/usr/irissys/mgr/myappdata/" : {}
},
"Databases":{
"myappdata" : {
"Directory" : "/usr/irissys/mgr/myappdata/"
}
}
}
此配置文件由“init_datasrv.sh”脚本在数据服务器容器启动时加载。 连接到数据服务器的所有应用程序服务器都必须可信。 此脚本将在 100 秒内自动验证所有连接,以限制管理门户中的手动操作。 当然,可以对其进行改进以提高安全性。
应用程序服务器
对于应用程序服务器,我们将:
- 启用 ECP 服务。
- 创建通信加密所需的 SSL 配置“%ECPClient”。
- 配置与数据服务器的连接信息。
- 创建远程数据库“myappdata”的配置。
- 在“USER”命名空间中创建到“myappdata”数据库的全局映射“demo.*”。 它可以让我们稍后测试 ECP 的运行。
{
"Security.Services" : {
"%Service_ECP" : {
"Enabled" : true
}
},
"Security.SSLConfigs": {
"%ECPClient": {
"CAFile": "${CA_ROOT}",
"CertificateFile": "${CA_CLIENT}",
"Name": "%ECPClient",
"PrivateKeyFile": "${CA_PRIVATE_KEY}",
"Type": "0"
}
},
"ECPServers" : {
"${DATASERVER_NAME}" : {
"Name" : "${DATASERVER_NAME}",
"Address" : "${DATASERVER_IP}",
"Port" : "${DATASERVER_PORT}",
"SSLConfig" : "1"
}
},
"Databases": {
"myappdata" : {
"Directory" : "/usr/irissys/mgr/myappdata/",
"Name" : "${REMOTE_DB_NAME}",
"Server" : "${DATASERVER_NAME}"
}
},
"MapGlobals":{
"USER": [{
"Name" : "demo.*",
"Database" : "myappdata"
}]
}
}
配置文件由“init_appsrv.sh”脚本在应用程序服务器容器启动时加载。
启动容器
现在,我们可以启动容器:
- 2 个应用程序服务器。
- 1 个数据服务器。
为此,请运行:
docker-compose up –scale ecp-demo-app-server=2
请参阅 docker-compose 文件以了解详情:
# Variables are defined in .env file
# to show the resolved docker-compose file, execute
# docker-compose config
version: '3.7'
services:
ecp-demo-data-server:
build: .
image: ecp-demo
container_name: ecp-demo-data-server
hostname: data-server
networks:
app_net:
environment:
# List of allowed ECP clients (application server).
- CLIENT_SYSTEMS=ecp-with-docker_ecp-demo-app-server_1;ecp-with-docker_ecp-demo-app-server_2;ecp-with-docker_ecp-demo-app-server_3
# Path authority server certificate
- CA_ROOT=/certificates/CA_Server.cer
# Path to data server certificate
- CA_SERVER=/certificates/data_server.cer
# Path to private key of the data server certificate
- CA_PRIVATE_KEY=/certificates/data_server.key
# Path to Config-API file to initiliaze this IRIS instance
- IRIS_CONFIGAPI_FILE=/home/irisowner/demo/data-server.json
ports:
- "81:52773"
volumes:
# Post start script - data server initilization.
- ./init_datasrv.sh:/home/irisowner/demo/init_datasrv.sh
# Mount certificates (see gen-certificates.sh to generate certificates)
- ./certificates/app_server.cer:/certificates/data_server.cer
- ./certificates/app_server.key:/certificates/data_server.key
- ./certificates/CA_Server.cer:/certificates/CA_Server.cer
# Mount config file
- ./config-files/data-server.json:/home/irisowner/demo/data-server.json
# IRIS License
- ~/iris.key:/usr/irissys/mgr/iris.key
command: -a /home/irisowner/demo/init_datasrv.sh
ecp-demo-app-server:
image: ecp-demo
networks:
app_net:
environment:
# Hostname or IP of the data server.
- DATASERVER_IP=data-server
- DATASERVER_NAME=data-server
- DATASERVER_PORT=1972
# Path authority server certificate
- CA_ROOT=/certificates/CA_Server.cer
- CA_CLIENT=/certificates/app_server.cer
- CA_PRIVATE_KEY=/certificates/app_server.key
- IRIS_CONFIGAPI_FILE=/home/irisowner/demo/app-server.json
ports:
- 52773
volumes:
# Post start script - application server initilization.
- ./init_appsrv.sh:/home/irisowner/demo/init_appsrv.sh
# Mount certificates
- ./certificates/CA_Server.cer:/certificates/CA_Server.cer
# Path to private key of the data server certificate
- ./certificates/app_server.cer:/certificates/app_server.cer
# Path to private key of the data server certificate
- ./certificates/app_server.key:/certificates/app_server.key
# Path to Config-API file to initiliaze this IRIS instance
- ./config-files/app-server.json:/home/irisowner/demo/app-server.json
# IRIS License
- ~/iris.key:/usr/irissys/mgr/iris.key
command: -a /home/irisowner/demo/init_appsrv.sh
networks:
app_net:
ipam:
driver: default
config:
# APP_NET_SUBNET variable is defined in .env file
- subnet: "${APP_NET_SUBNET}"
我们来测试一下!
访问数据服务器管理门户
容器已启动。 我们从数据服务器中检查一下状态。
端口 52773 映射到本地端口 81,因此可以使用此地址 http://localhost:81/csp/sys/utilhome.csp 进行访问
使用默认登录名\密码登录,然后转到 System -> Configuration -> ECP Params(系统 -> 配置 -> ECP 参数)。 点击“ECP Application Servers”(ECP 应用程序服务器)。 如果一切正常,您应该会看到 2 个状态为“Normal”(正常)的应用程序服务器。 客户端名称的结构为 "数据服务器名称":"应用程序服务器主机名":"IRIS 实例名称"。 本例中,我们没有设置应用程序服务器主机名,因此我们将获得自动生成的主机名。
访问应用程序服务器管理门户
要连接到应用程序服务器的管理门户,首先需要获取端口号。 由于我们使用了“--scale”选项,我们无法在 docker-compose 文件中设置端口。 因此,必须使用 docker ps
命令检索它们:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1844f38939f ecp-demo "/tini -- /iris-main…" 25 minutes ago Up 25 minutes (unhealthy) 1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:81->52773/tcp, :::81->52773/tcp ecp-demo-data-server
4fa9623be1f8 ecp-demo "/tini -- /iris-main…" 25 minutes ago Up 25 minutes (unhealthy) 1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:49170->52773/tcp, :::49170->52773/tcp ecp-with-docker_ecp-demo-app-server_1
ecff03aa62b6 ecp-demo "/tini -- /iris-main…" 25 minutes ago Up 25 minutes (unhealthy) 1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:49169->52773/tcp, :::49169->52773/tcp ecp-with-docker_ecp-demo-app-server_2
在本示例中,端口:
- 49170,用于第一个应用程序服务器 http://localhost:49170/csp/sys/utilhome.csp
- 49169,用于第二个应用程序服务器 http://localhost:49169/csp/sys/utilhome.csp
远程数据库上的读/写测试
我们在终端中执行一些读/写测试。
在第一个应用程序服务器上打开一个 IRIS 终端:
docker exec -it ecp-with-docker_ecp-demo-app-server_1 iris session iris
Set ^demo.ecp=$zdt($h,3,1) _ “ write from the first application server.”
现在,在第二个应用程序服务器上打开一个终端:
docker exec -it ecp-with-docker_ecp-demo-app-server_2 iris session iris
Set ^demo.ecp(2)=$zdt($h,3,1) _ " write from the second application server."
zwrite ^demo.ecp
您应该会看到两个服务器中的响应:
^demo.ecp(1)="2022-07-05 23:05:10 write from the first application server."
^demo.ecp(2)="2022-07-05 23:07:44 write from the second application server."
最后,在数据服务器上打开一个 IRIS 终端并执行全局 demo.ecp 读取:
docker exec -it ecp-demo-data-server iris session iris
zwrite ^["^^/usr/irissys/mgr/myappdata/"]demo.ecp
^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(1)="2022-07-05 23:05:10 write from the first application server."
^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(2)="2022-07-05 23:07:44 write from the second application server."
希望大家喜欢这篇文章。 欢迎您发表评论。