Cloud Native 16 min read

Deploying Spring Cloud Eureka on a Private Kubernetes Cluster with CI/CD

This guide walks through setting up a private Kubernetes environment, configuring namespaces and service accounts, modifying Eureka for IP registration, preparing Docker and Harbor authentication, creating StatefulSet and Service manifests, and automating continuous deployment with a Python script, enabling a fully functional Spring Cloud Eureka service in a resource‑constrained cluster.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Deploying Spring Cloud Eureka on a Private Kubernetes Cluster with CI/CD

Overview

After covering environment installation and testing, the article proceeds to deploy a production‑ready Spring Cloud application—specifically Eureka—into a private Kubernetes cluster. Due to limited memory, only a single‑node cluster is used, and the number of Eureka replicas is set to two.

Modifying Eureka Registration

Spring Cloud services normally register with Eureka using hostnames, which is unsuitable inside Pods. The configuration is changed to prefer IP registration by setting prefer-ip-address: true and updating serviceUrl.defaultZone with the addresses of both Eureka instances.

spring:
  application:
    name: eureka
server:
  port: 6210
eureka:
  instance:
    prefer-ip-address: true
    hostname: eureka
  client:
    registerWithEureka: true
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://eureka-0.eureka-svc.springcloud.svc.cluster.local:6210/eureka/,http://eureka-1.eureka-svc.springcloud.svc.cluster.local:6210/eureka/

Kubernetes Pre‑configuration

Create a dedicated namespace and a ServiceAccount with cluster‑admin rights so that the Spring Cloud resources can be managed.

# springcloud_ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: springcloud
---
# springcloud_sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: spring
  namespace: springcloud
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: springcloud-clusterrolebinding
  namespace: springcloud
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: spring
  namespace: springcloud

Docker Daemon Configuration for Insecure Registry

{
  "registry-mirrors": ["https://owcyje1z.mirror.aliyuncs.com"],
  "insecure-registries": ["http://192.168.1.64:8181"]
}

Harbor Authentication Secret

apiVersion: v1
kind: Secret
metadata:
  name: registry
  namespace: springcloud
data:
  .dockerconfigjson: ewoJImF1dGhzIjog... (base64 content)
type: kubernetes.io/dockerconfigjson

Eureka Kubernetes Manifests

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka
  namespace: springcloud
spec:
  serviceName: eureka-svc
  replicas: 2
  template:
    spec:
      imagePullSecrets:
      - name: registry
      containers:
      - name: eureka-container
        image: 192.168.1.64:8181/springcloud/eureka:4
        livenessProbe:
          httpGet:
            port: 6210
          initialDelaySeconds: 3
          timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: eureka-svc
  namespace: springcloud
spec:
  selector:
    app: eureka
  ports:
  - name: http
    port: 6210
    targetPort: 6210
  clusterIP: None
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: springcloud-ingress
  namespace: springcloud
spec:
  rules:
  - host: eureka.springcloud.com
    http:
      paths:
      - backend:
          serviceName: eureka-svc
          servicePort: 6210
        path: /

Deployment and Verification

Apply the manifests with kubectl apply -f eureka.yaml, then check the pods and services. Use wget inside the Pods to verify HTTP 200 responses from both Eureka instances.

# Verify pods
kubectl get all -n springcloud
# Test connectivity
kubectl exec -it -n springcloud eureka-0 sh -- wget -S -O /dev/null -q http://eureka-0.eureka-svc.springcloud.svc.cluster.local:6210
kubectl exec -it -n springcloud eureka-1 sh -- wget -S -O /dev/null -q http://eureka-1.eureka-svc.springcloud.svc.cluster.local:6210

Python CI/CD Script for Continuous Deployment

The script builds a Docker image from the compiled JAR, pushes it to Harbor, and updates the Eureka StatefulSet image in Kubernetes.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import docker, os, shutil, time, kubernetes

registry = '192.168.1.64:8181'
project = 'springcloud'
sitename = 'eureka'
webfile = 'eureka.jar'
sts_name = 'eureka'
sts_namespace = 'springcloud'

class Deploy(object):
    def __init__(self, rep, pro, name, file, sname, snamespace):
        self.KubernetesObj = kubernetes.client.Configuration()
        self.KubernetesObj.host = 'https://192.168.1.61:6443'
        self.KubernetesObj.verify_ssl = False
        self.KubernetesObj.api_key['authorization'] = '<TOKEN>'
        self.KubernetesObj.api_key_prefix['authorization'] = 'Bearer'
        self.StsName = sname
        self.StsNamespace = snamespace
        self.DockerClientObj = docker.DockerClient()
        self.WorkSpace = os.getenv('WORKSPACE')
        self.BuildId = os.getenv('BUILD_ID')
        self.Context = os.path.join(self.WorkSpace, 'context')
        self.SrcDockerFile = os.path.join(self.WorkSpace, 'Dockerfile')
        self.DestDockerFile = os.path.join(self.Context, 'Dockerfile')
        self.WebSiteFile = os.path.join(self.WorkSpace, 'target', file)
        self.BuildTag = os.path.join(rep, pro, name) + ':' + self.BuildId
        self.Repository = os.path.join(rep, pro, name)

    def createEnv(self):
        os.mkdir(self.Context)
        shutil.move(self.WebSiteFile, self.Context)
        shutil.move(self.SrcDockerFile, self.Context)
        return self.buildImage()

    def deleteImage(self):
        try:
            self.DockerClientObj.images.remove(self.BuildTag)
        except Exception:
            pass

    def buildImage(self):
        self.deleteImage()
        ImageObj, BuildLog = self.DockerClientObj.images.build(path=self.Context, dockerfile=self.DestDockerFile, tag=self.BuildTag, rm=True, forcerm=True)
        for Log in BuildLog:
            print(Log)
        return self.pushImage()

    def pushImage(self):
        PushLog = self.DockerClientObj.images.push(repository=self.Repository, tag=self.BuildId,
                                                   auth_config={"username": "admin", "password": "caichangen"}, decode=True)
        print(PushLog, end='')
        self.deleteImage()
        return self.deployKubernetes()

    def deployKubernetes(self):
        api_instance = kubernetes.client.AppsV1Api(kubernetes.client.ApiClient(self.KubernetesObj))
        sts_instance = api_instance.read_namespaced_stateful_set(name=self.StsName, namespace=self.StsNamespace)
        sts_instance.spec.template.spec.containers[0].image = self.BuildTag
        api_instance.patch_namespaced_stateful_set(name=self.StsName, namespace=self.StsNamespace, body=sts_instance)
        print('Deployment successful')

# Execute
deploy = Deploy(registry, project, sitename, webfile, sts_name, sts_namespace)
deploy.createEnv()

Final Verification

After the CI/CD pipeline updates the image, use

kubectl get pods -n springcloud -o json | jq .items[].spec.containers[].image

to confirm that the pods run the new image tags generated by Jenkins. The successful rollout completes the continuous delivery process for the Spring Cloud project.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerPythonci/cdKuberneteseurekaSpring CloudHarbor
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.