血と汗となみだを流す

クラウドエンジニアになるための修業の場

JAWS-UG コンテナ支部 入門編 #6 コンテナの始め方 後編③(Trivyで脆弱性スキャン)

後編③とは

概要

  • ClairとTrivyをECSで動かして、dockerイメージの脆弱性をチェックする(今回はTrivy)
  • ハンズオン資料はGithubに公開されており、AWSアカウントがあれば誰でも実施することができます。ぜひ手を動かしてみることをお勧めします

資料のリンク

まえがき

Clairでは脆弱性なしと結果がでた envoyproxy/envoy-alpine:v1.10.0を Trivyで検査する

curl -s -X GET -H 'Content-Type:application/json' \
  "http://${API_HOST}:9000/api/v1/images/envoyproxy%2Fenvoy-alpine%3Av1.10.0/vulnerabilities" \
  | jq .
{
  "Count": 1,
  "Vulnerabilities": [
    {
      "Description": "ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input for every encryption operation. RFC 7539 specifies that the nonce value (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length and front pads the nonce with 0 bytes if it is less than 12 bytes. However it also incorrectly allows a nonce to be set of up to 16 bytes. In this case only the last 12 bytes are significant and any additional leading bytes are ignored. It is a requirement of using this cipher that nonce values are unique. Messages encrypted using a reused nonce value are susceptible to serious confidentiality and integrity attacks. If an application changes the default nonce length to be longer than 12 bytes and then makes a change to the leading bytes of the nonce expecting the new value to be a new unique nonce then such an application could inadvertently encrypt messages with a reused nonce. Additionally the ignored bytes in a long nonce are not covered by the integrity guarantee of this cipher. Any application that relies on the integrity of these ignored leading bytes of a long nonce may be further affected. Any OpenSSL internal use of this cipher, including in SSL/TLS, is safe because no such use sets such a long nonce value. However user applications that use this cipher directly and set a non-default nonce length to be longer than 12 bytes may be vulnerable. OpenSSL versions 1.1.1 and 1.1.0 are affected by this issue. Due to the limited scope of affected deployments this has been assessed as low severity and therefore we are not creating new releases at this time. Fixed in OpenSSL 1.1.1c (Affected 1.1.1-1.1.1b). Fixed in OpenSSL 1.1.0k (Affected 1.1.0-1.1.0j).",
      "FixedVersion": "1.1.1b-r1",
      "InstalledVersion": "1.1.1a-r1",
      "PkgName": "openssl",
      "References": [
        "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=ee22257b1418438ebaf54df98af4e24f494d1809",
        "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=f426625b6ae9a7831010750490a5f0ad689c5ba3",
        "https://www.openssl.org/news/secadv/20190306.txt"
      ],
      "Severity": "MEDIUM",
      "Title": "openssl: ChaCha20-Poly1305 with long nonces",
      "VulnerabilityID": "CVE-2019-1543"
    }
  ]
}
docker run --rm \
  -e CLAIR_ADDR="http://${API_HOST}:6060" \
  supinf/klar:2.4 envoyproxy/envoy-alpine:v1.10.0 | jq .

{
  "LayerCount": 6,
  "Vulnerabilities": {}
}

Docker公式イメージであっても、古いバージョンには脆弱性が残っている例

  • python:3.7.3-alpine3.9python:3.4.10-alpine3.9
curl -s -X GET -H 'Content-Type:application/json' \
  "http://${API_HOST}:9000/api/v1/images/python%3A3.7.3-alpine3.9/vulnerabilities" \
  | jq .
{
  "Count": 2,
  "Vulnerabilities": [
    {
      "Description": "SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-of-bound read in the rtreenode() function when handling invalid rtree tables.",
      "FixedVersion": "3.28.0-r0",
      "InstalledVersion": "3.26.0-r3",
      "PkgName": "sqlite",
      "References": [
        "https://www.sqlite.org/releaselog/3_28_0.html",
        "https://www.sqlite.org/src/info/90acdbfce9c08858",
        "https://security.netapp.com/advisory/ntap-20190606-0002/",
        "https://usn.ubuntu.com/4004-1/",
        "https://usn.ubuntu.com/4004-2/"
      ],
      "Severity": "HIGH",
      "VulnerabilityID": "CVE-2019-8457"
    },
    {
      "Description": "An exploitable use after free vulnerability exists in the window function functionality of Sqlite3 3.26.0. A specially crafted SQL command can cause a use after free vulnerability, potentially resulting in remote code execution. An attacker can send a malicious SQL command to trigger this vulnerability.",
      "FixedVersion": "3.28.0-r0",
      "InstalledVersion": "3.26.0-r3",
      "PkgName": "sqlite",
      "References": [
        "http://packetstormsecurity.com/files/152809/Sqlite3-Window-Function-Remote-Code-Execution.html",
        "http://www.securityfocus.com/bid/108294",
        "https://security.netapp.com/advisory/ntap-20190521-0001/",
        "https://talosintelligence.com/vulnerability_reports/TALOS-2019-0777"
      ],
      "Severity": "MEDIUM",
      "VulnerabilityID": "CVE-2019-5018"
    }
  ]
}
curl -s -X GET -H 'Content-Type:application/json' \
  "http://${API_HOST}:9000/api/v1/images/python%3A3.4.10-alpine3.9/vulnerabilities" \
  | jq .
{
  "Count": 3,
  "Vulnerabilities": [
    {
      "Description": "ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input for every encryption operation. RFC 7539 specifies that the nonce value (IV) should be 96 bits (12 bytes). OpenSSL allows a variable nonce length and front pads the nonce with 0 bytes if it is less than 12 bytes. However it also incorrectly allows a nonce to be set of up to 16 bytes. In this case only the last 12 bytes are significant and any additional leading bytes are ignored. It is a requirement of using this cipher that nonce values are unique. Messages encrypted using a reused nonce value are susceptible to serious confidentiality and integrity attacks. If an application changes the default nonce length to be longer than 12 bytes and then makes a change to the leading bytes of the nonce expecting the new value to be a new unique nonce then such an application could inadvertently encrypt messages with a reused nonce. Additionally the ignored bytes in a long nonce are not covered by the integrity guarantee of this cipher. Any application that relies on the integrity of these ignored leading bytes of a long nonce may be further affected. Any OpenSSL internal use of this cipher, including in SSL/TLS, is safe because no such use sets such a long nonce value. However user applications that use this cipher directly and set a non-default nonce length to be longer than 12 bytes may be vulnerable. OpenSSL versions 1.1.1 and 1.1.0 are affected by this issue. Due to the limited scope of affected deployments this has been assessed as low severity and therefore we are not creating new releases at this time. Fixed in OpenSSL 1.1.1c (Affected 1.1.1-1.1.1b). Fixed in OpenSSL 1.1.0k (Affected 1.1.0-1.1.0j).",
      "FixedVersion": "1.1.1b-r1",
      "InstalledVersion": "1.1.1a-r1",
      "PkgName": "openssl",
      "References": [
        "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=ee22257b1418438ebaf54df98af4e24f494d1809",
        "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=f426625b6ae9a7831010750490a5f0ad689c5ba3",
        "https://www.openssl.org/news/secadv/20190306.txt"
      ],
      "Severity": "MEDIUM",
      "Title": "openssl: ChaCha20-Poly1305 with long nonces",
      "VulnerabilityID": "CVE-2019-1543"
    },
    {
      "Description": "SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-of-bound read in the rtreenode() function when handling invalid rtree tables.",
      "FixedVersion": "3.28.0-r0",
      "InstalledVersion": "3.26.0-r3",
      "PkgName": "sqlite",
      "References": [
        "https://security.netapp.com/advisory/ntap-20190606-0002/",
        "https://usn.ubuntu.com/4004-1/",
        "https://usn.ubuntu.com/4004-2/",
        "https://www.sqlite.org/releaselog/3_28_0.html",
        "https://www.sqlite.org/src/info/90acdbfce9c08858"
      ],
      "Severity": "HIGH",
      "VulnerabilityID": "CVE-2019-8457"
    },
    {
      "Description": "An exploitable use after free vulnerability exists in the window function functionality of Sqlite3 3.26.0. A specially crafted SQL command can cause a use after free vulnerability, potentially resulting in remote code execution. An attacker can send a malicious SQL command to trigger this vulnerability.",
      "FixedVersion": "3.28.0-r0",
      "InstalledVersion": "3.26.0-r3",
      "PkgName": "sqlite",
      "References": [
        "http://packetstormsecurity.com/files/152809/Sqlite3-Window-Function-Remote-Code-Execution.html",
        "http://www.securityfocus.com/bid/108294",
        "https://security.netapp.com/advisory/ntap-20190521-0001/",
        "https://talosintelligence.com/vulnerability_reports/TALOS-2019-0777"
      ],
      "Severity": "MEDIUM",
      "VulnerabilityID": "CVE-2019-5018"
    }
  ]
}
  • python:3.7.3-alpine3.9で検出された脆弱性
    • CVE-2019-8457
    • CVE-2019-5018
  • python:3.4.10-alpine3.9で検出された脆弱性
    • CVE-2019-1543
    • CVE-2019-8457
    • CVE-2019-5018
  • CVE-2019-8457CVE-2019-5018に関しては2019/05に出ているやつなので両方で検出されているのかな
  • おそらくここのハンズオンで差を出したかったのはCVE-2019-1543
  • python:3.8.0b1-alpine3.9にしたらゼロ件でした
curl -s -X GET -H 'Content-Type:application/json' \
  "http://${API_HOST}:9000/api/v1/images/python%3A3.8.0b1-alpine3.9/vulnerabilities" \
  | jq .
{
  "Count": 0,
  "Vulnerabilities": []
}

CIにおけるリリース判定

  • CI中に脆弱性が出たらリリースを停止したい
  • exit codeや応答値を見て処理が停止するように書くことができる
docker run --rm \
      -e CLAIR_ADDR="http://${API_HOST}:6060" \
      supinf/klar:2.4 envoyproxy/envoy:v1.10.0 \
      | jq ".Vulnerabilities | length"
1
curl -s -X GET -H 'Content-Type:application/json' \
  "http://${API_HOST}:9000/api/v1/images/python%3A3.4.10-alpine3.9/vulnerabilities?skip-update=yes" \
  | jq -r ".Count"
3

まとめ

  • 「このツールならすべての脆弱性をチェックできる」というのは無さそう
  • Dockerイメージごとに得意分野が異なってる
  • 公式イメージの最新であっても脆弱性が入っている可能性がままある

感想

  • まだDockerfileを書くのもままならない状態なので、脆弱性というところまで頭が回っていない
  • しかしインターネットに公開するのであれば脆弱性チェックはしっかりやって置かないと行けないと感じた
  • ただ、そのリリースサイクルに追いついていけるかが自信ない・・・

終わりに

  • アウトプットにだいぶ時間が掛かってしまいましたが、ハンズオンの裏には膨大な情報があることがよくわかりました。
  • 噛めば噛むほど味がでる、とてもよいコンテンツです。
  • 次回も是非参加したいですね!抽選漏れてもハンズオンはやるぞ!!!

6/5は俺がネカマを始めた日

本日6/5は「俺がネカマを始めた日」です。
Googleアカウントの一つの誕生日が6/5になっています。
毎年Googleさんが「お誕生日おめでとう!」と通知してきます。

何を言い出すんだこいつ?という感じなので順を追って説明していきます。
かなり雑に書いているので意味不明かも。
ツッコミお待ちしております。

前提となる話(FF11について)

2002年にFF11というオンラインゲームを始めました。
当時はYahoo!ADSLがはじまった時期でもあり、時間を気にすること無くADSLでインターネットを使えるようになった時期でした。
(それまでは11〜6時のテレホーダイ時間だけPSOをやったり・・・)

このFF11にどっぷりハマり、仕事は最低限、定時で帰ってプライベートはすべてFF11の生活をしていました。
名前は「Kazi」
ただ、Kajiという名前が取れなくて「j」を「z」にしただけです

初めてのMMORPGで、刺激の多い毎日でした。 

  • 知らない人からケアルを掛けてもらって生き延びたこと
  • そのままその知らない人と、次の街を目指してパーティを組んだこと
  • 黒魔道士二人で、敵を挟んで魔法打ちまくって経験値稼いだこと
  • Kaziという名前なので「鍛冶」を始め、その時レアだった武器の素材となるインゴットを作って大儲けしたこと
  • 誰もやらなかった「吟遊詩人」というジョブをやっていて、「実は支援能力がダントツでパーティにいると効率が最大化する存在」というのがわかってから毎日DMの嵐だったこと

それまでやっていたゲームと違って、「相手が人間」というのがとても大きかったと思います。
ちなみにFF11のせいで仕事を辞めた人も多数いましたね。

パーティプレイをした

FF11は基本パーティで行動するゲームです。
レベルが低いうちはソロでもなんとかなりますが、ある程度のレベルになるとパーティを組んで戦ったほうが効率が良くなります。
前衛3人、後衛2人、支援1人、みたいな。
具体的に言うと、
戦士、モンク、シーフ、黒魔道士、白魔道士、吟遊詩人みたいな感じです。
パーティを組んでレベル上げをしたり、強敵を戦ったりしていました。
時には時間を忘れてプレイし「寝落ち」をするプレイヤーもいました。
しかし俺はSESで日常的にある「日勤→夜勤→日勤」で鍛えられていたので最後まで起きているときが多かったです。

ギルドを作った

そしてそのうち「Dynamis」という大規模コンテンツが実装されます。
これは最大64人のプレイヤーで攻略するコンテンツです。

しかし制限も多く、

  • LV65以上
  • 入れるのは1団体まで
  • 攻略するのに最大3時間掛かる

という感じでした。

かなり厳しい条件です。
通常のサラリーマンプレイヤーも帰宅後に3時間以上の拘束と、64人もの人数を集めるのはかなり難しい感じでした。
条件が厳しいせいで、プレイできるのは一部のプレイヤー(NE○T)のみという状況です。

その時、仲の良かったプレイヤーがふと発した一言
「サラリーマンばっかり集中的に集めたら攻略できるんじゃないの?」

これを機に「サラリーマンの力を見せてやれ!」をスローガンに「サラリーマンプレイヤー集め」が始まります。
仲の良いプレイヤー繋がりで「大規模コンテンツやりたいけど仕事があってやれない」サラリーマンを集めていきました。
ありがたいことに、あっという間に64人以上集まりました。
フレンドの力が強かったと思います。
最大100人以上いたかな・・・

大規模コンテンツ(Dynamis)に挑戦しだした

集まったら集ったで、個々のスケジュール管理をしないといけなくなり、最初はメールとExcelを使って管理をしていました。
SESで鍛えられたExcel力を発揮する時です。

当日の業務状況などでドタキャンが日常的に発生する中、各人のジョブを把握して最適なパーティ構成を考えていました。
64人で攻略するので、6人のパーティが10組+4名できる想定です。
最初は統率が取れず全滅ばかりでしたが、何度もトライアンドエラーを繰り返していくうちに確実にギルドは強くなっていきました。

当初は、俺が全体の構成と攻略方法をすべて検討・指示していましたが、何度かプレイしているうちにメンバーから様々な意見が出てきました。

  • 個別に動けるパーティは、そのパーティの判断で動いたほうがよい
  • 攻撃魔法で一斉に攻撃するときは、黒魔道士になれた人が指揮を取ったほうが良い
  • 盾役は死にやすいので、回復魔法を使える人を集中したほうが良い

上は50代のおっさんから、下は10代の若者まで様々な意見をもらえました。
意見をもらってから、自分一人で考えるのではなく「ある程度任せた方が効率もよいし、何よりいろんな人間模様が見れて面白い」ということに気づきます。

それからはもらった意見をどんどん取り込んで行きました。
魔法で攻撃したほうが楽な場合は黒魔道士ばかりを集めたパーティを組みます。
通常戦闘のようバランスの取れたパーティが良い場合は、前衛と後衛を組み合わせたパーティを組み合わせます。

全体が強くなるし、自分の管理コストも下がるし、やっぱ画面の向こう側に人間がいると面白い
そのうち、最低限の構成と方針だけ出してあとはメンバーの行動に任せるようにしていました。

このころになると、俺自身のキャラの性能はどうでもよくなってくる場面が多く、「以下に早くタイピングで指示が出せるか」が重要になっていました。

寄生獣で言うと「体細胞に指揮を出すので精一杯で変形しない頭部分の後藤さん」です。

そのうち余裕が出てくると「Kaziが死んだら負け」みたいなゲームになっていきます。
(死んでてもチャットできるから関係ないんだけど)

メンバーがどんどん強くなっていき、俺のキャラはただ指揮を出すだけの状態になってました。
それが加速していき、俺の方は「如何にしてメンバーを全滅させるか」という域までいってました
だってみんな強くなりすぎなんだよ・・・

飽きた

ある程度攻略ができるようになったのと、現実世界で結婚することになったので大規模コンテンツをやめました。
またメンバーが強くなったのと「自分の力だけでなんとか攻略する」というのをやりたくなったのもあります。
その頃ペルソナとDARKSOULSをやってました。
自分だけで攻略するのも楽しいですね。

FF11やめる

大規模コンテンツをやめたあとホソボソとプレイしていましたが、MMORPG特有の長時間拘束が現実的に厳しくなり、また東日本大震災があったのでFF11自体のプレイを辞めました。
この時、高校生時代の友人のSくん(重要)が他のサーバから移転してきたので、ちょっと一緒に遊んだりしていましたが、プレイスタイルが合わないためだんだん遊ばなくなっていきました。

復帰

FF11をやめて数年後も、友人のSくんがまだFF11を続けてることを知ります。
俺も懐かしさと新コンテンツをやってみたさにFF11に復帰しました。
レベルが99まで緩和されており、いろんな選択肢が増えていましたが以前やっていた以上に「NE○T有利」の状況でした。
その頃子供も生まれていたので十分な時間が取れず、基本大規模コンテンツには参加せず、ソロでやれることばかりやっていました。
友人のSくんとは飲み会で話したりしながらたまにプレイしましたが、やはりプレイスタイルが合わないため遊びませんでした。
友人のSくんはパーティ効率とか装備の性能を重視しているツマラナイ男です。データなのに。

ここからが本題

長々と書いてしまいましたがここからが本題です。
通常プレイに飽きてしまった俺は、つまらんプレイをする友人のSくんにドッキリを仕掛けようと思います。

それが2014年6月5日です。
思いついたドッキリの内容は、

  • ネカマキャラを作って
  • 友人のSくんに近づいて
  • 魅了してゲーム内通貨を貢がせよう

でした。

ちなみに友人のSくんは高校時代からの友人です。
よくtwitterで書いている飲み会七英雄の一人です。

思いついたが吉日、即刻gmailアカウントを作りました。
アカウント大事。それっぽいメアドです。
誕生日も年齢も設定します。
このメアドを今でも使ってます。これが冒頭の誕生日通知です。

FF11でもアカウントを作ります。
キャラ名どうしようか・・・
眼の前に空気清浄機があります。
そこに「Nanoe」と書いてあります。

「なのちゃん」みたいにいけるのでは・・・・?
名前は「Nanoe」に決定!!

外堀を埋めていく

FF11内に「Nanoe」ちゃんが爆誕しましたが、友人のSくんに近づくにはいくつかのハードルがあります。

  • レベルが低すぎて一緒に遊べない
  • 数あるギルドの中で、友人のSくんがいるギルド(もともと俺が作ったやつ)に潜入しないといけない
  • 女性だと認識されないといけない
  • 友人のSくんが「ゲーム内通貨を貢ぎたい」と思わせるようにしないといけない

流石に一人では無理なので協力者を集めました。
俺がFF11を辞めたあともプレイしているプレイヤーにメールや電話を行い、今回の趣旨を伝えます。
皆、快く受けてくれました

何度かMTGを重ね、偶然を装ってギルドに潜入します。
またレベルも不自然にあげないように工夫します。
ただ、ゲーム内通貨を稼ぐ時間が取れなかったので、協力者に500万ギルくらい寄付してもらいました。
(みんなありがとう!)

ごく自然にギルドに潜入し(俺が作ったギルドだけど)、友人のSくんが貢ぎたいと思うような、頑張っている女性を演じます。
あ、友人のSくんの名前は「Tukiumi」と言います。
Luna Seaが好きなんでこの名前です。寒いですね。

この頃、俺のギルドは友人のSくんが引き継いでリーダーをやっていました。
何勝手にリーダーやってんだよ!!!誰がオメーに引き継ぐって言ったんだ?!?!
それはさておき、ある程度ギルド内で交流をし、「頑張ってるNanoeちゃん」を演じ続けました。
友人のSくんは全然気づく素振りがないので、だんだん遊び始めます

f:id:Anorlondo448:20190605004609j:plain f:id:Anorlondo448:20190605004745j:plain

<Tukiumi>  なのさん、一言いわせておくれ
<Nanoe(俺)> いま闇王の部屋に入っちゃったからちょっとまってーー!!
<Tukiumi>  ほい^^;;;
...
<Nanoe(俺)> そういえば、リーダーさっき何か良いかけていませんでしたっけー??
<Tukiumi>  忘れてもうた^^
<Nanoe(俺)> 一言いいたいことがあるとかなんとかーw
<Tukiumi>  思い出したら言うね〜^^
<Nanoe(俺)> ごめーん!エリアチェンジしてて見えなかった
<Tukiumi>  思い出したら言う〜〜^^
<Nanoe(俺)> って言いながらエリアチェンジ

どう見ても俺がやりそうなことなのに友人のSくんは一向に気づきません。
そしてアイテムにがめつい友人のSくんに対して当てつけのようなプレイスタイルを取ります。

f:id:Anorlondo448:20190605005951j:plain

<Nanoe(俺)> あいてむより みんなと遊ぶ時間が大事なものなのよ

さらに「レアアイテムを持っていないプレイヤーと遊ばない」というクソみたいな考えを持つ友人のSくんにあてつけるような行動を繰り返します
(アナイア:アナイアレーター、狩人というジョブに取って最強に近い武器)

f:id:Anorlondo448:20190605010201j:plain

「お前は、人ではなくて『武器を持っているやつ』と遊びたいの?」みたいな煽りです。
ただ煽りすぎて怒ってしまったようです

f:id:Anorlondo448:20190605010409j:plain

<Nanoe(俺)> リーダーってホントRMEにしか興味がないのねー
<Tukiumi> そんな言い方しなくてもいいじゃない^^

RME:簡単に言うとレア武器郡
怒った素振りにもわざわざ「^^」をつけるのが気持ち悪いですね。

貢がせ

最初は、友人のSくんからゲーム内通貨を貢がせる目的でしたが、友人のSくんのクソっぷりに「おめーなんか居なくても一人で十分遊べるんだよ」というプレイスタイルになってしまいました。

ある時友人のSくんから100万ギル送られてきたことが有りました。
が、あえて「あなたの力は借りずに、自分の力だけでみんなと遊べるようになってやるわ」みたいに返しました。
ここまで来ると友人のSくんに何か恵んでもらうこと自体が気持ち悪い感じになってましたね
「ギルドメンバー全体の戦力アップが〜〜」とか宣う友人のSくんに当てつける行動は今後も加速していきました。

終末

友人のSくんへのあてつけ行動も、ネカマもそろそろ飽きてきたのでネタバレしようかと思いました。
ネタバレの場はオフ会。

Nanoeちゃんはお酒大好き設定なので「オフでお酒飲みながらFF11の話をしたい!」みたいな流れでオフ会を仕込みます。
ここもすぐにオフ会をやるのでなく「お酒が好き」みたいな流れから徐々に浸透させていきました。
ココらへんの自然な振る舞いは自分でも凄いなと思います。

そして当日、俺もギルドのOBとして参加します。
「Nanoeちゃんは用事があって遅れてくる」設定を仕込んでおきます。

Nanoeちゃんの到着まで時間が掛かるということで、先に乾杯をします。
その時に協力者の一人が「それでは乾杯の音頭はNanoeちゃんにやってもらいましょう!」と言って俺に振りました。

ここでネタバレです。
6ヶ月におよぶドッキリを成功させました。
飲み会では友人のSくんが如何にクソかについて、みなで楽しく話しましたとさ。
そして今も、この「Nanoeちゃん」用につくったGmailアカウントを使い続けています。(connpassとか・・・)

毎年6/5になると思い出す楽しい思い出です

まとめ

ドッキリは面白い たぶん、俺の最大の特性は「ドッキリ仕掛け人」

JAWS-UG コンテナ支部 入門編 #6 コンテナの始め方 後編②(Clairで脆弱性スキャン)

後編②とは

概要

  • ClairとTrivyをECSで動かして、dockerイメージの脆弱性をチェックする(今回はClair)
    • ローカル、ECRにpushしたイメージをチェックする
  • ハンズオン資料はGithubに公開されており、AWSアカウントがあれば誰でも実施することができます。ぜひ手を動かしてみることをお勧めします

資料のリンク

まえがき

  • Clair
  • Klar
  • ClairとKlarを使ってenvoy-alpineのイメージのスキャンを実行する
    • 緊急度をパラメータ指定して同じイメージをスキャンし、結果を比較する
  • ECS上にClair と Trivyを起動
    • ローカルや CI 環境上から、そのサーバーを利用してコンテナの脆弱性を診断
  • イメージを格納するS3作成
  • CloudFormationで環境作成
  • このハンズオンのコンテナイメージは、可用性を求めていないのでアンチパターンになっている
    • 同じイメージにPostgreSQLが入っている

Clairで一般Dockerイメージのスキャン

docker run --rm \
  -e CLAIR_ADDR="http://${API_HOST}:6060" \
  supinf/klar:2.4 envoyproxy/envoy-alpine:v1.10.0 | jq .

{
  "LayerCount": 6,
  "Vulnerabilities": {}
}
  • "Vulnerabilities": {}ってことは脆弱性はゼロ
  • 緊急度をあげてやってみるが同じ結果だった
docker run --rm \
  -e CLAIR_ADDR="http://${API_HOST}:6060" -e CLAIR_OUTPUT=Medium \
  supinf/klar:2.4 envoyproxy/envoy-alpine:v1.10.0 | jq .

{
  "LayerCount": 6,
  "Vulnerabilities": {}
}

脆弱性のあるイメージで、緊急度をMEDIUMにして実行

docker run --rm \
  -e CLAIR_ADDR="http://${API_HOST}:6060" -e CLAIR_OUTPUT=Medium \
  supinf/klar:2.4 envoyproxy/envoy:v1.10.0 | jq .

{
  "LayerCount": 9,
  "Vulnerabilities": {}
}
  • あれ?脆弱性でない?!
  • と思ったら以下の注意書きが・・・
脆弱性 0 件でしたか??
とすると、それは脆弱性データベースがバックエンドで作成中だからです。
30 分ほどしてから再度試してみてください。
  • さすがフォローが熱い!筋トレして待とう
  • そしてちょっとまって再実行したらメッチャ出た!
{
  "LayerCount": 9,
  "Vulnerabilities": {
    "Medium": [
      {
        "Name": "CVE-2018-20839",
        "NamespaceName": "ubuntu:16.04",
        "Description": "systemd 242 changes the VT1 mode upon a logout, which allows attackers to read cleartext passwords in certain circumstances, such as watching a shutdown, or using Ctrl-Alt-F1 and Ctrl-Alt-F2. This occurs because the KDGKBMODE (aka current keyboard mode) check is mishandled.",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-20839",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 5,
              "Vectors": "AV:N/AC:L/Au:N/C:P/I:N"
            }
          }
        },
        "FeatureName": "systemd",
        "FeatureVersion": "229-4ubuntu21.19"
      },
      {
        "Name": "CVE-2019-3842",
        "NamespaceName": "ubuntu:16.04",
        "Description": "In systemd before v242-rc4, it was discovered that pam_systemd does not properly sanitize the environment before using the XDG_SEAT variable. It is possible for an attacker, in some particular configurations, to set a XDG_SEAT environment variable which allows for commands to be checked against polkit policies using the \"allow_active\" element rather than \"allow_any\".",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-3842",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 4.4,
              "Vectors": "AV:L/AC:M/Au:N/C:P/I:P"
            }
          }
        },
        "FixedBy": "229-4ubuntu21.21",
        "FeatureName": "systemd",
        "FeatureVersion": "229-4ubuntu21.19"
      },
      {
        "Name": "CVE-2009-5155",
        "NamespaceName": "ubuntu:16.04",
        "Description": "In the GNU C Library (aka glibc or libc6) before 2.28, parse_reg_exp in posix/regcomp.c misparses alternatives, which allows attackers to cause a denial of service (assertion failure and application exit) or trigger an incorrect result by attempting a regular-expression match.",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2009-5155",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 5,
              "Vectors": "AV:N/AC:L/Au:N/C:N/I:N"
            }
          }
        },
        "FeatureName": "glibc",
        "FeatureVersion": "2.23-0ubuntu11"
      },
      {
        "Name": "CVE-2018-6485",
        "NamespaceName": "ubuntu:16.04",
        "Description": "An integer overflow in the implementation of the posix_memalign in memalign functions in the GNU C Library (aka glibc or libc6) 2.26 and earlier could cause these functions to return a pointer to a heap area that is too small, potentially leading to heap corruption.",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-6485",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 7.5,
              "Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
            }
          }
        },
        "FeatureName": "glibc",
        "FeatureVersion": "2.23-0ubuntu11"
      },
      {
        "Name": "CVE-2019-8457",
        "NamespaceName": "ubuntu:16.04",
        "Description": "(SQLite3 from 3.6.0 to and including 3.27.2 is vulnerable to heap out-o ...)",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-8457",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 7.5,
              "Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
            }
          }
        },
        "FeatureName": "db5.3",
        "FeatureVersion": "5.3.28-11ubuntu0.1"
      },
      {
        "Name": "CVE-2019-9893",
        "NamespaceName": "ubuntu:16.04",
        "Description": "libseccomp before 2.4.0 did not correctly generate 64-bit syscall argument comparisons using the arithmetic operators (LT, GT, LE, GE), which might able to lead to bypassing seccomp filters and potential privilege escalations.",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-9893",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 7.5,
              "Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
            }
          }
        },
        "FixedBy": "2.4.1-0ubuntu0.16.04.2",
        "FeatureName": "libseccomp",
        "FeatureVersion": "2.3.1-2.1ubuntu2~16.04.1"
      },
      {
        "Name": "CVE-2016-1585",
        "NamespaceName": "ubuntu:16.04",
        "Description": "In all versions of AppArmor mount rules are accidentally widened when compiled.",
        "Link": "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2016-1585",
        "Severity": "Medium",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 7.5,
              "Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
            }
          }
        },
        "FeatureName": "apparmor",
        "FeatureVersion": "2.10.95-0ubuntu2.10"
      }
    ]
  }
}

ECRにおいたDockerイメージをスキャンしてみる

  • 脆弱性チェックが、AWSマネージドサービスで提供されていないのでこのような手法でやったほうがよいのかも
  • このハンズオンは各サービスや共通でもサーバを立てて脆弱性スキャンをする想定としている
  • ECRに、ハンズオンで使用しているイメージをpushして脆弱性スキャンをかける
docker run --rm \
  -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_DEFAULT_REGION \
  -e CLAIR_ADDR="http://${API_HOST}:6060" -e CLAIR_OUTPUT=Low \
  supinf/klar:2.4 ${image_name} | jq .

{
  "LayerCount": 20,
  "Vulnerabilities": {
    "High": [
      {
        "Name": "CVE-2016-4074",
        "NamespaceName": "alpine:v3.9",
        "Link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4074",
        "Severity": "High",
        "Metadata": {
          "NVD": {
            "CVSSv2": {
              "Score": 7.8,
              "Vectors": "AV:N/AC:L/Au:N/C:N/I:N"
            }
          }
        },
        "FixedBy": "1.6_rc1-r0",
        "FeatureName": "jq",
        "FeatureVersion": "1.6-r0"
      }
    ]
  }
}
  • alpine:v3.9のCVE-2016-4074が出た
  • jpの脆弱性かな?
  • このハンズオンの場合はリモートからJSONが送られることは無さそうだから大丈夫・・・?

次回

  • Trivyで同じ脆弱性をチェックしてみる!

JAWS-UG コンテナ支部 入門編 #6 コンテナの始め方 後編①

後編①とは

資料のリンク


ハンズオンの概要

ハンズオン環境の起動

  • さらっとコマンドを実行すれば環境が起動するのだが、「どのようにして起動するのか?」というのが気になったので調べる!(コンテナ便利すぎる)
1. アクセスキーをそれぞれ変数に設定します
  • これはいつもdirenvで設定しているのでOK
    • direnvを知らないと人生の半分を損している
  • ローカルPCからawscliで、AWS上のS3やCloudFormationを使うためのアクセスキー/シークレットキーの設定
2. ハンズオン環境の設定置き場を作ります
$ docker volume create scan-images
  • 設定の置き場・・・?
  • コンテナは使い捨てなので、設定などを永続化しておくボリュームをdocker volumeコマンドで作るっぽい
3. ハンズオン環境を起動します
$ docker run --rm -it -e AWS_DEFAULT_REGION=ap-northeast-1 \
     -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_DEFAULT_PROFILE \
     -v /var/run/docker.sock:/var/run/docker.sock \
     -v scan-images:/root/config \
     -v $HOME/.aws:/root/.aws \
     -p 8080:8080 jawsug/container:scan-images-fixed
  • docker run:コンテナ起動
  • オプション関連は公式のリファレンスを見ると良さそう
  • --rm:コンテナの終了時に自動的にコンテナをクリーンアップし、ファイルシステムを削除する
    • デフォルトではコンテナを終了してもコンテナのファイルシステムの内容を保持し続ける
    • 短い期間だけフォアグラウンドで動かす場合に適したオプション
  • -it:コンテナのプロセスに対してttyを割り当てる(簡単に言うとdocker内にログインして操作できる)
    • -i:標準入力を開き続ける
    • -t疑似ttyを割り当てる
  • -e:環境変数の組み合わせ
    • AWSのリージョン情報/アクセスキー/シークレットキー/プロファイル情報を、ローカルPCの環境変数から取得してDockerの環境変数としてセット
  • -v:共有ファイルシステム(VOLUME)
    • ホスト側のディレクトリ:コンテナ側のディレクトリでマウントを作成
    • /var/run/docker.sockをコンテナ内で操作できるようにする・・・?
    • scan-images:/root/config:コンテナ内の/root/configを共有VOLUMEに永続化しておく
    • $HOME/.aws:/root/.aws:ホストマシンのAWSクレデンシャル情報をコンテナ内に設定
      • コンテナ内からCloudFormationなどを操作するため
  • -p:ホストマシンとコンテナのポートのマッピング
    • コンテナが8080ポートで受けているのでホスト側の8080とマッピング
  • jawsug/container:scan-images-fixed

ついでにDockerfileを見てみる

FROM docker:18.06.0-ce-dind
  • FROM:コンテナのベースとなるイメージ
  • Dockerインストール済みのコンテナ
  • コンテナからコンテナを操作する
  • dindは「Docker in Docker」の略
ENV AWSCLI_VERSION=1.15.66 \
    JUPYTER_VERSION=1.0.0
  • AWS CLIとJUPYTERのバージョンの指定
RUN apk --no-cache add python3 git
  • Python3とGitのインストール
  • --no-cacheで不要なファイルを削除できる(イメージを小さくするため)

AWS CLIをインストールするレイヤ

# Install AWS CLI
RUN apk --no-cache add groff less jq \
 && apk --no-cache add --virtual build-deps py3-pip \
  • &&ワンライナーにしているのはイメージのレイヤーを少なくして、イメージの容量を減らすため
    • 複数行でコマンドを実行するとそれごとにレイヤーができる(=イメージの容量が増える)
  • AWSを操作するためのawscliのインストール
  • 前提として以下をインストール

    • groff
      • 文書整形を行う
    • less
      • テキストを1画面ずつ表示する
      • helpコマンドを打った時に必要になるらしい(後述の @pottava さんのtweet参照)
    • jq
      • JSONデータの整形
    • py3-pip
      • --virtual build-deps py3-pip
        • py3-pipbuild-depsという仮の名前でインストールしておく
        • あとでこの仮の名前で削除するため
      • py3-pipはPython3用のpip
  • groffやlessはAWS CLIが依存しているライブラリ

 && pip3 install "awscli == ${AWSCLI_VERSION}" \
 && pip3 install yq \
  • pip3コマンドでawscliをインストール
  • pip3コマンドでyqをインストール
    • yqYAMLが使えるjqのラッパー
 && find / -type d -name \__pycache__ -depth -exec rm -rf {} \; \
 && rm -rf /root/.cache \
  • rootユーザのキャッシュの削除
 && apk del --purge -r build-deps
  • build-depsという仮の名前でインストールしたpy3-pipを削除
  • awscliが入ればpip3自体はいらない

Jupyter Notebookをインストールするレイヤ

RUN apk --no-cache add bash tini \

(脱線)Dockerのinit processについて

  • ここを参考にさせて頂きました!
  • Dockerで特に考慮せずにプロセスを実行するとエントリーポイントとして設定したプロセスがPID:1で起動する
    • PID:1はdocker stopなどでSIGTERMシグナルを送ってもプロセスが停止しないで一定時間後にSIGKILLで強制終了する
    • コンテナの停止に余計な時間がかかったり、graceful shutdownがされないなどの問題がある
  • Dockerで使用できてシグナルを適切に処理するinit用プロセスがtini
    • Docker 1.13以降は--initオプションでdocker runすることでtiniが実行される
 && apk --no-cache add --virtual build-deps build-base python3-dev \
  • python3-devpython拡張ライブラリ
  • --virtualで仮の名前を付与しているけど、どこにも使ってない・・・?
 && pip3 install "jupyter == ${JUPYTER_VERSION}" \
  • pip3コマンドでjupyterのインストール
 && pip3 install backcall bash_kernel \
 && python3 -m bash_kernel.install \
 && find / -type d -name tests -depth -exec rm -rf {} \; \
 && find / -type d -name \__pycache__ -depth -exec rm -rf {} \; \
 && rm -rf /root/.cache
  • キャッシュの削除など
  • testsってディレクトリがどっかで作られてるのか・・・?
  • 他プロジェクトからの横展開で消し忘れとのことでした

Gitの設定をするレイヤ

RUN git config --global credential.helper '!aws codecommit credential-helper $@' \
 && git config --global credential.UseHttpPath true
  • CodeCommitでGitの認証をする際に使用するAWSのプロファイル情報を設定する

Jupyter Notebookの設定

WORKDIR /root/notebook
ADD notebooks_config/jupyter_notebook.py /root/.jupyter/jupyter_notebook_config.py
ADD notebooks /root/notebook
ADD application /root/notebook/application
ADD infrastructure /root/notebook/infrastructure
  • Jupyter Notebookで必要なファイルなどを配置
ADD notebooks_config/entrypoint.sh /
RUN chmod +x /entrypoint.sh
  • エントリポイントの設定
VOLUME /root/config
  • /root/configでマウントポイントを作る
ENTRYPOINT ["/entrypoint.sh"]
CMD ["tini", "--", "jupyter", "notebook"]
  • tiniでコンテナ起動

まとめ

  • コンテナを作る時にtiniを使ってゾンビプロセスの生成を防いでいる、という手法があるのを知れた
  • また、コンテナ関係ないがコールバック関数の上書きなども勉強になった
  • しかしgroffやbackcall、yqなどをどこで使うのかがまだわかっていない(Jupter Notebook関係)
  • コンテナを通じてインフラを勉強するの良さそう

次回

# JAWS-UG コンテナ支部 入門編 #6 コンテナの始め方に参加しました!(前編)

前編とは

  • 内容が濃すぎたため、1回で書けませんでした・・・
  • 前編は@toriclsさんと@marnieさんのセッションについてアウトプットしたいと思います。
  • ハンズオンはまだちゃんと理解できていないので、理解した上で後編を書きたいと思います。

後編リンク

概要

  • JAWS-UG コンテナ支部 #6にブログ枠で参加させていただいたのでそのアウトプットです
  • 最初のセッションはJAWS-UG全7支部が参加して、目黒で流す@toriclsさんの動画を、他の支部へ中継するという形式でした(@toriclsさん自身はバルセロナにいたらしい)
  • @toriclsさんの動画は隅から隅まで素晴らしい内容でした
  • 全部書き出すより、動画が公開されたらそちらを見てもらうほうが良いと思うので、動画の中で特に自分に刺さったものを書いています
  • @marnieさんのLTの内容は自分の業務にかなり似ている構成だったのでいろいろお聞きしたかったけど、できなかったのが心残り・・・
  • ハンズオン資料はGithubに公開されており、AWSアカウントがあれば誰でも実施することができます。ぜひ手を動かしてみることをお勧めします

書いてる人

  • 事業会社のインフラ系の人
  • サービスでAWSを利用している
  • サービスの一部をコンテナ化しているが、まだ十分な知見はない
  • 社内でのコンテナ導入の温度はまだ低いため、どのようなケースでコンテナが役に立つのか模索中

資料のリンク

ハッシュタグ

#awsxon
#jawsug
#jawsug_ct

AWS Expert Online これからはじめるコンテナワークロード - コンテナ化ベストプラクティス - @toricls / Amazon Web Services

ゴール

- ローカルでdocker runから始まって、本番環境で運用するまでのフローを学ぶ
- コンテナを本番運用していくためのフローににマイルストンを置いてタスクをイメージできるようになる

コンテナ化について

- 「コンテナ化すること」を目的とせず、何を成し遂げたいのか、どんな問題を解決したいのかを考える
- そもそも本当にコンテナが必要か?
- マイクロサービス化はコンテナのユースケースの一つ
  • 「何でもコンテナに載せてしまえば良い」という考え方をせず、要件にあったサービスやツールを選択して、「それが何故良いのか?」という理由をしっかり理解した上で、現場に説明できる力がないとだめだなと思いました。
  • コンテナ化/マイクロサービス化、その他手法についても最適なソリューションを選択できるように学んでいかねば・・・!

コンテナの導入から運用まで

- コンテナ導入は既存ワークフローへ適用する方がやりやすい
- 新規プロジェクトだとあれこれ欲が出てしまう
- まず既存のワークフローを変えずにコンテナ化をしてみる
- トライアンドエラーを繰り返し、改善のイテレーションを回すことが近道
- うまくいかない場合はコンテナを消せば元通りという状況を維持する
- これまで使ったことがない技術の導入には成功までの道筋が必要
  - 組織や文化的な課題も入る場合がある
- ゴールまでのマイルストンを適切に配置する
  • てっきり「新規開発でパイプラインをしっかりつくって導入!」が良いと思ってました
  • 既存のリファクタリング的な感じで置き換えていくのは良いなと思いましたが、モノリス化してしまっている箇所にどうメスを入れるかは課題です
  • コンテナ化に関わらず、「文化」という面での課題も取り込んでいかないと全体的な最適化は難しいと感じました

コンテナ導入から運用までのステップ

- 1st Milestone
  - コンテナの特性とそれらが解決する課題を知る
  - コンテナ化
  - 手動でデプロイ
- 2nd Milestone
  - オーケストレータの特性と解決する課題を知る
  - 仮想マシンの家畜化
- 3rd Milestone
  - チーム開発のための開発環境構築、自動化、CI/CD
  - 運用を見据えたデザイン
- 社内・チーム教育
- システムとチームの成長を見据えたモダナイゼーションと最適化
  • 3rd Milestoneからやっていくつもりだったけど、利用者側からしたら「何か環境変わってよくわからないけど使う」みたいな意識になってしまいそう
  • 「与えられた環境を使う」ではなく、段階的に広めていく重要性を感じた
  • こちらを聞いて、実際に1st Milestoneをやってみようと思いました
  • 実際に社内でも「まずは手動で雑にコンテナ化してみて、どう使うのが良いのかを体感する」というのを始めてみました。

コンテナワークロードまとめ

- ゴールと道筋を明確にする
- はじめてのコンテナワークロードには既存アプリケーションがお勧め
- コンテナ化から本番導入まで、全てにおいてイテレーションを回す
- コンテナ化にあたっての作業量、チームメンバーのオンボーディングの考慮
  • 以下をしっかり意識しないといけないと思いました
    • まずコンテナ云々の前に、何をしたいのか
    • 現状とゴールとの距離はどれくらいあるのか
    • 現状の文化に適した形のワークフロー
    • 場合によっては文化を変えていく
    • コンテナ化を「与えられたもの」では無く「自分たちで考えた自分たちに取って最適なソリューション」となるような自発的なアクションを促していく

twitterに投稿されたQA

- 異なるインスタンスタイプのノードを用意するのはなぜ?
  - あるインスタンスが起動しなくなる可能性がゼロではない
  - ミックスしておくことで確実にキャパシティを確保しやすい
  - コンテナとか関係なく、それなりの規模のクラスタを運用するときはやっておくべき
  • t3/m5は人気で、Availability Zoneによっては起動しないことが多く、スパイクした時のスケールアウトのリスクヘッジとして色んなインスタンスタイプを用意しておいたほうが良さそうと感じた
  • ただ、アプリケーションの特性によってインスタンスタイプを用意(r系やc系)しておくことが多いので、どのように使い分けるかはアプリケーションの特性を考えないと行けないと思った

平成最後なのでEC2インフラからECS+Fargateに置き換えた話

発表者

  • Masashi Yamamotoさん(@marnie)
  • SRE at eureka

発表内容について思ったこと

  • 構成が弊社のものとかなり近かったので、弊社との違いなどについて書きます。
- AZと同じ人数しかいない
- Aが疲弊している
  • ap-northeast-1bが過去に居たのかな・・・?!
  • AZごとの疲弊度は都度監視しないといけないな・・・
- packer + ansibleで作成したGolden Imageをterraformで展開
  • 同じやり方だ!!!
  • ただ弊社がやっているのは、コードは別途Githubからpullしてくるパターン
- コンテナ化のきっかけ
  - 本番反映までのコスト
  - 割と肥大化してきたplaybook
  • 環境変数の反映などはコストが発生していたが、現在はSecret Managerから別途取得する方法に変更してコストを減らした
  • コードの反映は別途行っているのと、AWS側の変更が発生することがそんなに無いため、それほどコストでは無い
  • playbookのメンテナンスは確かにコストになるかも(ansibleのバージョンアップなど)
- ECS + Fargateを選択した理由
  - 起動速度や単純な価格面ではEC2 on ECS(+SpotFleet)の方が有利
  - チームの管掌領域が広いのでなるべく運用/管理するコストを減らしたい
  - 今の時点ではEKSよりECSの方が運用・AWS内の別コンポーネントとの連携が充実してきている
    - Dataplaneのマネージドがきて、いろいろ枯れてきたら・・・!
  • たしかに同じ判断でECS + Fargeteを検討していました
  • 弊社としてはログやメトリクス管理を一元化して運用コストや学習コストを下げたいと思ってDataDogを選択した
  • しかし、DataDog LogsがまだFargateからのログ転送に対応してないので、DataDogが対応するまでデータプレーンはEC2を選択しました
    • CloudWatch Logsからの転送はまた別途Lambdaとか必要なのでやめました
  • EKSも面白そうですが、まだECSの方がいろいろ楽な面が多いと思います。今はECSでコンテナオーケストレーションの知見を貯めよう
- docker imageの軽量化
  - アプリケーションコンテナに不要なものが含まれている
  • 「コンテナに入れなくて良いもの」をちゃんと切り出していかないと、ECRからのpullで課金が死ぬ
  • サービスを起動しっぱなしならまだ良いけど、スケールしたり単発のタスク実行の場合はdocker imageの容量はできるだけ少なくしていきたい
- ログ転送をコンテナの責務から取り外す
  • Kinesis Firehoseで転送できることを知りました
    • そもそもKinesisシリーズをよく知らず・・・
    • Associate認定で、使い所はざっくり知りましたが、具体的なユースケースをちゃんと知らないと選択肢が増えないな
  • サイドカーだけで全部完結できるようになると幸せ
- コンテナ=銀の弾丸ではない
  • コンテナはやりたいことを実現するための一つの手段、として考えなければ行けないなと思いました。
  • (コンテナ使ってみたいという欲望だけではダメ)

感想

  • 内容がたっぷり詰まった有意義な時間でした!
  • 特にtoriclsさんの動画は、これからコンテナを導入する人は必ず見たほうが良いと思います。(弊社内でも動画を共有しました)

次回

  • ハンズオンをじっくりやり、何をやっているかをしっかり理解した上でアウトプットしたいと思います。

AWS Certified Developer - Associate 受かったので振り返り

SAA受けた時の振り返り

AWS経験

  • 業務でAWSを触っているが、サーバレス関連はほとんど触ったことがない(知識だけ何となくある)
  • 1年くらい前まではインフラ開発としてやっていたが、最近はマネージャロールばかりやってて開発をほとんどしてません
  • チームメンバーが作ったAWSアーキテクチャの構成やパラメータをヒヤリングしながら、わからんポイントをまとめたりしています

受験時のスキル

  • 触ったことがあり、ある程度理解があるサービス
    • VPC/Subnet/RouteTable
    • InternetGateway/NatGateway
    • EC2/ELB/EIP/SecurityGroup/EBS
    • SQS/SNS
    • S3/RDS
    • Athena
    • SystemsManager
    • ECS
  • 知識だけあるサービス
    • lambda
    • APIGateway
    • StepFunctions
    • CloudTrail
    • CloudFront
    • CloudWatch
    • Config
    • ParametorStore/SecretsManager
    • CodePipeline/CodeBuild/CodeDeploy/CodeCommit
  • 全然わからんサービス
    • Cognito
    • DynamoDB
    • KMS
    • ElasticBeanStalk
    • Kinesis
    • IAM
    • CodeStar
    • X-Ray
    • SAM
    • CloudFormation

今回の受験

  • 前回のP○Iがひどかったので、別のテストセンターで申し込み
  • 銀座CBTS歌舞伎座 テストセンター
    • 「歌舞伎町」と勘違いして申し込んでしまったらアタリだった
    • 環境は良いし対応も良いし駅直結で便利だし最高のテストセンターだった!
    • 銀座駅から歌舞伎座タワーB2Fに直結で、更に無料Wifi有りのPRONTOもあったので事前の復習も捗った!

前回との違い

  • 会場が綺麗
  • 会場に到着して手続きしたら即受験開始できた
  • リモート試験官は今回は無かった。PCに座って認証したらすぐスタート
  • 「試験中に顔や口を触らない」という制約なし

受験時間

  • 130分だけど、55分で完了
  • 最後見直した時点で正解がわかったのが45/65(69%)だったけど、残り20個はこれ以上考えてもわからないやつだったので諦めて完了した

結果

  • 826/1000(720で合格)

勉強方法

  • AWS認定デベロッパー - アソシエイトのページから試験ガイドをダウンロードしてホワイトペーパーを読む
    • 文字を読むのが苦手かつ、ただ読んでも頭に入ってこないので途中で断念
  • WHIZLABSで有料問題集($20くらい)を買う
    • 全部の問題を2週
    • 問題で出てきた箇所について深く調べていく
    • 試験範囲を網羅的に出してくるのでよかった
    • 問題と回答を丸暗記してしまいがちだが、それだと本番に通用しないので回答をどう導くかを考える力をつけるのが重要

勉強時間

  • 10時間くらいだと思う

特典

  • なんかDevelopers.IO感があるロゴ f:id:Anorlondo448:20190506221642p:plain
  • 次の試験が半額になるバウチャー
  • レーニングバウチャーなど

感想

  • 知識はあるが触ったことがないAWSサービスが結構出て、ちゃんと手を動かさないとだめだなと思いました
  • まとまった勉強時間が取れないので子供を相手しながら問題解いていたけど、体を動かしながら覚えるのって結構良いのかもしれません
  • バウチャー出たので、SysOps Administrator - Associateも取るぞ!

KubernetesのSecretの値を修正する

まえがき

  • Kubernetes実践で勉強しているとき発生した事象について書いています。
  • Secretオブジェクトをtypoして登録しまい、どうやって修正したら良いかを調べていたらバルゴさん(@go_vargo)に助言頂いて解決できたのでまとめた記事になります。

スコープ

  • 作成済みのSecretの値を編集する方法

スコープ外

  • 以下は厳密に検証しておりません。
    • 修正後の反映タイミング
    • Podの動き
  • こちらの方のブログが詳しいと思います。
  • ConfigMapの修正
    • おそらくyamlで定義しているのでyaml修正してapplyすればよいかと思います。

概要

  • Secretオブジェクト作成
  • kubectlで編集

Secretオブジェクト作成

  • パスワードを表すキーがパッソワルドになってしまった!(マジでやったやつ)
$ kubectl create secret generic test-secret --from-literal=user=dbuser --from-literal=passowrd=dbpass
  • 確認
$ kubectl get secret test-secret -o yaml
apiVersion: v1
data:
  passowrd: ZGJwYXNz
  user: ZGJ1c2Vy
kind: Secret
metadata:
  creationTimestamp: "2019-03-30T03:49:58Z"
  name: test-secret
  namespace: default
  resourceVersion: "48786"
  selfLink: /api/v1/namespaces/default/secrets/test-secret
  uid: e39397ca-529e-11e9-8815-025000000001
type: Opaque

修正する

  • kubectl editで登録済みのyamlを直接編集する
$ kubectl edit secret test-secret
  1 # Please edit the object below. Lines beginning with a '#' will be ignored,
  2 # and an empty file will abort the edit. If an error occurs while saving this file will be
  3 # reopened with the relevant failures.
  4 #
  5 apiVersion: v1
  6 data:
  7   passowrd: ZGJwYXNz
  8   user: ZGJ1c2Vy
  9 kind: Secret
 10 metadata:
 11   creationTimestamp: "2019-03-30T03:49:58Z"
 12   name: test-secret
 13   namespace: default
 14   resourceVersion: "48786"
 15   selfLink: /api/v1/namespaces/default/secrets/test-secret
 16   uid: e39397ca-529e-11e9-8815-025000000001
 17 type: Opaque
  • passowrdpassword修正して保存(:wq)
  • kubectl get secret test-secret -o yaml で治ってることを確認する

まとめ

  • kubectl edit でSecretオブジェクトの直接編集ができる。
  • が、手で変更をした場合の変更管理とかは気をつけないといけなさそう。
  • 実際の運用では、直接直してしまうよりyamlを使って暗号化して管理、の方が良いかもしれない。
プライバシーポリシー