블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

VM 수준의 보안을 제공하는 gVisor

조대협 (http://bcho.tistory.com)


Docker와 같은 일반적인 컨테이너 모델의 문제점은 Host Kernel을 공유하기 때문에, privilege escalation을 통해서 Host Kernel 을 접근해서 전체 시스템을 장악할 수 있다는 문제점이 있다. privilege escalation을 SeLinux나 컨테이너 정책으로 막는다고 하더라도, 버그등으로 인해서 Host Kernel 로의 접근을 허용할 수 있는 잠재적인 보안 위협이 있다.

컨테이너에 비해서 VM은 하드웨어 계층 부터 가상화를 해서, 전체를 Isolation 시키기 때문에, 보안적으로는 상대적으로 우세하지만, 전체적으로 무겁다는 단점을 가지고 있다.

이런 문제를 해결하기 위해서 VM과 컨테이너의 장점을 조합해서 만든 것이 gVisor 라는 오픈소스이다.


기본적으로 Host Kernel 위에서 KVM을 통해서 Kernel 을 Emulation한다. VM처럼 하드웨어 전체를 Emulate 하는 것이 아니라, Emulated 된 커널을 올릴 수 있도록 하고, 이 커널과 컨테이너는 User space에서 실행된다.

일반적인 컨테이너의 경우 컨테이너는 User space에서 실행되지만, system call을 통해서 Kernel space로 접근이 가능한데, gVisor의 경우에는 user space에 emulated 된 커널을 올려서, system call이 발생하더라도 user space를 벗어나지 않도록 해준다. 


아래 그림은 gVisor와 K8S의 관계 개념도인데, 쿠버네티스가 컨테이너를 생성 관리 하려면 컨테이너런 타임이 있어야 하는데,  gVisor의 runtime은 runsc이다. runsc는 OCI 규격을 준수하고 있기 때문에 쿠버네티스에서 기존의 컨테이너등과 호환이 가능하게 된다.   gVisor의 컨테이너는 컨테이너와 Sentry라는 가상화된 커널로 구성되며 이는 user space에서 기동된다. 


<출처 : https://www.youtube.com/embed/TQfc8OlB2sg


이러한 구조를 통해서 VM 수준의 Isolation을 제공함으로써 높은 보안을 제공한다. 

현재 Google Kubernetes Engine (이하 GKE)에서 옵션으로 활성화가 가능하며, Pod spec에 아래 그림과 같이 runtimeClassName 을 gvisor로 정해주면 된다.


apiVersion: apps/v1

kind: Deployment

metadata:

  name: httpd

  labels:

    app: httpd

spec:

  replicas: 1

  selector:

    matchLabels:

      app: httpd

  template:

    metadata:

      labels:

        app: httpd

    spec:

      runtimeClassName: gvisor

      containers:

      - name: httpd

        image: httpd


이렇게 하면 이 Pod는 gvisor를 통해서 isolation이 된다. 일반적인 애플리케이션인 java,node.js,ruby 나 redis나 mysql과 같은 범용 애플리케이션은 잘 동작하지만


gVisor는 높은 수준의 보안을 요구 하는 애플리케이션이나 특히 대외로 서비스 되는 Multi tenant application의 경우 높은 isolation 레벨을 제공해서, 다른 Pod 들이 영향을 받지 않도록 하는데 유용하게 사용할 수 있다. 


이러한 장점은 있지만 역시 만능은 아니고 제약 사항이 분명히 있다.

  • HostPath 볼륨 사용불가

  • Istio 사용불가

  • 일부 PSP 사용불가

  • Pod나 컨테이너 레벨 모니터링 불가

  • Kernel 의 특정 보안 모듈 secomp,Apparmor,Selinux 등 사용 불가

  • GPU 등 사용불가

자세한 제약 사항은 https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods#limitations 문서를 참고하기 바란다. 



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

  1. 조윤희 2019.09.24 08:22  댓글주소  수정/삭제  댓글쓰기

    GPU, TPU 지원되는 VM 이나, privilege 설정없이 TPU를 사용할수있는 docker는 없나요?

XGBoost 개념 이해

빅데이타/머신러닝 | 2019.09.17 23:31 | Posted by 조대협

XGBoost 알고리즘의 개념 이해


조대협 (http://bcho.tistory.com)


XGBoost는 Gradient Boosting 알고리즘을 분산환경에서도 실행할 수 있도록 구현해놓은 라이브러리이다. Regression, Classification 문제를 모두 지원하며, 성능과 자원 효율이 좋아서, 인기 있게 사용되는 알고리즘이다.


XGBoost는 여러개의 Decision Tree를 조합해서 사용하는 Ensemble 알고리즘이다.

먼저 Decision Tree에 대한 개념을 보면 다음과 같다. 여러개의 이진 노드를 겹쳐서 피쳐별로 판단을 해서 최종 값을 뽑아내는 형태가 된다. 


<그림. Decision tree>


Ensemble은 여러개의 모델을 조합해서 그 결과를 뽑아 내는 방법이다. 정확도가 높은 강한 모델을 하나 사용하는 것보다, 정확도가 낮은 약한 모델을 여러개 조합 하는 방식이 정확도가 높다는 방법에 기반한 방법인데, 


Ensemble은 방식에 따라서 Bagging과 Boosting 으로 분류된다.

Bagging

Bagging은 여러 모델을 사용할때, 각 모델에서 나온 값을 계산하여, 최종 결과값을 내는 방식이다.

예를 들어 아래 그림과 같이 모델 m1,m2,m3 3개의 모델이 있을때, 입력 데이터 X를 모델 m1~3에 넣고, 그 결과값을 받아서 합산 (또는 평균등 여러가지 방법이 있음)해서, 최종 결과를 취하는 방식이다. 

모델 m1~m3 로 데이터를 넣을때는 원본 데이타 x에서 매번 다시 샘플링을 해서 다른 샘플 데이터를 각각 모델에 넣는 방식이 된다. 



<그림 bagging 개념도>

Boosting

Boosting은 원리가 다른데 먼저 m1~3 모델이 있을때, m1에는 x에서 샘플링된 데이터를 넣는다. 그리고, 나온 결과중에서, 예측이 잘못된 x중의 값들에 가중치를 반영해서 다음 모델인 m2에 넣는다.  마찬가지로 y2 결과에서 예측이 잘못된 x’에 값들에 가중치를 반영해서 m3에 넣는다. 

그리고, 각 모델의 성능이 다르기 때문에, 각 모델에 가중치 W를 반영한다. 이를 개념적으로 표현하면 다음과 같은 그림이 된다. 



<그림 Boosting 개념도>


이를 이론적으로 다시 표현해보면

y=m1(x)+error(x) 모델 m1이 x에 대해서 제대로 예측할 확률이 y라고 하고, 이 정확도를 높이려면

error(x)를 작게 하는 모델을 적용하면 되는데, error(x) = m2(x) + error2(x)라고 볼 수 있다. 마찬가지로 error(x)를 작게 하려면 error2(x)를 작게 하면 되는데, 그러기 위해서는 여기에 다른 모델을 적용하면 된다. 즉 error2(x) = m3(x)+error3(x)가 되고, 이를 식으로 합치면


y= m1(x)+m2(x)+m3(x)+error3(x)


가 된다.

이렇게 하면 m1,m2,m3 모델의 가중치가 같기 때문에, 서로 모델이 간섭을 하여, 좋은 결과를 내기 어렵다. 그래서, 각 모델에 가중치를 반영한다.


y = W1m1(x)+W2m2(x)+W3m3(x)+error3(x)


와 같은 식이 된다. 정확한 수식은 아니지만 전체적인 개념을 이해하는 용도 정도로 이해하기 바란다. 

Boosting 기법을 이용하여 구현한 알고리즘은 Gradient Boost 가 대표적인데, 이 알고리즘을 병렬  학습이 지원되도록 구현한 라이브러리가 XGBoost 이다.

성능이 좋고, 컴퓨팅 자원 활용률이 좋아서 근래에 많이 사용되고 있고, 특히 Kaggle 상위 랭커들이 많이 사용하면서 더 유명해지고 있다.



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

CRI & OCI


기본적으로 도커 기반의 쿠버네티스는 다음과 같은 구조로 작동을 했었다. Kubelet이 명령을 받으면, Docker runtime을 통해서 컨테이너를 생성하거나 삭제하는 것과 같은 생명 주기를 관리하는 구조를 가지고 있었다. 



그런데, Docker 이외에도 여러가지 컨테이너 기술이 나오면서 쿠버네티스에서 이런 다양한 컨테이너 런타임에 대한 지원 요건이 생기기 시작하였고, 다양한 컨테이너 런타임을 지원하기 위해서 그때 마다 Kubelet의 코드를 수정해야 하는 문제가 생겼다.


그래서, kubelet의 코드를 수정하지 않고, 다양한 컨테이너 런타임을 지원하기 위해서, kubelet과 컨테이너 런타임 사이의 인터페이스를 통일화하는 스펙이 등장하였는데, 이것이 CRI (Container Runtime Interface)이다. 컨테이너의 생성,삭제 등의 생명 주기를 관리하는 스펙으로 gRPC 기반의 API 스펙으로 되어 있고, 새로운 컨테이너 런타임은 CRI 스펙에 맞춰서 CRI 컴포넌트를 구현하면 되는 구조가 되었다. 


그래서, 컨테이너 런타임이 CRI 스펙에 맞춰서 구현이 되면, kubelet의 코드 변화 없이 새로운 컨테이너 런타임을 플러그인 구조로 추가할 수 있는 구조가 된것이다.  Docker의 경우에는 docker shim 이라는 CRI 인터페이스를 준수하는 구현체를 제공하고 있고, rkt 컨테이너의 경우는 rktlet 이라는 이름의 CRI 구현체를 제공하고 있다. 

그런데, 지원되는 컨테이너의 종류가 계속해서 늘어가고 있고, 그때마다, CRI를 다시 구현해야 하는 문제가 생김에 따라 컨테이너 런타임 자체를 표준화하고자 하는 노력이 있었는데, 그로 인해서 정해진 스펙이 OCI (Open Container Initiative) 이다. OCI 스펙을 맞춰서 구현된 컨테이너 런타임을 별도의 CRI 구현이 없이 OCI를 지원하는 CRI 구현체에 의해서 관리가 가능해진다. OCI 스펙에 따른 컨테이너 런타임을 관리하는 CRI 컴포넌트는 CRI-O 라는 컴포넌트로 구현되어 있다. 즉 OCI 스펙을 준수한다면, CRI-O를 통해서 kubelet으로 부터 명령을 받을 수 있는 구조가 된다. 



본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

쿠버네티스 Skaffold에서는 하나의 Configuration에서 Profile을 통하여, 배포 파이프라인을 여러개 만들어서 다른 환경에 배포할 수 있고,

각 환경은 kubernetesContext를 이용해서, 쿠버네티스 클러스터를 고를 수 있다. 


build:
  artifacts:
  - image: gcr.io/k8s-skaffold/skaffold-example
deploy:
  kubectl:
    manifests:
    - k8s-pod
profiles:
- name: profile1
  activation:
    - env: MAGIC_VAR=42
- name: profile2
  activation:
    - env: MAGIC_VAR=1337
    - kubeContext: minikube
      command: dev


본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요