備忘録

頭の整理のために書いています

GAEにコンテナ化されたアプリケーションをデプロイする(golang:ginを例に)

こんにちは。

A○Sの記事は世の中にごまんとありますが、GCP界隈に関しては、その記事が少ないので共有。

GCPと言えば、0までスケールインしてくれるという驚異のGAEではありますが、
デフォルトのruntimeではなく、コンテナで実行するときにハマりました。

結論を言ってしまえば、以下のシリコンバリーなUberのエンジニアに救われました。笑
すごくわかりやすかったです。
自分の名前をそのままドメインにしちゃうあたりの自己主張性がシリコンバレーで働くのに、きっと必要なことなんでしょうね。笑

graysonkoonce.com

最低限のサンプルを公開しておりますので、よろしければ。

github.com

以上、よきコンテナ・ライフを!

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の認証情報など)

こちらみなさんどうしてますかね。。笑

環境変数を利用する場合と、外部から取得する場合とがありますが、
やっぱり現時点ではマネージドサービスに任せるのがいいように思います。

まとまってきたら、改めて記載します。。笑