Kubeflow V1.4 설치 및 초기 설정(User 추가, CORS, dex DB 분리)

Seokbin·2022년 2월 17일
5
post-thumbnail

1. Kubeflow 설치


kubeflow의 경우 kubeflow manifest github를 통해 손쉽게 설치 할 수 있습니다. 우선 kubernetes cluster는 구성되어있다고 가정하고 kustomize를 설치해야됩니다.

#kubeflow 1.4의 경우 kustomzie 4.x 버전에 호환이 안됩니다.
wget https://github.com/kubernetes-sigs/kustomize/releases/download/v3.2.0/kustomize_3.2.0_linux_amd64
gmv kustomize_3.2.0_linux_amd64 /usr/local/bin/kustomize

이후 프로젝트를 clone 한 후 매니페스트를 적용하면 됩니다. 기본적으로 multi-user 기반 pipeline으로 설치 됩니다.

  • manifests/common/user-namespace/base/params.env
  • manifests/common/dex/base/config-map.yaml

파일에서 기본 User에 대한 내용을 바꾸고 설치합니다. 변경이 없으면 user@example.com /1234123 로 설치 됩니다.

git clone https://github.com/kubeflow/manifests.git

while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

위의 커맨드로 kubeflow에 포함된 컴포넌트를 각각 배포합니다 (처음 시도시 kubectl apply 가 정상적으로 안되는 경우가있는데 이는 재시작 하면 됩니다) 정상적으로 설치되면 다음과 같은 네임스페이스에 파드가 모두 running 상태인 것을 확인 할 수있습니다.

설치를 진행하며 대부분의 파드가 정상적으로 running인 것을 확인했지만 kubeflow 네임스페이스에서 cache-deployment 등 조금씩 error가 발생하는 것을 확인 했습니다. 이러한 이유는 대부분 kubernetes 와 kubeflow version 호환성 문제로 보입니다. 저의 경우 kubernetes version v1.21.1 에서 kubeflow v.1.4.1설치는 오류가 있었지만 v1.4.0의 경우 정상적으로 설치 되었습니다. 따라서 설치 된 환경과 호환성 검토를 한 후 맞는 버전을 설치 해야됩니다.

2. Kubeflow Dashboard 접근


공식 github에서는 포트포워딩을 통해 대쉬보드로 접근하도록 간단하게 설명되어있지만 저는 Cluster가 VM으로 구성되어있기 때문에 localhost로 접근이 불가능했습니다. kubeflow 설치시 istio-system 에서 다음과 같은 내용을 볼 수 있습니다.

istio-ingressgateway가 NodePort로 생성되었기 때문에 [istio gateway pod가 생성된 노드의 IP:32082] 로 접속 시 접근이 가능합니다.


3. CSRF 문제 해결


위에서 접근하고 사용하면 정상적으로 실행된거 같지만 notebook이나 tensorboard 같은 kubeflow 기능을 사용할 때 권한 거부 문제가 발생합니다.

Kubeflow에서 사용하는 web은 Secure cookies를 사용하기 있기 때문에 이를 위한 HTTPS 세팅이 필요합니다.

kubectl edit -n kubeflow gateways.networking.istio.io kubeflow-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP
    tls:
      httpsRedirect: true
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

kubeflow gateway에서 http로 들어오는 통신을 https로 redirect 하고 TLS에 필요한 crt, key를 설정합니다.이후 TLS 접근을 위한 서버 인증서를 만들어 주도록합니다.

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: istio-ingressgateway-certs
  namespace: istio-system
spec:
  commonName: istio-ingressgateway.istio-system.svc
  # Use ipAddresses if your LoadBalancer issues an IP
  ipAddresses:
  - 172.16.156.10
  # Use dnsNames if your LoadBalancer issues a hostname (eg DNS name from Civo dashboard)
  #dnsNames:
  #- <LoadBalancer HostName>
  isCA: true
  issuerRef:
    kind: ClusterIssuer
    name: kubeflow-self-signing-issuer
  secretName: istio-ingressgateway-certs

이후 https://[LB IP]:[LB Port] 로 접근하면 접속 후 정상적으로 notebook 생성이 가능합니다. 하지만 VDI 외부에서도 접근하기 위해 이를 포트포워딩 해야되기 때문에 이를 위한 인증서 설정도 해야되서 위의 방법이 아닌 임시적으로 Secrue Cookies 모드를 해제하는 방법으로 사용했습니다.

k edit deploy jupyter-web-app-deployment -n kubeflow

.
.
spec:
      containers:
      - env:
        - name: APP_SECURE_COOKIES
          values: "false"

다음과 같이 web과 관련된 파드에서 Secured_cookies를 해제하는 환경 변수를 추가하였습니다. 이 방법은 공식적으로 추천하지 않는 방법이므로 실제 운영서버에서는 HTTPS를 사용하도록 해야합니다.


이후 Notebook이 정상적으로 실행되는 것을 확인 할 수 있습니다.

4. User 추가


다른 사용자를 추가하기 위해서는 두가지 과정이 필요합니다. dex 에서 ID/PW를 생성하고 이를 위한 Profile 을 작성해야합니다.

#manifest/common/dex/base/config-map.yaml
- email: testuser@mz.co.kr
      hash: $2y$12$4K/VkmDd1q1Orb3xAt82zu8gk7Ad6ReFR4LCP9UeYE90NLiN9Df72
      # https://github.com/dexidp/dex/pull/1601/commits
      # FIXME: Use hashFromEnv instead
      username: test
      userID: "test"

staticPassword 항목에 User 정보를 추가하고 hash에 bcrypt된 패스워드를 입력합니다. 이후 변경사항을 configmap에 적용합니다. 이후 변경사항 적용을 위해 dex를 재실행합니다.

k rollout restart deployment dex -n auth

이후 해당 ID/PW로 접속시 로그인이 가능합니다. 하지만 namespace가 지정되지 않아 자원을 생성할 수 없습니다

이를 위한 Profile을 생성합니다.

#profile.yaml
apiVersion: kubeflow.org/v1beta1
kind: Profile
metadata:
  name: testuser
spec:
  owner:
    kind: User
    name: testuser@mz.co.kr
  resourceQuotaSpec:
    hard:
      cpu: "2"
      memory: 2Gi
      persistentvolumeclaims: "1"
      requests.storage: "5Gi"

resource를 할당하고 Profile을 생성합니다. 생성이 완료되면 User 이름으로 namespace가 생성되고 재 접속시 Namespace가 할당된 것을 확인 할 수 있습니다.

5. Dex db 분리


위와 같이 ConfigMap으로 User 정보를 관리하는 것은 보안 문제가 생겨 DB로 저장하는 방식으로 변경 하였습니다.DB는 Postgres를 사용하였습니다.
5-1 .Postgres Database,User 생성

create database dex;
create user dex with encrypted password 'mypassword';
grant all privileges on database dex to dex;

5-2. Dex configMap 변경
dex configmap에서 다음과 같이 Postgres 접속 정보를 작성합니다.

    
data:
  config.yaml: |
    issuer: http://dex.auth.svc.cluster.local:5556/dex
    storage:
      type: postgres
      config:
        host: 172.16.156.24
        port: 32442
        database: dex
        user: dex
        password: mypassword
        ssl:
          mode: "disable"

이후 kubectl rollout restart deploy dex -n auth 로 재시작 후 Log를 확인 하면 정상적으로 Postgres와 접속 한 것을 확인 할 수 있습니다. dbeaver로 Postgres에 접속했을 때 다음과 같은 엔티티 관계도를 가진 데이터베이스를 확인 할 수 있습니다.

5-3 User정보 테이블에 Insert
기존에 static password로 넣은 정보를 Password 테이블에 넣습니다.

insert into password values('seokbin@mz.co.kr','$2y$12$4K/VkmDd1q1Orb3xAt82zu8gk7Ad6ReFR4LCP9UeYE90NLiN9Df72','seokbin','seokbin');

해당 정보로 Kubeflow에 로그인시 접속이 가능합니다. 하지만 Profile을 생성하지 않아 Namespace를 할당받지 않아 리소스를 생성할 수 없습니다.이를 위해 위에서 작성한 Profile을 생성해줍니다.
Profile 생성시 정상적으로 Namespace를 할당받은 것을 확인 할 수 있습니다.

1개의 댓글

comment-user-thumbnail
2023년 10월 13일

선생님 안녕하세요 포스팅 잘봣습니다 저는 mariadb 로 테스트하려고하는데
kubeflow에서는 postgres DB에서 password 라는 테이블을 참조하여 로그인한건가요?

답글 달기