由于公司的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
,我们可以发现以下几点:
- kubeflow仅使用了argo-workflows的workflow-controller组件,并未部署argo-server等
- workflow-controller默认采取了cluster模式部署
- 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