Configure TLS with Hazelcast Platform Operator tutorial
Learn how to secure Hazelcast cluster with TLS and Hazelcast Kubernetes Operator.
Context
In this tutorial, you'll do the following:
- Create Kubernetes Secret with TLS certificate and key.
- Deploy Hazelcast cluster with TLS (mTLS) encryption enforced between members.
- Deploy Management Center to monitor your Hazelcast cluster.
- Connect to your cluster using TLS to encrypt member to client network traffic.
Before you Begin
Before starting this tutorial, make sure that you meet the following prerequisites:
- Up and running Kubernetes cluster
- Kubernetes command-line tool, kubectl
- Deployed Hazelcast Platform Operator version 5.8 or above
- OpenSSL command-line tool, openssl
Step 1. Create Kubernetes Secret with TLS certificate and key
-
Generate TLS certificate and key in PEM format using OpenSSL
shellopenssl req -x509 -sha256 -nodes -days 3650 -subj '/CN=example' -addext "subjectAltName=DNS:example" -newkey rsa:2048 -outform pem -keyout example.key -out example.crt -addext "extendedKeyUsage=serverAuth,clientAuth" -
Create Kubernetes Secret with TLS certificate and key
shellkubectl create secret generic example \--from-file=tls.crt=example.crt \--from-file=tls.key=example.keynoteYou can also set
ca.crtto create a truststore. For more information, see TLS.
Step 2. Deploy Hazelcast cluster with TLS
-
Create a secret with your Hazelcast Enterprise License.
shellkubectl create secret generic hazelcast-license-key --from-literal=license-key=<hz-license-key> -
Create the Hazelcast cluster with TLS configured.
yamlkubectl apply -f - <<EOFapiVersion: hazelcast.com/v1alpha1kind: Hazelcastmetadata:name: hazelcastspec:clusterSize: 3licenseKeySecretName: hazelcast-license-keytls:secretName: exampleexposeExternally:type: SmartdiscoveryServiceType: LoadBalancermemberAccess: LoadBalancerEOF -
Run the following commands to check cluster status
shellkubectl get hazelcast hazelcastNAME STATUS MEMBERShazelcast Running 3/3 -
Run the following commands to fetch external addresses of the cluster:
shellkubectl get hazelcastendpoint --selector="app.kubernetes.io/instance=hazelcast"NAME TYPE ADDRESShazelcast Discovery 35.184.21.18:5701hazelcast-0 Member 35.188.131.33:5701hazelcast-1 Member 34.122.242.55:5701hazelcast-2 Member 35.194.44.37:5701hazelcast-wan WAN 35.184.21.18:5710
Step 3. Deploy Management Center
Enabling TLS for a Hazelcast cluster adds an essential layer of security to protect data during communication. When TLS is enabled, all clients, including the Management Center, must be configured with the appropriate TLS certificates to establish a secure connection with the Hazelcast cluster.
Apply the Management Center custom resource:
kubectl apply -f - <<EOF
apiVersion: hazelcast.com/v1alpha1
kind: ManagementCenter
metadata:
name: managementcenter
spec:
repository: 'hazelcast/management-center'
licenseKeySecretName: hazelcast-license-key
externalConnectivity:
type: LoadBalancer
hazelcastClusters:
- address: hazelcast
name: dev
tls:
secretName: example
EOF
Step 4. Connect to Hazelcast cluster over TLS
-
Clone the examples repository to access all sample clients:
shellgit clone https://github.com/hazelcast-guides/hazelcast-platform-operator-tls.gitcd hazelcast-platform-operator-tlsThe sample code(excluding CLC) for this tutorial is in the
docs/modules/ROOT/examples/directory. -
Configure the Hazelcast client with the TLS certificate:
- CLC
- Java
- NodeJS
- Go
- Python
noteBefore using CLC, it should be installed in your system. Check the installation instructions for CLC: Installing the Hazelcast CLC.
Run the following command for adding the cluster config to the CLC.
shellclc config add hz cluster.name=dev cluster.address=<EXTERNAL-IP> ssl.enabled=true ssl.server=example ssl.ca-path=<PATH/TO/example.crt>javapackage com.hazelcast;import com.hazelcast.client.HazelcastClient;import com.hazelcast.client.config.ClientConfig;import com.hazelcast.config.SSLConfig;import com.hazelcast.core.HazelcastInstance;import java.util.Properties;public class example {public static void main(String[] args) throws Exception {ClientConfig config = new ClientConfig();config.getNetworkConfig().addAddress("<EXTERNAL-IP>");Properties clientSSLProps = new Properties();clientSSLProps.setProperty("trustStore", "example.jks");clientSSLProps.setProperty("trustStorePassword", "hazelcast");config.getNetworkConfig().setSSLConfig(new SSLConfig().setEnabled(true).setProperties(clientSSLProps));HazelcastInstance client = HazelcastClient.newHazelcastClient(config);System.out.println("Successful connection!");}}javascript'use strict';const { Client } = require('hazelcast-client');const clientConfig = {network: {clusterMembers: ['<EXTERNAL-IP>'],ssl: {enabled: true,sslOptionsFactoryProperties: {caPath: 'example.crt',servername: 'example',}}}};(async () => {try {const client = await Client.newHazelcastClient(clientConfig);console.log('Successful connection!');} catch (err) {console.error('Error occurred:', err);}})();gopackage mainimport ("context""crypto/tls""fmt""github.com/hazelcast/hazelcast-go-client""github.com/hazelcast/hazelcast-go-client/cluster")func main() {var clusterConfig cluster.ConfigclusterConfig.Network.SetAddresses("<EXTERNAL-IP>")clusterConfig.Discovery.UsePublicIP = trueclusterConfig.Network.SSL.Enabled = trueclusterConfig.Network.SSL.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})ctx := context.Background()config := hazelcast.Config{Cluster: clusterConfig}client, err := hazelcast.StartNewClientWithConfig(ctx, config)if err != nil {panic(err)}fmt.Println("Successful connection!", client)}pythonimport loggingimport hazelcastlogging.basicConfig(level=logging.INFO)client = hazelcast.HazelcastClient(cluster_members=["<EXTERNAL-IP>"],use_public_ip=True,ssl_enabled=True,ssl_cafile="example.crt",)print("Successful connection!", flush=True) -
Build and run the Hazelcast client example:
- CLC
- Java
- NodeJS
- Go
- Python
shellclc -c hz map sizebashcd javamvn packagejava -jar target/*.jarbashcd nodejsnpm installnpm startbashcd gogo run example.gobashcd pythonpip install -r requirements.txtpython example.py
Step 5. Clean Up
To clean up the created resources remove the all Custom Resources and secrets:
kubectl delete $(kubectl get hazelcast,managementcenter -o name)
kubectl delete secret example