【亲测】Helm Java Api

本文介绍了Helm-Java库,一个用于操作Helm的Java库,它简化了HelmAPI的使用。作者分享了如何利用Java库远程连接主机并执行Linux命令,包括示例代码,展示了如何安装、列出、验证和卸载Helmchart,以及通过SSH2执行远程命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在做云原生运维相关系统开发,需要api操作helm,也是调研找了许久,找到个不错的开源项目,分享一下叫helm-java

链接https://github.com/manusa/helm-java

这个项目是之前分享过的文章Fabric8io团队24年初开源的,目前找了网上各个博客还都没有,都是操作helm比较麻烦的。这个Helm-Java使用简单,和Fabirc8差不多,该项目也有详细api使用讲解

注:有兴趣可以研究研究,这里和大家简单分享一下这个库

补充:对于开源项目还未实现的命令,如helm search repo [repo_name],大家可以先用java远程连接主机,再远程执行命令实现,拿到执行后打印的数据,就能对数据处理返回,代码在第二节也给出

24/4/22
helm search repo命令我在它github提了个issue,没想到官方快速回复并在0.0.7版本完善,真有开源精神,大家若有问题,也可以去提issue,官方有时间应该也会快速完善。

Helm-Java Demo使用

根据官网下方对每个命令对应api的讲解,做了demo,亲测有效

<dependency>
    <groupId>com.marcnuri.helm-java</groupId>
    <artifactId>helm-java</artifactId>
    <version>0.0.7</version>
</dependency>

个人demo代码,这里不做详细讲解,因为开源讲解已经很详细,自己可以去试着运行一下,就懂了,链式编程填参数也好理解

package com.yx;

import com.marcnuri.helm.*;

import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * Author:yx5411
 * Date:2024-03-27
 * Description: helm-java-api测试
 */
public class Main {
    public static void main(String[] args) {
        // 集群中的~/.kube/config连接文件下载放到本地
        String kubeConfigPath  = "D:\\IDEAProject\\helm_java_api\\src\\main\\resources\\conf\\config";
        String namespace = "kubeapps";
        String uuid = UUID.randomUUID().toString();
        String name = "nginx-test-" + uuid.substring(0, 4);
        System.out.println("name: " + name);
//        findNameSpaceAllChart(namespace, kubeConfigPath);
        installHelm(namespace, kubeConfigPath, name);
//        createChartDir();
//        lintHelm();
//        uninstallReleaseByName(namespace, kubeConfigPath);
    }

    // helm create:在指定位置创建一个包含chart包公共文件的目录,即初始化创建
    private static void createChartDir() {
        Helm.create()
            // Name of the chart to create
            .withName("test")
            // Path to the directory where the new chart directory will be created
            .withDir(Paths.get("D:\\IDEAProject\\helm_java_api\\src\\main\\resources\\tmp"))
            .call();
    }

    // helm list:查询某个命名空间下的所有已发布的chart
    private static void findNameSpaceAllChart(String namespace, String kubeConfigPath) {
        List<Release> releases = Helm.list()
                .withNamespace(namespace)
                .withKubeConfig(Paths.get(kubeConfigPath))
                .all()
//                .allNamespaces()
                .deployed()
                .failed()
                .pending()
                .superseded()
                .call();
        for (Release release : releases) {
            System.out.println("Name: " + release.getName());
            System.out.println("Namespace: " + release.getNamespace());
            System.out.println("Revision: " + release.getRevision());
            System.out.println("Status: " + release.getStatus());
            System.out.println("Chart: " + release.getChart());
            System.out.println("App Version: " + release.getAppVersion());
            System.out.println("-----------------------------");
        }
    }

    // helm lint:检查图表是否存在可能的问题,即验证
    public static void lintHelm() {
        String chatPath = "D:\\IDEAProject\\helm_java_api\\src\\main\\resources\\conf\\nginx-0.1.0.tgz";
        LintResult result = new Helm(Paths.get(chatPath))
                .lint()
                .strict()
                .quiet()
                .call();
        System.out.println(result.isFailed());
        System.out.println(result.getMessages());
    }

    // helm uninstall:删除某个命名空间下的release,可helm list -n [NAMESPACE]查看已发布的chart
    private static void uninstallReleaseByName(String namespace, String kubeConfigPath){
        // 假设先查询helm list
        List<Release> releases = Helm.list()
                .withNamespace(namespace)
                .withKubeConfig(Paths.get(kubeConfigPath))
                .all()
                // 下面是筛选查各种状态的release
//                .deployed()
//                .failed()
//                .pending()
//                .superseded()
//                .uninstalled()
                .call();
        // 删除状态为失败和挂起的release
        List<String> list = releases.stream().map(Release::getName).collect(Collectors.toList());
        for (String name: list){
            System.out.println("helm uninstall " + name + " -n " + namespace);
            String res = Helm.uninstall(name)
                    .dryRun() // 模拟卸载,不真实卸载,真卸载需将其注释
                    .noHooks()
                    .ignoreNotFound()
                    .keepHistory()
                    .withCascade(UninstallCommand.Cascade.BACKGROUND)
                    .withNamespace(namespace)
                    .withKubeConfig(Paths.get(kubeConfigPath))
                    .debug()
                    .call();
            System.out.println(res);
        }
    }

    // helm install:在某个命名空间下安装部署chart
    public static void installHelm(String namespace, String kubeConfigPath, String name){
        // 通过下面方式nginx.tgz安装正常running,mysql.tgz安装却是pending
        // 原因是mysql和redis均默认要1个master和3个pod进行部署,本地只部署1master和2node导致,资源问题
        String desc = "helm install " + name;
        String chatPath = "D:\\IDEAProject\\helm_java_api\\src\\main\\resources\\conf\\nginx-0.1.0.tgz";
        InstallCommand installCommand = new Helm(Paths.get(chatPath)).install();
        Release result = installCommand
                .withName(name)
                .withNamespace(namespace)
                .withKubeConfig(Paths.get(kubeConfigPath))
                .createNamespace()
                .withDescription(desc)
                .dependencyUpdate()
                .waitReady()
                .plainHttp()
                .debug()
                .call();
        System.out.println("Success");
    }
    
}

另外,关于安装部署chart引用

(1) 通过chart引用进行install,这里需要本地有repositories.yaml文件,我们远程主机用helm --help可以看到windows默认存的位置,是在%APPDATA%环境变量下
在这里插入图片描述在cmd窗口echo %APPDATA%,可以看到如下,这个变量对应的位置是C:\Users\yx5411\AppData\Roaming,所以需要在这目录下面加一个helm目录,然后放入yaml文件
在这里插入图片描述
(2) %TEMP%也echo打印,会发现路径C:\Users\yx5411\AppData\Local\Temp,如下
在这里插入图片描述
这里就对应cache中helm目录,需要将远程.cache目录中helm放%TEMP%对应路径,然后本地windows环境就能通过chart引用install了
在这里插入图片描述

补充方法:远程连接,执行Linux命令

这是参考一个博主的,自己测了下,能用,能拿到命令执行后,控制台打印的数据

导入Maven依赖,远程连接相关的ssh2

<dependency>
    <groupId>ch.ethz.ganymed</groupId>
    <artifactId>ganymed-ssh2</artifactId>
    <version>build210</version>
</dependency>
import java.io.BufferedReader;
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.UnsupportedEncodingException;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;  
import ch.ethz.ssh2.StreamGobbler;

/**
 * 远程执行Linux命令
 */
public class RemoteExecuteCmd {
    //字符编码默认是utf-8  
    private static String  DEFAULT_CHART = "UTF-8";
    private Connection conn;
    private String ip;  
    private String userName;  
    private String userPwd;  
      
    public RemoteExecuteCmd(String ip, String userName, String userPwd) {
        this.ip = ip;  
        this.userName = userName;  
        this.userPwd = userPwd;  
    }
      
    /** 
     * 远程登录linux的主机 
     * @author Ickes
     * @since  V0.1 
     * @return 
     *   登录成功返回true,否则返回false
     */
    public Boolean login(){  
        boolean flag=false;
        try {  
            conn = new Connection(ip);  
            conn.connect();//连接  
            flag = conn.authenticateWithPassword(userName, userPwd);//认证
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return flag;
    }  
    /** 
     * @author Ickes 
     * 远程执行shll脚本或者命令 
     * @param cmd 
     *      即将执行的命令 
     * @return 
     *      命令执行完后返回的结果值 
     * @since V0.1 
     */  
    public String execute(String cmd){  
        String result="";  
        try {  
            if(login()){  
                Session session= conn.openSession();//打开一个会话  
                session.execCommand(cmd);//执行命令  
                result=processStdout(session.getStdout(), DEFAULT_CHART);
                //如果为得到标准输出为空,说明脚本执行出错了  
                if(result.isEmpty()){
                    result=processStdout(session.getStderr(),DEFAULT_CHART);
                }  
                conn.close();  
                session.close();  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return result;  
    }  
      
      
    /** 
     * @author Ickes 
     * 远程执行shell脚本或者命令
     * @param cmd 
     *      即将执行的命令 
     * @return 
     *      命令执行成功后返回的结果值,如果命令执行失败,返回空字符串,不是null 
     * @since V0.1 
     */  
    public String executeSuccess(String cmd){  
        String result="";  
        try {  
            if(login()){  
                Session session= conn.openSession();//打开一个会话  
                session.execCommand(cmd);//执行命令  
                result=processStdout(session.getStdout(),DEFAULT_CHART);
                conn.close();  
                session.close();  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return result;  
    }  
      
   /** 
    * 解析脚本执行返回的结果集 
    * @author Ickes 
    * @param in 输入流对象 
    * @param charset 编码 
    * @since V0.1 
    * @return 
    *       以纯文本的格式返回 
    */  
    private String processStdout(InputStream in, String charset){  
        InputStream stdout = new StreamGobbler(in);
        StringBuffer buffer = new StringBuffer();;  
        try {  
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));  
            String line = null;
            while((line = br.readLine()) != null){
                buffer.append(line+"\n");  
            }  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return buffer.toString();  
    }
}  

OperateMain.java主类测试

public class OperateMain {
    public static void main(String[] args) {
    	// 得到命令执行后,打印出的数据
    	String res = demoCmd1();
        System.out.println(res);
    }
    private static String demoCmd1() {
    	// 或者其他命令ls /opt
	    String cmd = "helm repo list";
	    String res = executeCmd(cmd);
	    return res;
    }
    private static String executeCmd(String cmd){
        String usr = "root";
        String password = "root";
        String serverIP = "192.168.20.xxx";// 替换
        RemoteExecuteCmd executeCommand = new RemoteExecuteCmd(serverIP, usr, password);
        String res = executeCommand.execute(cmd);
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值