第 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中,函数的递归调用是一种非常强大且常用的编程技巧,它允许函数在其执行过程中调用自身。递归调用在解决许多问题时都显得尤为方便,比如遍历树形结构、计算阶乘、实现快速排序等。然而,递归也需要谨慎使用,因为…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果