eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Overview

Networking is an integral part of Kubernetes, with Service being one of its primitive networking objects. Kubernetes Service allows us to expose a network application to the external world. However, to access it, we must know its URL.

In this hands-on tutorial, we’ll discuss finding and using the Kubernetes service’s URL as a reliable network endpoint.

2. Setting up an Example

We need to create a few Kubernetes objects to use as an example. To begin, let’s create Namespace objects.

2.1. Creating Kubernetes Namespaces

Kubernetes namespaces allow us to isolate the resources within the same cluster. So, let’s use the create command to create two namespaces – dev and stg:

$ kubectl create ns dev
namespace/dev created

$ kubectl create ns stg
namespace/stg created

2.2. Creating Kubernetes Deployments

In the previous step, we created two namespaces. Now, let’s deploy the Redis pod to those namespaces:

$ kubectl create deploy redis-dev --image=redis:alpine -n dev
deployment.apps/redis-dev created

$ kubectl create deploy redis-stg --image=redis:alpine -n stg
deployment.apps/redis-stg created

Next, let’s verify that the pods have been created and that they’re in a healthy state:

$ kubectl get pods -n dev
NAME                         READY   STATUS    RESTARTS   AGE
redis-dev-7b647c797c-c2mmg   1/1     Running   0          16s

$ kubectl get pods -n stg
NAME                        READY   STATUS    RESTARTS   AGE
redis-stg-d66978466-plfpv   1/1     Running   0          9s

Here, we can observe that the status of both pods is Running.

Now, the required setup is ready. In the upcoming sections, we’ll create a few Service objects to establish communication with these pods.

3. Finding the URL of the ClusterIP Service

In Kubernetes, the default service type is ClusterIP. For ClusterIP services, we can use the service name or its IP address as its URL. This allows us to limit communication only within the cluster. Let’s understand this with a simple example.

3.1. Creating the ClusterIP Services

First, let’s create ClusterIP Service objects in both namespaces:

$ kubectl expose deploy redis-dev --port 6379 --type ClusterIP -n dev
service/redis-dev exposed

$ kubectl expose deploy redis-stg --port 6379 --type ClusterIP -n stg
service/redis-stg exposed

In this example, we’ve used the expose command to create a Service object. The expose command uses the selectors of the Deployment object and creates a Service using the same selectors.

In the following sections, we’ll discuss how to find and use the names of these services as URLs.

3.2. Using the URL of the ClusterIP Service in the Same Namespace

First, let’s use the get command to find the service name from the dev namespace:

$ kubectl get svc -n dev
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
redis-dev   ClusterIP   10.100.18.154   <none>        6379/TCP   9s

In the output, the first column shows the service name. In our case, it’s redis-dev.

Now, let’s exec to the Redis pod that is deployed in the dev namespace, connect to the Redis server using redis-dev as a hostname, and execute the PING command:

$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-dev PING
PONG
/data # exit

Here, we can see that the Redis server responds with the PONG message.

Finally, we execute the exit command to exit from the pod.

3.3. Using the URL of the ClusterIP Service From Another Namespace

Let’s examine the format of a ClusterIP service URL:

<service-name>.<namespace>.<cluster-name>:<service-port>

We didn’t use the namespace and cluster-name in the previous example because we executed the command from the same namespace and cluster. In addition to that, we also skipped service-port because the Service was exposed using the default Redis port 6379.

However, we need to specify a namespace name to use the ClusterIP service from another namespace. Let’s understand this with an example.

First, let’s find out the name of the service in the stg namespace:

$ kubectl get svc -n stg
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
redis-stg   ClusterIP   10.110.213.51   <none>        6379/TCP   9s

Now, let’s exec to the Redis pod that is deployed in the dev namespace, connect to the Redis server using redis-stg.stg as a hostname, and execute the PING command:

$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-stg.stg PING
PONG
/data # exit

In this example, we can see that the Redis server sends a PONG reply.

An important thing to note is that we’ve used redis-stg.stg as a hostname, where redis-stg is the service name and stg is the namespace name in which the Service object was created.

3.4. Cleaning Up

In the previous examples, we saw how to use the Service name as the URL.

Now, let’s use the delete command to clean up the services from the dev and stg namespaces:

$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted

$ kubectl delete svc redis-stg -n stg
service "redis-stg" deleted

4. Finding the URL of the NodePort Service

The NodePort service allows external connectivity to the application using the IP address and port of the Kubernetes node. Let’s understand this by creating a NodePort service.

4.1. Creating the NodePort Service

First, let’s use the expose command to create a Service with the type NodePort:

$ kubectl expose deploy redis-dev --port 6379 --type NodePort -n dev
service/redis-dev exposed

Next, let’s verify that the Service has been created:

$ kubectl get svc -n dev
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
redis-dev   NodePort   10.111.147.176   <none>        6379:30243/TCP   2s

Here, we can see that the Service type is NodePort. In the second-to-last column, it shows that the Kubernetes node’s port 30243 is mapped to the pod’s port 6379.

Now, we can use the IP address of the Kubernetes node and port 30243 from outside the cluster to access the Redis server. Let’s see this in action.

4.2. Using the URL of the NodePort Service

First, let’s find the IP address of the Kubernetes node:

$ kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
baeldung   Ready    control-plane   24h   v1.28.3   192.168.49.2   <none>        Ubuntu 22.04.3 LTS   5.15.0-41-generic   docker://24.0.7

Here, we’ve used the -o wide option with the Node objects to show the additional fields.

In the above output, the column with the header INTERNAL-IP shows the Kubernetes node’s IP address.

Now, from the external machine, let’s connect to the Redis server using 192.168.49.2 as a hostname, 30243 as a port number, and execute the PING command:

$ redis-cli -h 192.168.49.2 -p 30243 PING
PONG

Here, we can see that the Redis server responds with a PONG message.

4.3. Cleaning Up

In the next section, we’re going to see the usage of the LoadBalancer service. But before that, let’s do the cleanup of the NodePort service from the dev namespace:

$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted

5. Finding the URL of the LoadBalancer Service

Just like the NodePort service, the LoadBalancer service also allows external connectivity to the application using the load balancer’s IP address. To understand this, let’s create a LoadBalancer service:

5.1. Creating the LoadBalancer Service

Let’s use the expose command to create a LoadBalancer service in the dev namespace:

$ kubectl expose deploy redis-dev --port 6379 --type LoadBalancer -n dev
service/redis-dev exposed

5.2. Using the URL of the LoadBalancer Service

Next, let’s use the get command to find the load balancer’s IP address:

$ kubectl get svc -n dev
NAME        TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
redis-dev   LoadBalancer   10.111.167.249   192.168.49.10   6379:32637/TCP   7s

In this example, the column with the header EXTERNAL-IP represents the LoadBalancer service’s IP address.

In our case, the load balancer’s IP address is 192.168.49.10.

Now, from the external machine, let’s connect to the Redis server using 192.168.49.10 as a hostname and execute the PING command:

$ redis-cli -h 192.168.49.10 PING
PONG

In the output, we can see that the Redis server replies with a PONG message.

6. Cleaning Up

Deleting all unwanted objects to tidy up the cluster is a good practice. This helps us in lowering our costs by reducing hardware consumption.

So, let’s use the delete command to remove the dev and stg namespaces:

$ kubectl delete ns dev
namespace "dev" deleted

$ kubectl delete ns stg
namespace "stg" deleted

This command deletes the namespace itself and all objects that are present in this namespace.

Here, we deleted namespaces directly, as this is the test setup. However, we should be very careful while performing delete operations in the production environment.

7. Conclusion

In this article, we discussed how to find and use the URL of a service in Kubernetes.

First, we saw how to use the ClusterIP service name as a URL from the same and another namespace. Then, we discussed how to find and use the URL of the NodePort service.

Finally, we discussed using the load balancer’s IP address as a service URL.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)