前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于kubernetes部署JAVA项目

基于kubernetes部署JAVA项目

作者头像
用户1278550
发布2021-12-08 09:35:25
1.8K0
发布2021-12-08 09:35:25
举报
文章被收录于专栏:idba

制作镜像分为三步:

第一基础镜像,是基于哪个操作系统,比如Centos7或者其他的

第二步中间件镜像,比如服务镜像,跑的像nginx服务,tomcat服务

第三步项目镜像,它是服务镜像之上的,将你的项目打包进去,那么这个项

目就能在你这个服务镜像里面运行了

一般我们运维人员都是提前将我们的镜像做好,而开发人员就能直接拿这个镜像去用,这个镜像一定要符合现在环境部署的环境,

控制器管理pod

也就是k8s去部署这个镜像了,一般我们都会去拿控制器去部署,用的最多的就是deployment

  • Deployment:无状态部署
  • StatefulSet:有状态部署
  • DaemonSet:守护进程部署
  • Job & CronJob:批处理

无状态和有状态的有什么区别?无状态的是应用程序 有状态的是有身份的,比如网络ID、存储、这个两个是提前规划好的,有序启动/停止

Pod数据持久化

pod数据持久化主要是因对一个应用程序说的,比如开发一个项目,这个项目有没有落地到本地文件,如果有落的话,就保证他持久的有了,那就必须要用到pod数据的持久化了。

容器部署过程中一般有以下三种数据:

  • 启动时需要的初始数据,可以是配置文件
  • 启动过程中产生的临时数据,该临时数据需要多个容器间共享
  • 启动过程中产生的持久化数据
暴露应用

在k8s中,部署一个deployment,它是无法对外进行访问的,就是别的应用程序要想访问部署的deployment,它找不到该怎么去访问。为什么去这么讲?因为deployment一般都是多副本的去部署,有可能会分布在不同的节点之上,而且重建pod ip也会变,重新发布一下也会变,所以没有办法去固定去访问哪个pod,即使固定,其他的pod也访问不,要想做到多个pod都去提供服务的话,前面有必须要加一个负载均衡,提供一个访问入口,只有这个访问这个统一入口,才能转发到后端多个pod上,只要访问这个Cluster IP就能转发到后端的pod上。

Service

  • Service定义了Pod的逻辑集合和访问这个集合的策略
  • Service引入为了解决Pod的动态变化,提供服务发现和负载均衡
  • 使用CoreDNS解析Service名称
对外发布应用

暴露出去之后呢,也就是需要让用户去访问,比如搭建一个电商网站,让用户去访问,ingress相对于service,它是一个互补的状态,弥补了各自,service主要提供了集群内部的访问,也可以暴露一个TCP/UDP的端口,而ingress主要是一个7层的转发,也就是提供一个统一的入口,只要访问ingress controller,它就能帮你转发你部署所有的项目,也就是所有的项目都使用域名去访问。

传统部署与K8S部署区别

对于传统部署 首先开发者将代码部署到你的代码仓库中,主流的用的Git或者gitlab,提交完代码通过CI/CD平台需要对代码进行拉取、编译、构建,产生一个War包,然后交给Ansible然后发送到云主机上/物理机,然后通过负载均衡将项目暴露出去,然后会有数据库,监控系统,日志系统来提供相关的服务。

对于K8S部署

首先是开发将代码放在代码仓库,然后通过jenkins去完成拉取代码,编译,上传到我们的镜像仓库这里是将代码打包成一个镜像,而不是刻意执行的war或者jar包,这个镜像包含了你的项目的运行环境和项目代码,这个镜像可以放在任何docker上去run起来,都可以去访问。

首先得保证能够在docker上去部署起来,再部署到k8s上,打出来的镜像去放在镜像仓库中,来集中的去管理这些镜像,因为每天会产生几十个或者上百个镜像,必须通过镜像仓库去管理,这里可能会去写一个脚本去连接k8smaster,而k8s会根据自己的部署去调度这些pod,然后通过ingress去发布我们的应用,让用户去访问,每个ingress会关联一组pod,而service会创建这组pod的负载均衡,通过service去区分这些节点上的Pod,然后数据库是放在集群之外,监控系统日志系统也可以放在k8s集群放在去部署,也可以放在之外,我们是放在k8s集群内的,也不是特别敏感,主要用来运维和开发调试用的,不会影响到我们的业务,所以我们优先去k8s中去部署。

部署一个JAVA项目到k8s中

安装一个openjdk还是maven用来编译
代码语言:javascript
复制
[root@k8s-master ~]# yum -y install java-1.8.0-openjdk.x86_64 maven
[root@k8s-master ~]# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

然后我们将代码拉到本地一般Dockerfile中跟我们的代码都放在同一目录下,

代码语言:javascript
复制
[root@k8s-master tomcat-java-demo-master]# ls
db  Dockerfile  LICENSE  pom.xml  README.md  src
[root@k8s-master tomcat-java-demo-master]# vim Dockerfile 
FROM lizhenliang/tomcat
LABEL maintainer zhaochengcheng
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
进行编译

然后这里我们需要配置maven的国内源,这样的话就比较快一点

代码语言:javascript
复制
[root@k8s-master CI]# vim /etc/maven/settings.xml

<mirror>
    <id>centralid>
    <mirrorOf>centralmirrorOf>
    <name>aliyun mavenname>
    <url>https://maven.aliyun.com/repository/publicurl>
  mirror>
mirrors>

[root@k8s-master tomcat-java-demo-master]# mvn clean package -D maven test.skip=true
[root@k8s-master tomcat-java-demo-master]# ls
db  Dockerfile  LICENSE  pom.xml  README.md  src  target
[root@k8s-master tomcat-java-demo-master]# cd target/
[root@k8s-master target]# ls
classes  generated-sources  ly-simple-tomcat-0.0.1-SNAPSHOT  ly-simple-tomcat-0.0.1-SNAPSHOT.war  maven-archiver  maven-status
[root@k8s-master tomcat-java-demo-master]# cd target/

我们就使用这个编译好的war包,然后打成镜像,上传到我们的Harbor仓库里

代码语言:javascript
复制
[root@k8s-master target]# ls
classes            ly-simple-tomcat-0.0.1-SNAPSHOT      maven-archiver
generated-sources  ly-simple-tomcat-0.0.1-SNAPSHOT.war  maven-status

[root@k8s-master tomcat-java-demo-master]# docker build -t 192.168.30.24/library/java-demo:latest .
然后上传到我们的镜像仓库
代码语言:javascript
复制
[root@k8s-master tomcat-java-demo-master]# docker login 192.168.30.24
Username: admin
Password: 
Error response from daemon: Get https://192.168.30.24/v2/: dial tcp 192.168.30.24:443: connect: connection refused

这里报错,其实我们需要在每台docker下都要写入对harbor仓库的信任才可以,后面上传镜像也会用

代码语言:javascript
复制
[root@k8s-master java-demo]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["http://f1361db2.m.daocloud.io"],
        "insecure-registries": ["192.168.30.24"]
}

再等录一下push就可以了

代码语言:javascript
复制
[root@k8s-master tomcat-java-demo-master]# docker push 192.168.30.24/library/java-demo:latest
控制器管理pod

编写deployment,一般项目都写到自定义的命名空间下,名称写项目名称,方便记忆,

代码语言:javascript
复制
name: tomcat-java-demo
namespace: test

另外就是下一个项目名称,这里分为多个,一般有很多的组件组成,所以下面可以写个app的名称,比如组件1、2、3,起码标签有这两个维度

代码语言:javascript
复制
project: www
app: java-demo

另外就是镜像拉取,在哪个仓库去下载,这里我建议镜像仓库的项目名称和我们定义的是一种,避免混了 我重新打个标签,并传到我们的私有镜像仓库中

代码语言:javascript
复制
[root@k8s-master java-demo]# docker tag 192.168.30.24/library/java-demo  192.168.30.24/tomcat-java-demo/java-demo  
[root@k8s-master java-demo]# docker push 192.168.30.24/tomcat-java-demo/java-demo:latest

镜像地址也改一下地址

代码语言:javascript
复制
imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: tomcat
        image: 192.168.30.24/tomcat-java-demo/java-demo:latest

现在开始创建我们的yaml 创建项目的命名空间

代码语言:javascript
复制
[root@k8s-master java-demo]# vim namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: test

[root@k8s-master java-demo]# kubectl create -f namespace.yaml 
namespace/test created
[root@k8s-master java-demo]# kubectl get ns
NAME              STATUS   AGE
default           Active   22h
kube-node-lease   Active   22h
kube-public       Active   22h
kube-system       Active   22h
test              Active   5s

创建一个secret来保证我们harbor镜像仓库的认证信息,这里一定要写上我们的项目的命名空间

代码语言:javascript
复制
[root@k8s-master java-demo]# kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 --docker-email=111@qq.com --docker-server=192.168.30.24 -n test
secret/registry-pull-secret created
[root@k8s-master java-demo]# kubectl get ns
NAME              STATUS   AGE
default           Active   23h
kube-node-lease   Active   23h
kube-public       Active   23h
kube-system       Active   23h
test              Active   6m39s
[root@k8s-master java-demo]# kubectl get secret
NAME                   TYPE                                  DATA   AGE
default-token-2vtgm    kubernetes.io/service-account-token   3      23h
registry-pull-secret   kubernetes.io/dockerconfigjson        1      46s

[root@k8s-master java-demo]# vim deployment.yaml 
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      project: www
      app: java-demo
  template:
    metadata:
      labels:
        project: www
        app: java-demo
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: tomcat
        image: 192.168.30.24/tomcat-java-demo/java-demo:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        resources:
          requests:
cpu: 0.5
            memory: 1Gi
          limits:
            cpu: 1
            memory: 2Gi
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 20
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 20

[root@k8s-master java-demo]# kubectl get pod -n test
NAME                                READY   STATUS    RESTARTS   AGE
tomcat-java-demo-6d798c6996-fjjvk   1/1     Running   0          2m58s
tomcat-java-demo-6d798c6996-lbklf   1/1     Running   0          2m58s
tomcat-java-demo-6d798c6996-strth   1/1     Running   0          2m58s

另外就是暴露一个Service,这里的标签也要保持一致,不然他找不到相应的标签就提供不了服务,这里我们是使用ingress来访问发布应该,直接使用ClusterIP就可以

代码语言:javascript
复制
[root@k8s-master java-demo]# vim service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  selector:
    project: www
    app: java-demo
  ports:
  - name: web
    port: 80
    targetPort: 8080

[root@k8s-master java-demo]# kubectl get pod,svc -n test
NAME                                    READY   STATUS    RESTARTS   AGE
pod/tomcat-java-demo-6d798c6996-fjjvk   1/1     Running   0          37m
pod/tomcat-java-demo-6d798c6996-lbklf   1/1     Running   0          37m
pod/tomcat-java-demo-6d798c6996-strth   1/1     Running   0          37m

NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/tomcat-java-demo   ClusterIP   10.1.175.191   <none>        80/TCP    19s

测试访问我们的项目,是可以的,现在要发布出去通过ingress

代码语言:javascript
复制
[root@k8s-master java-demo]# curl 10.1.175.191
DOCTYPE html>
<html>
<head lang="en">
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>把美女带回家应用案例title>
 <meta name="description" content="把美女带回家应用案例">
 <meta name="keywords" content="index">

现在部署一个ingress-nginx的控制器,这个网上都可以找到,官方也有,我这里是按DaemonSet的方式去部署的,所以每个节点都会跑一个控制器

代码语言:javascript
复制
[root@k8s-master java-demo]# kubectl get pod -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-g95pp   1/1     Running   0          3m6s
nginx-ingress-controller-wq6l6   1/1     Running   0          3m6s
发布应用

这里注意两点,第一个就是网站域名,一个是service的命名空间

代码语言:javascript
复制
[root@k8s-master java-demo]# kubectl get pod,svc -n test
NAME                                    READY   STATUS    RESTARTS   AGE
pod/tomcat-java-demo-6d798c6996-fjjvk   1/1     Running   0          53m
pod/tomcat-java-demo-6d798c6996-lbklf   1/1     Running   0          53m
pod/tomcat-java-demo-6d798c6996-strth   1/1     Running   0          53m

NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/tomcat-java-demo   ClusterIP   10.1.175.191   <none>        80/TCP    16m
[root@k8s-master java-demo]# vim service.yaml 
[root@k8s-master java-demo]# kubectl create -f ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-java-demo
  namespace: test
spec:
  rules:
    - host: java.maidikebi.com
      http:
        paths:
        - path: /
          backend:
            serviceName: tomcat-java-demo
            servicePort: 80

另外我这边是测试的,所以绑定我本地的hosts来进行访问 在hosts文件里面加入域名和和节点ip就能访问到我们的项目了

from https://blog.51cto.com/u_14143894/2437186

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yangyidba 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 控制器管理pod
  • Pod数据持久化
  • 暴露应用
  • 对外发布应用
  • 传统部署与K8S部署区别
  • 部署一个JAVA项目到k8s中
    • 安装一个openjdk还是maven用来编译
      • 进行编译
        • 然后上传到我们的镜像仓库
          • 控制器管理pod
            • 发布应用
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档