本記事は、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)
- 作者: 青山真也
- 出版社/メーカー: インプレス
- 発売日: 2018/09/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
そして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の管理ページにとび、以下のように表示されていればクラスター作成成功です。
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/