Contained Availability Groups on Linux and Containers
Microsoft SQL Server 2022 introduced the contained availability group feature.  When configured, a contained availability group has private copies of the master and msdb databases, which contain metadata objects such as logins, permissions, SQL Agent jobs, etc..  As these databases are replicated to all members of the AG, their contents do not need to be manually configured on each replica, which can substantially reduce administrative overhead.
In order to make use of credential objects, certificates, or transparent database encryption in a contained availability group, with SQL Server 2022 on Linux, it is necessary to synchronize machine keys between SQL Server instances.  This allows the Service Master Key in the contained master database to be decrypted and used on each replica.
This guide provides further instructions necessary for setting up a new DxEnterprise SQL Server Availability Group cluster featuring contained availability group within a Kubernetes platform.
Preparing a New Machine Key
Before creating the DxEnterprise SQL Server Availability Group cluster, a common machine key to be used by all instances needs to be created. To generate a new machine key for use with SQL Server on Linux, in base64 format:
openssl rand -out machine-key.bin 44
printf '\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | dd of=machine-key.bin bs=1 seek=0 count=12 conv=notrunc
cat machine-key.bin | base64
Example:
$ openssl rand -out machine-key.bin 44
$ printf '\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | dd of=machine-key.bin bs=1 seek=0 count=12 conv=notrunc
12+0 records in
12+0 records out
12 bytes copied, 0.0002043 s, 58.7 kB/s
$ cat machine-key.bin | base64
AQAAAAAAAAAAAAAA4vuOBIOXHEoPE7Jg8RTI7yFM8w5MR/73HjOuZKzarjk=
Pre-Loading the Machine Key
Once a machine key has been prepared, it can be pre-loaded on the SQL Server data volume. Doing this before starting SQL Server for the first time allows SQL Server to perform its initial setup using this machine key.
- DxOperator
- StatefulSet
This section is meant to supplement the instructions in the DxOperator Quick Start Guide.
When performing a new deployment with DxOperator using DxEnterpriseSqlAg, a SQL Server machine key can be pre-seeded to the SQL Server persistent data volume(s) using the method explained below.  In the example, we will supplement a DxEnterpriseSqlAg deployment named dxesqlag.
- 
Create a secret containing the machine key, following the example in the previous section - Replace the example machine key with your own.
 kubectl create secret mssql-machinekey-dxesqlag --from-literal=MACHINE_KEY=AQAAAAAAAAAAAAAA4vuOBIOXHEoPE7Jg8RTI7yFM8w5MR/73HjOuZKzarjk=
- 
Add an initContainerto the DxEnterpriseSqlAg to install the machine key if not present.- Ensure that the imagematches the container image defined in the mssqlServerContainer section. The defaultlatestimage is used in the example.
 apiVersion: dh2i.com/v1
 kind: DxEnterpriseSqlAg
 metadata:
 name: dxesqlag
 spec:
 ...
 template:
 ...
 spec:
 ...
 initContainers:
 - name: machinekey-setter
 image: "mcr.microsoft.com/mssql/server:latest"
 command:
 - "sh"
 - "-c"
 - "if [ ! -f /var/opt/mssql/secrets/machine-key ]; then mkdir -p /var/opt/mssql/secrets; echo $MACHINEKEY | base64 -d >/var/opt/mssql/secrets/machinekey; fi"
 env:
 - name: MACHINEKEY
 valueFrom:
 secretKeyRef:
 name: mssql-machinekey-dxesqlag
 key: MACHINE_KEY
 volumeMounts:
 - name: mssql
 mountPath: "/var/opt/mssql"Note that the initContainerwill check if a machine key file already exists, and if not, it will create one based on the machine key stored in themssql-machinekey-dxesqlagsecret.
- Ensure that the 
- 
Complete the deployment, per the DxOperator Quick Start Guide 
This section is meant to supplement the instructions in the Deploy SQL Server Availability Groups in Kubernetes guide.
When performing a new deployment using StatefulSet, a SQL Server machine key can be pre-loaded to the SQL Server persistent data volume using the method explained below.  In the example, we will supplement a StatefulSet deployment named dxesqlag.
- 
Create a secret containing the machine key - Replace the example machine key with your own.
 kubectl create secret mssql-machinekey-dxesqlag --from-literal=MACHINE_KEY=AQAAAAAAAAAAAAAA4vuOBIOXHEoPE7Jg8RTI7yFM8w5MR/
- 
Add an initContainerto the StatefulSet to install the machine key if not present.- Ensure that the imagematches the image defined for the SQL Server container.
- The volume name under volumeMountsmust match the name of the SQL Server data volume.
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
 name: dxesqlag
 spec:
 ...
 template:
 ...
 spec:
 ...
 initContainers:
 - name: machinekey-setter
 image: "mcr.microsoft.com/mssql/server:latest"
 command:
 - "sh"
 - "-c"
 - "if [ ! -f /var/opt/mssql/secrets/machine-key ]; then mkdir -p /var/opt/mssql/secrets; echo $MACHINEKEY | base64 -d >/var/opt/mssql/secrets/machinekey; fi"
 env:
 - name: MACHINEKEY
 valueFrom:
 secretKeyRef:
 name: mssql-machinekey-dxesqlag
 key: MACHINE_KEY
 volumeMounts:
 - name: mssql
 mountPath: "/var/opt/mssql"
 ...
 volumeClaimTemplates:
 - metadata:
 name: mssql
 spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 1GiNote that the initContainerwill check if a machine key file already exists, and if not, it will create one based on the machine key stored in themssql-machinekey-dxesqlagsecret.
- Ensure that the 
- 
Complete the deployment, per the Deploy SQL Server Availability Groups in Kubernetes guide.