Auf dem richtigen Kurs mit最佳实践für Helm-Charts

Kubernetes, das beliebte Orchestrierungswerkzeug für Containeranwendungen, ist nach dem griechischen Wort für“Lotse”benannt,也称为demjenigen, der das Schiff steuert。阿贝尔·贝·吉德·瑞斯·康恩·德·领航员与他一起死去verfügbare卡特。
达斯舵-卡特的图表,也叫萨姆隆·达泰恩,死亡·埃纳姆Helm-Chart-Repository, das einen zusammenhängenden Satz von k8s - resource beschreibt, eingesetzt werden können。Wenn Sie Ihre Helm-Charts auf die effektivste Art and Weise gestalten, hilft dies Kubernetes, durch die Untiefen zu manövrieren, Wenn es Container in Ihrer production sumgebung bereitstellt。
阿贝尔的gibt auch andere Möglichkeiten, wie ich bei der Entwicklung von öffentlich zugänglichen K8s-Charts zum部署von产品的最佳效果。Mit jeder Pull-Anfrage hat mir das Feedback der Helm-Community geholfen,bewährte Verfahren für Helm-Chartszu finden, mit denen die besten Ergebnisse für Nutzung和Aktualisierung von Containern sichergestellt wurden。
爱因格·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德·德祖登丁根,安die Sie denken müssen, gehört:
- Welche Abhängigkeiten müssen Sie definieren?
- Benötigt Ihre Anwendung einen persistenten Zustand,嗯zu funktionieren?
- 我的手和你的死都是一样的?
- Wie kontrollieren Sie die Ausführung von Kubelet-Containern?
- Wie stellen Sie sicher, dass Ihre Anwendungen laufen and Anrufe empfangen können?
- 我的墓碑上的世界Verfügung?
- 你的Ihr表是什么?
diesel Leitfaden bietet einige Best Practices zur Strukturierung and Spezifikation Ihrer Helm-Charts, die K8s dabei helfen, Ihre Container-Anwendungen reibungslos in Dock zu bringen。
奥地利第一储蓄Schritte
Bevor Sie begin, stellen Sie sicher, dass Sie mit den wesentlichen Verfahren zurEntwicklung von Helm-Chartsvertraut信德。
在《舵图》中,《舵图最佳实践》中Erstellen, Lesen, Aktualisieren und Löschen-Anwendung (创建,读取,更新和删除= CRUD) für die Mongo-Datenbank unter Verwendung von Express.js bereitzustellen。
你在BeispielanwendungGitHub中的express-crud.
Das Helm-Chart erstellen und ausfüllen
Lassen Sie uns das Vorlagen-Helm-Chart mitcreate-Befehldes Helm-Client erstellen:
$ helm create express-crud
达杜尔奇wideine Verzeichnisstruktur für einexpress-crud-Helm-Chart erstellt。
Aktualisieren Sie zunächst die Chart-Metadaten in derChart.yaml-Datei, die gerade erstellt wurde。steellen Sie sicher, dass Sie die richtigen Informationen fürappVersion(die Anwendungsversion, die als Docker-Image-Tag verwendet werden soll),描述,版本(静脉SemVer 2-Versionsstring),来源,维护人员和图标eingeben。
apiVersion: v1 appVersion:“1.0.0”描述:Ein Helm-Chart für die express-crud - anwendung名称:express-crud版本:0.1.0来源:- https://github.com/jainishshah17/express-mongo-crud维护者:-名称:myaccount邮箱:myacount@mycompany.com图标:https://github.com/mycompany17/mycompany.com/blob/master/app/public/images/logo.jpg home: https://mycompany.com/
Definieren von Abhängigkeiten
Wenn Ihre AnwendungAbhangigkeiten帽子,dann müssen Sie einerequirements.yaml-《舵图》中的datei, die diese spezifiziert。Da unsere安文东死mongodb-Datenbank benötigt, müssen在derAbhangigkeiten-Liste derrequirements.yaml-Datei spezifiziren, die wir erstellen。
风景明信片requirements.yamlfür dieses Beispiel enthält:
依赖项:—name: mongodb version: 3.0.4 repository: https://kubernetes-charts.storage.googleapis.com/ condition: mongodb.enabled
Sobald风景明信片requirements.yaml-Datei erstellt ist, müssen Sie den依赖项更新-Befehl im Helm-Client ausführen:
$ helm dep update
Deployment-Dateien erstellen
Die Deployment-Dateien Ihres helm - chart在此找到\模板-Unterverzeichnis und geben an, wie K8s die Container-Anwendung bereitstellt。
德国国家部署-日期müssen欧洲国家部署-日期。
部署对象im Vergleich zum statefulset对象
Welche部署- datei Sie erstellen, hängt davon ab, ob es die Anwendung erforderlich macht, dass K8s Sie als部署- object oder alsStatefulSet-Objektverwaltet。
Ein部署-对象ist eine zustandslose Anwendung, die im Dateinamendeployment.yamlDeklariert ist und die种类参数肌萎缩性侧索硬化症部署spezifiziert。
Ein state - objekt ist für Anwendungen, die zustandsabhängig sind und mit verteilten Systemen verwendet werden。we werden im Dateinamenstateless.yamlDeklariert und spezifizieren den种类参数肌萎缩性侧索硬化症有状态.
| 部署 | StatefulSet |
| 部署信德für die zustandslose Nutzung gedacht und eher leichtgewichtig。 | statfulsets werden verwendet, wenn der Zustand persistent muss。长音了volumeClaimTemplatesauf persistenten Volumes verwendet, um sicherzustellen, dass sie den Status über Komponenten-Neustarts hinweg beibehalten können。 |
| Wenn Ihre Anwendung zustandslos ist oder Wenn der Zustand während des Starts aus后端系统aufgebaut werden kann, dann verwenden Sie部署。 | Wenn Ihre Anwendung zustandsabhängig ist oder Wenn Sie zustandsabhängigen Speicher über Kubernetes bereitstellen möchten, verwenden Sie ein StatefulSet。 |
大北柴油,安文东,德Zustand, nht,坚持,verwende ich,在部署对象。
死deployment.yaml-Datei ist bereits durch den执掌创建-Befehl erstellt worden。
Wir werden AppVersion als Docker-Image-Tag für unsere Anwendung verwenden。达达尔奇信风在德国,舵图在德国安文东和德国,舵图在德国Chart.yamlandern
image: "{{. values .image. "存储库}}:{{默认的。chart。AppVersion .Values.image。标签}}”
秘密im Vergleich zu ConfigMap
Sie müssen festlegen, welche der Anmeldeinformationen oder konfigationsdaten geeignet sinind,嗯Sie als秘密Zu speichern, and welche in einerConfigMapEnthalten sein können。
秘密信德für明智的信息伟Passwörter,死K8s在einem verschlüsselten格式speichert。
配置表数据配置信息,密码密码können。Die Informationen in einer ConfigMap sinind nicht verschlüsselt, sollten also keine sensiblen Informationen enthalten。
| 秘密 | ConfigMap |
| Diese Informationen in ein Secret zu packen ist sicherer und flexibler als sie wortwörtlich in eine Pod-Definition oder in ein Docker-Image zu packen; | Mit einer ConfigMap können Sie konfigationsartefakte vom Image-Inhalt entkoppeln,嗯containerisierte Anwendungen portabel zu halten |
| 奇怪für vertrauliche Daten verwendet | 奇怪für nicht vertrauliche Daten verwendet |
| Anwendungsbeispiele: API-Schlüssel,密码,令牌和ssh-Schlüssel | Anwendungsbeispiele: Log-Rotatoren, Konfiguration ohne vertrauliche Daten |
在diesem Beispiel ermöglichen wir Helm, Images vonprivaten Docker-Registriesunter Verwendung von Image-Pull-Secrets abzurufen。
Dieses Verfahren setzt voraus, dass dem Kubernetes-Cluster ein Secret zur Verfügung steht, das die Anmeldedaten für den Repository-Manager angibt。Dieses Secret kann über eine kubectl-Befehlszeile wie folgt erstellt werden:
$ kubectl create secret docker-registry regsecret——docker-server=$DOCKER_REGISTRY_RUL——docker-username=$USERNAME——docker-password=$PASSWORD——docker-email=$EMAIL
在火线values.yaml-Datei Ihres Helm-Charts können Sie dann den Secret-Namen an einen Wert übergeben:
imagePullSecrets: regsecret
Sie können dann das Secret verwenden,嗯Helm den Zugriff auf die Docker-Registry über diese Zeilen indeployment.yaml祖茂堂gewahren:
{{- if . values。imagePullSecrets}} imagePullSecrets: - name: {{. values。imagePullSecrets}} {{- end}}
Für秘密,死für死安文东verfügbar信德,sollten Sie diese Informationen direct invalues.yamleingeben。
额,额,额,额,额,额,额,额,额,额,额,额,额,额,额values.yaml静脉
mongodb: enabled: true mongodb brootpassword: mongodb busername: admin mongodb password: mongodb database: test
Beachten Sie, dass wir hier keine Standard-Anmeldeinformationen in unserem Helm-Chart hartcodieren。Stattdessen verwenden wir eine Logik zur zufälligen Generierung des密码,wenn es nicht über -set标志命令values.yamlbereitgestellt将
Wir verwenden ein Secret, um die Mongodb-Anmeldeinformationen an unsere Anwendung zu übergeben, und zwar durch diese Zeilen indeployment.yaml.
env:—name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: {{. release。Name}}-mongodb key: mongodb-password
Sie können die Ausführung von Kubelet-Containern entweder durch specizialisierteInit-Container奥得河的军队Container-Lifecycle-Hookskontrollieren。
| InitContainer | Container-Lifecycle-Hooks |
| InitContainer信德spezialisierte容器,die vor App-Containern ausgeführt werden und Dienstprogramme oder Setup-Skripte enthalten können, die in einem App-Image nicht vorhanden信德。 | 容器können das容器-生命周期-钩子-框架verwenden, um代码auszuführen, der durch Ereignisse während ihres Verwaltungslebenszyklus ausgelöst奇怪。 |
| Ein Pod kann einen oder mehere初始化容器haben, die ausgeführt werden, bevor die App-Container gestartet werden。 | Ein Pod kann nur einenPostStart——奥得河PreStop钩您 |
| DerPostStart-Hook unmittelbar nach der Erstellung eines集装箱ausgeführt。Es gibt jedoch keine Garantie, dass der Hook vor dem Container-ENTRYPOINT ausgeführt wild。Es werden keine参数an den Handler übergeben。 z. B.《关于日期的秘密》,《秘密的秘密》 |
|
| DerPreStop-钩状的无mittelbar对它们的Beenden eines容器。尔布洛克特,d。h。Er ist同步和muss daher, abgeschlossen werden, bever der Aufruf zum Löschen des容器,gesendwerden kann。 z.B安文东sanft herunterfahren |
|
| 您可以在initContainersverwenden,嗯Wartezeiten hinzuzufügen und so zu prüfen, ob abhängige微服务funktionsfähig信德,bevor Sie forfarren。 | 您可以在PostStart-胡克·阿克图阿利斯勒恩·冯·岱岱恩,在我的小木屋里,z.b.m恩·岱岱恩服务IP祖茂堂aktualisieren |
在unserem Beispiel fügen Sie dieseinitContainers-Spezifikationen derdeployments.yamlhinzu, um den Start unserer Anwendung zu verzögern, bis die Datenbank eingerichtet ist。
initContainers:—name: wait-for-db image: "{{. values . xml "initContainerImage}}"命令:- 'sh' - '-c' - > until nc -z -w 2 {{. release。Name}}-mongodb 27017 && echo mongodb ok;做睡眠2;完成
Hinzufügen von Bereitschafts- und Aktivitätssonden
我们的想法,我们的准备和我们的活力-探针hinzuzufügen,我们的快乐和热情überprüfen。晚上好,könnte晚上好,晚上好,晚上好,晚上好。
Diese Zeilen in derdeployment.yaml-Datei fügen diese Probes hinzu,嗯regelmäßige Prüfungen durchzuführen:
livingessprobe: httpGet: path: '/health' port: http initialDelaySeconds: 60 periodSeconds: 10 failureThreshold: 10 readinessProbe: httpGet: path: '/health' port: http initialDelaySeconds: 60 periodSeconds: 10 failureThreshold: 10
Hinzufügen冯RBAC-Unterstützung
Diese Prozeduren fügen Unterstützung fürrollenbasierte zugriffskontrol (RBAC)unserem Chart hinzu, wenn sie von einer Anwendung benötigt奇怪。
施里特1:我爱你罗尔,indemSie den folgenden Inhalt in einerrole.yaml-Datei hinzufugen:
Eine Rolle kann nur verwendet werden, um Zugriff auf resource inhalb eines einzelnen Namespace zu gewähren。
{{- if . values .rbac. if。创建}}apiVersion: rbac.authorization.k8s。io/v1 kind:角色元数据:labels: app: {{template "express-crud.name"。{} chart: {{template "express-crud. {}图”。}} heritage: {{. release。Service}} release: {{. release。名称}}name: {{ template "express-crud.fullname" . }} rules: {{ toYaml .Values.rbac.role.rules }} {{- end }}
施里特2:我在这里RoleBinding, indemSie den folgenden Inhalt in einerrolebinding.yaml-Datei hinzufugen:
Eine ClusterRole kann verwendet werden, um die gleichen Berechtigungen wie Eine Rolle zu gewähren, aber da sie zum Cluster-Geltungsbereich gehören, können sie auch verwendet werden, um Zugriff auf Folgendes zu gewähren:
- 聚类-贝佐金资源
- nicht- ressourcene - endpunkte (wie "/healthz")
- 在allen命名空间中的命名空间资源(wie Pods)
{{- if . values .rbac. if。创建}}apiVersion: rbac.authorization.k8s。io/v1 kind: RoleBinding metadata: labels: app: {{template "express-crud.name"。{} chart: {{template "express-crud. {}图”。}} heritage: {{. release。Service}} release: {{. release。名称}}name: {{ template "express-crud.fullname" . }} subjects: - kind: ServiceAccount name: {{ template "express-crud.serviceAccountName" . }} roleRef: kind: Role apiGroup: rbac.authorization.k8s.io name: {{ template "express-crud.fullname" . }} {{- end }}
施里特3:我在这里ServiceAccount的军队Hinzufügen des folgenden吸入eineserviceaccount.yaml-Datei:
Ein服务帐户bietet eine Identität für Prozesse,死在einem Pod laufen。
{{- if . values . serviceaccount。create}} apiVersion: v1 kind: ServiceAccount metadata: labels: app: {{template "express-crud.name"。{} chart: {{template "express-crud. {}图”。}} heritage: {{. release。Service}} release: {{. release。名称}}name: {{ template "express-crud.serviceAccountName" . }} {{- end }}
施里特4:“服务账户”。
Wir tun dies, indem Wir folgenden Inhalt in der_helpers.tpl-Datei hinzufugen
{{/* Erstellen Sie den Namen des zu verwendenden Service Accounts */}} {{- define "express-crud. "serviceAccountName" -}} {{- if . values . serviceaccount . if . value . serviceaccount . if " -Create -}} {{default(包含“express-crud. conf”)fullname”。) .Values.serviceAccount.name }} {{- else -}} {{ default "default" .Values.serviceAccount.name }} {{- end -}} {{- end -}}
艾宁·狄恩特hinzufügen
这是一个时代,这是一个不稳定的时代Öffentlichkeit über这是一个伟大的时代zugänglich这是一个伟大的时代。
Ein Dienst ermöglicht es Ihrer Anwendung, datenverkerhr über eine ip - address zu empfangen。Dienste können auf unterschedliche智慧指数werden, indem einTypangegeben将:
| ClusterIP | Der Dienst ist nur über eine interne IP von inhalb des Clusters erreichbar。 |
| NodePort | Der Dienst ist von außerhalb des Clusters über die NodeIP und den NodePort erreichbar。 |
| loadbalance | Der Dienst ist von außerhalb des Clusters über einen externen Load Balancer erreichbar。萤石入口-Funktion für die Anwendung haben。 |
死亡之路,死亡之路service.yaml-Datei hinzufugen:
apiVersion: v1 kind:服务元数据:name: {{template "express-crud. xml。fullname”。}}标签:app:{{模板"express- crude .name"。{} chart: {{template "express-crud. {}图”。}} release: {{. release。名称}}heritage: {{ .Release.Service }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.externalPort }} targetPort: http protocol: TCP name: http selector: app: {{ template "express-crud.name" . }} release: {{ .Release.Name }}
海滩上的Sie, dass wir im obigen Beispiel für unseren Dienst类型爱因斯坦在unserervalues.yaml verweisen:
service: type: LoadBalancer internalPort: 3000 externalPort: 80
Values.yaml-Zusammenfassung
爱因斯坦在埃纳values.yaml-Datei zu definieren, ist eine gute Praxis, um die Helm-Charts wartbar zu halten。
所以sieht dievalues.yaml-Datei für unser Beispiel aus, wobei die Vielfalt der einstein ersichtlich ist, die wir für viele der oben besprochenen Funktionen definieren:
# Standardwerte für express-mongo-crud。# YAML-formatierte Datei。# Deklarieren Sie variaben, die an Ihre Vorlagen übergeben werden sollen。## Rollenbasierte Zugriffskontrolle ## Ref: https://kubernetes.io/docs/admin/authorization/rbac/ rbac: create: true role: ## Zu erstellende Regeln。Gemäß Rollenspezifikation rules: - apiGroups: - " r2022世界杯阿根廷预选赛赛程esources: - services - endpoints - pods verbs: - get - watch - list ## ServiceAccount ## Ref: https://kubernetes.io/docs/admin/service-accounts-admin/ ## serviceAccount: create: true ## Der Name des zu verwendenden ServiceAccounts。## Wenn nicht eingestellt und create = true, wid ein Name unter Verwendung der fullname-Vorlage erzeugt Name: ## Konfigurationswerte für die mongodb-Abhängigkeit ## ref: https://github.com/kubernetes/charts/blob/master/stable/mongodb/README.md ## mongodb: enabled: true image: tag: 3.6.3 pullPolicy: IfNotPresent persistence: size: 50Gi # r2022世界杯阿根廷预选赛赛程esources: # requests: # memory:“12Gi”# cpu:“200m”# limits: # memory:“12Gi”# cpu:“12Gi”“2”## Stellen Sie sicher, dass die -wiredTigerCacheSizeGB nicht mehr als die Hälfte der Speichergrenze beträgt!## die ist entscheidend für den Schutz vor OOMKill durch Kubernetes!mongodb bextraflags: - "——wiredTigerCacheSizeGB=1" mongodb brootpassword: mongodb busername: admin mongodbPassword: mongodbDatabase: test # lifenessprobe: # initialDelaySeconds: 60 # periodSeconds: 10 # readinessProbe: # initialDelaySeconds: 30 # periodSeconds: 30 ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes. log =1"Io /tls-acme: "true"路径:/ hosts。local tls: [] # - secretName: chart-example-tls # hosts: # - chart-example。local initContainerImage: "alpine:3.6" imagePullSecrets: replicaCount: 1 image: repository: jainishshah17/express-mongo-crud # tag: 1.0.1 pullPolicy: IfNotPresent service: type: LoadBalancer internalPort: 3000 externalPort: 80 resources: {} # Wir empfehlen in der Regel, keine Standard-Ressourcen anzugeben und dies bewusst so zu belassen # Auswahl für den Benutzer. Dies erhöht auch die Chancen, dass die Charts in Umgebungen mit wenig # Ressourcen laufen, wie z. B. Minikube. Wenn Sie Ressourcen angeben möchten, lassen Sie die folgenden # Zeilen unkommentiert, passen Sie sie nach Bedarf an und entfernen Sie die geschweiften Klammern nach "resources:". # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi nodeSelector: {} tolerations: [] affinity: {}
舵图测试和安装
Es ist sehr wicichtig, dass wir unser helm - diagram testen;死亡与他们同在执掌线头-Befehl。
$ helm lint ./ ## Output ==> Linting ./ lint OK 1张图被检测,没有故障
Verwenden Sie den舵安装-Befehl,嗯unsere Anwendung mithillife von helm chart auf Kubernetes bereitzustellen。
$ helm install——name test1 ./ ##输出名称:test1 LAST DEPLOYED: Sat Sep 15 09:36:23 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES:2022世界杯阿根廷预选赛赛程==> v1beta1/ Service NAME DESIRED CURRENT - up - AVAILABLE AGE test1-mongodb 1 1 10 0s ==> v1beta2/Deployment test1- expressage 1 1 10 0s ==> v1/Secret NAME TYPE DATA AGE test1-mongodb Opaque 2 0s ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test1-mongodb Pending standard 0s ==> v1/ServiceAccount NAME SECRETS AGE test1- expresscrud 1 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE test1-mongodb ClusterIP 10.19.248.205 27017/TCP 0stest1-express-crud LoadBalancer 10.19.254.169 80:31994/TCP 0s ==> v1/Role NAME AGE test1-express-crud 0s ==> v1/RoleBinding NAME AGE test1-express-crud 0s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE test1-mongodb-67b6697449-tppk5 0/1 Pending 0 0s test1-express-crud-dfdbd55dc-rdk2c 0/1 Init:0/1 0 0s HINWEISE: 1. Rufen Sie die Anwendungs-URL ab, indem Sie diese Befehle ausführen: HINWEIS: Es kann ein paar Minuten dauern, bis die LoadBalancer-IP verfügbar ist. Sie können den Status von durch Ausführen von "kubectl get svc -w test1-express-crud" verfolgen export SERVICE_IP=$(kubectl get svc --namespace default test1-express-crud -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo https://$SERVICE_IP:80
Durch Ausführen des oben genannten helm install-Befehls wid eine External_IP für den Load Balancer erzeugt。Sie können diese ip地址verwenden,嗯die Anwendung auszuführen。
所以sieht unsere Anwendung aus, wenn sie ausgeführt奇怪:

Zusammenfassung
können, ist Helm ein extrevielsetiges System, das Ihnen eine große Flexibilität bei der Strukturierung und Entwicklung eines Charts bietet。Werden dabei die konentionen der Helm-Community befolgt, vereinfacht dies die Einreichung Ihrer Helm-Charts für die öffentliche Nutzung und die Pflege Ihrer Anwendung durch Aktualisierungen wid erheblich erleichtert。
Die fertiggestellten Helm-Charts für dieses Beispielprojekt finden Sie imexpress-crud-仓库auf GitHub。Außerdem können Sie diese funktionierenden Dateien überprüfen, um die Funktionsweise besser zu verstehen。
恩weitere Beispiele kennenzulernen, können Beispiel-Repository vonHelm-Chartsfür在Kubernetes ansehen的产品。