2017年5月31日水曜日

ESXi に独自のファイアウォールルールを追加する方法

概要

例えばあるポートの Outgoing を許可したい場合などです
実は vSphere Client からできなく直接 ESXi にログインしてコマンドで作業する必要があります
今回はその方法を紹介したいと思います

環境

  • ESXi 6.5.0, 4887370

設定方法

事前に ESXi の SSH ログインの有効と root ユーザのパスワードの設定を実施しておいてください
参考

  • cp /etc/vmware/firewall/service.xml /etc/vmware/firewall/service.xml.back
  • chmod 644 /etc/vmware/firewall/service.xml
  • chmod +t /etc/vmware/firewall/service.xml
<service id='0044'>
  <id>vchAccess</id>
  <rule id='0000'>
    <direction>outbound</direction>
    <protocol>tcp</protocol>
    <porttype>dst</porttype>
    <port>2377</port>
  </rule>
  <enabled>true</enabled>
  <required>true</required>
</service>
  • chmod 444 /etc/vmware/firewall/service.xml
  • esxcli network firewall refresh

Firewall のルールを管理している service.xml というファイルがあるのでそれを直接編集します
そしてその後 esxcli コマンドで設定を反映し完了となります

動作確認として vSphere Client でちゃんとポートがオープンになっているか確認してみましょう

ESXi を選択 -> 設定タブ -> 左サブメニューからシステム -> セキュリティプロファイル

で確認できます
今回であれば 2377 ポートが一覧に表示されていれば OK です

2017年5月30日火曜日

go-swagger で XML なレスポンスを返却する方法

概要

デフォルトだと application/json としてレスポンスが返却されます
レスポンスを XML として返却できないか試してみたので紹介します

環境

  • CentOS 7.3.1611
  • golang 1.8
  • swagger 2.0
  • go-swagger 0.10.0

swagger.yml

  • vim swagger.yml
consumes:
- application/json
info:
  description: The product of a tutorial on goswagger.io
  title: A To Do list application
  version: 1.0.0
produces:
- application/xml
schemes:
- http
swagger: "2.0"
basePath: /v1
definitions:
  item:
    type: object
    required:
      - description
    properties:
      id:
        type: integer
        format: int64
        readOnly: true
      description:
        type: string
        minLength: 1
      completed:
        type: boolean
  error:
    type: object
    required:
      - message
    properties:
      code:
        type: integer
        format: int64
      message:
        type: string
paths:
  /:
    get:
      tags:
        - todos
      operationId: findTodos
      parameters:
        - name: since
          in: query
          type: integer
          format: int64
        - name: limit
          in: query
          type: integer
          format: int32
          default: 20
      responses:
        200:
          description: list the todo operations
          schema:
            type: array
            items:
              $ref: "#/definitions/item"
        default:
          description: generic error response
          schema:
            $ref: "#/definitions/error"

ポイントは produces の部分でここでレスポンス時の Content-Type を application/xml に固定します

produces:
- application/xml

コード生成

  • swagger generate server -f swagger.yml

メイン部分修正

  • vim configure_a_to_do_list_application.go

一部抜粋です
適当に値を返す処理を追加します

api.TodosFindTodosHandler = todos.FindTodosHandlerFunc(func(params todos.FindTodosParams) middleware.Responder {
        result := make([]*models.Item, 0)
        item := new(models.Item)
        item.Completed = true
        s := "hoge"
        item.Description = &s
        result = append(result, item)
        return todos.NewFindTodosOK().WithPayload(result)
})

アプリ起動

  • go install ./cmd/a-to-do-list-application-server/
  • a-to-do-list-application-server --host 0.0.0.0 --port 18080

動作確認

  • curl localhost:18080/v1 | xmllint --format -

とすると

<?xml version="1.0"?>
<Item>
  <Completed>true</Completed>
  <Description>hoge</Description>
  <ID>0</ID>
</Item>

という感じで XML が返ってきます
-v で詳細を見ると Content-Type も application/xml となっているのが確認できると思います

追加調査

とりあえずこれで自分が実装する API の部分に関しては XML で返却することができます
ただ、go-swagger がデフォルトで実装しているエラーハンドリングの部分に関しては json で返ってきてしまいます
例えば今回であれば「/」にアクセスした場合、Not Found のエラーになるのですが、それが

{"code":404,"message":"path / was not found"}

となってしまいます
他には Method Not Allowed なども json になってしまいます

{"code":405,"message":"method POST is not allowed, but [GET] are"}

このあたりのデフォルトエラーに関しても XML にしたいと思います
デフォルトエラーのカスタマイズ方法についてはまだ調査できていないので別途調査が必要かなと思います

最後に

go-swagger で XML のレスポンスを返却する方法を紹介しました
基本は consumes の設定を変更するだけで XML にすることができました

2017年5月26日金曜日

Xcode で Authenticating with the iTunes Store でアップロードが止まる

概要

久しぶりにアプリのアップデートしようとしたら Xcode でタイトルのエラーが出てしまいアプリをアップロードできなくなってしまいました
自分の対応方法を紹介します
xcode_upload_error1.png

環境

  • macOS 10.12.4
  • Xcode 8.3.2 (8E2002)

Application Loader に一度ログインしてみる

Application Loader は Xcode に付属する ipa ファイルを iTunesStore にアップロードするためのツールです
Xcode を開いた状態で

  • Xcode -> Open Devloper Tools -> Application Loader

と選択します
すると AppleID でログインを求められるのでログインします
xcode_upload_error2.png

ここでログインするパスワードは AppleID のパスワードではなくアプリケーションパスワードというワンタイムパスワードを使います
アプリケーションパスワードは AppleID の管理画面 から App 用パスワード -> パスワードを生成で作成することができます
ランダムの文字列のパスワードが取得できたらそれを使って Application Loader にログインします

今回は Application Loader にログインするのが目的なのでログインできたら Application Loader は閉じて OK です
これで再度 Xcode からアプリをアップロードしてみましょう

それでもダメなら iTMSTransporter を初期化してみる

iTMSTransporter は iTuneStore にアップロードするツールです
おそらく Xcode もバックエンドではこれを使っているはずです
一旦これの設定ファイルを作成することで対処することができます

  • rm -rf ~/.itmstransporter/
  • /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms/bin/iTMSTransporter

デバッグログがつらつらと流れるので終了するまで待ちましょう
完了したら Xcode から再度アプリをアップロードしてみましょう

ちなみに自分はこっちの方法を試すことで対処することができました

最後に

Xcode で iTunesStore にアプリをアップロードする際に発生した Authenticating Error の対応をしてみました
他の Xcode のバージョンや macOS のバージョンだと発生しない可能性はありますが発生した場合は試してみると良いと思います

参考サイト

2017年5月25日木曜日

au SIM ロックの iPhone5 を復活させたのでメモ

概要

すごい昔に au で契約した SIM ロックな iPhone5 が眠りについていたので復活させてみました

環境

  • macOS 10.12.4
  • docker 17.05
  • docker registry 2.6.1

なぜ眠りについてしまったのか

iOS9 の時代に 2 年縛りが終了し au は解約しました
その後 Wifi のみで使い続けていたのですが、その時に iOS9 から iOS10 にアップグレードしました
iOS10 にアップグレードした際に iPhone のアクティベーションが必要でその際に実は SIM カードが必要でした
そのことを知らず au 解約時に SIM カードを捨ててしまったため iPhone5 は眠りについていました

その後いろいろと調べると解約済みでもいいので au の SIM カードがあればアクティベーションはできることを知り復活させることにしました
家族用の au SIM カードをありそれで SIM カードは代用しています

手順

電源が入らない

ずっと眠りについていたのでバッテリーが空になっていました
ライトニングでとりあえず充電していると勝手に起動し始めました

iPhone5 はバッテリーが空の場合、充電中であっても電源ボタンを押しても起動しません
なので、ある程度充電されるまで気長に待ちましょう

アクティベーション作業

SIM カードを挿しましょう
SIM カードは解約している SIM カードなので、通信はできません
なので変わりに Wifi を設定します
アクティベーションの途中で Wifi を設定するところがあるので設定します
すると Wifi で iPhone5 のアクティベーションが完了します

その後 AppleID でログインするように促されます
AppleID が 2 ファクタ認証になっている場合はここでパスワード以外に 6 桁のコードでの認証も必要になります
基本的には同じ AppleID で使用している iPhone や Mac にコードが送られてくるのでそのコードを使います
(このとき別の端末がない人はどうなるんだろうと思いました、実は別端末がなく 2 ファクタ認証をオンにしている人はここで詰んでしまうのだろうか、、、)

アクティベーションが完了し起動したあとは iPhone の初期化を行います

初期化

アクティベーション後は前回の iPhone の状態で起動します
今回自分は完全に初期化 (工場出荷時に初期化) したかったのでリセット作業を行いました

  • 設定 -> 一般 -> リセット -> 初期化 -> すべての設定をリセット
  • 設定 -> 一般 -> リセット -> 初期化 -> すべてのコンテンツと設定を消去

でリセットします
下が完全リセットなので、下だけ実行すればいいかもしれません
リセット後は起動したら iPhone 自体の初期化から始まります

iPhone の初期設定

以下指示に従い設定していきましょう
また、この段階でも SIM を挿しておきましょう
完全に初期化しているので再度アクティベーションが走ります

  • 言語、タイムゾーンの設定
  • Wifi の設定
  • アクティベーション (wifi で失敗する場合は何度か繰り返す)
  • GPS 設定
  • パスワード設定 (iPhone5 のためタッチ ID の設定はなし)
  • AppleID でログイン、2 ファクタ認証でログイン

であとは iPhone にログイン後完全に初期化した状態で普通に使うことができます

最後に

アクティベーションできずにいた iPhone5 を復活させてみました
ポイントは「解約済みでもいいので SIM カードを挿す」ことでした

当然自宅に Wifi 環境がないと何もできませんが、Wifi があえば iPod touch 的な使い方は全然できます

2017年5月24日水曜日

mackerel で docker コンテナを監視する

概要

簡単な手順を備忘録として残しておきます
起動中のコンテナから基本的なメトリックを取得したいのであれば十分かなとは思います

環境

  • CentOS 7.3.1611
  • docker 17.03

事前作業

  1. オーガニゼーションを作成
  2. サービスを作成
  3. サービス内にロールを作成
  4. エージェントのインストール
    • curl -fsSL https://mackerel.io/file/script/setup-all-yum.sh | MACKEREL_APIKEY='your-mackerel-apikey' sh

でホストの監視がスタートします

docker コンテナの監視

プラグインをインストールすることで実現します

  • yum install mackerel-agent-plugins

インストールできたら設定ファイルを編集します
docker plugin を有効にする設定を追記したらエージェントを再起動しましょう

  • vim /etc/mackerel-agent/mackerel-agent.conf
[plugin.metrics.docker]
command = "mackerel-plugin-docker -name-format name -method API"
  • systemctl restart mackerel-agent
  • tail -f /var/log/mackerel-agent.log

ログにエラーが吐かれていなければ OK です

動作確認

コンソールから Hosts -> localhost.localdomain -> カスタムメトリック に起動中のコンテナのメトリックが表示されると思います
表示される項目は

  • ブロック I/O バイト
  • ブロック I/O IOPS
  • CPU 使用率
  • メモリ使用率

が表示されます

mackerel-docker1.png

最後に

mackerel で docker コンテナのメトリックを取得してみました
手順がかなり簡単なので嬉しい点です

docker events 等の監視はしていないのでコンテナの死活監視は現状できないようです
ただ、削除されたコンテナのメトリックはコンテナが存在していた間は残るのでこれをうまく使えば死活監視的なことはできるかもしれません

参考サイト

2017年5月23日火曜日

VMware VIC 1.1.1 を触ってみたのでメモ

概要

知らぬ間に MyVMware からダウンロードできる VMware Integrated Container が 1.1.1 までバージョンアップしていたので検証してみました
1.1.1 から提供方式も ova になっているようです

環境

  • CentOS 7.3.1611
  • docker 17.05
  • VMware VIC 1.1.1

VIC 1.1.1 のダウンロード

以下の URL からダウンロードできます
https://my.vmware.com/group/vmware/details?downloadGroup=VIC110&productId=648&rPId=15925

自身のアカウントで MyVMware にログイン後ダウンロードしてください
vSphere Integrated Containers 1.1.1 OVA のサイズは 2.69GB あります

ova のデプロイ

基本的な方法はこちらを参照してください

デプロイ時に必要となるディスク際は 70 GB + 4.7 GB になります
ネットワークはデフォルトだと 1 つのみ設定できます
VIC の ova をデプロイする際に必須となるパラメータは以下の通りです

  • VM (Photon) に ssh ログインする際の root ユーザのパスワード
  • registry の admin ユーザのパスワード
  • MySQL の root ユーザのパスワード

デプロイ後の挙動の確認

ova デプロイが完了したら電源を ON にして VM を起動しましょう
設定したネットワークの IP が取得できれば起動完了です

管理画面が 2 つあり

Admiral 側は特にログイン用の ID/PW はありません
Harbor 側は ova デプロイ時に設定した registry の admin ユーザのパスワードでログインできます

また、VM は Photon OS で動作しています
SSH でログインできるのでログインしてみましょう
docker コマンドが使えるのでコンテナの一覧を確認すると以下が動作しています

  • docker ps
ONTAINER ID        IMAGE                                     COMMAND                  CREATED             STATUS              PORTS                                                  NAMES
6405166b4027        vmware/notary-photon:server-0.5.0         "/usr/bin/env sh -..."   55 minutes ago      Up 55 minutes                                                              notary-server
7414d1b3852b        vmware/nginx:1.11.5-patched               "nginx -g 'daemon ..."   55 minutes ago      Up 55 minutes       0.0.0.0:443->443/tcp, 80/tcp, 0.0.0.0:4443->4443/tcp   nginx
e6ae3a5f914a        vmware/harbor-jobservice:v1.1.1           "/harbor/harbor_jo..."   55 minutes ago      Up 55 minutes                                                              harbor-jobservice
b6e384167707        vmware/notary-photon:signer-0.5.0         "/usr/bin/env sh -..."   55 minutes ago      Up 55 minutes                                                              notary-signer
5b8ac98ebfab        vmware/harbor-ui:v1.1.1                   "/harbor/harbor_ui"      55 minutes ago      Up 55 minutes                                                              harbor-ui
647d830a9f49        vmware/registry:photon-2.6.0              "/entrypoint.sh se..."   55 minutes ago      Up 55 minutes       5000/tcp                                               registry
4dd9ef6abaed        vmware/harbor-db:v1.1.1                   "docker-entrypoint..."   55 minutes ago      Up 55 minutes       3306/tcp                                               harbor-db
904b46e34f20        vmware/harbor-adminserver:v1.1.1          "/harbor/harbor_ad..."   55 minutes ago      Up 55 minutes                                                              harbor-adminserver
f21e09a82015        vmware/harbor-notary-db:mariadb-10.1.10   "/docker-entrypoin..."   55 minutes ago      Up 55 minutes       3306/tcp                                               notary-db
07fa6ffcf209        vmware/harbor-log:v1.1.1                  "/bin/sh -c 'crond..."   55 minutes ago      Up 55 minutes       127.0.0.1:1514->514/tcp                                harbor-log
6ffc63081e6a        vmware/admiral:ova                        "/entrypoint.sh"         55 minutes ago      Up 55 minutes       0.0.0.0:8282->8282/tcp                                 vic-admiral

Admiral と Harbor 用のコンテナが起動しています

また network が全部で 7 つ作成されています

  • docker network ls
NETWORK ID          NAME                   DRIVER              SCOPE
816285492ff8        bridge                 bridge              local
4b1b23d24347        harbor_harbor          bridge              local
848a011f52ff        harbor_harbor-notary   bridge              local
b9a1717bb5e2        harbor_notary-mdb      bridge              local
091f255fbb90        harbor_notary-sig      bridge              local
832437bb1e05        host                   host                local
3f9ca92ef166        none                   null                local

どのコンテナがどのネットワークに属しているかは

  • docker network inspect harbor_harbor

とかで確認できます

registry を使ってみる

registry 機能には UI とコンテナレジストリの機能があります
UI はブラウザで 443 ポートにアクセスすれば OK です
IP ベースでレジストリを使用する際には先に証明書の配置が必要なので後述の手順を先に実施しておいてください

  • docker pull nginx
  • docker tag nginx 192.168.100.202/library/alpine
  • docker login
  • docker push nginx 192.168.100.202/library/alpine

docker login 時の ID/PW は管理 UI にログインしたものと同じになります
管理 UI で確認するとイメージが push されているのが確認できると思います

registry 用の証明書の配置

一点注意点としてデフォルトだと https でデプロイされてしまいます
証明書がちゃんと設定されていないレジストリにアクセスすることはできないので、自己証明書をダウンロードして dockerd の所定のパスに配置する必要があります
自己証明書をダウンロードするには管理画面にアクセスしてログインします
そして右上の Admin -> Download Root Cert から ca.crt を取得します

取得したら docker コマンドを実行ホストに配置します

  • mkdir -p /etc/docker/certs.d/192.168.100.202
  • cp ca.crt /etc/docker/certs.d/192.168.100.202

Admiral を使ってみる

Admiral はコンテナホストマシンのクラスタリングを実現するための機能です
管理 UI が提供されているので https://192.168.100.202:8282/ にアクセスします

Admiral は過去に試した使い方とほぼ同じです
VCH を作成したあとに Admiral に登録すると docker swarm のように VCH をクラスタリングすることができます

VCH に関して

これはどうやら従来通りコマンドを使って作成するようです
実は、今回デプロイした ova の中には含まれていて以下のリンクからダウンロードすることができます

すると申し訳ない程度のダウンロードページに遷移し、そこから vic_1.1.1.tar.gz というファイルをダウンロードすることができます
展開すると vic-machine-linux が含まれていました
しかもダウンロードページはコンテナで動作しておらず PhotonOS VM のローカルで 9443 が LISTEN しておりそこからダウンロードできるようになっていました

何か VCH だけ除け者扱いされている感がありますが、一応バイナリをダウンロードすることはできるようです

最後に

VMware VIC 1.1.1 では Harbor と Admiral が同じ ova となって配布されていました
VCH は従来通り vic-machine を使って作成する形式となっており、まだ管理 UI から VCH を作成することはできないようです
一応バイナリは ova に含まれているのでダウンロードをできることは確認しました

触ってみた感じコンテナ技術に必要なコンポーネント (コンテナホスト、レジストリ、クラスタリングツール) が 1 つになって提供されている感じでした
VMware vSphere 環境がある方は ova を 1 つデプロイするだけですぐにコンテナ環境が構築できるので便利かなと思いました

今後は VCH の作成も UI からできるようになるかもしれません

参考サイト

2017年5月22日月曜日

iOS 証明書更新方法

概要

Apple から証明書の期限切れメールが来た際に行う更新作業の流れを備忘録として残りしておきます

環境

  • macOS 10.12.4
  • Xcode 8.3.2
  • Apple Developer (2017/05/22 時点)

CSR 作成

  1. キーチェーンアクセスを開く
  2. 左メニューから キーチェーンアクセス
  3. 証明書アシスタント
  4. 認証局に証明書を要求を選択

入力情報は以下の通り

  • ユーザのメールアドレス -> DeveloperProgram に登録しているメールアドレス
  • 通称 -> 何でもOK
  • CAのメールアドレス -> 空でOK
  • ディスクに保存にチェック
  • 鍵ペア情報を指定にチェック

保存先を選択

  • 鍵のサイズ -> 2048ビット
  • アルゴリズム -> RSA

で OK

Apple Developer に証明書を作成する

  1. DeveloperCenter にアクセス
  2. 証明書管理画面に移動
  3. Certificates を選択し右上の「+」を選択
  4. iOS App Development/App Store and Ad Hoc
  5. Continue
  6. Continue
  7. Chooes File
  8. 先ほど作成した CSR を選択
  9. Continue
  10. Done

証明書は Development 用 (iOS App Development) と Distribution 用 (App Store and Ad Hoc) を作成します

証明書は作成できたらローカルマシンに保存しましょう
そしてクリックしてキーチェーンアクセスに登録しておきます

Apple Developer のプロビジョニングプロファイルを編集する

  1. DeveloperCenter にアクセス
  2. プロビジョニングプロファイル管理画面に移動
  3. 既存のプロビジョニングプロファイルを選択
  4. Edit
  5. Certificates に先ほど作成した Distribution 用の証明書を選択
  6. Generated
  7. Done

存在するプロビジョニングプロファイル分編集しましょう
ここまで完了すれば更新作業は完了です

Tips

期限切れになった証明書は心配であれば期限切れ後に削除しましょう
キーチェーンアクセスに登録した証明書も同様です

キーチェーンアクセスに登録した証明書から p12 ファイルを書き出しておくと後々嬉しいかもしれません
別の Mac で開発する場合に必要になります
1 台の Mac で開発しているのであれば不要です

また更新後は特に Apple から完了の連絡は来ません
期限切れの通知はしてくれるのですが、更新完了はないようです

最後に

現段階での更新手順は以上です
仕組み的に大きく変わらないのであれば、今後もこの流れで更新できると思います

Apple Developer の管理画面がちょくちょく変わる可能性がありそうだったのでスクリーンショットはあえて掲載しないようにしました

たぶん証明書の更新に影響するのは公開用のアプリのビルドとプッシュ通知だけになるので、すでに公開しているアプリが動かなくなるということはおそらくないと思います
なので、プッシュ通知を使っていないのであれば更新しないくても OK なのかなと思います
自分はプッシュ通知は使っていませんが更新するようにしていますが

2017年5月21日日曜日

LINE Notify を使ってみた

概要

LINE Notify は通知用のサービスで公式の LINE Notify という公式アカウントと友達になることで通知を受け取ることができます
通知だけ受け取るのであれば、とりあえず curl から使えたので通知の使い方を紹介します

環境

  • CentOS 7.3.1611
  • LINE Notify (2017/05/17 時点)

使い方

まず https://notify-bot.line.me/ja/ にアクセスします
自分の LINE アカウントでログインしましょう

そして「マイページ」からアクセストークンを発行します
トークンを発行するとスマホの LINE アプリ側にも通知が来ます
line_notify1.png

トークンを発行する際にトークンの名前と通知先のグループを選択する必要があります
トークルームは選択できないようです
今回は「1:1 で LINE Notify から通知を受け取る」を選択しました

トークンが発行できたらリクエストを組み立てます
と言っても以下で終わりです

curl -X POST -H 'Authorization: Bearer your-access-token' -F 'message=foobar' https://notify-api.line.me/api/notify

API リファレンスはこのページの通知系を参照しています
your-access-token の部分に先程取得したトークンを設定してください
あとはリクエストすれば OK です

アプリ側の LINE Notify 公式アカウントから通知が来ると思います
トークンの名称も square bracket に囲まれて付与されるようです
line_notify2.jpg

最後に

LINE Notify を試してみました
公式アカウントを使った通知方法なのでアイコンなどは変更できないようです

Messaging API と違ってサーバを立てたり IP を固定したりする必要がないので簡単に使うことができます
個人的な用途で使う簡単な通知を実装したいだけであればこれで十分かもしれません

また、LINE Notify にはサービスという概念もあり他の人が使える通知サービスを作成することもできます
その場合は認証系の API を使う必要があるようです
そっちもそのうち試せればなーと思います

2017年5月19日金曜日

docker logging driver を使ってみた

概要

docker はコンテナ内で動作するアプリの標準出力と標準エラーを docker logs で確認することができます
これは logging driver の json-file というドライバを使うことで実現しています
それ以外にも logging driver が存在しますが今回は json-file, syslog, journald, fluend を使ってみました

環境

  • CentOS 7.3.1611
  • docker 17.03

json-file

ログを吐き続けるコンテナを起動します

docker run --rm -it --name json-file alpine /bin/sh -c "while :;do  date; sleep 3; done;"
  • docker logs -f json-file

でログが出力されます
docker ホスト側の json ファイルは /var/lib/docker/containers/container_id/container_id-json.log に出力されています
json-file ドライバを使っている場合このログファイルが肥大化し続ける可能性があります

コンテナが再生成される可能性なども考えるとこのファイルをログ集約するのはあまり好ましくありません
そこで他の logging driver を使用します

syslog

syslog ドライバを使ったログを吐き続けるコンテナを起動します

docker run --rm -it --log-driver=syslog alpine /bin/sh -c "while :;do  date; sleep 3; done;"
  • tail -f /var/log/messages

でログを確認することができます
逆に docker logs でログを確認することができなくなります
ただ、先程あった /var/lib/docker/containers/container_id/container_id-json.log が docker ホストに出力されなくなります

この場合 docker ホストの syslog を使ってログを集約することができます
どこか別のホストにログを更に投げたい場合は rsyslog などを代用すれば良いかなと思います
複数のコンテナのログが混ざることになるので syslog のルールをちゃんと作成する必要はあります

journald

journald ドライバを使ったログを吐き続けるコンテナを起動します

docker run --rm -it --log-driver=journald alpine /bin/sh -c "while :;do  date; sleep 3; done;"
  • journalctl -f
  • tail -f /var/log/messages

でログを確認することができます
journalctl の場合 blob data として表示されてしまいます
journald の場合 docker logs は使えます
/var/lib/docker/containers/container_id/container_id-json.log は docker ホストに出力されなくなります

journalctl の場合も syslog 同様に journald.conf などでロギングルールを作成したほうが良いと思います
docker logs が使える分こちらの方が利便性が高いかもしれません

fluentd

まず fluend コンテナを起動します

cat << EOF > fluent.conf
<source>
  @type forward
  port 24224
</source>

<match docker.**>
  @type stdout
</match>
EOF
docker run --rm -p 24224:24224 -p 24224:24224/udp -v $(pwd)/fluent.conf:/fluentd/etc -e FLUENTD_CONF=fluent.conf --name=fluentd fluent/fluentd

で起動できます
fluent/fluend コンテナの使い方や設定できる環境変数などはこちらを参照してください

そして fluentd ドライバを使ったログを吐き続けるコンテナを起動します

docker run --rm -it --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag="docker.{{.Name}}" alpine /bin/sh -c "while :;do  date; sleep 3; done;"

すると fluentd コンテナ側にログが表示されると思います
先に fluentd 側のコンテナを起動しておく必要があります
そうしないと fluentd のポートが LISTEN していないといわれエラーとなります

fluentd ドライバの場合も docker logs は使えません

その他

コンテナが使っている logging driver を確認する方法

  • docker inspect -f '{{.HostConfig.LogConfig.Type}}' [container_id]

最後に

docker の logging driver 3 つほどを試してみました
基本はこれだけ使えていれば事足りると思います

他にも gelf, awslogs, splunk, etwlogs, gcplogs などクラウドサービス連携できるドライバもあるので用途に合わせて使い分けると良いかなと思います

参考サイト

2017年5月18日木曜日

docker logs で日本語を表示する方法

概要

Dockerhub で公開されている ruby の公式イメージでプログラム中で puts などで日本語の出力をしたアプリをコンテナ上で動かすと docker logs をしたときに日本語が表示されません
そんな場合に docker logs で日本語を表示される対策を紹介します

環境

  • CentOS 7.3.1611
  • docker 17.03.1-ce
  • ruby image 2.4.1 (debian 8.7)

対策

  • apt update
  • apt install locales locales-all
  • locale-gen ja_JP.UTF-8
  • export LANG=”ja_JP.UTF-8”

をすれば OK です
Dockerfile であれば

FROM ruby:latest

RUN apt update
RUN apt install locales locales-all
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8

を追加すれば OK です

最後に

Debian 系のコンテナで日本語を使う方法を紹介しました
RedHat 系だとまた手順が異なるので注意してください

あと少し気になったのは、今回 Ruby のプログラムを動かしていたのですが Ruby のマジックコメントで utf8 を指定するだけでも解決できるかもしれません

2017年5月17日水曜日

docker でコンテナのタイムゾーンを変更する方法

概要

タイトルの通り

環境

  • CentOS 7.3.1611
  • docker 17.03.1-ce

おすすめの方法

-e オプションを使って環境変数 TZ で設定します

-e "TZ=Asia/Tokyo"

ローカルの /etc/localtime をマウントすることで変更する方法もあるようですが、ECS などのコンテナサービスを使う場合にはローカルマウントできないので環境変数で変更する方法をオススメします

2017年5月16日火曜日

harbor のバックエンドに s3 を使ってみた

概要

前回 registry でバックエンドに s3 を使ってみました
VMware が提供する harbor も実は registry を使っているので s3 が使えないか試してみました

環境

  • CentOS 7.3.1611
  • docker 17.03.1-ce
  • docker-compose 1.9.0
  • harbor 1.1.1

インストーラのダウンロード

  • wget 'https://github.com/vmware/harbor/releases/download/v1.1.1/harbor-offline-installer-v1.1.1.tgz'
  • tar zvxf harbor-offline-installer-v1.1.1.tgz
  • cd harbor
  • vim harbor.cfg
hostname = 192.168.100.101

バケットの作成

適当に作成しましょう
本記事では前回作成した ap-northeast-1 の cf.hawksnowlog というバケットを使います

s3 の設定

  • vim common/templates/registry/config.yml
storage:
  s3:
    accesskey: your-accesskey
    secretkey: your-secretkey
    region: ap-northeast-1
    bucket: cf.hawksnowlog

という感じです
他にも設定項目はありますが、最低限の項目はこれで OK です

harbor のインストール

  • ./install.sh

完了するまで待ちましょう

動作確認

事前に insecure-registry の登録を dockerd に対して行っておきましょう
insecure-registry の登録方法は前回の記事を参考にしてください

  • docker pull nginx
  • docker tag nginx 192.168.100.101/library/nginx
  • docker push 192.168.100.101/library/nginx

push したあとに s3 のコンソールを確認するとバケット配下にイメージが保存されていることが確認できると思います

s3_with_harbor1.png

終了する場合は down しましょう

  • docker-compose down

少し気になったこと

上記で問題なく動作すると思いますが少し気になったことがあったので記載しておきます
registry に対して docker push すると以下のパスにイメージ情報が保存されていました

  • docker exec -it registry ls storage/docker/registry/v2/repositories/library/

これは storage ドライバに s3 を使った場合でもローカルを使った場合でも同じなのですが、rmi コマンドでイメージを削除した場合でも上記のファイルが残っていました
ちなみに s3 側にもデータ残っていました

rmi は dockerd が参照するイメージへのリンクを削除するだけで、物理的な削除は行わない感じでした
そうするとローカル領域が逼迫していずれ pull できなくなるような気がしました (試していません)
容量を気にしないためにわざわざ s3 を使ったのにこれだと本末転倒かなと思った感じです

ローカル側の領域はキャッシュとして置いているだけで、例えば 1 ヶ月間 pull されていない場合は自動で削除してくれるみたいな挙動をしてくれるのであれば問題ないとは思います
もしくはローカルの領域が逼迫しだしたら勝手にキャッシュを削除してくれるようになっていれば良いのかなと思います

この辺の挙動も本当は試しているといいのだと思いますが、、、

最後に

harbor + s3 を試してみました
harbor のバックエンドは純正の registry なのでストレージドライバなども問題なく使えました

今回は install.sh を実行してインストールする方法を紹介しましたが、harbor は ovf 方式でも提供されています
ovf 方式の場合、設定ファイルが編集できないと s3 を使うのは厳しいかもしれません
ovf 方式の場合に s3 を設定する方法も試してみたいとは思っています

参考サイト

2017年5月15日月曜日

docker rgistry のイメージの保存先に s3 を使ってみた

環境

  • macOS 10.12.4
  • docker 17.05
  • docker registry 2.6.1

概要

docker registry には storage driver という仕組みがありローカルのファイルシステムの他に s3, gce, azure などのクラウドストレージを使うことができます
今回はその中の s3 storage driver を使って s3 に image を保存してみました

イメージの取得

  • docker pull registry

s3 にバケットを作成する

AWS コンソールから作成しましょう
リージョンや名前は好きなもので OK です
s3_with_registry1.png

s3_with_registry2.png

また、s3 にアクセス可能なパーミッションを持つユーザのアクセスキーとシークレットキーの準備しておいてください
必要なパーミッションはこちらです

コンテナを起動する

docker run -d \
--name registry \
-p 5000:5000 \
-e REGISTRY_STORAGE=s3 \
-e REGISTRY_STORAGE_S3_ACCESSKEY=your-accesskey \
-e REGISTRY_STORAGE_S3_SECRETKEY=your-secretkey \
-e REGISTRY_STORAGE_S3_BUCKET=cf.hawksnowlog \
-e REGISTRY_STORAGE_S3_REGION=ap-northeast-1 \
registry

-e で指定している環境変数にはパターンがあり REGISTRY_varialbes というパターンで指定します
そして variables の一覧はこちらにあります

例えば storage: -> s3: を指定したい場合は REGISTRY_STORAGE=s3 とします
storege: -> s3: -> accesskey: を指定する環境変数は REGISTRY_STORAGE_S3_ACCESSKEY となります
s3_with_registry3.png
とりあえず最低限上記の設定があれば動作すると思います

テスト

適当にイメージをダウンロードして、自分のレジストリに登録します

  • docker pull alpine
  • docker tag alpine localhost:5000/alpine
  • docker push localhost:5000/alpine

s3 にアップロードするので少しつまる感じはありますがすぐに終わると思います
完了したら s3 を確認してみましょう
ちゃんとイメージがアップロードされていると思います
s3_with_registry3.png

最後に

registry の s3 driver を使ってイメージ置き場を s3 にしてみました
結構簡単に使える印象はありました

一点だけ
試している段階で以下のエラーに遭遇しました

{"errors":[{"code":"UNAVAILABLE","message":"service unavailable","detail":"health check failed: please see /debug/health"}]}

始め REGISTRY_STORAGE_S3_ROOTDIRECTORY を好きなパスで指定していたのですが、これを指定しないようにしたらエラーが出なくなりました
おそらくコンテナから指定したパスにアクセスできる権限がなく上記のエラーになったんだと思います (すいません詳細に調べていないので間違っているかもしれません)

参考サイト

2017年5月13日土曜日

起動中のコンテナに対してホストのポートをバインドする方法

環境

  • CentOS 7.3.1611
  • docker 17.05

概要

例えば以下のような感じで起動してしまった場合に

  • docker run -d --name test nginx

80/tcp で動作するのはコンテナ内のみになるので localhost に curl などできません
普通はこの場合コンテナを削除して再生成するのですが、データを永続している場合などはデータが来てしまうので削除したくありません (本当はちゃんと永続して削除できるようにしておくのが正解ですが、、、)

そんな場合は起動中のコンテナに対してホストのポートにコンテナのポートをバインドする方法を紹介します

docker commit を使う

一旦別のイメージを作成して、そこから別のコンテナを起動する方法です

  • docker commit test new_nginx
  • docker run -d --name new_test -p 8080:80 new_nginx

で新しくコンテナを起動したら古いコンテナを削除します

  • docker stop test
  • docker rm test

一応動作していた状態のコンテナからホストにポートをバインドしたコンテナを新たに生成することができます

(失敗例) iptables を使う

失敗したんですが、載せておきます
docker run で -p オプションを指定すると iptables のルールにいろいろと追加されます
それと同じルールを追加できればアクセスできるのではと思いやってみました
動作中のコンテナの IP は 172.17.0.2 とします

まず iptables -nL で表示される

Chain DOCKER (3 references)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:80

を追加します

  • iptables -A DOCKER -p tcp -d 172.17.0.2 --dport 80 -j ACCEPT

次に iptables -t nat -nL で表示される

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
MASQUERADE  all  --  172.19.0.0/16        0.0.0.0/0
MASQUERADE  all  --  172.18.0.0/16        0.0.0.0/0
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:80
  • iptables -t nat -A POSTROUTING -p tcp -d 172.17.0.2 --dport 80 -s 172.17.0.2 -j MASQUERADE
  • iptables -t nat -A DOCKER -p tcp -d 0.0.0.0/0 --dport 8080 -s 0.0.0.0/0 -j DNAT --to-destination 172.17.0.2:80

で追加はできます
これで 8080 ポートにアクセスしてみようとしたのですが、そもそも 8080 ポートが LISTEN していないのでダメでした (当然と言えば当然)
試しに -p ポートで正しく動作しているときに 8080 ポートが何のプロセスで動作しているか確認したところ docker-pr というプロセスが 8080 で動作していました
なので、iptables を使う場合は同じようにプロセスもどうにかして起動させる必要があると思います

最後に

起動中のコンテナのポートをホストにバインドする方法を紹介しました
結果的には新しいコンテナを作ることで解決しましたが、本当は起動中のコンテナでやりたいところです
いろいろ調べてみたのですが、現状その方法はないかなと思います

確かにコンテナの概念的にも作り直せばいいだけなので、既存のコンテナの設定を変更できる必要はないのですがまぁできたら便利かなとも思います

2017年5月12日金曜日

docker の最新版を CentOS7 にインストールする ansible のレシピ

概要

CentOS7 を構築するたびに docker のインストールを手動で行っていたので ansible のレシピ化をしてみました
別のディストリビューションでの動作やバージョンを指定してのインストールには対応していません

環境

  • CentOS 7.3.1611
  • docker 17.05.0-ce, build 89658be
  • docker-compose 1.12.0
  • ansible 2.3.0.0 (実行側クライアント)

レシピ

  • vim roles/docker/tasks/install.yml
- name: Remove installed docker
  yum:
    name:
      - docker
      - docker-common
      - container-selinux
      - docker-selinux
      - docker-engine
    state: absent
- name: Install yum-utils
  yum:
    name:
      - yum-utils
    state: present
- name: Add docker yum repositry
  command: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- name: Enable repo
  command: yum-config-manager --enable docker-ce-edge
- name: Make cache
  command: yum makecache fast
- name: Update
  yum:
    name: '*'
    state: latest
- name: Install newest docker
  yum:
    name:
      - docker-ce

ちなみに docker-compose までインストールしたい場合は以下を追記すれば OK です

- name: Install docker-compose
  shell: "curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose"
- name: Add execution permission
  command: 'sudo chmod +x /usr/local/bin/docker-compose'

という感じのレシピを作成してメイン側の yml ファイルで

---
- hosts: all
  user: root
  roles: 
    - docker

とかすれば OK かなと思います

最後に

CentOS7 に ansible で docker の最新版をインストールする方法を紹介しました
docker のインストール方法は結構変わるのでいずれ使えなくなる可能性がありますが、備忘録として残しておきます

今回のレシピは変数やテンプレートも使っておらずかなりシンプルなレシピになっています
とりあえず動けば的な感じで作ったので command や shell も多用しています

ansible は最新バージョンに追従したりしなきゃいけないので結構メンテナンス大変ですね、、、