01 打包部署server-openapi-zuul镜像

打包部署server-openapi-zuul镜像

prerequisite

  • jdk8镜像(提供jre8环境,alpine国内源,添加fonts,修改默认时区等)
  • java应用基础镜像模板(Dockerfile模板+java程序启动脚本+初始化参数)

调整k8s-jenkins中agent的资源限制

可能会遇到jnlp出现oom的情况,需要调整下jenkins agent默认的资源限制

[root@jingmin-kube-archlinux k8s]# cat jenkins/my-override-values.yaml 
#...
agent:
  enabled: true
  resources:
    requests:
      cpu: "1024m"
      memory: "1024Mi"
    limits:
      cpu: "2048m"
      memory: "2048Mi"
#...

[root@jingmin-kube-archlinux k8s]# helm upgrade -n jenkins jenkins -f jenkins/my-override-values.yaml ./jenkins

Kubernetes CLI插件配置

参考: https://plugins.jenkins.io/kubernetes-cli/#plugin-content-parameters-with-kubeconfig-file

参考: https://www.jenkins.io/doc/pipeline/steps/kubernetes-cli/

安装Kubernetes CLI插件

方法一: (使用kubeconfig)

导出kubeconfig

kubectl config view --minify --flatten > kubeconfig

新建credential

image-20230923131037057

方法二: (使用token,k8s v1.21之后已失效)

添加token配置文件,作为credential

参考: https://plugins.jenkins.io/kubernetes-cli/#plugin-content-generating-kubernetes-credentials

注意,高版本v1.21之后,token方式义失效

Kubernetes 1.21以前版本的集群中,Pod中获取Token的形式是通过挂载ServiceAccount的Secret来获取Token,这种方式获得的Token是永久的。该方式在1.21及以上的版本中不再推荐使用,并且根据社区版本迭代策略,在1.25及以上版本的集群中,ServiceAccount将不会自动创建对应的Secret。

参考:https://support.huaweicloud.com/usermanual-cce/cce_10_0477.html

如果是在k8s中的pod中执行kubectl命令,可以不提供credential给Kubernetes CLI插件

参考: https://plugins.jenkins.io/kubernetes-cli/#plugin-content-parameters-when-running-inside-a-pod

参考: https://plugins.jenkins.io/kubernetes-cli/#plugin-content-usage-when-running-inside-a-pod

Config File Provider插件配置

Dashboard->Manage Jenkins->Managed files->Add new Config

创建名为service-k8s.yaml的配置文件

Dashboard->Manage Jenkins->Managed Files

创建service-k8s.yaml配置文件

apiVersion: apps/v1
kind: Deployment
##元数据信息
metadata:
  name: <PROJECT_NAME>
  ##命名空间
  namespace: <NAME_SPACE>
  labels:
    app: <PROJECT_NAME>
spec:
  selector:
    matchLabels:
      app : <PROJECT_NAME>
  ##设置历史版本数量
  revisionHistoryLimit: 2
  ##滚动升级策略
  ##Kubernetes在等待设置的时间后才进行升级
  minReadySeconds: 5
  strategy:
    #    type: Recreate
    type: RollingUpdate
    rollingUpdate:
      ## 升级过程最多可以比原先设置多出的POD数量 Kubernetes会先启动1一个新的Pod后才删掉一个旧的
      maxSurge: 1
      ## 升级过程中最多有多少个POD处于无法提供服务的状态
      maxUnavailable: 1
  ##代表2个副本
  replicas: 1
  template:
    metadata:
      labels:
        app: <PROJECT_NAME>
    spec:
      #affinity:
      #  nodeAffinity:
      #    requiredDuringSchedulingIgnoredDuringExecution:
      #      nodeSelectorTerms:
      #        -  matchExpressions:
      #             -  key: node_env
      #                operator: In
      #                values:
      #                  - jtest
      ##重启策略
      #      Always:当容器失效时,由kubelet自动重启该容器。
      #      OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
      #      Never:不论容器运行状态如何,kubelet都不会重启该容器。
      restartPolicy: Always
      ##挂载容器外面
      #      volumes:
      #        - name: <PROJECT_NAME>-log
      #          hostPath:
      ##            type: Directory
      #            path: /applogs/<NAME_SPACE>
      imagePullSecrets:
        - name: harbor-secret
      containers:
        ##容器名称
        - name: <PROJECT_NAME>-container
          ##镜像拉取策略
          imagePullPolicy: Always
          ##容器镜像地址
          image: harbor.ole121238.cn/<repoNamespace>/<PROJECT_NAME>:<BUILD_TAG>
          ## 环境变量设置
          env:
            - name: TZ
              value: Asia/Shanghai
            ##元数据获取POD名称到环境变量
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: SRV_NAME
              value: <PROJECT_NAME>
          #          lifecycle:
          #            postStart:
          #              exec:
          #                command:
          #                  - /bin/sh
          #                  - '-c'
          #                  - >-
          #                    rm -rf /applogs &&
          #                    mkdir -p /home/mount/<NAME_SPACE>/${POD_NAME} && ln -s
          #                    /home/mount/<NAME_SPACE>/${POD_NAME}
          #                    /applogs
          ##  containerPort 容器监听端口 、hostPort 容器所在主机监听端口
          ports:
            - name: <PORT_NAME>-con-port
              containerPort: <projectPort>
          ##挂载容器
          #          volumeMounts:
          #            - mountPath: /home/mount/<NAME_SPACE>
          ##              subPath: server-zuul.log
          #              name: <PROJECT_NAME>-log
          ##资源限制和请求限制
          resources:
            ##请求限制容器启动的初始可用CPU/内存
            requests:
              memory: <REQUEST_MEMORY>
              cpu: <REQUEST_CPU>
            ##资源请求限制
            limits:
              memory: <LIMIT_MEMORY>
              cpu: <LIMIT_CPU>
            ##健康检查
            #(就绪检查)可读探针会去连接容器的8067端,如果连接成功,则该 Pod 将被标记为就绪状态。
            #然后Kubelet将每隔10秒钟执行一次该检查
          readinessProbe:
            tcpSocket:
              port: <projectPort>
            ##指定kubelet在该执行第一要等待5秒钟。
            initialDelaySeconds: 30
            periodSeconds: 20
            timeoutSeconds: 5
            ##(存活检查)存活探针容器启动15秒后,去尝试连接容器的8067端,如果liveness probe失败,容器将重新启动
          livenessProbe:
            tcpSocket:
              port: <projectPort>
            initialDelaySeconds: 240
            periodSeconds: 20
            timeoutSeconds: 5

---

#添加自动弹性扩缩容
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: <PROJECT_NAME>-autoscal
  namespace: <NAME_SPACE>
spec:
  maxReplicas: 2
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: <PROJECT_NAME>
  targetCPUUtilizationPercentage: 80

---
apiVersion: v1
kind: Service
metadata:
  ##定义服务名称
  name: <SERVICE_NAME>
  namespace: <NAME_SPACE>
  labels:
    app: <PROJECT_NAME>
spec:
  selector:
    ##这里对应上面定义的labels标签
    app: <PROJECT_NAME>
    ##service类型:
    ## ClusterIp : 集群内部IP暴露服务
    ## NodePort : 通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务
    ## LoadBalancer 使用云提供商的负载局衡器,可以向外部暴露服务
    ## ExternalName 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)
  clusterIP: None
  ##端口号设置
  ports:
    - protocol: TCP
      port: <projectPort>
      targetPort: <projectPort>
      name: <PORT_NAME>-service-port

注意到插件自动为其分配了个id,我这边是

cbb3823e-3c04-4834-9de4-15e0b15770d2

创建创建名为Dockerfile的配置文件

Dashboard->Manage Jenkins->Managed Files

创建名为Dockerfile的配置文件

#基础镜像
FROM  harbor.ole12138.cn/wy_spc/java:latest
#维护者信息
MAINTAINER wangjm
##配置环境变量参数
ARG CONFIG_ENV
##初始化堆内存
ARG INIT_HEAP_MOMERY
##最大堆内存
ARG MAX_HEAP_MOMERY
##配置NACOS命名空间
ARG NACOS_NAMESPACE
##配置NACOS服务访问地址
ARG NACOS_SERVER
ENV CONFIG_ENV=$CONFIG_ENV
ENV NACOS_NAMESPACE=$NACOS_NAMESPACE
ENV INIT_HEAP_MOMERY=$INIT_HEAP_MOMERY
ENV MAX_HEAP_MOMERY=$MAX_HEAP_MOMERY
ENV NACOS_SERVER=$NACOS_SERVER
##系统语言环境设置
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
#将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
ADD  ./app/app.jar /app.jar
#COPY  ./app.sh   /
#RUN  sh -c 'touch /app.jar'
#     chmod 777 /app.sh
#指定外界交互的端口
#EXPOSE 9021
##配置容器,使其可执行化。配合CMD可省去"application",只使用参数。
#ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","$INIT_HEAP_MOMERY", "$MAX_HEAP_MOMERY","-jar","/app.jar","--config.profile=$CONFIG_ENV"]

#CMD  sh  /app.sh  $INIT_HEAP_MOMERY $MAX_HEAP_MOMERY  "-Dconfig.profile=$CONFIG_ENV -Dspring.cloud.nacos.discovery.namespace=$NACOS_NAMESPACE -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE -Dspring.cloud.nacos.server-addr=$NACOS_SERVER"
CMD  sh  /app.sh  "-XX:+UseContainerSupport" "-XX:MaxRAMPercentage=70.0 -XX:InitialRAMPercentage=45.0 -XX:MinRAMPercentage=45.0 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m"  "-Dconfig.profile=$CONFIG_ENV -Dspring.cloud.nacos.discovery.namespace=$NACOS_NAMESPACE -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE -Dspring.cloud.nacos.server-addr=$NACOS_SERVER"

创建配置文件的时候,同样自动为我们自动生成了一个文件id,我这边是

478d3df3-0a15-4c44-ba94-5c83c28cf56e

这里改了一下基础镜像, 注意开头的语句FROM harbor.ole12138.cn/wy_spc/java:latest

备份仓库

新建本地分支

git checkout master
git checkout -b jtest

新建远程仓库

gitee新建私有仓库server-openapi-h5-zuul

上传分支

git remote add jingmin https://gitee.com/ole12138/server-openapi-zuul.git

# jtest分支设置上游分支,并推送
git push -u jingmin jtest
git push -u jingmin master:master

git checkout develop
git push -u jingmin develop:develop

git checkout jtest

# 推送所有(本地)分支到新仓库
#git push --all jingmin

# 推送所有分支到新仓库(会多个HEAD临时分支)
git push jingmin +refs/remotes/origin/*:refs/heads/*
# 删除远程分支HEAD
git push jingmin --delete HEAD

调整配置

调整springcloud的bootstrap.yml

#spring.cloud.nacos.server-addr=nacos.c253e0c129d8f453a82dfb1ae4ba19613.cn-shenzhen.alicontainer.com:80
spring.cloud.nacos.server-addr=nacos-headless.nacos.svc.cluster.local:8848
spring.cloud.nacos.discovery.group=woyun
spring.cloud.nacos.discovery.namespace=765fa359-2e1b-41f3-a4b2-17c3856764fe
spring.cloud.nacos.config.namespace=765fa359-2e1b-41f3-a4b2-17c3856764fe
spring.cloud.nacos.config.group=woyun
spring.cloud.nacos.config.shared-configs[0].data-id=redis.properties
spring.cloud.nacos.config.shared-configs[0].group=woyun
spring.cloud.nacos.config.shared-configs[1].data-id=application.properties
spring.cloud.nacos.config.shared-configs[1].group=woyun
spring.cloud.nacos.config.shared-configs[2].data-id=rabbitmq.properties
spring.cloud.nacos.config.shared-configs[2].group=woyun

# 服务名
spring.application.name=OPENAPI-GATEWAY

# 端口,端口规划-可用端口:8061~8069
server.port=8067

主要调整nacos地址和命名空间

本地调试

telepresence connect

试运行

没问题的话提交修改

git add *.properties
git commit -m "jtest分支配置”

部署自动化发布

  • 登录Jenkins
  • new Item, 选择pipeline, 名称为server-openapi-zuul (这个自动化pipeline的Jenkins是根据项目名称匹配的远程仓库)
  • 配置pipeline

pipeline通用配置

discard old build, 保留2个

This project is parameterized -> Choice Parameter-> name: branchName, Choices只有一个 **/jtest

pipeline具体配置

  • pipeline defination: pipeline script from SCM
    • SCM: git
      • repositories: https://gitee.com/ole12138/delopy-k8s.git
      • credentials: xxx/xxx
      • branchToBuild: */jtest
      • Addtional behaviors:
        • Sparse Checkout paths: service/jtest/Jenkinsfile
        • Checkout to sub-directory: jenkins
      • Script Path: service/jtest/Jenkinsfile

应用并保存

build with parameters。 选中choice开始构建。

构建成功后到k8s中看下jtest空间是否有对应的depoyment及pod跑起来。

nacos 看下服务列表jtest空间下有没有出现新的服务


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注