안녕하세요~!
오늘은 두달간의 삽질을 끝내고 AWS의 End To End Kubeflow install을 기록해보고자 합니다.
급하다고 하나라도 빼먹고 진행했다간 저처럼 끝없는 에러에 휘둘릴지 모르니,
모든 섹션을 정확히 따라하면서 진행하시기 바랍니다!!
시작하기에 앞서 aws에서 kubernetes 인프라를 다루고자 하신다면 아래의 툴들을 먼저 설치해놓으시기 바랍니다. 해당 툴 설치 방법은 다양한 곳에 자료가 많으니 참고하세요!
클러스터가 아직 없으신 분은 먼저 배포를 진행하시기 바랍니다.
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: <클러스터명>
region: <사용하고자 하는 aws 리전>
nodeGroups:
- name: ng <노드 그룹명>
desiredCapacity: 6
instanceType: m5.xlarge
eksctl create cluster -f cluster.yaml
kubectl get nodes
저는 미리 구축된 p2.xlarge 사양의 노드 2개를 가진 클러스터를 이용하였습니다.
kubeflow 설치시 생성되는 총 파드 개수는 50개 이상이니 파드 생성 제한에 걸리지 않게 주의하세요.
eksctl scale nodegroup --cluster=<클러스터명> --nodes=4 ng
AWS 콘솔 - Route 53 - 도메인 등록
원하는 도메인 등록 후 생성자 연락처 정보 기록 및 결제
- .com
도메인의 경우 1년에 12달러입니다.
등록하면 아래와 같이 도메인 정보를 확인할 수 있습니다.
Route 53 - 대시보드 - DNS 관리(호스팅 영역)
호스팅 영역 - 호스팅 영역 생성
도메인 이름 입력 후 호스팅 영역 생성 완료
처음엔 NS, SOA 타입으로 2개의 레코드가 존재합니다. 레코드 생성 버튼을 눌러 A 레코드를 임시로 생성합니다.
AWS 콘솔 - AWS Certificate Manager - 요청 - 퍼블릭 인증서 요청
.<도메인 이름>.com 으로 인증서 요청
- 와일드카드를 이용해 하위 도메인에 대한 모든 인증을 대신합니다.
- 예를 들어 .musma.com이 작성하시면 됩니다.(위에서 생성한 도메인으로)
인증서 검증 대기 상태가 되면 인증서 ID를 클릭해서 세부사항으로 들어간 후, 생성된 CNAME을 기반으로 레코드를 생성해서 DNS 인증을 진행합니다.
인증서의 CNAME이 제대로 생성되었고, 검증 대기 중이라면 필터를 통해 자동으로 레코드 정보가 들어온 것을 볼 수 있습니다. 바로 레코드 생성을 클릭합니다.
시간이 어느정도 지나면(5~15분 정도) 인증서 발급이 완료됩니다.
(중요) 위의 1~6과정을 '버지니아 북부(us-east-1)' 리전에서 똑~같이 반복합니다.
서울 리전의 인증서와 버지니아 리전의 인증서 모두 세부사항으로 들어가서 인증서 arn(ACM arn)을 기록해둡니다. 나중에 사용합니다.
AWS 콘솔 - Cognito - 사용자 풀 관리 - 사용자 풀 생성
사용자 풀 이름 입력 후 기본값 검토
- 풀 이름은 그다지 중요하지 않습니다.
별도의 설정은 하지 않고 그대로 생성하시면 됩니다.(물론 보안을 위해 다양한 설정을 추가할 수 있습니다.)
풀 생성 후 나오는 일반 설정 창에서 풀 ID와 풀 ARN은 중요하니 기록해두시길 바랍니다.
일반 설정 - 앱 클라이언트 항목에 들어가서 '앱 클라이언트' 추가를 진행합니다.
앱 클라이언트 이름은 중요하지 않으니 임의로 생성하고, 아래로 드래그하여 앱 클라이언트 생성을 누릅니다.
- 앱 클라이언트 ID도 나중에 사용하니 따로 기록해두세요!
앱 통합 - 앱 클라이언트 설정에 들어가 아래와 같이 설정합니다.
- 활성화된 자격 증명 공급자 : Cognito User Pool (추후에 OIDC, google 등 다양한 자격 증명 공급자도 추가할 수 있습니다. 로그인 및 회원가입에 이용하는 공급자를 의미합니다.)
- 콜백 URL : https://kubeflow.<도메인 이름>/oauth2/idpresponse
- 로그아웃 URL : https://auth.<도메인 이름>/logout?response_type=code&client_id=<클라이언트 ID>&redirect_uri=https://auth.<도메인 이름>/logout&state=STATE&scope=openid+profile+aws.cognito.signin.user.admin
- 허용된 OAuth Flows : Authorization code grant
- 허용된 OAuth Scopes : email, openid, aws.cognito.signin.user.admin, profile
앱 통합 - 도메인 이름 설정에 들어가 자체 도메인을 구성합니다.
- 도메인 이름 : auth.<도메인 이름>
- AWS 관리형 인증서(중요) : us-east-1에 인증서가 존재한다면 아래 이미지처럼 인증서가 선택됩니다. 아니라면 위 섹션에서 다시 버지니아 북부 리전에 인증서를 생성하세요.
- 변경 내용 저장을 눌러 저장합니다. 다만 위 섹션에서 인증서 DNS 인증을 진행한 뒤로, 아직 발급되지 않은 상태라면(시간이 좀 걸릴 수도 있습니다.) 변경 내용이 저장되지 않습니다. 인증서 발급이 완료된 것을 확인한 후 진행해주시면 되겠습니다.
변경 사항이 적용되면 아래에 Alias Target DNS 주소가 생성됩니다. 해당 주소를 복사해서 위 섹션에서 임시로 생성한 Route 53의 A 레코드(127.0.0.1로 임시 지정해놨었죠?)를 별칭 사용으로 변경하여 해당 주소로 변경해주시면 됩니다.
- 전 이미 해당 도메인을 하나 사용하고 있기 때문에 auth2.<도메인이름>
으로 진행했습니다. 사실 같은 도메인에서 유저 풀만 다르게 해서 진행하고 싶은데 이렇게 두 번 생성하지 않고 기존의 도메인을 그대로 사용해도 될 것 같긴 합니다.
- 트래픽 라우팅 대상을 CloudFront 배포에 대한 별칭으로 설정하고, 8번에서 복사한 별칭을 그대로 붙여넣기 하신 뒤 레코드를 생성해주시면 됩니다.
아래와 같이 자체 도메인이 Active 상태로 변경됐는지 확인해주세요!
export AWS_DEFAULT_PROFILE=<프로파일명>
kubectl config use-context <사용할 컨텍스트>
mkdir env-kr, cd env-kr, wget ~
을 진행하시면 됩니다.wget https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_aws_cognito.v1.2.0.yaml
vim kfctl_aws_cognito.v1.2.0.yaml
auth.<도메인이름>
) - kind: KfAwsPlugin
metadata:
name: aws
spec:
auth:
cognito:
certArn: arn:aws:acm:eu-west-1:xxxxx:certificate/xxxxxxxxxxxxx-xxxx
cognitoAppClientId: xxxxxbxxxxxx
cognitoUserPoolArn: arn:aws:cognito-idp:ap-northeast-2:xxxxx:userpool/eu-west-1_xxxxxx
cognitoUserPoolDomain: auth.platform.domain.com
region: ap-northeast-2
#roles:
#- eksctl-aiplatform-aws-nodegroup-ng-NodeInstanceRole-xxxxx
kfctl apply -V -f kfctl_aws_cognito.v1.2.0.yaml
kubectl get ingress -n istio-system
명령을 실행하여 Address 파트에 DNS 주소가 정상적으로 나오는지 확인합니다. 설치후 3분 정도 소요될 수 있습니다.https://<받아온 주소>/oauth2/idpresponse
*.<도메인이름> / CNAME / <받아온 주소>
*.default.<도메인이름> / CNAME / <받아온 주소>
<도메인 이름> / A / 클래식 로드 밸런스에 뜨는 리소스(dualstack.<받아온 주소>
값/트래픽 라우팅 대상
이 일치하지 않는 문제가 있습니다.service 'istiod' not found
: 다른 버전의 istio를 설치하지 마세요!
failed calling webhook "webhook.cert-manager.io" : 웹훅을 불러오지 못하는 에러
- 여러 문제는 기다리면 해결됩니다.(설치 중)
- 두 세번 배포(kfctl apply)를 재시도해보시고 안되면 오류 메세지를 잘 확인해보세요.
오류 메세지 중 crd 관련 로그가 있다면, kubectl get crd -A
혹은 특정 네임스페이스 관련 crd kubectl get crd | grep <관련 기능>
으로 검색해서 삭제하시면 되겠습니다.
kubectl patch crd/issuers.cert-manager.io -p '{"metadata":{"finalizers":[]}}' --type=merge
kubectl delete crd/issuers.cert-manager.io
설치/삭제 중 너무나 많은 오류가 발생하지만, 오류 기재하기엔 기록해놓은 것이 없네요. 여러분이 겪으실 대부분의 문제는 저도 겪어봤으니 댓글 남겨주시면 최선을 다해 도와드리도록 하겠습니다.
kubernetes.io/cluster/<클러스터명>:shared
, kubernetes.io/role/elb:1
kubernetes.io/cluster/<클러스터명>:shared
, kubernetes.io/role/internal-elb:1
kfctl delete -V -f kfctl_aws_cognito.v1.2.0.yaml
ClusterName: <컨텍스트명>
을 추가해주시면 됩니다.kubectl get namespaces
를 확인하면 kubeflow 관련한 모든 네임스페이스가 Terminating 상태에 빠졌을 겁니다. 아래 명령을 활용해서 하나씩 모두 해제해줍니다.NAMESPACE=<네임스페이스명>
명령에 해제할 네임스페이스명을 바꿔 넣어주면서 반복 실행하시면 되겠습니다. proxy는 한번만 실행해도 됩니다. $ kubectl proxy &
$ NAMESPACE=kubeflow
$ kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize
kubectl delete clusterroles katib-controller katib-ui ml-pipeline-persistenceagent ml-pipeline-viewer-controller-role pipeline-runner
kubectl delete clusterrolebindings katib-controller katib-ui ml-pipeline-persistenceagent ml-pipeline-scheduledworkflow ml-pipeline-viewer-crd-role-binding pipeline-runner
kubectl delete validatingwebhookconfiguration istio-gallay istiod-system admission-webhook-mutating-webhook-configuration experiment-mutating-webhook-config istio-sidecar-injector mutating-webhook-configuration
kubectl delete crd applications.app.k8s.io
kubectl get configmap -o name -n kube-system | egrep 'cert-manager'|xargs kubectl delete -n kube-system
kubectl get mutatingwebhookconfiguration -o name | egrep 'kubeflow|katib'|xargs kubectl delete
kubectl get crd -o name| egrep 'kubeflow|istio|certmanager|cert-manager|applications.app.k8s.io'|xargs kubectl delete
kubectl get clusterrole -o name| egrep 'kubeflow|istio'|xargs kubectl delete
kubectl get clusterrolebinding -o name| egrep 'kubeflow|istio'|xargs kubectl delete
kubectl get namespaces
kubectl get clusterroles -A
kubectl get crd -A
kubectl get pods -A
kubectl get validatingwebhookconfiguration -A