使用helm和kustomize零一部署应用

379 阅读6分钟

一、  前言

k8s 部署应该是目前大部分应用都选择的部署方式,在工作中大家都或多或少实操过k8s。但大公司的话一般会提供打包部署插件,比如腾讯蓝盾流水线,或者说有专业运维操作,使得开发并没有机会实操。

本篇分享主要会从helm chart、kustomize 两种方式从零到一部署一个http 服务。服务访问链路 url->lb->ingress->service->deployment->pod。

二、  实践准备

1.  一套k8s 环境

可以到云厂商购买,我这里演示的是火山云实例。

image.png

2.  http 应用服务

代码仓库:github.com/fabxu/deplo…

image.png 非常简单的http应用,通过Dockerfile 构建镜像备用

三、  k8s 资源文件部署

这种方式是k8s 原生支持的资源文件部署,直接kubectl apply 即可。

例如如下service和deployment 最简单的资源配置,需要关注的重点是端口对应问题,尤其是Service.spec.ports.targetPort 需要和 Deployment.spec.template.spec.containers.ports.containerPort 一致,Deployment.spec.template.spec.containers.ports.containerPort 是应用监听的端口。

imagePullSecrets 是拉镜像需要用到的secret,如果镜像推到了火山云就没有这个问题

apiVersion: v1
kind: Service
metadata:
  name: deploy-kustomize
  namespace: deploy
  labels:
    app: deploy
spec:
  ports:
    - protocol: TCP
      port: 80     
      targetPort: 8089
  selector:
    app: deploy
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-kustomize
  namespace: deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy
  template:
    metadata:
      labels:
        app: deploy
    spec:
      containers:
        - name: deploy
          image: registry.sensetest.com/beacon/aigc/backend/aigc-service:5
          ports:
            - containerPort: 8089
      imagePullSecrets:
        - name: regcred
        - name: regcred-sensetest

四、  helm 部署

1、  helm介绍

很多人都使用过Ubuntu下的ap-get或者CentOS下的yum, 这两者都是Linux系统下的包管理工具。采用apt-get/yum,应用开发者可以管理应用包之间的依赖关系,发布应用;用户则可以以简单的方式查找、安装、升级、卸载应用程序。

先了解下常见术语

● Helm: Kubernetes的应用打包工具,也是命令行工具的名称。

● Tiller: Helm的服务端,部署在Kubernetes集群中,用于处理Helm的相关命令。

● Chart: Helm的打包格式,内部包含了一组相关的kubernetes资源。

● Repoistory: Helm的软件仓库,repository本质上是一个web服务器,该服务器保存了chart软件包以供下载,并有提供一个该repository的chart包的清单文件以供查询。在使用时,Helm可以对接多个不同的Repository。

● Release: 使用Helm install命令在Kubernetes集群中安装的Chart称为Release。

2、  helm 构建

● 使用helm脚手架生成chart 的骨架

helm create deploy-chart 

该命令创建一个deploy-chart目录,该目录结构如下所示,我们主要关注目录中的这三个文件即可: Chart.yaml,values.yaml 和 templates 里面需要用的负载配置。

image.png  

研究一下可以发现,模板里的文件里引用的变量基本来自Chart.yaml,values.yaml 两个文件,尤其是values.yaml。values.yaml 常用放在工程里去替换实际部署的变量。

● helm lint 校验chart

在deploy-chart 执行 helm lint 。

image.png

如果文件格式错误,可以根据提示进行修改;如果一切正常,可以使用下面的命令对chart进行打包:

helm package deploy-chart --debug

3、  helm 部署与升级

  部署与升级放在一起说明是因为测试期经常要多次helm install,但之前安装过的组件再次helm install 就会报错,比如说service->deployment->pod 安装没问题,只需要更改ingress。下面的命令意思是如果有就升级,没有就安装。

helm upgrade deploy ./deploy-chart -n deploy -f values.yaml --install

image.png  执行 kubectl get all -n deploy 可查看应用相关负载的状态 image.png   到此应用已经部署完成了,可以对应用发起访问。

● cluterIp

管理节点上,curl http://192.168.94.107:80/get/jobs

kubectl get svc -n deploy
deploy-kustomize      ClusterIP   192.168.94.107   <none>        80/TCP         28h

● podIp

管理节点上,curl http://10.134.16.35:8089/get/jobs

kubectl get pod -n deploy -o wide 
 
NAME                                  READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES
deploy-deploy-chart-9b995ddc9-v4x4n   1/1     Running   0          3d5h   10.134.16.35   xxx.xxx.8.2   <none>           <none>
 

● nodePort

如果想对外提供服务,可以采用nodePort 方式

kubectl get svc -n deploy
deploy-deploy-chart   NodePort    192.168.69.128   <none>        81:30008/TCP   3d6h

● port-forward

也是类似nodePort 的一种访问方式,常用于开发期。将本地端口的请求转发到集群服务端口。

例如如下命令,将my-service 的 Service 并且想将其 80 端口映射到本地的 9000 端口:

kubectl port-forward service/deploy-deploy-chart 9000:80

4、  helm 其他命令

正式的cicd,chart 需要被发布以及被纳入本地仓管控,参考一下命令

helm repo add ingress-nginx(仓库名) https://kubernetes.github.io/ingress-nginx
helm repo update
// chart 地址也可以是本地的,helm install xxx ./xxx/
helm install ingress-nginx(安装实例的名字:release) ingress-nginx(仓库名)/ingress-nginx(chart名)

五、  Kustomize 部署

1、  kustomize介绍

Kustomize 是一个专门用于 Kubernetes 的模板化工具,它允许用户通过声明式配置管理应用程序的不同版本或环境(如开发、测试和生产)。与传统的模板引擎不同,Kustomize 不依赖于特定的模板语言;相反,它是基于原生的 Kubernetes YAML 文件进行操作,并通过 overlays(覆盖层) 和 patches(补丁) 来定制这些文件。 先了解下常见术语

● Overlays(覆盖层): 允许为不同的环境(如 dev, prod)创建自定义配置,而不需要复制基础配置文件。

● Patches(补丁): 通过 JSON Patch 或 Strategic Merge Patch 对现有资源进行修改。

● Bases(基础层): 定义一组通用的基础配置,供多个 overlays 使用。

● Components(组件): 支持将一组相关的资源打包成可复用的组件。

● Transformations: 提供多种变换功能,例如设置命名空间、添加标签等。

2、  kustomize层级说明

如下是kustomize层级说明,把需要的资源文件放在base里,针对不同环境做的补丁放在overlay里,例如说ingress配置的访问域名、deployment 内置的环境变量等等。kustomize 实际做的事情就是用overlays中的patches来覆盖或者修改base里的资源配置,形成可直接kubectl apply 的资源文件。

image.png  

3、  kustomize 构建与部署

 kubectl kustomize . > output.yaml
 kubectl apply -f output.yaml

4、  ingress

对于需要域名发起的请求,可使用ingress。域名绑定lb,lb绑定集群的ingress-controller,通过设置ingress路径访问策略,请求就可以被拦截做进一步的分发或者校验。

ingress-controller 分为Traefik Ingress Controller 和 Nginx Ingress Controller两种,二者都是 Kubernetes 中用于管理外部访问集群内服务(HTTP/HTTPS 流量)的入口点。Traefik应用于动态配置更新和灵活的服务发现项目,例如说ingress 新增了配置,ingress controller 并不会重启导致服务不可用。重性能和传统Web服务器的强大功能用nginx。

● Nginx Ingress Controller

如下是我本次使用的nginx ingress 的配置,rewrite-target 会重置访问路径,对于aigcpoc.test.com/api/get/job… 的请求才会转发到集群服务,并且路径会被修改成aigcpoc.test.com/get/jobs

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: aigcpoc.test.com
    http:
      paths:
      - backend:
          service:
            name: deploy-kustomize
            port:
              number: 80
        path: /api(/|$)(.*)
        pathType: Prefix

● Traefik Ingress Controller

traefik 的配置参考如下,在这个例子中,IngressRoute 不仅定义了路由规则,还引入了一个名为 my-auth 的中间件来增强请求处理能力。

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: example-ingressroute
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`example.com`) && PathPrefix(`/api`)
      kind: Rule
      services:
        - name: api-service
          port: 80
      middlewares:
        - name: my-auth@kubernetescrd