DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements
  • Spring Boot With Kubernetes
  • Containerization and Helm Templatization Best Practices for Microservices in Kubernetes
  • Messaging With Spring Boot and Azure Service Bus

Trending

  • Accelerating AI Inference With TensorRT
  • DGS GraphQL and Spring Boot
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • Apache Doris vs Elasticsearch: An In-Depth Comparative Analysis
  1. DZone
  2. Coding
  3. Frameworks
  4. Configuring Spring Boot on Kubernetes With Secrets

Configuring Spring Boot on Kubernetes With Secrets

When configuring a Spring Boot app on Kubernetes, here's how to bring Secrets into the picture either as environment variables or as mounted files.

By 
Kamesh Sampath user avatar
Kamesh Sampath
·
Updated Oct. 06, 17 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
41.4K Views

Join the DZone community and get the full member experience.

Join For Free

In Part 1 of this series, we saw how to use ConfigMaps to configure a Spring Boot app on Kubernetes. ConfigMaps are OK when we use simple configuration data that does not contain sensitive information. When using sensitive data like API keys, passwords, etc., Secrets are the preferred and recommended way. In this second part of the series, we will explore configuring Spring Boot on Kubernetes with Secrets.

The sources for this blog post are available in my GitHub repo.

Setup

You might need access to a Kubernetes cluster to play with this application. The easiest way to get a local Kubernetes cluster up and running is using minikube.The rest of this post assumes you have minikube up and running.

Like ConfigMaps, Secrets can be configured in two ways:

  1. As Environment Variables
  2. As Files

Secrets as Environment Variables

The Spring Boot application that we will build in this blog post uses spring-security. Spring Security, by default, enables security on the entire Spring Boot application.

The default user and password of the application will be displayed to the developer during application boot up.

Using default security password: 981d5f9f-c8ea-413f-8f3b-71daaa20d53c


To override the default security user/password, you need to update the application.properties to be:

security.user.name=${SECRETS_DEMO_USER:demo}
security.user.password=${SECRETS_DEMO_USER_PASSWD:demo}


Let’s now follow the next steps to inject the environment variables.

Create Secrets

Developers can start by creating a Kubernetes Secret called spring-security. This is just the name I am using, but it could be anything of your choice, but remember to use the same name in our deployment.yaml that will configure later.

You can then add two properties — “spring.user.name” and “spring.user.password” — to the Secrets by executing the following command:

kubectl create secret generic spring-security \
--from-literal=spring.user.name=demo \
--from-literal=spring.user.password=password


If you wish to see how your Secrets look, execute the following command,

kubectl get secret spring-security -o yaml


The sample output of the above command is shown below.

apiVersion: v1
data:
  spring.user.name: ZGVtbw==
  spring.user.password: cGFzc3dvcmQ=
kind: Secret
metadata:
  creationTimestamp: 2017-09-19T15:24:29Z
  name: spring-security
  namespace: default
  resourceVersion: "71363"
  selfLink: /api/v1/namespaces/default/secrets/spring-security
  uid: a0e0254e-9d4e-11e7-9b8d-080027da6995
type: Opaque


NOTE: All the values of the properties in the Secrets will be displayed as base64 encoded values.

Create the Fragment deployment.yaml

To configure Spring Boot application on Kubernetes and inject environment variables from Secrets, we need to create the deployment.yaml fragment. Fragments are only bits and pieces of complete Kubernetes resources like deployments, services, etc. It is the responsibility of fabric8-maven-plugin to merge the existing fragments to a complete Kubernetes resource(s) or generate new and missing ones.

The following sections show the required fragments that can be created by the developers inside $PROJECT_HOME/src/main/fabric8 folder:

deployment.yaml

spec:
  template:
    spec:
      containers:
        - env:
          - name: SECRETS_DEMO_USER
            valueFrom:
              secretKeyRef:
                name: spring-security
                key: spring.user.name
          - name: SECRETS_DEMO_USER_PASSWD
            valueFrom:
              secretKeyRef:
                name: spring-security
                key: spring.user.password


The environment variables SECRETS_DEMO_USER and SECRETS_DEMO_USER_PASSWD will have its value injected from secret with name matching secretKeyRef –> name with its value from secret property specified by secretKeyRef –> value

NOTE: As the application is configured to use fabric8-maven-plugin, we can create a Kubernetes deployment and service as fragments in ‘$PROJECT_HOME/src/main/fabric8’. The fabric8-maven-plugin takes care of building the complete Kubernetes manifests by merging the contents of the fragment(s) from ‘$PROJECT_HOME/src/main/fabric8’ during the deploy.

Deploy the Application

To deploy the application, execute the following command from the $PROJECT_HOME:

./mvnw clean fabric8:deploy.

Access the Application

The application status can be checked with the command kubectl get pods -w . Once the application is deployed, let’s do a simple curl like this:

curl $(minikube service spring-boot-secrets-demo --url)/; echo "";

It should return an HTTP 401 Unauthorized error, as we did not provide the credentials to access the app.

Now do a curl -u demo:password $(minikube service spring-boot-secrets-demo --url)/;
echo "";
, which should still return HTTP 404, as we don’t have any resource at that URI, but we are now authorized.

NOTE:

  • The very first deployment of this application tends to take a bit of time, as Kubernetes needs to download the required Docker images for application deployment.
  • The application service URL is found using the command:

    minikube service blog-configmaps-secrets-demo --url
    .

Mounting Secrets as Files

Let’s consider a very simple scenario. Say you want to write a REST API that will call the GitHub API to get all the organizations that your GitHub user account is associated with. The GitHub API to get the organizations you belong to is an authorized call, meaning you need to send a GitHub Personal Access Token as part of the request. Injecting your personal access token as an environment variable might not be as secure as you think, so how do you do it?

The simple way for us to do that is by making the application mount the Secrets as volumes. Once we are able to do that, then we can alter and set permissions on those volumes like how we do for an ssh private key.

Before we get started, I assume that you have created a GitHub Personal Access Token. Once you have it, store them in files.

  • github.user – will store your GitHub user ID.
  • github.token – will store your GitHub Personal Access Token.

Create Secrets From a File

Let’s start creating a new secret called spring-github-demo, similar to how we configured a Spring Boot application on Kubernetes to use Secrets as Environment Variables.

kubectl create secret generic spring-github-demo \
  --from-file ./github.user \
  --from-file ./github.token


When we execute the command kubectl get secret spring-github-demo -o yaml, it will display an output similar to the one shown below.

apiVersion: v1
data:
  github.token: NjE2OTliMjJjOWQ3YTQ5MDJjZjI5NjBhZThjOWMxNWIxMGQzMmI3Ngo=
  github.user: a2FtZXNoc2FtcGF0aAo=
kind: Secret
metadata:
  creationTimestamp: 2017-09-18T13:55:59Z
  name: spring-github-demo
  namespace: default
  resourceVersion: "28217"
  selfLink: /api/v1/namespaces/default/secrets/spring-github-demo
  uid: 19ad298b-9c79-11e7-9b8d-080027da6995
type: Opaque


Update Fragment deployment.yaml

Update the deployment.yaml to add the volume mounts that will allow us to mount the application.properties under /deployments/config inside the container.

spec:
  template:
    spec:
      containers:
        - env:
          - name: SECRETS_DEMO_USER
            valueFrom:
              secretKeyRef:
                name: spring-security
                key: spring.user.name
          - name: SECRETS_DEMO_USER_PASSWD
            valueFrom:
              secretKeyRef:
                name: spring-security
                key: spring.user.password
          volumeMounts:
          - name: github-user 
            mountPath: "/deployments/github" 
            readOnly: true
      volumes:
      - name: github-user
        secret:
          secretName: spring-github-demo 
          items:
          - key: github.user 
            path: user 
          - key: github.token 
            path: token 


The container will now have the secrets:

  • github.user mounted as a file inside the container at /deployments/github/user
  • github.token mounted as a file inside the container at /deployments/github/token

The “GitHubController” REST Controller loads your GitHub user and token from the mounted paths and uses them when interacting with the GitHub API. You can access the REST URI path /mygithuborgs, which will return all your organizations that your GitHub ID is associated with as JSON.

Deploy the application again using the command ./mvnw clean fabric8:deploy and access the application using this curl command:

curl -u demo:password $(minikube service blog-configmaps-secrets-demo --url)/mygithuborgs


If you omit the -u demo:password, then it will result in an HTTP 401 Unauthorized error.

In Part 2 of this blog series, we saw how to configure Spring Boot on Kubernetes with Secrets. In the next part, we will see on how to use the spring-cloud-kubernetes Spring module to configure Spring Boot applications on Kubernetes.

Spring Framework Kubernetes Spring Boot application

Published at DZone with permission of Kamesh Sampath, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Java, Spring Boot, and MongoDB: Performance Analysis and Improvements
  • Spring Boot With Kubernetes
  • Containerization and Helm Templatization Best Practices for Microservices in Kubernetes
  • Messaging With Spring Boot and Azure Service Bus

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!