在k8s集群中通过CICD进行部署Eureka集群

一、前言

普通后端如果想要同时起多个服务来进行负载均衡,可以通过部署Deployment并调整Pod的数量,然后交由Service来代理这些Pod,而对于Eureka而言,这样做就没那么方便了,因为Eureka之间还需要互相注册,因此需要做一些特殊的改动。主要用到了StatefulSetHeadless Service这两个控制器

二、控制器介绍

1、StatefulSet

这是一个用于管理有状态程序的控制器,它在管理Pod时,确保每一个Pod有一个按顺序增长的ID。它与Deployment相似,也是基于一个Pod模板进行管理其Pod,最大的不同在于
它始终给Pod分配不变的名称。

(1)使用场景

  • 稳定且唯一的网络标识,Pod重新调度后并不会更改PodNameHostName,基于Headless Service实现
  • 稳定的持久化存储,每个Pod始终对应属于自己的存储,基于PersistentVolumeClaimTemplate
  • 有序的增加(从0到N-1)、减少副本(从N-1到0)
  • 按顺序的滚动更新

(2)DNS格式

StatefulSet中每个Pod的DNS格式为

StatefulSetName-{0..N-1}.ServiceName.namespace.svc.cluster.local
  • ServiceNameHeadless Service的名字
  • 0..N-1Pod所在的序号,从0开始到N-1
  • StatefulSetNameStatefulSet的名字
  • namespace为命名空间,Headless Service和StatefulSet必须在相同的namespace
  • cluster.localCluster Domain

如果Pod在同一个命名空间内,可以省略.namespace.svc.cluster.local

2、HeadLess Service

HeadLess Service和普通的Service最大的区别在于它代理的每一个Pod都会有对应一个域名(上节提到的DNS格式),在实际使用它的时候,我们需要将它的clusterIP属性设置为None
来表明它是一个HeadLess Service

三、搭建Eureka项目

1、创建项目

这里自行创建Eureka项目哦,这里不做演示

2、启动类增加注解

/*** 增加@EnableEurekaServer来开启Eureka服务* @author Gjing*/
@EnableEurekaServer
@SpringBootApplication
public class K8sEurekaDemoApplication {public static void main(String[] args) {SpringApplication.run(K8sEurekaDemoApplication.class, args);}
}

3、配置文件

这里使用了变量的形式设置配置的值,这样就可以根据不同的环境来分别配置了。如果对变量的使用不熟悉的话建议恶补一下SpringBoot项目在Yaml文件使用变量。这里只是演示的配置,在实际使用时
根据业务需求来合理配置

server:port: ${EUREKA_HOST:8761}
spring:application:name: ${SERVER_NAME:k8s-eureka-demo}
eureka:client:# 从eureka获取注册信息fetch-registry: ${FETCH_EUREKA:false}# 注册自己register-with-eureka: ${REGISTER_EUREKA:false}# 服务注册中心地址service-url:defaultZone: ${EUREKA_URL:http://localhost:8761/eureka/}instance:# 当前实例的主机名称hostname: ${HOST_NAME:localhost}server:# 关闭安全模式enable-self-preservation: false

4、Dockerfile

FROM openjdk:8-jdk
COPY target/*.jar app.jar
ENTRYPOINT java $JAVA_OPTS -jar $CONFIG app.jar

5、CI脚本文件

不是很熟悉CI写法的建议先看阅读:SpringBoot使用CICD

before_script:- export IMAGE_FULL_NAME=${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA}
stages:- compile- build- run
variables:MAVEN_REPO: "/.m2"PROJECT_NAME: "k8s-eureka"K8S_FILE: "eureka-k8s.yml"
compile:stage: compileimage: 172.20.9.4:5001/gjing/maven:1.0only:- mastertags:- pubscript:- mvn -Dmaven.repo.local=$MAVEN_REPO clean package -Dmaven.test.skip=trueartifacts:name: $PROJECT_NAMEexpire_in: 1weekpaths:- target/*.jar
build:stage: buildimage: docker:stableonly:- mastertags:- pubscript:- docker login --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY- docker build -t $IMAGE_FULL_NAME .- docker push $IMAGE_FULL_NAME- docker rmi -f $IMAGE_FULL_NAME
run:stage: runimage: roffe/kubectlonly:- mastertags:- pubvariables:PROJECT_PORT: 8761PROJECT_NAMESPACE: gj # 命名空间需要提前在k8s中创建好script:# 配置 kubectl, ${KUBE_CONFIG}这个变量会在下面发布的章节介绍如何配置- mkdir -p /root/.kube- echo ${KUBE_CONFIG} | base64 -d > /root/.kube/config- export KUBECONFIG=/root/.kube/config- kubectl version# 修改k8s文件里的一些变量- sed -i "s#{PROJECT_NAME}#$PROJECT_NAME#g;s#{PROJECT_PORT}#$PROJECT_PORT#g;s#{PROJECT_NAMESPACE}#$PROJECT_NAMESPACE#g;s#{PROJECT_IMAGE}#$IMAGE_FULL_NAME#g" $K8S_FILE# 创建- kubectl apply -f $K8S_FILE

6、项目的k8s文件

创建一个名为eureka-k8s.yml文件

# 定义一个ConfigMap用于存储eureka的注册中心地址
apiVersion: v1 # 版本号
kind: ConfigMap # 类型
metadata: # 定义元数据,名称与命名空间name: eureka-hostnamespace: {PROJECT_NAMESPACE}
data: # 定义这个ConfigMap要存储的数据registry_url: http://{PROJECT_NAME}-0.{PROJECT_NAME}:{PROJECT_PORT}/eureka/,http://{PROJECT_NAME}-1.{PROJECT_NAME}:{PROJECT_PORT}/eureka/,http://{PROJECT_NAME}-2.{PROJECT_NAME}:{PROJECT_PORT}/eureka/
--- # 定义service
apiVersion: v1
kind: Service
metadata: # service的元数据,包含名称、命名空间、标签name: {PROJECT_NAME}namespace: {PROJECT_NAMESPACE}labels:app: {PROJECT_NAME}
spec: # 定义属性selector: # 需要代理的pod的标签app: {PROJECT_NAME}ports: # service的端口- port: {PROJECT_PORT}name: {PROJECT_NAME}clusterIP: None # 设置为None,表示我们这是一个Headless Service
--- # 定义一个StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata: # 定义元数据,名称与命名空间name: {PROJECT_NAME}namespace: {PROJECT_NAMESPACE}
spec:replicas: 3 # 副本数serviceName: {PROJECT_NAME} # 服务名selector:matchLabels: # 匹配下方的template中定义的labelapp: {PROJECT_NAME}template: # 定义pod的模板metadata: # 模板的元数据labels:app: {PROJECT_NAME}spec: # 定义模板的属性containers:- name: {PROJECT_NAME}image: {PROJECT_IMAGE}ports:- containerPort: {PROJECT_PORT}readinessProbe: # 就绪检查httpGet:path: /actuator/healthport: {PROJECT_PORT}failureThreshold: 3 # 探测失败的重试次数,如果超过3次了没成功就认定为pod是失败的状态initialDelaySeconds: 60 # pod启动延迟多久进行一次检查periodSeconds: 10 # 检测的时间间隔successThreshold: 1 # 只要一次成功就认为pod是正常的timeoutSeconds: 10 # 检测的超时时间,如果超时了就认为是失败的一个状态env: # 配置环境变量,传递给项目的配置文件- name: EUREKA_HOSTvalue: "{PROJECT_PORT}"- name: SERVER_NAMEvalue: {PROJECT_NAME}- name: FETCH_EUREKAvalue: "true"- name: REGISTER_EUREKAvalue: "true"- name: EUREKA_URLvalueFrom:configMapKeyRef:name: eureka-hostkey: registry_url- name: HOST_NAMEvalueFrom:fieldRef:fieldPath: metadata.name

这时候我们就所有的准备工作都完成了

四、发布

由于我们配了CI文件,那么当我们代码提交到Gitlab的时候,就会自动进行构建并启动啦

1、配置KUBE_CONFIG变量

首先,我们先登陆到 k8s master节点服务器上,进入到/etc/kubernetes/目录,然后通过cat admin.conf将这个文件的内容输出到控制台,最后将复制出来的内容先保存到
自己电脑的文本编辑器中,然后修改红色框中的地址,将dns修改为你的ApiServer的IP,如果是多master的话就是填写ApiServer的LoadBalance IP了

然后我们复制修改后的所有内容,到浏览器随便搜索一个在线的base64加密工具将内容进行加密。随后,我们来到GitLab,进到具体项目或者项目组里,点击下方图中的选项

点击后进到下方页面并添加变量,注意:要和你ci里面写的保持一致,的话就是刚刚加密后的内容了

最好将此变量配置在项目组中,这样该项目组的所有项目都会继承该变量

2、提交

上面已经配置了KUBE_CONFIG变量了,这时候我们就可以直接提交代码到GitLab啦,提交成功后就可以在GitLab项目左侧的CICD选项中看到流水线在执行

当三个阶段都打勾了就说明执行成功啦,如果出现了错误,那就可以点击指定阶段进去查看下错误日志进行针对性修改了

这时我们可以去master服务器上执行命令查看下pod启动成功没

可以看到三个Pod都是running状态了,这时我们也可以通过kubectl logs -f k8s-eureka-0 -n gj命令进行查看下其中一个Pod的日志,这里我们可以看到Eureka已经成功起来了

3、访问

通过第二步,我们通过命令查看已经启动成功了三个Eureka副本,这时候,如果我们想通过浏览器访问怎么办呢,这时候就需要定义一个Ingress了,我们创建eureka-ingress.yml文件,内容如下

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: {PROJECT_NAME} # 这里你自己定义Ingress的名称namespace: {PROJECT_NAMESPACE} # 这里是命名空间,要与Eureka所在的命名空间一样
spec:rules:- host: eureka.snowbd.onesport.com.cn # 这里更改为你的域名http:paths:- backend:serviceName: {PROJECT_NAME} # 指定后端的Service,也就是Eureka的ServiceservicePort: {PROJECT_PORT} # Service端口

定义好后通过kubectl apply -f eureka-ingress.yml命令进行构建,构建成功后我们可以通过kubectl get ingress -n gj查看到刚刚构建的Ingress

我们通过刚刚配置的域名使用浏览器访问一下Eureka的界面,如果访问失败,那就要检查下域名是否正确了


文章中的项目地址为:k8s-eureka-demo

k8s部署eureka集群相关推荐

  1. K8S 部署rabbitmq集群

    K8S 部署rabbitmq集群 版本介绍 名称 版本 k8s 1.18 rabbitmq 3.8 命名空间:rabbitmq 我这里已经建立 configmap 配置文件 [root@k8s-mas ...

  2. docker 部署rabbitmq,k8s部署rabbitmq集群,跟踪和监控rabbitmq

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 rabbit原理和架构可以参考https://blog.csdn.net/luanpeng825485697/article/details/8208 ...

  3. kubernetes入门到精通(二):k8s部署Tomcat集群,基于NTFS协议的文件集群共享,Service提供负载均衡,端口转发工具Rinetd配置外部访问

    首先,配置 Docker 镜像加速服务 登录阿里云账号,进入控制台 -> 容器镜像服务 (不需要有阿里云的服务器,只要注册账号即可) 在两台 node 节点上配置好阿里云的镜像加速. 重启一下 ...

  4. k8s部署redis集群

    K8S部署Redis Cluster集群 kubernetes部署单节点redis: https://www.cnblogs.com/zisefeizhu/p/14282299.html Redis ...

  5. k8s部署kafka集群

    前言 环境:centos 7.9 k8s集群.zookeeper集群 本篇将在k8s中部署kafka集群,kafka依赖zookeeper集群,zookeeper集群我们已经搭建好了,可以参考http ...

  6. 使用K8S部署zookeeper集群

    1.目的: 本次的目的是通过使用k8s搭建一个三节点的zookeeper集群,因为zookeeper集群需要用到存储,所以我们需要准备三个持久卷(Persistent Volume) 简称就是PV. ...

  7. 【华为云CCE】 k8s部署nacos集群

    业务场景: 华为CCE,根据自己的nacos镜像,部署nacos集群.由于公司使用的是华为云CCE内网环境,不能通过外网下载镜像,只能根据公司自己的镜像进行部署.看了网上华为云CCE部署nacos集群 ...

  8. k8s部署mysql集群(statefulset):主写从读、一主多从集群

    安装nfs server和client端都执行 yum install nfs-utils rpcbind -y systemctl start nfs systemctl start rpcbind ...

  9. k8s部署zookeeper集群 运行 ZooKeeper, 一个 CP 分布式系统

    本教程展示了在 Kubernetes 上使用 StatefulSets,PodDisruptionBudgets 和 PodAntiAffinity 特性运行 Apache Zookeeper. 准备 ...

最新文章

  1. stella forum v 2.0 的两款主题样式
  2. Minimum Path Sum,最短路径问题,动态规划
  3. 视频专辑:Hibernate 视频
  4. Linux awk的 if语句,AWK if(条件)语句与循环简介
  5. HTML5基本知识小测验
  6. 设计模式(博客园精华集)
  7. PHP的时间增加10分钟和加一天的时间
  8. 二元二次方程 c语言,C语言求二元二次方程组的解 我要代码 谢谢大家了
  9. 腾讯云如何设置二级域名?
  10. 视频分割软件有什么,怎么分割视频
  11. 百度司南是什么产品?
  12. 关于华为云会议的测评
  13. Python 豆瓣网的全自动登录(豆瓣验证码自动识别)
  14. go扩展ticker实现优雅起停
  15. MATLAB画双纵轴曲线。
  16. 显示系统信息(System Info)
  17. APEX包管理器简述(二)
  18. 例说生产者和消费者模型
  19. 洛谷P1462 通往奥格瑞玛的道路 题解
  20. Python 办公小助手:读取 PDF 中表格并重命名

热门文章

  1. DZ论坛全自动挂机回帖助手2015.10.25实用版
  2. MPI并行计算PI,并进行n值和并行进程个数影响探讨
  3. 大型商场借力泛微,实现内外协同招商,合同、铺位、费用统一管理
  4. Python类变量和实例变量区别
  5. 一图读懂赛灵思 UltraScale+ 新成员
  6. 假期无聊,我又发现一个刷题神器
  7. 苹果6s手机怎么录屏 苹果手机投屏电脑
  8. 与Hadoop之父聊聊天
  9. python只保留数据的某几列_python怎么选取csv某几列
  10. 计算10000以内的平方数