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
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Kubernetes Scheduler Plugins: Optimizing AI/ML Workloads
  • A Transaction-Grade Performance Blueprint for Spring Boot FinTech Microservices (Tracing, Histograms, and Kubernetes)
  • Stop Debugging Code That Works: Identifying False Failures in Kubernetes
  • Kubernetes 101: Understanding the Foundation and Getting Started

Trending

  • Production Database Migration or Modernization: A Comprehensive Planning Guide [Part 2]
  • Monitoring Spring Boot Applications with Prometheus and Grafana
  • The Hidden Bottlenecks That Break Microservices in Production
  • How Retry Storms Crash API-Led Systems: Bounded Reliability Patterns for Distributed Architectures
  1. DZone
  2. Software Design and Architecture
  3. Microservices
  4. A Practical Guide to Deploying Microservices on Kubernetes

A Practical Guide to Deploying Microservices on Kubernetes

This guide covers deploying microservices on Kubernetes, highlighting containerization, scaling, monitoring, and security.

By 
Puneet Pahuja user avatar
Puneet Pahuja
·
Oct. 21, 25 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
2.5K Views

Join the DZone community and get the full member experience.

Join For Free

So, you're thinking about using Kubernetes to run microservices? You're not the only one. As of 2024, more than 60% of businesses use Kubernetes, and by 2027, that percentage is predicted to climb to more than 90%. That's pretty crazy, huh?

But here's the deal. Microservices provide us a lot of freedom and the opportunity to grow, but they can be hard to manage. Do you know what it means? There are dozens or perhaps hundreds of services floating around, and it can be hard to keep track of everything. That's where Kubernetes comes in. It's like having a really clever helper who takes care of all the scalability, deployment, and management for you.

This post will show you how to actually install microservices on Kubernetes. No fluff, just useful advice from the real world. Are you ready? Let's go.

Understanding the Fundamentals

Before we start deploying things, let's talk about how Kubernetes really organizes your microservices. Kubernetes uses "pods" as the smallest parts to build things. Normally, each pod has one or more containers in it. For microservices, you'll normally run each service in its own pod. It's pretty easy, right?

But this is where it gets fascinating. Kubernetes doesn't want you to manage pods directly. You utilize higher-level tools like Deployments and StatefulSets instead.

Why? 

A Deployment makes sure that your microservice always has the proper number of copies running, manages updates without a hitch, and can even go back to a previous version if something goes wrong. Services (that's what they're called) let your microservices talk to each other via the network.

You may trust me when I say that knowing these essentials will save you a lot of grief later on.

Containerizing Your Microservices

Alright, first things first. You need to get your microservices into containers. Each microservice needs its own Dockerfile that packages everything it needs to run. Here's what a typical Node.js microservice looks like:

Dockerfile
 
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]


See that? We're using Alpine Linux as the base image. Why? Because it's super lightweight. The smaller your images, the faster your deployments. And honestly, who wants to wait around for huge images to download, right?

One more thing. Never use the "latest" tag for your images. I know it's tempting, but use semantic versions instead, like "1.2.0." This way, you know exactly what you're deploying, and rolling back becomes way easier if something breaks.

Creating Kubernetes Manifests

Now we're getting to the meat of it. Kubernetes uses YAML files (manifests) to define what you want to run. For a typical microservice, you'll need at least two things: a Deployment and a Service. Check this out:

Dockerfile
 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-service
  labels:
    app: payment-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: payment-service
  template:
    metadata:
      labels:
        app: payment-service
    spec:
      containers:
      - name: payment-service
        image: myregistry/payment-service:1.2.0
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: url
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5


Look at all that goodness! Those resource requests and limits? They prevent one microservice from hogging all your cluster's resources. And those health checks? Kubernetes uses them to know when your service is actually ready and healthy. Super important stuff.

Notice how we're pulling the database URL from a secret? Never hardcode sensitive data in your manifests. Just don't do it.

Service Discovery and Communication

So, your microservices need to talk to each other. How does that work? Well, here's the cool part: Kubernetes has built-in service discovery through DNS. When you create a Service, Kubernetes automatically creates DNS entries for it.

Let's say you have a service called "payment-service" in the "production" namespace. Other services can reach it at payment-service.production.svc.cluster.local. Pretty neat, huh?

Here's what a Service manifest looks like:

Dockerfile
 
apiVersion: v1
kind: Service
metadata:
  name: payment-service
spec:
  selector:
    app: payment-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: ClusterIP


For internal communication between microservices, use ClusterIP services. This keeps all the traffic inside your cluster and gives you automatic load balancing across all your Pod replicas. Can you imagine doing all that manually? No thanks!

Configuration Management

Here's something that trips up a lot of people: managing configuration across multiple microservices. You've got non-sensitive config like feature flags, and sensitive stuff like database passwords. Kubernetes handles both.

For regular config, use ConfigMaps:

Dockerfile
 
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  log_level: "info"
  max_connections: "100"
  feature_flags: |
    {
      "new_checkout": true,
      "beta_features": false
    }


For sensitive data, use Secrets (and please, please encrypt them at rest). The key thing is keeping configuration separate from your code. This lets you deploy the same container to different environments without rebuilding it. Makes sense, right?

Scaling Strategies

Okay, this is where Kubernetes really shines. Companies using container orchestration see a 20–30% improvement in their deployment speed. That's a huge boost!

Kubernetes can automatically scale your microservices based on CPU usage, memory, or even custom metrics. It's called horizontal pod autoscaling, and it looks like this:

Dockerfile
 
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: payment-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: payment-service
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70


Set your minimum replicas high enough to handle sudden traffic spikes. You don't want to be caught off guard when everyone decides to use your app at the same time, you know?

Observability and Monitoring

You really need high observability in production. If you don't have it, you're flying blind. Use structured logging with correlation IDs so you can follow a single request as it moves between several microservices.

Always log to standard output, as this is a pro tip. You don't have to worry about collecting and combining logs; Kubernetes will do it for you. Don't try to handle log files inside containers; that's just asking for trouble.

Use a tool like Prometheus to track metrics. Set up an endpoint in your service that works with Prometheus and keep track of things like request latency, error rates, and any other business metrics that are important to you. Jaeger and other tools can help you with distributed tracing. They help you find bottlenecks when requests go via more than one service.

Handling State and Persistence

Now, ideally, your microservices should be stateless. But let's be real — sometimes you need to store data. For services like databases that need stable identities and persistent storage, use StatefulSets instead of Deployments.

You'll need to request storage through PersistentVolumeClaims:

Dockerfile
 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd


But honestly? For most microservices, try to keep them stateless. Store session data in external systems like Redis. This makes scaling and recovery from failures so much easier.

Deployment Strategies

There are many ways to provide updates to your microservices. Rolling updates slowly replace old Pods with new ones, which is great because there is no downtime. Blue-green deployments keep two full environments and switch traffic after testing the new version. Canary deployments deliver a tiny amount of traffic to the new version first. If everything goes well, they will slowly send more traffic to it.

No matter what plan you pick, make sure you get the right health exams. You don't want Kubernetes to deliver traffic to pods that aren't ready yet. Been there, not fun.

Security Best Practices

Let's talk about safety for a moment. Two-thirds of companies say they are delaying or slowing down the deployment of applications because they are worried about Kubernetes security. A lot of businesses are anxious about security, and they should be!

NetworkPolicies let you decide which pods can talk to each other. This is like a firewall for your microservices. When you can, run containers as non-root users and make the root filesystem.

Conclusion

Look, deploying microservices on Kubernetes is a journey. It takes time to understand all the pieces and how they fit together. But once you get the hang of it? The benefits are huge. Automatic scaling, self-healing, rolling updates, it's all pretty amazing.

The CNCF annual survey shows that Kubernetes adoption rates have increased to 96% among respondents, telling you something: this isn't a fad. Kubernetes has become the standard way to run containerized applications, especially microservices.

Kubernetes pods microservices

Published at DZone with permission of Puneet Pahuja. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Kubernetes Scheduler Plugins: Optimizing AI/ML Workloads
  • A Transaction-Grade Performance Blueprint for Spring Boot FinTech Microservices (Tracing, Histograms, and Kubernetes)
  • Stop Debugging Code That Works: Identifying False Failures in Kubernetes
  • Kubernetes 101: Understanding the Foundation and Getting Started

Partner Resources

×

Comments

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

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

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 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook