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.
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: springcloudDocker 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/dockerconfigjsonEureka 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:6210Python 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[].imageto 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
