2016年9月 のアーカイブ
実行されたJenkinsFileはReplayから確認できる
muraveです。
なうなやんぐなのでPipelineでJenkinsFileを使ってビルドについてもソースコード管理したいわけですが、他チームのJenkinsFileを参考にしたいときにJenkins上から内容が確認できないと、お願いしてJenkinsfileを送ってもらうという悲しいことになったり(実際に発生)。
Jenkins上から確認できるように出来ないものかとプラグインを探したり、ファイルは残っていたのでそれを参照できるようにできないかいろいろ試したりしていました。
しかし、そんな事をしなくても内容をみることができる方法がみつかったのでした。
まぁ、答えはタイトルに書いちゃってますが、こんなん予想できませんわー。
一部マスクしますが、キャプチャを貼っておきますね。
スクリプトを参照する場合は間違ってRunしないように注意ですね。
JenkinsのwithCredentialsでユーザー名とパスワードを扱えるのかを確認したいだけだった
muraveです。
なうなやんぐはPipelineでJenkinsFileを使ってビルドについてもソースコード管理ですよねー、ということで試してみているんですが、ユーザー名やパスワードをJenkinsFile内に書くわけにはいかないわけで。
方法を探してみたところ withCredentials でどうにか出来そうでした。
Fetch a userid and password from a Credential object in a Pipeline job.
ここを見ながらザックリと Pipeline script なジョブを作成して動作を確認しようとしたところ、少々ハマリました。
テスト用にユーザー名test、パスワードpassword、credentialsIdがtestの認証情報を作成しています。
node {
stage 'withCredentials Test'
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'test',
usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
sh 'echo uname=$USERNAME pwd=$PASSWORD'
}
}
これを実行したログを確認すると
[credential_****] Running shell script
+ echo uname=**** pwd=****
みたいな表示。うーん。何か権限的に引っかかってるのか、表示が潰されているだけなのかがわかりません。
結論を先に言うとユーザー名、パスワードについて表示を****で潰すようになっているようです。
あとで気づいたのですが[credential_****]のところもジョブ名がcredential_testなのでユーザー名であるtestが潰されているのでした。
ではユーザー名、パスワードが本当に取れているのかをどのように確認したのか?ですが次のような Pipeline script を作成しました。
node {
stage 'withCredentials Test'
def uname //withCredentials外にUSERNAMEを持ち出す為に使用
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'test',
usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
sh 'echo uname=$USERNAME pwd=$PASSWORD > idpw.txt'
sh 'pwd' //ワークスペースの位置確認をしたかったのだが、しかし
println(env.USERNAME) //groovyでの扱い
uname = env.USERNAME //withCredentials外にUSERNAMEを持ち出す
}
stage 'withCredentialsの外で出力'
println(uname)
stage 'ワークスペースの位置確認'
sh 'pwd'
}
実際に行ったのはidpw.txtファイルにリダイレクトして内容を確認でしたが、その際の謎動作の説明のための処理や、その後にログ上で確認できないかな?と思ってやってみたことも混ぜてあります。
ログから抜粋してまとめると以下のようになります。
Entering stage withCredentials Test
Proceeding
[credential_****] Running shell script
+ echo uname=**** pwd=****
[credential_****] Running shell script
+ pwd
/var/jenkins_home/workspace/credential_****
****
Entering stage withCredentialsの外で出力
Proceeding
test
Entering stage ワークスペースの位置確認
Proceeding
[credential_test] Running shell script
+ pwd
/var/jenkins_home/workspace/credential_test
idpw.txtの位置が知りたくてpwdしているのですがwithCredentialsのブロック内で実行すると
[credential_****] Running shell script
+ pwd
/var/jenkins_home/workspace/credential_****
と、ユーザー名のtestと同じだったために一部マスキングされてしまっています。まぁ、大体の位置は予想がついたのでidpw.txtを探して内容確認はできたわけですが(ちゃんとユーザー名、パスワードが出力されていました)。
最後にブロック外でpwdしてみるとちゃんと
Entering stage ワークスペースの位置確認
Proceeding
[credential_test] Running shell script
+ pwd
/var/jenkins_home/workspace/credential_test
と出力されているのがわかります。
ログだけでの動作確認ですがブロック外ならマスキングされないのがわかったのでuname変数を定義して外に持ちだしてやればいいかな〜と
Entering stage withCredentialsの外で出力
Proceeding
test
やはりマスキングされずに出力されました。動作の確認はできましたが、これは通常はやってはいけないパターンですね。
以上です。
Dockerのデータボリュームをバックアップ・リストア
現状試しているのはローカルストレージドライバでのデータボリュームの場合ですが、コンテナでバインドして扱うのが常道な感じです。
データ・ボリュームのバックアップ・修復・移行
http://docs.docker.jp/engine/userguide/dockervolumes.html#id9
に書いてあるやり方ですね。
jenkins-masterというコンテナの /var/jenkins_home をバックアップ・リストアする例をあげます。
バックアップ
$ docker run --rm -u root --volumes-from jenkins-master -v $(pwd):/backup alpine tar czvf /backup/alp.tar.gz -C /var jenkins_home
リストア
$ docker run --rm -u root --volumes-from jenkins-master -v $(pwd):/backup alpine sh -c "rm -rf /var/jenkins_home/* && cd /var && tar xzvf /backup/alp.tar.gz"
念のためユーザーにrootを指定し、Alpine Linuxで実行しています。バックアップ時、相対ディレクトリ指定のためtarの-Cオプションを使用しています。展開時はゴミファイルが残るのが嫌だったのでリストア対象ディレクトリ内を全て削除してから展開していますが、削除はしないほうが安全かもしれません。
以上です。
データボリュームコンテナについての蛇足
データ永続化のために別途データボリュームコンテナを作成している場合でもローカルストレージなデータボリュームを使用していれば同じこと、docker save や docker export でバックアップというわけにはいかないようです。残念。
DockerのJenkinsコンテナでアクセスログについて悩んでいた
muraveです。
今年の4月にリリースされたJenkins 2系をDocker公式イメージ
で試していたのですが、Webフックからキックしてのビルドを試していて大変ハマリました。Webフックからのアクセス状況とかどうなってんだ?などなどtcpdumpとか使って調べてたんですけど、アクセスログもあったほうがいいよね、と思ったのでした。
公式イメージのJenkinsさんってそのまま立ち上げたらアクセスログ出してくれないんですよね。
調べまして、JENKINS_OPTSに
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=ログファイルのパス
てな感じで設定すれば良いことはわかりました。分かりましたが、コンテナ内やボリュームにログファイルを出すのは違う気がします。docker logs で見ることができるログはどういう扱いなんでしょう?
デフォルト設定のロギング・ドライバのログ(JSON形式)はホストの
/var/lib/docker/containers/(コンテナID)/(コンテナID)-json.log
にあって、これが docker logs の表示元になっています。
問題はどうやったらここに出力されるのか?ですが、標準出力、標準エラー出力へ出力すれば良いそうです。例えば、Nginx公式イメージのDockerfileでは
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
と、/dev/stdout と /dev/stderr へのシンボリックリンクを作成することで対応しているようです。
Jenkinsさんの場合は先ほどのJENKINS_OPTSでログファイルのパス指定が可能でしたので
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/dev/stdout
と設定すると標準出力に出力されるようになり、コンテナのログにJenkinsさんへのアクセスログが記録されるようになりました。
これでDockerのロギング・ドライバでアクセスログも統一的にあつかえますね。
例えばFluentdロギング・ドライバに切り替えてログ集約するようにしたりする場合にも安心です。
