Press "Enter" to skip to content

如何把Kubeflow的Argo用起来

由于公司的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 pipeline下面的third_party/argo
目录和argo-workflows的manifests
,我们可以发现以下几点:

 

 

    1. kubeflow仅使用了argo-workflows的workflow-controller组件,并未部署argo-server等

 

    1. workflow-controller默认采取了cluster模式部署

 

    1. 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就应该一起被装上去了。

 

装完之后,可能还需要一些设置,我这里是直接通过istio把argo-server的界面暴露出去的,你也可以参考argo官方的ingress配置
,使用nginx之类的来做这个暴露。

 

对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

 

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以便登录进去。

 

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

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注