写在最前
在一些老旧项目中 Eureka 仍然在使用,且为了实现高可用性必须搭建集群。然而,公开的 Eureka 服务没有足够的安全保障,因此本篇将记录如何为 Eureka 集群配置账号和密码,以确保安全连接。
1. docker 部署
2. kubernetes 部署
当前部署在 default 命名空间,后续资源内容可根据需要自行调整。
2.1 secret
kind: Secret
apiVersion: v1
metadata:
name: eureka-secret
namespace: default
annotations:
kubesphere.io/creator: admin
data:
EUREKA_HOST_NAME: JChNWV9QT0RfTkFNRSkuZXVyZWthLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWw=
EUREKA_PASSWORD: NkI5QkQ2NEQtOEFBOC00MDNFLUI3NDgtQzI4ODUyMzhFRDM4
EUREKA_SERVER_ADDRESS: >-
aHR0cDovLyQoRVVSRUtBX1VTRVJOQU1FKToke0VVUkVLQV9QQVNTV09SRH1AZXVyZWthLTAuZXVyZWthLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWw6ODc2MS9ldXJla2EvLGh0dHA6Ly8kKEVVUkVLQV9VU0VSTkFNRSk6JHtFVVJFS0FfUEFTU1dPUkR9QGV1cmVrYS0xLmV1cmVrYS5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsOjg3NjEvZXVyZWthLyxodHRwOi8vJChFVVJFS0FfVVNFUk5BTUUpOiR7RVVSRUtBX1BBU1NXT1JEfUBldXJla2EtMi5ldXJla2EuZGVmYXVsdC5zdmMuY2x1c3Rlci5sb2NhbDo4NzYxL2V1cmVrYS8=
EUREKA_USERNAME: YWRtaW4=
type: Opaque
2.2 service
提供了一个nodeport可以看到集群内容,生产禁止配置nodeport
kind: Service
apiVersion: v1
metadata:
name: eureka
namespace: default
labels:
app: eureka
annotations:
kubesphere.io/creator: admin
spec:
ports:
- name: eureka
protocol: TCP
port: 8761
targetPort: 8761
selector:
app: eureka
clusterIP: None
clusterIPs:
- None
type: ClusterIP
sessionAffinity: None
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
internalTrafficPolicy: Cluster
kind: Service
apiVersion: v1
metadata:
name: eureka-nodeport
namespace: default
labels:
app: eureka-np
annotations:
kubesphere.io/creator: admin
spec:
ports:
- name: http-8761
protocol: TCP
port: 8761
targetPort: 8761
nodePort: 30724
selector:
app: eureka
type: NodePort
sessionAffinity: None
externalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
internalTrafficPolicy: Cluster
2.3 statefulset
ENVIRONMENT 变量生产可以换成 prod 这样在界面上可以看到相关的字样。
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: eureka
namespace: default
annotations:
kubesphere.io/creator: admin
kubesphere.io/description: 'tanqidi/eureka:latest'
spec:
replicas: 3
selector:
matchLabels:
app: eureka
template:
metadata:
creationTimestamp: null
labels:
app: eureka
annotations:
kubesphere.io/creator: admin
kubesphere.io/imagepullsecrets: '{}'
kubesphere.io/restartedAt: '2025-08-12T11:16:51.209Z'
spec:
containers:
- name: eureka
image: 'tanqidi/eureka:latest'
ports:
- name: http-8761
containerPort: 8761
protocol: TCP
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: ENVIRONMENT
value: uat
- name: JVM_OPTS
value: '-Xms1g -Xmx1g'
- name: EUREKA_HOST_NAME
valueFrom:
secretKeyRef:
name: eureka-secret
key: EUREKA_HOST_NAME
- name: EUREKA_PASSWORD
valueFrom:
secretKeyRef:
name: eureka-secret
key: EUREKA_PASSWORD
- name: EUREKA_USERNAME
valueFrom:
secretKeyRef:
name: eureka-secret
key: EUREKA_USERNAME
- name: EUREKA_SERVER_ADDRESS
value: >-
http://$(EUREKA_USERNAME):${EUREKA_PASSWORD}@eureka-0.eureka.default.svc.cluster.local:8761/eureka/,http://$(EUREKA_USERNAME):${EUREKA_PASSWORD}@eureka-1.eureka.default.svc.cluster.local:8761/eureka/,http://$(EUREKA_USERNAME):${EUREKA_PASSWORD}@eureka-2.eureka.default.svc.cluster.local:8761/eureka/
resources:
limits:
cpu: 500m
memory: 1200Mi
requests:
cpu: 500m
memory: 1Gi
livenessProbe:
httpGet:
path: /
port: 8761
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 8761
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: Always
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
serviceName: eureka
podManagementPolicy: OrderedReady
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
revisionHistoryLimit: 10
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain
whenScaled: Retain
2.4 测试命令
在进行模拟请求时,请确保使用你自定义的 Eureka 账号、密码和地址。比如,将测试用的账号密码 admin:6B9BD64D-8AA8-403E-B748-C2885238ED38
替换为你实际配置中的账号、密码和 Eureka 服务的地址。
curl -v -X POST http://admin:6B9BD64D-8AA8-403E-B748-C2885238ED38@eureka-0.eureka.default.svc.cluster.local:8761/eureka/apps/hello-service -H "Content-Type: application/json" -d '{"instance":{"instanceId":"h
ello-instance-1","hostName":"localhost","app":"hello-service","ipAddr":"127.0.0.1","port":{"$":8080,"@enabled":"true"},"securePort":{"$":443,"@enabled":"false"},"healthCheckUrl":"http://localhost:8080/healt
h","statusPageUrl":"http://localhost:8080/info","homePageUrl":"http://localhost:8080","vipAddress":"hello-service","dataCenterInfo":{"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo","name":
"MyOwn"}}}'
3. 镜像成品
我已使用 Docker Buildx 构建了同时支持 amd64 与 arm64 架构的镜像,便于在不同平台运行,可按需优化或扩展。
tanqidi/eureka:latest
4. 代码变更
本篇章我们主要基于 BitInit 大佬的代码进行编译,并且结合@dixitsatish34大佬的贴文进行新增改造安全认证功能。
4.1 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
4.2 SecurityConfig
package site.bitinit.eureka;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/eureka/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic();
}
}
4.3 application-xxx.yml
全部抽取成为变量,在statefulset中通过ENV动态传入。
eureka:
instance:
hostname: ${EUREKA_HOST_NAME}
client:
serviceUrl:
defaultZone: ${EUREKA_SERVER_ADDRESS}
spring:
security:
user:
name: ${EUREKA_USERNAME}
password: ${EUREKA_PASSWORD}
5. 优秀贴文
https://github.com/BitInit/eureka-on-kubernetes
https://medium.com/@dixitsatish34/secure-eureka-endpoint-using-basic-authentication-0d69535ab4f7