AWS SAA-C02合格記
2021年にとる予定だった、AWS-SAAを取りました。
勉強時間
ちゃんとやっていたのは、1ヶ月いかないくらい。
SAAの勉強をしようと思ってから、別のことに興味を持ちすぎてだらだらとしてしまったので時間がかかりました。
インプットは1週間くらいであとは試験対策をしていた感じです。
勉強方法
改訂新版 徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書[SAA-C02]対応を購入しました。
インプットの部分は全て飛ばして問題だけやって、間違えたら戻ってじっくり読むだけです。
AWSの経験があるのでほとんど読み飛ばしました。
模擬試験がダウンロード可能なのでそれがよかったです。
気をつけるところ
今は廃止されてます。ただ出てくることがあるみたいなので気をつけないといけないです。
選択肢に「キャパシティー予約されたオンデマンドインスタンス」がなければ正解になるのかな?
- Snowball
ただ大量データを転送するだけではなく、「エッジコンピューティング機能」があること。
サービス名くらいは知っていたのですが、snowballファミリーの使用経験がないので利用経験ないので実質初めて知るサービスとなりました。
Snowball Edge Compute Optimized というのが問題で出てくるとGPUを搭載されているので機械学習とかもできるとのこと。
実際に使ってみたいです。
感想
とにかく文章量が多いので疲れます。
試験時間が長いので何回も見直そう!と思っても疲労が先に来ます。心が折れます。
税抜で15000円かかっているので、その出費を痛む心に火が付けばできそうですが、私は結局1回見直した後、怪しい問題を見直すだけで終わりました。
和訳が怪しい問題は英語に戻すことができるので、英文で読むことをおすすめします。
AWSのサービス名は頭に入っているためセンター英語よりも簡単です。
次はDAVでもとろうかなと思ってます。
2021年振り返り
2022年にはいってしまったけど、2021年の振り返り。
プライベートでやったこと中心です。
— mutao (@mutao_net) October 22, 2021
1~3月
なんとなく自分のやりたいこととかをまとめていたりした。
マインドマップの書き方自体おかしいので、今見ると参考にならないものになってたし、変化があった部分もあった。
やりたいことをマインドマップで書いてみた pic.twitter.com/zjouvbSvrV
— mutao (@mutao_net) January 11, 2021
他にはラズベリーパイを購入して自宅にSSHできるCentOSな環境を整備してスクラップ&ビルドを繰り返したりもしていた。
インフラエンジニアっぽいことをしているのでその勉強ですね。
4~6月
SEOをちょっと噛みしながらラズベリーパイいじりをしていた。
https://mutaonet.hatenablog.com/archive/2021/5
このあたりから勉強へのモチベが高くなってきていて新しい領域に踏み出そうとかしていた。
インフラ領域に手を出してみたり、Go言語を勉強し始めていたり。
Githubの草もこのあたりから増えていった。
7~9月
仕事がめちゃくちゃ忙しくなる。
ひたすらAnsibleを書いたり、メトリクスの種類を色々と覚えてみたり。
SREについて本格的に考え始めたのもこのあたり。
SREの概念的なところはチームビルディング的なところでかじっていたりもしてました。
自宅ラズベリーパイにもGrafana/Prometheusな環境構築してみたりとか。
自分の市場価値が知りたくなって転職draftに応募なんかもしてました。
勇気を出して転職DRAFTにレジュメを出しました。
— mutao (@mutao_net) July 23, 2021
どこからも指名されなかったら泣きながら勉強します。
転職draftではSREやインフラエンジニアとしてのオファーが多かったので自分のスキルセットを見直したりもしました。
10 ~ 12月
引き続き多忙な毎日を過ごす。
大分前からかじり始めていたk8s関連を本格的に入門し始める。
CKA/CKAD取りたいです。
同じ流れでterraformも勉強していました。
とりあえず手を動かす。
— mutao (@mutao_net) October 27, 2021
詳細は公式ドキュメントと参考書があればそれでカバーしてみよう https://t.co/bon6suWykm
とりあえずローカルでapplyしてAWSで色々構築してdestroyしてみる感じです。
お仕事するにはまだまだといった感じなのでもっとがんばります。何より楽しい。
Githubにcommitしてますが、単に触ってみただけのものなのでちゃんとしたものはその内アウトプットとして出します。鋭意作成中。
MySQLにも興味がでてきました。ひたすら公式documentを読んだり、著名な方のスライドを読んで実践してみたり。
MySQLが好きになりそう。というか好きです #infrastudy
— mutao (@mutao_net) October 29, 2021
総括
色々なものに興味を持ち始めた年でした。その割にアウトプットは少ないのは反省です。
エンジニアとしてのキャリアをちゃんと考えたのも2021年でした。
2022年はもっとハードな年になりそうな気がしているのでインプットの量を増やすことと、アウトプットの品質を上げようと思います。
Flask+MySQLなローカル環境をDockerで構築する
Flask + MySQL なアプリケーションのローカル環境を作成する機会があったので残す。
作ったもの github.com
欲しかったもの
- ローカル環境に依存しないようにしたい。
- docker-compose up -d だけでローカル環境を整備したい。
- MySQL用のコンテナも作ってテストデータも入れ込みたい。
docker-compose.ymlの中身はこんな感じ
つまった所
FlaskコンテナとMySQLコンテナ間のアクセスがうまくいかない。
実はこれまでコンテナ間で通信するような環境を作ったことがなくてちょっと躓いた。
container_name: db_container build: ./mysql image: mysql:5.7 restart: always environment: MYSQL_DATABASE: test MYSQL_USER: user MYSQL_PASSWORD: pass ports: - 3309:3306
3309ポートにアクセスすればいけるだろと思ってました。
実際にlocalからの接続からは mysql -h localhost -u test -P 3309 -p
で問題なく見れました。
すっかり忘れていたのが Docker Networking です。
network
keyを使ってDocker Networkを構築しました。
MySQLコンテナへのアクセスはIPを明示的に指定して接続したりもできますが、コンテナ名でもできるので今回はコンテナ名を指定してアクセスするようにしてます。
基本的なことだけど使ってない知識は錆びるのでまた忘れたときようにメモ。
log4j2の脆弱性についてのポエム
災害レベルの脆弱性に出会ったので記念?に書く。
ゼロデイ脆弱性だし、日本は金曜日だし最悪なタイミングでした。
Base CVSS Score: 10.0 と文句なしの満点。
loggerにこのレベルの脆弱性があるとは考えもしてなかった。
私が気づいたのはluasec社のpost。というかそれが拡散されて届いた形になる。
2.0 <= Apache log4j <= 2.14.1 のバージョンで特定の文字列(jndi)を変数として置換(Lookup)することで任意のコードを実行できる。
log4j2が出力したログ全てが対象なので攻撃が容易。404でも500でもHTTPリクエストさえ通ってログに出力できればよい。
脆弱性が報告された段階では JVMの起動オプションに LOG4J_FORMAT_MSG_NO_LOOKUPS=true を追加する(2.10以降)みたいな対策が取られてました。
現在ではlog4j2 2.15.0が maven repositoryに上がっていて、バージョンアップが勧められてます。
log4j 1.xはどうなのか?
今回の脆弱性では影響は受けないみたいでした。というかそもそも別物。
ceki氏によると1.x系ではLookup機能が提供されていないため、変数ではなくそのまま文字列としてJMSに送られるとのこと。
ただ、すでにサポート終了しているし、下記のような脆弱性があるので許容している状態で危険。
// 2021/12/12追記
ceki氏も以下のようにコメントしています。
Here are some short comments on the CVE-2021-44228 log4j 2.x vulnerability.https://t.co/xiqLJmjglz
— ceki ${jndi:ldap://${log4j1:is}.not.log4j2/} (@ceki) December 11, 2021
jpcertでも脆弱性の報告上がっていました。
Tweetを見る限り、2021/11/21の15:00頃かな。
休日にjpcertが動く印象がないので少し驚きました。
Apache Log4jにおける脆弱性(CVE-2021-44228)に関する注意喚起を公開。すでに本脆弱性の悪用を試みる通信を確認しています。影響を受けるバージョンを使用している場合、速やかに対策実施をご検討ください。^TK https://t.co/4GWY0igeCM
— JPCERTコーディネーションセンター (@jpcert) 2021年12月11日
Twitter見てて思ったこと
SLF4J + logbackだから平気だったみたいなツイートが結構ありました。
SLF4Jは開発止まっているしあんまり使わない方がいいよね。みたいな風潮があったと思っていたので少し驚きです。
ちなみに開発は止まっていないというか再開されてます。
AWS
AWS WAFでブロックする機能が公開されました。早い。
MySQL8系への移行に備える
MYSQL8系を使用するにはSpring で使われているMySQL Connector/Jをアップデートする必要があります。
今回はちょっと詰まってしまったところがあるのでメモ。
MySQLのEOL
https://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf
Oracle's MySQL Releasesに(p.28)記載がある通り5.7系は2023/10でEOLを迎える
まだ2年弱はあるものの、気づけばEOL...なんてことはどんなものでもあるのでなるはやで布石を打っておきたい。
MySQL Connector/J
pom / gradleの記載方法はmaven repositoryにあるのでここでは記載しない。
MySQL8系はConector/Jの8系を必要する必要がある。5.7系とも互換性があるので、Connector/Jだけまずはアップデートする戦略は結構あるあるらしい。
DriverNameに設定するPATHが変更になっているので注意すること。
丁寧にlogも出してくれるようになっていた。
public class Driver extends com.mysql.cj.jdbc.Driver { public Driver() throws SQLException { super(); } static { System.err.println("Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. " + "The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary."); } } // https://github.com/mysql/mysql-connector-j/blob/18bbd5e68195d0da083cbd5bd0d05d76320df7cd/src/legacy/java/com/mysql/jdbc/Driver.java#L37-L46 抜粋
logger
これでちょっとハマった。
いざ動作確認としてみると Unable to load log4j... というエラーが出てしまった。
5.1.15 will ship with an SLF4J logger (which can then be plugged into Log4J). Unfortunately, it is not possible to ship a direct Log4J integration because the GPL is not compatible with Log4J's license. (Bug #59511, Bug #11766408)
なるほど 5.1.14以降でライセンス問題により削除されているとのこと。
削除commitは以下。
SLF4JというFacadeを使用してエラーログを出力する必要がある。
5.0系から一気にアップグレードを入れたので今回のエラーに遭遇したというわけでした。
loggerの指定をLog4JからSLF4Jへの指定するとエラーはなくなりました。
Kubernetes入門メモ書き
k8sに入門しているのでどうやって習得していったのか備忘録ながら書く。
k8sって2年前?くらいは「人類には早すぎる」って言われてた気がするのにもはや知ってて当たり前みたいな風潮がある。
人類の進化が早いのか、人類のミュータント化に成功したのか、k8sが歩み寄ったのか、AWS等のパブリッククラウドがカスタムして使いやすくなったのか。
多分一番最後かその前が当たりだと思っている。
第一歩
なにはともかく公式ドキュメントを読む。やっぱり文章量は公式が随一。
Kubernetesとは何か?では公式が丁寧に過去まで振り返って説明してくれている。
チュートリアルではRedis podを作成してみる等ハンズオンも手堅い。
参考書
仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん
ほとんどがDockerについて言及されている。
k8sについては最後の章で少しだけハンズオンがある。
Dockerについての知識だったり経験はすでにあったのでその辺は読み飛ばした。
ただ、最後の章だけはイラストも豊富で公式ドキュメントで得た知識に肉付けすることができたかなと思っている。
「あとがき」では作者のDockerに対する著者の思い、今後私達が習得しなければならない知識に関しても言及してくれている点で良書。
買ってよかったと思える一冊。必須ではない。
入門 Kubernetes
絶対正義オライリーの参考書。オライリーあるあるというか物量がものすごいので何周もしないといけない。
ロールアウト戦略とかスケジューラの動きとかともかく詳細に書かれている。
k8s入門には必須だと思う。
本書について言及すると別のPOSTにした方がいいと思うので割愛する。
その他
気になっているものです。
udemyのコースがありました。udemyを多用している私にとって魅力的だったのですが、
講義概要を見るとEKSでのハンズオンになるみたいなので、EKSをマスターノードにして、EC2等をワーカーノードで構築していくんだろうなぁと思ってしまった。
EKSが巻き取ってくれているところが多そうというので最初は愚直にCerficide Kubernetesを使わないようにしようかなと悩んでいるところ。
多分、セールが来たら買います。
PHP Benchmark
の続き。
benchmarkに使うscriptは公式が出しているものを使っていきます。
実行環境
Raspberry Pi4 ModelB
CPU: 4core Arm Cortex-A72 ARMv8 64bit
RAM: 4GB
JIT機能は有効にしてないです。PHP8でもデフォルトで無効化なのでまずは基本の状態で見ていきます。
phpbrewについては↓のREADMEを参照するのが一番よいです。
PHP8.0.11
PHP 8.0.11 (cli) (built: Oct 17 2021 21:12:34) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.11, Copyright (c) Zend Technologies $ php Zend/bench.php simple 0.034 simplecall 0.012 simpleucall 0.050 simpleudcall 0.051 mandel 0.250 mandel2 0.272 ackermann(7) 0.058 ary(50000) 0.016 ary2(50000) 0.013 ary3(2000) 0.103 fibo(30) 0.189 hash1(50000) 0.022 hash2(500) 0.027 heapsort(20000) 0.059 matrix(20) 0.059 nestedloop(12) 0.071 sieve(30) 0.039 strcat(200000) 0.011 ------------------------ Total 1.337
PHP 7.4.25
$ php -v PHP 7.4.25 (cli) (built: Oct 26 2021 20:39:21) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies $ php Zend/bench.php simple 0.088 simplecall 0.018 simpleucall 0.056 simpleudcall 0.060 mandel 0.253 mandel2 0.294 ackermann(7) 0.062 ary(50000) 0.016 ary2(50000) 0.013 ary3(2000) 0.116 fibo(30) 0.194 hash1(50000) 0.025 hash2(500) 0.025 heapsort(20000) 0.064 matrix(20) 0.064 nestedloop(12) 0.125 sieve(30) 0.042 strcat(200000) 0.012 ------------------------ Total 1.526
PHP 7.3.31
$ php -v PHP 7.3.31 (cli) (built: Oct 26 2021 21:25:58) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies $ php Zend/bench.php simple 0.103 simplecall 0.033 simpleucall 0.083 simpleudcall 0.098 mandel 0.507 mandel2 0.398 ackermann(7) 0.103 ary(50000) 0.018 ary2(50000) 0.014 ary3(2000) 0.162 fibo(30) 0.388 hash1(50000) 0.030 hash2(500) 0.030 heapsort(20000) 0.098 matrix(20) 0.104 nestedloop(12) 0.185 sieve(30) 0.055 strcat(200000) 0.014 ------------------------ Total 2.424
PHP 7.2.24
$ php -v PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies PHP Fatal error: Uncaught Error: Call to undefined function hrtime() in /home/dev/ssd/git/php-src/Zend/bench.php:350 Stack trace: #0 /home/dev/ssd/git/php-src/Zend/bench.php(357): gethrtime() #1 /home/dev/ssd/git/php-src/Zend/bench.php(384): start_test() #2 {main} thrown in /home/dev/ssd/git/php-src/Zend/bench.php on line 350
https://www.php.net/manual/ja/function.hrtime.php
hrtime()関数って標準であったよな・・・?と思ったらphp7.3から導入してました。
そりゃだめですよね。
5.6系を入れてみる。
エラーが出てだめでした。理由はopensslのバージョン問題です。
phpbrewの issuesも見てみましたが、サポートする気はないようです。
そもそもEOLを2018年に迎えているので当たり前ですね。
opensslのバージョン下げて無理やりいれようとか思いましたがクレイジーすぎると思ってすぐやめました。
やるとしてもソースからインストールですね。どこかでこけそうな予感してますが。
$ phpbrew known --old $ phpbrew install 5.6 ===> Loading and resolving variants... Checking distribution checksum... PHP Fatal error: Uncaught Error: Call to undefined function PhpBrew\Tasks\hash_file() in phar:///usr/local/bin/phpbrew/src/PhpBrew/Tasks/DownloadTask.php:28 Stack trace: #0 phar:///usr/local/bin/phpbrew/src/PhpBrew/Command/InstallCommand.php(384): PhpBrew\Tasks\DownloadTask->download('https://www.php...', '/root/.phpbrew/...', 'sha256', 'ffd025d34623553...') #1 [internal function]: PhpBrew\Command\InstallCommand->execute('5.6.40') #2 phar:///usr/local/bin/phpbrew/vendor/corneltek/cliframework/src/CommandBase.php(846): call_user_func_array(Array, Array) #3 phar:///usr/local/bin/phpbrew/vendor/corneltek/cliframework/src/Application.php(398): CLIFramework\CommandBase->executeWrapper(Array) #4 phar:///usr/local/bin/phpbrew/src/PhpBrew/Console.php(105): CLIFramework\Application->run(Array) #5 phar:///usr/local/bin/phpbrew/bin/phpbrew(26): PhpBrew\Console->runWithTry(Array) #6 /usr/local/bin/phpbrew(12): require('phar:///usr/loc...') #7 {main} thrown in phar:///usr/local/bin/phpbrew/src/PhpBrew/Tasks/DownloadTask.php on line 28