まっしろけっけ

めもてきなやーつ

RDS for MySQL の version up (5.6 -> 5.7) 時のアレコレ

はじめに

長年 RDS for MySQL の 5.6 を使っていたのですが、昨年の 10 月くらいにリザーブドが切れるタイミングで(安くなって性能も上がるので)インスタンスタイプを変更しようと思ったのですよ。インスタンスタイプ変更なのでメンテ挟んで〜ということになるので、準備などをしてメンテ前日を迎えたわけです。

新しいインスタンスタイプでレプリカを作っておくというのをやろうとしたら、作れないと言われる...色々調べてみたら MySQL 8 以降じゃないとそのインスタンスタイプは使えないと...(料金表にはそんなこと書いてないじゃないかクソが!などと思った記憶があるのですが)そんなこんなで 2021 年のお仕事の一つが MySQL の version up に決定。

2 月に 5.7 にするか〜と思っていたら 5.6 サポート終了のお知らせ が出てました。

ということで 5.7 にする際に調べた RDS の挙動などをメモっておく

5.6 -> 5.7 の変更点

社の福利厚生で @yoku0825 さんに気軽に質問出来るので教えてください〜と言ったら
大量に教えてもらった。

5.7 に関してはこのくらいで 8 に関しては 5 倍くらいの情報を教えてくれた(感謝)
自分のサービスで使用している RDS で気にしないといけないところは特になかった。というのも、sql_mode は 5.7 デフォルトのパラメータグループであれば 5.6 と一緒だし、innodb_tmp_data_file_path に関しては RDS では変更不可。

version up 方法

続いてはどうやって version up させるか?という話。
前提としてプライマリに対して n 台のレプリカ紐づいているという構成

検証なので本番のスナップショットから復元した検証用の構成を使っている

プライマリを 5.7 にする

何も考えずプライマリを 5.7 にあげようとしたところ、レプリカが全台プライマリより上の version じゃないとプライマリは version up 出来ないと言われて終了。

レプリカを 5.7 にする

上記のような結果になったので全てのレプリカを 5.7 にした。5.7 にしている最中は一定時間接続出来なくなる。

再度プライマリの 5.7 化にチャレンジ

すんなりいけた。
これで 5.7 にするという方法は理解できたのだけれど、何か問題があって一定時間稼働させた後に 5.6 に戻したいとなった場合に辛いなと思ったのでそこら辺の検証をした。

version のロールバック方法の検証

上記の version up の検証をする前に考えていたのは下記

レプリカ一台を 5.6 のままにしておき、他のプライマリ/レプリカ全台を 5.7 にする。この状態で問題が起きたら 5.6 のレプリカを昇格させる。だったのだが上記の検証でそれが不可能なことが発覚した。

次に試したのが、プライマリ 5.6 の状態でレプリカが 5.7 と 5.6 の状態で 5.7 のレプリカを昇格させると 5.6 のレプリカのレプリケーション先は昇格した 5.7 のシン・プライマリに向くんでは?というやーつ。試したが 5.6 レプリカは 5.6 プライマリに対してレプリケーションしてた(元々こういう挙動だったっけ?)

実際に試した方法は上記だけで、他には binlog や全クエリのログを保存しているのでそれを使って差分を流し込むなどが考えられる。
その他にも RDS から EC2 とかで自前で建てた MySQLレプリケーションが出来ればごにょごにょできるよね〜という選択肢もあるにはあるか?など考えていた。

結局簡単に戻せる方法はないのか?が知りたかったので AWS の中の人に直接聞いたら、結論としては簡単に戻せる方法はないのでクエリのログとかから手動で頑張ってという回答をいただいた。

さいごに

そんなこんなで問題が起きたら手動で頑張るしかないのか〜(手順はわかるが)めんどくさいな〜と思いつつ、水曜日の早朝にメンテナンスを行い 5.7 に上げたが特に問題は発生していないので、大勝利。

8 への version up も少し時間を空けてからトライする予定。

PC を自作した

はじめに

今月の初めくらいに人生で初めて PC を自作した。
自作自体は 10 年以上前からやりたい〜とは思っていたのですが当時はお金もあまりなく(今の給料の 1/3 以下?)、それなりにお金を稼げるようになってからは windows は使わなくなりもっぱら Mac だったので今更ゲーミング PC に 10 ~ 20 万もかけるのはなぁ...という気持ちがあった。

しかし、最近では windows 環境でも開発がしやすくなりゲーミング + 開発用と考えれば windows あっても困らんなと思い出したり。
マンションを購入して広い書斎が持てたのでデカイ PC あっても困らんなという考えから自作することにした。

構成

構成はこんな感じ
自作PC 構成見積もり てすと

CPU は本当は Ryzen 7 5800X BOX を買う予定だったのだけれど売ってない...ということで変更した。
あとは、ゲーミング PC なので無駄に光らせるかという気持ちで光るケースファンを選んだ。

f:id:shiro-16:20201205155354j:plain

組み立て

実際に組み立てたわけですが、3,4 時間あれば終わるかと思って夕方くらいに始めたのだけれど色々あり次の日の夜くらいに OS のインストールが終わるという長丁場になった。(途中予定があり外出なども有り)

それほど困らず全体を組み終わったのですが、実際に電源を入れてみると BIOS が表示されんなぁというのであれこれやっていて初日は終わり。

よくわからんので youtube とかで同じマザボ使って組み立てている人の動画なども眺めてメモリがちゃんとハマってるようではまってないのでは?と思い挿し直してみたら BIOS が起動して歓喜したのですが一旦色々バラしており最小構成で BIOS 起動まで行ったので諸々ちゃんと組み立てたらまた BIOS が起動しないということでハマる...

何箇所かパーツ抜き差ししてたら起動するようになったので OS インストールや〜となってパーティションの設定で SSD が認識されているのにうまくいかんとなり SSD を抜き差しするイベントが発生するなどが有り無事に OS のインストールも終わり出来上がり。

f:id:shiro-16:20201207161045j:plain

ちゃんと光ってる様子

最後に

初めての自作だったので色々ハマったが無事に出来てよかった...
ついでにキーボードも自作するか?と考えたがまだあわてるような時間じゃないと思い直して今回は見送り

ゲーミング PC 作って何をやっているかというと数年ぶりにエオルゼアを旅しています。(前は新生発売時に PS3 でやっていた)

k8s に Datadog を導入して APM のみ有効にしたい

はじめに

www.datadoghq.com

Datadog とはサーバのモニタリングなどを行ってくれるサービス。
一般的なメトリクスのモニタリング以外にも log を集約したりなど様々な機能があり、設定次第でそれぞれを有効化/無効化できます。

で今回はメトリクスのモニタリングは別でやってるので APM だけ有効にしたいんだよね〜ということをやっていきます。

Datadog 導入

まず Datadog には agent というものが存在します。
この agent が Datadog の server にメトリクスの情報を送るなどを行ってくれるものになります。

NewRelic などは gem として入れた agent が直接情報を NewRelic の server に送信しますが、Datadog は agent を別でインストールし、それに加えて gem も入れるということになります。この gem が agent に情報を送り agent が server に情報を送るという構成になっています。

APM としての機能だけではなく、server のメトリクス収集なども行ってくれるのでおそらくこういう構成になっているんでしょうね。

kubernetes に agent を install

導入方法はマニュアルの ここ に書いてありますが、k8s 上では daemonset として agent を deploy します。(見てもらえればわかりますが helm を使った install 方法なども書いてあります)

$ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/clusterrole.yaml"

$ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/serviceaccount.yaml"

$ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/clusterrolebinding.yaml"

必要な RBAC を設定していきます。

次に API key の secret を作成

$ kubectl create secret generic datadog-agent --from-literal api-key="<DATADOG_API_KEY>" --namespace="default"

最後に daemonset を apply

$ cat daemonset.yaml
---
# Source: datadog/templates/install_info-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: datadog-agent-installinfo
  labels: {}
  annotations:
    checksum/install_info: 9f58f4fe71f1b79dfabae5311eb8f5373bd03072d4636e248cd3f581f8752627
data:
  install_info: |
    ---
    install_method:
      tool: kubernetes sample manifests
      tool_version: kubernetes sample manifests
      installer_version: kubernetes sample manifests
---
# Source: datadog/templates/daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: datadog-agent
  labels: {}
spec:
  selector:
    matchLabels:
      app: datadog-agent
  template:
    metadata:
      labels:
        app: datadog-agent
      name: datadog-agent
      annotations: {}
    spec:
      containers:
        - name: agent
          image: "gcr.io/datadoghq/agent:7.23.1"
          imagePullPolicy: IfNotPresent
          command: ["agent", "run"]
          resources: {}
          ports:
            - containerPort: 8125
              name: dogstatsdport
              protocol: UDP
          env:
            - name: DD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: "datadog-agent"
                  key: api-key
            - name: DD_KUBERNETES_KUBELET_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: KUBERNETES
              value: "yes"
            - name: DOCKER_HOST
              value: unix:///host/var/run/docker.sock
            - name: DD_LOG_LEVEL
              value: "INFO"
            - name: DD_DOGSTATSD_PORT
              value: "8125"
            - name: DD_APM_ENABLED
              value: "false"
            - name: DD_LOGS_ENABLED
              value: "false"
            - name: DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL
              value: "false"
            - name: DD_LOGS_CONFIG_K8S_CONTAINER_USE_FILE
              value: "true"
            - name: DD_HEALTH_PORT
              value: "5555"
            - name: DD_ENABLE_PAYLOADS_EVENTS
              value: "false"
            - name: DD_ENABLE_PAYLOADS_SERIES
              value: "false"
            - name: DD_ENABLE_PAYLOADS_SERVICE_CHECKS
              value: "false"
            - name: DD_ENABLE_PAYLOADS_SKETCHES
              value: "false"
            - name: DD_PROCESS_AGENT_ENABLED
              value: "false"
          volumeMounts:
            - name: installinfo
              subPath: install_info
              mountPath: /etc/datadog-agent/install_info
              readOnly: true
            - name: config
              mountPath: /etc/datadog-agent
            - name: runtimesocketdir
              mountPath: /host/var/run
              mountPropagation: None
              readOnly: true
            - name: procdir
              mountPath: /host/proc
              mountPropagation: None
              readOnly: true
            - name: cgroups
              mountPath: /host/sys/fs/cgroup
              mountPropagation: None
              readOnly: true
          livenessProbe:
            failureThreshold: 6
            httpGet:
              path: /live
              port: 5555
              scheme: HTTP
            initialDelaySeconds: 15
            periodSeconds: 15
            successThreshold: 1
            timeoutSeconds: 5
          readinessProbe:
            failureThreshold: 6
            httpGet:
              path: /ready
              port: 5555
              scheme: HTTP
            initialDelaySeconds: 15
            periodSeconds: 15
            successThreshold: 1
            timeoutSeconds: 5
        - name: trace-agent
          image: "gcr.io/datadoghq/agent:7.23.1"
          imagePullPolicy: IfNotPresent
          command: ["trace-agent", "-config=/etc/datadog-agent/datadog.yaml"]
          resources: {}
          ports:
            - containerPort: 8126
              hostPort: 8126
              name: traceport
              protocol: TCP
          env:
            - name: DD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: "datadog-agent"
                  key: api-key
            - name: DD_KUBERNETES_KUBELET_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: KUBERNETES
              value: "yes"
            - name: DOCKER_HOST
              value: unix:///host/var/run/docker.sock
            - name: DD_LOG_LEVEL
              value: "INFO"
            - name: DD_APM_ENABLED
              value: "true"
            - name: DD_APM_NON_LOCAL_TRAFFIC
              value: "true"
            - name: DD_APM_RECEIVER_PORT
              value: "8126"
          volumeMounts:
            - name: config
              mountPath: /etc/datadog-agent
            - name: runtimesocketdir
              mountPath: /host/var/run
              mountPropagation: None
              readOnly: true
          livenessProbe:
            initialDelaySeconds: 15
            periodSeconds: 15
            tcpSocket:
              port: 8126
            timeoutSeconds: 5
        - name: process-agent
          image: "gcr.io/datadoghq/agent:7.23.1"
          imagePullPolicy: IfNotPresent
          command: ["process-agent", "-config=/etc/datadog-agent/datadog.yaml"]
          resources: {}
          env:
            - name: DD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: "datadog-agent"
                  key: api-key
            - name: DD_KUBERNETES_KUBELET_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: KUBERNETES
              value: "yes"
            - name: DOCKER_HOST
              value: unix:///host/var/run/docker.sock
            - name: DD_LOG_LEVEL
              value: "INFO"
            - name: DD_ORCHESTRATOR_EXPLORER_ENABLED
              value: "false"
          volumeMounts:
            - name: config
              mountPath: /etc/datadog-agent
            - name: runtimesocketdir
              mountPath: /host/var/run
              mountPropagation: None
              readOnly: true
            - name: cgroups
              mountPath: /host/sys/fs/cgroup
              mountPropagation: None
              readOnly: true
            - name: passwd
              mountPath: /etc/passwd
            - name: procdir
              mountPath: /host/proc
              mountPropagation: None
              readOnly: true
      initContainers:
        - name: init-volume
          image: "gcr.io/datadoghq/agent:7.23.1"
          imagePullPolicy: IfNotPresent
          command: ["bash", "-c"]
          args:
            - cp -r /etc/datadog-agent /opt
          volumeMounts:
            - name: config
              mountPath: /opt/datadog-agent
          resources: {}
        - name: init-config
          image: "gcr.io/datadoghq/agent:7.23.1"
          imagePullPolicy: IfNotPresent
          command: ["bash", "-c"]
          args:
            - for script in $(find /etc/cont-init.d/ -type f -name '*.sh' | sort) ; do bash $script ; done
          volumeMounts:
            - name: config
              mountPath: /etc/datadog-agent
            - name: procdir
              mountPath: /host/proc
              mountPropagation: None
              readOnly: true
            - name: runtimesocketdir
              mountPath: /host/var/run
              mountPropagation: None
              readOnly: true
          env:
            - name: DD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: "datadog-agent"
                  key: api-key
            - name: DD_KUBERNETES_KUBELET_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: KUBERNETES
              value: "yes"
            - name: DOCKER_HOST
              value: unix:///host/var/run/docker.sock
          resources: {}
      volumes:
        - name: installinfo
          configMap:
            name: datadog-agent-installinfo
        - name: config
          emptyDir: {}
        - hostPath:
            path: /var/run
          name: runtimesocketdir
        - hostPath:
            path: /proc
          name: procdir
        - hostPath:
            path: /sys/fs/cgroup
          name: cgroups
        - name: s6-run
          emptyDir: {}
        - hostPath:
            path: /etc/passwd
          name: passwd
      tolerations:
      affinity: {}
      serviceAccountName: "datadog-agent"
      nodeSelector:
        kubernetes.io/os: linux
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 10%
    type: RollingUpdate

# Source: datadog/templates/containers-common-env.yaml
# The purpose of this template is to define a minimal set of environment
# variables required to operate dedicated containers in the daemonset

$ kubectl apply -f daemonset.yaml

元々の daemonset.yaml と比べてもらえるとわかりますがいくつかの環境変数を設定することで APM のみを有効にしています。

gem を install

今回は Rails のアプリケーションに APM を入れるので Gemfile に書いていきます。

$ vi Gemfile
+ gem 'ddtrace'
$ bundle install
$ vi config/initializers/datadog.rb
Datadog.configure do |c|
  c.tracer enabled: true
  c.use :rails, service_name: "hoge"
end

この状態でリリースしてあげると Datadog の画面上で APM の情報が見れるようになると思います。

最後に

APM のみ有効にしてみましたが、導入して一ヶ月経っていないので支払いがまだ発生しておらず APM のみになっているか不安ではあるのですが Usage の画面を見ると APM の情報のみしか出ないのでおそらく成功していると思われます。

Pepabo Tech Conference #13 に登壇

はじめに

pepabo.connpass.com

こちらに登壇しました。

登壇内容

speakerdeck.com

ここ数年で主に自分がやってきているアーキテクチャの変更について一部を紹介したのと来年に向けてのやっていきを話た。

来年に関しては若者が色々頑張ってくれているので僕がメインで開発を進めることに関しては話してないのだけれど、色々とやっていく予定

さいごに

前日から犬の体調が優れず、大変だったのですが無事に終わって良かった...(犬のだいぶ回復してきた)

食べるものを変えてみた

はじめに

在宅勤務になり基本家でご飯を食べることが多くなりました。
元々平日夜は自炊をしていました。
基本的に同じものをずっと食べ続けることができるので同じものを作っていたのですが多少作るのがめんどくさいなぁ〜などと思いつつも 1 食 300 ~ 400円くらいで作れるし節約にはなるしなぁと思いやっていたんですが元同僚の ひさいちくんつくりおき.jp について tweet してるのを見て良さそうかもと思い利用し始めたので before/after を書いておく

before

朝飯

元々朝飯は食べておらず火曜日と木曜日に朝ジムにいくようになりジム後はお腹が空くのでコンビニでおにぎりを買うなどしていたが 1.5 ヶ月ほど前からプロテインに切り替えた。
これはつくりおき.jpの件とは関係なくなんとなくプロテイン飲んでみるか?となって

昼飯

昼飯はだいたいコンビニで弁当なりを買って食べていたので、毎日昼の時間になるとコンビニに買いに行っていた。
コンビニに行くと弁当だけではなくなんか余計なものも買っちゃうよね...というのと減量したいときはサラダと低カロリーのものだったりを買うので割と 1000 円いかないくらいかかってしまっていた。

夕飯

夏場はあまり火を使いたくないのでオーブンレンジを活用していた。
何種類かの野菜と鶏肉を適当な大きさに切って袋に入れてそこにオリーブオイルとその日の気分で塩や醤油などを入れて全体になじむように揉んだ後にオーブン用の鉄板にクッキングシートをしいてそれの上に先のものを並べてオーブンで 30 分放置するだけでそれなりに美味しいものができる。

冬場はずっと鍋を食べている。スープは市販のものではなく粉末のかつおだしや鶏だしをベースに塩や醤油などで薄味にしていた。一回で 2,3 日分をまとめて作って残ったやつはそのまま冷蔵庫行きにしているので毎日料理する必要がなくて楽。


基本的には週の初めにその週使う野菜と肉は切っておくので週の途中で調理を行う時間を短縮していた

両方とも野菜が取りやすいし、塩分なども控えめにできるので健康的にもいいかなという感じ。
基本的に夕飯に関しては米は食べないようにしていたのでこれで終わり。

after

朝飯

特に変わらずジムに行った後だけプロテインを飲んでいる。

昼飯

つくりおき.jpから送られてきた料理を皿に取り分けてレンジでチンするだけ、ご飯は数年ぶりに稼働させた炊飯器で炊いている。
米に関してはロウカット米なるものを購入してそれに十六穀を混ぜて食べているが普通にうまい。

夕飯

夕飯も昼飯と同じでつくりおき.jpから送られてきた料理を取り分けてレンジでチンするだけ。
それだけだと足りないので夕飯も米を食べるようにした。

最後に

こんな感じでつくりおき.jpを利用しだしたことによって平日は完全に料理をしなくなり時間が増えた。
今までも休日にそれなりに手の込んだものだったりを作ったりしてたのでそれは変わらず。

つくりおき.jpは週 3 食プランで合計で 12 食届くので月 ~ 金と土日のどちらかの昼飯と夕飯という感じで食べている。
金額的にも一食 650 円で1日なら * 2 で 1300 円ほどになるので以前の料理をしていた時と比べてもすごく差があるという感じではない。
味はすごく美味しいし、料理の種類も自分では作らんだろうなって感じのものが多いのですごく嬉しいし毎日ほぼ同じものを食べていた以前と比べると今日はどれを食べようか?という楽しみができた。

nosh も試しはしたがメインは良いとして付け合わせの野菜などがやはり冷凍感があってそこがつくりおき.jpと比べると劣るなって感じだった。

体重的な変化だと 10 年以上ぶりに家で夕飯に米を食べ出したが体重に大きな変化はないというか緩やかに落ちている感じもある
コンビニで余計なものを買う機会が減ったからかもしれない...

炊飯器は 10 年以上前に 3000 円くらいで買ったやつなので買い換えようと思っている

EKS の node を managed node groups 管理に移行する

はじめに

aws.amazon.com

EKS の managed node groups にカスタム AMI と EC2 起動テンプレートのサポートが追加されました。
元々 managed node groups が出る以前から EKS を使用しておりかつカスタム AMI も使用していたので managed node groups が登場した当初に試した時はカスタム AMI 使えないならダメじゃんとなり移行を諦めましたが、サポートされたことにより移行するぞとなりました。

managed node groups を使わない場合の問題

問題というほどではありませんが、managed node groups を使わない場合 CloudFormation で node を定義して cluster にアタッチするような手法だったので EKS のコンソールを見ても node との繋がりがわかりにくいという問題がありました。
`k get nodes` で node 一覧を取得するか EC2 インスタンスの特定のタグで絞込みをすることで EKS の node なのだと把握できるくらいでしょうか?(それでも大きな問題はないんですけど)

手順

EKS cluster の作成

https://console.aws.amazon.com/eks/home#/clusters こちらからクラスター作成を選択

f:id:shiro-16:20200828115940p:plain

cluster 名とかは適当に入れます。今回は shiro16-test としています。 kubernetes の version はお好きなものを選びます。今回は最新が最高ということで選べる最新の 1.17 にしています。
クラスターサービスロールはこちらを参考に IAM ロールを作成しそれを選択します。

f:id:shiro-16:20200828115945p:plain

続いてのネットワーク周りの設定は自身の運用環境に合わせて設定してください。

f:id:shiro-16:20200828115954p:plain

ログ周りも運用に合わせて設定してください。本番稼働なのであれば全て取得しておくのが良いかもしれません。
これで入力することはほぼ終わりなので確認画面で作成をポチッとすると cluster が作成されます。(10min ほど完了まで時間がかかるかと思われます)

managed node groups 作成

EKS cluster の作成が完了し cluster の詳細画面にいくと下記のような画面が表示されていると思います。

f:id:shiro-16:20200828120005p:plain

ここでノードグループの追加を選択します。

f:id:shiro-16:20200828120020p:plain

ノードグループ名は好きな名前を入力し、ノード IAM ロールはこちらを参考に IAM ロールを作成しそれを選択します。

更に今回はカスタム AMI を使用するので起動テンプレートを使用するを選択します。
起動テンプレートの設定に関しては後述しますが、強力にキャッシュしているのかここの選択に新規で作成したテンプレートやバージョンがリロードしても表示されないことがありますが、再読み込みマークを選択すると表示されるはずです。

f:id:shiro-16:20200828120027p:plain

最後に node 数を決めて作成を開始すれば EC2 インスタンスが立ち上がり node が cluster に join してくれます。

EC2 起動テンプレート作成

https://console.aws.amazon.com/ec2/home#LaunchTemplates こちらのページで起動テンプレート作成を選択します。
起動テンプレート名や説明を入力します。次に下記のような項目があるので使用したい AMI とインスタンスタイプを選択します。

f:id:shiro-16:20200828120024p:plain

ちなみに仕事では packer + ansible でこちらの AMI に wazuh agent や stns 等をインストールした AMI を作成しています。

最後に高度な詳細 という箇所があるのでそこを開いて一番下のユーザーデータの部分にこのようなスクリプトを書きます。

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: text/x-shellscript; charset="us-ascii"
#!/bin/bash
set -ex
B64_CLUSTER_CA=xxxxxxxxxxxxxxx
API_SERVER_URL=https://xxxxxxxxxxxx.xx.region.eks.amazonaws.com
/etc/eks/bootstrap.sh shiro16-test --kubelet-extra-args '--node-labels=eks.amazonaws.com/nodegroup=shiro16-test-nodegroup,eks.amazonaws.com/nodegroup-image=ami-xxxx' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL

--//--

shiro16-test は自身の cluster 名
shiro16-test-nodegroup は node group 名
ami-xxxx は使用する AMI 名

B64_CLUSTER_CA と API_SERVER_URL に関しては下記のコマンドで取得可能です。

$ aws eks describe-cluster --name shiro16-test --query 'cluster.[endpoint,certificateAuthority]'
[
    "https://xxxxxxxxxxxx.xx.region.eks.amazonaws.com",
    {
        "data": "xxxxxxxxxxxxxxx"
    }
]

これで作成を行えば起動テンプレートの作成も完了です。

さいごに

AutoScale に関しては下記を見れば全てわかる

docs.aws.amazon.com


なぜ移行したではなくするなのかというと来週(8/31)から夏休みなのでその間に万が一何か起こるとだるいという理由だけです。
なので休み明けに移行します。

mackerel-agent を使って異常を検知した際に自動で復旧させる

はじめに

普段会社では監視ツールとして mackerel などを使ったりしているのですが、mackerel を使っている場合 nginx が動いている server のメモリ使用量が一定割合を超えたらエスカレが来るみたいなことをしていると思います。

こういう場合の対応は基本的に nginx を reload させてあげて終わりとなることがほとんどなのでエスカレの電話きてわざわざ人が対応するよりは自動化できた方がいいよね?という気持ちになるわけです。
でそれが mackerel-agent を使えばできますという話。

mackerel-agent の設定

まずは mackerel-agent の conf を用意します。

mackerel-plugin-memory-checker.conf

[plugin.checks.memory]
command = "/usr/local/bin/memory_checker"
action = { command = "bash -c '[ \"$MACKEREL_STATUS\" != \"OK\" ]' && systemctl reload nginx", user = "root" }

これは command が正常に終了しなかった際に action を実行するという意味です。

memory_checker の中身はこんな感じ

#!/usr/bin/env ruby

metrics = {}
File.foreach("/proc/meminfo") do |line|
  if md = line.match(/(MemTotal|MemAvailable):[\s]+([0-9]+)/)
    metrics[md[1]] = md[2].to_i
  end
end

available_percentage = metrics["MemAvailable"] / metrics["MemTotal"].to_f * 100

if available_percentage < 20
  puts "Memory WARNING: #{available_percentage}%"
  exit 1
else
  puts "Memory OK: #{available_percentage}%"
end

メモリの残り容量が 20% をきっていたら exit 1 で異常終了させるというコードになります。
これによって mackerel-agent は conf で記述した action 内のコマンドを実行してくれます。

さいごに

対応方法がほぼ固定化しているエスカレであれば mackerel-agent の機能などを使ってどんどん楽をしていくのが良いと思います。

深夜も平和に寝れるしね