オフライン本番環境での機械学習実行環境構築シナリオとAnsibleによる構築自動化(後編)

初版: 2020年12月5日

著者: 株式会社 日立ソリューションズ 堤 友希

監修: 株式会社 日立製作所



# はじめに

本投稿では、前編で実施したオフラインの本番環境への任意パッケージのインストールのうち、手順の多い検証サーバ上での作業を、インフラ構築自動化ツールのAnsibleを使って自動化する手順を示します。

自動化をしておくことで、定期的に本番環境の任意パッケージをアップデートする場合などに作業工数を削減できます。

*前編ではAnacondaリポジトリにアクセスしておりますが、商用でAnacondaのリポジトリを使用する場合はAnaconda Commercial Edition等のライセンスを購入する必要があります。詳細は下記リンクをご確認ください
https://www.anaconda.com/terms-of-service

# 投稿一覧

[1.オフライン本番環境での機械学習実行環境構築シナリオとAnsibleによる構築自動化（前編）](https://qiita.com/yuki-tsutsumi/items/a4cf28110a4ac7908935 "オフライン本番環境での機械学習実行環境構築シナリオとAnsibleによる構築自動化（前編）")

2.オフライン本番環境での機械学習実行環境構築シナリオとAnsibleによる構築自動化（後編）・・・本投稿

# Ansibleの概要

はじめに、Ansibleの概要について説明します。

表1 各インフラ構築自動化ツールの特徴比較

| ツール名 | プログラミング知識要否 | Agent要否 |
| ------ | ------ | ------ |
| puppet | 要（Ruby+独自） | 要 |
| chef | 要（Ruby） | 要 |
| ansible | 不要（YAML：データ定義） | 不要 |

Ansibleはpuppetやchefなどの他のインフラ構築自動化ツールと比較すると、
Rubyなどのプログラミング知識が不要で、Agentlessなことが特徴となります。

targetサーバに対して、 Ansibleをインストール済みのcontrollerサーバが
構築スクリプト実行リクエストを送信します。

![図1(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/4e5b5c0f-d963-20d4-2f7d-c5586e6015f8.png)

図1 Ansible利用シーン

## 自動化はDockerfileでできるのでは？

コンテナを活用するのであればDockerfileで自動化できます。

ただ、今回はコンテナを活用しない場合にも対応可能なAnsibleを使った方法を紹介します。

## Ansible利用環境の構築

検証環境でAnsibleを利用するために、ControllerサーバにAnsibleを導入し、Targetサーバへ疎通確認します。

下図に疎通確認のスコープやサーバ間の関係を示します。

![図2(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/93dafad9-41a6-5297-79a0-178da83d57f6.png)

図2 疎通確認のスコープ<span style="color: red; ">(赤枠)</span>やサーバ間の関係

```:CentOSのコンソール画面

#controllerサーバにAnsibleをインストールします。

[root@localhost ~]# yum install epel-release –y
[root@localhost ~]# yum install ansible -y

#続いてtargetサーバにpingモジュールで疎通確認します。
#鍵チェックする設定の場合、controller-target間で通信に鍵が必要なので、鍵生成/受け渡しをしておきます。

[root@localhost ~]# ssh-keygen -t rsa #鍵の生成
[root@localhost ~]# ssh-copy-id <targetのIPaddress>@<targetのホスト名> #鍵を渡す
[root@localhost ~]# ssh <targetのIP address> #ssh接続確認

#Ansibleが利用するtargetの情報を記載したinventoryファイルを作成しておきます。

[root@localhost ~]# cat inventory.txt
ansible_host=<targetのIPaddress> ansible_ssh_pass=<targetへのssh接続時パスワード>

#疎通が成功すると、以下のように返答されます。
#これで、自動化スクリプト実行スクリプト実行リクエストがtargetサーバに通信可と確認できました。

[root@localhost ~]# ansible <targetのホスト名> -m ping -i inventory.txt
<targetのホスト名> | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

```

図3 Ansible利用環境の構築例

## Rolesと自動化スコープ

Ansibleでは、playbookというyamlで記載された自動化スクリプトを実行します。

また、rolesという機能で自動化の内容を分割して整理することができます。

下記のようなrolesの構成にしており、それぞれの自動化範囲を示します。

![図4(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/8d8e2cac-4b63-6219-7c73-56c0fbc18e3c.png)

図4 rolesと自動化スコープ

表2 各rolesとその自動化内容

| roles | 自動化内容 |
| ------ | ------ |
| conda-install | Minicondaインストール |
| env-setting | Miniconda初期化&プロキシ設定 |
| dev-channel | 仮想環境構築とカスタムチャネル開発 |

proenv_auto.yml(以降、メインplaybook)がconda-install→env-setting→dev-channelの順番で、各rolesのtasks直下のmain.yml(以降、サブplaybook)を実行します。

Ansibleは実行するplaybookが存在するディレクトリにあるrolesディレクトリ階層を認識します。

サブplaybookの実行順序は、メインplaybookに記載して定義します。

各rolesのfilesやvarsに存在するファイルはサブplaybookの実行時に利用するシェルスクリプトなどのファイルや変数定義です。

## Minicondaインストールの自動化テンプレート

本番環境においては、多数のサーバに同様の作業をするのでなければAnsible用のControllerサーバを
用意できないので、本番環境へのパッケージインストールは自動化の範囲に含めません。

その代わり、パッケージをインストールするシェルスクリプトの作成方法を記載します。

proenv_autoディレクトリ直下のメインplaybookでは全rolesで共通の変数定義やroles実行順序、targetサーバの情報を記載しています。

今回のメインplaybookであるproenv_auto.ymlの記載内容を示します。

![図5(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/5f2176b4-2d02-ddd4-dfef-e8311f25c5c9.png)

図5 proenv_auto.yml

次にcontrollerサーバからtargetサーバへの通信に必要な情報を記載したinventory.txtの内容を示します。

![図6(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/f10e424d-e5fb-a53c-db2f-69b08bd981f5.png)

図6 inventory.txt

rolesはproenv_auto.ymlでの記載に従って、conda-installから実行されます。

conda-installのtasks直下のmain.ymlの記載内容を示します。

![図7(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/30d9c39b-4e1b-ed28-2cb1-c91c649f97fd.png)

図7 conda-installのtasks直下のmain.yml

conda-installのvars直下のmain.ymlの記載内容を示します。

ここではconda-install固有の変数名を定義しており、
Minicondaのインストーラが変更されるとき、
インストーラ名の変更に対応できます。

![図8(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/e3aaf1c2-b8ba-4202-4554-b611bdde8045.png)

図8 conda-installのvars直下のmain.yml

次にenv-settingが実行されます。
env-settingのtasks直下のmain.ymlの記載内容を示します。

![図9(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/3560bb45-d044-bda9-a023-72261e848caf.png)

図9 env-settingのtasks直下のmain.yml

Minicondaのインストールをすると、Minicondaの初期化処理が行われ、CentOSやRHELのrootディレクトリに存在する.bashrcに変更が加えられます。

後述しますが、この初期化処理による.bashrcの変更部分をAnsibleで利用します。

一方、今回のAnsibleを用いて自動化されたMinicondaのインストールではインストールはバッチオプションとして行われますが、この場合Minicondaの初期化処理が行われません。

そのため、一度手動でMinicondaのインストールを実施し、その際の初期化処理で変更された.bachrcを利用します。

![図10(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/11c8788f-7746-dde6-0096-d014b3a4667b.png)

図10 .bashrc

## 任意パッケージダウンロードとカスタムチャネル化の自動化テンプレート

conda-installに続き、dev-channelが実行されます。

dev-channelのtasks直下のmain.ymlの記載内容を示します。

このmain.ymlでは任意パッケージのインストール・ダウンロード情報の取得と、カスタムチャネル化を実施します。

![図11(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/1d3e757f-dc46-6253-67ff-7203ce9de52a.png)

図11 dev-channelのtasks直下のmain.yml

main.yml内で実行されるシェルスクリプトのdev_channel.shとdev_channel2.shの記載内容を示します。

それぞれdev_channel.shは任意パッケージのインストールとダウンロード情報の取得、dev_channel2.shは任意パッケージのカスタムチャネル化を行います。

シェルスクリプトには、黄色で示したように、.bashrcにMinicondaの初期化で追記される箇所を記載しないと、playbook実行時にエラーが発生しますので、記載しておく必要があります。

![図12(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/86fc8bc0-c515-e2cc-ede2-86fd48f657a4.png)

図12 dev_channel.sh

![図13(後編).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865566/38f780da-8f8e-13bb-ee30-f42ac0dd09d1.png)

図13 dev_channel2.sh

## 本番環境へのパッケージインストールの自動化テンプレート

本番環境では下記のシェルスクリプトで任意パッケージをインストールします。

```proenv_build.sh

#!/bin/sh
初期化が反映された部分。
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init’ !!
__conda_setup="$('/root/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)“
if [ $? -eq 0 ]; then
   eval "$__conda_setup“
else
   if [ -f "/root/miniconda3/etc/profile.d/conda.sh" ]; then
       . "/root/miniconda3/etc/profile.d/conda.sh“
   else
export PATH="/root/miniconda3/bin:$PATH“
   fi
fi
unset __conda_setup
# <<< conda initialize <<<
#前提条件
#①Minicondaのインストールは手動で実施
#②/rootにカスタムチャネルが存在すること
#③UnsatisfiableErrorのデバッグが完了していること
conda create -n proenv -y --offline && \
conda config --add channels /root/proenv-custom-channel && \
conda config --remove channels defaults && \
conda activate proenv && \
conda install --quiet --yes 'python=3.7.6' && \
conda install --quiet --yes 'notebook=6.0.3' && \
conda install --quiet --yes 'tensorflow=2.1.0'
```

図14 proenv_build.sh

# まとめ

本投稿では、環境構築の自動化をAnsibleで実施するノウハウを示しました。

自動化により煩雑な手順を効率化できるので、本番環境の任意パッケージをアップデートする場合などの運用に活用いただければと思います。