Np-Urのデータ分析教室

オーブンソースデータなどWeb上から入手できるデータを用いて、RとPython両方使って分析した結果を書いていきます

GKE(Google Kubernetes Engine)でRを動かしてみる

本記事は、R Advent Calendar 2018の7日目の記事です。


以前に、Docker上でRの環境を作る方法について紹介しました。
www.randpy.tokyo

今回はDockerで作ったR環境をGKE(Google Kubernetes Engine)にデプロイしてみます。

KubernetesやGKEについて簡単に

Kubernetesとは、Dockerなどのコンテナ化されたアプリケーションを管理するためにプラットフォームです。複数のDockerコンテナを管理できたり、自動でスケーリングしてくれたりなどメリットがあります。

Kubernetesについては、公式サイトのチュートリアルを試してみるのが良さそうです。
最近以下のような本が出ましたが、個人的には上のチュートリアルをやった後に読むと、より知識が整理される気がしました。

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)


そしてGKEは、それをGCP(Google Cloud Platform)で動かすためのツールです。
今回は、Kubernetesで簡単なShiny環境を作ってGKEにデプロイして動かすということをやってみます。

前提となる環境

  • GCPアカウントを持っていて、GKEが使える状態
  • ローカル環境にて、kubectl コマンドやgcloudコマンドが実行できる状態
  • Helm(Kubernetesのパッケージ群の管理ツール)が使える状態

ということを前提に進めます。

RとKubernetes

KubernetesRという、Rセッション上からGKEにアクセスして、デプロイするためのライブラリが既にあります。
KubernetesRパッケージ

ただし、まだ柔軟なことをしようと思うとできないことが多いようなので、今後のアップデートに期待しつつ、今回はターミナルから操作をしてみます。

クラスターを作成

まず、以下を実行して、first-clusterという名前でクラスターを作成します。

$ gcloud container clusters create first-cluster --num-nodes=3 --region=asia-east1
$ gcloud container clusters get-credentials first-cluster --region=asia-east1

GKEの管理ページにとび、以下のように表示されていればクラスター作成成功です。
f:id:Np-Ur:20181208130014p:plain


Ingressを追加

外部から、Kubernetesクラスタ内部にアクセスするために、先ほど作ったクラスターにIngressを追加します。
なお、特にShinyなどWebアプリケーションとして公開するために使うのでなければ、Ingressは追加しなくても大丈夫です。

まず、以下のyamlファイルを用意します。

tiller.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: tiller-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: tiller
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: ""

作成できたら、以下のコマンドを実行してください。

$ kubectl create serviceaccount tiller --namespace kube-system
$ kubectl create -f tiller.yaml
$ helm init --service-account tiller --upgrade
$ helm install --name ingress stable/nginx-ingress --set rbac.create=true

ここまでエラーなく実行できたら、

$ kubectl get service

を実行し、ingress-nginx-ingress-controller という名前のサービスに、外部公開用のIPアドレスが作られていることを確認してください。

使いたいDockerイメージを元にデプロイする

ここまでで、クラスターの作成と外部に公開するようのingress追加ができたので、次はDockerイメージを元にデプロイしてみます。
今回は公開されている、shiny-googleauthrdemo というDockerイメージを元にしてみます。

まず、以下のyamlファイルを用意します。

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: r-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: / 
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: shiny1
          servicePort: 3838

作成できたら、以下のコマンドを実行しましょう。

$ kubectl run shiny1 --image gcr.io/gcer-public/shiny-googleauthrdemo:latest --port 3838
$ kubectl expose deployment shiny1 --target-port=3838  --type=NodePort
$ kubectl apply -f ingress.yaml 

ここまでエラーなく実行できたら、先ほど(kubectl get serviceで)確認した公開用IPアドレスの後ろに、「/shiny」をくっつけてアクセスしてみましょう。
例)111.111.111.111/shiny みたいに

サンプルのShinyアプリケーションが立ち上がっていれば成功です。

最後に

今回は、Rのサービス(Rが関係したのは最後だけですが…)をGKEにデプロイする方法を紹介しました。Shinyに限らず、plumberなどでWeb APIを作ったり、Rスクリプトをクラウド上で定期実行させたい場合などは、使えると便利かと思います。

今回は公開されているサンプルのShinyアプリケーションを元にデプロイしてみましたが、Dockerイメージとして作っておけば当然オリジナルのアプリケーションを公開できます。
RとKubernetesの情報は中々出てこないので、もし試したら色々共有してくださると嬉しいです。

参考;
https://code.markedmondson.me/r-on-kubernetes-serverless-shiny-r-apis-and-scheduled-scripts/