凡ジニアのtxt

エンジニアリングができないエンジニア

「Kubernetes on AWS 勉強用」CloudFormationでROLLBACK_COMPLETEになる

はじめに

Kubernetes on AWSを勉強していて、第2章のCloudFormationの設定登録においてテンプレートをアップロード後、ROLLBACK_COMPLETEになったので、メモ。

Kubernetes on AWS ~アプリケーションエンジニア 本番環境へ備える | 会澤 康二, 佐藤 和彦 |本 | 通販 | Amazon

CloudFormationとは

AWS CloudFormation は Amazon Web Services リソースのモデル化およびセットアップに役立つサービス(以下、引用)になります。あらゆるAWSのリソースをIaC(Infrastructure as Code)として定義し、リソースの構築や管理の工程を簡単にできるものだと思われる。

docs.aws.amazon.com

エラー事象

CloudFormationに01_base_resources_cfn.yamlをアップロードして、設定を登録します。そうすると、以下のようにROLLBACK_COMPLETEになり、次へのステップが進めません。サンプルがあるyamlは以下、GitHubにあります。

https://github.com/kazusato/k8sbook

f:id:aki5151:20210806061527p:plain

eks_test > EventsのStatus Reasonを見ると、どうやらサンプルyamlのregionが自分の環境では使えない。先程のyamlを有効なregionとavailability zoneに変える必要があります。 f:id:aki5151:20210806061352p:plain

対応

 01_base_resources_cfn.yamlにあるTargetRegionAvailabilityZone1~3Defaultを有効なus-east-1a, us-east-1b, us-east-1c, us-east-1d, us-east-1e, us-east-1fに変更する必要があります。コメントアウトは、サンプルコードのデフォルト値になります。

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  ClusterBaseName:
    Type: String
    Default: eks-work

  TargetRegion:
    Type: String
    Default: us-east-1
#  Default: ap-northeast-1

  AvailabilityZone1:
    Type: String
    Default: us-east-1a
#  Default: ap-northeast-1a

  AvailabilityZone2:
    Type: String
    Default: us-east-1b
#  Default: ap-northeast-1c

  AvailabilityZone3:
    Type: String
    Default: us-east-1c
#  Default: ap-northeast-1d
...

変更したyamlをアップロードして設定を登録します。 f:id:aki5151:20210806063315p:plain StatusがCREATE_COMPLETEになっているので、これで次へのステップへ進めます。

Redisとは

Redis

f:id:aki5151:20210728005934p:plain

 Redisとは、データベースやキャッシュ、メッセージブローカーのように使うことができるインメモリのデータストアのオープンソースである。

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams

引用: https://redis.io/

 つまり、ヒープ領域のメモリ内にCRUDが可能なデータベースだと思われる。メモリはストレージよりread/writeが早いので、高速なデータ管理が実現可能になる。Redisの使用例を見ると、ビックデータの一時データ格納先にしたり、ユーザーのセッション管理に用いられることが多いようである。

Redisの起動

 今回はdocker環境上にRedisを構築します。以下、簡単な設定のRedisのdocker-compose.yamlになります。

version: '3'
services:
  master:
    image: "redis:latest"
    hostname: master    
    command: redis-server 

docker compose upのコマンドでRedisを起動させます。

# docker-composeの起動
docker compose up

# dockerプロセスの確認
docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS      NAMES
1b95c0719f0e   aa4d65e670d6   "docker-entrypoint.s…"   7 seconds ago   Up 3 seconds   6379/tcp   redis-master-slave_master_1

# docker上のRedisが起動しているか確認
docker exec -it redis-master-slave_master_1 redis-cli info
# Server
redis_version:6.2.5
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:cc49a38120feeb6b
redis_mode:standalone
os:Linux 5.10.25-linuxkit x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:c11-builtin
gcc_version:8.3.0
process_id:1
process_supervised:no
run_id:efd6d591ad6057fe858f81e74ae066dcb1eadd2b
tcp_port:6379
server_time_usec:1627399820470195
uptime_in_seconds:69
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:9868
executable:/data/redis-server
config_file:
io_threads_active:0 
... (省略)

 次に、key-valueを登録させてRedisの挙動を確認します。

# Redisにkey-valueに登録
docker exec -it redis-master_1 redis-cli set str "test"
OK

# 登録されたkey-valueを確認
docker exec -it redis-master_1 redis-cli get str 
"test"

# JSON形式でも登録
docker exec -it redis-_master_1 redis-cli set json "{ test: "" }"
OK

# 登録されたJSON形式のkey-valueを確認
docker exec -it redis-master_1 redis-cli get json             
"{ test:  }"

RedisのMaster/Slave構成の確認

 RedisのMaster/Slave構成も確認しておきます。レプリケーションができるようにMaster1台/Slave1台の構成を以下にします。

version: '3'
services:
  master:
    image: "redis:latest"
    hostname: master    
    command: redis-server 
  slave:
    image: "redis:latest"    
    hostname: slave    
    command: redis-server --slaveof master 6379 

docker-composeを起動させ、Master用のRedisにkey-valueを登録し、Master/Slave共に登録できているか確認します。

# docker-composeを起動
docker compose up

# dockerプロセスを確認
docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS      NAMES
10e64077c5ae   aa4d65e670d6   "docker-entrypoint.s…"   19 seconds ago   Up 15 seconds   6379/tcp   redis-master-slave_slave_1
494d55f1bc71   aa4d65e670d6   "docker-entrypoint.s…"   19 seconds ago   Up 15 seconds   6379/tcp   redis-master-slave_master_1

# Master用のRedisにkey-valueに登録
docker exec -it redis-master_1 redis-cli set str "test1"
OK

# Master用のRedisにkey-valueを確認
docker exec -it redis-master_1 redis-cli get str 
"test1"

# Slave用のRedisにkey-valueを確認
docker exec -it redis-slave_1 redis-cli get str 
"test1"

また、Slaveを更に増やしたい場合はdocekr compose up --scale slave=2とすれば、Master1台/Slave2台の構成を構築することもできます。

所感

 会社の商用環境で、Redisが使われていて触ってみたかったので、簡単な設定でRedisを構築してみました。やっぱり、実際に動かしてみた方が理解しやすいので、docker環境で試せるのは楽だな。RedisにはSentinelというHA構成を実現する設定もあるので、自動フェイルオーバーの挙動もやってみたい。

Kubernetes運用における調査コマンド集

最初に

 Kubernetes運用において、Issue調査上でよく使うコマンドをまとめていきます。

Kubernetes

 まず、Kubernetes上のアプリケーションが動いているPodのリソース使用量をチェックします。あとは各Node/Podのステータスも確認しておきます。

# Podのリソース使用量を確認
kubectl top pods -n <namespace>

# or Nodeのリソース使用量の確認
kubectl top nodes

# Nodeのステータスを確認
kubectl get nodes

# Podのステータスを確認
kubectl get pods -n <namespace>

# 指定のPodの df -f コマンドを実行
kubectl exec -it -n <namespace> <pod name> -- df -h
# 複数のコンテナの場合
kubectl exec -it -n <namespace> <pod name> -c <container name> -- df -h

 Podステータス上がCrashLoopBackOff担っている場合は、yaml上のパラメータが誤りであったり、docker repoとの疎通を確認します。NodeがNotReadyであることやkubectlの応答がない場合は、Master/Worker Nodeが動いているホストに直接ログインして、変なプロセスがメモリを食いつぶしてないか確認します。

 上記以外の場合は、以下のコマンドを使ったチェックを進めます。エラーログが確認できる場合、Pod上のアプリケーションに関して問題がある可能性があります。なので、アプリチームとバグがないか確認します。

# Podのログを確認
kubectl logs -n <namespace> <pod name>

# 複数のコンテナの場合
kubectl logs -n <namespace> <pod name> -c <container name>
 

 またPodのログは、/var/log/containers配下でもファイル出力されているので、確認することができます。

Linux

 kubectlの応答がない場合、OOM Killerが原因でMaster Nodeのkubeletが落ちている可能性があります。なので、kubeletが動いていることや他プロセスがメモリを食いつぶしているか確認します。

# 実行中のプロセス確認
top

# OOM Killerのログ確認
cat /var/log/messages | grep Kill
 
# kubeletのステータス確認
systemctl status kubelet

# kubeletの再起動
systemctl restart kubelet

他プロセスがメモリを食いつぶしているときは、該当するプロセスを停止させるのが一時的な対処になると思います。

所感

 今回は、自分がKubernetes運用で問題が起きた場合に確認する主な流とコマンドになります。

TOEIC受験記1 600++

 1か月程前に書いたTOEICに関する記事ですが、先日TOEICを受けたのでその時の感想と次回までの策を書こうかと思います。 aki5151.hateblo.jp

結果

  • Listening: 370
  • Reading: 270
  • 合計: 640

ということで、35点アップという結果になりました。

所感

 Listeningに関して、前回とスコアが同じなのでした。なので、ある程度の基礎力はあるとします。

 次にReadingですが、240 -> 270なので、少し勉強したから上がった程度っていうのが正直な感想になります。Readingに関しては、どうしても長文読解が最後まで解けないという課題があります。次に試験を受けるまでの課題解決として、

  1. 捨て問題を早く判断すること
  2. わからない単語・表現を減らすこと

を念頭に入れます。具体的な策としては、”1. 捨て問題を早く判断すること”は、長文読解の問題では1つの文章に対して、3~5問解くことになります。なので、5問の場合は、必ず1問捨てる方法を行おうかと思います。

 次に、”2. わからない単語・表現を減らすこと”になりますが、今使っているテキストを繰り返し解き、覚えられていない単語・表現を脳に焼き付けることをします。

"入門 監視"を読んでみて

"入門 監視"を読んでみて

 監視システムを運用するようになってから、2年近くになってきました。監視について勉強しているときに、オライリー本の"入門 監視"も読んでいました。再度、この本を読んで、思ったことを書きます。

 以下に、オライリー公式のリンクを貼っておくので、興味ある方はぜひ検討してみてください。 www.oreilly.co.jp

1章 監視のアンチパターン

 監視とはいっても、OSや物理リソースまたは仮想リソース、はたまたそれらの上で稼働しているアプリケーション、ネットワークなど多くのドメインに対して監視する必要がある。監視するにしても、対象ドメインの知識は必要となり、属人化してはならない。うちのチームと照らし合わすと、「.......、まぁ属人化してますな.....」。

 あとは監視ツールは最小限にすべきとあるが、開発体制や予算の都合でさまざまな監視ツールが存在する組織もあるだろう。Grafana/Prometheus/Kibana/NewRelicがあるが、ドメインによっては複数のGrafana/Kibanaが多く運用されている。アクセス方法やユーザー管理もそれぞれ違うチームが対応するので、運用観点から統一してほしい。統一できるように行動はしているが、あまり上の了承が得られないのが悩みどころになっている。了承を得られるまで、粘ってみたいと思う。

2章 監視のデザインパターン

 監視デザインパターンの一つとして、監視の仕組みを作るのではなく、買うこともひとつとある。New Relicやdata dogがこれらに当てはまる。New Relicを使っているが、確かにこれは便利である。

 例えば、PrometheusとGrafanaを同時に作ることは一般的であると思う。しかし、メトリックス収集用のExporterをインストールしたり、どのようにメトリックスをグラフ化するかなど結構工数がかかったり、仕様変更などの対応も大変だったりする。NewRelicのAgentをインストールすれば、すぐにデフォルトのグラフが表示できるので、楽である。(楽は正義....)

3章 アラート、オンコール、インシデント管理

 一番大切なことは「アラートにメールを使うのをやめよう」だ。意外とアラートをメールで投げている会社は多いのではないか。うちも考慮漏れされたシステムの監視方法に対してメール発報がある。これは、関連のあるシステム動作も追うことは困難になるし、必ずアラート数が増える。何度も言う「アラートにメールを使うのはやめよう」。

 Runbookの作成や不要なアラートの削減は効果的であると思う。Runbookは、他メンバーの教育にもなるし、属人化を避けることができる唯一の手段になる。また、不要なアラートの削減に対しては、アラートの目的を明確にして、閾値をシンプルしていった方がいいと思う。

4章 統計入門

 私は統計学がわかるとまで必要ではなく、最低限で簡単な数式を理解できればいいかなと思っている。例えば、Prometheusでよく使われるrate関数がある。これは最新x分範囲で抽出されたデータセットの増加率を調べるものである。

 最新5分範囲のデータセットをx = [1, 2, 3, 4, 5]とした場合に、(5 - 1) / (5 * 60) * 100 = 1.33333...% の増加率となる。なので、1分単位で0.8ずつ値が増えていることとなる。観測対象によるが、この増加率以下となれば、システムは正常に稼働している。増加率以上になれば、システムに何かしらの不具合が起きているという判断になると思う。HTTP 5xxが常に応答されている等。

 ここで述べたのは、専門的な統計学ではなく、高校で習う数列と乗算ぐらいで最低限は通じるはずである。(複雑な場合は、都度勉強すればいいと思う。)

5章 ビジネスを監視する

 ビジネスと言えばKPIが重視される。監視観点から、一般的なのはApdexではないだろうか。これはWebシステムに対するユーザーの満足度を計測しているものとなっている。この閾値が下がれば、レスポンスの遅さに不満を抱いている可能性があるから、パフォーマンス改善が求められている。

 New RelicではAPM上で観測でき、アラートも設定できる。これで一早くビジネスに影響を与える要因を探して対応すれば、ビジネスに貢献できるのではないだろうか。計算式は以下New Relicの公式サイトに説明されているので割愛します。

docs.newrelic.com

6章 フロントエンド監視 & 7章 アプリケーション監視

 ロード時間、例外処理もみようぜ。また最近はマイクロサービス化されているから、分散トレーシングしていこうぜ。

8章 サーバ監視

 CPU、メモリ、ストレージを監視しようぜ。あとはOOM Killerには気をつけよう。うん、OOM Killer怖い。でも、起きることはしょうがないので、すばやく対応できるようにしておこう。

9章 ネットワーク監視

 ネットワーク監視といっても、プロトコルだけでなく、インターフェース、スイッチ、シャーシなど数多くの監視対象があるので、大変だよね。

10章 セキュリティ監視

 セキュリティ知識があまりないが、audit logと取ってセキュリティ違反者を探そうぜってことかな。よくsshのパスワードなど間違えて、セキュリティ違反対象になる。とほほ。。。

11章 監視アセスメントの実行

 ここの章は、本誌で述べたことをチェックリストみたいなものなので、見たい方は本誌を購入してみてください。

終わりに

 後半は、本誌で紹介されている例が多かったので、感想しか書けなかった。しかし、改めてどのように監視を改善してビジネスを成長させられるかがよく書かれた本だと思う。まだまだ監視について、出来ていない箇所(特に6&7章)があるので、また振り返って監視を強化していきたい。また本誌で説明されていることは、New Relicやdatadog、mackerelなどの監視用SaaSで対応できるから、すごい世の中になったなと思う。   

エンジニアがストレスとして感じること

ある日

ある日、ふらーっとYoutubeを見てたら、以下Daigoさんの「今すぐ転職すべき職場ランキングTOP7〜心身崩壊するブラック企業の特徴」が流れた。この動画のタイトルにも記載されているが、心身共にストレスを与える特徴の七つがランキングとして紹介されている。タイトルにはブラック企業と書かれているが、仕事上で感じるストレスTop7で置き換えることもできるのではないかと思った。これまでエンジニアとして働いた経験での主観的な意見をここに書きたい。(再度、これはあくまで私の主観的な意見になります。)

www.youtube.com

ランキング

以下が、動画で紹介されているランキングになります。

  • 1位 仕事の制限が多い
  • 2位 役割の衝突
  • 3位 ネガティブコミュニケーション
  • 4位 作業負荷が高い
  • 5位 役割が曖昧
  • 6位 裁量権がない
  • 7位 長時間労働

7位 長時間労働

はい、みなさん。皆さん大嫌いな長時間労働になります。ここ一年の月間労働時間は月45h程度か60h以上75h以下のどちらかになります。人によっては、まだまだ少ない方じゃないかと言われる強者の方がいるかもしれません。しかし、60h以上を超える月が続くと、気分がモヤモヤすることが多くなりました。例えば、休日などにやりたいことがなく、月曜の仕事のことを考えてしまうことや、寝る前まで仕事のことで脳のメモリが占有されてしまってます。人手が足りない部署になると、これは当たり前になってることが多いかもしれないですね。

6位 裁量権がない

エンジニアとしては、ある程度の裁量権があれば、開発も改修も楽しくなるのではないでしょうか。しかし、トップからの不透明な要件が飛んできて、背景もわからずその要件をクリアしないといけいないことを経験した方が多いと思います。意外と不透明なことをやるには、イライラしますよね。最低限、背景ぐらい教えろよと。

5位 役割が曖昧

エンジニアをしていると、いつの間にか主担当ではない他システムも担当させられていることが多いのではないでしょうか。AとBというシステムがあり、主担当はAで、一応AとBが連携しているから、Bの要件や設計などに首を出していると、勝手に担当をアサインされている。悲しいですよね。はい、元担当者。きちんと役割を果たせと。

4位 作業負荷が高い

日中は、これまでに作成されてチケットを見ながら、トラブルがある場合はチームと連携とって、対策はどうするかなど話して、もし一次解析が可能なら、実際にシステムのログを取ったり、復旧を見計らったりしてます。夜は設定作業や夜間のトラブル対応などもすることがあるのでは、ほとんど気が休まらない日が続いてます。しかも、他システムに首を突っ込むとこの人が理解しているから、この人に聞いてと。更に作業負荷が増えますよね。

3位 ネガティブコミュニケーション

ネガティブな発言を公の場で言うのは、避けましょう。これは他チームから、自分のチームが悪いと言われました。具体的には書きませんが、色々とグッと堪えて大人の対応していて、相手側からネガティブな発言を向けらえると、こっちもネガティブな感情しか持たなくなりますよね。実現出来もしないものに対して、ネガティブな発言しても意味ないので、スマートで建設的な会話をしましょう。

2位 役割の衝突

動画内で言われてる役割とは、様々な指示系統から発生する役割と紹介されている。例えば、開発/改修のマネジメントして実作業も行う中で、他チームのリーダーから全チームの予算会に出席して、稟議出してこいと。ほな、あほなとなりますよね。

1位 仕事の制限が多い

予算の関係上、改善策を提案しても後ろ向きな意見しか出ず、問題点をそのまま放置されたら、ストレス溜まりますよね。例えば、アラートがなって、どのパターンでどの人に連絡しないといけないかって意外と作業工程に時間がかかったりしますよね。そこを自動化しようと、PagerDutyを使ってみましょうよと提案する。2000円/月/ユーザーなので、チームで連絡入るのも3-4人程度なので、年で10万程度で改善できますよ。うん、これ通らなかったというか、スルーです。上場企業なのにね。

終わりに

ランキングを基にある程度抽象化して書いてみたが、心身ともにダメージがきたら、逃げましょうしか言えない。愚痴っぽくなってしまったが、自チームのメンバーや直近の上司は良い人達です!!

格言「逃げるは恥だが役に立つ

Argo CDを起動してログインしてみた

Argo CDを、自分の環境で立ち上げて、ログインしてみました。今回は自分の環境でログインできるまでを書いていこうと思います。

Argo CDとは

f:id:aki5151:20210621181302p:plain

これまでにGitOpsとはなんぞやで書いたGitを用いたk8sリーソースまたはコンテナアプリケーションの継続デリバリー(CD)を実現するオープンソフトウェアになります。

以下、公式サイトになります。 argoproj.github.io

環境

ラズパイ2台で構成されたk8sクラスターは以下になります。

  • Master node: 1台, Worker node: 1台
  • OS: Ubuntu18.04.5
  • kubectl: 1.21.0
  • kubelet: 1.21.0
  • kubeadm: 1.21.0
  • aarch64

手順

以下、手順はArgoCD公式サイトを基に記載しています。

ArgoCDをデプロイ

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

kubectl get pods -n argocd
NAME                                 READY   STATUS             RESTARTS   AGE
argocd-application-controller-0      0/1     Error              3          85s
argocd-dex-server-56dc8fc7df-l9crz   0/1     Init:Error         3          86s
argocd-redis-9567956cd-46297         1/1     Running            0          86s
argocd-repo-server-747c48457-ps9hc   0/1     CrashLoopBackOff   3          85s
argocd-server-595b6f797d-gjlgn       0/1     CrashLoopBackOff   3          85s

デプロイ後、Podのステータスを確認すると見事にエラーが出ています。ログを見ると、

kubectl logs -n argocd argocd-application-controller-0      
standard_init_linux.go:219: exec user process caused: exec format error

ArgoCDの公式docker imageがarm64に対応されてなさそうなので、以下のarm64対応のdocker imageに変更してみます。 hub.docker.com

# install.yamlをダウンロード
wget https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# docker image変更 
# Before the change: quay.io/argoproj/argocd:v2.0.2
# After the change: alinbalutoiu/argocd:v2.0.3
cp install.yaml install-changed.yaml
vim install-changed.yaml

# 差分チェック
diff install-changed.yaml install.yaml
2547c2547
<         image: alinbalutoiu/argocd:v2.0.3
---
>         image: quay.io/argoproj/argocd:v2.0.2
2647c2647
<         image: alinbalutoiu/argocd:v2.0.3
---
>         image: quay.io/argoproj/argocd:v2.0.2
2743c2743
<         image: alinbalutoiu/argocd:v2.0.3
---
>         image: quay.io/argoproj/argocd:v2.0.2
2836c2836
<         image: alinbalutoiu/argocd:v2.0.3
---
>         image: quay.io/argoproj/argocd:v2.0.2

arm64対応のイメージに置き換えたらyamlをデプロイします。Runningになるまで、少し時間がかかるみたいです。

kubectl apply -f install-changed.yaml -n argocd
kubectl get pods -n argocd
NAME                                 READY   STATUS    RESTARTS   AGE
argocd-application-controller-0      1/1     Running   0          57s
argocd-dex-server-7ff75fb568-zkgvb   1/1     Running   1          58s
argocd-redis-9567956cd-7czcj         1/1     Running   0          58s
argocd-repo-server-587b4ccb4-2prmp   1/1     Running   0          57s
argocd-server-7886d64f5-hh6xl        1/1     Running   0          57s

外部からArgo CDのUIにアクセスするために, 先ほどデプロイされたServiceのTypeをLoadBalancerに変更します。

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
kubectl get svc -n argocd
...
argocd-server           LoadBalancer   10.106.82.17     192.168.100.112   80:30302/TCP,443:31019/TCP   4m15s
...

192.168.100.112:80にアクセスすると、以下ログインページが表示されます。 f:id:aki5151:20210621181224p:plain

デフォルトの設定では、secret上にユーザ(admin)とパスワードがあります。以下コマンドで取得したら、ログインページからログインができます。

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
gxxXjcWCJtcpPeHJ

f:id:aki5151:20210621181838p:plain

終わりに

今回、ラズパイ上で構築したKubernetes上にArgo CDをデプロイして、ログインできるまでの手順を記載した。次はArgo CDがどのように挙動するか、GitHubからCDを実現できるか試して書いていきます。