第 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中,函数的递归调用是一种非常强大且常用的编程技巧,它允许函数在其执行过程中调用自身。递归调用在解决许多问题时都显得尤为方便,比如遍历树形结构、计算阶乘、实现快速排序等。然而,递归也需要谨慎使用,因为…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...