出力を入力へ

プログラミングに関する基本的な事を中心にまとめます

GitHub Actionsのsteps.withディレクティブでは環境変数ではなく出力パラメータを利用する

タイトルがすべて.

steps.with ディレクティブにおける制御

GitHub ワークフローにてActionsを呼び出すとき, Actionsのパラメータ設定としてsteps.withディレクティブを利用する.

例えば,GitHubのリリースページにビルド成果物をアップロードする Upload Release Asset Actions では以下のように指定する.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact.zip
          asset_name: my-artifact.zip
          asset_content_type: application/zip

ここで, steps.withディレクティブ以下の upload_url, asset_path, asset_name, asset_content の4つが upload-release-asset Actionsの入力パラメータである.

入力パラメータの動的制御

Releaseページにアップロードするファイルを指定する asset_path において, ビルドソフトウェアのバージョンが含まれたファイルを指定したい. ソフトウェアバージョンを環境変数に設定したとして, 以下のような利用方法を想定する.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Set software version
        run: |
          VERSION=$(cat VERSION)
          echo ${ VERSION }
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact-${ VERSION }.zip
          asset_name: my-artifact-${ VERSION }.zip
          asset_content_type: application/zip

このように,VERSIONファイルに格納されているソフトウェアバージョンをVERSION変数に格納し, ビルド成果物の制御にこの値を利用したい. しかし,この方法には以下の2つ問題がある

このため,Set software versionのステップにおける echo ${ VERSION }では期待した通りの値が出力されるが, Upload Release Assetのステップではそんなファイル存在しない (##[error]ENOENT: no such file or directory )と怒られてしまう. これは,VERSION 変数が設定されていない問題と,仮に設定されていたとしてもその変数を利用できない問題の両方を解決する必要がある.

出力パラメータによる制御

ではどうするかと言うと環境変数ではなく 出力パラメータ(output parameter)を利用しましょう,というのが解決策である. 出力パラメータは別のステップから出力結果を参照するための仕組みであり, steps.withディレクティブでも利用できる.

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Set software version
        id: software_version
        run: |
          VERSION=$(cat VERSION)
          echo ::set-output name=version::${ VERSION }
          echo ${ VERSION }
      - name: Check output parameter value
        run: |
          echo ${{ steps.software_version.outputs.version }}
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./my-artifact-${{ steps.software_version.outputs.version }}.zip
          asset_name: my-artifact-${{ steps.software_version.outputs.version }}.zip
          asset_content_type: application/zip

このように, Set software version ステップにて VERSION変数の値を出力パラメータに設定しているので, 後段の Check output parameter value では最初に設定した VERSION 変数と同じ出力を確認することができ, Upload Release Assetステップの asset_pathasset_name でも利用することができる.

Requestsで取得したwebサイトの文字化けに対処する

Requestsで取得したWebサイトをlxmlスクレイピングしようとすると, いくつかのサイトで文字化けすることに気が付いた.

これに対処するのに苦労したし,何ならまだ完全には解決できていない. 間違いとかあれば教えて欲しい.

文字化けの確認

例えば O'reillyのサイトだと文字化けが発生する. webサイトのタイトルを出力するPythonスクリプトは以下の通り.

import requests
import lxml.html

res = requests.get('https://www.oreilly.co.jp/books/9784873118864/')
root = lxml.html.fromstring(res.content)

print(root.xpath('//title')[0].text)

このスクリプトの実行結果は以下の通り

O'Reilly Japan - ã¬ã¬ã·ã¼ã³ã¼ãããã®è  ´

上記サイトはタイトルに「O'Reilly Japan - レガシーコードからの脱却」が指定されており, この通り出力して欲しい.

このブログでもダメ.

'å\x87ºå\x8a\x9bã\x82\x92å\x85¥å\x8a\x9bã\x81¸'

一方で,Yahooニュースなら正常に動作する.

'Yahoo!ニュース'

原因

もちろんエンコーディングの指定誤りが原因で, Requests で取得したwebサイトの文字コードを正しく識別できていないことが原因. これについては,以下のサイトが詳しい.

orangain.hatenablog.com

実際,HTTPレスポンスを確認すると

$ wget --server-response https://www.oreilly.co.jp https://www.oreilly.co.jp/books/9784873118864/
...
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Date: Sat, 12 Oct 2019 16:42:53 GMT
  Content-Type: text/html
  Content-Length: 23094
  Connection: keep-alive
  Server: Apache
  Last-Modified: Thu, 10 Oct 2019 05:06:47 GMT
  ETag: "5a36-594875e4b2e01"
  Accept-Ranges: bytes
  Vary: Accept-Encoding

...

$ wget --server-response https://thaim.hatenablog.jp/ 
...
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Server: nginx
  Date: Sat, 12 Oct 2019 16:25:25 GMT
  Content-Type: text/html; charset=utf-8
  Transfer-Encoding: chunked
  Connection: keep-alive
  Vary: Accept-Encoding
  Vary: User-Agent, X-Forwarded-Host, X-Device-Type
  Access-Control-Allow-Origin: *
  Content-Security-Policy-Report-Only: block-all-mixed-content; report-uri https://blog.hatena.ne.jp/api/csp_report
  P3P: CP="OTI CUR OUR BUS STA"
  X-Cache-Only-Varnish: 1
  X-Content-Type-Options: nosniff
  X-Dispatch: Hatena::Epic::Web::Blogs::Index#index
  X-Frame-Options: DENY
  X-Page-Cache: hit
  X-Revision: a7694746800267be0e2d318311d7b13e
  X-XSS-Protection: 1
  X-Runtime: 0.042860
  X-Varnish: 34747135
  Age: 0
  Via: 1.1 varnish-v4
  X-Cache: MISS
  Cache-Control: private
  Accept-Ranges: bytes
...

$ wget --server-response https://news.yahoo.co.jp 
...
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Cache-Control: private, no-cache, no-store, must-revalidate
  Content-Type: text/html;charset=UTF-8
  Date: Sat, 12 Oct 2019 16:26:09 GMT
  Set-Cookie: B=1qlmjdleq3vl1&b=3&s=l0; expires=Tue, 12-Oct-2021 16:26:09 GMT; path=/; domain=.yahoo.co.jp
  Vary: Accept-Encoding
  X-Content-Type-Options: nosniff
  X-Download-Options: noopen
  X-Frame-Options: DENY
  X-Vcap-Request-Id: 9826dce8-3f25-4d7b-7749-c0e9fdcd8fba
  X-Xss-Protection: 1; mode=block
  Age: 0
  Server: ATS
  Transfer-Encoding: chunked
  Connection: keep-alive
  Via: http/1.1 edge2502.img.umd.yahoo.co.jp (ApacheTrafficServer [c sSf ])
  Set-Cookie: XB=1qlmjdleq3vl1&b=3&s=l0; expires=Sat, 19-Oct-2019 16:26:09 GMT; path=/; domain=.yahoo.co.jp; secure; samesite=none
...

そう,実ははてなブログではContent-Typeが適切に設定されているのに上手くいかない. 文字コードを小文字で指定しているのが原因かとも思ったけれど RFCによるとどちらでもよいみたい.

tools.ietf.org

requestsは chardet文字コードの 推定も行っているので確認してみたけど, ブログもYahooニュースもどちらもUTF-8を認識している.

>>> import requests, lxml.html
>>> res = requests.get('https://thaim.hatenablog.jp/')
>>> res.encoding
'utf-8'
>>> res.apparent_encoding
'utf-8'
>>> res = requests.get('https://news.yahoo.co.jp/')
>>> res.encoding
'UTF-8'
>>> res.apparent_encoding
'utf-8'

これについてはお手上げで, なぜYahooニュースでは上手くいくのに はてなブログでは上手くいかないのかわからなかった.

対策

根本原因がどうであれ, 正しく文字コードを指定して処理すればいいだけなので, この問題を解決するだけならlxmlでスクレイピングする前に文字コードを指定してデコードしてあげればよい.

意図した通り動作するスクリプトは以下の通り.

import requests
import lxml.html

res = requests.get('https://www.oreilly.co.jp/books/9784873118864/')
root = lxml.html.fromstring(res.content.decode('utf-8'))

print(root.xpath('//title')[0].text)

ここでは,UTF-8で固定しているけれど, res.apparent_encoding を指定したり,HTML内で文字コードを指定されているのであればそれに従う方法もある.

Terraform backendsのパラメータ化にPartial Configurationを利用する

Terraform Backends

対象インフラの状態を管理するtfstateファイルをチーム共有・管理するためにbackendを利用する.

www.terraform.io

例えば,AWS S3をバックエンドに利用する例は以下の通り. これによりS3でtfstateファイルを管理できる.

terraform {
  backend "s3" {
    bucket = "my-tfstate"
    key    = "sample-project/prod.tfstate"
    region = "ap-northeast-1"
  }

  required_version = "= 0.12.2"
}

backendにおける設定のカスタマイズ

上記設定においてバケット名やkey(ファイル名)をパラメータ化して実行時に指定したい.

バケット名はGitで公開したくない,keyは開発/検証/本番 環境によって切り替えたい といった要望に対応するため,各種設定項目に変数を利用したい. 場合によってはアクセスキーやシークレットキーの指定も必要で, その場合は特にGit以外で管理する必要がある.

これを解決するために,パラメータ部分に変数を利用したい

tf_backend_bucket = "my-ftstate"
tf_backend_key    = "sample-project/prod.tfstate"
variable "tf_backend_bucket" {}
variable "tf_backend_key" {}

terraform {
  backend "s3" {
    bucket = var.tf_backend_bucket
    key    = var.tf_backend_key
    region = "ap-northeast-1"
  }

  required_version = "= 0.12.2"
}

しかし,このような方法でterraformを実行してもエラーになる. backendの設定には変数は利用できない.

$ terraform init

Error: Variables not allowed

  on main.tf line 3, in terraform:
   3:     bucket = var.tf_backend_bucket

Variables may not be used here.


Error: Variables not allowed

  on main.tf line 4, in terraform:
   4:     key    = var.tf_backend_key

Variables may not be used here.

解決策

バックエンドのパラメータ化には変数ではなく Partial Configuration を利用する. Partial Configurationでは,terraform init実行時のオプションとして -backend-config を指定する.

  -backend-config=path This can be either a path to an HCL file with key/value
                       assignments (same format as terraform.tfvars) or a
                       'key=value' format. This is merged with what is in the
                       configuration file. This can be specified multiple
                       times. The backend type must be in the configuration
                       itself.

key=value 形式で指定するなら以下の通り:

$ terraform init -backend-config="bucket=my-tfstate" \
                 -backend-config="key=sample-project/prod.tfstate"

設定ファイルに書くなら以下の通り:

$ terraform init -backend-config="backend.tfvars"
bucket="my-tfstate"
key="sample-project/prod.tfstate"

このとき,backendの設定は空欄とする.

terraform {
  backend "s3" {
    region = "ap-northeast-1"
  }

  required_version = "= 0.12.2"
}

あらかじめデフォルト値を設定しておいてもよい. -backend-configオプションで指定すると上書きできる.

また,tfファイルで未設定のまま-backend-configで指定しないと インタラクティブに入力が求められる.

backendに Partial Configurationではなく 変数を利用したいというIssueは挙がっているけど, 対応される見込みはなさそう.

GoCon 2019 Springに参加しました

半年に1度のGo言語に関するカンファレンスのGo Conference 2019 Springに参加しました.

自分はGo言語は読む方がメインで,少し書く程度というGo言語初心者. そんな自分でもカンファレンス発表内容はGo言語自体の話だけではなく, Go言語を用いたソフトやシステムの話など幅広いトピックを扱っており, 非常に刺激になった.

gocon.jp

gocon.connpass.com

以下自分が聴講したセッション

keynote: Go Module Proxy Life of a Query

github.com

go modulesの話はなんとなく知っていた程度なので, 正直なところ概要しか理解できなかったのが残念だった. 発表のKatieさんの英語は聞きやすかったけど,前提知識が異なる場合は自分の英語力もまだまだだと実感した. 特にChecksum Databaseの話が難しかった.

前提知識としては,公式のブログ記事を 理解しておけばもう少し楽しめただろうか? とはいえ,Mirror (module proxy) の話は面白かったし, どの程度データ量等削減されるのかは試してみたい.

A1: Case Studies of designing developer friendly libraries

speakerdeck.com

内容としてはGo言語に限らない話で,かつGo言語の場合は特にどうなのかしっかりまとめられていた. なので自分みたいなGo言語以外をメインに利用している人には特に刺さると思った. 実際, context.Context の話とか自分の実装は適当だったなと反省した.

B2: エラー設計について / Designing Errors

docs.google.com

エラー設計はまさに悩んでいるところだったのでちょうど良い内容だった. failure とその設計思想を知れたのはよかった. 一方で自分で書くgoアプリは小規模なものなので,エラーハンドリング用パッケージの導入まで必要かは検討の余地がある. このあたりはいろいろ試行錯誤してみたい.

A3: Goによる外部プロセス起動ベストプラクティス及びtimeoutパッケージ徹底解決

songmu.github.io

goの外部プロセス停止に関する仕組みを調査・実装する上で, オフィシャルの見解の確認やGNU timeoutをベースとした知見の流用など, 開発の取り組み方がすばらしいと感じた. おまけにあたる終了コードを正しく取得するという内容も, 自分もきちんと考えていなかったことを再認識したので聞けて良かった.

A4: Design considerations for container-based Go applications

speakerdeck.com

どちらかと言うとコンテナの話がメインで,基本がしっかりと抑えられていた. 一方でGoの方はあっさりと結論だけ示されている形式だったので, Go初心者の自分としてはもう少しこのあたりの試行錯誤などが気になった. 実際に自分で実装するとき,他の実装方法やPros/Consがないかは自分でいろいろ考えてみたい.

A5: Expand observability in Go

docs.google.com

パフォーマンスチューニングの話は現状まったく取り組めていないので とっかかりになればいいなと考えていたけど, パフォーマンスチューニングの基礎から実際にどのように取り組めばよいか, デモ付きで話を聞けたのはすごくよかった. 忘れないうちに実践してみたいところ.

H6: Dive into Buildkit LLB with Go

speakerdeck.com

Dockerイメージ生成のはなしは概要レベルでしか把握できていなかったのでそれが ソースコードレベルで知れたのはよかった. Dockerfileの静的解析の話とかは度々出てくるので, 実際に手を動かして試してみるためのとっかかりになりそう. Docker / BuildKit は自分がGo言語を始めるきっかけでもあったので このレベルで理解できるようになりたい.

H7: We want AWESOME CLI tool & development

speakerdeck.com

Golden fileについては知らなかった. 参考となるリポジトリを複数挙げていたのは 実際に自分が実装するときの参考になるので助かる. 複数プラットホームにおけるHOMEの取得は, 標準でも対応しているみたいなので別途確認しておきたい.

B8: CPU, Memory and Go

speakerdeck.com

あまり詳細なGo言語の実装等の話になると理解できなくなるから困るなと心配していたけど, 計算機の基礎からC言語との比較までと,自分が理解できるちょうどいい内容だった. むしろ最近はこの手の話から遠ざかっていたのでいい復習になった. メモリの話がメインだったのでもう少しCPUや実行速度の話が気になった.

ansibleでansible-tower-cliモジュールを利用する

Ansible TowerCLIで制御するためのansible-tower-cli、 これをansibleで制御するansible-tower-cliモジュールの利用に苦労したのでそのまとめ。

ちなみに、動作検証に利用しているのはAnsible Towerではなく、そのOSS版のAWX。 動作環境は以下の通り

  • OS: Ubuntu 18.04
  • ansible: 2.7.10
  • tower-cli: 3.3.3

ansibleとansible-tower-cliの関係

当初の自分のイメージでは、 ansibleがtower-cliのライブラリを利用しつつtower-cliを意識することなく ansible towerを制御できるものだと思っていた。

ansibleのインベントリではansible towerを指定して動作する、 つまりは以下のようなイメージ。

f:id:thaim:20190412003936p:plain
誤解していたansible-tower-cliモジュールの動作

ところはこれは誤りで、当初ansibleを実行しても以下のようなエラーが表示されるだけで、 どうしてもansible-tower-cliモジュールが利用できていないことから悩んでいた。

FAILED! => {"changed": false, "msg": "ansible-tower-cli required for this module"}

ansibleのansible-tower-cliモジュールは単に tower-cliを実行する機能しか持たない。 ansible-tower-cliはansibleの実行ホストではなく、 接続先ホストにインストールしておく必要がある。 つまりは以下のようなイメージ。

f:id:thaim:20190412004222p:plain
実際のansible-tower-cliモジュールの動作

実際にはあえてansibleとansible-tower-cliの実行元を分ける必要はないので、 ansibleはローカルホスト接続して実行するとよさそう。 つまりは以下のようなイメージ。

f:id:thaim:20190412004758p:plain
ansible-tower-cliを用いた実際の構成

ansible-tower-cliのインストール方法

ansibleとansible-tower-cliの関係を確認している中で、 ansible-tower-cliのインストール方法も影響することがわかった。

ansible-tower-cliをグローバルインストールしている場合 (pip install --system ansible-tower-cli など)、 これは問題は発生しないが、 ローカルインストールした場合 (pip install --user ansible-tower-cli など)、 ansibleがansible-tower-cliモジュールを参照できない可能性がある。

ローカルインストールした場合にansibleからtower-cliが呼び出せるのは 両方とも同一バージョンのpythonインタプリタにインストールされた場合のみ。 つまりansibleもansible-tower-cliもpip install --userまたは、 pip3 install --userでインスートールした場合のみ動作する。

ansibleはapt installでインストールした場合や、ansibleはpip3でansible-tower-cliはpip、 またはansibleはpipでansible-tower-cliはpip3でインストールした場合は動作しない。

ansible-tower-cliはpipでしかリリースされていないので ansibleをapt installした場合はansible-tower-cliもpip install --systemでインストールする、 どうしてもuser installしたい場合はansibleと同じタイミングで同じ方法で インストールするように注意した方がよさそう。

tower-cliSSL検証

Ansible TowerをHTTPでホストする場合や自己署名のHTTPSでホストする場合は ansible-tower-cliからの接続でverify_sslオプションをfalseとする必要がある。

ansibleでansible-tower-cliモジュールを利用する場合は、 自動的に ~/.tower_cli.cfgが参照されるが、このverify_sslオプションのみ読み込まれず デフォルトのTrueが反映される。 一方で、ansible-tower-cliモジュールで明示的に設定ファイルを指定するとき (tower_config_fileでファイルを指定するとき)は設定ファイルで指定したverify_sslオプションが反映される。

個人的にはこの動作は非常に気持ち悪いが、 そもそもansibleの接続先のtower_config_fileを 明示的または暗黙的に参照するのはよくなさそう。

tower_config_fileは参照せず、ansible-tower-cliモジュールで 面倒でも明示的にホスト名やユーザ名などのオプションを指定した方がよさそう。

OpenShift Meetup Tokyo #1 に参加しました

海外からOpenShiftコアメンバを招いての OpenShiftの最新機能および今後のロードマップについて語ってもらう 国内初の?OpenShift公式コミュニティイベントに参加してきました.

参加者も既にOpenShiftを利用している人が多く, LT含めて内容が濃いイベントでした.

openshift.connpass.com

OpenShift JPのご紹介

発表に先立ってOpenShift関連の簡単な紹介.

海外含めたOpenShift共通のコミュニティとして OpenShift Commonsをチェックしておくといいよか, 今後国内でもRedHat Forumとかハンズオンセミナーあるよとか.

commons.openshift.org

redhat-forum.jp

www.redhat.com

中でも,気になった内容として OpenShift Container Engine という OpenShiftの新しいディストリビューション(?)の紹介があった. 既にCI環境等を構築しているユーザ向けに ロギングやCI/CD機能などをOpenShift Container Platformから省いたものらしい.

確かに,すべての環境をKubernetes/OpenShiftに移行しないケースもあるので 選択肢の1つとしてあるのはうれしい気がする.

blog.openshift.com

OpenShift Strategy and Roadmap & OpenShift Day 2 Management

タイムテーブルでは2つに分かれていましたが内容盛り沢山のため, 休憩カットでOpenShift 3.11の最新機能を2つのデモを通しての紹介と メジャーアップデートを控えたOpenShift 4.0についての紹介がありました.

www.redhat.com

リリースサイクルの話として, Kubernetesのリリースから1-3ヶ月後の 1サイクル遅れでリリースされるという話や KubernetesのコントリビューションはGoogleRedHatが大半を占めているという話. また,OpenShift 3.11ではCoreOSを買収し,Techtonicの機能を OpenShiftに統合したリリースであるという説明があった.

具体的なTechtonic由来の機能として,管理者向けコンソールが統合され, クラスタのステータスやリソース状況が確認できる. また,OpenShift上の操作イベント/発生イベントが時系列で確認でき, 各イベントから詳細な内容を確認できるということを 実際の画面を通した紹介があった.

また,デモとしてRBACの機能により参照可能なリソースを GUIから操作可能であることの紹介があった. 権限設定ミスにより本来参照できて欲しくないリソースが参照できてしまう状況にて, 管理者がGUIを通して権限を修正することで, 参照可能なリソースが修正できることを実際に動作させて説明があった.

もう1つの主要な新機能として PrometheusおよびGrafana による 監視機能の紹介があった. 単に連携しているだけでなく,コミュニティベースの知見を活かした 監視ルール等が反映されているとのこと. ただし,収集した監視データは永続化されていないとのこと. 永続化するには別途ボリュームプラグイン等を導入して対応する必要があるらしい.

プレビュー版ではあるが,Operatorも3.11から導入された. Prometheusやetcd, mongoDBなどのOperatorがある.

そのあと,OpenShift 4.0のロードマップにっついての説明があった. 新機能として, Unified Hybrid Cloud, Day-2 Operations, Kubernetes App Marketplace の紹介があった.

Unified Hybrid Cloud は パブリッククラウドやオンプレミスで動作する 複数のOpenShiftを連携動作させるための機能. Day-2 Operationsとして,Operatorが正式サポートされる. 中でもAnsible Operatorがサポートされ, Operator Frameworkに従ってansible playbookが実行できるようになる件は気になる話だった. また,Istioによるサービスメッシュも統合される. (実際にはIstioは3.11から Tech Previewで利用できる).

これ以外にも, Container Native Virtualizationの話があった. これはKubeVirtをベースとし,podを操作するように VM操作ができるようになるものらしい. 以下スライドの16ページにも記載あるが, VMがコンテナ内で動作しているように見える.詳細がよくわからない.

www.slideshare.net

ホストOSとしてRHELおよびCoreOSについても説明があった. 従来のOpenShift3.11まではOSにRHELを利用していたが, OpenShift4からはこれに加え,CoreOSを利用する選択肢が増える. このときデプロイがOpenShiftと統合されイミュータブルなインフラとして管理できる.

加えて,アップデートが Over the Airとなることで運用が容易かつ 高頻度なアップデートが可能になる. もちろんアップデートが強制されるわけではなく ユーザがアップデートのタイミングを決定できるし 必要に応じてロールバックもきちんとサポートされているという補足もあった.

そんな気になるOpenShift4のリリースは パブリックベータを2018年12月-2019年1月頃に公開し, フィードバックを踏まえて正式リリースになるとのこと.

LT: OpenShift上で動くAPI管理「3scale」

www.slideshare.net

OpenShiftにおけるAPI管理ツールである3scaleの紹介. APIゲートウェイはもちろん,課金・負荷抑制のための流量制御や GUIベースでの仕様設定,API利用状況の確認 keycloakと連携した認証機能などをサポートする.

LT: プライベートネットワーク上でOpenShift

プロキシ環境下でOpenShiftをセットアップする場合における プロキシ設定やDNS設定のカスタマイズ方法の紹介. Ansibleスクリプトの修正やデプロイ後の影響範囲など.

Jenkins ユーザ・カンファレンス 東京 2018 に参加しました

作成・公開が遅くなったけど,3週間前に開催されたJenkinsユーザカンファレンスの参加記録です.

Jenkinsの公式ユーザカンファレンスとして3年に1度開催されている Jenkins ユーザ・カンファレンス東京2018に参加しました. 3連休中日の9/23(日)に開催でしたが,約300名規模が参加するなど非常に盛況でした.

聴講セッション

基調講演 (CloudBees, Inc. 川口耕介さん)

ソフトウェア開発・CI/CDの重要性といった全体の話から Jenkinsのユーザ拡大,CloudBeesの取り組みといった現状についての紹介. その後Jenkinsの最近の新機能として以下の5つを中心に説明があった:

  • ビルドフローを設定ファイルとして記述してリポジトリに保存する Jenkins Pipeline
  • デフォルト設定とプラグインをパッケージ化して5分でJenkinsを使えるようにする Jenkins Evergreen
  • Jenkins自体の設定をファイルとして記述し履歴管理を可能にする Configuration as Code
  • JenkinsがSPOFになることを回避するため,成果物等をS3に保存するなど分散実行する Cloud Native Jenkins
  • Kubernetesと連携し,簡単にかつ学習コスト少なくKubernetesの恩恵を受けられるようにする Jenkins X

既に利用しているPipelineや情報としては知っているJenkins Xもあるが, 知らない機能やJenkinsが現在も大きく変化しようとしていること, その方向性を知ることができたのはよかった. 新機能についてはリリースされたばかりのものもあるので実際に評価して確かめていきたい.

Accelerate with Jenkins X (James Rawlings さん)

クラウドネイティブな開発を簡単に実現するため, 簡単には利用できないKubernetesをJenkins Xを通して簡単に利用できるようにする, というJenkins Xのミッションとそのデモの紹介.

デモでは実際にコマンドからGitHub上にリポジトリを構築したり,Kubernetesクラスタを構築したり, パイプラインを生成してビルド・デプロイを実施したりできる.

デモを見るまではCI環境として利用するKubernetesを構築することが Jenkins Xの内容だと理解していたが,説明やデモを見て Kubernetesは完全に隠蔽してその上で動かすアプリを提供するものだと理解した.

Jenkinsおじさんの育て方 (ビズリーチSREチームマネージャー 阪本稔さん)

slides.com

今後もCIの重要性が増す中で,開発を支援しトラブル対応可能な人材を育てるために SRE本を参考に教育カリキュラムを構築・実践してきた内容の紹介.

内容はJenkinsをターゲットにはしているけど,SRE本および教育方針がメインテーマに感じた. CI/CDの歴史やJenkinsの基礎知識は問題ないにしても, 既存ジョブの知識やトラブルシューティングtipsはどう教えるのか難しいのではと感じた. ジョブやパイプラインにどのようなものがあるのかという設計指針や プロジェクトやJenkinsバージョン等によって異なるトラブルシューティングtipsは そう簡単には教育資料としてまとめられる気がしない.

AWSとJenkinsを活用して1年間で約500回商用デプロイした話とKubernetes活用 (NTTデータAgileプロフェッショナルセンタ主任 高見将則 さん)

speakerdeck.com

実際のWebサービス開発においてJenkinsを導入した事例における, 導入の話や,パイプラインの設計およびトラブル対応の紹介.

発表時間の割に重要な情報が多い印象を受けた(当時は発表自体はすぐ終わり質疑に多くの時間が割かれた). パイプラインとしてブランチビルド,リリースビルド,デプロイの3種類を定義していることは, 確かに自分も似たような構成を取ってはいるが,きちんと名前付けして整理されていない. パイプラインの設計は暗黙知化されているので,設計指針とすれば複数開発プロジェクトに展開できる知見だと感じた.

開発が始まってからの導入が難しいので事前または初期に導入すべし,というのはその通りだけど それに必要となる教育(特に他社ベンダへの展開)をどうしたのかが気になった. 最近ではJenkinsだけでなくCIは当然の知識としてあるのかもしれないけど 自社の場合はまだCIとは何か,CIの必要性といったことを上司含めて説得する必要があるので 特に課題が具体化されていない初期でどのように説得するのかは悩ましいところ. (課題が具現化された状況では導入は遅く,具現化される前は軽視されて取り合ってくれない).

課題なんかもよくあるテーマだと感じた. 特にスローテストまわりはプロジェクトや開発フェーズによって いろいろな要因があるので何度も悩まされる課題という印象. こういった課題への対処こそきちんと知見として共有していく必要がある.

LT: Jenkinsを簡単運用ツールとして活用して非エンジニアに喜ばれた話 (morihayaさん)

www.slideshare.net

定型的なSQLクエリの管理にJenkinsを利用したという話. 非エンジニアとは言うが運用チームの話なのである程度技術背景もあるし 導入もそこまで大変ではないかな,という印象.

Jenkinsを利用することでレビューや認証認可を強制する,というのは納得感のある話. むしろ非エンジニアだと少しリッチでGUIのあるcron程度で十分なので Jenkinsだと機能過多になる,という話の方が多いのでそういった話かと勘違いしていた.

話を聞く限りではまさにJenkinsがバッチリとはまるケースの印象. 問題はこういった仕組みを導入するとJenkinsインフラの管理もこちらの仕事にされるところだろうか. 責任分担をどうしたのかが気になる.

LT: Jenkins World 2018の参加報告 (Masayoshi Sakamotoさん)

Jenkins World 2018のホットトピックであった * as Code, DockerのCI/CD, DevSecOpsの紹介と 特に気になったセッションの紹介.

いずれのテーマもまさに今注目の内容なので Jenkins Worldのような場で話を聞けるのは羨しく思う. 特にDevSecOptまわりは,考え方としては知っていても実感できていないので 非常に気になるところ. コンテナCI/CDも自分の環境でやっと形になったところなので, 段階的にでも導入するという話を聞いて自分が取り組んでいることに 確信が持てたのでよかった.

LT: Jenkinsで運用業務の改善をしてみて気づいたこと (Yoshitaka Shirakoさん)

www.slideshare.net

Jenkinsの自動化により効率化やコード化による品質向上を実現したが 自動化が目的化してしまい本当に必要な業務効率化には至らなかったという話.

自動化による業務改善自体は上手くいっているが 上司をまきこめなかったので最適化はできなかったという話だろうか. 似たような話に自動化を進めた結果,自動化した中身がブラックボックス化 してしまうという話だと思ったので,ここまでできているのなら上出来では?とも考えてしまう.

これは改善の目的をどこに置くかという話で, いわゆるアジャイルにおけるふりかえりを踏まえた 課題の明確化や継続的な改善に取り組まないと 中途半端な状況で改善が止まってしまう.

自分もかなり悩んだ状況なので参考に頑張りたい.

LT: JenkinsとCodeBuildとCloudBuildと私 (Shoji Shirotori さん)

www.slideshare.net

Jenkinsの管理や権限設計の改善のために CodeBuildやCloud Buildの利用比較を行った話.

気にはなっていたけど検討できていない内容だったので参考になる話ではある. ただし,Cloud Buildはともかく, CodeBuildはCodePipelineなど複数サービスを組合せてパイプラインを構築することが 前提となっている様子なのでもう少し検討したいところ.

Jenkinsのすべてを置き換えるのか,一部を置き換えるのか, パイプラインの方針などによって異なるので 必要な機能に応じて自分でもいろいろ比較検討してみたいところ. 最近だとAzure DevOpsも比較対象に加えたい.