GAEにコンテナ化されたアプリケーションをデプロイする(golang:ginを例に)
Kong入門
基本チュートリアルどおり
- 設定ファイル(デフォルト)の場所
etc/kong/kong.conf.default
コピーして使いましょう。
$ cp /etc/kong/kong.conf.default /etc/kong/kong.conf
- 設定ファイルのチェック
$ kong check /etc/kong/kong.conf
- デフォルトでlistenしているポート
:8000 => httpリクエストを受け付けて、上流サービスへフォワードするポート
:8001 => 管理者向けAPIのポート
- サービスの登録
管理者向けポートの以下のエンドポイントにPOSTします。
$ curl -i -X POST --url http://localhost:8001/services/ --data 'name=example-service' --data 'url=http://mockbin.org'
成功したら下記のようなレスポンス
HTTP/1.1 201 Created Content-Type: application/json Connection: keep-alive { "host":"mockbin.org", "created_at":1519130509, "connect_timeout":60000, "id":"92956672-f5ea-4e9a-b096-667bf55bc40c", "protocol":"http", "name":"example-service", "read_timeout":60000, "port":80, "path":null, "updated_at":1519130509, "retries":5, "write_timeout":60000 } Back to TOC Permalink
- サービス用のルーティング作成
$ curl -i -X POST \ --url http://localhost:8001/services/example-service/routes \ --data 'hosts[]=example.com'
成功時のレスポンス
HTTP/1.1 201 Created Content-Type: application/json Connection: keep-alive { "created_at":1519131139, "strip_path":true, "hosts":[ "example.com" ], "preserve_host":false, "regex_priority":0, "updated_at":1519131139, "paths":null, "service":{ "id":"79d7ee6e-9fc7-4b95-aa3b-61d2e17e7516" }, "methods":null, "protocols":[ "http", "https" ], "id":"f9ce2ed7-c06e-4e16-bd5d-3a82daef3f9d" }
これでプロキシの準備完了
プロキシのリクエストはデフォルト:8000番ポートであることをお忘れなく。
$ curl -i -X GET \ --url http://localhost:8000/ \ --header 'Host: example.com'
管理者向けのAPI一覧
https://docs.konghq.com/0.14.x/admin-api/
素晴らしい。。Kong
Web API チェックリスト
- URIが短く入力しやすいか
- URIが小文字のみで構成されているか
- URIにサーバ側のアーキテクチャが反映されていないか
- 適切なHTTPメソッドを利用しているか
- ページネーションは適切に設計されているか
- レスポンスのデータ形式はJSONがデフォルトになっているか
- データ形式の指定には、クエリパラメータを使う方法をサポートしているか
- レスポンスのデータ内容はクライアントから指定できるようになっているか
- レスポンスデータの構造は可能な限り、フラットになっているか
- レスポンスデータが配列ではなくオブジェクトになっているか
- バージョンで管理されているか
- APIが受け取るパラメータは、きちんと不正値をチェックしているか
- Rate Limitによる制限を行なっているか
pruneが便利すぎて禿げそう
こんにちは
日々コンテナを使って"ごにょごにょ"していると不要なイメージやコンテナ、それにネットワークが溜まってくるかと思います。
そして、macosから"dockerプロセスが重いよ"とpush通知を頂くことが多いかと思います。笑
いつからのverから"prune”という何て発音したらいいのかわからないコマンドが使えるようになりました。
私の環境はこちらでした。
$ docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3
こいつは停止中のコンテナなど、不要なコンテナ やイメージをよしなに削除してくれる。というものです。
早速実行してみましょう。
$ docker container prune
こうですね。
こうすると、"停止中のコンテナ を全部削除するけどホンマにええんか?"と聞かれます。
WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N]
ええので、"y"と打ち込みます。
Deleted Containers: 4a7f7eebae0f63178aff7eb0aa39cd3f0627a203ab2df258c1a00b456cf20063 f98f9c2aa1eaf727e4ec9c0283bc7d4aa4762fbdba7f26191f26c97f64090360 Total reclaimed space: 212 B
こうですね。
うーん。
気持ちいいですよね。笑
いちいち-rm渡すのがめんどくさい僕にはとてもありがたいツールでした。
もちろん、イメージにも使えます!
$ docker image prune
ネットワークにも
$ docker system prune
以上。よきコンテナ 生活を!
コンテナの動作環境をセキュアにするためのtips
- ユーザーを設定する
rootユーザーを使ってはいけません。笑
Dockerfileで非特権ユーザーを作成しましょう。
RUN groupadd -r user_grp && useradd -r -g user_grp user USER user
こうすることで、user_grpというグループと、それに属するuserという新しいユーザーが作成できます。
ソフトウェアのインストールでrootユーザーが必要な場合がありますので、USERコマンドのタイミングには気をつけて下さいまし。
※もちろん、エントリーポイントのシェルで切り替えるのもありです。
簡易的には
RUN useradd hoge USER hoge
- 不要なバイナリを削除する
setuidあるいは、setgidされたバイナリは、アプリケーションの実行に不要な場合があります。
そういうバイナリは削除して、コンテナ から"牙"を抜いておくことで、権限昇格攻撃からアプリを守ることができます。
イメージ内のそういったバイナリのリストは、以下のコマンドで確認できます。
$ find / -perm +6000 -type f -exec ls -id {} \ ; 2> /dev/null
chmod a-s としてsuidビットをオフにすればいいです。
以下は、Debianの例です。
FROM debian:wheezy RUN find / -perm +6000 -type f -exec chmod a-s {} \ ; || true
- CPUを制限する
攻撃が特定のコンテナ を乗っ取り、CPUの制限をしていなかった場合、相対的に他のコンテナをCPUリソース不足に陥れて、DoS攻撃が実現できることになります。
Dockerでは、CPUの割り当ては1024をデフォルト値とする相対的な重みで決定されます。
よって、デフォルトでは全てのコンテナが等しくCPUを割り当てられることになります。
runコマンドにショートオプション:-cを渡すことで相対値を指定できます。
※詳しくは、
Docker run リファレンス — Docker-docs-ja 17.06.Beta ドキュメント
- メモリを制限する
メモリを制限することで、DoS攻撃や、ホストのメモリを消費するようなメモリリークの可能性を持つアプリに対する対策を立てることができます。-mおよび、--memory-swapオプションをrunコマンドに渡すことで、コンテナ が使用できるメモリの量とスワップメモリの量を制限することができます。
- ファイルシステムを制限する
攻撃者がファイルに書き込みできないようにすることで防げる攻撃があり、概して、そうすることで攻撃者の行動は難しくなります。
Docker1.5から、--read-onlyオプションをrunコマンドに渡して、コンテナ内のファイルシステムを完全にROにできるようになりました。
ボリュームについては:roを渡すことで実現できます。
$ docker run --read-only alpine
$ docker run -v `pwd`:/hoge:ro alpine
- Docker Bench for Security
こちらは長くなりそうなので、別チケットで書きます。笑
- 機密情報の扱い(例えば、APIやDBの認証情報など)
こちらみなさんどうしてますかね。。笑
環境変数を利用する場合と、外部から取得する場合とがありますが、
やっぱり現時点ではマネージドサービスに任せるのがいいように思います。
まとまってきたら、改めて記載します。。笑