概述
在当今云原生时代,微服务架构已成为构建复杂分布式系统的主流选择。Kubernetes(常简称为K8s)作为开源的容器编排系统,为微服务的管理和部署提供了强大的支持。然而,对于初学者或小型团队来说,直接在生产环境中部署K8s可能存在一定的挑战。因此,Minikube作为一个轻量级的K8s实现,为开发者提供了一个在本地机器上运行K8s集群的便捷方式,从而方便地进行微服务部署和测试。
微服务镜像包准备
打包流程,以Eureka为例展开,其余服务Dockerfile也这么写,下边就不一一列举了(因ENV放到环境变量原因,无需加额外参数)
Dockerfile配置文件
# 基礎鏡像 依賴的鏡像
FROM openjdk:8u342
WORKDIR work
ADD demo-eureka.jar demo-eureka.jar
# 設置命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","demo-eureka.jar"]
执行命令
docker build -t demo-eureka -f Dockerfile .
minikube image load demo-eureka
相关命令
方式一:打包docker镜像然后load到minikube
docker build -t <镜像名称> -f Dockerfile .
minikube image load <镜像名称>
方式二:直接使用minikube打包镜像
minikube image build -t <镜像名称> .
minikube 已上传镜像
minikube image ls
删除 minikube 镜像
minikube image rm <minikube image ls 的镜像名称>
加载 docker 镜像至 minikube
minikube image load <镜像名称>
添加镜像至 minikube
minikube image build -t <镜像名称> .
minikube 命令帮助
minikube help
微服务部署启动
SpringCloud Eureka集群(双节点)
对于eureka来说,要实现eureka的高可用,那就不是修改replicas这么方便了。由于部署的多个eureka之间需要将自己注册到彼此,因此要做一些特殊改动。
对于一般的后端微服务来说,在k8s中同时起多个相同的服务来做负载均衡,只需要简单的修改deployment的replicas,增加pod数量,然后通过对外暴露一个service来代理这些pod。
主要是用到了StatefulSet和headless service这两个k8s对象
StatefulSet
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态)
Headless Service
Headless Service 和普通service的一个显著的区别是,Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名。例如:我们可以用过这种域名来访问某个具体的pod
statefulSetName-0.serviceName.namespace.svc.cluster.local
这点在eureka的配置文件中defaultZone非常重要。
Eureka服务的yaml配置文件
#spring 注册中心名称
spring.application.name=serivce-eureka
#spring 注册中心配制
server.port=${PORT:11080}
#注册中心名称
eureka.instance.hostname=${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}
#实例名称显示IP配置
eureka.instance.preferIpAddress=true
# 实例ID
eureka.instance.instance-id=${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.long(1000000,9999999)}
#优先使用
#eureka.instance.ipAddress=127.0.0.1
#是否将自身注册
eureka.client.registerWithEureka=false
#如果为true,启动时报警.
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/}
# 设为false,关闭自我保护
#eureka.server.enable-self-preservation=false
# 清理间隔(单位毫秒,默认是60*1000) 心跳监控
eureka.server.eviction-interval-timer-in-ms=30000
配置文件解读:PORT,EUREKA_SERVER 等参数都会在Eureka的StatefulSet的yaml文件中定义;当K8S容器启动时,对应自定义参数会放到启动容器的环境变量中(可在容器执行env命令查看);届时应用会优先读取并覆盖替换为环境变量的参数。
Eureka的StatefulSet的yaml文件(本地镜像模式)
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: demo
name: demo-eureka
labels:
app: demo-eureka
spec:
serviceName: 'serivce-eureka'
replicas: 2
selector:
matchLabels:
app: demo-eureka
template:
metadata:
labels:
app: demo-eureka
spec:
#volumes:
#- name: logs
# nfs:
# path: /home/docker/k8s_yaml/nfs_logs/demo-eureka
# server: 192.168.xx.xx
#nodeName: serverxx
#imagePullSecrets:
# - name: xxxxx
containers:
- name: demo-eureka
image: demo-eureka
imagePullPolicy: Never
ports:
- containerPort: 11080
#volumeMounts:
# - name: logs
# mountPath: /opt/app/logs
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: EUREKA_SERVER
value: "http://demo-eureka-0.serivce-eureka.demo:11080/eureka/,http://demo-eureka-1.serivce-eureka.demo:11080/eureka/"
- name: EUREKA_INSTANCE_HOSTNAME
value: ${POD_NAME}.serivce-eureka.demo
- name: PORT
value: '11080'
Eureka 集群需要通过容器的主机名相互通讯,需要配置 Headless Service 资源,这也是为什么defaultZone配置会写成是 “http://demo-eureka-0.serivce-eureka.demo:11080/eureka/,http://demo-eureka-1.serivce-eureka.demo:11080/eureka/” 的原因。
域名解读:{POD_NAME}-{INDEX}.{SERVICE_NAME}.
Headless Service 的 yaml文件
注:这里的clusterIP为None,这是区别Headless Service与普通Service的地方。
apiVersion: v1
kind: Service
metadata:
namespace: demo
name: serivce-eureka
labels:
app: demo-eureka
spec:
clusterIP: None
ports:
- port: 11080
selector:
app: demo-eureka
端口转发执行命令
kubectl port-forward -n demo statefulsets/demo-eureka 11080:11080
浏览器本地访问
K8S部署SpringCloud Config配置中心(单节点)
“K8s上部署配置中心服务模块,同时也可以进一步检测eureka集群是否可用”
Config Service的 Deployment 的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: demo
name: demo-config
labels:
app: demo-config
spec:
serviceName: 'serivce-config'
replicas: 1
selector:
matchLabels:
app: demo-config
template:
metadata:
labels:
app: demo-config
spec:
#volumes:
#- name: logs
# nfs:
# path: /home/docker/k8s_yaml/nfs_logs/demo-config
# server: 192.168.xx.xx
#nodeName: serverxx
#imagePullSecrets:
# - name: mysecret
containers:
- name: demo-config
image: demo-config
imagePullPolicy: Never
ports:
- containerPort: 11084
#volumeMounts:
# - name: logs
# mountPath: /opt/app/logs
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: eureka.client.serviceUrl.defaultZone
value: "http://demo-eureka-0.serivce-eureka.demo:11080/eureka/,http://demo-eureka-1.serivce-eureka.demo:11080/eureka/"
- name: spring.cloud.config.server.native.searchLocations
value: "/export/demo/config"
- name: eureka.instance.ipAddress
value: ${POD_IP}
注意:为了通知注册中心 注册服务地址,eureka.instance.ipAddress 配置需从容器获取(例:POD_IP)。
K8S部署SpringCloud Service(多节点)
“K8s上部署应用服务模块”
注:若使用配置中心,配置优先级:配置中心 > yaml定义的配置 > Jar包内的配置。
1、如果部分配置如果需要抽到K8S yaml定义,需注释掉相关内容
2、从配置中心读取的配置不支持注册中心${PORT, 18080}(尤其这点需注意)
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: demo
name: demo-auth
labels:
app: demo-auth
spec:
serviceName: 'serivce-auth'
replicas: 2
selector:
matchLabels:
app: demo-auth
template:
metadata:
labels:
app: demo-auth
spec:
#volumes:
#- name: logs
# nfs:
# path: /home/docker/k8s_yaml/nfs_logs/demo-auth
# server: 192.168.xx.xx
#nodeName: serverxx
#imagePullSecrets:
# - name: xxxxx
containers:
- name: demo-auth
image: demo-auth
imagePullPolicy: Never
ports:
- containerPort: 11083
#volumeMounts:
# - name: logs
# mountPath: /opt/app/logs
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: eureka.client.serviceUrl.defaultZone
value: "http://demo-eureka-0.serivce-eureka.demo:11080/eureka/,http://demo-eureka-1.serivce-eureka.demo:11080/eureka/"
- name: eureka.instance.ipAddress
value: ${POD_IP}
微服务本地访问
kubectl port-forward 通过端口转发
kubectl port-forward 通过端口转发映射本地端口到指定的应用端口,从而访问集群中的应用程序(Pod).
执行命令
kubectl port-forward -n demo statefulsets/demo-eureka 11080:11080
本地浏览器打开:http://localhost:11080 即可访问
评论区