Example Kubernetes Projects
Two example Kubernetes projects that demonstrate the use and capabilities of the DirX Directory container images are delivered in the same archive as two separate folders: standalone and scalable. The standalone example project runs a full DirX Directory installation in a single pod using the dxd container image. The scalable example project demonstrates a horizontally scalable deployment using the per-server container images and the dirxcontroller image. The next sections describe both example projects and how to use them.
Restrictions
This section describes restrictions that apply to the example DirX Directory Kubernetes projects.
Distribution
The example DirX Directory Kubernetes projects are supported on Kubernetes certified distributions. The example projects only use the default set of Kubernetes resources, so any certified distribution should work. However, certain distributions may have platform-specific behavior or limitations that could cause issues. Currently, minikube and Rancher are actively tested. If you encounter problems with a different certified distribution, the configuration may need to be adapted to accommodate its specifics.
Artifacts
The example DirX Directory Kubernetes projects are delivered and tested as reference deployments. Any modifications to the Kubernetes configuration beyond the procedures described in this document are the responsibility of the customer and are outside the scope of DirX Directory support.
Scalable Example Project
Due to the scalable nature of the scalable example project, where DirX Directory processes run in separate containers, certain features behave differently or are not available compared to a traditional installation.
Extended Operations
Extended operations issued over the load balancer are routed to any one of the load-balanced servers. Therefore, extended operations that must target a particular server instance should be executed from debug containers attached to the chosen server pod instead of through the load balancer. For example:
kubectl debug -n dxd -it dirxldap-abcd --image=dxd --target=dirxdsa --profile=general -- /bin/bash
RPC Ports
RPC ports are not exposed by default, because load balancing would route RPC requests to arbitrary servers. If you still need to expose RPC ports externally, you must create a more specific service that targets a particular pod. The following example service definition exposes the RPC ports for the master DSA:
apiVersion: v1
kind: Service
metadata:
name: dirxdsa-0-rpc
labels:
app: dirxdsa-rpc
spec:
type: LoadBalancer
selector:
statefulset.kubernetes.io/pod-name: dirxdsa-0
ports:
- name: rpc-5999
port: 5999
targetPort: 5999
protocol: TCP
- name: rpc-6000
port: 6000
targetPort: 6000
protocol: TCP
- name: rpc-6001
port: 6001
targetPort: 6001
protocol: TCP
- name: rpc-6002
port: 6002
targetPort: 6002
protocol: TCP
- name: rpc-6003
port: 6003
targetPort: 6003
protocol: TCP
- name: rpc-6004
port: 6004
targetPort: 6004
protocol: TCP
RPC Authentication in LDAP Server
RPC authentication in the LDAP server relies on a shared file between the DSA and the LDAP server. Since in the scalable example project these processes run in separate containers, this shared file is not available. Therefore, the LDAP RPC interface will not require authentication.
Prerequisites
Standalone Example Project
The standalone example project runs the DirX Directory service using the dxd container image in a single stateful set pod.
Architecture
The standalone example project runs the DirX Directory service in a single stateful set pod. The pod contains the dxd container image with all server and client binaries. The stateful set is connected to persistent volume claims for database files, log files, and other persistent data. A set of Kubernetes services expose the DSA, LDAP, and HTTP ports via LoadBalancer resources. Configuration files are provided through ConfigMaps and Secrets that are mounted into the container as read-only volumes.
Configuration
The root of the standalone example project contains a set of folders that are similar to a normal DirX Directory installation: client, conf, dsa, http, ldap, progsvr, tools and several other configuration files.
The content of these folders corresponds to a normal DirX Directory installation and contains several types of configuration files. The next sections describe these files in more detail.
init_scripts_config_map.yaml
As in Kubernetes, the standalone example project has a resource called an init container. The init_scripts_config_map.yaml configuration file contains the initialization scripts to be executed before the DirX Directory container starts up. It handles initializing a database file and loading the o=My-Company example database. You can customize the initialize_db.sh script to set the DBAM profile to your requirements.
stateful_set.yaml
This configuration file contains the definition of the main stateful set resource. It defines the init container, the container, the container ports used and the mounted volumes. As the stateful set contains the definition of the container in use, the dxd container image version to be used can be specified here. For this, the image property should be set in both the container and the init container definition.
service.yaml
The service.yaml configuration files define the service resources that are used to expose ports. There are multiple service.yaml files, one for each DirX Directory server. You can modify the exposed port numbers in these files.
*_pvc.yaml
These configuration files define the persistent volume claims that are used to persist the files used by the DirX Directory service. These files include the database files, log files, audit files, etc. You can adjust the size of the persistent volume claims by setting the storage parameter.
*config_map.yaml
Config maps are used to store the configuration files used by the DirX Directory service. There are several files with this naming structure, containing all configuration files used in a normal DirX Directory installation. You can modify these configuration files according to your requirements.
Scalable Example Project
The scalable example project demonstrates a horizontally scalable DirX Directory deployment. Instead of running all servers in a single pod, it uses the per-server container images to run each server type as a separate Kubernetes resource. Replication between DSA instances is managed automatically by the dirxcontroller image.
Architecture
The scalable example project deploys the following components:
-
A DSA stateful set running multiple replicas of the dirxdsa image. Each replica holds a copy of the directory database. The first replica (dirxdsa-0) acts as the master, and the remaining replicas are consumers that receive data through synchronous shadowing agreements.
-
An LDAP server replica set running multiple replicas of the dirxldapv3 image. These stateless pods provide LDAP access to the DSAs.
-
An HTTP server replica set running multiple replicas of the dirxhttp image. These stateless pods provide HTTP/HTTPS access to the LDAP servers.
-
A controller CronJob running the dirxcontroller image. The controller periodically reconciles the desired number of DSA replicas with the actual state by creating or removing shadowing agreements and managing readiness gates.
-
Network policies that restrict traffic between components to only the required ports.
-
Services that expose the DSA, LDAP, and HTTP ports via LoadBalancer resources and provide internal headless service for DSA-to-DSA communication.
Configuration
The root of the scalable example project contains four folders: controller, dsa, http, and ldap. Each folder contains the Kubernetes resource definitions for the respective component.
controller/
The controller folder contains the configuration for the dirxcontroller CronJob:
-
config_map.yaml - contains the reconciliation script that manages shadowing agreements, scales the DSA stateful set, and maintains readiness gates on DSA pods.
-
cronjob.yaml - defines the CronJob that runs the controller every minute.
-
log_pvc.yaml - defines the persistent volume claim for controller logs.
dsa/
The dsa folder contains the configuration for the DSA stateful set:
-
stateful_set.yaml - defines the DSA stateful set using the dirxdsa image. It uses the dxd image as an init container for database initialization. The
dirxdsa/desired-replicasannotation controls the desired number of DSA replicas. -
internal_service.yaml - defines a headless service for inter-DSA communication using RPC ports.
-
loadbalancer_service.yaml - defines a LoadBalancer service to expose DSA ports externally.
-
config_map.yaml and conf_config_map.yaml - contain the DSA configuration files.
-
secret.yaml and conf_secret.yaml - contain sensitive data such as encrypted password files, certificates, and license files.
-
init_script_config_map.yaml - contains the initialization scripts for database setup.
ldap/
The ldap folder contains the configuration for the LDAP server replica set:
-
replica_set.yaml - defines a replica set using the dirxldapv3 image.
-
service.yaml - defines a LoadBalancer service to expose LDAP and LDAPS ports.
-
config_map.yaml and conf_config_map.yaml - contain the LDAP server configuration files.
-
secret.yaml and conf_secret.yaml - contain sensitive data such as encrypted password files, certificates, and license files.
-
log_pvc.yaml and audit_pvc.yaml - define persistent volume claims for logs and audit files.
http/
The http folder contains the configuration for the HTTP server replica set:
-
replica_set.yaml - defines a replica set using the dirxhttp image.
-
service.yaml - defines a LoadBalancer service to expose HTTP and HTTPS ports.
-
config_map.yaml - contains the HTTP server configuration files.
-
secret.yaml - contains sensitive data such as encrypted password files and certificates.
-
log_pvc.yaml and audit_pvc.yaml - define persistent volume claims for logs and audit files.
Scaling
The scalable example project supports horizontal scaling of each server. The following sections describe how to scale the individual components.
DSA
The desired number of DSA replicas is controlled by the dirxdsa/desired-replicas annotation on the DSA stateful set. To scale the DSA, modify the annotation value in the dsa/stateful_set.yaml file and reapply the configuration:
kubectl apply -n namespace -f dsa/stateful_set.yaml
|
Do not specify the |
This is the recommended approach when using file-based deployments, as it keeps the desired state in version control and ensures consistency between the configuration files and the running cluster.
When scaling up, the controller CronJob will detect the change and automatically:
-
Scale the stateful set to the desired number of replicas.
-
Wait for new pods to be running.
-
Create shadowing agreements between the master (dirxdsa-0) and the new consumer replicas.
-
Wait until the database has been replicated to the new consumers.
-
Mark the new pods as ready for the load balancer using readiness gates.
When scaling down, the controller will:
-
Remove the pods to be deleted from the load balancer by clearing their readiness condition.
-
Wait for endpoint updates to propagate.
-
Delete the shadowing agreements for the removed replicas.
-
Scale down the stateful set.
LDAP Server / HTTP Server
The LDAP server and HTTP server are deployed as replica sets. To scale them, modify the replicas field in the respective replica_set.yaml file and reapply the configuration:
kubectl apply -n namespace -f ldap/replica_set.yaml kubectl apply -n namespace -f http/replica_set.yaml
Since these servers are stateless, Kubernetes handles scaling directly without additional coordination. New pods become available to the load balancer as soon as they are running and ready.
Using the Example Kubernetes Projects
This section describes example workflows for deploying and using the example DirX Directory Kubernetes projects. For these instructions, minikube is used as an example local Kubernetes environment. The same kubectl commands apply to any certified Kubernetes distribution.
Setting up Minikube
Follow the minikube installation instructions (see https://minikube.sigs.k8s.io/docs) and ensure the minikube instance is running. Use the following command to check it:
minikube status
The default-storageclass and storage-provisioner addons must be enabled. The status of the addons can be verified by executing the following command:
minikube addons list
Loading the Container Images
The first step of executing a containerized application is to get and load the container images. Load the DirX Directory container images to the local registry.
For minikube, use the command:
minikube image load dxd-k8s-9.7.138.tar
This command adds the container image to the local registry inside the minikube environment. DirX Directory delivers the container images with only a single label containing the full version.
However, the example projects use the default "latest" tag to refer to the container images in both the container and the init container definitions. After loading the images, you should either re-tag them to "latest" or update the image references in the yaml configuration files to use the specific version tag.
To use a specific image version, you can specify the tag in the image property of the containers and initContainers sections of the respective yaml configuration files. Alternatively, you can tag the image with the specific version tag to the default tag, as shown in the following command:
minikube image tag dxd:9.7.138 dxd
For the scalable example project, all images must be loaded: dxd, dirxdsa, dirxldapv3, dirxhttp, and dirxcontroller.
Tunneling the Ports
The example Kubernetes projects use LoadBalancer Kubernetes resources to expose their ports. In minikube, these ports are only available inside the minikube environment by default. To expose these ports to a specified bind address, use the command:
minikube tunnel --bind-address=target_IP
where target_IP is the IP address of the network interface to which the exposed ports should be bound. For example, to make the LDAP ports available outside minikube on the host’s loopback interface, use the command:
minikube tunnel --bind-address=127.0.0.1
Standalone
This section describes workflows specific to the standalone example project.
Starting the Standalone Example Project
The provided Kubernetes configuration files and the container image make it easy to run the DirX Directory service in the Kubernetes environment with the default My-Company configuration. To start the standalone project:
-
Get and load the dxd container image as described in the section "Loading the Container Images".
-
Extract the Kubernetes configuration files and then modify the parameters defined in the configuration section to your requirements; for example, DirX Directory version, port numbers, storage space, and so on. When preparing the configuration files, it is recommended to create a new namespace using the command:
kubectl create ns namespace -
Apply the configuration files with the command:
kubectl apply -n namespace -Rf configuration_path
where configuration_path is the folder to which you have extracted the provided Kubernetes configuration yaml files. -
Check the status of the DirX Directory pod by running the command:
kubectl get pods -n namespace
Here is an example startup command sequence for a DirX Directory service dxd-standalone:
kubectl create ns dxd-standalone kubectl apply -n dxd-standalone -Rf standalone/ kubectl get pods -n dxd-standalone
Please note that starting up a pod takes time, so the last command may be repeated several times until the pod comes up, showing a Running status.
Setting up Shadowing
This section describes how to implement a simple supplier-consumer scenario using the standalone example project.
Create Master and Shadow Kubernetes Projects
As this shadowing scenario needs two DirX Directory instances with different configurations, the first step is to copy the standalone example project files into two different folders called dxd-master and dxd-shadow. These folders will contain the necessary configuration for the supplier and the consumer respectively. To perform this task, run the following commands:
cp -R standalone dxd-master cp -R standalone dxd-shadow
Set Master and Shadow DSA Identifiers
Next, set the DIRX_HOST_NAME, DIRX_DSA_NAME and DIRX_OWN_PSAP environment variables. Open the dxd-master/conf/config_map.yaml file and append the following rows to dirxenv.ini:
set DIRX_DSA_NAME=CN=DirX-k8s-master set DIRX_HOST_NAME=dxd-service.dxd-master.svc.cluster.local set DIRX_OWN_PSAP=TS=DSA1,NA='TCP/IP_IDM!internet=1.2.3.4+port=1234',DNS='(HOST=dxd-service.dxd-master.svc.cluster.local,PLAINPORT=21200)'"
Now open the dxd-shadow/conf/config_map.yaml file and append the following rows to dirxenv.ini:
set DIRX_DSA_NAME=CN=DirX-k8s-shadow set DIRX_HOST_NAME=dxd-service.dxd-shadow.svc.cluster.local set DIRX_OWN_PSAP=TS=DSA2,NA='TCP/IP_IDM!internet=1.2.3.4+port=1234',DNS='(HOST=dxd-service.dxd-shadow.svc.cluster.local,PLAINPORT=21200)'"
Adjust Duplicate LoadBalancer Resources
As both dxd-master and dxd-shadow are copied from the same source, they contain the same definitions for the LoadBalancer service resources. If multiple LoadBalancer resources are started with the same port, it will result in port collisions when the traffic is tunneled to an IP address. So as the next step, you should delete or modify these resources. If you would like to access only one of the nodes from an external IP, you can delete the dsa/service.yaml, ldap/service.yaml, progsvr/service.yaml and http/service.yaml files from one of the copied folders. If you would like to access both, you can modify the port numbers in these files to avoid port collision.
Start Master and Shadow Instances
When the configuration is finished, start the dxd-master instance with the following commands:
kubectl create ns dxd-master kubectl apply -n dxd-master -Rf dxd-master/ kubectl get pods -n dxd-master
Then start the dxd-shadow instance:
kubectl create ns dxd-shadow kubectl apply -n dxd-shadow -Rf dxd-shadow/ kubectl get pods -n dxd-shadow
Create the Shadowing Agreement
After these commands are executed, there are two separate standalone DirX Directory instances running. Both are loaded with the o=My-Company example database. The next step is to create the shadowing agreement between the two standalone DSAs using the following commands:
kubectl exec -it -n dxd-master dxd-0 -- bash
dirxadm -c "defbind; sob create -consumer {/CN=DirX-k8s-shadow} \
-agreementid 15 \
-consumerpsap {TS=DSA2,NA='TCP/IP_IDM!internet=1.2.3.4+port=1234',DNS='(HOST=dxd-service.dxd-shadow.svc.cluster.local,PLAINPORT=21200)'} \
-supplier {/CN=DirX-k8s-master} \
-supplierpsap {TS=DSA1,NA='TCP/IP_IDM!internet=1.2.3.4+port=1234',DNS='(HOST=dxd-service.dxd-master.svc.cluster.local,PLAINPORT=21200)'} \
-consumerkind CENTRALADMIN \
-status cooperative \
-agreement {SS={AREA={CP={/o=My-Company},\
RA={DEF=TRUE}},\
ATT={DEF=TRUE}},\
UM={SI={OC=TRUE}},CHANGEO=FALSE} \
-pol {CONS={REPLS=TRUE}}"
Scalable
This section describes workflows specific to the scalable example project.
Starting the Scalable Example Project
To start the scalable example project:
-
Get and load all DirX Directory container images (dxd, dirxdsa, dirxldapv3, dirxhttp, dirxcontroller) as described in the section "Loading the Container Images".
-
Extract the Kubernetes configuration files and create a new namespace:
kubectl create ns namespace -
Apply the configuration files with the command:
kubectl apply -n namespace -Rf configuration_path
where configuration_path is the scalable folder. -
Check the status of all pods by running the command:
kubectl get pods -n namespace
Here is an example startup command sequence:
kubectl create ns dxd-scalable kubectl apply -n dxd-scalable -Rf scalable/ kubectl get pods -n dxd-scalable
After startup, the controller CronJob will run within a minute and establish the shadowing agreements between the master DSA and the consumer replicas. You can monitor the controller’s progress by checking its logs.
Customizing the Initialization
You can customize the example Kubernetes projects by adjusting the delivered yaml configuration files and then applying the changes with the "apply" command described in the startup sections.
Please note that the Kubernetes example projects are delivered as reference deployments and a basis for developing custom containerized DirX Directory solutions. Any modifications to the Kubernetes configuration beyond the procedures described in this document are the responsibility of the customer and are outside the scope of DirX Directory support.
Executing Tools and Clients
The dxd container image contains all tools and clients as well as a bash shell. You can use these tools by using kubectl’s exec functionality. For example, you can open an interactive shell into the DirX Directory pod with the command:
kubectl exec -it -n namespace dxd-0 -- bash
In the interactive shell, you can manage the DirX Directory service as a normal Linux installation.
In the scalable example project, the per-server images do not contain a shell. To execute tools interactively, use a debug container with the dxd image:
kubectl debug -it -n namespace dirxdsa-0 --image=dxd -- bash
Deleting a Directory Instance
DirX Directory instances, if running in a separate namespace, can be deleted with the command:
kubectl delete ns namespace
Please note that this command will not clean up the persistent volumes. You should remove them manually.
Setting up Crash Handling
In the standalone example project, the DirX Directory watchdog (dirxdsas) handles all server crashes. However, some Kubernetes environments do not allow ptrace calls by default, so the watchdog procedure is not allowed to generate core dumps.
In the scalable example project, the per-server images do not include dirxdsas. Crash handling must be set up using systemd-coredump.
To activate automatic core dump collection, install the systemd-coredump package and then disable the watchdog’s core dump handling by setting DIRX_WDOG_CRASH_HANDLER=0 in dirxenv.ini. These settings enable systemd to collect the core dumps.
Troubleshooting
All files (including log, audit, ldif, and others) in the DirX Directory container images are written as they are in a normal Linux installation, so files required for troubleshooting are written as files. In the example Kubernetes projects, all paths used to store these files are mapped to persistent volume claims so that files needed for troubleshooting are persisted.
Log File Naming in Containerized Environments
In a containerized environment, multiple container instances may write to the same persistent volume over time. To ensure that log files from different container instances do not overwrite each other, the example Kubernetes projects use special dirxlog.cfg files that include the container ID in the log file name.
In a standard DirX Directory installation, the default dirxlog.cfg uses a simple naming pattern with only a sequence number:
dir:*.0:BINFILE.10.20000:%s/server/log/%sLOG%d dba:*.0:GOESTO:dir FATAL:TEXTFILE.10.20000:%s/server/log/%sEXC%d;GOESTO:dir ERROR:TEXTFILE.10.20000:%s/server/log/%sUSR%d;GOESTO:FATAL
In the Kubernetes example projects, the dirxlog.cfg files use an additional %s format specifier that resolves to the container ID, making each container instance’s log files unique:
dir:*.0:BINFILE.10.20000:%s/server/log/%sLOG_%s_%d dba:*.0:GOESTO:dir FATAL:TEXTFILE.10.20000:%s/server/log/%sEXC_%s_%d;GOESTO:dir ERROR:TEXTFILE.10.20000:%s/server/log/%sUSR_%s_%d;GOESTO:FATAL
The additional %s in the file name pattern inserts the container ID, so log files are named like LOG_abc123_1, LOG_abc123_2, etc. This ensures that when a container is restarted, the new instance writes to files with a different name and does not overwrite or interfere with logs from previous instances.
When deploying DirX Directory in Kubernetes, always use this container-ID-aware dirxlog.cfg pattern in your ConfigMaps to ensure proper log persistence across container restarts.