近日,由于公司项目标准化改造需要,需要将docker-swarm编排的容器化部署的工程改造成使用k8s编排部署,因此有了以下的学习及研究的过程。阅读本文需要有K8S的基础知识,了解微服务的基本概念及docker的基本使用。k8s的学习从0到入门可以推荐一个不错的学习地址:https://kuboard.cn/learning 将网站从头看到尾,基本也可以入门了。
首先我们需要搭建好自己的微服务Eureka工程,具体的搭建我这就不具体细说,主要将说明下应改的配置。
application.yaml:
spring:
profiles:
active: 8761 #选择哪个配置文件
eureka:
server:
enable-self-preservation: false
client:
service-url:
defaultZone: http://eureka-0.eureka.box.svc.cluster.local:8761/eureka,http://eureka-1.eureka.box.svc.cluster.local:8761/eureka,http://eureka-2.eureka.box.svc.cluster.local:8761/eureka
#从服务器上获取注册信息
fetch-registry: true
#是否注册到自己
register-with-eureka: true
instance:
prefer-ip-address: false
spring:
application:
name: eureka
server:
port: 8761
注意点:
1. defaultZone的配置:此处可以配置为任意地址,通过k8s的配置文件环境变量重新注入改变或者按照本文中配置的名称修改(这是固定写法)配置。至于eureka-0.eureka.box.svc.cluster.local 这个域名的下面会详细介绍,简单说句这个域名的命名由$(service name).$(namespace).svc.cluster.local 组成。
2.prefer-ip-address配置:请务必设置为false.设置eureka.instance.prefer-ip-address
为false时,那么注册到Eureka中的Ip地址就是本机的Ip地址,也就是k8s为pod分配的ip地址。
K8S中Pod(容器组)是 Kubernetes 中最小的调度单元,通过引入Controller(控制器)来管理Pod。
控制器具有以下特性:
- 水平扩展(运行 Pod 的多个副本)
- rollout(版本更新)
- self-healing(故障恢复) 例如:当一个节点出现故障,控制器可以自动地在另一个节点调度一个配置完全一样的 Pod,以替换故障节点上的 Pod。
常用的几种控制器有Deployment StatefulSet DaemonSet等,普通的微服务工程通常选择Deployment作为控制器,常用于部署无状态服务,可以以声明的方式更行Pod(容器组)和ReplicaSet(副本集)。本文中由于Eureka的特殊性,将采用StatefulSet控制器进行部署。
SatefulSet 用于管理 Stateful(有状态)的应用程序。StatefulSet 管理 Pod 时,确保其 Pod 有一个按顺序增长的 ID。与Deployment 相似,StatefulSet 基于一个 Pod 模板管理其 Pod。与 Deployment 最大的不同在于 StatefulSet 始终将一系列不变的名字分配给其 Pod。这些 Pod 从同一个模板创建,但是并不能相互替换:每个 Pod 都对应一个特有的持久化存储标识。
StatefulSet的使用场景:
- 稳定、唯一的网络标识(dnsname)
- 每个Pod始终对应各自的存储路径(PersistantVolumeClaimTemplate)
- 按顺序地增加副本、减少副本,并在减少副本时执行清理
- 按顺序自动地执行滚动更新
1.降低网络损耗。Sevice的ClusterIP的工作原理,一个Service可能对应多个Endpoint(Pod),client访问的是Cluster IP。通过iptables关泽转发到Real Server,从而达到负载均衡的效果。服务通过Service访问Pod每次都需要经过Kube-Proxy代理流量,增加了与注册中心的通信,造成了一定的损耗。通过StatefulSet的Headless Service可以直接解析到Pod,采用轮询的访问,每次直接与Pod进行访问。
2.Pod之间可以互相访问。StatefulSet对应的pod的域名将为xxx-0,xxx-1,他们直接按可以互相访问,这样对于一些集群类型的应用可以解决互相之间身份识别的问题。
(一)eureka-statefulSet.yaml
---
apiVersion: v1
kind: Service
metadata:
name: eureka
namespace: box #命名空间
spec:
clusterIP: None
ports:
- name: eureka
port: 8761
selector:
product: box
app: eureka
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka
namespace: box
spec:
serviceName: eureka
replicas: 3 #副本数
selector:
matchLabels:
product: box
app: eureka
template:
metadata:
labels:
product: box
app: eureka
spec:
terminationGracePeriodSeconds: 10 #删除Pod时 等待时间
containers:
- name: eureka
image: harbor.box.com/box/eureka #请使用自己的harbor仓库地址
imagePullPolicy: Always #镜像拉取策略
ports:
- protocol: TCP
containerPort: 8761
env: #容器环境变量设置,可以覆盖工程中的配置
- name: APP_NAME
value: "eureka"
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: eureka.instance.appname
value:
"${spring.application.name}"
- name: eureka.instance.hostname
value:
"${POD_NAME}.${APP_NAME}"
- name: registerWithEureka
value:
"true"
- name: fetchRegistry
value:
"true"
- name: eureka.instance.preferIpAddress #这里一定要配置为false
value:
"false"
- name: eureka.client.serviceUrl.defaultZone #固定写法
value:
"http://eureka-0.${APP_NAME}:8761/eureka/,http://eureka-1.${APP_NAME}:8761/eureka/,http://eureka-2.${APP_NAME}:8761/eureka/"
resources: #资源限制
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 2000m
memory: 1024Mi
readinessProbe: #就绪探针
tcpSocket:
port: 8761
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 10
failureThreshold: 5
livenessProbe: #存活探针
tcpSocket:
port: 8761
initialDelaySeconds: 60
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- mountPath: /opt/logs/box
name: box-logs
volumes: #日志挂载
- name: box-logs
hostPath:
path: /opt/logs/box
(二)eureka-nodeport.yaml
同时我们需要将eureka的端口暴露出来,这样也方便查看服务的注册情况。
---
apiVersion: v1
kind: Service
metadata:
name: eureka-nodeport
namespace: box
labels:
product: box
app: eureka-nodeport
spec:
type: NodePort
ports:
- name: server
port: 8761
targetPort: 8761
nodePort: 30001 #对外暴露30001端口
selector:
product: box
app: eureka
在部署了K8s集群的机器上,进行部署操作。环境需具备docker和harbor仓库,其次每个节点对harbor的都可以访问到,否则会导致镜像拉取失败。
docker build -t="harbor.box.com/box/eureka" .
docker push harbor.box.com/box/eureka
2. 启动k8s配置文件:
kubectl apply -f eureka-statefulSet.yaml
kubectl apply -f eureka-nodeport.yaml
3. 查看pod是否启动:
kubectl get po -n box -o wide
如下图所示,可以看到eureka-0 eureka-1 eureka-2都已经正常启动 -n 后面的参数可以改成box也就是上文中配置的namespace,这边的截图为我本地项目中跑的namespace名字
接下来打开eureka界面(http://${nodeIp}:30001/eureka)可以看到服务都已经注册上去:(端口及ip请用自己的配置)
到这里 我们就搭建好一个基于k8s集群+docker的SpringCloud组件Eureka集群,下一节我将讲述我是如何搭建api-gateway组件Zuul网关的。如果有疑问,欢迎留言区留言。
本文参考:
https://kuboard.cn/learning
https://blog.csdn.net/qq_32641153/article/details/99700281
https://www.cnblogs.com/chadiandianwenrou/p/11928080.html