- 投稿日:2019-03-30T23:52:36+09:00
SageMaker を ローカルPC に構築する
あまり見かけないのですが、SageMakerのライブラリは GitHub に公開されているので、ローカルに構築可能です。
SageMaker は無料枠が無いので、お金をかけたくない個人ユーザーは活用すると良いと思います。
リポジトリ
The SageMaker Python SDK is built to PyPI and can be installed with pip as follows:
pip install sagemaker
You can install from source by cloning this repository >and running a pip install command in the root directory of the repository:
git clone https://github.com/aws/sagemaker-python-sdk.git
cd sagemaker-python-sdk
pip install .Amazon SageMaker Examples - SageMakerのサンプルソース集
使い方
Anaconda をインストールして、Jupyter Notebook や Jupyter lab と一緒に使いましょう。
ただ、conda skeleton でビルドしようとして上手くいかなかったので、公式の手順の通りに pip コマンドで入れてしまいました。。。
併せて、awscli もインストールすると使い方が広がります。
- 投稿日:2019-03-30T22:48:01+09:00
CloudFormationの基本のキ
AWSのサービス"CloudFormation"をについての勉強メモ
AWS CloudFormationとは
- AWSが提供するInfrastructure as Codeを実現するためのサービス
- AWSリソースの設定やプロビジョニングを担ってくれる
Infrastructure as Codeとは
- 一言で言うと、ITインフラの構築や維持作業をコード化すること
メリット
- 自動化
- インフラ構築をコード化し、それを実行することで素早く・正確にインフラを構築する
- 冪等性
- 人の手を介さないため、一度コードを作ってしまえば、ミスなく同じ環境を同じように構築可能
- 「冪等性」と言う言葉は数学界で用いられる言葉で、1回の操作でもn回の操作でも結果が変わらないこと
- 変更管理
- 再利用性の高いコードとして管理することで、インフラ設定をバージョン管理でき、変更後の差分が分かりやすくなる
デメリット
- 学習コスト
- ツールを利用するのに、まずそのツールを理解しなければならない
- 部分変更に時間がかかる
- サーバーの設定を少しいじるだけでも、コードを修正して適用になるため、手作業よりも時間がかかる
CloudFormation実行の主な流れ
- テンプレートを作成する
- テンプレートの拡張子はyamlとjsonがある
- 特別な理由がない場合は可読性が高いので、yamlを用いるのが良いと言われている
- スタックを作成する
- スタックはCloudFormationで構築するインフラのひとかたまり
- =テンプレートごとの単位
基本のテンプレート
- 9つのセクションを記述できる
- ここではよく使うセクションについて詳しく書きます
AWSTemplateFormatVersion(形式バージョン)
Description
Parameters
Resources
Outputs
- 投稿日:2019-03-30T20:08:51+09:00
Elastic BeanstalkにSpring Bootアプリケーションをデプロイ
Spring Bootを使ったJavaアプリケーションをElastic Beanstalk(AWSのPaaS)上にデプロイする手順をざっくりおさらいします。
初投稿なので、至らないところもあるかとは思いますが、ご了承ください。BeanstalkへのデプロイはAWSのコンソールからでもできるのですが、今回はCIツールからも実行したいので、CLI(EB CLI)を使います。
前提
今回はBeanstalkの設定手順を説明します。
SpringBootアプリの作成については割愛します。
ビルドツールはgradleです。環境
Mac OSX10.14.3
EB CLIのインストール
homebrewでBeanstalkのCLIをインストールします。
$ brew install awsebcliAWS CLIのインストール
Access KeyとSecret Access Keyの設定を保存するためにAWSのCLIもインストールします。
$ brew install awscliアクセスキー設定
$ aws configure AWS Access Key ID [None]: {アクセスキーを入力} AWS Secret Access Key [None]: {シークレットアクセスキーを入力}プロジェクト設定
デプロイはプロジェクトのディレクトリで行います。
例$ cd workspace/ebdemo/demo初めにプロジェクトの設定です。
$ eb init対話型で設定していきます。
リージョンSelect a default region 1) us-east-1 : US East (N. Virginia) 2) us-west-1 : US West (N. California) 3) us-west-2 : US West (Oregon) 4) eu-west-1 : EU (Ireland) 5) eu-central-1 : EU (Frankfurt) 6) ap-south-1 : Asia Pacific (Mumbai) 7) ap-southeast-1 : Asia Pacific (Singapore) 8) ap-southeast-2 : Asia Pacific (Sydney) 9) ap-northeast-1 : Asia Pacific (Tokyo) 10) ap-northeast-2 : Asia Pacific (Seoul) 11) sa-east-1 : South America (Sao Paulo) 12) cn-north-1 : China (Beijing) 13) cn-northwest-1 : China (Ningxia) 14) us-east-2 : US East (Ohio) 15) ca-central-1 : Canada (Central) 16) eu-west-2 : EU (London) 17) eu-west-3 : EU (Paris) 18) eu-north-1 : EU (Stockholm) (default is 3): 9アプリケーションSelect an application to use 1) [ Create new Application ] (default is 1): Enter Application Name (default is "demo"): Application demo has been created.プラットフォーム→SpringBootの場合はJavaSelect a platform. 1) Node.js 2) PHP 3) Python 4) Ruby 5) Tomcat 6) IIS 7) Docker 8) Multi-container Docker 9) GlassFish 10) Go 11) Java 12) Packer (default is 1): 11 Select a platform version. 1) Java 8 2) Java 7 (default is 1):SSHCannot setup CodeCommit because there is no Source Control setup, continuing with initialization Do you want to set up SSH for your instances? (Y/n): Y Select a keypair. 1) key 2) [ Create new KeyPair ] (default is 2): 2デプロイ
デプロイの前にアプリケーションのjarをプロジェクトルートにコピーします。
$ cp build/libs/demo-0.0.1-SNAPSHOT.jar .デプロイします。
$ eb create Enter Environment Name (default is demo-dev): Enter DNS CNAME prefix (default is demo-dev): Select a load balancer type 1) classic 2) application 3) network (default is 2):数分かかります。
動作確認
動いてます。
$ curl http://demo-dev.ap-northeast-1.elasticbeanstalk.com Hello, World!2回目以降のデプロイ
2回目以降は以下のコマンドだけでデプロイできます。
SSH、アクセスキー等設定しておけば、CIツールから自動デプロイ可能です。$ gradle clean build test $ cp build/libs/demo-0.0.1-SNAPSHOT.jar . $ eb deploy
- 投稿日:2019-03-30T18:39:23+09:00
AWS KMSのマスターキーとデータキー
AWSで暗号化の話しになると登場するKMSについて勉強したのでこのエントリーを書きました。
公式のKMSドキュメントはKMS全般の優れたドキュメントですが、ここではマスターキーとデータキーの関係に絞って書こうと思います。マスターキーとデータキー
KMSの言うところのマスターキー(CMKとかカスタマーマスターキーとも呼ばれます)と、データキーって何?どんな関係なの?という点を図解します。例えばS3のサーバーサイド暗号化を例にとると、KMSを使う場合は以下のような関係になります。
KMSがやってくれるのは、マスターキーの管理とデータキーの復号ということですね。データの暗号化に使うデータキーは使う側でちゃんと管理しないといけないと。
マスターキー
マスターキーの作成ですが、AWSマネージドの方法に加えて、ユーザー側で生成した暗号鍵をマスターキーとしてKMSに保管することもできるみたいです。
自分で生成した秘密鍵をKMSに登録する具体的方法は公式ドキュメントに記載があります。RSAで暗号化してやりとりするんですねー。
データキー
データキーの生成は、KMSにGenarateDataKeyリクエストをすることで行います。
平文データキーが不要な場合は、GenerateDataKeyWithoutPlaintextリクエストと言うのもあります。マスターキーの権限管理
カスタマーマスターキーを使用する権限をIAMユーザーやIAMロールに付与しようとした場合、IAMのポリシーをどうのこうのしただけでは不十分で、KMSのキーポリシーでも権限を与えてあげる必要があります。KMSのキーポリシーはCMK毎に設定するCMKに対する権限のポリシーです。
具体的にどうすればいいのかは公式ドキュメントにあります。
- 投稿日:2019-03-30T18:31:13+09:00
AWS S3を使ってホームページを公開する
背景
独自ドメインを取得してホームページを開設したかった。
レンタルサーバを利用しなくてもAWSのS3を利用して簡単にできるようだったので、試しにやってみる。
参考(AWSチュートリアル)全体像
作業概要
だいたいの作業手順はこんな感じです。
- 独自ドメインの購入
- バケット作成
- Route53へバケットのエイリアスレコード追加
作業内容
独自ドメインの購入
AWSドキュメントに、より詳細な内容が書かれていますので参考に。AWSドキュメント
- AWSコンソールにログイン後、
サービスからRoute53を選択する。画面真ん中あたりのテキストボックス(Type a domain name)に取得したいドメイン名を入力し、Checkボタンをクリックする。(.com以外のドメインが欲しい場合は右隣のリストボックスから選択すること)
Add to cartをクリックし、欲しいドメインをカートに加える。
(画像はgetsampleapp.comをカートに加えた後のキャプチャです)
画面を下にスクロールしてcontinueボタンをクリックする。
購入します。
以下の作業を行うと、Complete Purchase作成が完了するとroute53のRegistered domainsに出現します。
バケットの作成
AWSサービスの中からS3を選択し、バケットを作成する。
ホスティングするウェブサイトと同じ名前のバケットを作成すること(AWSチュートリアル参考)。バケットポリシーを設定する
画面下のポリシージェネレータを利用すると簡単にjsonを生成することができます。
こんな感じで良いかと思います(ARNは作成したS3バケットのARNを設定してください)
Generate Policyボタンをクリックし、画面に表示されたポリシーをコピペして貼り付けてください。
※バケットのパブリックアクセス設定内の新規のパブリックバケットポリシーをブロックする (推奨)にチェックが入っているとポリシーの保存ができないので要注意です(そりゃそうか...って感じですが)。
ウェブサイトのホストとして設定する
AWSチュートリアルを参考に、S3のバケットをウェブサイトのホストとして利用する設定をします。
ひとまず簡単なindex.htmlを作成してホスティングの設定をするのが良いかと思います。S3エンドポイントへアクセスしてみる
設定がうまくいっていればエンドポイントへアクセスできるはずなのでお試ししてみてください。
AccessDenyエラーが出るときはバケットのアクセス権限周りの設定を再確認してみると良いかもしれません。Route53へエイリアスレコードの追加
AWSチュートリアルのエイリアスレコードを追加するを参考に、エイリアスレコードを設定します。
Nameと同じ名前でないとAlias Targetとして表示されないので注意です。同じ名前のバケット名を作成したのはそのためか。と一人で納得しました。
作成後、
http://xxxx.com(xxxxは購入したドメイン名)にアクセスすると、いい感じにアクセスできます。詰まったところ
全体的にあまりつまるところはなかったけど、地味にちょこちょこ引っかかってしまいました...
バケットポリシーが保存できない
S3アクセス権限の「パブリックアクセス設定」
新規のパブリックバケットポリシーをブロックするにチェックが入ってた。チェックを外して保存できたS3のエンドポイントにアクセスしてもコンテンツが表示されない
S3アクセス権限の「パブリックアクセス設定」
バケットにパブリックポリシーがある場合、パブリックアクセスとクロスアカウントアクセスをブロックするにチェックが入ってた。チェックを外してアクセスできたエイリアスターゲットにS3のバケットが表示されない
バケット名のスペルが誤っていた。正しい名前(Route53レコード追加画面の
Nameと同じ名前)のバケット名を作成したらエイリアスターゲットとして選択することができた今後の課題と感想
ACMとCloudFrontを利用してHTTPS化したい。文書を書くのに途中で力尽きてしまって急に適当になってしまいがちなので、なんとか工夫したい...段々雑になってごめんなさい...
- 投稿日:2019-03-30T13:38:35+09:00
AWSのElastic Beanstalkにtd-agent3をデプロイする
目次
1. はじめに
2..ebextension内にtd-agent3の設定ファイルを作る
3..ebextension内にtd-agent3のインストールファイルを作る
4. デプロイ1. はじめに
環境
fluentd-v1.0(td-agent3)
Amazon Linux 12.
.ebextensionでtd-agent3の設定ファイルを作るElastic Beanstalk以下(eb)では、
.ebextensionという設定ファイルを追加することによって環境設定が可能です。
- 作成したファイルの拡張子は
.configとし、YAMLもしくはJSON形式にします。- 設定ファイルはアルファベット順に実行されます。
(設定ファイル読み込み例)
以下のように設定ファイルを作成した場合
.ebextensions/01td-agent3.configが先に読み込まれます。
.ebextensions/01td-agent3.config
.ebextensions/02td-agent-install.config
(設定例 01-td-agent.config)
設定の中身はバージョンによって書き方が異なるので注意が必要ですので、使用されるtd-agentのバージョン確認することをおすすめします。
例えばbufferプラグインでも書き方が全く異なります。
td-agent2.configbuffer_type filetd-agent3.config<buffer> @type file </buffer>(Amazon Linuxのバージョン確認方法)
使用したいebに接続した状態で$ cat /etc/system-releaseと入力すると、
=> Amazon Linux AMI release 2017.09のように使用してるバージョン確認ができます。下記は
01td-agent.configの設定例です。
※設定内容は適当ですので、実際に設定したい内容に書き換えてください。設定例01-td-agent.configfiles: "/etc/td-agent/td-agent.conf": owner: root group: root content: | <match pattern1> <buffer> @type file path /var/log/fluent/s3 </buffer> </match> <match pattern> @type s3 aws_key_id YOUR_AWS_KEY_ID aws_sec_key YOUR_AWS_SECRET_KEY s3_bucket YOUR_S3_BUCKET_NAME s3_region YOUR_S3_BUCKET_REGION path logs/ <buffer tag,time> @type file path /var/log/fluent/s3 timekey 3600 timekey_wait 1m timekey_use_utc true chunk_limit_size 256m </buffer> </match>3.
.ebextensionでtd-agent3のインストールファイルを作る# errors get logged to /var/log/cfn-init.log. See Also /var/log/eb-tools.log commands: 01-command: command: echo 'Defaults:root !requiretty' >> /etc/sudoers 02-command: command: curl -L https://toolbelt.treasuredata.com/sh/install-amazon1-td-agent3.sh | sh 03-command: command: /etc/init.d/td-agent restartインストールするURLはご自身の環境に合わせてください。↑はAmazon Linux 1の場合です。
4. デプロイ
eb環境がない方は
eb initでEB上でアプリケーションを作成し、
eb createで環境を構築してください。この辺の説明は省きます。すでにある方は
eb deployで設定内容反映させてください。
設定がおかしかったりすると、deployに失敗すると思うので原因はログで確認してください。
eb sshで接続したあと起動確認しましょう。便利コマンドバージョン確認 $ rpm -q td-agent $ td-agent --version 起動、停止、再起動、ステータス $ sudo /etc/init.d/td-agent start $ sudo /etc/init.d/td-agent stop $ sudo /etc/init.d/td-agent restart $ sudo /etc/init.d/td-agent status コマンドライン上でS3プラグインがどんな設定項目を持っているか確認 td-agent --show-plugin-config output:s3参考
Installing Fluentd Using rpm Package
設定ファイル (.ebextensions) による高度な環境のカスタマイズ
AWS Elastic Beanstalk の詳細な環境設定 » 設定オプション
- 投稿日:2019-03-30T13:05:12+09:00
TCPのLISTEN見て、ヘルスチェック応答させる
背景
AWSのALB(Application Load Balancer)を使いたかったんですけど、アプリがヘルスチェックにうまく反応しない。。
(ALBは正常のHTTPステータスコードとして、200 ~ 499の範囲で指定可能ですが、アプリが500を正常で応答する仕様 orz)そしてアプリ側の改修して頂ける雰囲気はないので、ヘルスチェックを書きました。
サマリ
最終的に出来たコード
・ net/httpでヘルスチェック用webを起動
・ health check requestを受けたら、net.Listen でサービスが稼働しているポート20000番のポートをListenを試みる
・ Listen出来た場合(サービス停止) → 404を応答
or
・ Listen出来なかった場合(サービス稼働) → 200を応答handler作成
ヘルスチェックのリクエスト受けた時に、特定ポート(今回は20000port)の Listen を試みる handler です。
listen出来たら、404 NotFoundで、Listen出来なかったら、200OKを応答する。var ( svcProtocol = "tcp4" svcPort = ":20000" okMsg = "healthy" ngMsg = "unhealthy..." ) func checker(writer http.ResponseWriter, request *http.Request) { // Try to listen on svcProtocol and svcPort. listenchecker, err := net.Listen(svcProtocol, svcPort) if err == nil { // able to listen it... Which means, the service has stopped...ng writer.WriteHeader(http.StatusNotFound) fmt.Fprint(writer, ngMsg) defer listenchecker.Close() return } // not able to listen it. Which means, the service is working...ok!!! fmt.Fprint(writer, okMsg) return }handler登録してヘルスチェック応答web起動
ヘルスチェックのパスとポートを決めて、 handler を登録して web を起動
health.govar ( healthPath = "/health" healthPort = ":80" ) func main() { http.HandleFunc(healthPath, checker) http.ListenAndServe(healthPort, nil) }windows 用にコンパイル
-ldflags="-H windowsgui"はプロンプト起動させない様にするとか。GOOS=windows GOARCH=386 go build -ldflags="-H windowsgui" health.goAWS側
リスナー設定
ヘルスチェック設定
次にヘルスチェックの指定
ポイントはヘルスチェックのポートをトラフィックポートではなく、上書きを指定しヘルスチェック専用ポートを指定すること。実験開始
まずは、windowsサーバでコンパイルした自作ヘルスチェックを起動
c:\>health.exeヘルスチェック(80)と、サービス(20000)共に起動(LISTEN)している
c:\>netstat -aon | find "80" TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 3552c:\>netstat -aon | find "20000" TCP 0.0.0.0:20000 0.0.0.0:0 LISTENING 3636curlでヘルスチェック先を叩くと200が返ってくる。
~ ❯❯❯ curl -i http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com/health HTTP/1.1 200 OK Date: Sat, 30 Mar 2019 03:33:21 GMT Content-Length: 7 Content-Type: text/plain; charset=utf-8 healthyサービスを停止し、再度curlで確認するとちゃんと連動してるのが確認できた。
~ ❯❯❯ curl -i http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com/health HTTP/1.1 404 Not Found Date: Sat, 30 Mar 2019 03:34:17 GMT Content-Length: 12 Content-Type: text/plain; charset=utf-8 unhealthy...
- 投稿日:2019-03-30T07:02:47+09:00
Windows7環境なのにdocker入れて開発することになった話【③docker開発環境編】
はじめに
2章では、不足していたライブラリやソフトウェアを導入し、実際に動作確認を行いました。3章では、2章で動作確認を行ったモジュール群を、docker環境下でどのように実行させるのかを記述していきます。ついにdockerについて触れます。章の構成としては、以下の構成となります。
開発環境における動作確認
- コンテナにマウントするためのpythonファイルをテストする
python XXXX.pyにてモジュールを実行する(2章で解説したため割愛)- DockerFile、docker-compose.yml、shellを駆使して「1.」と同様の動きを実現する
デプロイ環境における動作確認
- 開発環境にて作成したDockerFile、docker-compose.ymlを利用してデプロイする
本章を読んでいただくことで、以下のDockerFileを作ることのメリットが伝わると幸いです。
メリット1
dockerをインストール済みの環境(1章参照)であれば、DockerFileとソースコードを共有することで、環境構築なしで実行することができる。GitHubではソースコードの共有まではできるが、開発環境の共有はできないため、共同開発を行う際は非常に有用なメリット。
メリット2
コンテナを利用可能なサービス(AWSではESC)において、簡単にデプロイできる。(本章では開発環境までしか触れられないので次章以降になります)
メリット3
そのアプリケーションを実行するための環境が、DockerFile内に全て書かれているため、開発環境・本番環境に対してどのようなソフトウェアやライブラリが必要か一目で分かる。
一応デメリットも
- DockerはLinuxカーネルを利用しているため、Linux環境下を推奨。(Windows10からはDocker ToolboxからWSLを利用することで実行できるが、まだまだ不安定なのが現状
- 開発者が、開発環境にインストールされるソフトウェア/ライブラリを意識せずに開発を行えてしまうため、開発終盤までいっても環境を把握している人はチームに数人しかいないことになる
ついにdockerに触れられるということで前置きが長くなりましたが、今しばらくの間お付き合いください。
第3章
技術バリバリの人「動作確認お疲れ!DockerFile書けた?」
わたし「書けるわけないじゃないですか。そもそもなんですかdockerって」
技術バリバリの人「1章で教えて上げたじゃん」
技術バリバリの人「あ、あと開発環境はもちろんgit使うし、ビルドの情報とかは全部Dockerファイルに書くね。さらに言えばdocker-compose使っちゃえば複数のサーバーをビルドする情報がチーム全体でで同時に管理できちゃったりするねー」
わたし「そういえば単語は一回聞きましたね。でも何言ってるか分からないです。簡単に教えてください!」
技術ばりばりの人「…分かった、Dockerの中身の話を全部話すと長くなるから、1章の辞書整理を見てね。今からは、実際にdockerを使った際に実感できるメリットについて2つ話すね」
技術ばりばりの人「まずこの図を見てね。これは、今回のアプリケーションのライブラリやソフトウェアを、dockerを利用して管理した場合の概念図だよ。左の青い部分がDockerfileで、今回は2つのDockerfileを作ろう。上の『GetNews_Dockerfile』の部分が、インターネットからデータを取得するモジュールに必要なライブラリ/ソフトウェア郡だね。下の『Post_Dockerfile』部分はまだ実装していないけど、取得したデータを外部に送信する部分だね」
わたし「『GetNews_Dockerfile』に、2章でインストールした、スクレイピングで使用する『beautifulsoup4』、AWSにローカルからアクセスする『boto3』、自然言語処理で利用する『mecab』が書いてますね」
技術ばりばりの人「そうだね。2章で既に君が開発環境にインストールしたライブラリ/ソフトウェアを書いただけだよ。次は真ん中の黄色い部分、docker-compose.ymlについて説明するね」
技術ばりばりの人「docker-composeを使うことで、Dockerfileに定義されたコンテナを共通管理することができるんだ。開発したソフトウェアをコンテナ上のどの領域にマウントして、最初に実行するコマンドは何を実行するか等を定義することができるよ」
わたし「もしdocker-composeが無かったらどうなるんですか?」
技術ばりばりの人「もしdocker-composeを使わなかった場合、ビルド・デプロイ・破棄・スケール・ネットワーク設定などのコマンドを、それぞれのDockerコンテナ/イメージに対して実行する必要があるんだ」
わたし「ビルド・デプロイ・破棄だけでも単純にコンテナの数だけコマンドたたく回数が増えちゃうんですね」
技術ばりばりの人「そうだね。正確にはスケールやネットワーク設定についてはDockerfileでやれちゃう部分もあるんだけど、ソフトウェア/ライブラリ部分はDockerfile、ネットワークやスケールなどのインフラ周りについてはdocker-composeに任せちゃう運用が分かりやすいね」
わたし「開発環境の管理が楽なことがなんとなく分かってきました!」
技術ばりばりの人「じゃぁこれでもDockerfileとdocker-compose.ymlが書けるね!よろしく!」
わたし「はい!」
技術ばりばりの人「あ、そうだ、MeCabのDocker化は1癖も2癖もあるらしいから気をつけてね。まぁ大丈夫だね!それじゃ!」
わたし「え、ちょ」
辞書整理
本文章(第3章)を読む上で頭に入れておいたほうが良い文言をピックアップ。文中分からない文言が出たら見返してください。(不足あれば、コメントいただけたら追記していきます)
忙しい人はここだけ読めばDockerの概念がつかめるので、下記は補足として読んでください。
コンテナ
- ホストOS(Linux限定)のkernel機能を利用することで、仮想サーバのような立ち振る舞いをする
- プロセス・メモリ・デバイス・ネットワーク等、仮想サーバとして必要な部分についてはコンテナごとに保有する
- ホストOSから見ると、単に1プロセスが起動しているように見えている
- kernel部分は複数コンテナで共有しているため、kernelにかかわるような操作はできない(正確にはできるがやらない)
- kernelを共有しているため、kernel依存のエラーである「オープンしているファイルの最大数を超える」等のエラーが、ゲストOS(コンテナ)・ホストOSをまたいで生じることがある
- Dockerとコンテナは意味が異なり、「Dockerソフトウェアを用いてコンテナという概念を扱っている」が正しい
- Dockerにおいては、コンテナがkernelを共有して実行している部分は「Docker daemon」が担っている
- 参考:コンテナ技術の基礎知識
Dockerデーモン
- Linux kernelをコンテナから実行する、いわばホストOSとゲストOS(コンテナ)の橋渡しの部分
- ホストOSの環境変数、プロキシ設定、DNS設定などをコンテナでも利用したい場合は、Dockerデーモンのオプションを修正する
- コンテナから見ると、ある意味kernelのような存在
- Linuxのコマンド、「systemctl」で操作できる
- 参考:Dockerデーモンに関するもう少し詳しい説明
Dockerイメージ
- コンテナを実行する時に必要なファイルシステム
- イメージ・レイヤ(Dockerイメージを構成するファイルシステム)の集まり
- 難しいので、OSおよび必要なアプリケーションに必要なソフトウェア一式が書き込まれているディスクのようなものだと認識していれば良い
- 自分で1から作成することも可能であるが、GitHubのような形でイDockerメージを管理しているDockerHubから取得することも可能
- Dockerイメージを作成することをビルド、Dockerイメージをビルドし、アプリケーションをその環境下で実行させることをデプロイと呼んでいる
- 参考:Dockerイメージとは?【Docker解説】
WSL
- Windows Sybsystem for Linux
- Windows環境からLinuxの実行環境を実現するサブシステムのこと
- Windows10以降しか使えない
- Windows10以降にDockerがWindows環境でも使えるようになった原因
- Windows10環境にてDockerを利用するには、DockerToolboxをインストールすることで、同ツールがWSLを利用して、Linuxカーネルを叩いている仕組み
- とはいえ実際動作確認を行っていく中で、まだ不安定であるという噂や、アップデートで動くようになっているという噂もある
- 参考:WSL上でDocker Engineが動くようになっていたっぽいという話
1.Dockerの設定
第1章で書いた内容も重複しますが、インストールした後の設定が一番難しく、しくじるともちろん動かないので、再掲します。ちなみに、公式ドキュメントが一番参考になります。参考:Docker-docs-ja
前提条件
第1章のDockerのインストールが完了している
proxyおよびDNS設定
社内等プロキシ環境下で実行している場合、Dockerデーモン実行時にプロキシの設定を渡す必要があるため、Dockerデーモンのオプション設定を変更する。(Ubuntu環境を想定しています。)
- プロキシおよびDNSサーバの設定
$ sudo mkdir -p /etc/systemd/system/docker.service.d/$ sudoedit /etc/systemd/system/docker.service.d/http-proxy.conf[Service] Environment="HTTP_PROXY=http://各プロキシサーバ:8080/" "HTTPS_PROXY=http://各プロキシサーバ:8080/" "NO_PROXY=127.0.0.1,localhost" "DOCKER_NETWORK_OPTIONS=--dns 各DNSサーバ" ExecStart= ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONSDockerデーモンのオプションファイル自体は別にありますが、『docker.service.d/』以下に記載した設定が、Dockerデーモン実行時に上書かれて実行されます。「ExecStart=」の部分はおまじない。最初に空実行を設定することで、2回目の実行時にオプションを指定した状態で上書き実行ができる仕組み。
- Dockerデーモンのリロード
sudo systemctl daemon-reload- Dockerの再起動
sudo systemctl restart docker2.Dockerfileの記載
2章で開発したモジュール郡を動かすためには、下記を「Getnews_Dockerfile(拡張子不要)」という名称で作成する。
Get_news_Dockerfile
FROM python:3.6.5 RUN apt-get update && apt-get upgrade -y RUN apt-get install -y sudo RUN pip install --upgrade pip # ----------- install scrayping module at Python --------------- RUN pip install beautifulsoup4==4.6.3 # --------------------- mecab configure ------------------------ RUN apt-get install mecab mecab-ipadic libmecab-dev -y RUN pip install mecab-python3==0.7 RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git /usr/src/mecab-ipadic-neologd \ && /usr/src/mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y -p /var/lib/mecab/dic/mecab-ipadic-neologd \ && rm -rf /usr/src/mecab-ipadic-neologd # -------------- install aws module at Python ------------------ RUN pip install boto3==1.7.4 WORKDIR ./解説
FROM python:3.6.5
- DockerHub上から、どのDockerイメージをベースにカスタマイズするかを指定。今回の場合は、Python3.6.5を導入したDockerイメージをベースにカスタマイズを加えている
RUN apt-get update && apt-get upgrade -y~RUN pip install --upgrade pip
- apt-getやpipなどソフトウェア管理ツールを最新化しておくおまじない
# ----------- install scrayping module at Python ---------------以降
- スクレイピングに利用するライブラリのインストール
# --------------------- mecab configure ------------------------以降
- MeCabを利用する際に必要なライブラリ/ソフトウェア郡のインストール
# -------------- install aws module at Python ------------------以降
- PythonからAWSアクセスに必要なライブラリのインストール
WORKDIR ./
- デプロイ時、コンテナ内の最初に居るディレクトリを指定
3.docker-compose.ymlの記載
「2.Dockerfile」の記載にて定義したイメージを、コンテナ化して実行するための「docker-compose.yml」を記載する。
docker-compose.yml
version: '2' services: get-news: env_file: .env build: context: ./ dockerfile: Get_news_Dockerfile volumes: - ./shell:/root/shell - ${get_news_root_dir}/backEndLogic:/root/backEndLogic - ${host_aws_credential}:/root/.aws command: > bash -c "chmod +x /root/shell/get_news.sh && /root/shell/get_news.sh" tty: true解説
version: '2'
- docker-composeのバージョンを指定する。HTMLの一番初めに書くバージョン宣言と同じ(HTML5からは書かないが…)
get-news:
- 任意のコンテナ名称。コンテナを立ち上げる際、ターミナルから指定する名称となる
env_file .env
- AWSのシークレットキーやマウントのパスなど、ホストOSの環境依存でパスを指定する部分については別途「.env」ファイルを作っている。Dockerの設定を完璧に行っても、唯一各環境で書き換える必要がある部分。docker-compose.ymlと同フォルダに作成している
build:
- どのDockerfileをbuildするかをここに書く
contextにDockerfileのあるフォルダを指定。今回の場合はdocker-compose.ymlと同フォルダに作成しているdockerfileに、このコンテナ(今回の場合get-news)をbuildするために利用するDockerfile物理名称を指定volumes:
- 各種ローカルからコンテナへのマウント情報。今回の場合は、①shell(後述)、②作成したモジュール郡、③AWSクレデンシャルをマウントする
- ①shellについては各開発者環境で共通して利用するため、docker-compose.ymlと同フォルダに作成し、envを介さずに相対パスを記載
- ②作成したモジュール郡および③AWSクレデンシャルについては各開発者環境で異なるため、envで指定した環境変数を記載
command: >
- デプロイ後最初に実行するコマンドを記載。今回はshell(後述)を呼び出すことで、2章で作成したPythonモジュールの管理や、MeCabの辞書コンパイルなどを行う
参考(.envファイル中身)
# ------------------以下ホストの環境に合わせて変更してください ------------------ # ソースディレクトリへのPath. 各コンテナは以下Pathを参照して環境を構築します. # 指定したディレクトリは、コンテナ上からmountされ参照されます. get_news_root_dir=/home/username/backEndLogic # AWSのcredential情報を記載したファイルパス host_aws_credential=/home/username/.awsインフラ周りの設定情報についても、docker-compose.ymlに書く。たとえばファイルオープン数が最大に達してしまい、コンテナにもっとリソースを割きたい場合は、volumeと同じ階層に以下のように追記すると良い。
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000※この場合、後述するshellの中にスタックサイズの開放コマンド
$ ulimit -s unlimitedを書く必要がある。4.shellの記載
1~3までで、コンテナ環境の構築や、コンテナ環境へのPythonモジュールのマウントは完了した。しかし、デプロイ後に実際にPythonモジュールを実行したり、MeCabの設定が必要だったりするので、shellを外だしで作成する。
get_news.sh
- MeCabの辞書がローカルで更新されていた場合、Dockerコンテナ上で毎回ユーザ辞書を更新する必要があるため、shellに任せました
- 作成したPythonモジュールを実行するために、main.pyに飛ばしました(ここは各々好きに作ればよいと思います)
get_news.sh# ユーザ辞書のコンパイル cd /root/backEndLogic/mecabDict /usr/lib/mecab/mecab-dict-index \ -d /var/lib/mecab/dic/mecab-ipadic-neologd \ -u /root/backEndLogic/mecabDict/select_dic.dic \ -f utf-8 \ -t utf-8 select_dic.csv # mecabの設定ファイルにユーザ辞書を追記 cd /etc sed -i -e 's@.*userdic.*@userdic = /root/backEndLogic/mecabDict/select_dic.dic@' mecabrc # モジュールのおいてあるパスへ移動 cd /root/backEndLogic/ # News収集機能を実行 python /root/backEndLogic/main.pymain.py
main.pyimport subprocess def main(): subprocess.check_call(['python','ニュース取得機能.py']) print("complete get_news") subprocess.check_call(['python','ニュース選定機能.py']) print("complete select_target") if __name__ == '__main__': main()※実際のアプリケーションとは異なるため、簡易的に「ニュース取得機能.py」、「ニュース選定機能.py」を呼び出すような記載としています
docker-compose実行
ここまでくれば、後は2つコマンドを実行してあげるだけです。その前に、現状のフォルダ構成はこうなっています。
.../ - shell - get_news.sh - Get_news_Dockerfile - docker-compose.yml - .envdocker-compose.ymlと同フォルダに、Dockerfileや.env、shellが置いてあります。(docker-compose.ymlの記載次第)
いよいよコマンドを実行します。実行するコマンドはたったの2つ。(コンテナが増えても同様に2つです)
build
プロキシ環境下
-$ docker-compose build --build-arg https_proxy=${https_proxy} --build-arg http_proxy=${http_proxy} get-news
非プロキシ環境下
-$ docker-compose build get-newsコンテナ起動&デプロイ
$ docker-compose upあとがき
わたし「Docker環境で、pythonモジュールが動きました!」
技術バリバリの人「これで実際にAWS環境にデプロイするときも簡単にできるし、モジュールが複雑化しても実行環境を修正するのが簡単になったね!」
技術バリバリの人「次回はついに、取得したデータをフロントエンドに出力する部分を作っていこう!」
続く

























