背景: Kaniko について
Kaniko についてご存知の方は読み飛ばしてください。
CD/CI, Pipeline 便利ですよね。
コンテナベースの開発・k8s などが整備されている場合は、おおよそ以下のような流れの Job の Pipeline を作成されているところが多いかと思います。
- アプリケーションコードのビルド
- コンテナ化・harbor などのレジストリへのアップロード
- k8s などどこかへデプロイ
- etc...
各 Job はコンテナ内で実行されるので、この 2. のコンテナ化の Job において docker コマンドを用いた実装をしてしまうと Container in Container 問題が発生してしまいます。
これを解決するためによく用いられるのが Kaniko です。
Job の実行元として公式提供のイメージを指定して、イメージビルドについての変数を渡して executor を script として実行するだけで image build/push を行ってくれるのです。
前提: Pipeline と Harbor の接続
レジストリとして Harbor を利用します。
Pipeline と Harbor の繋ぎこみに関しては Gitlab のページなどで詳しく説明されています。
Kaniko を用いて Harbor に push する際、Job は auths という変数を含む JSON を /kaniko/.docker/config.json に配置する必要があります。
auths の中身には、Harbor の push を行うユーザー名とそのユーザーのパスワードを : で連結して base64 変換した文字列を auths の中に auth:{} として指定します。
- echo "{\"auths\":{\"${HARBOR_HOST}\":{\"auth\":\"$(echo -n ${HARBOR_USERNAME}:${HARBOR_PASSWORD} | base64)\"}}}" > /kaniko/.docker/config.json
今回の解決したい悩み
ユーザーとして robot アカウントを利用するときなどには、ユーザー名に $ などのエスケープの必要な文字が含まれている場合があります。
ユーザー名・パスワードは
Pipeline 環境変数等での ${HARBOR_USERNAME}, ${HARBOR_PASSWORD} の入力 //(1)
-> (Job 内 Script による Base64 変換)
-> /kaniko/.docker/config.json //(2)
-> (Kaniko による Harbor へのアクセス)
-> Harbor
-> Harbor 側での認証プロセス
といった具合に渡されていくわけですが
この各受け渡しのうち、どの部分にエスケープ処理が必要になるの?
というのが今回の疑問です。要は次の 2 点です。
- 大元の USERNAME, PASSWORD はエスケープ処理する? (1)
- Base64変換で得られた文字列はエスケープ処理する? (2)
結論
-
大元の USERNAME, PASSWORD(1)
エスケープ処理が必要 -
Base64変換で得られた文字列 (2)
エスケープ処理は不要
よく考えると、前述の公式 Script では Base64 変換して得られる値を "" で囲っていますね、要はあの Script を手元で実行することを考えると自然と (1) はエスケープ、(2) はエスケープしないという結論が得られると思います。
まとめ
公式のドキュメント・コマンドはちゃんと読んだ方が良い(1敗)
脳内では「エスケープ処理された文字列をもう一度エスケープ処理して渡すなんてことがあるか?」と思いつつなんだかんだ頭が混乱してしまいました。
Pipeline 系は実装の確認・検証に手間がかかるので、こういった細かいところでのつまずきは減らしていきたい..