Hazelcast with SSL in Kubernetes
Enable SSL between Hazelcast members and Hazelcast clients in Kubernetes.
Before you Begin
This example focuses on the security features and assumes that you have some general knowledge about the following topics:
-
Hazelcast on Kubernetes:
-
Java KeyStore and TrustStore
This tutorial also assumes you have a running Kubernetes cluster, and the kubectl
tool installed.
1. Create Secrets
To secure the connection between Hazelcast Server and Hazelcast Client we need to make keys available as secrets.
kubectl create secret generic keystore --from-file=server/keystore --from-file=server/truststore
2. Start Hazelcast Cluster
Hazelcast SSL is an enterprise feature, so you need to create a secret with Hazelcast Enterprise License (if you don’t have one, get a trial license key from this link).
kubectl create secret generic hz-license-key --from-literal key=<hz-license-key>
Then, you can start Hazelcast Cluster with the following command.
helm repo add hazelcast https://hazelcast-charts.s3.amazonaws.com/
helm repo update
kubectl create configmap hazelcast-configuration --from-file=server/helm/hazelcast.yaml
helm install hz -f server/helm/values.yaml hazelcast/hazelcast-enterprise
kubectl apply -f https://raw.githubusercontent.com/hazelcast/hazelcast/master/kubernetes-rbac.yaml
kubectl create configmap hazelcast-configuration --from-file=server/kubectl/hazelcast.yaml
kubectl apply -f server/kubectl/deployment.yaml
You can check in the logs that Hazelcast cluster has been formed and that SSL is enabled for the communication.
$ kubectl logs pod/hz-hazelcast-enterprise-0
...
INFO: [10.172.2.29]:5701 [dev] [4.0] SSL is enabled
...
Members {size:3, ver:3} [
Member [10.244.1.3]:5702 - 8eb71540-5be6-4a06-aa2f-78492816230b this
Member [10.244.2.4]:5702 - 53d5a2a9-f1f5-4bea-b881-0ffe48f0eea0
Member [10.244.1.4]:5702 - f8b42a13-6944-4e94-970a-030c69e75a5b
]
3. Starting Hazelcast Client
As a client side, you’ll deploy a Spring Boot application which connects to the Hazelcast cluster.
The application already includes the client configuration and truststore
. All you need to do is to compile, package, create Docker image, and push it into your Docker Hub account. You may do it all with the following commands.
mvn clean package -f client/pom.xml
docker build -t hazelcastguides/hazelcast-client-ssl client
docker push hazelcastguides/hazelcast-client-ssl
If you want to build your own Docker image, then please make sure you change hazelcastguides
to your Docker Hub name and update client/deployment.yaml
accordingly. Otherwise, you can use hazelcastguides/hazelcast-client-ssl
.
Finally, you can deploy the client application.
kubectl apply -f client/deployment.yaml
You can see that the client connected to the cluster using SSL by checking the logs.
$ kubectl logs deployment.apps/hazelcast-client
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
...
2020-11-11 13:01:14.576 INFO 1 --- [ main] c.hazelcast.client.impl.ClientExtension : SSL is enabled
...
Members [3] {
Member [10.244.1.3]:5701 - 8eb71540-5be6-4a06-aa2f-78492816230b
Member [10.244.2.4]:5701 - 53d5a2a9-f1f5-4bea-b881-0ffe48f0eea0
Member [10.244.1.4]:5701 - f8b42a13-6944-4e94-970a-030c69e75a5b
}
...
2020-11-11 13:01:17.226 INFO 1 --- [ main] com.hazelcast.kubernetes.Application : Started Application in 8.705 seconds (JVM running for 10.03)
Then, assuming you have Load Balancer configured for your Kubernetes environment, you can check the public IP of your client application.
$ kubectl get all | grep service/hazelcast-client
service/hazelcast-client LoadBalancer 10.175.254.124 35.241.133.251 8080:31220/TCP 10m
Now, to check that everything works fine by executing the following commands.
$ curl "35.241.133.251:8080/put?key=some-key&value=some-value"
{"response":null}
$ curl "35.241.133.251:8080/get?key=some-key"
{"response":"some-value"}
Note: In the example, we didn’t use Mutual Authentication, so Hazelcast client itself was not being authorized. For more information check Mutual Authentication section.
4. Clean up
To delete all created resources, exucte the following commands.
kubectl delete -f client/deployment.yaml
helm uninstall hz
kubectl delete configmap hazelcast-configuration
kubectl delete secret keystore
kubectl delete secret hz-license-key
kubectl delete -f client/deployment.yaml
kubectl delete -f server/kubectl/deployment.yaml
kubectl delete configmap hazelcast-configuration
kubectl delete -f https://raw.githubusercontent.com/hazelcast/hazelcast/master/kubernetes-rbac.yaml
kubectl delete secret keystore
kubectl delete secret hz-license-key
More Information
How KeyStore and TrustStore were Generated
KeyStore and TrustStore files for this example were generated using the following commands:
$ keytool -genkey -alias client -keyalg RSA -keystore keystore -keysize 2048 -storepass 123456
What is your first and last name?
[Unknown]: hazelcast-mancenter
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=my-release-hazelcast-enterprise-mancenter, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
$ keytool -export -alias client -file client.crt -keystore keystore -storepass 123456
Certificate stored in file <client.crt>
$ keytool -import -v -trustcacerts -alias client -file client.crt -keystore truststore -storepass 123456
Owner: CN=my-release-hazelcast-enterprise-mancenter, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=my-release-hazelcast-enterprise-mancenter, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Serial number: 7c8af8f7
Valid from: Wed Nov 28 13:41:29 GMT 2018 until: Tue Feb 26 13:41:29 GMT 2019
Certificate fingerprints:
SHA1: 0B:8B:B2:F2:BA:DA:4F:3E:88:90:A7:7E:47:4A:DE:18:BE:DD:7E:5D
SHA256: A9:A4:EE:BB:1E:FB:A2:0F:18:D0:34:09:07:0A:63:AE:62:4E:F6:1B:A0:4F:E1:D2:6A:CD:EB:2B:91:D2:EE:29
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F1 CC 48 90 06 75 D0 51 1D 75 D8 E0 16 DC 66 04 ..H..u.Q.u....f.
0010: FC 4D A3 9B .M..
]
]
Trust this certificate? [no]: yes
Certificate was added to keystore
[Storing truststore]
$ rm client.crt
We used |
Mutual Authentication section
SSL Mutual Authentication can be enabled to increase the security. To enable it, you need to configure it in both Hazelcast Server and Hazelcast Client.
Currently, Mutual Authentication does not work with |
-
Hazelcast Server
Add the following line to the ssl properties section (in hazelcast.yaml):
mutualAuthentication: REQUIRED
-
Hazelcast Client
Add the following lines to the SSLConfig
object in hazelcastConfig()
(in the file Application.java
):
.setProperty("keyStore", "keystore")
.setProperty("keyStorePassword", System.getEnv("KEYSTORE_PASSWORD"))
You also need to add keystore into resources by appending the following line to Dockerfile:
COPY src/main/resources/keystore keystore