nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

OpenShift Enterprise 3.1.1にNexusをデプロイする

Mavenリポジトリミラーが内部にあったほうがビルドが高速になって便利なのでOpenShift Enterprise 3.1.1上につくります。

oc new-app sonatype/nexus
oc expose service nexus

簡単ですね。これでNexusに http://<nexus url>/ でアクセスできます。この例ではPersistenceVolumeは使ってませんが、そのうち使う例も書くかもしれません。

これでCentralとredhatをキャッシュしてくれるMirror Repositoryができました。

JBoss EAPのs2i builderでは以下のようにBuildConfigのenvで指定すれば、指定されたミラーが利用されるようになり、Nexusがjarをキャッシュしてくれるのでビルドが高速になります。

spec:
  strategy:
    sourceStrategy:
      env:
      - name: MAVEN_MIRROR_URL
        value: http://<nexus url>/content/groups/main/

OpenShiftのnodeSelector

OpenShiftのpodはnodeSelectorによって利用するノードが決まります。nodeSelectorにはざっくり2つのレベルがあり、projectのnodeSelectorとDeploymentConfigのnodeSelectorがあります。

上位のproject (namespace)レベルのnodeSelectorは、openshift.io/node-selectorアノテーションで指定されます。このプロジェクトのpodは全てこのregion=infraラベルの付与されたノード群にしかデプロイされません。

$ oc describe project default
Name:           default
Created:        18 hours ago
Labels:         <none>
Annotations:        openshift.io/node-selector=region=infra
            openshift.io/sa.initialized-roles=true
            openshift.io/sa.scc.mcs=s0:c1,c0
            openshift.io/sa.scc.supplemental-groups=1000000000/10000
            openshift.io/sa.scc.uid-range=1000000000/10000
Display Name:       <none>
Description:        <none>
Status:         Active
Node Selector:      region=infra
Quota:          <none>

アノテーションの付与にはoc annotate namespaceを利用します。projectはnamespaceのエイリアスでread-onlyなので、projectは更新できません。

oc annotate namespace default openshift.io/node-selector=region=infra

projectのnodeSelectorのデフォルトはmaster-config.xmlprojectConfig: defaultNodeSelectorに定義できます。プロジェクトにこのopenshift.io/node-selectorアノテーションが付与されていない場合は、defaultNodeSelectorが暗黙で適用されます。

/etc/origin/master/master-config.xml

projectConfig:
  defaultNodeSelector: region=primary

project (namespace)の書き換えはOpenShift管理者の権限が必要で、ユーザはprojectレベルのnodeSelectorを超えてpodをデプロイすることはできません。これを利用して、OpenShift管理者は特定のプロジェクトに専用のノードを割り当てたりすることができます。

ユーザはDeploymentConfigに追加でnodeSelectorを指定できます。例えば地域ごとにノード群にzone=tokyo1などのラベルを付与しておくことで、ユーザはnodeSelectorを指定してレイテンシの低いローカル地域のノード群にpodをデプロイ、というようなことが可能になります。

template:
  spec:
    nodeSelector:
      zone: tokyo1

Dell XPS 13 2015をFedora 23にした

奥さんのラップトップ、以前はそこそこ大きいのが良いということでInspiron 15 2010年モデルだったんだけど、少し前にHDDが壊れてしまいWindowsとはおさらば、SSD換装してFedora 21という構成にしていた。最近は子供も居るしちょこちょこ使うユースケースが増えて、やはりもう少しコンパクトでかわいいラップトップがいい、ということでMac超え狙って開発したという話のDell XPS 13 2015 (XPS 9350 Skylake model)を買っていた。なかなかかっこいいボディである。

プリインストールされているWindows 10で試しに運用してみたのだけど、やはりWindowsに慣れていないので仕事しづらいということと、日本語入力がなぜかデフォルトでカナ入力になるという現象が発生して設定いろいろ探して変えたけどなおらないという微妙な状態になってしまい、非技術系な奥さんですらFedoraのほうが使いやすいという話になってFedora 23にすることにしたのであった。

  • Win上でBIOSアップデート
  • 起動F2でBIOSに入ってUEFIブートをLegacyへ、Secure Boot無効化、RAIDをAHCIへ変更
  • USBブートしてFedora 23インストール

UEFIでこのへん手間どった。BIOSアップデートしていないとFedora 23のインストーラが起動時にカーソル出して固まる。

インストールしたFedora 23起動するとWiFiが認識されない。調べてみるとBroadcomのもので、対応するLinuxのドライバがない、もしくは不安定、という状況のWiFiチップのようだ。

sudo lspci -vnnの結果が以下。

3a:00.0 Network controller [0280]: Broadcom Corporation BCM4350 802.11ac Wireless Network Adapter [14e4:43a3] (rev 08)

ここでおもむろにNexus 6をUSB接続してテザリング、Nexus 6は自宅のWiFiにつないでるのでとりあえず結果的にWiFiに接続している状況にしていろいろ試行錯誤。

まずはsudo dnf update -yカーネルも最新にしてリブートしたけど状況変わらず。

いろいろ調べていくと標準のbroadcom向けドライバは未対応、rpmfusion-nonfreeのbroadcom-wlが対応しているかもしれないという情報を元にインストールしてみたけどダメ。

他に43a3はLinux 4.4カーネルのbrcmfmacというドライバで対応しているという情報があったので、試してみることに。Fedora 23の現時点でのstableのカーネルは4.3.5だが、Linux 4.4カーネルはtestingにある状況なのでそちらをインストールしてみる。

sudo dnf install kernel -y --enablerepo=updates-testing --bestでkernel-4.4.2-301が入るのでリブートしてみるとビンゴ、WiFiが使えるようになった。今のところ特に不安定ということもなく、普通に使えている。

調べている過程で、多くの人はこのXPS 13にLinuxをインストールするためにWiFiチップをIntelのものに換装という手をとっているみたいだったけど、XPS 13のアルミ削り出しボディ開けるのも結構シビアでツメ折れるリスクがあるという記述もあったので、やらなくて済んで良かった。

追記: 次の日dnf updateしたらstableからkernel-4.4.2-301が落ちてきたというオチ。今日以降の人はとりあえずネットワークをゲットしてdnf updateすれば普通に使えるということになる。

OpenShift上でネットワークサービスを提供しないイメージでコマンドを実行する

OpenShiftにデプロイするイメージは通常、EXPOSEENTRYPOINT/CMDが定義されている、ネットワークサービスを提供するイメージです。これらが定義されていないイメージは正常に起動していないとみなされ、動作しません。

例えば、以下のようなDockerコマンドは一見OpenShift上では実行できないように思えます。

docker run -it centos bash

実際にはこのようなコマンドを実行する方法があります。

oc run --restart=Never --attach --stdin --tty --image centos centos bash

イメージ名は--imageで指定します。続くパラメータはpod名とコマンド部です。コマンド部は通常のDockerと同一で、CMDが指定されているイメージであればコマンド上書き、ENTRYPOINTが指定されているイメージであればエントリポイントのコマンドのパラメータとなります。

MattermostをOpenShift Enterprise 3.1.1上でインスタントアプリケーション化する

MattermostはSlackのようなWebベースのチームチャットツールです。GolangとReactで書かれています。

以下の一行でセットアップができるようになっています。Mattermost 1.4.0, MySQL 5.6でMySQLがPersistentVolume使います。コードはGitHubにあります。

oc new-app -f https://raw.githubusercontent.com/nekop/openshift-sandbox/master/apps/mattermost/mattermost.yaml

アクセスすると以下のように初期画面がでます。

f:id:nekop:20160205145040p:plain:w300

このアプリケーションの定義ファイル(マニフェスト、とも呼ばれます)は200行程度です。route定義は含めていないのですが、oc expose svc mattermostすればrouteができて環境に応じたURLが割り当たるはずなので、マニフェストには含めなくてもいいかなぁ、と思っています。

Mattermostはjson設定ファイルにデータベースの接続情報を持つので、DockerのENTRYPOINTに指定する起動シェルスクリプトで、環境変数からデータベースの接続情報をこのファイルに反映させる、という処理をする必要があります。

Mattermostはデータベースの接続情報の他にも設定項目はいっぱいあるのですが、デプロイ時に動的に変わるものはとりあえずデータベースの接続情報だけのような感じだったので、あとの設定はイメージに焼いてしまっていいかなーと思って環境変数化していません。というか50個くらいある設定項目を全部環境変数にしてしまうと環境変数ヘルと呼ばれるような状態になりますし、json書き換えるのも収集つかなくなると思います。他の設定項目を書き換えたかったらおとなしくイメージを再ビルドすることにします。ビルドはOpenShiftに投げるだけですしね。

これからのDocker対応アプリケーションでどのように設定を受け取るか、というのは結構重要なポイントかもしれません。とりあえずアプリケーションは設定を環境変数を受けとれるようにする、という機能は入れておいて欲しいですね。yamlやらjsonやらxmlの設定ファイルに環境変数を反映させるようシェルスクリプトで書き換えるのはかなりきびしい印象があります。また、外部から設定情報をフェッチする、という方法も考えたんですがDockerイメージの自己完結性が失われるのでかなりダメな感じがします。外部に置いてある設定ファイルを編集したら動いていたDockerイメージが動かなくなった、というのはちょっと勘弁してもらいたいシナリオです。DockerイメージはDocker環境で完結する情報だけで動作すべきでしょう。

今回Mattermostのインスタントアプリケーションを作る手順は以下のような感じでした。

  1. Dockerfileを書いてgit push
  2. ベース作成のために oc new-app
    • oc new-app <git clone url>
  3. oc exportしてベースにするyaml生成
    • oc export dc,is,bc,svc -o yaml --as-template=mattermost > mattermost.yaml
  4. import時に省略できる設定も明示的にexportされてしまうので(ポータビリティ考えるとまぁそうだよね感)、そのへんは消す。dancer-exampleが結構最小に近いようなので参考にした。
    • oc get template dancer-example -n openshift -o yaml
  5. アプリケーション名をAPPLICATION_NAMEパラメータにして作成時にカスタマイズできるようにする
    • mattermost${APPLICATION_NAME}に置換して最終部パラメータにAPPLICATION_NAMEを定義
  6. MySQLを追加する。mysql-persistentのテンプレートからobjectsとparametersを抜き出してそのままmattermost.yamlにつなげる
    • oc get template mysql-persistent -n openshift -o yaml
  7. MySQLのパラメータをmattermostのDeploymentConfigにも渡すようにする
  8. mysqlのDeploymentConfigのenvをそのままコピー
  9. 設定ファイルにデータベース接続情報を反映させて起動するmattermost-launch.shを作成してDockerfileENTRYPOINTにする

いくつか参考になるテンプレート、シェルスクリプトやDockerfileを把握しておけば1時間程度でできるかな、という雰囲気です。

WildFly 10.0.0.Final リリースしました

Java EE 7アプリケーションサーバであるWildFly 10.0.0.Finalがリリースされました。WildFlyのサイトからダウンロードできます。

f:id:nekop:20160201100503p:plain

リリースノートはこちら。起動時間は僕の手元で1.6秒でした。

09:53:17,610 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) started in 1606ms - Started 267 of 553 services (371 services are lazy, passive or on-demand)

ハイライトとしては以下のような感じです。

ActiveMQ ArtemisはHornetQがActiveMQに合流してできた新しいメッセージングミドルウェアです。このような合流はJavaミドルウェアだと以前にXML WebServicesでCeltixとXFireが合流してApache CXFができた、というのがありますね。

Java EE 7の商用サポート版であるJBoss EAP 7はこのWildFly 10をベースにエンタープライズ版になるためのエンジニアリングがされてリリースされる予定です。JBoss EAP 7のリリース予定日はまだ公式には未発表ですが、今までのリリースの傾向からするとたぶん今年の前半には出るんじゃないかなーという感じです(非公式見解です、内部リリース予定情報は見ないで書いています)。Red Hat Summitも6月にありますし。

OpenShiftのsource-to-image (s2i)をすごく簡単に説明するよ

この投稿はOpen PaaS Advent Calendar 2015の16日目の記事です。

OpenShiftにはソースコードからDockerイメージをビルドするs2iという仕組みがあります。ドキュメントを見ると煩雑な印象を受けるかもしれませんが、実はとっても簡単です。

単体のs2i

s2iはgithubなどのソースコードのURL、s2i builder imageを受け取って、Dockerイメージを作成するソフトウェアです。以下実行例ですがそのまんますぎて説明のしようがないくらいです。openshift/ruby-20-centos7というs2i builder imageを使ってtest-ruby-appというDockerイメージをビルドしています。

s2i build git://github.com/pmorie/simple-ruby openshift/ruby-20-centos7 test-ruby-app
docker run --rm -i -p :8080 -t test-ruby-app

s2i builder image

s2i builder imageはs2iスクリプトが入っていて、ラベルが付いているだけのDockerイメージです。ぶっちゃけ以下のラベル付けるだけでs2i builder imageの要件は満たせます。

LABEL io.openshift.s2i.scripts-url=image:///usr/libexec/s2i

s2iはこのs2i builder imageのラベルからs2iスクリプトの場所を読み込み、実行してその結果のイメージを出力のDockerイメージとするだけです。s2iをマニュアルでやるとするとdocker runしてs2iスクリプトをキックしてdocker commit/tagする、というイメージです。

OpenShiftでのsti-builderイメージ

OpenShiftではopenshift-sti-builderとかorigin-sti-builderなどのイメージが提供されていますが、これらはs2i builder imageではありません。ややこしいですね、すみません。

これは実際には最初に説明した「単体のs2i」をOpenShift環境上で行うDockerイメージ、つまりOpenShift版s2iです。openshift-sti-buildコマンドというs2iを実行するコマンドが入っていて、OpenShift上ではs2iはこのイメージで実行しています。

stiだったりs2iだったり

同じです。最初stiだったんですけど途中でs2iにしようぜってことになったんですが全部修正されているわけではないので表記が混ざっています。熟練したOpenShift使いには同じに見えるはずです。

まとめ

  • s2iはすごくシンプル
  • s2i builder imageもスクリプト入ってるだけの単なるDocker image
  • OpenShiftのsti-builderは単なるs2i