kubeflow pipeline을 구축하다보면 전처리가 되지 않은 원시 데이터 파일을 어딘가에서 받아오거나,
원시 데이터 파일을 전처리 후 어딘가에 저장한 후, 훈련에 사용하기 위해 해당 파일을 다시 불러오거나,
훈련 후 matrics 및 각종 결과 파일 및 모델을 어딘가에 저장하고 시각화 및 배포 등을 진행하게 됩니다.
이 때 이 어딘가에 저장한다는 개념이 아티팩트, 오브젝트라고 생각하면 되는데
제대로 설정해놓지 않으면 artifact repository를 찾을 수 없다는 오류로 파이프라인이 정상적으로
진행되지 않는 모습을 확인할 수 있습니다.
예를 들어 이런 모습입니다.
정상적으로 데이터를 로드했지만, 로드한 데이터를 어떠한 과정(전처리 등)을 거친 후 저장하고 다음 파이프라인(training-pipeline)으로 넘어가야 하는데 오루가 발생합니다.
cannot get key for artifact location. because it is invaild
해당 오류를 검색해봐도 제대로 설명된 곳이 많이 없어서 이슈를 해결하기 위해 설정한 것들을 하나씩 정리해보고 넘어가려합니다.
my-s3-credentials
라는 secret을 만들어 aws s3 bucket에 접근하기 위한 aws accesskey와 secretkey를 base64로 encoding해서 생성합니다.(workflow-controller-configmap이 kubeflow namespace에 있기 때문에 kubeflow에 생성했습니다.)kubectl edit -n kubeflow configmap/workflow-controller-configmap
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
config: |
{
executorImage: argoproj/argoexec:v3.2,
containerRuntimeExecutor: emissary,
artifactRepository:
{
s3: {
endpoint: s3.amazonaws.com,
bucket: mlpl,
accessKeySecret: {
name: my-s3-credentials,
key: accesskey
},
secretKeySecret: {
name: my-s3-credentials,
key: secretkey
}
}
}
}
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"config":"{\nexecutorImage: argoproj/argoexec:v2.3.0,\ncontainerRuntimeExecutor: docker,\nartifactRepository:\n{\n s3: {\n bucket: mlpipeline,\n keyPrefix: artifacts,\n endpoint: minio-service.kubeflow:9000,\n insecure: true,\n accessKeySecret: {\n name: mlpipeline-minio-artifact,\n key: accesskey\n },\n secretKeySecret: {\n name: mlpipeline-minio-artifact,\n key: secretkey\n }\n }\n}\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"argo","app.kubernetes.io/name":"argo","kustomize.component":"argo"},"name":"workflow-controller-configmap","namespace":"kubeflow"}}
creationTimestamp: "2021-11-16T23:38:33Z"
labels:
app.kubernetes.io/component: argo
app.kubernetes.io/name: argo
kustomize.component: argo
name: workflow-controller-configmap
namespace: kubeflow
resourceVersion: "45712166"
uid: f2db86b2-55d2-4755-b215-b20c64c11fc9
export
를 이용해서 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 지정하고 시크릿을 아래와 같이 생성해주면 되지만 저는 minio키(minio/minio123)을 사용했을 때 kubectl 이용을 위한 권한 인증이 풀려버리는 이슈가 있어서 해당 명령을 입력하고 직접 kubectl edit
으로 수정했습니다.kubectl -n moey920 create secret generic kfp-aws-secret \
--from-literal=AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
--from-literal=AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
kubectl edit secret/kfp-aws-secret -n moey920
minio/minio123
이기 때문에 그냥 보여드립니다. 동일한 인코딩 문자열을 사용해도 됩니다.apiVersion: v1
data:
AWS_ACCESS_KEY_ID: bWluaW8=
AWS_SECRET_ACCESS_KEY: bWluaW8xMjM=
kind: Secret
metadata:
creationTimestamp: "2021-12-16T07:39:11Z"
name: kfp-aws-secret
namespace: moey920
resourceVersion: "46682073"
uid: 6cee3a61-25c6-49a7-8289-342442c7b811
type: Opaque
kubectl -n moey920 create secret generic aws-secret \
--from-literal=AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
--from-literal=AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
kubectl edit secret/aws-secret -n moey920
apiVersion: v1
data:
AWS_ACCESS_KEY_ID: <당신의 AWS_ACCESS_KEY_ID>
AWS_SECRET_ACCESS_KEY: <당신의 AWS_SECRET_ACCESS_KEY>
kind: Secret
metadata:
creationTimestamp: "2021-12-16T08:24:22Z"
name: aws-secret
namespace: moey920
resourceVersion: "46728108"
uid: 5e9d0def-e05d-4ebf-94c1-f0fd4b8deeb6
type: Opaque
kubectl -n kubeflow port-forward svc/minio-service 9000:9000
localhost:9000
접속secret_name = "kfp-aws-secret"
시크릿을 지정하고 엔드포인트를 포트포워딩한 서버 주소로 보내는 것입니다.import kfp
from kfp import dsl
from kubernetes.client.models import V1EnvVar, V1EnvVarSource, V1SecretKeySelector
@dsl.pipeline(
name='pipeline_minio',
description = "pipeline_minio"
)
def pipeline_minio():
secret_name = "kfp-aws-secret"
s3_endpoint = 'minio-service.kubeflow.svc.cluster.local:9000'
minio_endpoint = "http://" + s3_endpoint
minio_region = "us-east-1"
dsl.ContainerOp(
name='mnist-s3',
image='kangwoo/kfp-mnist-storage:0.0.1',
arguments=['--model', 's3://mlpl']
).add_env_variable(V1EnvVar(name='S3_ENDPOINT', value=s3_endpoint)) \
.add_env_variable(V1EnvVar(name='AWS_ENDPOINT_URL', value=minio_endpoint)) \
.add_env_variable(V1EnvVar(name='AWS_ACCESS_KEY_ID',
value_from=V1EnvVarSource(
secret_key_ref=V1SecretKeySelector(name=secret_name, key='AWS_ACCESS_KEY_ID')))) \
.add_env_variable(V1EnvVar(name='AWS_SECRET_ACCESS_KEY',
value_from=V1EnvVarSource(secret_key_ref=V1SecretKeySelector(name=secret_name,
key='AWS_SECRET_ACCESS_KEY')))) \
.add_env_variable(V1EnvVar(name='AWS_REGION', value=minio_region)) \
.add_env_variable(V1EnvVar(name='S3_USE_HTTPS', value='0')) \
.add_env_variable(V1EnvVar(name='S3_VERIFY_SSL', value='0'))
if __name__ == '__main__':
my_run = kfp.Client().create_run_from_pipeline_func(pipeline_minio, arguments={},
experiment_name='Sample Experiment')
minio의 1번은 동일하게 참고해주세요.
파이프라인 코드
import kfp
from kfp import aws
from kfp import dsl
from kubernetes.client.models import V1EnvVar
@dsl.pipeline(
name='pipeline_s3',
description = "pipeline_s3"
)
def pipeline_use_aws_secret():
secret_name = "aws-secret"
dsl.ContainerOp(
name='mnist_use_aws_secret',
image='kangwoo/kfp-mnist-storage:0.0.1',
arguments=['--model', 's3://mlpl']
).apply(aws.use_aws_secret(secret_name,
aws_access_key_id_name='AWS_ACCESS_KEY_ID',
aws_secret_access_key_name='AWS_SECRET_ACCESS_KEY')) \
.add_env_variable(V1EnvVar(name='AWS_REGION', value='ap-northeast-2'))
if __name__ == '__main__':
my_run = kfp.Client().create_run_from_pipeline_func(pipeline_use_aws_secret, arguments={},
experiment_name='Sample Experiment')
해당 오류를 해결하기 위해 오랜 기간 레퍼런스를 찾아보며 수정했기 때문에 위에 적은 사항 이외에 설정한 것이 있는지 잘 기억이 나질 않습니다. 안되면 댓글 달아주시면 추가로 확인해보겠습니다.