计算巢使用helm hook实现helm chart在ack集群中部署

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
资源编排,不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 计算巢是阿里云开放给ISV与其客户的服务管理PaaS平台,旨在解决ISV云上交付、部署、运维问题,建立ISV与客户之间的通道。针对ISV的实际场景,计算巢提供了私有化部署、托管版部署、代运维服务三种模式。托管版和私有化部署的区别是针对于部署在ISV的账号下还是部署在用户账号下。本文主要介绍如何在计算巢中,通过服务部署helm chart到ack集群中。

计算巢简介

计算巢是阿里云开放给ISV与其客户的服务管理PaaS平台,旨在解决ISV云上交付、部署、运维问题,建立ISV与客户之间的通道。针对ISV的实际场景,计算巢提供了私有化部署、托管版部署、代运维服务三种模式。托管版和私有化部署的区别是针对于部署在ISV的账号下还是部署在用户账号下。

本文主要介绍如何在计算巢中,通过服务部署helm chart到ack集群中。

实现思路

利用ROS进行服务部署

计算巢服务部署主要借助于[ROS资源编排服务](https://www.aliyun.com/product/ros)来实现资源编排, 因此最初的实现思路是使用ros的ClusterHelmApplication直接进行部署,对应的模版关键部分如下:

ClusterHelmApplication:
    Type: ALIYUN::CS::ClusterHelmApplication
    DependsOn:
      - AddonsSleep
    Properties:
      ChartValues:
        Ref: ChartValues
      ClusterId:
        Fn::If:
          - CreateAck
          - Fn::GetAtt:
              - ManagedKubernetesCluster
              - ClusterId
          - Ref: ClusterId
      ChartUrl:
        Ref: ChartUrl
      Namespace:
        Ref: Namespace
      Name:
        Ref: Name

经过测试发现,这种方式存在两个问题:

  1. 存放在acr镜像仓库中的helm chart包不支持转成https链接使用
  2. ack线上部署依赖的helm版本为3.0.7,不支持helm一些比较高级的语法。如部署nginx服务时,提示不支持lookup函数。

job中helm命令安装

既然使用ack提供的线上部署方式走不通,就考虑直接使用helm命令进行安装,实现方式就是在ack集群中起个job,在job中进行helm chart部署的动作,模版关键部分如下:

Resources:
  ClusterUserKubeconfig:
    Type: DATASOURCE::CS::ClusterUserKubeconfig
    Properties:
      ClusterId:
        Ref: ClusterId
  ClusterApplication:
    Type: ALIYUN::CS::ClusterApplication
    Properties:
      YamlContent: 
        Fn::Sub:
          - |
            apiVersion: batch/v1
            kind: Job
            metadata:
              name: helm-install-job
            spec:
              template:
                metadata:
                  name: helm-install-job
                spec:
                  containers:
                  - name: helm-intall
                    image: alpine/helm:3.12.0
                    command: [ "/bin/sh", "-c", "--" ] 
                    args: ["cd ~; mkdir ~/.kube; echo '${KubeConfig}' | base64 -d >> ~/.kube/config; chartPackage=$({{ computenest::helmpull::test }}); helm install $chartPackage --generate-name;"]
                  restartPolicy: Never
          - KubeConfig:
              Fn::Base64Encode:
                Fn::GetAtt:
                  - ClusterUserKubeconfig
                  - Config

在job中将KubeConfig写到config文件中,然后执行helm pull命令,最后使用helm install命令进行helm chart安装,其中的{{ computenest::helmpull::test }}标识符会被替换为helm chart下载命令。

这种方式的问题是job进行了helm chart的部署,服务实例进行删除时,helm chart并不会进行卸载。

Helm Hook方式进行安装

helm提供了hook功能,可以在post-install-hook中进行helm chart的安装操作,在pre-delete-hook中进行helm chart的卸载操作,这样就可以解决job只进行了部署,未进行卸载的问题了。

同样还是使用ros的ClusterHelmApplication资源类型,去运行helm hook模版框架,在框架中去执行helm chart的安装和卸载。

post-install-hook处理逻辑如下:

apiVersion: batch/v1
kind: Job
metadata:
  name: post-install-job-{{ .Release.Name }}
  labels:
    app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
    app.kubernetes.io/instance: {{ .Release.Name | quote }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
  annotations:
    # This is what defines this resource as a hook. Without this line, the
    # job is considered part of the release.
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    metadata:
      name: "{{ .Release.Name }}"
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    spec:
      restartPolicy: Never
      containers:
        - name: post-install-job
          image: "alpine/helm:3.12.0"
          command:  [ "/bin/sh", "-c", "--" ]
          args: ["
              set -x;
              cd ~;
              curl -LO \"https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl\"; 
              install -o root -g root -m 0755 kubectl /usr/bin/kubectl;
              mkdir ~/.kube; echo {{ .Values.Kubeconfig }} | base64 -d >> ~/.kube/config;
              echo {{ toYaml .Values.ChartValues | b64enc }} | base64 -d > values.yaml;  
              export HELM_EXPERIMENTAL_OCI=1; 
              wget {{ .Values.ChartUrl }};
              data=$(helm install {{.Values.ReleaseName}} {{ .Values.ChartPackage }} -f values.yaml --namespace {{ .Values.ChartNamespace }} | base64 | tr -d '\n');
              if [ -n \"{{ .Values.OutputCmd | b64enc }}\" ];
              then
                  sleep {{ .Values.InstallSeconds }};
                  echo {{ .Values.OutputCmd | b64enc }} | base64 -d > outputCmd.sh; 
                  data=$(source outputCmd.sh | base64 | tr -d '\n');
              fi;
              {{ .Values.CurlCli }} -d \"{\\\"Data\\\":\\\"$data\\\",\\\"status\\\":\\\"SUCCESS\\\"}\";
              "]

pre-delete-hook的处理逻辑如下:

apiVersion: batch/v1
kind: Job
metadata:
  name: pre-delete-job-{{ .Release.Name }}
  labels:
    app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
    app.kubernetes.io/instance: {{ .Release.Name | quote }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
  annotations:
    # This is what defines this resource as a hook. Without this line, the
    # job is considered part of the release.
    "helm.sh/hook": pre-delete
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    metadata:
      name: "{{ .Release.Name }}"
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    spec:
      restartPolicy: Never
      containers:
      - name: pre-delete-job
        image: "alpine/helm:3.12.0"
        command:  [ "/bin/sh", "-c", "--" ] 
        args: ["
            cd ~; 
            mkdir ~/.kube; 
            echo {{ .Values.Kubeconfig }} | base64 -d >> ~/.kube/config; 
            export HELM_EXPERIMENTAL_OCI=1; 
            helm uninstall {{ .Values.ReleaseName }} --namespace {{ .Values.ChartNamespace }};
        "]

计算巢服务模版关键部分如下,将真正要部署的chartUrl通过values的方式传到helm hook部署模版中:

总结

在计算巢中在线部署helm chart到ack集群的探索过程中,遇到了很多的问题,现有的云产品对通过api调用和在线使用支持不是很完善,估计是这种使用方式比较少,大部分用户还是通过命令来执行,比如acr服务不支持https方式拉取,ack的ack-helm-manager对应的helm版本过低,最终只能想办法通过其它路径来达到想要的效果。

 

相关文章
|
5天前
|
Kubernetes Java Docker
使用Kubernetes和Docker部署Java微服务
使用Kubernetes和Docker部署Java微服务
|
4天前
|
Kubernetes 网络协议 Docker
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船
|
4天前
|
Kubernetes Ubuntu jenkins
超详细实操教程!在现有K8S集群上安装JenkinsX,极速提升CI/CD体验!
超详细实操教程!在现有K8S集群上安装JenkinsX,极速提升CI/CD体验!
|
5天前
|
Kubernetes 应用服务中间件 nginx
K8s高可用集群二进制部署-V1.20
2.4 部署Etcd集群 以下在节点1上操作,为简化操作,待会将节点1生成的所有文件拷贝到节点2和节点3. 1. 创建工作目录并解压二进制包 mkdir /opt/etcd/{bin,cfg,ssl} -p tar zxvf etcd-v3.4.9-linux-amd64.tar.gz mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
|
8天前
|
Kubernetes Ubuntu Linux
k8s部署grafana beyla实现app应用服务依赖图可观测
k8s部署grafana beyla实现app应用服务依赖图可观测
17 4
|
2天前
|
消息中间件 Kubernetes Android开发
消息队列 MQ产品使用合集之如何在kubernetes环境里面部署
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
4天前
|
前端开发 Devops 测试技术
阿里云云效产品使用问题之更换所部署的环境关联的ACK集群该如何实现
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
5天前
|
Prometheus 监控 Kubernetes
一篇文章讲明白Kubernetes(k8s)部署Promehteus监控
一篇文章讲明白Kubernetes(k8s)部署Promehteus监控
12 0
|
5天前
|
Prometheus 监控 Kubernetes
一篇文章讲明白Kubernetes(k8s)部署Promehteus监控
一篇文章讲明白Kubernetes(k8s)部署Promehteus监控
14 0
|
5天前
|
Kubernetes Docker 容器
007.Kubernetes二进制部署Flannel
007.Kubernetes二进制部署Flannel

热门文章

最新文章