Devops系列二(使用helm chart,将java应用发布部署至k8s的示例)

news2024/12/23 11:46:55

一、接着上一篇的话

docker镜像已经有了,本文我们将接着演示如何使用helm部署应用到k8s。
分为两大部分:

  • 制作helm chart,推送到私有仓库nexus
  • helm拉取chart,部署到k8s

二、制作helm chart

要求你先安装helm,随便一台linux机器即可,不要求你要有k8s或者docker环境。

xxx@local:~/Downloads$ wget https://get.helm.sh/helm-v3.12.1-linux-amd64.tar.gz
--2023-06-30 10:49:03--  https://get.helm.sh/helm-v3.12.1-linux-amd64.tar.gz
正在解析主机 get.helm.sh (get.helm.sh)... 152.199.39.108, 2606:2800:247:1cb7:261b:1f9c:2074:3c
正在连接 get.helm.sh (get.helm.sh)|152.199.39.108|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 16036346 (15M) [application/x-tar]
正在保存至: “helm-v3.12.1-linux-amd64.tar.gz”

helm-v3.12.1-linux- 100%[===================>]  15.29M  1.19MB/s    用时 13s   

2023-06-30 10:49:18 (1.14 MB/s) - 已保存 “helm-v3.12.1-linux-amd64.tar.gz” [16036346/16036346])

xxx@local:~/Downloads$ tar -xf helm-v3.12.1-linux-amd64.tar.gz 

xxx@local:~/Downloads$ sudo mv linux-amd64/helm /usr/local/bin/helm
[sudo] xxx 的密码: 

xxx@local:~/Downloads$ helm version
version.BuildInfo{Version:"v3.12.1", GitCommit:"f32a527a060157990e2aa86bf45010dfb3cc8b8d", GitTreeState:"clean", GoVersion:"go1.20.4"}

xxx@local:~/Downloads$ helm repo list
NAME       URL                               
bitnami    https://charts.bitnami.com/bitnami

1、创建helm模板

helm creta java

在这里插入图片描述这里,我删除了没用到的一些文件,最后保留的见下:
在这里插入图片描述
templates下的三个文件就是对应K8S容器的三个yaml,没有什么好说的,helm这里额外增加了一个values.yaml文件,它是用来替换templates下的yaml文件里的变量。

那有人要问了,values.yaml文件里的变量可以替换吗?

在helm install的时候,你仍然可以替换values.yaml中的变量。所以我这设计的所有java应用,不同的环境,都使用同一个helm chart。

不同应用存在环境的差异,这个问题也就因此解决了。

2. deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.appName }}
  namespace: {{ .Values.namespace }}
  labels:
    app: {{ .Values.appName }}
spec:
  progressDeadlineSeconds: 600
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: {{ .Values.appName }}
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        app: {{ .Values.appName }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets: 
        {{- toYaml . | nindent 8 }}
      {{- end }}
      containers:
        - name: {{ .Values.appName }}
          env:
            - name: TZ
              value: Asia/Shanghai
            - name: APPNAME
              value: {{ .Values.appName }}
            - name: CONFIG_SERVICE_ADDR
              value: {{ .Values.env.configServiceAddr }}
            - name: CONFIG_SERVICE_NAMESPACE
              value: {{ .Values.env.configServiceNameSpace }}
            - name: CONFIG_SERVICE_GROUP
              value: {{ .Values.env.configServiceGroup }}
            - name: CONFIG_EPHEMERAL
              value: 'false'
            - name: CONFIG_SERVICE_ENABLED
              value: '{{ .Values.env.configServiceEnabled }}'
            - name: spring.cloud.nacos.config.accessKey
              value: {{ .Values.env.configAccessKey }}
            - name: spring.cloud.nacos.config.secretKey
              value: {{ .Values.env.configSecretKey }}
            - name: spring.cloud.nacos.discovery.accessKey
              value: {{ .Values.env.configAccessKey }}
            - name: spring.cloud.nacos.discovery.secretKey
              value: {{ .Values.env.configSecretKey }}
            - name: JAVA_OPTS
              value: {{ .Values.env.javaOpts }}

          image: "{{ .Values.image.repository }}{{ .Values.appName }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /mgm/health
              port: {{ .Values.service.port }}
              scheme: HTTP
            initialDelaySeconds: 1
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 3
          startupProbe:
            failureThreshold: 22
            httpGet:
              path: /mgm/health
              port: {{ .Values.service.port }}
              scheme: HTTP
            initialDelaySeconds: 25
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 5
          resources:
            limits:
              cpu: {{ .Values.resource.limitCpu }}
              memory: {{ .Values.resource.limitMemory }}
            requests:
              cpu: {{ .Values.resource.requestCpu }}
              memory: {{ .Values.resource.requestMemory }}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

3、values.yaml

# Default values for java.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

namespace: java-service

appName: devops-service

replicaCount: 1

env:
  javaOpts: 
  # consul
  configServiceEnabled: true
  configServiceHost: 192.168.10.19
  configServicePort: 8500
  # nacos
  configServiceAddr: 192.168.5.28:8848
  configServiceNameSpace: a5fdc665-4267-462e-9b03-d363984d9963
  configServiceGroup: DEFAULT_GROUP
  configAccessKey:
  configSecretKey:

image:
  repository: 192.168.5.6:8086/xxx/
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: 1.0.7

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""


podAnnotations: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

service:
  type: NodePort
  port: 8085

ingress:
  enabled: false
  className: "nginx"
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: devops-service.ztyedu.net
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resource:
  limitCpu: '2'
  limitMemory: 2Gi
  requestCpu: 250m
  requestMemory: 2Gi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

4. service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ .Values.appName }}
  namespace: {{ .Values.namespace }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.port }}
      protocol: TCP
      name: {{ .Values.appName }}
  selector:
    app: {{ .Values.appName }}
  sessionAffinity: None

5、 ingress.yaml

{{- if .Values.ingress.enabled -}}
{{- $fullName := .Values.appName -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
  {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
  {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
  {{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ $fullName }}
  namespace: {{ .Values.namespace }}
spec:
  {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
  ingressClassName: {{ .Values.ingress.className }}
  {{- end }}
  {{- if .Values.ingress.tls }}
  tls:
    {{- range .Values.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}
                port:
                  number: {{ $svcPort }}
              {{- else }}
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
              {{- end }}
          {{- end }}
    {{- end }}
{{- end }}

6、Chart.yaml

version是helm chart的版本号,应用的版本号见values.yaml文件中的image.tag(每次构建版本号都会追加1)

apiVersion: v2
name: java
description: java demo

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.8

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

三、推送chart至helm私库

1、添加 helm repo

xxx@local:~$ helm repo list
NAME    URL                               
bitnami https://charts.bitnami.com/bitnami

# 新增helm仓库
xxx@local:~$ helm repo add nexus http://150xxxx9916:123456@192.168.5.6:8081/repository/xh-helm/
"nexus" has been added to your repositories

xxx@local:~$ helm repo list
NAME    URL                                                           
bitnami https://charts.bitnami.com/bitnami                            
nexus   http://150xxxx9916:123456@192.168.5.6:8081/repository/xh-helm/

2、安装helm推送插件

xxx@local:~$ helm plugin install --version master https://gitee.com/mirrors_sonatype-nexus-community/helm-nexus-push.git
Installed plugin: nexus-push

3、构建并推送

# 构建chart
xxx@local:~/Downloads$  helm package java
Successfully packaged chart and saved it to: /home/xxx/Downloads/java-0.1.8.tgz

# 推送chart到私有仓库
xxx@local:~/Downloads$ helm nexus-push nexus java-0.1.8.tgz -u 150xxxx9916 -p 123456
Pushing java-0.1.8.tgz to repo http://150xxxx9916:123456@192.168.5.6:8081/repository/xh-helm//...
  HTTP/1.1 100 Continue
  
  HTTP/1.1 200 OK
  Date: Fri, 30 Jun 2023 10:16:44 GMT
  Server: Nexus/3.37.3-02 (OSS)
  X-Content-Type-Options: nosniff
  Content-Security-Policy: sandbox allow-forms allow-modals allow-popups allow-presentation allow-scripts allow-top-navigation
  X-XSS-Protection: 1; mode=block
  Content-Length: 0
  
Done

四、总结

登录nexus,查看上传的chart。

在这里插入图片描述
在这里插入图片描述
可以看到,chart上传成功。
接下里,就是我们在k8s的控制台,将在下一篇文章进行描述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/721972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rust 第四天—Rust进阶1

上一篇介绍了Rust的所有权特性,今天就把剩下一些之前没介绍但项目中常用的内容总结一下. 结构体泛型trait 1 结构体 和c语言一样,Rust使用struct关键字来定义一个结构体,结构体可以将不同的类型数据进行整合,加快内存访问速度. 1.1 结构体定义 struct Test{username:Strin…

【第四天学习】决策分支,判断语录

决策分支 If语句 If语句是对基础的一种选择结构语句,它主要有三种形式,分别是if语句,if else语句和if else If else多分支语句。 int nCheck 0; if(nNum4) { nCheck4; } else { nCheck8; }If语句其实就是一个判断语句,它会判断…

详细解释lvs的工作原理

vsl用于集群中的直接路由它的原理如下 如果在公司并发太高了怎么解决 1.加配置cpu 内存 带宽 ssd高效硬盘 2.加服务器 为用户提供服务 横向扩展 集群是什么 由的多台主机构成,相当于一台大型计算机,只提供一个访问入口(域名与ip地址) 集群用在那个场景 高并发场景 vrrp是…

linux下删除ARP缓存表【网络工程】(保姆级图文)

目录 linux下删除ARP缓存表总结 欢迎关注 『网络工程专业』 系列,持续更新中 欢迎关注 『网络工程专业』 系列,持续更新中 温馨提示:对虚拟机做任何设置,建议都要先快照备份! linux下删除ARP缓存表 这里老师的命令ip…

docker的安装和使用

1.新建一个项目 比如vue init vuelatest完事之后运行打包到build目录下 2.在项目根目录下通过执行命令 touch Dockerfile 3.拉取nginx镜像 首先打开你的Docker,默认会启动。控制台拉取 Nginx 镜像:运行 docker pull nginx4.在根目录创建Nginx配置文件…

【多线程】锁策略

1. 说在前面 这里的锁策略内容,属于典型的面试八股文!如果未来工作,需要实现一把锁,那么得好好研究下锁策略,但基本上不会让我们自己设计一把锁的。 而这里的锁策略内容不局限于 Java,任何 "锁" …

python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)

简介 有些 post 的请求参数是 json 格式的,这个前面发送post 请求里面提到过,需要导入 json模块处理。现在企业公司一般常见的接口因为json数据容易处理,所以绝大多数返回数据也是 json 格式的,我们在做判断时候,往往只…

golang 实现四层负载均衡

大家好,我是蓝胖子,做开发的同学应该经常听到过负载均衡的概念,今天我们就来实现一个乞丐版的四层负载均衡,并用它对mysql进行负载均衡测试,通过本篇你可以了解到零拷贝的应用,四层负载均衡的本质以及实践。…

代码模版-element plus如何进行前端校验输入框

文章目录 步骤一:引入 element plus 框架步骤二:使用 element plus 的 form步骤三:form 明确指定 rules步骤四:事件触发校验 使用 vue3 element plus 步骤一:引入 element plus 框架 先 npm 安装 在 src/main.js 中…

linux[armbian]环境安装nginx

文章目录 linux[armbian]环境安装常用命令遇到的问题和解决方法问题一:conf/koi-win复制错误解决方法问题二:缺少相关的日志目录解决方法 linux[armbian]环境安装 下载Nginx: 访问[Nginx官方网站](https://nginx.org/)&#xff0c…

排序算法(1):冒泡排序

在计算机科学领域,排序算法是一个重要的主题。冒泡排序法是最基础且简单的排序算法之一,它的原理简单易懂,是学习排序算法的理想起点。本文将详细介绍冒泡排序法的原理、实现方法以及优化技巧,帮助读者全面了解和掌握这一经典算法…

重新安装conda时报错

自己因为最近利用 conda 安装了比较多的软件,在输入创建环境时: conda create -n python27 python2.7 报错,环境创建不成功。 显示 miniconda3 文件夹已存在 (因为安装时会默认安装至此目录,如果此目录已经存在则会冲突报错&…

【基础算法】贪心算法

贪心算法又称贪婪算法,是一种常见的算法思想。贪心算法的优点是效率高,实现较为简单,缺点是可能得不到最优解。 贪心算法的基本思想 贪心算法就是在求解问题时,总是做出当前看来最好的选择。也就是说贪心算法并不从整体最优上考…

word转PDF后图片为何会变小?怎么解决?

有些同学反映将Word文档转换为PDF后,发现里面的图片居然变小了,这是什么原因造成的?该怎么解决呢? 先来说说原因,我个人认为可能是由以下原因造成的: 1、word插入图片后压缩“太狠”了。当你在word中插入…

GENMARK控制器维修S08S4P.D工业电脑维修

机器人GENMARK SYSTEM CONTROLLER系统控制器维修S08S4P.D工业电脑;晶圆转移机器人SΛΛALL CONTROLLER; SΛΛC1100 半导体设备机械臂GENMARK控制器等 GenMark的两大构架:eSensor(电子传感)和Elecitrowetting&#xf…

ibaq intensity 蛋白组学 蛋白质组学两个定量方法(iBAQ和LFQ)的区别及常见的标准化方法

4.MaxQuant中的Intensity,LFQ和iBAQ 大佬的软件,三种定量算法都发了文章。 Intensity是将某Protein Groups里面的所有Unique和Razor peptides的信号强度加起来,作为一个原始强度值。用得很少。iBAQ是在Intenstiy的基础上,将原始…

JUC#线程池加锁逻辑梳理

带着问题看源码 为什么要用线程池?Java是实现和管理线程池有哪些方式? 请简单举例如何使用。为什么很多公司不允许使用Executors去创建线程池? 那么推荐怎么使用呢?ThreadPoolExecutor有哪些核心的配置参数? 请简要说明ThreadPoolExecutor可以创建的是哪三种线程池呢?当…

【Web3】Web3Js高频Api

目录 Web3Js方法 初始化Web3实例 Web3Api 创建账号Api 获取余额Api 单位转换工具函数 Web3Js方法 web3.eth:用于与以太坊区块链和智能合约之间的交互。 web3.utils:包含一些辅助方法。 web3.shh:用于协议进行通信的P2P和广播。 web3…

1066 Root of AVL Tree (PAT甲级)

这道题类似1123题。 #include <cstdio> #include <algorithm>struct node{int key;node* left nullptr;node* right nullptr; };int N, t; node* root nullptr;int getHeight(node* r){if(!r){return 0;}return std::max(getHeight(r->left), getHeight(r-&…

【json-server】json-server安装与使用:

文章目录 一、下载安装:二、启动db.json数据及相关参数&#xff1a;三、创建json数据——db.json&#xff1a;四、修改端口号&#xff1a;五、操作数据&#xff1a;【1】常规获取&#xff1a;【2】过滤获取 Filter:【3】分页 Paginate&#xff1a;【4】排序 Sort&#xff1a;【…