JFrog Japan Blog

DevOpsを加速する、JFrog日本法人メンバーによるブログです。

JFrog ArtifactoryやXrayといった自社ツールはもちろん、CI/CDやコンテナ技術(DockerやKubernetes)などDevOpsの一般的な内容も扱います。その他、日本でのDevOps事例紹介やお楽しみコンテンツも掲載予定です。 JFrogならではの面白くて役に立つブログを目指しますので、お楽しみに!

JFrog 製品と Apache Log4j 2 の脆弱性に関して

(このブログは GENERAL: JFrog Services Are Not Affected by Vulnerability CVE-2021-44228 の日本語訳および補足です)

On 10 December 2021, a RCE (remote code execution) exploit was exposed on several versions of the Apache Log4j 2 utility. Affected code exists in log4j core libraries: log4j-core-*.jar, versions 2.0 to 2.14.1.

2021年12月10日 Apache Log4j 2 ユーティリティのいくつかのバージョンで、RCE(リモートコード実行)の脆弱性が公開されました。 影響を受けるコードは log4j コアライブラリ: log4j-core-*.jar のバージョン2.0~2.14.1 です。

Following internal research and validation by the JFrog Security and R&D teams, we can confirm that JFrog services are not affected by this vulnerability (CVE-2021-44228). First, we have validated that JFrog services are not configured to implement the log4j-core package. Additionally, we can confirm that the JDK version used in JFrog services (e.g. Artifactory) contains default protection against remote class loading via JNDI objects. Therefore, no action is required by JFrog customers regarding this issue for JFrog solutions.

JFrog セキュリティチームと R&D チームによる内部調査と検証の結果、JFrog のサービスがこの脆弱性(CVE-2021-44228)の影響を受けていないことが確認できました。まず、JFrog のサービスが log4j-core パッケージを利用するように設定されていないことを確認しました。さらに JFrog サービス(Artifactory など)で使用されている JDK のバージョンには JNDI オブジェクトを介したリモートでのクラス読み込みに対するデフォルトの保護機能が含まれていることを確認しています。したがって、この問題に関して JFrog のお客様が特別に何か対処する必要はありません。

JFrog Security and Xray product teams have updated the Xray database with CVE information regarding this vulnerability, and this information will be available for Xray customers to assist in detection and remediation across customer portfolios.

JFrog Security と JFrog Xray製品チームは、この脆弱性に関する CVE 情報をすでに Xray データベースに更新済みです。つまり JFrog Xray をご利用のお客様は、すぐにアプリケーション全体でこの脆弱性の検出および修正の支援を受けることが可能です。

※ JFrog Xray に関して詳細を知りたい方は下記ウェビナー及びプレゼン資料を参照ください。

www.youtube.com

speakerdeck.com

JFrog has examined and validated that none of the following products reference the vulnerable libraries:

Artifactory 6.x and 7.x, and the accompanying Access service

Distribution

Mission Control

Insights

JFrog は以下の製品が脆弱性のあるライブラリを参照していないことを調査・確認しました。

  • JFrog Artifactory 6.x および 7.x、ならびに付随する Access サービス
  • JFrog Distribution
  • JFrog Mission Control
  • JFrog Insights

(訳注)JFrog Xray がリストにないのは JFrog Xray は Go で実装されているためです!

【Google Cloud Build & JFrog Artifactory + Xray + CLI】Dockerイメージを自動でビルド・保存・セキュリティスキャンする

こんにちは、デベロッパーアドボケイトのよこなです。もう9月ですね。な〜つのお〜わ〜り〜

ソースコードだけじゃなくてアーティファクトを専用リポジトリで保存しましょう!
という話をよくするのですが、最近はもはやおまじないであっという間に「ソースコード→デプロイ」の過程を終えられる便利ツールが増えていますよね。「アーティファクトを取っておくと言っても、コマンド叩いたらサーバーまで行っちゃうんだけど…」と思われる方もいらっしゃるかもしれません。

この記事ではGCPとJFrog Platformを組み合わせた例を使って、アーティファクトの保管・セキュリティスキャンを行います。

☝やりたいこと

f:id:ihcomega:20210904124728p:plain

  1. Dockerで動くアプリケーションをビルドする
  2. アーティファクトをJFrog Artifactoryに保存する
  3. Artifactory上のアーティファクトにセキュリティスキャンをかけ、問題ない場合のみビルドを正常終了させる

この流れをCloud Build (CI/CDツール) 上で実現します。デプロイするところまで書こうかと思ったのですが、上記だけで超大作になったため別記事にします。
記事が長いので身構えるかもしれませんが、動かしたいアプリもない、クラウド環境もない、JFrogサーバーもないというゼロからの状態で始めて丁寧に説明しているからなのでご安心を。実際は既存で使っているものをカスタマイズすることになると思うのでもうちょっと気楽にお試し頂けるかと思います。
例えば既にCloud Buildでコンテナイメージのデプロイをしている場合はちょっとステップを追加するだけで脆弱性のスキャンができるようになります!必要に応じ読み飛ばしながらご活用ください🐸

☝Frogに関する前提知識

  • JFrog Artifactory: アーティファクト(今回はDockerイメージ)を保存するためのリポジトリ。
  • JFrog Xray: いわゆるSCAツール。Artifactoryと連携し、アーティファクトが依存するOSSに脆弱性やライセンス違反がないかをスキャンする。

☝コンテナ化されたアプリケーションを用意する

今回デプロイするアプリケーションはこちらです。JavaとSpring bootというフレームワークで作りました。アプリの作り方は詳細割愛しますが、Springの公式ドキュメントを参考にしました。
github.com

実行・アクセスすると Hello Docker World! と返せるだけのシンプル・サンプルアプリケーションです。
f:id:ihcomega:20210903165717p:plain

☝JFrog Artifactory上にDockerイメージ用のリポジトリを作成する

JFrog SaaS版の利用を開始する

jfrog.com

ここから登録してJFrog Platformが使える状態にしてください。
Name Your Environment*欄はお好きな値を指定していただけばOKです(既存の別のサーバーと重複はNG)。それがURLになり、後々Cloud Build側の設定にも使います。

リポジトリを作成する

アカウント作成して初回ログイン(これ以降、admin権限があるユーザーを使ってください)をしたら、そのままリポジトリも用意しちゃいましょう。

  • リモートリポジトリ
  • ローカルリポジトリ
  • バーチャルリポジトリ

の3つを作成します。以前は別々に作成する必要があったのですが、最近まとめて3つ作れるようになったので結構楽ちんです。

f:id:ihcomega:20210903130807p:plain
最初のログイン後表示される画面で「Docker」を選択する

f:id:ihcomega:20210903131037p:plainf:id:ihcomega:20210903131104p:plain
プロジェクト名を入れてリポジトリを作成する

今回は雑(サンプルとしては分かりやすいとも言う)ですが、springという名前を指定しました。spring-docker-local, spring-docker-remote, spring-dockerという3つのリポジトリが爆誕します。

リポジトリをXrayでスキャンできるよう設定する

スキャンには時間がかかるので、予めインデックスを追加しておくことでいざスキャンの命令が来たときに素早く結果を返せるようにしておきます。

f:id:ihcomega:20210903154145p:plain

リポジトリの設定画面からローカル・リモートリポジトリに対してEnable Indexing in Xrayを有効にする設定を入れてあげればOKです。ローカルとリモートを束ねる存在であるバーチャルリポジトリには設定不要です(そもそも設定項目がありません)。

f:id:ihcomega:20210903154554p:plainf:id:ihcomega:20210903154557p:plain
ローカルもリモートも似た画面で設定する

☝Cloud Buildでビルドできるようにする

Google Cloud上にプロジェクトを作成(手順)済みの状態で始めましょう。今回の例では「My First Project」を作りました。

ビルドを定義する設定ファイルcloudbuild.yamlを作成する

さて、ビルドの準備を進めていきますが、基本的には公式ドキュメントが詳しいし分かりやすいです。
cloud.google.com

サンプルアプリケーションのプロジェクトルートにcloudbuild.yaml (Cloud Build上で自動で実行したいことを書き連ねていく設定ファイル)を追加します。完成形はGitHub上のファイルをご確認ください。
では、まずはDockerイメージをビルドしてタグをうつところまで。

steps:
  - name: 'gcr.io/cloud-builders/docker'
    entrypoint: 'bash'
    args:
    - '-c'
    - |-
      docker build --build-arg JAR_FILE==build/libs/*.jar -t gcr.io/$PROJECT_ID/spring-boot-docker .
      docker tag gcr.io/$PROJECT_ID/spring-boot-docker:latest ${_JFROG_PLATFORM_URL}/spring-docker/spring-boot-docker:latest

公式ドキュメントと異なるのはentrypointを指定してbash -cでコマンドをまるごと渡せるようにしているところです。これで、ひとつのステップで2行コマンドを実行できます(参考: bash スクリプトの実行)。
コマンド内の$PROJECT_IDはプロジェクトIDに置換される変数で、Cloud Buildが標準で提供しているものです。一方、${_JFROG_PLATFORM_URL}は独自で設定する環境変数です。値の設定方法は後ほど見せますが、ここではArtifactoryのURLをCI実行時に埋め込むようにしています。

ここまで出来たらgcloudコマンドが使えるようCloud SDKをインストール(手順)して、プロジェクトルートで次のコマンドを実行すればCloud Buildを動かすことができます。

gcloud builds submit

結果はそのままターミナルで確認できますが、Cloud Buildのコンソールにて「履歴」を見ることも可能です。

f:id:ihcomega:20210903054042p:plain
コンソール上で確認できるビルド履歴

ビルドのトリガーを設定し、自動でビルドが実行されるようにする

先に設定ファイルを書ききってもいいですが、いったん何らかのイベントをきっかけにCloud Build上で自動ビルドが走るように設定しちゃいましょう。ローカルでコマンドを打たなくて良いので動作確認も楽になります。

今回はspring-boot-dockerリポジトリのmainブランチに変更が入ったらビルドするという設定にします。Cloud Buildのコンソールで「トリガー」ページを開きます。

f:id:ihcomega:20210903054345p:plain

先に最終形をお見せするとこんな感じです。

f:id:ihcomega:20210903123638p:plain

GitHubと初めて連携する場合、リポジトリを指定するところでGitHubとの行き来が発生します。認証を行い、使うリポジトリにGoogle Cloud Buildのツールを入れましょう。

f:id:ihcomega:20210903130158p:plain

また、変数をセットするのもポイントですね。今回は次の2つを設定しておいてください(参考: 変換値の置換)。

変数名
_JFROG_PLATFORM_URL JFrog Platform登録時に指定したサーバー名を含むURL(xxx.jfrog.io)
_JFROG_PLATFORM_USER JFrog Platformのログインユーザー(メアド)

f:id:ihcomega:20210903134041p:plain

☝Cloud BuildからArtifactoryへDockerイメージを保存する

Cloud Build上でさっきビルドしたイメージをArtifactoryへ保存するための設定をしていきます。

JFrog PlatformのAPI KEYをCloud Key Management Serviceで暗号化する

まずはJFrog Platformで認証するためのAPI KEYを発行し、クリップボードにコピーしてローカルで使えるようにします。

f:id:ihcomega:20210903133112p:plainf:id:ihcomega:20210903133122p:plain
右上のメニューからプロフィールページへ行くと発行できる

続いて、今取得したAPI KEYを暗号化します。そうすることで、cloudbuild.ymlに(暗号化した)値を直接書いて安全に使うことができるようになります。

公式ドキュメントを参考にしつつ、暗号化するための鍵を作る2ステップを実施します。

gcloud kms keyrings create [KEYRING-NAME] --location=global
gcloud kms keys create [KEY-NAME] --location=global --keyring=[KEYRING-NAME] --purpose=encryption

[KEYRING-NAME](Keyring = 簡単に言うと鍵のグループ)と[KEY-NAME](Key = 鍵)は自分で決めます。サンプルではそれぞれspring-docker-keyring, key-exampleとしました。これらの値はこの後cloudbuild.yamlでも使います。

これで鍵が作成されたので、それを使って暗号化します。さっきクリップボードにコピーしたAPI_KEYをローカルの環境変数$RT_API_KEYに設定した上で、次のコマンドを実行します。3つ目のコマンドを実行すると返ってくる値こそが暗号化したAPI KEYなので、控えておいてください(まぁ紛失してもまたコマンドを実行すればOKです)。

echo $RT_API_KEY | gcloud kms encrypt --plaintext-file=- --ciphertext-file=- --location=global --keyring=[KEYRING-NAME] --key=[KEY-NAME] | base64

暗号化した値を復号できるよう設定する

暗号化した鍵はビルド実行時に復号したいので、Cloud Buildに復号の許可を与えます。Cloud Buildのコンソールより「設定」画面で変更してください。
f:id:ihcomega:20210903140608p:plain

おそらくこのときに「APIを有効にしてね」という別画面が立ち上がると思うので、画面に従って設定しましょう。

f:id:ihcomega:20210903145443p:plainf:id:ihcomega:20210903145451p:plain
KMS APIを有効にする

設定ファイルで暗号化したAPI KEYを使えるよう追記する

ようやく準備が整ったので、cloudbuild.yamlに追記します。まずはファイルの末尾に暗号化したAPI KEYを追記しましょう。[]で覆われた値は上の手順にある鍵発行・暗号化時に得たものに差し替えてください。

secrets:
  - kmsKeyName: projects/dark-hall-324609/locations/global/keyRings/[KEYRING-NAME]/cryptoKeys/[KEY-NAME]
    secretEnv:
      APIKEY: '[暗号化されたAPI KEY]'

つまり私のサンプルバージョンだとこんな感じになります。

secrets:
  - kmsKeyName: projects/dark-hall-324609/locations/global/keyRings/spring-docker-keyring/cryptoKeys/key-example
    secretEnv:
      APIKEY: 'CiQAy/L6lVzsfbJqvTbOInV71GDrfUnHFPMbclD7a45xkGgsXlkScwAbTXpQ7gUCXwLhVYLC9BaGcGx7KmaSjuIaErsNQ7CacG/Jetll1xpDc/ITCAr+WrCZqYSktGWyvmE4zSBct9cMWPdVgPnoc1mmOst9iiD1S8G9QeCu8xY9XFYJq/T5K+Cu5lchGtAfWRNB8c1QA58/Qk4='

JFrog CLIを使ってDockerイメージをArtifactoryへ保存する

続いて、ArtifactoryへにDockerイメージを保存するためのステップを追加します。やっとこの記事の肝にたどり着きました…。

ググるとGoogle Cloud Blog - News, Features and Announcementsっていう公式の記事もあるんですが、

  • 最新のJFrog CLIのバージョンがv2になっていること
  • かつてCLIのイメージを取得する先であったbintrayはサービス終了していること
    をふまえると、次のような記述が良いでしょう。
  - name: 'releases-docker.jfrog.io/jfrog/jfrog-cli-v2'
    entrypoint: 'bash'
    args:
    - '-c'
    - |-
      apk add docker-cli
      jfrog c add my-jfrog-server --url=https://${_JFROG_PLATFORM_URL}/ --user=${_JFROG_PLATFORM_USER} --password=$$APIKEY
      jfrog rt dp ${_JFROG_PLATFORM_URL}/spring-docker/spring-boot-docker:latest spring-docker --build-name=spring-boot-docker-build --build-number=${BUILD_ID} --server-id=my-jfrog-server
      jfrog rt bce spring-boot-docker-build ${BUILD_ID}
      jfrog rt bp spring-boot-docker-build ${BUILD_ID}

jfrog-cli-v2イメージを使用することでCLIを有効にし、jfrogコマンドが使えるようにします。

CLIの使い方はやりたいことに応じてご確認いただくのが1番ですが、今回使っているコマンドについては説明します。
www.jfrog.com

apk add docker-cli

(当然これはJFrog CLIじゃないですが、準備として必要なので補足します)

  • Cloud Build上ではCLIもコンテナで動いているわけですが、そのコンテナからDockerイメージをプッシュするためにDockerクライアントが必要です。
  • Alpine(CLIのDockerコンテナで動いている軽量のLinux)にapkというパッケージマネージャーでDockerクライアントをインストールしておきます。

jfrog c add

  • cconfigのことです。この記事の上の方で作ったJFrogのサーバーを指定し、認証しておきます。
  • CLIにおいてJFrogのサーバーを一意に識別するため、my-jfrog-serverという名前をここでつけています。

jfrog rt dp

  • rtはArtifactoryを操作するコマンド、dpdocker-pushの略です。直前に設定したmy-jfrog-serverという名前でサーバーを指定し、そこに対してdocker pushしています。
  • この作業でspring-boot-docker-buildという名の「ビルド」という塊を作っているのですが、この後セキュリティスキャンをする際もこのビルドに対して操作を行います。
  • spring-dockerは前半で作成したバーチャルリポジトリの名前で、プッシュ先として指定しています。バーチャルリポジトリに対してプッシュするとアーティファクトはローカルリポジトリに保存されます*1
  • ビルドを識別するためにIDを振る必要があるので、今回はCloud Buildが標準で提供してくれている変数$BUILD_IDを使いました。シーケンシャルな番号を振るとかでも良いです。

jfrog rt bce

  • bcebuild-collect-env の略で、次のステップ (jfrog rt bp) を実行する前の準備としてbuild info (アーティファクトの詳細や依存関係、サーバーの環境変数などビルドの付加情報) を収集します。

jfrog rt bp

  • bpbuild-publishを意味しており、これを実行するとビルド実行時のbuild infoがArtifactory上に一緒に保存されます。

上記の設定を反映してGitHubにプッシュすると、トリガーの設定がうまく行っていればCloud Buildが実行されるはずです。

f:id:ihcomega:20210903143759p:plain
ArtifactoryのBuildsに行が増えていればイメージの保存成功

f:id:ihcomega:20210903144119p:plain
build info

ビルドをXrayでスキャンできるよう設定する

作成したビルドにもXrayのインデックスを追加しておきましょう。AdminメニューのXray SettingsでIndexed Resourcesを開き、Buildタブで操作します。

f:id:ihcomega:20210903161241p:plainf:id:ihcomega:20210903161238p:plain
Xray設定画面からスキャンしたいビルドを追加する

Manage Indexをクリック後に開く画面でspring-boot-docker-buildを追加すれば完了です。
f:id:ihcomega:20210903161632p:plain

☝JFrog Xrayでスキャンする

無事ビルドを作成できたのでXrayを使ってスキャンします。無料版では脆弱性のスキャンのみが使えるので、やっていきましょう。

その前にXray用語をごく簡単に紹介します。

  • ルール: チェックのレベルを定義します。「どの緊急度まで検知するか」「検知したら誰にどうやって通知するか」「検知した場合、そのアーティファクトの利用を許可するか」などを決めます。CVSSのスコアにも対応しています。
  • ポリシー: ルールを束ねてスキャンの方針を示すようなものです。後述のウォッチと紐付けて使います。
  • ウォッチ: ポリシーをどのビルド, リポジトリ*2に適用するかを定義します。

ということでルール, ポリシー, ウォッチを用意します。

f:id:ihcomega:20210903152038p:plain
adminメニューのXray設定画面を開く

ポリシー・ルールを追加する

f:id:ihcomega:20210903152127p:plain
ポリシーの作成画面からRuleを作成していく

ルールの作成画面はこのように細かい決まりを定められます。今回は例として

  • 緊急度がHigh以上なら検知する
  • 検知をしたらCIでのビルドを失敗させる(Fail Buildにチェックを入れるとそうなります)
    という設定を入れてみます。

f:id:ihcomega:20210903152424p:plainf:id:ihcomega:20210903152431p:plain
実現したいことをルールで表現する

ルールが追加できたらポリシーを保存しましょう。

f:id:ihcomega:20210903152924p:plain

ちなみに、なぜ1つのポリシーに複数のルールが設定できるのかについてはユースケースの例を挙げると分かりやすいかもしれません。
例えば「緊急度がHigh以上ならビルドを失敗させたいけど、Medium以下ならとりあえずメールで通知してほしい」場合は、今行った設定に加えて、Mediumならばメール通知するというルールを足してあげればOKです。

ウォッチを作成する

ポリシーを作った画面で隣のWatchesタブから操作できます。

f:id:ihcomega:20210903161717p:plain

ウォッチはポリシーとビルドを紐付けるものです。どのリポジトリのどのビルドに対しどのポリシーでXrayスキャンを行うかここで指定してください。

f:id:ihcomega:20210903161925p:plain

それぞれプラスボタンを押して、追加画面でポチポチ選択していきます。

f:id:ihcomega:20210903162108p:plainf:id:ihcomega:20210903162101p:plainf:id:ihcomega:20210903162104p:plain
リポジトリ、ビルド、ポリシーを追加する

f:id:ihcomega:20210903162706p:plain
無事追加できたら設定完了

JFrog CLIを使って保存したDockerイメージにセキュリティスキャンを行う

Xrayが準備万端になったので、cloudbuild.yamlにスキャンするためのコマンドをbpコマンドの後に追記しましょう。

jfrog rt bs spring-boot-docker-build ${BUILD_ID}

bsbinary-scanのことで、これがIDで特定したビルドに対しスキャンを行うための記述です。

結果

ついに全ての設定が完了しました!!!GitHubへ変更を反映させるとまたCloud Buildが走ります。

f:id:ihcomega:20210903164407p:plain

Xrayをオンにしたらビルドがコケるようになりました(1番上の行)。サンプルで使ったアプリケーションはベースイメージで大量の脆弱性が見つかってしまったんです…。

Cloud Buildの実行結果を見たらJSON形式で詳細が確認できます。
f:id:ihcomega:20210903164843p:plain

JFrog Platformにアクセスすればよりリッチに詳細を見ることもできます。

f:id:ihcomega:20210903165103p:plainf:id:ihcomega:20210903165059p:plain

☝終わりに

今回はGCP系のツールでやってみましたが、別のプラットフォーム、CI/CDツールでも同様のことが出来ます。オフィシャルにインテグレーションがサポートされている場合は公式ドキュメントが見つかるはずですが、英語しかなかったり最新バージョンを追従できていなかったりすることもあるので、JFrog関連で気になることや不明点があったらぜひご連絡ください〜!ブログのコメント欄でもOKです◎

文中に出てこなかった参考文献

*1:つまり、ここでローカルリポジトリを指定しても同じことが実現できるのですが、基本的にバーチャルリポジトリを使うようにすると便利です。詳細は別の機会に…

*2:「リリースバンドル」にも適用できるのですが、今日は登場していない概念なので割愛しました

デブサミ2021夏でDevSecOpsを始めるためのヒントをお伝えしました #devsumi

こんにちは、JFrogデベロッパーアドボケイトのよこなです。毎日地獄のように暑いですが皆さんバテていませんか…。

7月30日に行われたDevelopers Summit 2021 SummerにてJFrogはプラチナスポンサーをさせていただきました。

スポンサーセッションとしてDevSecOpsの話をしたので、簡単に振り返ってみます!といってもプレゼンの動画も公開される予定ですし、基本的に資料はそれだけ見てもなんとなく分かるように作ってありますし(本人はいつもそのつもり…)、ポイントと所感だけ。
speakerdeck.com

セッションでお伝えした内容は次のような感じです。

  • DevOps復習: コラボレーションにより顧客に価値を届け続けることを目指す
  • DevSecOpsの考え方ではDevとOpsに加えSec(セキュリティ)も協力する
    • セキュリティといっても色々あるが、DevSecOpsでは主にソフトウェアのセキュリティを扱う
    • 開発ライフサイクル(≒CI/CD)に自動で行うセキュリティチェックを組み込むのを目指すと分かりやすい
  • ソフトウェアのセキュリティとして取り組めることにも種類があるが、動的・静的なチェックともに(できる/必要なところから)行うと良い
  • 関心の向きがちな自分の書いたコードのみならず、依存するOSSの脆弱性にも対策を講じる必要がある
    • OSSの脆弱性を放置したことによるインシデント(個人情報の流出など)は実際に事例がある
    • CI/CDを活用し、自動で早めかつ定期的なチェックを行う
  • 効率良いセキュリティチェックのためにもバイナリ・リポジトリマネージャーでアーティファクトを管理する
    • アーティファクトは依存解決が済んでおり、リリースする対象となる
    • 自らビルドして作成したアーティファクト・ライブラリなど外から取得したアーティファクトの両方を管理しておく
    • セキュリティチェックが出来る以外にも管理のメリットは多数ある
  • ツール追加で自動のセキュリティチェックを当たり前にするとともに、効率化により出来た時間は思考や判断が必要な作業に割く
  • どこから始めるかは組織次第だが、まずは普段の悩みや隣の人との雑談など身近なところからやっていきたい
    • DevOpsやDevSecOpsなどが定着していない(させづらい)組織ではセキュリティというポイントを使って周りを巻き込むのも手である
    • 自分が楽に、幸せになるところからやればそれが組織にとってプラスになる

三行に出来たら良かったんですが…結構長くなりました。これが40分程度のセッションのまとめです。
純粋にセキュリティやっていき💪な方はぜひ参考にしていただけたら嬉しいですし、終盤で話したように「周りを巻き込むためのタネ」とするのもアリだと思います。結果として何かが良くなるのであれば!
実際DevSecOpsはとても関心が高く、JFrogにコンタクト取って下さるかたも、セキュリティきっかけで興味を持ったという方がたくさんいらっしゃいますよ!

さて、ソフトウェアエンジニアだった頃の私がこうしたセキュリティに対する取り組みを理解していたかというと…足りていなかったように思います。
どちらかというとマーケティングとか自分の担当システムの使い手といった方々とのコラボを重視していた私ですが、運用やセキュリティとのそれについては今振り返ればもっと出来たことがありました。単純に知識不足が原因な気がします。
言い訳ではないですが、担当以外のことって難しいし時間も足りないし、ちゃんと分かってコラボレーションのため積極的に動くのは簡単なことではないですよね。「もやもやを抱えて仕事しているけど自分にはどうしようもない」「やる気はあるが何をどう変えたらいいか分からない」という方に日々出会うのも本当によく分かります😢
だからこそデベロッパーアドボケイトとなった今、忙しい中クイックに大事なことを知るための話をしたり、スーパーマンじゃないエンジニア(←まさに私のような)にも出来ることをお伝えしたりと、過去の学びからなるべく有益なネタを見つけようと思う今日この頃です。
ぜひ皆さんの悩みや取り組みなども教えて下さいね。

最後に、デブサミの運営、参加者、スピーカーの皆様、お疲れさまでした。そして、ありがとうございました。


ちょうど次のウェビナーがDevSecOpsに関するツールについてなのでよければぜひ!スピーカーは同僚の三宅です◎
leap.jfrog.com

JFrog Artifactoryを使ってDocker Hubのdownload rate limit (ダウンロード回数の制限) を回避する

Docker Hubのdownload rate limitとは?

blog.jfrog.co.jp

以前この記事で詳しく紹介した(翻訳ですが…)とおり、みんな大好きDocker Hubを無料で使っていると次のような利用制限がかかります。

ダウンロードの制限
イメージのプルが制限され、匿名ユーザーは6時間あたり100回、無料アカウントだと6時間あたり200回までとなります。

今日はダウンロードの際、JFrog Artifactory(クラウド版)をプロキシとして間に挟むことでこの回数をなるべく消費せずにDockerイメージを取得する方法を見ていきます。他のメリット含め、詳細は先ほど紹介した記事をご覧ください!

https://cdn-ak.f.st-hatena.com/images/fotolife/i/ihcomega/20200915/20200915055858.png

Artifactoryの設定をする

Artifactoryのアカウントを作成する

jfrog.com

ここからクラウド版の無料アカウントを作成します。もちろん有料アカウントをお持ちの方はそちらをお使いいただけます。
サーバー名(Server Name)はお好きなものを指定してください。 <サーバー名>.jfrog.ioにアクセスすればJFrog Platformが使えるようになります。なお、既に他のサーバーで使われている名前は指定できません。

リモートリポジトリを作成する

リポジトリにはいくつか種類がありますが、Docker Hubのように別のリポジトリと接続するときはリモートリポジトリを使います。

f:id:ihcomega:20210705164604p:plain
「New Remote Repository」をクリックする

f:id:ihcomega:20210705165425p:plain
パッケージの種類として「Docker」を選択する

f:id:ihcomega:20210705165457p:plain
リポジトリ作成に必要な情報を入力する

  • リポジトリ名は何でも良いですが、<特徴(アプリ名、サービス名など)>-<パッケージの種類>-<リポジトリの種類>とするのが分かりやすくてオススメです。ここでは example-docker-remoteとしました
  • URLにはイメージの取得先としてDocker Hub https://registry-1.docker.io/ を指定します(デフォルトで入力されています)。
  • Docker Hubにログインした状態でイメージを取得するには、ログイン情報も入力します

Save & Finishをクリックするとリポジトリが作成され、次のような画面が表示されます。ログインなどの操作をコマンドラインで行うのに便利です。

f:id:ihcomega:20210705184940p:plain
作成したリポジトリを操作するためのヒント

Dockerイメージをpullする

例としてGradleのイメージを取得することとします。普通にDocker Hubからダウンロードする場合、 docker pull gradleとやる操作です。
Artifactoryを介してDocker Hubにアクセスできるよう、まずはログインします(Docker for Mac / Windowsを使っている場合はsudoが要りません)。 *1

sudo docker login <サーバー名>.jfrog.io

続いて、必要なイメージをArtifactory経由でpullします。 *2

docker pull <サーバー名>.jfrog.io/example-docker-remote/gradle:latest

これで初回のみDocker Hubへアクセスしますが、1度コンテナイメージを取得したらArtifactoryにキャッシュされるので、2回目以降はそこから取得するようになります。
取得済みのアーティファクトはArtifactoryのUI上でも確認することができます。

f:id:ihcomega:20210705173910p:plain

ちなみに

自分のダウンロード回数の確認

残り何回ダウンロードできるかは Download rate limit | Docker Documentation に記載されている方法で調べることが可能です。

f:id:ihcomega:20210705160759p:plain
ダウンロード回数の上限と残り (あと92/200)

リモートリポジトリへの操作のコマンド確認

上で紹介したリポジトリ作成直後に表示されるコマンドは、後からも確認できます。ArtifactsのビューでSet Me Upをクリックしてください。

f:id:ihcomega:20210705185059p:plain
右上の「Set Me Up」をクリックする

すると、さっきみたいな画面がまた表示されます。

f:id:ihcomega:20210705185115p:plain

バーチャルリポジトリの利用

今回はリモートリポジトリ経由での操作を紹介しましたが、リモートリポジトリと紐付いたバーチャルリポジトリを使うことも可能です。
バーチャルリポジトリって何?という記事はまた書く予定がありますのでそちらにて!


以上、この簡単なステップだけでDocker Hubの制限に悩まされることも減るはずです。無料でお気軽に始められるのでぜひお試しあれ😋

*1:Artifactoryのバージョンが古い場合、リポジトリにログインする必要があるかもしれません。その場合は docker login <サーバー名>-example-docker-remote.jfrog.io を試してみてください

*2:Artifactoryのバージョンによっては docker pull <サーバー名>-example-docker-remote.jfrog.io/gradle とする必要があります

ふだん実践しているインフォーマルコミュニケーションのポイント #devsumi

デベロッパーアドボケイトのよこなです。2月にデブサミ(Developers Summit)に登壇した際、「フォーマルコミュニケーションとインフォーマルコミュニケーションの使い分けについて意識していることはあるか」といったご質問をいただいたのですが、面白いテーマだなと思ったので今更ながらブログ記事にしてみます。

speakerdeck.com

資料はこちらです。JFrogとしてのスポンサーセッションでしたが製品ネタはナシで、周りの人を巻き込みながらDevOpsを少しずつ実践していこうというお話をしました。人の協力を得るからにはコミュニケーションは不可欠で、だからこそ関連する質問をいただいたということですね。
コミュニケーションがフォーマルかインフォーマルか、どういうコミュニケーションを取るかといったことはあまり意識したことがなかったので、自分の行動をふりかえって「インフォーマルコミュニケーションにおいて(無意識に)実践していること」を書いてみます。なんとなく習慣や癖として身についている思考を言葉にしてみるという記事になります。

ちなみにコミュニケーションとか人の心理とかマネジメントとか…技術ネタとかと比べるとふわっとして言語化が難しいものを語るときは何か参考文献を用意するようにしているのですが、今回は以下をヒントとして使いました。

(フォーマルコミュニケーション、インフォーマルコミュニケーションについての書籍が意外と見つからなかったのですが、私の探し方のせい?)


インフォーマルコミュニケーションは仕事の一部

はじめに私のインフォーマルコミュニケーションに対しての考え方をお伝えしておくと、仕事上の関係や状況を良くするために使うアイテムと捉えています。雑談や世間話とはいえプライベートでのそれとは異なりますし、だからこそこのような記事が書けるんだなぁと改めて考えると気付かされます。
まぁただ本当に間抜けな発言をしたり趣味でダジャレ(すごく面白い)を言ったりすることもあるので、私と一緒に働いたことのある方が見たら笑っちゃうかもしれません。そんなちゃんと考えてないでしょ、本能のまま喋ってるだけでしょ、と…。もちろんまったく頭を使っていなくてそういう時も多々あります。ハハハ。

意識しているポイント3選

ということで漸く本題ですが、仕事にプラスの影響を与えればいいなという「インフォーマルコミュニケーション」とか「オフとは違う雑談」をしている際、実践していることたち3選です。

1. 課題と目的を意識する

そもそも頭を使ってインフォーマルコミュニケーションを取りたいのはちょっとした困りごと、より良くしたい状況があるときです。

  • ◯◯さんが元気ないな
  • △△さんが最近何を思っているか謎だな
  • チームの雰囲気が良くないな
  • 連休明けで皆ポケポケしてるな

など。こうした小さな気付きをもとに、話の内容や相手、タイミング、手段などを考えてから人とコミュニケーションを取ることはよくあります。
例えば「◯◯さんが元気ないな」ということが気になったとしても、どういったアプローチを取るかは様々です。

【相手と内容】

  • ◯◯さんの話を聞いてなんで元気がないのか探ってみる
  • ◯◯さんに持ちネタを披露して元気づける
  • 今はそっとしておいてとにかく観察する
  • ムードメーカーの□□さんに話しかけて明るい雰囲気を作る

【タイミングや手段】

  • 一緒にランチしたときさりげなく
  • ミーティング前のスキマ時間に
  • 1on1で
  • チャットで

いずれも元気のない◯◯さんを思っての行動だとしても、コミュニケーションの取り方は異なります。
そして、臨機応変にこうした切り替えが出来ると良いもののなかなか難しいこともあるので、予め行動を決めておくのです。
「今日16時からミーティングあるし、◯◯さんはいつも早めに来てるから自分も早めに言って話しかけてみよう」とかですね。

手段の決め方は

  • 相手が好む方法か? (例えば、相手がいつもご飯の時おしゃべりならご飯に誘ってみたらいい)
  • 自分がうまくやれる方法か? (例えば、自分はテキストコミュニケーションが苦手だと思うなら避ければいい)
  • 実現可能か? (例えば、そもそも滅多に会えないのに「次会ったら言おう」というタイミングの計り方ではチャンスを逃すかもしれない)

といったことから自分なりにベストだと思う方法を選べば良い(慎重に考えすぎなくて良い)と思います。

2. よく聞き、相手の反応から情報を得る

当たり前じゃんと思うかもしれませんが、意外と出来ていないことも多いのがこれです。
何かを良くしたい人は、多かれ少なかれアツい思いを持っていて、それを発信することで周りを動機付けたりパワーを与えたりすることが得意だったりします。
ただ、そればかりになってしまうと相手から得られたはずの情報を見落としかねません。上に書いた、「ベストなコミュニケーションの取り方を自分なりに考える」ということも難しくなります。

ぐっと我慢して口を噤んでおき、かわりに目や耳をフル稼働させるのもコミュニケーションスキルのひとつだと言える気がします。

3. 振り返る

これは目的があってこそ出来る行動ですが、やろうと思っていたコミュニケーションを終えたら自分なりに上手く出来たかふりかえります。
もちろん全然思い通りにいかないことも多々ありますが、自分の行動も相手の反応も覚えておいて次どうするかをぼんやり考えます。

以上が意識している3つのポイントでした!要は、無計画に望まないということですね。しかしコミュニケーションって難しいよね・・・失敗もたくさんしながら磨いていきたいものです💪
この記事がネットの海を泳いで、いつか質問してくださった方にも届いたら嬉しいな!(そう思うならもっと早く書きましょう)