Skip to content

Commit 2693e7c

Browse files
marianne013fstagnichrisburr
committed
feat: add documentation for diracx container deployment
Co-authored-by: Federico Stagni <federico.stagni@cern.ch> Co-authored-by: Chris Burr <chrisburr@users.noreply.github.com>
1 parent ef2162b commit 2693e7c

4 files changed

Lines changed: 231 additions & 1 deletion

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Installing DiracX in a container
2+
3+
!!! warning "This is for container deployment only. For kubernetes deployment please refer to [Installing DiracX](installing.md)."
4+
5+
## Notes
6+
7+
- We are running a 'developer' setup where we can edit the diracx code directly and run the local code
8+
inside the container. This really helps with debugging ;-)
9+
- Similar to DIRAC this is installed as the (unprivileged) dirac user (and not root). There might be limitations to the approach that we have not found yet.
10+
- We give the version numbers of the code we tested, you should always check for the latest version and install this. If in doubt, please as on the DiracX [mattermost channel](https://mattermost.web.cern.ch/diracx/channels/town-square). In this example we used DIRAC v9.0.2, diracx 0.0.2 and diracx-web v0.1.0-a10.
11+
- If the same version number has to be specified in two different places, we indicate this explicitly.
12+
- We keep all of our configuration files in a folder called dirac-container. This name is chosen arbitrarily, and can be replaced with a name of your choice. However, the configuration examples assume that all files needed are kept in the same directory.
13+
14+
## Configuration Files
15+
16+
There are four configuration files that need to be provided to install DiracX in a container:
17+
`diracx.env`, `diracx-web.env`, `podman-compose.yaml` and `jwks.json`.
18+
In addition we also overwrite the entry point to include the database initialisation/schema management.
19+
You also need your OpenSearch server's `/etc/opensearch/root-ca.crt` (here called opensearch-ca.pem) to be able to connect to your OpenSearch server.
20+
Both `entrypoint.sh` and `opensearch-ca.pem` should be placed in the same folder as the configuration files.
21+
22+
`diracx.env` is based on [reference/env-variables](../../reference/env-variables.md) <br>
23+
`jwks.json` is used to to generate the diracx authentication tokens. Please also see [how to rotate a secret](../../how-to/rotate-a-secret.md) <br>
24+
`podman-compose.yaml` is the container steering/manifest file. <br>
25+
26+
### jwks.json
27+
28+
To generate the jwks.json use a diracx container and start it with a shell (code adapted from `diracx/run_local.sh`): <br>
29+
`podman run --rm -ti ghcr.io/diracgrid/diracx/services:v0.0.2 /bin/bash`
30+
The --rm removes the container automatically after exiting.
31+
`python -m diracx.logic rotate-jwk --jwks-path "/tmp/jwks.json"`
32+
Then copy content of /tmp/jwks.json to file outside of the container to be mapped in a volume to the real thing.
33+
34+
### diracx.env
35+
36+
At this point you need to have created the `DiracXAuthDB` and the `jwks.json` (see above).
37+
Now you need two further keys:
38+
39+
`DIRACX_SERVICE_AUTH_STATE_KEY`: Please see also [env-variables/diracx_service_auth_state_key](../../reference/env-variables.md#diracx_service_auth_state_key) and [dynamic-secrets-diracx-dynamic-secrets](../../explanations/chart-structure.md#dynamic-secrets-diracx-dynamic-secrets)
40+
To generate the key we follow diracx/run_local.sh: `state_key="$(head -c 32 /dev/urandom | base64)"`
41+
42+
`DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY`:
43+
This is adapted from ["generating a legacy exchange api key"] (connect.md) ("generating a legacy exchange api key") goes into dirac.cfg (as diracx:legacy...) and into diracx.env as a hash, but the gist of it is, the shared secret allows dirac and diracx to communicate.
44+
To generate the legacy key, you can use the following python snippet:
45+
46+
```
47+
import secrets
48+
import base64
49+
import hashlib
50+
51+
token = secrets.token_bytes()
52+
# This is the secret to include in the request by setting the
53+
# /DiracX/LegacyExchangeApiKey CS option in your legacy DIRAC installation (in the local -- secluded -- dirac.cfg file)
54+
print(f"API key is diracx:legacy:{base64.urlsafe_b64encode(token).decode()}")
55+
56+
# This is the environment variable to set on the DiracX server
57+
print(f"DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY={hashlib.sha256(token).hexdigest()}")
58+
```
59+
60+
Below is an example of a dirac.env file. The server is called 'diractest.grid.hep.ph.ic.ac.uk'. Replace as necessary.
61+
62+
```
63+
DIRACX_SERVICE_AUTH_STATE_KEY=[state_key from above]
64+
DIRACX_SERVICE_AUTH_TOKEN_ISSUER=["Your hostname here", e.g. "https://diractest.grid.hep.ph.ic.ac.uk"]
65+
DIRACX_SERVICE_AUTH_TOKEN_KEYSTORE=file:///keystore/jwks.json [The one you made earlier]
66+
# replace diractest.grid.hep.ph.ic.ac.uk with your hostname
67+
DIRACX_SERVICE_AUTH_ALLOWED_REDIRECTS='["https://diractest.grid.hep.ph.ic.ac.uk/#authentication-callback"]'
68+
# we are currently not using S3, nevertheless these variables need to be set
69+
DIRACX_SANDBOX_STORE_S3_CLIENT_KWARGS="{}"
70+
DIRACX_SANDBOX_STORE_BUCKET_NAME="notsetyet"
71+
# disable the jobs router (and hopefully S3)
72+
DIRACX_SERVICE_JOBS_ENABLED=false
73+
# we are using a local git repo on the node, this is not fully supported yet.
74+
# Please see: https://diracx.io/en/latest/RUN_PROD/#cs for the approved way.
75+
DIRACX_CONFIG_BACKEND_URL="git+file:///cs_store?branch=main"
76+
DIRACX_DB_URL_AUTHDB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/DiracXAuthDB
77+
# these are the users and passwords you have chosen for the databases in DIRAC; they can be found in
78+
# dirac.cfg
79+
# host.containers.internal: For the development node our databases are on the same machine
80+
DIRACX_DB_URL_JOBDB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/JobDB
81+
DIRACX_DB_URL_JOBLOGGINGDB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/JobLoggingDB
82+
DIRACX_DB_URL_PILOTAGENTSDB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/PilotAgentsDB
83+
DIRACX_DB_URL_SANDBOXMETADATADB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/SandboxMetadataDB
84+
DIRACX_DB_URL_TASKQUEUEDB=mysql+aiomysql://YourUser:YourPassword@host.containers.internal:3306/TaskQueueDB
85+
# opensearch related; the user and password are specific to opensearch,
86+
DIRACX_OS_DB_JOBPARAMETERSDB={"hosts":"YourOpensearchUsername:YourOpensearchPwd@YourOpensearchServer:9200", "use_ssl":true, "ca_certs":"/etc/opensearch-ca.pem"}
87+
DIRACX_OS_DB_PILOTLOGSDB={"hosts":"YourOpensearchUsername:YourOpensearchPwd@YourOpenSearchServer:9200", "use_ssl":true, "ca_certs":"/etc/opensearch-ca.pem"}
88+
DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY=(from the output from generating the legacy key)
89+
```
90+
91+
### diracx-web.env
92+
93+
This file contains one line:
94+
`DIRACX_URL=https://diractest.grid.hep.ph.ic.ac.uk/api`
95+
96+
### podman-compose.yaml
97+
98+
Note: Please check that your ports specified in the yaml file match the ports you set up during the preparing a node for a container install procedure. The DiracX version specified must match the ones you use when you install the code. The `uvicorn` command is what actually starts diracx services. <br>
99+
Sources: <br>
100+
`ghcr.io`: from https://diracx.diracgrid.org/en/latest/RUN_PROD/#diracx-service-configuration <br>
101+
`command`: from diracx-charts/diracx/templates/diracx/deployment.yaml <br>
102+
`/opt/dirac/diracx-config:/cs_store:z,rw`: only needed because we use a local repo for the CS, a remote repo would be read directly over https. <br>
103+
104+
```
105+
---
106+
services:
107+
diracx-services:
108+
ports:
109+
- 127.0.0.1:8000:8000
110+
image: ghcr.io/diracgrid/diracx/services:v0.0.2
111+
env_file: "diracx.env"
112+
command: "uvicorn --factory diracx.routers:create_app --host=0.0.0.0 --port=8000 --proxy-headers --forwarded-allow-ips=*"
113+
volumes:
114+
- ./entrypoint.sh:/entrypoint.sh:z,ro
115+
- ./jwks.json:/keystore/jwks.json:z,ro
116+
- /opt/dirac/diracx-config:/cs_store:z,rw
117+
- /opt/dirac/diracx:/diracx_sources:z,ro
118+
- ./opensearch-ca.pem:/etc/opensearch-ca.pem:z,ro
119+
diracx-web:
120+
image: ghcr.io/diracgrid/diracx-web/static:v0.1.0-a10
121+
ports:
122+
- 127.0.0.1:8001:8080
123+
env_file: "diracx-web.env"
124+
```
125+
126+
### entrypoint.sh
127+
128+
```bash
129+
#!/bin/bash
130+
131+
set -e
132+
echo "Welcome to the dark side"
133+
134+
eval "$(micromamba shell hook --shell=posix)" && micromamba activate base
135+
136+
# this sets it up so that we can make changes to the code
137+
pip install -e /diracx_sources/diracx-core \
138+
-e /diracx_sources/diracx-db \
139+
-e /diracx_sources/diracx-logic \
140+
-e /diracx_sources/diracx-routers \
141+
-e /diracx_sources/diracx-client
142+
143+
# initialise database and make updates if necessary
144+
python -m diracx.db init-sql
145+
146+
exec "$@"
147+
```
148+
149+
## Install the code
150+
151+
<div class="annotate" markdown>
152+
```bash
153+
git clone https://github.com/DIRACGrid/diracx.git
154+
git checkout v0.0.2
155+
```</div>
156+
1. The version matches image: `ghcr.io/diracgrid/diracx/services:v0.0.2` in
157+
the yaml file.
158+
159+
## Tests
160+
161+
Once the containers are installed, the following tests should be working (note: when testing, we needed to run the
162+
first command twice as there seemed to be a bug in DiracX. This might be fixed by the time you are trying this.)
163+
We ran these as root, as we were setting up our apache config as root and debugging this config as part of the process, but you can run this as any user.
164+
165+
```
166+
[root@diractest ~]# curl -k https://diractest.grid.hep.ph.ic.ac.uk/.well-known/openid-configuration`
167+
{"issuer":"https://diractest.grid.hep.ph.ic.ac.uk","token_endpoint":"https://diractest.grid.hep.ph.ic.ac.uk/api/auth/token","userinfo_endpoint":"https://diractest.grid.hep.ph.ic.ac.uk/api/auth/userinfo","authorization_endpoint":
168+
[etc]
169+
```
170+
171+
```
172+
[root@diractest ~]# curl -k https://diractest.grid.hep.ph.ic.ac.uk/.well-known/jwks.json`
173+
{"keys":[{"crv":"Ed25519","x":"3_SrPXQyalji7nL4fNFh7JGBTwQBztmjnW7ogFusiPs","key_ops":["sign","verify"],"alg":"EdDSA","kid":"019a3a1b95b77b11a18bde7813b78fe2","kty":"OKP"}]}
174+
```
175+
176+
To test the web container:
177+
178+
```bash
179+
$ curl -k https://diractest.grid.hep.ph.ic.ac.uk/
180+
<!DOCTYPE html><html lang="en"><head>[etc] (i.e. returns a web site)
181+
```
182+
183+
## A selection of helpful podman commands
184+
185+
```
186+
podman ps -a # see all containers, dead or alive
187+
podman rm diracx-container_diracx-services_1 # remove dead container by name
188+
podman-compose -f podman-compose.yaml up -d --force-recreate # restart all containers (e.g. after update)
189+
podman exec -ti diracx-container_diracx-services_1 /bin/bash # to look into a running container
190+
podman logs -f diracx-container_diracx-services_1 # to look at the logs of a running container
191+
```

docs/admin/how-to/install/minimal-requirements.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ In order to run DiracX in production we recommend having:
88
- **S3-compatible storage** for storing jobs' sandboxes
99
- An **IdP** supporting OAuth/OIDC (e.g. [Indigo IAM](https://indigo-iam.github.io/))
1010

11-
At the time of writing, the only supported way of running DiracX is through **[Kubernetes](https://kubernetes.io/docs/tutorials/kubernetes-basics/)**.
11+
At the time of writing, the only fully supported way of running DiracX is through **[Kubernetes](https://kubernetes.io/docs/tutorials/kubernetes-basics/)**.
12+
13+
If you need to decouple your DIRAC v9 upgrade from a kubernetes deployment, you can deploy DiracX in a container. This has only been tested in conjunction with a DIRAC v9.0 deployment. In this case, your starting point is: [Prepare a node for container deployment](prepare-container-node.md).
1214

1315
The following chapters will *NOT* cover:
1416

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Preparing a node for container deployment
2+
3+
!!! warning "This is for container deployment only. For kubernetes deployment please refer to [Installing kubernetes](install-kubernetes.md)."
4+
5+
## Podman
6+
7+
These instructions are using the podman container tools as they are native to Rocky9. They are very similar to docker. Please check that these are installed on your system.
8+
9+
## Configuring Apache
10+
11+
Open port 443 for apache which serves up the connection to diracx services.
12+
Apache is configured in reverse proxy mode to forward external requests into the private container network.
13+
An example for an apache config (/etc/httpd/conf.d/diracx.conf) file is given below:
14+
15+
```
16+
ProxyPreserveHost On
17+
ProxyPass /api http://127.0.0.1:8000/api
18+
ProxyPassReverse /api http://127.0.0.1:8000/api
19+
ProxyPass /.well-known http://127.0.0.1:8000/.well-known
20+
ProxyPassReverse /.well-known http://127.0.0.1:8000/.well-known
21+
ProxyPass / http://127.0.0.1:8001/
22+
ProxyPassReverse / http://127.0.0.1:8001/
23+
RequestHeader set "X-Forwarded-Proto" "https"
24+
```
25+
26+
Note: We use 8000 for the diracx container and 8001 for the diracx-web container.
27+
The same ports need to the specified in the yaml files used to steer the containers.
28+
29+
## Create the DiracXAuthDB
30+
31+
At this point we also create the DiracXAuthDB. You can refer to the documentation [here](installing.md#create-the-diracxauthdb)
32+
33+
Note: The username and password will then re-appear in the `diracx.env` connection strings for the databases.
34+
35+
You can now continue to [Convert CS](convert-cs.md). After this please read [Installing DiracX](installing.md) for some background information before proceeding to [Installing DiracX in a container](installing-in-a-container.md).

mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ nav:
8383
- admin/how-to/install/index.md
8484
- Minimal requirements: admin/how-to/install/minimal-requirements.md
8585
- Installing kubernetes: admin/how-to/install/install-kubernetes.md
86+
- Preparing a container node: admin/how-to/install/prepare-container-node.md
8687
- Convert CS: admin/how-to/install/convert-cs.md
8788
- Installing DiracX: admin/how-to/install/installing.md
89+
- Installing DiracX in a Container: admin/how-to/install/installing-in-a-container.md
8890
- Connect DIRAC to DiracX: admin/how-to/install/connect.md
8991
- Register the admin VO: admin/how-to/install/register-the-admin-vo.md
9092
- Register a VO: admin/how-to/install/register-a-vo.md

0 commit comments

Comments
 (0)