helm系列之-构建自己的Helm Chart

构建自己的Helm Chart

一般常见的应用(nginx、wordpress等)公有的helm仓库都提供了chart,可以直接安装或者自定义安装。下面实践从零构建自己的helm chart应用。

准备工作

准备一个用于部署测试的应用镜像并推送到镜像仓库。

应用代码

这里使用python基于flask开发一个web服务器,该服务通过读取环境变量 USERNAME 获得用户自己定义的名称,然后监听 80 端口。对于任意 HTTP 请求,返回 Hello ${USERNAME}。比如如果设置USERNAME=world(默认场景),该服务会返回 Hello world。

创建app.py,内容如下:

from flask import Flask
import osapp = Flask(__name__)@app.route("/", methods=["GET"])
def hello():username = os.getenv("USERNAME", "world")return f"Hello {username}!"if __name__ == "__main__":app.run(host="0.0.0.0", port=80)

构建容器镜像

  1. 创建Dockerfile
# 使用官方 Python 基础镜像
FROM python:3.10-slim# 设置工作目录
WORKDIR /app# 复制当前目录内容到工作目录
COPY . /app# 安装依赖
RUN pip install --no-cache-dir Flask -i https://mirrors.aliyun.com/pypi/simple/# 设置环境变量
ENV USERNAME world# 暴露应用运行的端口
EXPOSE 80# 运行 Flask 应用
CMD ["python", "app.py"]
  1. 构建容器镜像
root@master1:~/hello# docker build -t my-hello .
  1. 将镜像推送到harbor
root@master1:~/hello# docker tag docker.io/library/my-hello:latest harbor.test.com/library/my-hello:v1.0
root@master1:~/hello# docker push harbor.test.com/library/my-hello:v1.0

在 Docker 构建好镜像之后,我们把镜像上传到仓库中,可以使私有镜像harbor,或者公有仓库比如 Docker Hub 或是阿里云容器镜像仓库。

构建应用的helm chart

应用的容器镜像已经构建推送到仓库,接下来我们创建应用的helm chart。

创建helm chart

使用以下命令创建一个新的 Helm Chart:

helm create my-hello

这个命令会生成一个名为 my-hello 的目录,里面包含了 Helm Chart 的基本结构。my-hello 目录的结构如下:

root@master1:~/hello# helm create my-hello
Creating my-hello
root@master1:~/hello# tree my-hello/
my-hello/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

需要注意的是,Chart 里面的 my-hello名称需要和生成的 Chart 文件夹名称一致。如果修改 my-hello,则需要做一致的修改。

编辑 Chart.yaml

在根目录下的 Chart.yaml 文件内,声明了当前 Chart 的名称、版本等基本信息,这些信息会在该 Chart 被放入仓库后,供用户浏览检索。

编辑 Chart.yaml 文件,定义 Chart 的元数据:

apiVersion: v2
name: my-hello
description: My hello app Helm chart for Kubernetes      # helm chart描述信息# 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: 1.0   #Chart 的版本# 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"   # 应用的版本
编辑 values.yaml

根目录下有一个values.yaml文件,这个文件提供了应用在安装时的默认参数。编辑 values.yaml 文件,定义 Chart 的默认值:

replicaCount: 1image:repository: harbor.test.com/library/my-hellopullPolicy: IfNotPresenttag: "v1.0"service:type: ClusterIPport: 80
...
Username: helm

这里主要修改values.yaml内的 image.repository,image.tag,并添加Username: helm。其他保持默认。

values.yaml 下面还包括资源设置、健康检查、autoscaling、卷挂载等其他设置,根据需求进行设置即可。

编辑模板文件

templates文件夹内存放了应用部署所需要使用的YAML文件,比如DeploymentService。在我当前的应用内,只需要一个 deployment,而有的应用可能包含不同组件,需要多个deployment,就需要在 templates 文件夹下放置不同deployment的YAML文件。同样serviceaccountsecretvolumes 等内容,也可以在里面添加相应的配置文件。

在这些YAML文件中的参数数值是由上述的Values.yaml提供的。

  1. 编辑templates/deployment.yaml

增加env部分:

...containers:- name: {{ .Chart.Name }}securityContext:{{- toYaml .Values.securityContext | nindent 12 }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"imagePullPolicy: {{ .Values.image.pullPolicy }}env:- name: USERNAMEvalue: {{ .Values.Username }}
...
  1. 编辑 templates/service.yaml

保持默认,无需修改:

apiVersion: v1
kind: Service
metadata:name: {{ include "my-hello.fullname" . }}labels:{{- include "my-hello.labels" . | nindent 4 }}
spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: httpprotocol: TCPname: httpselector:{{- include "my-hello.selectorLabels" . | nindent 4 }}

打包应用

校验打包

使用Helm lint校验Chart有无语法问题。

root@master1:~/hello/my-hello# ls
charts  Chart.yaml  templates  values.yaml
root@master1:~/hello/my-hello# helm lint
==> Linting .
[ERROR] Chart.yaml: version should be of type string but it's of type float64
[INFO] Chart.yaml: icon is recommendedError: 1 chart(s) linted, 1 chart(s) failed
# 上面提示,version应该为string,而不是float64。将Chart.yaml中的version字段改为字符串,version: "1.0"。重新校验通过:
root@master1:~/hello/my-hello# helm lint
==> Linting .
[INFO] Chart.yaml: icon is recommended1 chart(s) linted, 0 chart(s) failed

或者在上一级目录校验,注意当前位置:

root@master1:~/hello# helm lint --strict my-hello
==> Linting my-hello
[INFO] Chart.yaml: icon is recommended1 chart(s) linted, 0 chart(s) failed
打包

使用helm package对已经创建好的chart应用进行打包,即得到我们厂家的tgz格式的chart包。

root@master1:~/hello# helm package ./my-hello/
Successfully packaged chart and saved it to: /root/hello/my-hello-1.0.tgz
root@master1:~/hello# ls
app.py  Dockerfile  my-hello  my-hello-1.0.tgz

部署 Chart进行测试

使用以下命令部署你创建的 Helm Chart:

helm install my-hello my-hello-1.0.tgz

这个命令会在 Kubernetes 集群中部署 my-hello 应用。

root@master1:~/hello# helm install my-hello my-hello-1.0.tgz
NAME: my-hello
LAST DEPLOYED: Sat Jul 13 21:21:58 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-hello,app.kubernetes.io/instance=my-hello" -o jsonpath="{.items[0].metadata.name}")export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT# 查看部署的my-hello资源,并进行测试 
root@master1:~/hello# kubectl get pod
NAME                              READY   STATUS             RESTARTS         AGE
my-hello-6b696d4bdd-58pvh         1/1     Running            0                7sroot@master1:~/hello# kubectl get svc
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
kubernetes       ClusterIP      10.96.0.1        <none>          443/TCP                      22d
my-hello         ClusterIP      10.103.187.93    <none>          80/TCP                       22sroot@master1:~/hello# curl 10.103.187.93
Hello helm!root@master1:~/hello#

也可以根据部署后的提示,配置端口转发到宿主机的8080端口进行测试:

# 依次执行如下命令
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-hello,app.kubernetes.io/instance=my-hello" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

此时节点处于监听8080端口状态,任何访问8080端口的流量都会转发到my-hello容器的80端口 :

root@master1:~/hello# kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80# 再打开一个节点的ssh会话进行curl测试
root@master1:~/my-wordpress# curl localhost:8080
Hello helm!

参数重载

应用开发者在 Chart 的 values 配置中只是提供了默认的安装参数,用户也可以在安装时指定自己的配置,通过set参数传递参数。如果应用已经部署,可以用upgrade命令替代install,实现在原有部署好的应用的基础上变更配置。

# 全新安装
helm install my-hello my-hello-1.0.tgz --set Username="K8S"
# 也可以通过配置文件进行传参
helm install my-hello2 my-hello-1.0.tgz -f my-values.yaml
# 升级更新。基于新的value.yaml或者set更新参数
helm upgrade my-hello my-hello-1.0.tgz -f my-new-values.yaml
helm upgrade my-hello my-hello-1.0.tgz --set Username="K8S"

修改提示信息

部署chart后的提示信息来自templates目录下的NOTES.txt文件:

root@master1:~/hello/my-hello/templates# cat NOTES.txt
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}{{- range .paths }}http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-hello.fullname" . }})export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}NOTE: It may take a few minutes for the LoadBalancer IP to be available.You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "my-hello.fullname" . }}'export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "my-hello.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "my-hello.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")echo "Visit http://127.0.0.1:8080 to use your application"kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

根据需要可以自定义输出。

清理部署

如果你不再需要这个部署,可以使用以下命令删除它:

# 查询部署的信息
root@master1:~# helm ls
NAME         NAMESPACE    REVISION   UPDATED                                 STATUS     CHART              APP VERSION
my-hello     default      1          2024-07-13 21:21:58.121466781 +0800 CST deployed   my-hello-1.0        1.16.0# 卸载
helm uninstall my-hello

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

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

相关文章

Linux 命令个人学习笔记

1. 操作目录的命令 (1) ls : 查看指定目录中, 都有哪些内容 直接输入 ls 是查看当前目录中的内容. 还可以给 ls 后面加上一个路径(绝对/相对), 就可以查看指定目录中的内容 比如看根目录(刚安装Centos下) ls / 根目录的地位类似于Java中的Object ls -l 详细查看当前文件的内容…

(十一) Docker compose 部署 Mysql 和 其它容器

文章目录 1、前言1.1、部署 MySQL 容器的 3 种类型1.2、M2芯片类型问题 2、具体实现2.1、单独部署 mysql 供宿主机访问2.1.1、文件夹结构2.1.2、docker-compose.yml 内容2.1.3、运行 2.2、单独部署 mysql 容器供其它容器访问&#xff08;以 apollo 为例&#xff09;2.2.1、文件…

pyinstaller教程(二)-快速使用(打包python程序为exe)

1.介绍 PyInstaller 是一个强大的 Python 打包工具&#xff0c;可以将 Python 程序打包成独立的可执行文件。以下会基于如何在win系统上将python程序打包为exe可执行程序为例&#xff0c;介绍安装方式、快速使用、注意事项以及特别用法。 2.安装方式 通过 pip 安装 PyInstal…

万界星空科技MES系统:食品加工安全的实时监控与智能管理

万界星空科技MES系统通过集成多种技术和功能&#xff0c;能够实时监控食品加工过程中各环节的安全风险。以下是对该系统如何实现实时监控的详细分析&#xff1a; 一、集成传感器和数据分析技术 万界星空科技MES系统利用集成的传感器和数据分析技术&#xff0c;实时监控生产过程…

基于SSM的校园一卡通管理系统的设计与实现

摘 要 本报告全方位、深层次地阐述了校园一卡通管理系统从构思到落地的整个设计与实现历程。此系统凭借前沿的 SSM&#xff08;Spring、Spring MVC、MyBatis&#xff09;框架精心打造而成&#xff0c;旨在为学校构建一个兼具高效性、便利性与智能化的一卡通管理服务平台。 该系…

数学建模入门

目录 文章目录 前言 一、数学建模是什么&#xff1f; 1、官方概念&#xff1a; 2、具体过程 3、适合哪一类人参加&#xff1f; 4、需要有哪些学科基础呢&#xff1f; 二、怎样准备数学建模&#xff08;必备‘硬件’&#xff09; 1.组队 2.资料搜索 3.常用算法总结 4.论文撰写的…

微前端解决方案

在实施微前端架构时&#xff0c;前端框架和技术的选型是非常重要的。不同的框架和技术有着不同的优缺点&#xff0c;需要结合具体的应用场景进行选择。一、常见的微前端解决方案 Web Components Web Components&#xff08;包括Custom Elements、Shadow DOM和HTML Imports&…

数据建设实践之大数据平台(一)准备环境

大数据组件版本信息 zookeeper-3.5.7hadoop-3.3.5mysql-5.7.28apache-hive-3.1.3spark-3.3.1dataxapache-dolphinscheduler-3.1.9大数据技术架构 大数据组件部署规划 node101node102node103node104node105datax datax datax ZK ZK ZK RM RM NM

HTML网页大设计-家乡普宁德安里

代码地址: https://pan.quark.cn/s/57e48c3b3292

Layer2是什么?为什么需要Layer2?

目录 什么是Layer1需要Layer2的原因概念结构图Layer2有哪些风险 什么是Layer1 要了解Layer2前&#xff0c;需要先了解下Layer1。 一层网络&#xff08;Layer 1 Network&#xff09;通常指的是区块链技术中的主链或基础层&#xff0c;它提供了区块链的核心功能和特性。以下是一…

二分图——AcWing 257. 关押罪犯

目录 二分图 定义 运用情况 注意事项 解题思路 AcWing 257. 关押罪犯 题目描述 运行代码 代码思路 改进思路 二分图 定义 二分图&#xff08;Bipartite Graph&#xff09;是一种特殊的图&#xff0c;在这种图中&#xff0c;顶点可以被分成两个互不相交的集合&…

C语言 | Leetcode C语言题解之第233题数字1的个数

题目&#xff1a; 题解&#xff1a; int countDigitOne(int n) {// mulk 表示 10^k// 在下面的代码中&#xff0c;可以发现 k 并没有被直接使用到&#xff08;都是使用 10^k&#xff09;// 但为了让代码看起来更加直观&#xff0c;这里保留了 klong long mulk 1;int ans 0;f…

硬盘HDD:AI时代的战略金矿?

在这个AI如火如荼的时代&#xff0c;你可能以为硬盘HDD已经像那些过时的诺基亚手机一样&#xff0c;被闪存和云存储淘汰到历史的尘埃里。但&#xff0c;别急着给HDD们举行退休派对&#xff0c;因为根据Finis Conner这位硬盘界的传奇人物的说法&#xff0c;它们非但没退场&#…

MATLAB算法实战应用案例精讲-【数模应用】Lasso回归(套索回归)(附MATLAB、R语言和Python代码实现)

目录 知识储备 拟合 (一): 过拟合与欠拟合 (二): 常用解决办法 几个高频面试题目 岭回归与套索回归的比较: 5种常见回归类型及属性 算法原理 为什么要用LASSO套索回归? 应用场景 与普通最小二乘法的区别 数学模型 lasso回归 - 梯度下降(在线性回归后加上L1正则项…

Linux进程——子进程详解

文章目录 查看进程的另一种方式如何创建子进程fork函数详解fork函数的用法fork函数做了什么为什么fork有两个返回值父子进程的运行顺序是什么样的为什么fork函数的两个返回值不同 在上一节中我们简单介绍了进程的概念&#xff0c;还有父进程和子进程 这篇文章的主要内容是介绍…

eNsp公司管理的网络NAT策略搭建

实验拓扑图 实验需求&#xff1a; 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带…

护网HW面试——redis利用方式即复现

参考&#xff1a;https://xz.aliyun.com/t/13071 面试中经常会问到ssrf的打法&#xff0c;讲到ssrf那么就会讲到配合打内网的redis&#xff0c;本篇就介绍redis的打法。 未授权 原理&#xff1a; Redis默认情况下&#xff0c;会绑定在0.0.0.0:6379&#xff0c;如果没有采用相关…

暴雨让服务器不怕热҈热҈热҈热҈

在AI算力呈几何倍数增长的趋势下&#xff0c;算力逐渐朝着“高性能、高密度、高耗能“发展。在高耗能的算力下&#xff0c;AI服务器功率已逐步逼近风冷散热极限&#xff0c;而液冷作为更加高效、低能耗的制冷技术&#xff0c;逐渐成为了高密度算力散热场景的首选方案。 液冷的…

网络安全----防御----防火墙nat以及智能选路

前面要求在前一篇博客 网络安全----防御----防火墙安全策略组网-CSDN博客 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的ht…

Jenkins中Node节点与构建任务

目录 节点在 Jenkins 中的主要作用 1. 分布式构建 分布式处理 负载均衡 2. 提供不同的运行环境 多平台支持 特殊环境需求 3. 提高资源利用率 动态资源管理 云端集成 4. 提供隔离和安全性 任务隔离 权限控制 5. 提高可扩展性 横向扩展 高可用性 Jenkins 主服务…