Join a DxSqlAg Cluster to an Existing DxEnterprise Cluster
This guide explains a few different approaches for configuring the DxEnterprise containers in a DxSqlAg to join an existing DxEnterprise cluster somewhere else.
By default, a DxSqlAg creates a new, standalone DxEnterprise cluster made up only of its own pods. If you provide a joinTarget, those pods instead join an existing DxEnterprise cluster.
This cluster may already include other Kubernetes pods, virtual machines, or bare-metal hosts.
Optionally, the pods can also join an existing Vhost and availability group, meaning that you can stretch your availability group across namespaces, Kubernetes clusters, off-site VMs, and more.
Prerequisites
These prerequisites apply to all four examples below. The examples also call out additional prerequisites.
- An installed and running DxOperator. For information about installing DxOperator, see the Installing DxOperator guide.
Joining a DxSqlAg to an existing DxEnterprise cluster will make persistent changes to the cluster configuration that will not automatically undo if you delete the DxSqlAg.
In production, double-check these points before applying the DxSqlAg.
-
The
DxSqlAgwill always try to reconcile the DxEnterprise cluster to match what you defined in thespec. Some settings have default values:spec.statefulSetSpec.podSpec.dxEnterpriseContainer.vhostName=VHOST1spec.sqlAgConfiguration.availabilityGroupName=AG1
When targeting an existing cluster:
- If these resources already exist in the target cluster, the operator will add its pods to that Vhost and AG.
- If those resources do not exist in the target cluster, the operator will create a new Vhost and AG.
To avoid accidentally updating or creating the wrong Vhost/AG, explicitly set both values whenever you join an existing cluster.
-
The
DxSqlAgDxEnterpriseSecret(dxEnterpriseContainer.clusterSecret) must:- Have a
DX_PASSKEYthat matches the target cluster's passkey, and - If
joinTarget.useNat: true, have aDX_OTPKthat matches the target cluster's OTPK.
Misconfiguring this
Secretwill cause join failures or prevent the operator from connecting to its pods after joining. - Have a
-
Every
DxSqlAgpod name generated by theStatefulSetshould be unique within the DxEnterprise cluster. No existing DxEnterprise node can share the same name. Reusing node names can cause cluster members to be removed, prevent new nodes from joining, and disrupt applications.
Join Scenarios
Because of the sheer number of configurations possible with this feature, only a handful of them are covered in this guide.
- Locally: When joining a new
DxSqlAginto an existingDxSqlAgwithin the same Kubernetes cluster.- Uses two
DxSqlAgsas an example, but a minor tweak (see step #3) makes it applicable to VM/bare-metal target clusters.
- Uses two
- External NAT: When joining a new
DxSqlAgto an existing DxEnterprise cluster running on VMs or bare-metal.- Best suited for when the
DxSqlAgpods and the target cluster are unreachable to each other.
- Best suited for when the
- Per-Pod Load Balancers: When joining a new
DxSqlAgto an existingDxSqlAgin a different Kubernetes cluster. - Cluster Load Balancers: When joining a new
DxSqlAgto an existingDxSqlAgin a different Kubernetes cluster.- This example has unique network requirements. See the section for more information.
Option 1: Join Locally
This example explains how to join a new DxSqlAg to an existing DxSqlAg running in the same Kubernetes cluster.
Prerequisites
- Top-level prerequisites.
- A deployed and running
DxSqlAg. ThisDxSqlAgcan be running in any namespace. For more information about creating a newDxSqlAgcluster, see theDxSqlAgCreation Guide.
Steps
-
Create a new namespace for the new
DxSqlAg.kubectl create namespace test -
In the new namespace, create secrets for DxEnterprise and SQL Server.
-
Create a new DxEnterprise secret that contains your DxEnterprise cluster passkey and license key.
kubectl create secret generic dxe -n test --from-literal=DX_PASSKEY=<pass> --from-literal=DX_LICENSE=<license_key> -
Create a new SQL Server secret that contains the SQL Server SA account password.
kubectl create secret generic mssql -n test --from-literal=MSSQL_SA_PASSWORD=<pass>
-
-
Apply the
DxSqlAg.yamlexample below.Configuration-
Ensure all prerequisites are met, including the top-level prerequisites.
-
The
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTargetcontrols which existing DxEnterprise node thisDxSqlAgwill join.This example uses another
DxSqlAgas its target, butjoinTarget.targetcan be set to any DxEnterprise node that is reachable from within the DxEnterprise pods (for example, anotherDxSqlAgin a different namespace, or a DxEnterprise node running on a VM in another environment). -
For a local join to another
DxSqlAgin the same Kubernetes cluster, thejoinTarget.targetmust point to a pod in the targetDxSqlAgcluster.In the highlighted YAML example below,
<target_name>and<target_namespace>must be the headless service name for a pod in the target cluster and the namespace that service/pod is running in, respectively. For example, a target pod servicedxsqlag-a-0in thedefaultnamespace would use:dxsqlag-a-0.default.svc.cluster.localHeadless service nameFor a
DxSqlAgpod, the name of the headless service is identical to the pod name.
DxSqlAg.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag-b
namespace: test
spec:
sqlAgConfiguration:
synchronousReplicas: 3
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
joinTarget:
target: "<target_name>.<target_namespace>.svc.cluster.local"
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
-
Verify the pods are created.
kubectl get pods -n test -
(optional) After giving the cluster a little while to set up, verify the configuration is correct by running
dxcli get-ags-detail.kubectl exec -it -n test -c dxe dxsqlag-b-0 -- dxcli get-ags-detail "VHOST1" "AG1"
Option 2: Join with NAT Matchmaking
This second example explains how to join a DxSqlAg to an existing VM cluster running outside of Kubernetes using the NAT join features of DxEnterprise.
Prerequisites
-
A valid DxEnterprise license with NAT and tunnels enabled. A fully featured Developer Edition is available free for non-production use. To purchase DxEnterprise software for production workloads, please contact us.
-
Permissive NATs for at least one - but preferably both - clusters. You can test your NAT type by visiting the DH2i NAT test page.
-
A pre-existing DxEnterprise cluster.
Setting up a ClusterThe cloud NAT matchmaker provides a mechanism for peers (DxEnterprise cluster nodes) to find each other, and is used to join nodes together and establish connections. This is helpful in situations where it might be very difficult for the nodes to find each other, such as when they are on different networks. More information about setting up a cluster can be found below:
- VMs and bare-metal: See the Linux or Windows quick start guides.
- Kubernetes: See the DxOperator quick start guide or the Dxemssql StatefulSet guide.
- Docker: See the Docker quick start guide.
Steps
-
If not done already, set a cluster passkey on the existing (VM/bare-metal/Kubernetes/Docker) DxEnterprise cluster.
dxcli cluster-set-secret-ex <pass> -
Set a One-Time Passkey on the existing cluster and copy the OTPK.
dxcli set-otpk -
Create secrets for DxEnterprise and SQL Server.
-
Create a new DxEnterprise secret that contains your DxEnterprise cluster passkey, license key, and OTPK.
kubectl create secret generic dxe --from-literal=DX_PASSKEY=<pass> --from-literal=DX_LICENSE=<license_key> --from-literal=DX_OTPK=<otpk> -
Create a new SQL Server secret that contains the SQL Server SA account password.
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD=<pass>
-
-
Apply the
DxSqlAg.yamlexample below.Configuration- Ensure all prerequisites are met, including the top-level prerequisites.
- Set the
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTargetvalues:target: match.dh2i.comuseNat: true
These values tell the DxEnterprise containers to use the DH2i NAT matchmaker to find the other cluster.
DxSqlAg.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag
spec:
sqlAgConfiguration:
synchronousReplicas: 3
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
joinTarget:
target: "match.dh2i.com"
useNat: true
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
Verify the pods are created.
kubectl get pods -
(optional) After giving the cluster a little while to set up, verify that the pods have joined the cluster by running
dxcli get-cluster-nodeskubectl exec -it -c dxe dxsqlag-0 -- dxcli get-cluster-nodes -
(optional) Verify the configuration is correct by running
dxcli get-ags-detail.kubectl exec -it -c dxe dxsqlag-0 -- dxcli get-ags-detail "VHOST1" "AG1"
Option 3: Join Across Kubernetes Clusters with Per-Pod Load Balancers
In this third example, you will create load balancers for each pod in two different Kubernetes clusters, then join the two DxEnterprise clusters together using those load balancers. Use this example when you need per-node IPs or firewall rules.
Prerequisites
- Top-level prerequisites.
- Two Kubernetes clusters with DxOperator installed.
Steps
-
In the first Kubernetes cluster, create secrets for DxEnterprise and SQL Server.
-
Create a new DxEnterprise secret that contains your DxEnterprise cluster passkey and license key.
kubectl create secret generic dxe --from-literal=DX_PASSKEY=<pass> --from-literal=DX_LICENSE=<license_key> -
Create a new SQL Server secret that contains the SQL Server SA account password.
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD=<pass>
-
-
For each pod in the first Kubernetes cluster, create a load balancer with a static IP and a selector for the pod. These load balancers let the DxEnterprise cluster nodes (pods) find each other across the network. An example configuration with the necessary ports is given below.
Kubernetes load balancer implementationKubernetes load balancers are implemented by outside software stacks and vendors, so the details of assigning a load balancer a static IP will vary. Cloud providers like Azure, AWS, and Google Cloud have documentation on how to assign static IPs to load balancers within their own infrastructure.
warningPorts mapped to a load balancer within Kubernetes will be accessible to the external network, which in some configurations may be a public network.
lbs-a.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-0-clb
# Static IPs are often assigned through annotations or the spec.loadBalancerIP.
# The annotations below are given for example only from Azure documentation.
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP1
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
# Optional external access to SQL Server and DxAdmin
- port: 1433
targetPort: 1433
protocol: TCP
name: mssql
- port: 7979
targetPort: 7979
protocol: TCP
name: dxadmin
selector:
statefulset.kubernetes.io/pod-name: dxsqlag-a-0
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-1-clb
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP2
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
# Optional external access to SQL Server and DxAdmin
- port: 1433
targetPort: 1433
protocol: TCP
name: mssql
- port: 7979
targetPort: 7979
protocol: TCP
name: dxadmin
selector:
statefulset.kubernetes.io/pod-name: dxsqlag-a-1
type: LoadBalancer -
Create Services on the A-side to map the names of B-side pods to their external IPs. These must be set to the static IPs allocated to the external load balancers in the B-side cluster below
hostmap-a.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-0
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-b-0-ip
labels:
kubernetes.io/service-name: dxsqlag-b-0
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-b-0_lb_ip> ]
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-1
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-b-1-ip
labels:
kubernetes.io/service-name: dxsqlag-b-1
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-b-1_lb_ip> ] -
Use the example
DxSqlAgYAML below to deploy the pods in the first Kubernetes cluster.Configuration- Ensure all prerequisites are met, including the top-level prerequisites.
- The
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTargetis not present because this is a new cluster.
DxSqlAg-a.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag-a
spec:
sqlAgConfiguration:
synchronousReplicas: 2
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
Switch to the second cluster and repeat step #1.
-
For each pod in the second Kubernetes cluster, create a load balancer with a static IP. Example load balancers are given below.
warningPorts mapped to a load balancer within Kubernetes will be accessible to the external network, which in some configurations may be a public network.
lbs-b.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-0-clb
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP3
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
# Optional external access to SQL Server and DxAdmin
- port: 1433
targetPort: 1433
protocol: TCP
name: mssql
- port: 7979
targetPort: 7979
protocol: TCP
name: dxadmin
selector:
statefulset.kubernetes.io/pod-name: dxsqlag-b-0
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-1-clb
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP4
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
# Optional external access to SQL Server and DxAdmin
- port: 1433
targetPort: 1433
protocol: TCP
name: mssql
- port: 7979
targetPort: 7979
protocol: TCP
name: dxadmin
selector:
statefulset.kubernetes.io/pod-name: dxsqlag-b-1
type: LoadBalancer -
Create Services on the B-side to map the names of A-side pods to their external IPs. These must be set to the static IPs allocated to the external load balancers in the A-side cluster above
hostmap-b.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-0
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-a-0-ip
labels:
kubernetes.io/service-name: dxsqlag-a-0
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-a-0_lb_ip> ]
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-1
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-a-1-ip
labels:
kubernetes.io/service-name: dxsqlag-a-1
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-a-1_lb_ip> ] -
Use the example
DxSqlAgYAML below to deploy the pods in the second Kubernetes cluster.Configuration- Ensure all prerequisites are met, including the top-level prerequisites.
- The
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTarget.targetmust be the static IP of one of the load balancers in the first cluster.
DxSqlAg-b.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag-b
spec:
sqlAgConfiguration:
synchronousReplicas: 2
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
joinTarget:
target: <target_lb_ip>
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
(optional) After giving the cluster a little while to set up, verify that the pods have joined the cluster by running
dxcli get-cluster-nodeskubectl exec -it -c dxe dxsqlag-b-0 -- dxcli get-cluster-nodes -
(optional) Verify the configuration is correct by running
dxcli get-ags-detail.kubectl exec -it -c dxe dxsqlag-b-0 -- dxcli get-ags-detail "VHOST1" "AG1"
Option 4: Join Across Kubernetes Clusters with a Shared Load Balancer
In this fourth and final example, you will create a load balancer in two different Kubernetes clusters, then join the two DxEnterprise clusters together using those load balancers.
This example uses fewer IPs and simpler infrastructure, but both Kubernetes clusters must have permissive NAT types. Without this, joins might fail or DxEnterprise nodes may lose their connections to each other.
See our NAT Types article for more information.
Additional Prerequisites
- Top-level prerequisites.
- Two Kubernetes clusters with DxOperator installed.
Steps
-
In the first Kubernetes cluster, create secrets for DxEnterprise and SQL Server.
-
Create a new DxEnterprise secret that contains your DxEnterprise cluster passkey and license key.
kubectl create secret generic dxe --from-literal=DX_PASSKEY=<pass> --from-literal=DX_LICENSE=<license_key> -
Create a new SQL Server secret that contains the SQL Server SA account password.
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD=<pass>
-
-
Create a load balancer with a static IP, an
externalTrafficPolicyset tolocal, and a selector for the entireDxSqlAgcluster. The load balancer lets the DxEnterprise cluster nodes (pods) find each other across the network. An example configuration with the necessary ports is given below.Kubernetes load balancer implementationKubernetes load balancers are implemented by outside software stacks and vendors, so the details of assigning a load balancer a static IP will vary. Cloud providers like Azure, AWS, and Google Cloud have documentation on how to assign static IPs to load balancers within their own infrastructure.
lb-a.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-clb
# Static IPs are often assigned through annotations or the spec.loadBalancerIP.
# The annotations below are given for example only from Azure documentation.
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP1
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
selector:
dh2i.com/entity-name: dxsqlag-a
type: LoadBalancer
externalTrafficPolicy: Local -
Create Services on the A-side to map the names of B-side pods to the external IP. These must be set to the single static IP allocated to the external load balancer in the B-side cluster below
hostmap-a.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-0
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-b-0-ip
labels:
kubernetes.io/service-name: dxsqlag-b-0
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-b_lb_ip> ]
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-1
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-b-1-ip
labels:
kubernetes.io/service-name: dxsqlag-b-1
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-b_lb_ip> ] -
Use the example
DxSqlAgYAML below to deploy the pods in the first Kubernetes cluster. Note the following values:Configuration- Ensure all prerequisites are met, including the top-level prerequisites.
- The
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTargetis not present because this is a new cluster.
DxSqlAg-a.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag-a
spec:
sqlAgConfiguration:
synchronousReplicas: 2
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
Switch to the second cluster and repeat step #1.
-
Create a load balancer with a static IP, an
externalTrafficPolicyset tolocal, and a selector for the entireDxSqlAgcluster. Example load balancers are given below.lb-b.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-b-clb
#annotations:
# service.beta.kubernetes.io/azure-load-balancer-resource-group: <node resource group name>
# service.beta.kubernetes.io/azure-pip-name: myAKSIP3
# metallb.universe.tf/loadBalancerIPs: <ip_address>
spec:
ports:
- port: 7980
targetPort: 7980
protocol: TCP
name: join-tcp
- port: 7981
targetPort: 7981
protocol: UDP
name: group-udp
selector:
dh2i.com/entity-name: dxsqlag-b
type: LoadBalancer
externalTrafficPolicy: Local -
Create Services on the A-side to map the names of B-side pods to the single external IP. These must be set to the static IP allocated to the one external load balancer in the B-side cluster below.
hostmap-b.yamlapiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-0
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-a-0-ip
labels:
kubernetes.io/service-name: dxsqlag-a-0
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-a_lb_ip> ]
---
apiVersion: v1
kind: Service
metadata:
name: dxsqlag-a-1
spec:
clusterIP: None
ports:
- name: dxcmonitor-tcp
protocol: TCP
port: 7980
- name: dxcmonitor-udp
protocol: UDP
port: 7981
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: dxsqlag-a-1-ip
labels:
kubernetes.io/service-name: dxsqlag-a-1
addressType: IPv4
ports:
- name: dxcmonitor-tcp
port: 7980
- name: dxcmonitor-udp
port: 7981
protocol: UDP
endpoints:
- addresses: [ <dxsqlag-a_lb_ip> ] -
Use the example
DxSqlAgYAML below to deploy the pods in the second Kubernetes cluster.Configuration- Ensure all prerequisites are met, including the top-level prerequisites.
- The
spec.statefulSetSpec.podSpec.dxEnterpriseContainer.joinTarget.targetmust be the static IP the load balancer in the first cluster.
DxSqlAg-b.yamlapiVersion: dh2i.com/v1
kind: DxSqlAg
metadata:
name: dxsqlag-b
spec:
sqlAgConfiguration:
synchronousReplicas: 2
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupName: AG1
statefulSetSpec:
podSpec:
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
joinTarget:
target: <target_lb_ip>
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer -
(optional) After giving the cluster a little while to set up, verify that the pods have joined the cluster by running
dxcli get-cluster-nodeskubectl exec -it -c dxe dxsqlag-b-0 -- dxcli get-cluster-nodes -
(optional) Verify the configuration is correct by running
dxcli get-ags-detail.kubectl exec -it -c dxe dxsqlag-b-0 -- dxcli get-ags-detail "VHOST1" "AG1"