Helm Package Manager - Kubernetes Applications

Tổng quan

Helm là package manager cho Kubernetes. Helm charts package Kubernetes applications với templates và configuration.

Helm Basics

Installation

# Lệnh cài đặt Helm trên Linux
curl https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz
tar -zxvf helm-v3.12.0-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm

Basic Commands

# Search charts
helm search repo nginx

# Install chart
helm install my-nginx bitnami/nginx

# List releases
helm list

# Upgrade release
helm upgrade my-nginx bitnami/nginx --version 15.4.2

# Uninstall
helm uninstall my-nginx

Thực thi lệnh Helm từ Java

Bạn có thể thực thi các lệnh Helm từ Java bằng cách sử dụng ProcessBuilder.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class HelmExecutor {

    public static void executeCommand(String command) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", command);

        Process process = processBuilder.start();
        StringBuilder output = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line + "
");
        }

        int exitVal = process.waitFor();
        if (exitVal == 0) {
            System.out.println("Success!");
            System.out.println(output);
        } else {
            // Handle error
            System.out.println("Command failed with exit code: " + exitVal);
        }
    }

    public static void main(String[] args) {
        try {
            // Ví dụ cài đặt một chart
            executeCommand("helm install my-release bitnami/wordpress");
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Charts

Chart Structure

mychart/
  Chart.yaml
  values.yaml
  templates/
    _helpers.tpl
    deployment.yaml
    service.yaml
    ingress.yaml
  charts/
  .helmignore

Chart.yaml

apiVersion: v2
name: mychart
description: A Helm chart for my application
version: 0.1.0
appVersion: "1.0"

Templates và Values

Basic Template

File templates/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}
  labels:
    app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}-{{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}-{{ .Chart.Name }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: 80

Values

File values.yaml:

replicaCount: 3

image:
  repository: nginx
  tag: "1.20"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

Biểu diễn Deployment bằng Java (Fabric8)

Bạn có thể tạo các đối tượng Kubernetes bằng Java thay vì viết YAML thủ công.

import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

public class KubernetesDeploymentCreator {

    public void createDeployment() {
        try (KubernetesClient client = new DefaultKubernetesClient()) {
            Deployment deployment = new DeploymentBuilder()
                .withNewMetadata()
                    .withName("my-nginx-deployment")
                .endMetadata()
                .withNewSpec()
                    .withReplicas(3)
                    .withNewSelector()
                        .addToMatchLabels("app", "nginx")
                    .endSelector()
                    .withNewTemplate()
                        .withNewMetadata()
                            .addToLabels("app", "nginx")
                        .endMetadata()
                        .withNewSpec()
                            .addNewContainer()
                                .withName("nginx")
                                .withImage("nginx:1.20")
                                .addNewPort()
                                    .withContainerPort(80)
                                .endPort()
                            .endContainer()
                        .endSpec()
                    .endTemplate()
                .endSpec()
                .build();

            client.apps().deployments().inNamespace("default").createOrReplace(deployment);
            System.out.println("Deployment created successfully!");
        }
    }
}

Advanced Templating

Named Templates (_helpers.tpl)

Để tái sử dụng code và giữ cho templates gọn gàng, bạn có thể định nghĩa các template con trong file templates/_helpers.tpl.

File templates/_helpers.tpl:

{{/*
Define a common label structure.
*/}}
{{- define "mychart.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

Sử dụng trong deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
...

Functions và Pipelines

Helm cung cấp nhiều hàm dựng sẵn. Bạn có thể kết hợp chúng bằng pipelines (|).

image: "{{ .Values.image.repository | upper }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
# Kết quả: "NGINX:1.0" nếu values.yaml không có tag

Flow Control (if/else, range)

# if/else
{{- if .Values.service.enabled -}}
apiVersion: v1
kind: Service
...
{{- end -}}

# range
{{- range .Values.ingress.hosts }}
- host: {{ . | quote }}
  http:
    paths:
    - path: /
      backend:
        serviceName: my-service
        servicePort: 80
{{- end }}

Chart Repository Management

ChartMuseum

ChartMuseum là một repository server cho Helm charts, hỗ trợ lưu trữ trên S3, GCS, Azure Blob Storage, và nhiều hơn nữa.

Cài đặt và chạy ChartMuseum:

# Chạy bằng Docker
docker run --rm -it -p 8080:8080 -v $(pwd)/charts:/charts chartmuseum/chartmuseum:latest --storage=local --storage-local-rootdir=/charts

Thêm repository và push chart:

# Thêm repo
helm repo add my-repo http://localhost:8080

# Push chart
helm cm-push mychart/ my-repo

OCI Registries

Helm 3 hỗ trợ lưu trữ charts trong các OCI-compliant container registries (như Docker Hub, ACR, GCR).

# Đăng nhập vào registry
helm registry login myregistry.example.com

# Push chart lên OCI registry
helm push mychart-0.1.0.tgz oci://myregistry.example.com/charts

# Pull chart từ OCI registry
helm pull oci://myregistry.example.com/charts/mychart --version 0.1.0

Repositories

# Add repository
helm repo add bitnami https://charts.bitnami.com/bitnami

# Update repositories
helm repo update

# List repositories
helm repo list

Best Practices

  • Version your charts
  • Use semantic versioning
  • Document charts thoroughly
  • Test charts before release
  • Use chart hooks for lifecycle management
  • Implement proper RBAC

Chart Development

Creating Charts

helm create mychart

Testing Charts

# Dry run
helm install --dry-run --debug mychart ./mychart

# Template debugging
helm template mychart ./mychart

Nội dung đã được mở rộng với advanced templating, chart repository management và các ví dụ bằng Java.