第 6 篇 自定义 Helm Chart
文章目录
- 第 1 步:创建 chart
- Chart.yaml
- values.yaml
- templates 模板文件
- _helpers.tpl 模板辅助文件
- serviceaccount.yaml
- service.yaml
- deployment.yaml
- hpa.yaml
- ingress.yaml
- NOTES.txt
- tests/test-connection.yaml
- 第 2 步:检查 chart 格式
- 第 3 步:模拟运行
- 第 4 步:打包并上传到仓库
- 打包并上传
- 生成 index.yaml 并上传
- 生成仅一个 chart 的 index.yaml
- 合并生成 index.yaml
- 相关博文
🚀 本文内容:如何创建一个属于自己的 chart。
⭐ 详细步骤:
- 使用 helm create mychart 创建 chart,chart 名称为 mychart,默认为 nginx
- 修改 chart,以满足实际的自定义需求
- 使用 helm lint mychart 检查格式
- 使用 helm install 模拟运行/实际运行 chart,验证是否满足功能要求
- 打包并生成 index.yaml
下面的例子,创建一个 Nginx chart。默认创建的 chart 是以 nginx 为例的。
第 1 步:创建 chart
使用 helm create mychart 创建 chart:
helm create mychart
# Creating mychart
查看创建的目录及文件:
mychart/Chart.yamlvalues.yamltemplates/deployment.yamlhpa.yamlingress.yamlserviceaccount.yamlservice.yaml_helpers.tpl # 可被复用的 chart 模板辅助对象NOTES.txttests/test-connection.yamlcharts/
Chart.yaml
内容不多:
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
type: application
# chart 版本
version: 0.1.0
# nginx 版本
appVersion: "1.16.0"
values.yaml
可以看到,有很多是默认就存在的配置。
- replicaCount:副本数量
- image:容器镜像相关
- serviceAccount:服务账号
- podAnnotations、podSecurityContext:Pod 相关
- securityContext:安全上下文
- service、ingress
- resources、autoscaling
- nodeSelector、tolerations、affinity
# Default values for mychart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.replicaCount: 1image:repository: nginxpullPolicy: IfNotPresent# Overrides the image tag whose default is the chart appVersion.tag: ""imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""serviceAccount:# Specifies whether a service account should be createdcreate: true# Annotations to add to the service accountannotations: {}# The name of the service account to use.# If not set and create is true, a name is generated using the fullname templatename: ""podAnnotations: {}podSecurityContext: {}# fsGroup: 2000securityContext: {}# capabilities:# drop:# - ALL# readOnlyRootFilesystem: true# runAsNonRoot: true# runAsUser: 1000service:type: ClusterIPport: 80ingress:enabled: falseclassName: ""annotations: {}# kubernetes.io/ingress.class: nginx# kubernetes.io/tls-acme: "true"hosts:- host: chart-example.localpaths:- path: /pathType: ImplementationSpecifictls: []# - secretName: chart-example-tls# hosts:# - chart-example.localresources: {}# We usually recommend not to specify default resources and to leave this as a conscious# choice for the user. This also increases chances charts run on environments with little# resources, such as Minikube. If you do want to specify resources, uncomment the following# lines, adjust them as necessary, and remove the curly braces after 'resources:'.# limits:# cpu: 100m# memory: 128Mi# requests:# cpu: 100m# memory: 128Miautoscaling:enabled: falseminReplicas: 1maxReplicas: 100targetCPUUtilizationPercentage: 80# targetMemoryUtilizationPercentage: 80nodeSelector: {}tolerations: []affinity: {}
templates 模板文件
_helpers.tpl 模板辅助文件
_helpers.tpl 是一个模板辅助文件,比如最常见的 chart 名称的处理。
{{/*
Expand the name of the chart.
*/}}
{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "mychart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}{{/*
Common labels
*/}}
{{- define "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.chart" . }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}{{/*
Selector labels
*/}}
{{- define "mychart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "mychart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}{{/*
Create the name of the service account to use
*/}}
{{- define "mychart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "mychart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
serviceaccount.yaml
创建 ServiceAccount:
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:name: {{ include "mychart.serviceAccountName" . }}labels:{{- include "mychart.labels" . | nindent 4 }}{{- with .Values.serviceAccount.annotations }}annotations:{{- toYaml . | nindent 4 }}{{- end }}
{{- end }}
service.yaml
创建 Service:
apiVersion: v1
kind: Service
metadata:name: {{ include "mychart.fullname" . }}labels:{{- include "mychart.labels" . | nindent 4 }}
spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: httpprotocol: TCPname: httpselector:{{- include "mychart.selectorLabels" . | nindent 4 }}
deployment.yaml
创建 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:name: {{ include "mychart.fullname" . }}labels:{{- include "mychart.labels" . | nindent 4 }}
spec:{{- if not .Values.autoscaling.enabled }}replicas: {{ .Values.replicaCount }}{{- end }}selector:matchLabels:{{- include "mychart.selectorLabels" . | nindent 6 }}template:metadata:{{- with .Values.podAnnotations }}annotations:{{- toYaml . | nindent 8 }}{{- end }}labels:{{- include "mychart.selectorLabels" . | nindent 8 }}spec:{{- with .Values.imagePullSecrets }}imagePullSecrets:{{- toYaml . | nindent 8 }}{{- end }}serviceAccountName: {{ include "mychart.serviceAccountName" . }}securityContext:{{- toYaml .Values.podSecurityContext | nindent 8 }}containers:- name: {{ .Chart.Name }}securityContext:{{- toYaml .Values.securityContext | nindent 12 }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"imagePullPolicy: {{ .Values.image.pullPolicy }}ports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /port: httpreadinessProbe:httpGet:path: /port: httpresources:{{- toYaml .Values.resources | nindent 12 }}{{- with .Values.nodeSelector }}nodeSelector:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.affinity }}affinity:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.tolerations }}tolerations:{{- toYaml . | nindent 8 }}{{- end }}
hpa.yaml
创建 HorizontalPodAutoscaler:
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:name: {{ include "mychart.fullname" . }}labels:{{- include "mychart.labels" . | nindent 4 }}
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: {{ include "mychart.fullname" . }}minReplicas: {{ .Values.autoscaling.minReplicas }}maxReplicas: {{ .Values.autoscaling.maxReplicas }}metrics:{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}- type: Resourceresource:name: cputargetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}{{- end }}{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}- type: Resourceresource:name: memorytargetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}{{- end }}
{{- end }}
ingress.yaml
创建 Ingress:
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "mychart.fullname" . -}}
{{- $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 }}labels:{{- include "mychart.labels" . | nindent 4 }}{{- with .Values.ingress.annotations }}annotations:{{- toYaml . | nindent 4 }}{{- end }}
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 }}
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 "mychart.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 the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "mychart.fullname" . }}'export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mychart.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 "mychart.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 }}
tests/test-connection.yaml
Chart Test,用于测试验证 chart 是否按预期运行。也可以具体划分下,放在 tests 目录下【这样可以定义更多的 Test,且能更好的与模板隔离开】。
test 放在 templates/ 目录下,其会指定容器并执行特定的任务,任务的定义必须包含测试钩子的注释:"helm.sh/hook": test。
test 本质就是一个 Helm 钩子,所以类似于 helm.sh/hook-weight和 helm.sh/hook-delete-policy的注释也可用于 test。
apiVersion: v1
kind: Pod
metadata:name: "{{ include "mychart.fullname" . }}-test-connection"labels:{{- include "mychart.labels" . | nindent 4 }}annotations:"helm.sh/hook": test
spec:containers:- name: wgetimage: busyboxcommand: ['wget']args: ['{{ include "mychart.fullname" . }}:{{ .Values.service.port }}']restartPolicy: Never
运行方式:
helm install demo demo --namespace default# 执行 Chart 测试
helm test demo
第 2 步:检查 chart 格式
helm lint mychart/
# ==> Linting mychart/
# [INFO] Chart.yaml: icon is recommended
#
# 1 chart(s) linted, 0 chart(s) failed
第 3 步:模拟运行
helm install 时添加 – dry-run,即可模拟运行。命令如下:
helm install --debug --dry-run goodly-guppy ./mychart
运行日志如下:
- 重点1:Release 基本信息
- 重点2:Values 数据,用户提供的 Values + 最终计算得出的 Values
- 重点3:helm hooks,这里是 test 钩子,执行连接测试的
- 重点4:实际运行的 Kubernetes manifest
- 重点5:打印出的 NOTES.txt (已使用模板渲染过)
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /home/userlocal/mychart#### 重点1:Release 基本信息
NAME: goodly-guppy
LAST DEPLOYED: Mon May 27 14:28:22 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1#### 重点2:Values 数据,用户提供的 Values + 最终计算得出的 Values
USER-SUPPLIED VALUES:
{}COMPUTED VALUES:
affinity: {}
autoscaling:enabled: falsemaxReplicas: 100minReplicas: 1targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:pullPolicy: IfNotPresentrepository: nginxtag: ""
imagePullSecrets: []
ingress:annotations: {}className: ""enabled: falsehosts:- host: chart-example.localpaths:- path: /pathType: ImplementationSpecifictls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:port: 80type: ClusterIP
serviceAccount:annotations: {}create: truename: ""
tolerations: []#### 重点3:helm hooks,这里是 test 钩子,执行连接测试的
HOOKS:
---
# Source: mychart/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:name: "goodly-guppy-mychart-test-connection"labels:helm.sh/chart: mychart-0.1.0app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppyapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helmannotations:"helm.sh/hook": test
spec:containers:- name: wgetimage: busyboxcommand: ['wget']args: ['goodly-guppy-mychart:80']restartPolicy: Never#### 重点4:实际运行的 Kubernetes manifest
MANIFEST:
---
# Source: mychart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: goodly-guppy-mychartlabels:helm.sh/chart: mychart-0.1.0app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppyapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:name: goodly-guppy-mychartlabels:helm.sh/chart: mychart-0.1.0app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppyapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
spec:type: ClusterIPports:- port: 80targetPort: httpprotocol: TCPname: httpselector:app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppy
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: goodly-guppy-mychartlabels:helm.sh/chart: mychart-0.1.0app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppyapp.kubernetes.io/version: "1.16.0"app.kubernetes.io/managed-by: Helm
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppytemplate:metadata:labels:app.kubernetes.io/name: mychartapp.kubernetes.io/instance: goodly-guppyspec:serviceAccountName: goodly-guppy-mychartsecurityContext:{}containers:- name: mychartsecurityContext:{}image: "nginx:1.16.0"imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /port: httpreadinessProbe:httpGet:path: /port: httpresources:{}#### 重点5:打印出的 NOTES.txt (已使用模板渲染过)
NOTES:
1. Get the application URL by running these commands:export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=goodly-guppy" -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
模拟运行或实际运行符合预期后,即可打包上传到仓库了。
第 4 步:打包并上传到仓库
打包并上传
先进行打包,打包后手动将 mychart-0.1.0.tgz 上传到 chart 仓库。
# 第 1 步:打包:未做签名哦
helm package mychart/
# Successfully packaged chart and saved it to: /home/userlocal/mychart-0.1.0.tgz# 第 2 步:移动到 mychart/:不移动的话,后面生成的 index.yaml 是空的!!!
mv mychart-0.1.0.tgz mychart/
生成 index.yaml 并上传
生成 index.yaml 有两种方式:
- 直接生成,index.yaml 里只有一个 chart
- 合并生产,根据现有仓库的 index.yaml,添加当前 chart 进去
生成仅一个 chart 的 index.yaml
命令如下:
# 生成 index.yaml
helm repo index mychart/ --url http://nexus.hengtiansoft.space/repository/helm-repo/# 查看 index.yaml
cat mychart/index.yaml
# apiVersion: v1
# entries:
# mychart:
# - apiVersion: v2
# appVersion: 1.16.0
# created: "2024-05-27T15:01:22.810201593+08:00"
# description: A Helm chart for Kubernetes
# digest: 0a07369207529008da67a724dda35b86b4721b3dfe9dffcabb2ce767c2267b9d
# name: mychart
# type: application
# urls:
# - http://nexus.hengtiansoft.space/repository/helm-repo/mychart-0.1.0.tgz
# version: 0.1.0
# generated: "2024-05-27T15:01:22.808723439+08:00"
合并生成 index.yaml
# 跳转到 chart 目录
cd mychart/# 下载仓库 index.yaml
wget http://nexus.xxx.space/repository/helm-repo/index.yaml# 合并生成 index.yaml
helm repo index . --merge index.yaml# 查看合并生成的 index.yaml
cat index.yaml | grep -A 5 mychart
# mychart:
# - apiVersion: v2
# appVersion: 1.16.0
# created: "2024-05-27T15:09:00.3621419+08:00"
# description: A Helm chart for Kubernetes
# digest: 0a07369207529008da67a724dda35b86b4721b3dfe9dffcabb2ce767c2267b9d
# name: mychart
# type: application
# urls:
# - mychart-0.1.0.tgz
# version: 0.1.0
# mysql:
# - apiVersion: v1
# appVersion: 8.0.33
# created: "2023-10-30T02:54:37.437Z"
如果你使用 Nexus 作为 chart 仓库,则直接上传 chart tgz 包,然后 Rebuild Index 即可刷新 index.yaml 文件。
相关博文
1.第 1 篇 Helm 简介及安装
2.第 2 篇 Helm 部署 MySQL【入门案例】
3.第 3 篇 Helm 命令、环境变量、相关目录
4.第 4 篇 Chart 仓库详解
5.第 5 篇 Chart 文件结构详解
6.第 6 篇 自定义 Helm Chart
7.第 7 篇 Helm 部署 Nacos【详细步骤】
8.第 8 篇 Chart 修改入门示例:Nacos
9.第 9 篇 Helm 部署 Seata Server
10.第 10 篇 Chart 修改完美示例:Seata Server
11.第 11篇 Helm 部署 RabbitMQ
12.第 12 篇 Helm 部署 Redis
13.第13 篇 Helm 部署 ElasticSearch
相关文章:
第 6 篇 自定义 Helm Chart
文章目录 第 1 步:创建 chartChart.yamlvalues.yamltemplates 模板文件_helpers.tpl 模板辅助文件serviceaccount.yamlservice.yamldeployment.yamlhpa.yamlingress.yamlNOTES.txttests/test-connection.yaml 第 2 步:检查 chart 格式第 3 步:…...
Jenkis部署vue前端项目提示:sh: vue-cli-service: command not found
解决方法: 1. 进入到/var/lib/jenkins/workspace/项目名下,查看是否有node_modules,如果没有执行 npm install 2. 如果执行npm intall的过程中提示:npm ERR! 407 Proxy Authentication Required - GET http://registry.npm.taob…...
中介者模式mediator
学习笔记,原文链接 https://refactoringguru.cn/design-patterns/mediator 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。...
GO语言性能分析
Go语言基准测试与pprof工具性能分析详解 在现代软件开发中,性能优化是一个重要的环节。Go语言提供了强大的工具来进行基准测试和性能分析,其中 testing 包用于基准测试,而 pprof 工具用于性能分析。本文将详细讲解如何使用这些工具来进行性能…...
关于 PreparedStatement
Mysql 层面的语法也支持 prepare 这个确实第一次见 PREPARE prepares a statement for execution (see Section 13.5.1, “PREPARE Statement”).EXECUTE executes a prepared statement (see Section 13.5.2, “EXECUTE Statement”).DEALLOCATE PREPARE releases a prepared…...
漫谈设计模式 [9]:外观模式
引导性开场 菜鸟:老鸟,我最近在做一个项目,感觉代码越来越复杂,我都快看不懂了。尤其是有好几个子系统,它们之间的调用关系让我头疼。 老鸟:复杂的代码确实让人头疼。你有没有考虑过使用设计模式来简化你…...
多进程编程
基本概念 进程是一个具有单独功能的程序对某个数据集在处理机上的执行过程,进程也是作为资源分配的一个单位。 进程和程序是相辅相成的,进程是一个动态概念。 进程具有并行性特征。进程具有独立性和异步性。 进程的描述 进程分为三部分:…...
7-Zip压缩包如何添加密码,加密后如何取消
压缩包文件大家经常使用,最熟悉的肯定是RAR、ZIP格式压缩文件,但是7z压缩文件格式也很好用,它是三种压缩文件格式中压缩率最大的。想要将文件压缩到最小,使用7z格式可以达到最大化。那么在使用7z压缩格式的时候,我们可…...
HarmonyOS---应用测试概述
一、应用质量要求 应用质量要求分为应用体验质量建议和应用内容合规要求两大部分。 1、应用体验质量建议 功能数据完备、基础体验要求、HarmonyOS特征增强体验要求。 (1)功能数据完备 (2)基础体验要求 (3)增…...
密码学---真题演练
✨Base加密:题目-base? 靶场网址:https://polarctf.com/ Base100加密!!! 得到的新的一串密码是 rot47 密码,属于凯撒密码的一种变体. ✨斐波那契:题目-FB 从第三项开始,每一项都等…...
时间日期工具类
时间日期工具类 import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit;public class DateTimeUtils {private static final String DEFAULT_DATE_FORMAT "yyyy-MM-dd";private static final String DEFAULT_TIME_…...
linux中vim常用命令大全
前言 Linux有大量的配置文件,所以 Linux的文本处理工具也是比较多的,其中编辑一些配置文件时,常用的工具就是 vim。在Linux中,Vim编辑器是一个非常强大的文本编辑工具,它提供了多种模式和命令来满足不同的编辑需求。以…...
计算机的错误计算(八十九)
摘要 探讨反双曲余切函数 acoth(x) 在 附近的计算精度问题。 Acoth(x) 函数的定义为: 其中 x 的绝对值大于 1 . 例1. 计算 acoth(1.000000000002) . 不妨在 Excel 的单元格中计算,则有: 若在Python中用定义直接计算,则有几乎…...
深入理解java并发编程之aqs框架
跟synchronized 相比较,可重入锁ReentrankLock其实原理有什么不同? 所得基本原理是为了达到一个目的;就是让所有线程都能看到某种标记。synchronized通过在对象头中设置标记实现了这一目的,是一种JVM原生的锁实现方式。而Reentran…...
ubuntu配置tftp、nfs
tftp配置 tftp是简单文件传输协议,基于udp实现传输。这里的简单文件,指的是不复杂、开销不大的文件。 先在ubuntu中安装tftp,输入命令:sudo apt-get install tftp-hpa tftpd-hpa。 接着配置tftp。 输入命令:sudo v…...
Sklearn的datasets模块与自带数据集介绍
datasets 模块 用 dir() 函数查看 datasets 模块的所有属性和函数 import sklearn.datasets as datasets# 列出 sklearn.datasets 模块中的所有属性和函数 print(dir(datasets)) datasets 模块下的数据集有三种类型: (1)load系列的经典数…...
css 个人喜欢的样式 速查笔记
起因, 目的: 记录自己喜欢的, 觉得比较好看的 css. 下次用的时候,直接复制,很方便。 1. 个人 html 模板, 导入常用的 link 设置英语字体: Noto导入默认的 css使用网络 icon 图标导入 Bootstrap css 框架 html <…...
C/C++ let __DATE__ format to “YYYY-MM-DD“
C/C let DATE format to “YYYY-MM-DD” code: #include <iostream> #include <string>class compileDate {// 静态函数,用来格式化并返回编译日期 static std::string formatCompileDate() {// 编译时的日期,格式为 "MMM…...
git如何灵活切换本地账号对应远程github的两个账号
git如何灵活切换本地账号对应远程github的两个账号 问题: 有时候我们会同时维护两个github的账号里面的仓库内容,这时候本地git需要频繁的切换ssh,以方便灵活的与两个账号的仓库可以通信。这篇日记将阐述我是怎么解决这个问题的。1. 第一个账…...
Python中实现函数的递归调用
在Python中,函数的递归调用是一种非常强大且常用的编程技巧,它允许函数在其执行过程中调用自身。递归调用在解决许多问题时都显得尤为方便,比如遍历树形结构、计算阶乘、实现快速排序等。然而,递归也需要谨慎使用,因为…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
