大神ミオさんのソロライブ(Our Sparkle)に応援広告とフラスタを贈った忘備録
轍を残す意味も兼ねて、推し活における応援広告とフラスタに関して主催者目線での忘備録を書いておこうと思います。今後、応援広告やフラスタやろうとしてる人の何かしらの糧になれば……
大神ミオさんのソロライブ Our Sparkle を応援するため、盛り上げるために応援広告とフラワースタンドを贈りました〜!!🎉🎉
🌲応援広告公開のお知らせ🌲
— ミオファの森の盛り上げ隊 (@miofa_ryu) 2025年9月5日
来週に迫った大神ミオさんのソロライブ #ミオスパークル の応援広告が、群馬県高崎駅で公開されました!🥳 #holocheer
群馬県の皆さん、大神ミオ、大神ミオをよろしくお願いします!
🗓️掲出期間 9月5日(金) 〜 9月11日(木)
📍場所 JR東日本 高崎駅… pic.twitter.com/uIIPZgmj1Y
一応メンバーが増える可能性を考慮して「ミオファの森の盛り上げ"隊"」という名義で活動していましたが……うん、ひとり部隊でしたね。(絵師さんたち入れていいなら3人部隊!)
かかった費用大公開
まず気になるであろう費用感について。気になるものは先出ししていくスタイル。イラストやデザインなどの個人間取引の費用は個人情報なので非公開ですが、他の部分についてはまとめておきました。参考までに。
応援広告
計 21万円ちょっと
ポストカード スタードリームFS クリスタル 209kg マットPP 角丸加工 箔押し加工 3万円ちょい
- フラワースタンド本体 66000円
- パネル
- 本印刷(B3 耐水紙 UVマット カットライン作成 3枚) 10000円
計 8万円いかないくらい
累計は……おっと?意外といったな(白目)
応援広告編
この辺りを一通りまとめておいたドキュメントがこちらであります。(ただしLLM用) 参考にしてみてください。ざっと読むとどんなタスクが出てくるのか何が必要になるのかわかると思います。(この記事では省略します)
ということで、以下はそんな波乱万丈にならなかった応援広告の自分語り。
ざっくり目的と手段の確認
今回ぼくの応援広告の目的は「(ファンからも)大神ミオさんの故郷に錦を!」でした。群馬に絶対送りたい、群馬県民の皆さま、大神ミオを、大神ミオをよろしくお願いします!!一方、明らかに時期的にプライベートの時間があまり取れないことがわかっており、手間はなるべく避けたいというお気持ちでいっぱいでした。
そこで次のルールで動くことにしました。
- 目標は「ミオさんの故郷に広告を!」「大神ミオを知っている人が『そろそろじゃん!』とそわそわしてほしい」に絞る。目立とうとするな。
- 任せらる部分はひとりに集約してコミュニケーションを最小限にする。ただしこれは「クオリティを疎かにできる」ための免罪符ではない。質が下がるなら、やれ。
- 予算は目一杯使う。一片たりとも残すな。少しオーバーしても良い。
メモを書く
書く。書く。ひらすらに書く。割と注力してました。今回はGoogle Docsにすべての情報をまとめて書きました。そして「TODOリスト」「問い合わせたこと」「選んだ理由」「ダメだったこと」「今後使うサイトのリンク」まで、ぜーーーんぶ書きました。仕事柄、Visibilityには気を遣いたい派だったのでイラスト/デザインの担当の人にもドキュメントを丸ごと共有しました。

意外と過去の自分が調べたことに助けられることがあり、良かった良かった。これがデザイン担当の人にどれくらい役立ったのかは不明……お、おしえてほしいな〜チラッ
タイムラインの線引き
広告は掲出日が決まるとほぼ自動的にデッドラインが定まります。今回は掲出の終わりを9月10日直後にしたかったので自然とこのようなタイムラインが浮かび上がりました。(実績)
広告の開始日から1ヶ月+αくらい前にはデザインが出来上がっていないといけないので、ある意味デッドラインがわかりやすいというか……
実際には広告代理店さんに相談して色々日程を調整してもらったりしました。本当に感謝。
参考 掲出スケジュール(週別) – 応援広告(センイル広告) Cheering AD| よくあるご質問
ちなみに、今回はキービジュアルの公開(6月28日)からデザインレビューまで1ヶ月しかないというタイトスケジュールでした。ありがとうPAISHENさん。しかも2枚。どう考えても狂ってる。(激褒め) 本当にありがとう🍍
予算決定
諸事情である程度まとまったお金が浮いていたことがあり、それをベースに使うことを決めました。足りないけど。クラファンで足りない分を集めることも考えましたが、プライベートの時間があまり取れないことがわかっていたので
- 集めたり告知する時間があまり取れない可能性
- 費用を細かく計算しないといけない手間
- 単純に面倒臭い
今回はひとりで全部出すことにしました。ひとりで全額出すのはアホのやることです。お財布がビビります。余程の理由がなければクラファンを利用しましょう。そして何より、ひとりは寂しいぞ。
許諾取り
応援先の団体によって異なるとは思いますが、多くの場合事前に許諾が必要なはず……?今回はカバー株式会社hololiveプロダクションへの広告となるため、ガイドラインに従って許可を取りました。ガイドラインがない事務所さん等であれば、一度問い合わせたほうが良いでしょうね。
申請後、運営さんが対応して1-2営業日ほどで許諾が取れました。許諾を取る際に「団体名」「どこの駅にどの期間」など聞かれますので、ある程度準備した上で許諾を取る必要があります。100%詳細を決めていないといけないわけではないので、まずやる気が起きたら予算と場所くらいのイメージはつけて問い合わせしましょう。これがないと何も始まらない。
今回は「群馬県と東京、会場付近に出したい」「9月10日を含めたい」程度の内容で申請を出しました。サポートの方とはかなりいろんな話をして、追加のあれこれがとてもスムーズに拡張できました。体験◎
場所選定
群馬県フォーカスが最初の最初。そこで、高崎駅、前橋駅、水沼駅、フラワーパークetc……当初は群馬オンリーで固める布陣だったのですが、調べていくと応援広告を受け付けてなかったり休業中だったりで思ったとおりに進められないと判断して群馬オンリーを断念。無念。いろんな人に相談しつつ、掲出場所は次に決めました。
3箇所にした理由は予算の都合上。東京山手圏内、たっかい。許されるなら「高崎駅ジャック!」とかやりたかった……
イラスト、デザイン
応援広告の機運を感じた瞬間、イラストは𝙋𝘼𝙄𝙎𝙃𝙀𝙉さんという方にお願いしようと心に決めていました。PAISHENさんのイラストのキャラクターから感じられる前後の動きや感情、息遣いを一目で感じられる独特な間と空気感が素敵です。道ゆく乗客さんたちが一瞬しかチラ見してくれない駅の広告で、悪目立ちせずに魅せるには良いだろうと思ってました。快諾してくださり、本当に感謝です。ちなみにここぞとばかりにデザインのお仕事もお願いするキラーパスをDMでぶん投げてました、改めてごめんなさい。引き受けてくださりありがとうございます。
個人的に、イラストの依頼するときにそのイラストの取り扱いと権利については明確にしておくと良いと思います。今回は「著作権等諸々は全部PAISHENさんに帰属したまま」「ぼくは使わせていただく立場」「事が終わったらいっぱい使って」と伝えておきました。
ステークホルダーの選定
ここまで来ると具体的な業者さんを探さないといけないためひたすらDeepResearchと睨めっこの日々でした。
応援広告で選ばないといけないのは3つ
- クラファンプラットフォーム
- 広告代理店
- 印刷業者
今回クラファンはしない選択でしたので、残りの2つを選定。ちなみにこれらをすべてまとめてやってくれる業者さんもいますが、後述の理由で今回は別々に選びました。
広告代理店
駅広告の場合はほぼ確実に代理店さんを通さないといけないです。今回はCheering ADさんを採用しました。有名どころであることと、広告を掲出したい駅すべてをサポートしていたこと、そしてサポートからの応答がそれなりに早いため調整を多少進められたのでここに決めました。いろんな相談をして助けてもらい、大変に感謝!
印刷業者
個人的に一番大変だったのが印刷業者さん選びでした。実はCheering ADさんには印刷までまとめてやってくれるプランがあるのですが、そこで利用される紙が半光沢タイプの少しテカテカするようなタイプだったんですね。PAISHENさんの画風上、バキッとした強いコントラストが映えるような紙よりも表面がマットで発色の良い用紙の方が良い可能性があるよな〜と思い、別枠でやることに。この頃はまだデザインどうなるかも定まっていない時期でしたしね。
馴染みの珈琲屋さん 目が合えば一日HAPPY#みおーん絵 pic.twitter.com/CfR4S5DGDh
— 🍹𝙋𝘼𝙄𝙎𝙃𝙀𝙉🍍 (@INUTOBI21) 2025年3月15日
印刷業者さんを探して、今回はプリオさんを採用しました。RGB入稿が可能でポスター用紙の種類が多く、そしてサポートの応答が非常に早いこと、相談にかなり乗ってくれたおかげで見通しが立ちやすかったです。最終的な駅へのポスター搬入の方法まで事前に相談できたのは本当にありがたかったです。
広告枠購入
代理店さんが決まったところで枠を購入します。特別難しいことはなく、「この枠買います!」とECサイトよろしくカートに入れてチェックアウトするだけです。ただし裏で在庫がなくなっていたりすることもあります(一敗)、購入後に正式に連絡が来るのでそれまで待機。
購入後に代理店さんからいろんな詳細情報がもらえます。特に駅固有の制限(QRコードのサイズや個数)や注意書き(例: XXをポスターに入れてください)があったりするので、しっかりメモしてすべてデザイン担当に渡す必要があったり。
なお、広告代理店さんによっては「個人NG」「過去実績ない場合はNG」みたいなこともあったりするので、しっかり条件は読みましょう。(※ Cheering ADさんではないです)
デザイン制作(待機)
暇である。
そう、主催側はやることがないのである!!!!!!この期間、暇である!!!!(5月下旬〜7月上旬)
約1ヶ月ほどやることがなくなったので、自分はこんなことして過ごしていました。ぼけーっとしていると、あっという間に自分の番になりますからね。
- 広告の告知の方法(クラファンやっていないので認知を上げる方法)
- SNSやファンサイトでなんとかできないか考えたり
- メモをする
- グッズ作って現地で配布したい
- ポストカード(後述)の制作に必要なものを調べたり
- メモを整理する
- SNSレビューの準備
- 並行してできます
- メモをする
- 仮印刷の準備
- 一発勝負は怖いので、B3サイズでいろんな用紙に印刷してみる
- これがかなり良かった
- デザイン入稿後のシミュレーション
- 「進捗いかがすか〜」
クラファンとかやる場合はこの期間に告知してお金を集める勘定したりとさらにバタバタするんだろうな〜と思ってました。
仮印刷
デザインデータを印刷業者へ入稿後、その印刷物を目で見るのは掲出後です。印刷ミスや色合いが想定外等のトラブルがあると公開後に気がつくことになります。そこで今回は事前に仮印刷を刷ることにしました。
プリオさんに相談してみたところ、小さいサイズで印刷すると発色は同じように見れるよとのアドバイス。今回は試しに2種類の紙質でそれぞれ小さいサイズで印刷しました。刷ってみた感想ですが、用紙ごとに思っていたよりも色の出方は違いました。たとえば高崎駅バージョンのイラストの場合、耐水紙とマット合成紙で色の表現や表面の反射の色が異なり雰囲気がぐっと変わりました。

今回のポスターデザインは空気感重視だったこともあり、ここでしっかり検証できたのは大きかったです。期日とお金に余裕があれば試してみる価値あるかもしれません。
デザインレビュー入稿
完成したデータを広告代理店さんに渡してレビューです。これ以降、デザインの手直しができなくなるので提出前に細かいチェックは忘れずに。デザインレビュー通過後、納品先の情報や納品時の注意事項がもらえました。
SNSレビュー
応援広告特有というか、迷惑にならないようにする大切な予防線。掲出日前に「この日この駅に広告が出るよ!」と事前告知すると人が集まったりして迷惑になってしまうので、「告知は掲出日の正午以降」「告知内容は事前にレビューしたものを使う」というのがCheering ADさんでのルールでした。
こんな感じに告知する際のツイートポストの内容を事前に決めて、掲出の3週間前までにレビューを出します。「この文言入れて」「この表現ダメ」みたいな駅固有ルールもあったりするので、ささっと情報集めて用意しておきました。画像もこのときに準備するのじゃぞ!
🌲応援広告公開のお知らせ🌲#ミオスパークル はついに今週です!盛り上がってキタァ!!
— ミオファの森の盛り上げ隊 (@miofa_ryu) 2025年9月8日
そして、会場のぴあアリーナMMの最寄駅「みなとみらい駅」にて応援広告が公開されました🥳 #holocheer
🗓️掲出期間 9月8日(月) 〜 9月14日(日)
📍場所 みなとみらい線 みなとみらい駅 B2 北改札(改札外)… pic.twitter.com/0248zhtFvv
ポスター印刷
仮印刷で用紙も入稿方法もデータ不備チェックも済んでたので、さっと入稿しておしまい。ちなみにプリオさんは納品配送時の伝票情報を変更できるので、そこで注文番号など書いてCheering ADさん宛のフォーマットにしておきました。
……が、ここでトラブル発生🚨 Cheering ADさんから「納品されたポスターに傷が……」と連絡が。リアルな物品が関わる部分なのでこうゆうことも起こる。すぐプリオさんの再印刷できるか相談し、Cheering ADさんからのアドバイスに従って速やかに再納品されました。みなさん、トラブルにも関わらず速やかに対応してくださり本当に感謝です。
掲出
事前に掲出される時間は保証されてないからね〜という話を聞いてたのですが、いざ行ってみたらどの駅も朝イチで掲出されてました。うわぁぁぁありがてぇぇぇ。🙏ちなみに掲出現場に行く必要はないらしいとの。遠くに掲出しても安心だね💕
ま、行くけど。
また群馬の高崎駅のポスターを見に行った際、ついでにタワーレコード高崎店へ伺いました。ミオさんを推してくれてる同志の香りのする店舗……!そしたらなんとすでに広告を見てくださった店員さんがおり、和気藹々に意気投合。不思議な出会いでしたが、縁ができてあり良かったです。ありがとうございました。
【#大神ミオ 】
— タワーレコード高崎オーパ店 (@TOWERTAKASAKI) 2025年9月6日
🌲🐺🌲🐺🌲
\\群馬のタワ高はミオしゃ熱烈応援!!✊🏻//
ソロライブももうすぐ~~!!🎤✨
なんと高崎駅ではミオファの森の盛り上げ隊(@miofa_ryu
)様企画の大きな応援広告が掲出中です!!👏🏻
😌<担当も昨日見てきました!! とっっても素敵でした~!!✨
(③)#ミオスパークル
🌲🐺🌲🐺🌲 https://t.co/bjooAwUR3b pic.twitter.com/oMhN0sgZXB
……って呟かれてる!?ありがてぇ🙏
後日談
応援広告の後処理はないです。ポスターは処分されます。ポスターは処分されます。 大事なことなので2回言いました。なにか残しておきたい場合は、ポストカードとかにして残しておくと良いと思います。ぼくはせっかくなのでスーパーリッチ仕様のポストカード作りました。(イラスト担当の方に許諾を得ました)
一応ポストカード
盛りたかったのです。素敵なイラスト描いてくれたので、それなりの良いポストカードを……!なんて思いあれこれ考えた結果、こうなりました。
- 紙: スタードリームFS クリスタル 209kg
- キラキラしたパール加工が雰囲気とマッチ◎ 箔押し加工をしたかったので重めの紙にしました。
- マットPP
- 長期保存したい
- 角丸加工
- 角削れてダメージ入るの嫌だった
- 目立たせたかった
- 箔押し加工
- どうしてもやりたかった……どうしても
原価1枚100円近くするポストカードってどうゆうことなんですかね(白目)
手に取れた方はラッキーです。200枚ほど現地で配布したのですが、あっという間に完配し終えてしまったようで……これ以上はお財布の都合で刷れないんだ。
🎉🥳追加の告知有〼🥳🎉
— ミオファの森の盛り上げ隊 (@miofa_ryu) 2025年9月8日
イラスト担当してくださったPAISHENさん(@INUTOBI21)の協力のもと、このイラストが「ポストカード」になりました!!!ウォォォォ!! 箔押し付きだぁ!!ドンドンパフパフ~~✌️
9月10日 お昼頃、日本丸メモリアルパークにて無料配布予定です🥳詳細は後ほど公開します! https://t.co/FTxF7rOILu pic.twitter.com/xkX5biwqLJ
応援広告まとめ
主催してみて思ったことは、主催者はあまりやることがないのである!!!!
【注意】個人の感覚です、ここでは継続的に4時間/週くらい集中して作業する程度のことは「やることがあまりない」としています。たぶんRyuSAは4ヶ月間で60時間くらい稼働してます。
上記の通り、基本的にはマネジメントだけなので交通整理しているだけで大体終わります。調べることいっぱいありますが、世の中には多くの実践者がいてゴールデンパスが確立されているのでそこまで大変ではなかったです。間違いなくこの応援広告の立役者はイラスト兼デザイン担当のPAISHENさんでした。みなとみらい駅の広告、ライブ後に見て完成するの卑怯っすよ……

が、ミスったら推しの顔に泥を塗るものなので重圧はやばかったです。関係者にも「あ、この人のファンは応援広告すらできないのか〜」と思われたらどうしよう、と必死こいて失敗しないよう予防線張りまくって安牌コンチプラン充実ルートで進んでました。これは大変だった。気軽におすすめできるようなものではないですが、覚悟と時間とお金があるのならぜひ。
ありがとうございます…❣️👏👏 https://t.co/7gy3jcxUFy
— 大神ミオ🌲9/10 1stLive『Our Sparkle』 (@ookamimio) 2025年9月8日
フラワースタンド編
やることはとても少なかったけど、かなりバタバタしましたね……
今回、Our Sparkle宛のフラスタは当選が必要なパターンだったのでこのようなタイムラインでした。(実績)
- 2025年7月31日 当落発表
- 2025年8月31日 パネル入稿
- 2025年9月某日 搬入
- 2025年9月某日 搬出
当落発表から1カ月ちょっとでデザイン、イラストを完成させてパネル印刷してお花を組み立てて搬入しないといけない……だと!?
超スーパータイトな日程だったので、事前にある程度は考えてました……が、さすがに当選でないとお金払えないのでもどかしい感情……ぐぬぬ。
わぁい!フラスタですよぉ!!!🥳
— ミオファの森の盛り上げ隊 (@miofa_ryu) 2025年9月10日
ミオファからミオさんへ、お花を添えてプレゼントです!!🎉🎉🎉
デザインとパネルイラストはぱんじゃむのなめさん(@nononanameme)が担当してくれました!
大神ミオさん、ソロライブおめでとうございます〜!🥰🥰 #ミオスパークル #みてみてミオしゃ https://t.co/U0kOBvCwJ3 pic.twitter.com/35NqtI1LZv
全体の流れ
後から見返すと、大きく分けてこんなフェーズを考える必要がありました。
- 目的を明確にする
- 予算組む
- デザイン担当依頼
- イラスト担当依頼
- お花さん担当依頼
- デザインこねこね
- パネル印刷
- 組み上げ、搬入、搬出
特にデザインは花の部分を含めてデザインしないといけないので、お花屋さんとよく相談しないといけないな〜と。
タスク - 人探し
今回目的は明確で「ミオファからミオさんへプレゼント花を送りたい」ことでした。なので「お祝いのためのお花プレゼント」「パネルはすべてミオファだけ、祝われる側の大神ミオは出さない」「お花をメインにしたい」にすると決めてました。そしてそこから導き出されたイラスト担当の方は……そう、我らが父、ぱんじゃむのなめさん。
連絡を取ったところOKをいただき、さらに(恐らくぼくの不甲斐ないデザイン力に呆れて)デザインの担当までお願いいたしました。神。パパ、ごめん……おれイメージをイメージできない脳のデザインしているんだ……
お花屋さんは、せっかく横浜であること、お花が好きなミオさんが満足できるよう、結婚式などを担当してくれているハマフローリストさんにお願いしました。搬入搬出もまとめて取り仕切ってくれて、とても感謝……!
パネル印刷はすでにやり取りしてるプリオさんに引き続き依頼しました。ありがとう、プリオさん。ちなみにカットラインについて、初回だったことと時間がタイトだったのでプリオさんにカットラインの追加を依頼しました。ミオファのシルエットが定まった段階でプリオさんに相談し、これなら1営業日でできますよと連絡いただけました。ありがとうございました、プリオさん。
タスク - こねこね
こちらが最初期のデザインです。(by RyuSA)

苦笑。
が、ここからやりたいこととキービジュアルのイメージをハマフローリストさんとぱんじゃむのなめさんにお伝えして使えるアイテムなどが出揃ってきたところで、ぱんじゃむのなめさんからこんなデザインが。

ど、どうゆうことだってばよ??ハマフローリストさんも「ここは造花で、このお花で、色合いは……」と、あれよあれよという間に決まりました。プロってすげぇ……。
パネルの素材は、水回り触れる可能性があるかもしれないと判断して耐水紙を選択。作業環境もわからないので、念のためUVカット加工も追加してもらいました。こ、これで良かったんかな……?
メンバーと決めること決まれば主催側は用無し。イラスト担当の方からデータを受け取って印刷所に渡してお花屋さんに転送、組み立ててもらって搬入と搬出をしてもらい……あれ?こうやって文章にすると、ぼく何もしてない(ry
後日談
「終わった後に何も残らない」というもの寂しいので、今回お花屋さんに相談してパネルを返却してもらえないか相談してみました。ありがたいことにOKをいただけで、現在自分の手元にあります。はぁ〜〜〜〜〜かわよ🥰

また、お花屋さんが会場近くでしたのでライブ当日に感謝を伝えるために挨拶に伺いました。そのタイミングで実際にフラスタを組み立ててくれた店員さんがいらっしゃり「楽しかったですよ〜」というコメントもらえてとても嬉しかったです。ハマフローリストさん、本当にありがとうございました!

フラスタまとめ
おそらくフラスタに関しては絵が描ける人、少なくとも頭の中にイメージを作れてそれを絵にアウトプットできる人がメンバーにいるとスムーズなんじゃないかなと思います。そうじゃないとマジで話進められない……
できる人はこちら↓
ちなみにお花屋さんとデザインを詰める際、コミュニケーションが結構大事だなと思います。物理的な話になるので「ここはこうゆう材質で」「この部分はこんなお花が合いそう」など、すり合わせが大事になってきます。ま、今回はのなめさんのデザインPOWERとハマフラさんの知識がハマったようであまり大変にはならなかったのですが……
このフラスタは動画配信でも取り上げてもらえました、𝕙𝕒𝕡𝕡𝕚𝕟𝕖𝕤𝕤
供養:最初の最初は999本の薔薇計画があったりしたのですが、ぼくのフラスタの目的から逸れるということで自分で中止に。本邦初公開、お焚き上げ〜〜〜。
トータルまとめ
たのしかった〜〜〜〜〜〜。ホクホクの思い出。

Kubernetesのいろんな資格とった話
数年前にCKA/CKADを取得しました。懐かしいですね。
あれから数年、すでにあの頃取得したCKA/CKADはExpiredしてしまいましたが、新しくKubernetes関連の資格を取得してみました。
- CKA
- CKAD
- KCNA
- KCSA
- CKS
そう、いわゆるKubestronautってやつです。この記事は忘備録的な内容です。
……と思って筆を走らせてみたのですが、当時と違って最近ではすでに多くの人が体験記を書いている時代になりました。Kubernetesもよりメジャーになったと言うことでしょう、良い時代だ。
一般的な話やよく使える教材などの紹介は避けて、ここではぼくの場合固有の問題とかについて語るに留めておこうと思います。
メタ情報 👀
受験した際のメタ情報を書いておきます、初心者ではないのです。
- Kubernetesチョットワカル人
- おうちKubernetesクラスターを3ヶ月に一回作り直す人
- 初めて触れたKubernetesは1.14あたり
試験環境周り
Environment Checkとして、部屋に余計なものがない環境で受験する必要があります。先人の知恵を借りて、自宅の浴室を使って受験しました。
試験環境は某氏を見習ってお風呂場でやりました🫠
— RyuSA🌲 (@ryusa_eng) 2025年2月2日
この時期、浴室エアコンマジ助かる〜〜 https://t.co/7WZF205dFd pic.twitter.com/by2b6R33bm
給湯器のことは適当にHouse Controllerとか言って回答しました。Environment Checkの担当者が給湯器のこと知らないこともあるはずだし、まぁ間違ってないはず……
トラブル
CKA編
ノートPCのバッテリーが切れました(マジで申し訳ない) 元々バッテリーのへたってた貧弱ノートPC使ってたのがよくなかったです
慌てて充電ケーブルで充電してSecure Browser開き直したらそのまま試験続行して良いよと回答もらえたので本当に助かりました。たぶんこの対応には保証はないはずですが、同じようにバッテリー切れた場合は素直に「ノートPCの充電切れちゃいました」と伝えましょう。もしかしたらワンチャン助けてくれるかもしれません。
CKS編
接続先のリモートPCとVMが非常に不安定で試験どころではない状態のままスタート……してそのままフィニッシュでした。このときも素直にチャットで「文字入力してから数秒後に入力が表示される」「カーソルが瞬間移動する」「画面がしょっちゅうタイムアウトする」と連絡して20分ほどトラブルシューティングしてもらいましたが原因は不明。「終わった後にチケット上げてね」という形で再開して終わりました。(冒頭20分返して……)
残念ながら結果的にそのまま合格しちゃったので、実際にこのパターンはどうなるのか不明……
いずれも言えることは、困ったら素直にヘルプを求めましょう。たぶんきっと何か前進できるはず。(少なくともログには「ヘルプを求めた」事実は残るので重要なはず)
勉強教材
Killer.shを信じろ
……と言ったものの、実際Killer.shは素晴らしいです。特に試験に付属するシミュレーターは本番で利用する環境とUIから使い勝手まで大体一緒です。ぜひ使ってみてください。
なお、Killer.shのCKA/CKADコースを一通り学び 理解して 理解して 理解して コマンドぱぱっと叩けるようになれればおそらくCKA/CKADは足りると思います。
CKSはこの座学だけでは足りない、純粋なLinux力も必要ですがITエンジニアとしての総合力と勘が大事な気がします。この不足分をどこで補えるのかは正直不明……。とりあえずKKDが大事。
ちなみにKiller.shの出しているCKSの教材はYouTubeに上がっています。知識面はだいたいこれで補えます。おいおいマジかよ(Udemyで買ってたマン)
それとタイピングが遅いそこのあなたには寿司打おすすめです。
ぼくはタイピングが致命的に遅かった(=お勧めコースクリアできなかった)ので、これで練習しました。高級コースクリアしたい。
最後に
ぼくはKubernetesたのしい〜〜〜^^派なのでゲーム感覚で楽しめました。業務ではめっきりKubernetesに触れることがなくなってしまったので、久しぶりにkubectlにたっぷり触れて満足でした。個人的な話ですが、この試験ラッシュの最中に自分も alias k=kubectl 派に改宗しました。
サポートしてくれた家族、夜中作業のお供にいてくれた大神ミオさん(の配信)にこの場を借りて感謝……!!
kubenews#57 Cloud Nativeなニュース - プロダクト紹介縛り
本記事はkubenewsの第57回目のゲスト枠で参加するRyuSAのコンテンツです。
なお、本登壇および本記事はあくまで 私自身の見解 であり、私の所属団体・企業における立場、戦略、意見を代表するものではありません。
Markdoc
Stripe社の公開したドキュメントをMarkdownで書くためのOSSです。利用できるMarkdownはGitHub Flavored……でありつつも一部AsciiDoc的に似た拡張を使ってドキュメントを記述できます。そのため多くのエンジニアが普段から書き慣れているMarkdownを使ってドキュメントのメンテナンスを行うことができます。
--- title: What is Markdoc? --- # {% $markdoc.frontmatter.title %} {% #overview %} Markdoc is a Markdown-based syntax and toolchain for creating custom documentation sites. Stripe created Markdoc to power [our public docs](http://stripe.com/docs). {% callout type="check" %} Markdoc is open-source—check out its [source](http://github.com/markdoc/markdoc) to see how it works. {% /callout %} ## How is Markdoc different? Markdoc uses a fully declarative approach to composition and flow control, where other solutions… [Read more](/docs/overview). ## Next steps - [Install Markdoc](/docs/getting-started) - [Explore the syntax](/docs/syntax)
またNext.jsやReactなどと組み合わせて複雑なビルドやレイアウトのごにょごにょができたりと、拡張の方法はかなり自由のため社内WikiのGit管理などに使えるような気がします。
Talos Linux
Kubernetes"専用"のOS……え??専用???となりますがそんな不思議なOSがTalos Linux。このLinuxディストリビューションはコンテナ向けOSLinuxのひとつで、特にKubernetesを起動/運用するためのものです。OSにSSHすることはできず、設定はすべてはtalosctlを使ったAPI経由で行うことになります。
Talos LinuxはDockerで起動することが可能で、手元でサクッと動作検証することができます。

個人的に好みなのは、このOS自体がメモリ上で展開できるためサーバーがステートフルになることを防ぐことができます。PXEブートなどにも当然対応しているため、Raspberry Piなどが活躍するワークロード(IoTや誤自宅勢とか)にはとても便利なんじゃないかなと思います。
trivy
超便利だったので共有したい、というだけ……
23:22:35 ryusa@TUNA-KAN:~/develop/local/kubenews#57 $ trivy kubernetes --report summary cluster 2022-07-13T23:22:54.708+0900 INFO Need to update DB 2022-07-13T23:22:54.708+0900 INFO DB Repository: ghcr.io/aquasecurity/trivy-db 2022-07-13T23:22:54.708+0900 INFO Downloading DB... 32.96 MiB / 32.96 MiB [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 19.91 MiB p/s 1.9s 141 / 141 [----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 7 p/s Summary Report for admin@talos-default ┌─────────────┬──────────────────────────────────────────────────────────────┬────────────────────┬────────────────────┬───────────────────┐ │ Namespace │ Resource │ Vulnerabilities │ Misconfigurations │ Secrets │ │ │ ├───┬───┬───┬────┬───┼───┬───┬───┬────┬───┼───┬───┬───┬───┬───┤ │ │ │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ C │ H │ M │ L │ U │ ├─────────────┼──────────────────────────────────────────────────────────────┼───┼───┼───┼────┼───┼───┼───┼───┼────┼───┼───┼───┼───┼───┼───┤ │ kube-system │ Role/system::leader-locking-kube-scheduler │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ kube-system │ Role/system::leader-locking-kube-controller-manager │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ kube-system │ Deployment/coredns │ 1 │ 1 │ │ │ │ │ │ 3 │ 5 │ │ │ │ │ │ │ │ kube-system │ DaemonSet/kube-flannel │ │ 6 │ 8 │ 6 │ 2 │ │ 2 │ 9 │ 30 │ │ │ │ │ │ │ │ kube-system │ Role/system:controller:cloud-provider │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ kube-system │ Role/system:controller:token-cleaner │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ kube-system │ Role/system:controller:bootstrap-signer │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ kube-system │ DaemonSet/kube-proxy │ 6 │ 8 │ 2 │ 57 │ │ │ 2 │ 4 │ 10 │ │ │ │ │ │ │ │ kube-system │ Service/kube-dns │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ kube-public │ Role/system:controller:bootstrap-signer │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ ClusterRole/cluster-admin │ │ │ │ │ │ 2 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:namespace-controller │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:job-controller │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:endpointslice-controller │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:root-ca-cert-publisher │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ ClusterRole/system:kube-scheduler │ │ │ │ │ │ │ 2 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/admin │ │ │ │ │ │ 3 │ 7 │ 1 │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:endpoint-controller │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:resourcequota-controller │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:replicaset-controller │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:generic-garbage-collector │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/edit │ │ │ │ │ │ 2 │ 7 │ 1 │ │ │ │ │ │ │ │ │ │ ClusterRole/system:aggregate-to-edit │ │ │ │ │ │ 2 │ 7 │ 1 │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:deployment-controller │ │ │ │ │ │ │ 2 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:horizontal-pod-autoscaler │ │ │ │ │ │ 2 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:persistent-volume-binder │ │ │ │ │ │ 1 │ 2 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:expand-controller │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:replication-controller │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:aggregate-to-admin │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:endpointslicemirroring-contro- │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ ller │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:kube-controller-manager │ │ │ │ │ │ 5 │ 2 │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:node │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ │ │ │ │ ClusterRole/system:controller:cronjob-controller │ │ │ │ │ │ │ 2 │ │ │ │ │ │ │ │ │ └─────────────┴──────────────────────────────────────────────────────────────┴───┴───┴───┴────┴───┴───┴───┴───┴────┴───┴───┴───┴───┴───┴───┘ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN
う、美しい……!(jsonでのレポートもできるので自動化もしやすいたすかる)
Trivy Operator
というそんなTrivyのOperatorについても紹介、要するに↑をKubernetes内部からチェックしてくれるとても素晴らしいOperator。CRとしてPodや各種設定の脆弱性を出力してくれます。
00:14:21 ryusa@TUNA-KAN:~/develop/local/kubenews#57 $ kubectl apply -f https://raw.githubusercontent.com/aquasecurity/trivy-operator/v0.1.3/deploy/static/trivy-operator.yaml customresourcedefinition.apiextensions.k8s.io/vulnerabilityreports.aquasecurity.github.io created customresourcedefinition.apiextensions.k8s.io/configauditreports.aquasecurity.github.io created customresourcedefinition.apiextensions.k8s.io/exposedsecretreports.aquasecurity.github.io created customresourcedefinition.apiextensions.k8s.io/clusterconfigauditreports.aquasecurity.github.io created customresourcedefinition.apiextensions.k8s.io/clusterrbacassessmentreports.aquasecurity.github.io created customresourcedefinition.apiextensions.k8s.io/rbacassessmentreports.aquasecurity.github.io created namespace/trivy-system created serviceaccount/trivy-operator created clusterrole.rbac.authorization.k8s.io/trivy-operator created clusterrole.rbac.authorization.k8s.io/aggregate-config-audit-reports-view created clusterrole.rbac.authorization.k8s.io/aggregate-exposed-secret-reports-view created clusterrole.rbac.authorization.k8s.io/aggregate-vulnerability-reports-view created clusterrolebinding.rbac.authorization.k8s.io/trivy-operator created role.rbac.authorization.k8s.io/trivy-operator created rolebinding.rbac.authorization.k8s.io/trivy-operator created role.rbac.authorization.k8s.io/trivy-operator-leader-election created rolebinding.rbac.authorization.k8s.io/trivy-operator-leader-election created secret/trivy-operator created secret/trivy-operator-trivy-config created configmap/trivy-operator created configmap/trivy-operator-trivy-config created configmap/trivy-operator-policies-config created Warning: would violate PodSecurity "restricted:latest": runAsNonRoot != true (pod or container "trivy-operator" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "trivy-operator" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") deployment.apps/trivy-operator created service/trivy-operator created 00:21:19 ryusa@TUNA-KAN:~/develop/local/kubenews#57 $ kubectl create deployment nginx --image nginx:1.16 Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") deployment.apps/nginx created 00:22:10 ryusa@TUNA-KAN:~/develop/local/kubenews#57 $ kubectl get vulnerabilityreports -o wide NAME REPOSITORY TAG SCANNER AGE CRITICAL HIGH MEDIUM LOW UNKNOWN replicaset-nginx-7f597d689d-nginx library/nginx 1.16 Trivy 32s 38 74 57 119 1
現在の最新バージョンで用意されているのは - clusterconfigauditreports - clusterrbacassessmentreports - configauditreports - exposedsecretreports - rbacassessmentreports - vulnerabilityreports の6つのリソース、雑に環境に放り込んでおくだけでそれっぽくなりそうな予感
Sigstore
ソフトウェアのサプライチェーンを防ぐための仕組みを考えよう!という実験的なプロジェクト Sigstoreは - cosign - Fulcio - Rekor の3つのソフトウェアを組み合わせて機能でき、最終的な目的としては「アーティファクトをキーレスで署名して、その署名を改竄できないログとして保存して、アーティファクトを公開する」ことです。これにより、だれでもアーティファクトが正しく署名されていることを検証することができつつ鍵の管理が不要なので色々幸せになれそうな予感……!
残念ながら手元のWindows環境ではなぜかうまく動かなかった&話するとかなり長くなるので詳細は先人の神資料を参考に……
OCIイメージに対しての署名もできる一方、当然普通にバイナリにも署名ができるのでJavaのGradleやRubyのRubyGemsなどでIssueとしてあがっています。Sigstoreが広がって、すべてのソフトウェアのサプライチェーンを守れるようなそんな世界が来るといいですね。
とあるYouTube Streamerのファンサイトを作った話
この活動は自分個人の趣味であり、所属する企業や組織の立場、戦略、意見を代表するものではありません。
こんなの作ってました。たのしかった(小並感
リリースしてからしばらく経ったので、少し技術的な選定の話とかをまとめておきます。尖ったことはあまりしてないのでアレですが……🤔

Question. そもそもなんで作ったの?
Answer. 久しぶりにフロントエンド作りたかったから🤪
ここ最近はKubernetesやDNSなどのインフラストラクチャーばかり触ってたので、たまにはリフレッシュしたいな〜と……
要件と技術選定を進める
今回の要件はこんな感じでした。個人プロジェクトなので自分中心で楽しくやりたいってのが理由ですね。
- まだ触ったことがないものに挑戦したい
- 個人開発である以上モチベを維持しやすいように新しいものに触れることを前提に
- 安く早く済ませたい
- 言わずもがな
- マネージドなサーバーを持ちたくない
- 管理したくない(怠惰
- ホットなコンテンツを相手にする以上、もしかしたらスパイクが発生するかも……?(という想定訓練は大事)
- デプロイ自動化が可能
- 令和ですよ?Continuous Deploymentくらいは標準搭載ですよね??
- 万が一怒られた際にロールバックがスムーズにできるようにする(これから怒られる可能性はまだありますので、怒られたら速攻で消します)
- ガイドラインを読む(超大事)
- 趣味の範囲のプロダクトだしプラットフォームにも準拠するようにするし……
- 二次創作ガイドライン | ホロライブプロダクション
- ガイドラインを読む(大事なことなので(ry
- ガイドラインを読む(超大事なことなので(ry
ということを前提に技術選定を進めました。
プラットフォーム
まずはプラットフォームの選定。今回のコンテンツ的には静的なもので十分(=バックエンドで動的にコンテンツを生成する必要がない)のでサーバーどころかLambdaすら不要。単純なSPA等の静的ファイル配信ができればOKです。
そこで今回はNetlifyかVercelかCloudflare Pagesのいずれかをプラットフォームとして使おうかなと🤔Netlify / Vercel / Cloudflare Pages はいずれもフロントエンドホスティングサービスで、ReactやVueなどで作ったSPAなどをホスティング&CDN配信してくれるとても素敵なサービスたちです。……が、実はNetlifyはかつて使ったことがあり、いろんなところで話題に聞くVercelが気になったので今回はまったく触ったことがないVercelでホストすることに決めました👀ごめんねCloudflare Pages
ドメイン名とか証明書とか
このファンサイトは二次創作のプロダクトであり、万が一ご本家様とドメイン名争奪戦が起こっては大変なので自分のドメインryusa.appからのサブドメインを切り出しました。
Vercelは、ホスティングサイトなので当然ではありますがカスタムドメインを利用してサイトを公開することができます。
自分のryusa.appはGoogle Domainsで用意しているドメインなので、GoogleのDNSにVercel向けのCNAMEだったりTXTレコードだったりを登録してVercel側にドメインの登録を完了しました。超簡単。

……ちなみにVercelにドメインの登録をすると、自動的にLet’s EncryptでTLS証明書を発行してくれるようになります。マジでなにも考えなくてもTLS証明書がホストされるようになります。超簡単。
言語とか
今回はTypeScript/Reactベースで実装することを決定しました。最初は今アツいSvelteで行こうかと思いましたが、React 18がちょうど出たタイミングだったので波に乗るなら今だ!!と思って今回はReactベースにしました。Svelteはまた今度ね……🥰また最初はSPAとしてビルドしようと思っていましたが、フロントエンドの規模的にそこまで大きくなく、かつ動的なAPI呼び出しも発生しないことを踏まえると静的ビルドで十分と判断し、今回はまだ触ったことのないGatsbyを利用することにしました。
ちなみに、実装中に検証としてExperimentalで公開されてるReactのServer Componentも触ってみましたがかなり良さげでした。そこまでコストかけずにバンドルサイズを減らせるのは強い……!ただ今回は検証の時間がそこまでなかったので見送り……
CI/CD
GitHub ActionでビルドしてVercel側で自動デプロイ……というのが当初の予定でしたが、実はそもそもVercel側にGitリポジトリをfetchして自動ビルドをかける機能が存在しているんですよね。自分は知らなかったのですが、Vercelにはリポジトリを連携するとリポジトリの中身をチェックして自動的にビルドコマンドとデプロイコマンドを生成してくれる神機能が付いていました。

実装周りとか
そんな難しいことしてないし特に書くものなくね??と思っていましたが、個人的に気を配ったことだけ……
IEのサポートを、しない
力強く!
日本はやたらIEシェアが高いらしいですが、別にお仕事でもないプライベートプロジェクトなのでIE対応はしませんでした。React 18からIEのサポートも切れることですしIEそのものも消えますし、まぁ妥当かなと。
(IEを除く)ブラウザシェア上位 95% を(目安に)サポートする
ファンサイトとしてホストする以上、モダンブラウザをサポートしておかないと場合によっては他の熱心なファンが応援できない可能性があります。「(レイアウト崩れを見て)なんだよーFirefoxはサポートしてくれないのかー」となっては悲しいですし、せっかくの盛り上がりに水を差してしまうでしょう。ということで今回はChromeを始めとしてブラウザシェア95%に入るブラウザをサポートすることを目標に動作検証を行いました。なのでCSSのsvhや@layerなどの超モダンな機能群が使えなくて少し悲しいところではありましたが……
業務ではモダンブラウザサポートなんて当然の作業ですが、個人プロジェクトで動作検証しっかりやったのは初めてでしたね……一部環境の動作検証にお手伝いいただいた方々には、改めてこの場で感謝を。ありがとうございました!(iPhone民/Samsung民)
まとめ
Vercelとフロントエンド周りのエコシステムが本当に充実しており、CI/CDの環境をサクッと構築できるおかげで手元で開発して本番デプロイまでが数分でできる世界観でした。ブランチで本番環境にデプロイするアセットを管理できるので、これであれば大規模なフロントエンド開発チームでの開発フローにも導入できそうです。
今度Cloudflare Pagesも使ってみる予定なので、もしタイミングがあれば具体的なNetlify / Vercel / Cloudflare Pages の比較ができるかもしれないですね👍
最後に、お手伝いいただけたみなさんありがとうございました。wappaさんも素敵なイラストを提供&OGP画像作成ありがとうございました。
久しぶりの人目に触れるプロダクトを公開し、いろんな人からの感想がもらえたのはすごく励みになりました👏ありがとうございました!
あいあいじぇいを退職します👋
エンジニアもすなる退職ブログといふものを……
2022年3月31日を最終出社日として、株式会社インターネットイニシアティブを退職します👏 新卒で入社してちょうど4年間、大変お世話になりました。
退職ブログを書いてみようと筆を走らせてみたものの、思いのほかたくさん書けそうになく……ですが、せっかくなので少しだけですが、将来の自分のためにもエントリーを残しておきます
IIJでどんなことしていたの
僕はIIJのとある金融サービスの部署のエンジニアとして仕事をしていました。最終的な肩書きがただの「エンジニア」なのは、それはそれでちょっぴり寂しい気もする……ww
主な業務内容としては次のようなものに携わってきました。
- アプリケーション開発
- フロントエンド
- バックエンド
- インフラ開発
- AWS関連
- Kubernetes
- プラットフォームエンジニア的なやつ
……おぉ、こうやって並べてみると専門領域がフワッフワしてるなぁw スキルセット的にはインフラ領域1に対してアプリケーション3……ぐらいの立ち位置ですね🤔
最初はアプリケーションエンジニアとして金融システムを開発し、その後インフラに近い領域からプラットフォームエンジニア的な立ち位置で開発メンバーの補佐や技術検証などをやってきました。とはいえ今でも自分の一番の専門と言える領域はアプリケーション開発ですね。コーディング楽しい🤪
メイン業務とは若干外れますが、IIJのブログにこんなネタを投稿していました。多々反響もらえて(特にKubernetesネタ)非常に楽しかったですw
Why 退職?
退職する主な理由は、転職するからです。(?🤔?)
新しい環境で挑戦してみたいな〜と考えていた矢先、とあるクラウドベンダーさんとお仕事する機会があったので挑戦してみようと思い転職を決めました。やっぱりね、刺激が欲しいんですよww
おそらく今の環境に残っていても様々なキャリア、技術面を磨くことはできるとは思いますが……それはあくまでもIIJという会社から見える世界でのみ、やっぱり一度外に出てみたいなと思うわけです。
最後に
4年間、面倒を見てくださったメンバーに最大限の感謝を。たくさん尻拭いしてくださり本当に感謝しております。この4年間は、自分にとって大切な4年間になりました👏
また社内に転がっている様々なコミュニティ(IIJ Bootcamp GitHub - iij/bootcamp: Bootcamp ハンズオンで使用する資料集 とか)での会話も非常に楽しかったです。気軽に困ったことや技術ネタをネットミームとともに盛り上がれる場があるのは、なんというかすごくIIJらしさを感じてますw
とはいえ退職するからと言って人が変わるわけでもなく、今後もTwitter等で元気よく自生しておりますので
ではでは👋
技術書典 #12で「Java開発 for Kubernetes」を頒布します🎉
はじめての技術同人誌ですが、がんばります💪
どんな書籍?
「次のプロジェクトでは、DockerとKubernetesでクラウドネイティブだ!」 ……なーんて話を聞かされて、困っている開発者の人はいませんか?
アプリケーションの実行環境をコンパクトにまとめた隔離環境「コンテナ」 コンテナを自在にデプロイし面倒くさい管理を自動化できるエコシステム「Kubernetes」
大コンテナ時代を迎えようとしている今、どのようにJavaでアプリケーションを書き、どのように開発フローを回し、どのように運用/監視していくのか、ざっくり表面だけ舐め回すことができるコンテンツを集めました。 JavaのWebアプリケーションとしてSpring Bootを使いながら、実際にコマンドを叩いてアプリケーションをコンテナにしてKubernetesにデプロイする開発フローを体験してみましょう!
という感じの本です。つまるところ「Kubernetes上で動かすコンテナアプリケーションを開発するにあたって、どんなツールがあったり嬉しいものがあったりするの?」ってのをざっくりをまとめたエッセンス本です。注意していただきたいのは「これを読めばKubernetes完全に理解できる!」タイプの本ではないです。マジでアプリケーションサイド目線の話しか書いていません。なのでインフラの話はほぼ出てきません。
コンテンツ
- 含まれているもの
- コンテナの概要説明
- Kubernetesの概要説明
- コンテナのための開発フロー体験
- 開発ヘルパーツールの紹介とざっくり使い方
- 運用のために覚えておくこと
- これらのサンプルコード
- 含まれていないこと
- Kubernetesのバックエンド(kubeadmとかkubeletとか)
- インフラの話(OSとかCNIとかコンテナランタイムとか)
ターゲットとなる人
主に開発者、特にJava/Spring Bootの開発を行なっている人にとっては良い本だと思っています。またJavaで書かれたワークロードをメンテナンスするぜ!という(広義での)SREの方も読んでおくとアプリケーション開発者と会話しやすいかもしれないです。
自分はアプリケーション開発者である一方でCKA等も取得しKubernetes完全にわからんを通過してきた身でもあります。その背景を元に「こんな情報が横断的にあったら嬉しかったのにな〜」というものをかき集めてました。すいません、実は書ききれてないです物理的な予算が足りなかったです。
ということで、買って💕
電子書籍版は1000円、電子書籍+物理本セットも1000円で頒布しています!一応別の場所でも頒布する予定はありますが、お値段上がったり電子版/物理本いずれか……など、セットでは購入できなくなると思います。
GitLab OperatorはGitLab運用の自動化の夢を見るか
注意 : GitLab Operatorは10月9日現在まだv0.1.0のリリースがあったばかりです。本番環境への適用にはまーだ早いのでご注意してください🤔
–– さぁ、GitLab OperatorでGitLab運用の自動化をはじめよう!!
背景
GitLabはおそらく多くのエンジニア、組織で利用されているGitリポジトリ管理ツールです。しかし、GitLabには多様な機能が日々追加されており今やGitLabはただのGitリポジトリツールではなくっている……と個人的に思っています。
GitLabのIssue/Milestoneをはじめ、MavenやコンテナイメージのリポジトリやKubernetes Integrationなど多様なコミュニケーション機能や開発者向けの機能が追加されています。GitLabに求められる可用性は日々上がっている一方、ますます複雑になるGitLab運用は人間の手でやりたくないですよね。
そこで使えるのがGitlab Operator、Helmに次ぐ新しい"Cloud Native"なGitlabホスト方法です。
全体像

検証環境
AWSのEKS上で実施します。ただEKS専用の機能を使う部分は限定的なため、他のKubernetes環境でも同じように起動することができるはずです。
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ryusa-gitlab version: "1.21" # 後述のExternalDNSとcert-managerをRoute53で管理するためのIRSAを定義 iam: withOIDC: true serviceAccounts: - metadata: name: external-dns namespace: external-dns labels: {} wellKnownPolicies: externalDNS: true roleName: eksctl-ryusa-external-dns-role - metadata: name: cert-manager namespace: cert-manager labels: {} wellKnownPolicies: certManager: true roleName: eksctl-ryusa-cert-manager managedNodeGroups: - name: workers minSize: 1 maxSize: 6 desiredCapacity: 3 spot: true instanceTypes: - t3.medium - t3.large volumeSize: 60 volumeType: "gp3"
Getting Startedする
依存関係のセットアップ
GitLab Operatorは
を利用してGitLabを起動します。まずはこれらを適当にKubernetesにデプロイしておきましょう。
NGINX Ingress Controller
GitLabをKubernetesの外からアクセスできるようにするためのIngress ControllerとしてNGINX Ingress Controllerが推奨されています。実際にはIngress Controllerとして
の2点が必要な機能だと思います。
推奨に従ってNGINX Ingress ControllerをKubernetesにHelmでデプロイします。使うHelmチャートはingress-nginx/ingress-nginx、Valueファイルは下記のYAMLで実装します。
# Helmチャート ingress-nginx/ingress-nginx controller: ingressClassResource: name: nginx enabled: true default: true # NGINX Ingress ControllerにSSH用のTCPプロキシーを作成する # 22: ${GITLAB_NAMESPACE}/${GITLAB_NAME}-gitlab-shell:22 tcp: 22: "gitlab-system/vulture-gitlab-shell:22"
cert-manager
GitLabのTLS証明書を発行するためにインストールが必須です、GitLabのシステム内部で利用する自己証明書の作成もcert-managerのIssuerを使って実装されています。
推奨に従ってcert-managerをKubernetesにHelmでデプロイします。使うHelmチャートはjetstack/cert-manager、Valueファイルは下記のYAMLで実装します。一部項目にEKSからRoute53を変更するためのIRSAの設定が入ってますが、不要な方はスルーしてください。
# Helmチャート jetstack/cert-manager installCRDs: true # EKSのIRSAを利用するための設定 serviceAccount: create: false name: cert-manager annotations: eks.amazonaws.com/role-arn: arn:aws:iam::XXX:role/eksctl-ryusa-cert-manager securityContext: enabled: true fsGroup: 1001
今回はIssuerとしてLet's Encryptを利用するため、Let's EncryptのACMEを持つClusterIssuerを先に作成しておきます。
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt namespace: cert-manager spec: acme: email: YOUR_EMAIL privateKeySecretRef: name: letsencrypt-privatekey server: https://acme-v02.api.letsencrypt.org/directory solvers: - dns01: route53: region: YOUR_REGION hostedZoneID: HOST_ZONE_ID
External DNS
Ingressに割り振るドメイン名を自動的にDNSに設定するツールのインストールが推奨されています。GitLabをデプロイ後、デフォルトの状態で「GitLab」「MinIO」「Repository」の3つのIngressが作成され、それぞれ適切なドメイン名で名前解決できることが期待された状態でコンポーネントが起動してきます。
もちろん、Ingress作成後に手動でDNSを操作しても良いですが……素直にExternalDNSを利用した方が良いでしょう。今回はExternalDNSの公式リポジトリでホストされているマニフェストを利用してデプロイすることにします。
# 公式のRBACの定義は省略 --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns namespace: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns annotations: # IRSAのための設定 iam.amazonaws.com/role: arn:aws:iam::XXX:role/eksctl-ryusa-external-dns-role spec: serviceAccountName: external-dns containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.7.6 args: - --source=service - --source=ingress - --domain-filter=ryusa.example.com - --provider=aws - --policy=upsert-only - --aws-zone-type=public - --registry=txt - --txt-owner-id=some-identifier securityContext: fsGroup: 65534
GitLab Operatorインストール
公式ドキュメントに沿ってインストールしていきます。
❯ GL_OPERATOR_VERSION=0.1.0
❯ PLATFORM=kubernetes
❯ kubectl create namespace gitlab-system
namespace/gitlab-system created
❯ kubectl apply -f https://gitlab.com/api/v4/projects/18899486/packages/generic/gitlab-operator/${GL_OPERATOR_VERSION}/gitlab-operator-${PLATFORM}-${GL_OPERATOR_VERSION}.yaml
Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
customresourcedefinition.apiextensions.k8s.io/gitlabs.apps.gitlab.com created
serviceaccount/gitlab-app created
serviceaccount/gitlab-manager created
serviceaccount/gitlab-nginx-ingress created
role.rbac.authorization.k8s.io/gitlab-leader-election-role created
role.rbac.authorization.k8s.io/gitlab-nginx-ingress created
clusterrole.rbac.authorization.k8s.io/gitlab-app-role created
clusterrole.rbac.authorization.k8s.io/gitlab-manager-role created
clusterrole.rbac.authorization.k8s.io/gitlab-proxy-role created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
clusterrole.rbac.authorization.k8s.io/gitlab-metrics-reader created
rolebinding.rbac.authorization.k8s.io/gitlab-leader-election-rolebinding created
rolebinding.rbac.authorization.k8s.io/gitlab-nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/gitlab-gitlab-app-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/gitlab-gitlab-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/gitlab-gitlab-proxy-rolebinding created
service/gitlab-controller-manager-metrics-service created
service/gitlab-webhook-service created
deployment.apps/gitlab-controller-manager created
Warning: cert-manager.io/v1alpha2 Certificate is deprecated in v1.4+, unavailable in v1.6+; use cert-manager.io/v1 Certificate
certificate.cert-manager.io/gitlab-serving-cert created
Warning: cert-manager.io/v1alpha2 Issuer is deprecated in v1.4+, unavailable in v1.6+; use cert-manager.io/v1 Issuer
issuer.cert-manager.io/gitlab-selfsigned-issuer created
Warning: admissionregistration.k8s.io/v1beta1 ValidatingWebhookConfiguration is deprecated in v1.16+, unavailable in v1.22+; use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration
validatingwebhookconfiguration.admissionregistration.k8s.io/gitlab-gitlab-validating-webhook-configuration created
❯ kubectl get all -n gitlab-system
NAME READY STATUS RESTARTS AGE
pod/gitlab-controller-manager-645466b464-jxn5l 2/2 Running 0 2m5s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gitlab-controller-manager-metrics-service ClusterIP 10.100.68.88 <none> 8443/TCP 2m10s
service/gitlab-webhook-service ClusterIP 10.100.163.107 <none> 443/TCP 2m9s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/gitlab-controller-manager 1/1 1 1 2m10s
NAME DESIRED CURRENT READY AGE
replicaset.apps/gitlab-controller-manager-645466b464 1 1 1 2m11s
いい感じに起動しますね、ヨシ!これからGitLab OperatorがWatchしているGitLabリソースをKubernetesにデプロイして、GitLab OperatorにGitLab本体をデプロイしてもらいましょう。
GitLabをデプロイする
GitLab Operatorをデプロイした際にGitLabリソースのCustom Resource Definition(CRD)もデプロイされています。
❯ kubectl api-resources --api-group apps.gitlab.com NAME SHORTNAMES APIVERSION NAMESPACED KIND gitlabs gl apps.gitlab.com/v1beta1 true GitLab
GitLab OperatorはOperator SDKのHelm Operatorで実装されています。つまりGitlabリソースのスキーマはHelmチャート(gitlab/gitlab)と同一になっています。
GitLabのHelmチャートを参考にしつつ、cert-managerとExternalDNS、NGINX Ingress Controllerと連携するGitLabリソースを作成していきます。
まずは*.ryusa.example.comワイルドカードの証明書のためCertificateリソースを作成しておきます。このリソースをあとでGitLabリソースに連携し、すべてのIngressがこのCertificateリソースを参照できるようにします。
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: gitlab-tls namespace: gitlab-system spec: dnsNames: - "*.ryusa.example.com" issuerRef: group: cert-manager.io kind: ClusterIssuer name: letsencrypt secretName: gitlab-tls
Certificateリソースが作成され、TLS証明書が発行されたらGitLabをデプロイしましょう。
apiVersion: apps.gitlab.com/v1beta1 kind: GitLab metadata: name: vulture namespace: gitlab-system spec: chart: version: "5.2.4" values: global: hosts: # `gitlab` `registory` `minio`のサブドメインが生えてくる domain: ryusa.example.com ingress: # NGINX Ingress Controllerを使うように指定 class: nginx configureCertmanager: false # *.ryusa.example.com ワイルドカード証明書を指定 tls: secretName: gitlab-tls nginx-ingress: enabled: false certmanager: install: false
これでGitLabをKubernetes上に展開できました。(長い……)
サクッと運用してみる
それではGitLabで運用作業をやってみましょう!とはいえGitLab OperatorはDay 2 Operationを効率化するためのツールなので、バックアップやバージョンアップなどは非常にシンプルに行うことができます。
実際にコマンドを叩いて動かしてみます。
バックアップ
GitLabリソースを作成するとデフォルトでハウスキーピング用のTask-Runnerが起動します。このTask-Runnerにバックアップ含め様々な作業をお願いすることができます(らしい)。Task-RunnerのPodにはデフォルトでMinIOへの接続情報が保存されているため、Podの内部でbackup-utilityコマンドをキックするだけでバックアップを保存することができます。
❯ kubectl exec -it \
-n gitlab-system task-runner-b854bfbd7-zrfgw -- backup-utility
Defaulted container "task-runner" out of: task-runner, certificates (init), configure (init)
Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
done
...
Dumping pages ...
empty
Packing up backup tar
[DONE] Backup can be found at s3://gitlab-backups/XX_gitlab_backup.tar
すごく簡単、これでMinIOのオブジェクトストレージにバックアップが保存されました。

なお、GitLabリソースのTask-Runnerのサブチャートにバックアップのcron設定を追加することで定期的にバックアップを取ってくれるようになるらしいです。(未確認
apiVersion: apps.gitlab.com/v1beta1 kind: GitLab metadata: name: vulture namespace: gitlab-system spec: chart: version: "5.2.4" values: # 省略 gitlab: task-runner: enabled: true backups: cron: enabled: true # 毎日朝3時にバックアップを取得 schedule: '0 3 * * *'
リストア
リストア……を完全自動化することはあまりないと思いますが、手動バックアップと同じようにデータをリストアすることができます。バックアップと同じようにTask-Runner Podのコンテナ上でbackup-utilityコマンドをキックするだけです。
❯ kubectl exec -it -n gitlab-system vulture-task-runner-7dd4d9c4bd-dgs6l \
-- backup-utility --restore -f 'https://minio.ryusa.example.com/gitlab-backups/XXX_gitlab_backup.tar?...'
...
[DONE]
done
ただし上記コマンドでリストアできるのはデータのみであり、鍵などの秘密情報はリストアしてくれません。GitLabの再インストールなどする場合は、Secretリソースを自分でリストアする必要があります。(ドキュメントに記載あり)
GitLabアップグレード
Gitlabのバージョンをアップグレードするには、対応するHelmチャートのバージョンを変更してapplyすればOKです。あとの処理はOperatorが実施してくれます。
上記でインストールしたGitLabリソースのHelmチャートバージョンは5.2.4ですので、これを5.3.0にアップグレードにします。これによりインストールされるGitLabのバージョンが14.2.4から14.3.0に上がります。
apiVersion: apps.gitlab.com/v1beta1 kind: GitLab metadata: name: vulture namespace: gitlab-system spec: chart: # 5.2.4 -> 5.3.0 version: "5.3.0" # あとは省略

まとめ
GitLab Operatorを利用することでKubernetes上にGitLabを展開し、Kubernetesの言葉でGitLabを管理できるようになるところを確認しました。日時のバックアップや機能の拡張、アップデートなど日々の作業の多くをkubectlコマンドだけで管理できるようになるのは、少なくとも個人的には嬉しいですね。
今回はcert-managerやNGINX Ingress ControllerをGitLab Operator内蔵のものではないExternalなものと連携しましたが、他にもいくつかのコンポーネントをExternalに変更できるみたいです。特にPostgreSQLやObject Storageなどの状態を持つものはマネージドサービスで使いたいところですね。
このGitLab Operatorはまだまだ開発中とのことで、Issueを見ている限り面白そうなIssueがいくつか上がってます。(ダウンタイムなしアップグレードとか、アツい……!)
現時点ではまだHelm版とOperator版のGitLabの間のクリティカルなギャップがあるわけではない(と思う)ですが、Operatorによる管理はHelmより柔軟な運用が可能になるのでこれからのロードマップに期待ですね。