网站首页 > 技术文章 正文
适合ingress-nginx接入外部负载均衡的部署 一文主要介绍了如何通过ingress-nginx对外暴露服务,以及与外部负载均衡的结合,下面我们通过将SpringBoot项目迁入K8S中,来完整了解下从一个Java项目的整体流程。
环境准备
1.命名空间
K8S通过namespace划分集群资源。因此我们通过prod、test、develop来划分生产环境、测试环境、开发环境。
在此我们主要以test进行演示。
2. 镜像仓库
我们通过harbor仓库来存储springboot项目的镜像,可参考Docker部署spring boot体验来了解helloworld项目从打包到上传harbor仓库的过程。
部署
1.创建命名空间
kubectl create ns test
2.添加harbor认证
通过secret 可以实现类似docker login登录harbor仓库认证过程。
#在对应的namespace下创建secret
kubectl create secret docker-registry harbor --namespace test --docker-server=harbor.test.cn --docker-username=admin --docker-password=admin --docker-email=test@test.cn
注意:一定要在对应的namespace下创建secret,否则会导致从harbor仓库pull镜像认证不通过。
3.定义Deployment
通常Deployment、service、ingress 写在一份yaml文件中,为方便演示我们都进行单独分解。
# 1.vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
namespace: test
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
template:
metadata:
name: helloworld
labels:
app: helloworld
spec:
hostAliases:
- ip: "10.11.10.11"
hostnames:
- "api1.test.cn"
- "api2.test.cn"
- ip: "10.11.10.12"
hostnames:
- "api3.test.cn"
containers:
- name: helloworld
env:
- name: JAVA_OPTS
value: "-Xmx128m -Xms128m -Dspring.profiles.active=test"
image: harbor.test.cn/helloworld/helloworld:1311c4520122dfa67bb60e0103c9519fcb370e50
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 200
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 180
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: "0.5"
memory: "500Mi"
requests:
cpu: "0.5"
memory: "500Mi"
volumeMounts:
- name: logdir
mountPath: /logs
- name: localtime
mountPath: /etc/localtime
- name: timezone
mountPath: /etc/timezone
imagePullSecrets:
- name: harbor
volumes:
- name: logdir
emptyDir: {}
- name: localtime
hostPath:
path: /etc/localtime
- name: timezone
hostPath:
path: /etc/timezone
# 2.应用配置文件
kubectl apply -f deployment.yaml
# 3.查看
# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
helloworld-6f78bd8668-j6hmp 1/1 Running 0 3d18h
要点:
- hostAliases: 用于指定适用于该项目的hosts解析,可根据实际情况进行添加。
- env: jvm启动参数通过环境变量env传递,而args只适用于dockder build阶段,因此不能使用。
- resources: 容器默认会无限制占用宿主机资源,因此需要进行限制。对于java 项目 xms xmx只是堆内存,实际进程所占内存比这还大,例如某项目默认Xms Xmx都是128M,但是pod的资源限制为200M、300M都会导致OOM,因此调整的资源需要比Xmx还要大。
- hostPath: 将宿主机节点文件系统中的文件或目录挂载到集群中,由于基于宿主机的目录,多副本跨节点必须保证目录存在,否则可能导致失败。
- emptyDir: 当pod被分配给节点时,首先创建emptyDir卷,并且只要该pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。pod中的容器可以读取和写入emptyDir卷中的相同文件。尽管该卷可以挂在到每个容器中的相同或不同路径上。当出于任何原因从节点中删除pod时,emptyDir中的数据将被永久删除。
- 容器时区: 挂在宿主机的localtime和timezone,保证项目日志时间正常。
- livenessProbe: 通过探针livenessProbe进行检测,httpGet获取的状态码等于200或小于400则正常。检测失败后,将根据使用restartPolicy策略。restartPolicy默认为always。
- readinessProbe: 通过探针readinessProbe进行检测,httpGet获取的状态码等于200或小于400则正常。指示容器是否准备好服务请求。如果就绪探针失败,则端点控制器将从与Pod匹配的所有服务的端点中删除Pod的IP地址。默认每10秒检测一次,连续失败数为3,连续成功数为1。
- initialDelaySeconds: 如果启动时间超过initialDelaySeconds会导致livenessProbe、readinessProbe检测不成功。readinessProbe 失败导致无法接受请求,livenessProbe失败导致容器不断重启。因此initialDelaySeconds要大于实际启动时间。
注意:
- 对于SpringBoot项目的日志文件,我们并没有进行持久化存储,而是通过emptyDir临时存储,然后通过写入ELK做长期存储。
- 对于SpringBoot项目的数据文件,无论通过hostPath还是emptyDir都不合适,需通过PVC进行持久化存储。
4.定义service
# 1.vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
namespace: test
spec:
type: NodePort
selector:
app: helloworld
ports:
- port: 8080
targetPort: 8080
# 2.应用配置文件
kubectl apply -f service.yaml
# 3.查看状态
# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld NodePort 10.1.139.205 <none> 8080:30949/TCP 6d
# 4.访问
# curl 10.1.138.205:8080
Hello,world
对于NodePort类型的service,通过集群所有节点的IP都可以访问服务。
# curl 192.168.3.218:30949
Hello,world!
# curl 192.168.3.219:30949
Hello,world!
# curl 192.168.3.217:30949
Hello,world!
# 原因:
# 所有节点lvs信息都有对service 30949端口的转发,因此集群内所有节点都可通过service访问服务
ipvsadm -l -n |grep -A 2 -B 2 30949
TCP 192.168.3.217:30949 rr
-> 10.244.2.100:8080
5.定义ingress-ingress
此部分细节可参考适合ingress-nginx接入外部负载均衡的部署 选择适合自己的部署方式,本文我们使用默认的Deployment+NodePort进行部署。
# 1.vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld
namespace: test
spec:
rules:
- host: hello.test.cn
http:
paths:
- path: /
backend:
serviceName: helloworld
servicePort: 8080
# 2.应用
kubectl apply -f ingress.yaml
# 3.查看
# kubectl get ing -n test
NAME CLASS HOSTS ADDRESS PORTS AGE
helloworld <none> hello.test.cn 10.1.217.16 80 4d18h
# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.1.217.16 <none> 80:30687/TCP,443:31826/TCP 15h
# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.1.217.16 <none> 80:30687/TCP,443:31826/TCP 15h
# 4.访问
# curl -x 192.168.3.218:30687 hello.test.cn
Hello,world!
注意: 默认ingress-nginx部署并不能让我们从外部通过80端口访问到服务,只能通过NodePort暴露的端口访问。
总结
以上是整个SpringBoot项目的部署过程及需要注意的地方,个人认为K8S部署SpringBoot项目最主要的应该是资源限制、健康检查及存储这三点。
- 资源限制保证集群内容器合理占用宿主机资源,避免资源无限占用导致集群问题;
- 健康检查保证集群内容器正常运行,合理摘除不健康的节点,保证请求的转发到健康节点;
- 选择合适的存储方式,保证项目的运行时数据、日志文件合理存储;
- 上一篇: datax 学习一(dataxweb)
- 下一篇: JVM中如何理解强引用、软引用、弱引用、虚引用?
猜你喜欢
- 2024-10-28 美团面试:熟悉哪些JVM调优参数,幸好我准备过
- 2024-10-28 Java虚拟机:Jvm概念和原理详解以及GC机制的分析
- 2024-10-28 JVM 的内存模型(jvm1.8内存模型)
- 2024-10-28 JDK、JRE、JVM,是什么关系?(jdk jrejvm的区别)
- 2024-10-28 一个 JVM 参数引发的频繁 CMS GC(当产生一个异常时,jvm会做什么)
- 2024-10-28 JVM系列一:JVM内存组成及分配(jvm的内存分配)
- 2024-10-28 谈谈JMM与JVM的相关知识(jmm jvm juc)
- 2024-10-28 常见的JVM参数配置(常见的JVM参数配置有哪些)
- 2024-10-28 一份详细介绍JVM的资料(对比JDK8和JDK7)
- 2024-10-28 理解JVM运行时数据区域,看这一篇文章就够了
- 11-26Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 11-26一文搞懂MySQL行锁、表锁、间隙锁详解
- 11-26电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 11-26代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 11-26CMD命令提示符能干嘛?这些功能你都知道吗?
- 11-26性能测试之慢sql分析
- 11-26论渗透信息收集的重要性
- 11-26如何查看电脑连接过的所有WiFi密码
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)