IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    如何把Kubeflow的Argo用起来

    Windfarer发表于 2021-08-24 10:41:00
    love 0

    由于公司的CI/CD系统特别垃圾,还不如一些开源货靠谱,而我这边又有一些构建项目部署到AWS的需要,所以就在之前部署的kubeflow上动起了脑筋,它里面有集成了argo,也许可以把它用起来。

    argo是个基于kubernetes的项目,包含多个组件,其中argo-workflows就是工作流引擎,有点类似airflow,它可以编排各种容器,控制工作流的执行。

    kubeflow内部使用了argo-workflow作为pipeline底层的任务编排组件,换句话说,你运行的每个pipeline任务,底层都是一个workflow在跑,由argo-workflows做控制。

    但是在目前的版本中,kubeflow默认并没有把argo-server等组件装上,只部署了它需要的workflow-controller。并且由于采用manifests默认安装的kubeflow的argo-workflows是采用cluster(可以理解为集群全局)模式安装,所以我们直接再用namespaced方式再部署一套argo也不太行得通,会受到kubeflow里面那个的影响。

    于是我研究了一下如何直接把kubeflow内部集成的这个argo-workflows抠出来用,就形成了本文,邪门歪道,仅供参考。

    本文基于Kubeflow Pipelines 1.7.0
    对应的Argo Workflows版本是3.1

    准备

    通过研究kubeflow pipeline下面的third_party/argo目录和argo-workflows的manifests,我们可以发现以下几点:

    1. kubeflow仅使用了argo-workflows的workflow-controller组件,并未部署argo-server等
    2. workflow-controller默认采取了cluster模式部署
    3. kubeflow使用的workflow-controller部署方式基本继承自argo-workflows本体提供的方式,对镜像也没有什么破坏性的修改

    基于以上几点,我们就可以尝试直接部署argo相关的组件,来补全argo相关的功能,以便可以独立使用argo。我这里只部署argo-workflows(argo-server)和argo-events。

    Argo Workflows: argo-server

    这个其实相当于argo-workflows的管理界面前后端,这里如果不嫌麻烦的话,可以去argo-workflows官方的manifests下面把argo-server组件相关的部署到kubeflow namespace下。而我的做法更简单粗暴一些,在部署的时候直接改了kubeflow pipelines里面的配置,在kustomization.yaml里面,把被剔除的对上游的依赖

    - ../upstream/manifests/base/argo-server
    - ../upstream/manifests/base/cluster-install/argo-server-rbac
    

    重新加回来。然后像往常一样部署整个pipeline组件,argo-server就应该一起被装上去了。

    注意需要修改上面路径里的argo-server这个配置文件的内容,由于之前的里面镜像tag写了latest,这里需要改回3.1.x,如果是3.2在UI展示上似乎有变化无法显示

    https://quay.io/repository/argoproj/argocli?tab=tags 这里找个合适的3.1版本。

    装完之后,可能还需要一些设置,我这里是直接通过istio把argo-server的界面暴露出去的,你也可以参考argo官方的ingress配置,使用nginx之类的来做这个暴露。(其实这个比用istio方便一点,不需要处理访问权限相关的问题)

    对argo-server部署上面做相应的修改,以便能正确暴露,使用下面的命令进行yaml编辑:

    kubectl edit deployment -n kubeflow argo-server
    

    下面是我主要修改的部分节选,主要改了几个:

    • args里面加了--x-frame-options=因为我是通过kubeflow的istio统一暴露出去的,所以它的页面是通过iframe展示的,需要配置这个参数为空来允许这样访问。
    • args里面--secure=false是因为我是采用HTTP来访问该服务,如果你用HTTPS可以不改。
    • BASE_HREF环境变量配置成/argo/还是因为通过istio的子路由进行访问,需要加这个前缀
    • readinessProbe的httpGet scheme字段从HTTPS改为HTTP,因为我的服务用secure=false已经是HTTP服务了,这样改才能让健康检查通过。
        spec:
          containers:
          - args:
            - server
            - --x-frame-options=
            - --secure=false
            env:
            - name: BASE_HREF
              value: /argo/
            image: quay.io/argoproj/argocli:latest
            imagePullPolicy: Always
            name: argo-server
            ports:
            - containerPort: 2746
              name: web
              protocol: TCP
            readinessProbe:
              failureThreshold: 3
              httpGet:
                path: /
                port: 2746
                scheme: HTTP
    

    然后给istio加个virtualservice ,把下面这坨东西apply了,注意其把/argo/rewrite成/,这样才能访问到静态资源,我也懒得研究为啥it works,又不是不能用。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      namespace: kubeflow
      name: argo
    spec:
      gateways:
      - kubeflow/kubeflow-gateway
      hosts:
      - '*'
      http:
      - match:
        - uri:
            prefix: /argo/
        rewrite:
          uri: /
        route:
        - destination:
            host:  argo-server.kubeflow.svc.cluster.local
            port:
              number: 2746
        timeout: 300s
    

    还需要给argo-server加个AuthorizationPolicy,不然会有RBAC的报错

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: argo-server
      namespace: kubeflow
    spec:
      action: ALLOW
      rules:
      - {}
      selector:
        matchLabels:
          app: argo-server
    

    也许这时候访问/argo/还是不行,那么需要改argo-server的service配置, 以便能让istio能正确认识该用哪个协议访问下游

    kubectl edit service -n kubeflow argo-server
    

    把服务的name从web改成http-web
    这时候应该就能在/argo/路径访问到argo的管理界面了。

    由于它默认是用client模式进行身份认证,所以你可以exec一下生成token的命令,来获取token以便登录进去。

    kubectl exec -it -n kubeflow <your-argo-server-container> argo auth token
    

    Argo Events

    如果需要一些外部的服务(比如GitHub和GitLab的webhook)触发workflow,可以用argo-events,这个是argo的另外一个组件,可以单独部署。跟着argo-events的官方文档使用cluster模式安装即可。

    给argo-events配置各种权限:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      namespace: argo-events
      name: operate-workflow-sa
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: operate-workflow-role
      namespace: argo-events
    rules:
      - apiGroups:
          - argoproj.io
        verbs:
          - "*"
        resources:
          - workflows
          - clusterworkflowtemplates
          - workflowtemplates
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: operate-workflow-role-binding
      namespace: argo-events
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: operate-workflow-role
    subjects:
      - kind: ServiceAccount
        name: operate-workflow-sa
        namespace: argo-events
    

    使用

    通过上述的折腾,应该是基本能用了,但还有一些限制要知道。对于kubeflow的用户namespace,因为上面有istio-injection=enabled的label存在,所以所有在里面启动的pod都会默认被注入一个istio sidecar劫持流量,但在我们argo workflow运行时,通过sidecar通信会有问题,因此如果需要在用户namespace下运行workflow时,需要在workflow配置中显式设置

    metadata:
      annotations:
        sidecar.istio.io/inject: 'false'
    

    取消掉istio sidecar,以便容器间能够正常通信。

    另外,还需要配置serviceAccountName: default-editor,这个应该是kubeflow在用户namespace默认生成的serviceaccount,如果需要用ns下的某些资源的话,配这个基本没啥问题。

    由于上述不便,可能在单独的namespace下运行argo workflows和events的pod更好一些。

    参考:

    • Argo Workflows Docs
    • Argo Events Docs
    • Argo(events) Trigger an existing ClusterWorkflowTemplate using Sensor


沪ICP备19023445号-2号
友情链接