AWS EKSのCoreDNSにおいて、名前解決が失敗する事例とその解決法について

はじめに

どうもrenjikariです。SREです。

AWS Elastic Kontainer Service(以下EKS)環境にて起きた事象の対策が結構たいへんだったので、対応とともに共有しておきます。 もっといいやり方あるぜ!って人はぜひ教えて下さい:bow:

今回の事象には原因が2つあり、それぞれに解決策を用意したため、記事でも原因その① => 解決策その① => 原因その② => 解決策その②という順番で書いていきます

TL;DR

  • EKSにおいてある程度以上のDNS通信がある中で、CoreDNSがshutdownする際に一部のpodで一定時間名前解決ができなくなる
  • 解決策① CoreDNSのhealthcheck pluginにlameduckを導入
  • 解決策② AWS AutoscalingGroupのLifecyleHookで安全に落とすためにNode-drainerを導入

名前解決が一部失敗する話

  • 数ヶ月前、EKS上で動かしているとあるサービスの名前解決が一部失敗していることに気づきました。
  • hpaなどによってpodが増減し、CoreDNSの乗っているNodeがshutdownされるときに名前解決が失敗していることに気づきました。
  • 補足するとCoreDNSはEKSを利用するときのデフォルトで起動しているDNS Cacheサーバ(という言い方であっているか…?)であり、今回の話でもこのCoreDNSを利用しているときに起きたものになります。

CoreDNSのhealth checkと終了時の挙動(一部推測が含まれる)

そもそものpodの終了時についてはこちらの記事がまじでわかりやすい。神。なので省略 https://qiita.com/superbrothers/items/3ac78daba3560ea406b2

CoreDNSはservice + deploymentによって宣言されているリソースで、podの終了時には以下の1及び2が順序制御されずに行われる。

  1. podにshutdown命令がだされる
  2. serviceのendpointの削除命令がだされる

つまり、"serviceのendpointの削除が行われる前"にpodにたどりついたdns要求には(podがshutdown中なので)CoreDNSから応答がないということになる。 このケースを図に書くとこうだ(図とは)

CoreDNS Podにshutdown命令が出される&serviceのendpoint削除命令が出される
↓
CoreDNS Podはshutdown命令により、新規のリクエストからは応答しないようになり、shutdownの準備に入る。
↓
タイミングの問題でServiceのendpointはまだ削除されず、(shutdown中の)CoreDNSに対して新規のリクエストが発行される
↓
CoreDNSは新規のリクエストを受け付けない状態なので応答しない(あるいはshutdownされていてrouting不可)

原因その① 調査編

再現検証

理屈では前述のとおり発生しうることですが、これは本当にどんなclusterでも発生しうるのか、今回起きたclusterでインフラorアプリ特有のなにか踏んでしまっているのかを切り分ける必要があったので新しく検証用clusterを作って、検証を行いました。 結構たくさん検証して紆余曲折したので、あとから振り返って意味のあった検証をピックアップしてこちらに残します。

検証環境について

  • AWS EKS v1.16を使用(ちなみにのちにv1.14でもやって発生した)
  • CoreDNSのversionは1.6.6
  • 以下のmanifestを使用
ore-dns-verification ❯ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dig-deployment
spec:
  replicas: ${そのときに応じて変えた}
  selector:
    matchLabels:
      app: dig-pod
  template:
    metadata:
      labels:
        app: dig-pod

    spec:
      containers:
        - name: dig-pod
          image: giantswarm/tiny-tools
          args:
          - /bin/sh
          - -c
          - while true; do dig freee.co.jp; sleep 300; done;
          livenessProbe:
            exec:
              command:
              - /bin/sh
              - -c
              - dig +time=1 +tries=1
            initialDelaySeconds: 3
            periodSeconds: 1
            failureThreshold: 1
          resources:
            limits:
              cpu: "200m"
            requests:
              cpu: "150m"
  • livenessで名前解決をしているので、名前解決に失敗するとrestartしてわかるという仕組み
  • EKS上にたくさんの名前解決をするpodを並べて、CoreDNSやCoreDNS Podの乗っているNodeを落として、再現検証を行いました。
  • dig Podの数をふやしたり、1Podが行う名前解決数を増やしたりして挙動を確認しました。

結果

  • CoreDNSのpod数やCluster全体のPod数よりもCluster全体のDNSリクエスト数に応じて、この現象が起こるようでした。
  • DNSリクエストが 1k req/secを超えたあたりからCoreDNSやCoreDNSの載っているNodeを落とすと名前解決が失敗するようです。
  • CoreDNSのPod数が2でも10でも発生はしていたので、今回の事象にPod数は関係はない気はしています。

原因その① 対策編

対策方針

  • 方針①
    • preStopでsleep(あるいは何らかの操作を)させる
  • 方針②
    • CoreDNSのhealth pluginに対してlameduckオプションを導入することで終了時にsleepさせる
  • 方針③
    • 各PodのSidecarにDNS Cacheを用意する

これらの対策を考えました。理想的には方針③でいつかはこういう方式にしたいと思ってはいるのですが、 非常にコストがかかるので、一旦諦めました。(というか、方針③を選んだとしても結局今回の対応は安全な終了のために行うべき)方針①と②は大変さも同じくらいなのでどっちでもいいんですが、 以下のようなissueにもlameduck使えばよいというような話も書いてあり、せっかくCoreDNS側で用意されている機能なので方針②を選びました。 https://github.com/coredns/coredns/issues/2984

corefileはこんな感じ。検証では10sでも名前解決が失敗することはありませんでしが(5sでは頻度は激減するもののたまに失敗する)、さらに念の為15sで運用することにしました

 .:53 {
        health {
            lameduck 10s
        }
    (関係ないので略)
    }

原因その②

今回の根本解決のためには解決策その①だけでは不十分でした。 ここでは解決策その①をしてなお失敗する事例を紹介します。

どんなときに名前解決が失敗するか

  • ClusterAutoscaler(以下CA. https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)AWS AutoScalingGroup(以下ASG)の相性が良くないようで、CAがnodeをへらすときにASGがdesiredをフラッピングさせてしまうことがあるようです。
  • CAが正常に(CorednsPodの乗っている)Nodeをdrainしていれば解決策その①によって、CoreDNS Podは終了時にsleepし安全に落ちます。
  • しかし、上記のようにASGのdesiredのフラッピングによって、ASGがInstanceを落とす際にはdrainなどをせず突然落とします。そうするとlameduckを設定していても同様に名前解決が失敗する事象が発生します。

原因その② 対策編

  • ASGがInstanceを落とすときにlifecycle hookによって、安全に落としてあげれば良さそうです。
  • 今回はlifecycle hookの追加とそれをhookしてNodeをDrainするnode-drainerというものを作りました。

やり方

このnode-drainerは思想自体はもとともあったようで、実装もいくつか見かけましたが、そのままK8s上にデプロイできるものが見つからなかったのでマニフェスト等は自分で用意しつつ、 実装はkube-awsのやり方を参考に(というかほぼコピペして)使わせて頂いています。

参考実装の例4つと採用したやりかた

解説

  • ① ASGがInstanceをTerminateしようとする
  • ② Lifecycle Hookに以下の設定を入れておくことで、Status がTermination:waitになる
Name: nodedrainer
Lifecycle Transition: EC2_INSTANCE_TERMINATING
Default Result: CONTINUE
Heartbeat Timeout: 3600
  • K8s上にいるDaemonset node-drainerが定期的に自分のstatusをmetadata経由で監視していて、termination:waitになったら、自分自身に対してdrainをかける
  • ④ とても安全

まとめ

  • はじめにK8s上で名前解決失敗しだしたときは何事かと思いました。
  • いろんな原因とそれに対する複数の解決策を考えて検証してってやっててなんか楽しかったです。
  • 今回の話は全編に渡って、僕一人ではなく、チームで原因調査、検証、実装を行っています。

Kubernetes Upstream Training に参加してきました!

Kubernetes Upstream Traing

どうもrenjikariです。 めちゃ久しぶりに記事書きます。

2020/9/7(月)にCNDT(Cloud Native Days Tokyo 2020)のサブイベント?としてオンラインで開催されていた、 Kubernetes Upstream Traingに参加してきました。してきました、という書き方ですがonlineです。

メインは技術的トピックというよりもKuberentesコミュニティについての話とそこにcontributeする際のやり方や心構えという話でしたが、非常に面白く有意義でしたので共有します。

資料はこちらで公開されていて読めるので、資料だけでは伝わりづらそうなところをまとめていきます。

いつの間にが内容が馬鹿長くなってたので、以降ここだけ読めばいいってとこだけ太字にしておきます。それだけなら5分もかからず読めますたぶん。

はじめに

  • kubeconではこういうeventを前からやっているとのこと
  • kubeconで前回(2019.11)にやったやつを日本語バージョンでやってくれる(優しい、感謝しかない)
  • k8sのupstreamにcontributeできる人を増やす

kubernetes コミュニティについて

このセッションの感想

  • このsessionがめちゃめちゃ有用でした
  • K8sを使うことはしていても無数(は言い過ぎ)にあるK8sのgroupがどんな役割なのか、どうやって参加できるのかなどについて話してもらえました

sessionのまとめ

  • contributeについて
    • Kubernetesコミュニティは誰でもcontribute可能
    • K8sに貢献する理由は様々だが、仕事の中で、仕事に沿った形で貢献すればよい
    • 自身でどこに貢献できるかをさぐる冒険をしてほしい
  • コミュニティについて
    • コミュニティのあり方
      f:id:renjikari:20201002205613p:plain
      1ページだけの引用ができなかったのでスクショ引用元は https://github.com/kubernetes-sigs/contributor-playground/blob/master/japan/cndt-2020/docs/k8s-upstream-training-cndt-2020.pdf
      • 集中よりも分散
      • プロセス全体の自動化
      • プロダクトや会社を超えたコミュニティ
      • 排他的よりも包括的
      • 進化は停滞よりもよい
      • "文化が戦略を喰らう"
    • コミュニティの構成
      f:id:renjikari:20201002205343p:plain
      引用: https://github.com/kubernetes/community/blob/master/kubernetes_governance_diagram.png
      • SIGs(Special Interest Groups)
        • メインのグループ
        • そのほかはSIGsをサポートする役割
        • SIGsの中でsubprojectsが別れていて、subprojectがK8sの特定の場所のコードオーナーになっている
      • WGs(Working Groups)
        • あらかじめ期日がきめられているグループ
        • 特定の期間活動する
        • コードオーナーはもってない
      • UGs(User Groups)
        • end userが特定の機能を推進する場所
        • コードオーナーはもってない
      • Committees
        • code of conductやsecurityや機密的なセンシティブ内容をあつかう
        • steering commeetie(K8sコミュニティの偉い人)とかから選出される
  • コミュニティの細かい話
  • SIGs
    • K8sは2000以上のcontributersがいて、巨大なので階層化されている
    • ざっくり説明すると、SIGsは"charter"と呼ばれる約定のようなものを持っていて(なんと訳せばいいかわからなかった)それの中で、SIGsのガバメントや、コードのオーナーシップ、subproject、working groupについての情報を定義しています。
    • SIGもさらに複数のタイプ(がありますが結パット見でむずかったので、例とともに書いておきます)
      • Vertical: Network, Storage, Node, Scheduling
      • Horizontal: Scalability, Architecture
      • Project: Testing, Release, Docs, PM, Contributor Experience
    • project SIGsにおもろいのが一個あったので紹介します
      • sig-contribx(上で言うContributor Experienceになります)
        • contributerの健康とか貢献しやすさみたいなところをみるらしい
    • SIGにどう入るか
    • コミュニケーションについて
      • これはSIGsだけじゃなくて全部同じようなものだと想像されますが、以下のようなものでコミュニケーションされています。
        • mailing list
        • slack
        • google groups
      • 相互のリスペクトが健全なコラボレーションに必要だと信じられている

開発について

  • githubのレポジトリについて
    • 当然ですが、K8sgithub organizationの中には複数のrepositoryがあり、K8s本体のものだけでなくいろいろなものがあります。わかりやすそうなやつを列挙してみます
      • kubernetes/kubernetes
        • 本体
        • api/build/cmd/pkgなど
        • セッション中には、kubectlを読みたいと思ったら直感的にはcmd/kubectlの中にありそうだがmain codeはstaging/src/k8s.io/kcubectl配下にあるので、そういう読み方の慣れは必要だったりする
      • kubernetes/community
      • kubernetes/website
  • 開発環境について
    • localでbuildするなら結構リッチなものが必要
    • ビルドするの結構重い
      • CPU8コア/ memory32GBでも15分かかるとのこと
    • すくなくとも6GBのメモリを専有する
  • 開発のサイクル
    • repositoryにより様々ではあるが、大体は以下
    • 3month(12weeks)で1イテレーション
    • 仕様決定 => 開発(~Weeks 8) => code freeze(Weeks 9~11) => Post-Release(Weeks 11+)
      • code freezeはバグを修正したり、機能についてのdocumentがちゃんと整備されているか(少なくとも誰が責任をもってdocを書くか)を精査する時間
  • testについて

コントリビューション実践(心構え的な話)

  • OSSで貢献する心構えの話

  • 何がコントリビューションなのか

    • なんでもコントリビューションになりえる
    • コードを書くのだけでなく、docを書いたり翻訳したり、自分のほしい機能やバグについてissuesを書くだけでも貢献になる
    • また、今回CNDTにて開いていただいたこういう新contributor育成もコミュニティ貢献の一つ(そういう意味ではこのブログも遠回しな貢献になると願って:pray:)
  • First PR Ideas
  • reviewalbe codeにすること
    • reviewerのやることを簡単にしてあげる
    • 特にcommit massageは重要
  • contributeのプロセス
    • 時間がかかることを認識する
    • quality vs speed

ハンズオン

まとめ

こういったcontributor育成の機会を開いていただいてすごくためになりました。開催してくれた方たちに大変感謝してます。

冒頭でも触れましたが、たくさんあるSIGsやWGsについて紹介していただいて(あとこれを書くために自分で調べて)なんとなく全体感がつかめた気がします。

3年間勤めたNTTコミュニケーションズを退職します

表題の通り、3/31を持ちまして、新卒より3年間勤めましたNTTのコミュニケーションズ(以下、NTTコム)を退職します。

TL;DR

いわゆる退職エントリです。一時期NTTの退職エントリなるものが流行りましたが、NTTコムの退職エントリはあんまりなかったと思うので書き留めて置こうと思った次第です。 おそらくすでに出ている複数のエントリと同じようなことしか書いておらず、完全にチラ裏なので見たい人だけ見てくださればと思います。

また、本記事の全ては個人の見解に基づくもので、所属する組織、団体の公式見解ではありません。

NTTコムについて(の感想含む)

いわずと知れた大企業であり、代表的なサービスとしてOCN*1があります。 私はR&D系の部に属しており、残念ながら多岐に渡る部やサービスのすべてを把握できていないので、書かせていただくのは主に所属していた部署についてとなります。

私の仕事

自社向けの社内システムやR&D周りのwebアプリやコントローラなどを書くSoftware Engineer(以下、SWE)として働いていました。 その他にも社内検証網の開発運用なども担当し、実務を通したネットワークや物理環境の経験なども積ませていただきました。

とにかく働きやすい

服装がほぼ自由、フレックス(そのうえ時間休を組み合わせられる!)、理由の問わないリモートワーク、取り放題の年休と、最高の環境でした。 新入社員のころから社会を舐めたような(個人の感想です)服装をしていても、特になにも言われることなく過ごすことができましたし、1年目からかなり多くの年休と夏休みが付与されます。

いい人が多い&すごすぎる人がいる

関係する人が非常にいい人ばかりで、不快な思いをすることや日本語が通じないことがほとんどありません。 また、主に日本のネットワークやインターネットを切り拓いてきた人が多数在籍しており、めちゃめちゃすごい人がめちゃめちゃすごいです(語彙)。

ネットワークについて

部署によると思いますが、ネットワークの基礎的なところはいつの間にか身につきます。 今でも勉強中ではありますが、他の分野でも頻繁に必要になるような 基礎的なネットワーク知識については研修や普段のいたるところの業務から身につける事ができます。 SWE職についているとインフラ周りのスキルが伸びづらい環境の人も多いと思うので、非常にためになりました。 また、インターネットの歴史や外に出せないような話なども聞けて、元から好きだったインターネットがもっと好きになりました。

退職事由

大きな不満はありませんでしたが、それでも退職する決断をいたしました。 端的に言えば「今、NTTコムにいる理由が薄い」と感じたためです。詳細を3点ほどに分けて説明します。

エンジニアとして一番成長できる場所か

webアプリを書くのがメインの仕事でしたが、アプリケーションについてはすでにチームで一番わかる、という状態になっていました。 完全に私個人の悪癖なのですが、自分よりできる人がいてその人を追いかけるくらいの気持ちでいないとすぐにサボり始めます。 当然まだまだエンジニアとして未熟な私としては、指導できる人(いわゆる強い人)と働きたく思っていました。 20代後半という時期を投資したいと思える場所を探そうと、転職活動をしていました。

キャリアパス

まず、エンジニアとして働き続ける(=スペシャリストとして給与を上げる)キャリアパスがほとんどありません。 私自身はマネージメントも興味がありますが、多様性のあるキャリアパスのある会社(や環境)で働きたいと思っていますし、エンジニアである間も給与をあげる制度があるといいなと思っていました。

style.nikkei.com

最近こちらの記事が話題になりましたね。記事になっている通り様々な営みが行われており、実際すこしずつ形になってきています。 私自身もエンジニアが楽しく働ける環境を目指して、及ばずながら様々な(e.g. NTT Tech Conference - connpass)活動もしていました。ただ、理想に近づけようとする最高の仲間たちがいる一方で、なかなかうまいように進んでいない実感もありました。

また、(resumeを書いたり転職活動して気づいたことだが)エンジニア職の原初風景がインフラにあるのも影響してか、 キャリアパスとしては「インフラを担当するソフトウェアエンジニア」になりたいと現時点では*2思っております。 ただ、NTTコムにはそういったポジションはあまりなさそうだと感じ、興味が外に向かっていきました。

給与制度

定年まで考えたときに決して低くはない給与をいただけます。ただ、学部卒の私は、最初の昇格まで5年を要します。(昇格しなくても一応ゆるゆると給与は上がっていきます) 順調に出世(昇格)を続け、30代半ばころになれば十分な給与を貰えるのですが、そこにたどり着くまでに10年近くあり、平たく言えば待てなかったです。

謝辞

今まで業務で関わったすべての方、及び身勝手な理由により退職を決めた僕を円満に送り出してくださった上長、チームメイト、同期の皆様に最大限の感謝の意を表します。

f:id:renjikari:20190331200757j:plain
親愛なる同期が洒落で作ってくれた卒業証書

最後に

なんだかんだ書いてますが私はNTTコム好きです。なんならいつか戻りたい。 NTTコムが労働者にとってより働きやすく魅力的な会社になることを願っています。

*1:たくさんのサービスがありますが詳細は省きます

*2:明日には変わってるかも

TDDの権化、t_wadaさんによるTDDワークショップに参加しました

t_wadaさんによるTDDの1dayワークショップに参加しました

2018/2/27(火)にTDDのスタンドの使い手 id: t-wada さんによる、1日ワークショップに参加してきました。 一ヶ月以上もブログ書くのが遅れてしまった…

ワークショップアジェンダ

ワークショップは以下のような流れですすみました。

  • TDDについての講演
    • 講義とライブコーディング
  • ペアプロ
    • 全員参加のコードレビュー大会

TDDについての講演

テスト駆動開発とは何かというところから始まり、TDDがうまくいかない(主に技術的でないもの)原因を学び、TDDを実際に行うためのサイクルをライブコーディングを交えつつ披露していただきました。

こちらの詳細な内容については、 以下で非常によくまとめていただいていたので詳しい内容は割愛して僕の感想だけ書こうと思います。(講義時のメモをまとめたら全く同じ内容の記事ができてしまったため)

developer.ntt.com

予測可能性について

講義の中で、今はまだソフトウェアが工学(Engineering)になりきれておらず、予測可能性が低いという話をされていました。

まさに目からウロコといった表現で、実体験としてこういうことを感じており非常に心に響きました。言い方をかえると「書いてみないとわからないことが多い」という当たり前のようなことですが、設計してるときはついつい忘れがちになります。 わりと緻密に設計をしたつもりでも、いざコードを書いてみると全く想定していないところで動かないことは頻繁にあり、今までは単に「辛い」と女子高生のような語彙力の低さを撒き散らしていたので、これからは「予測可能性が低いから(キリッ)」と言おうと思います。

どうやって「動作するきれいなコード」へいくか

ソフトウェア工学の世界では予測可能性が低いので「動かない汚い -> 動く汚い -> 動くきれい」(動かない汚いって単体で見るとすごい表現だな)というステップを踏もうとします。 そのために取れる手法のうちの一つがTDDというわけです。 しかし、このステップを進もうとするときにどす黒い感情が我々の前に立ちはだかります。

  • 堕落
    • 動いてればいいじゃん
  • 焦り
    • 動いているから、もっとほかのところ、次のところをやるべきではないか
    • 内発的な焦りと外発的なプレッシャー
  • 恐れ
    • 動くコードをきれいにしていく過程で動かなくなったら意味ないじゃん
    • しかし、ソフトウェアの世界が日進月歩なので動いているものを手をいれて変えないと、いつか動かなくなる

これらはそれぞれ誰にでも経験があるだろうことで、もっと言えばみんな上司とか偉い人から言われたことあるよね????(ぼくはあるよ)。

こいつらを乗り越えないと「動かない汚い -> 動く汚い -> 動くきれい」といった順番に乗れず、予測可能性が低い方法(しつこい)を取らざるを得なくなったり、動くけど汚いコードのまま過ごすはめになるわけです。

TDDではこの中でも特に「恐れ」に対抗する手段としてとれる手法とおっしゃっていました。

TDDのサイクル

- 次の目標を考える
- その目標を示すテストを書く
- そのテストを実行して(予想どおり)失敗させる(Red)
- 目的のコードを書く
- テストを成功させる(Green)
- テストが通るままでリファクタリングを行う(Refactor)

TDDのサイクルを載せました。TDDではこの中でもrefactoringが一番折れやすく、ないがしろになりやすい(「堕落/焦り」ですね)のでここは普段のプログラミングや日課に紛れ込ませてやるのがいいとおっしゃっていました。

(例えば、テストと目的のコードをたくさん書いたあと、次のスプリントはまるまるリファクタリングさせて下さい! よりも日々の中にリファクタリングを積んでしまったほうが良い。スプリントまるまるリファクタリングに費やすと新規機能が0なのでSMやPOからしても指示や承諾がしづらい)

ペアプロとコードレビュー大会

さて、午後からはペアプロの時間でした。お題は Semantic Versioning(参考: Semantic Versioning 2.0.0 | Semantic Versioning)です。

1時間半程度のペアプロをしてその後全員参加のレビュー大会をする、という流れを二回繰り返しました。

載せて良いのかわかりませんがその時のペアプロしたものと、あとからいろいろと変更を加えたものをおいておきます。

github.com

私はpython3 + unittestを利用して課題に取り組みました。 行った感想としては

  • ペアと一緒に要件を書き出していって、書き出した順に実装していたのですが、もう少し順番を考えたほうが良かった。
    • 今回はスピード勝負ではないので問題ないといえば問題ないんですが、一番複雑なところから手を付けてしまった。
  • 要件の洗い出しについては「近いところを詳しく、遠いところはざっくりと」ということをt_wadaさんがおっしゃっていて、非常に重要な感覚だなぁと思いました。色々な要件を実装する際に最初からすべて考えようとすると、前提条件の実装が動いていないので非常にコストがかかる感じがしました。そろそろ実装するぞ(=近い所)というところだとすぐ実装を決められます。最初から全ての要件を綺麗にしようとすると予測可能性があれということをこの時間のうちに体感できました。
  • python的な書き方に少々つまずき、綺麗でない実装になってしまった
    • ちゃんとgitに上がっているやつは直しています。commitログをみるとすごい複雑なif文が表れますw

全体的な感想

  • Testを書くこと自体もそれほど得意ではなく(やったことはあるが体系的に学んだことがない)、TDDに関しては完全にノータッチだったのでイチから学ぶ機会を頂いて非常に良かった。
  • 単純にペアプロしてレビューするのが楽しかった。
  • 企画してくれた先輩にとっても感謝します。

マイグレーションコンペティション 2018で優勝してきました

マイグレーションコンペティション 2018に参加して優勝しました!!!!!!!!!111

マイグレーションコンペティション 2018 winter

詳細は以下のURLより御覧ください

日本MSP協会のコンペティション担当による、運用技術を競うコンペティションです。次代を担う若手運用技術者同士の交流・競争を通して日本のMSP事業者における運用技術の向上を目的としています。

とのこと。

今回は EC2の1インスタンスにいるWebAppDBサーバその他もろもろをAzure上に移行する、というお題でした。

優勝のご様子 f:id:renjikari:20180129000822j:plain

メンバー

運営が当日ランダムでチームを組むのですが、チームメンバーはid:kani_bさんと大阪からいらっしゃっていたokazakiさんでした。 主にid:kani_bさんがDB周りの移行とチームマネジメント(リーダー)、okazakiさんがWebAppの移行、私がメール周りの移行を担当しました。 メール周りなんて大学生ぶりにさわるのでまじで怖かった

お題詳細

今回のお題はEC2サイトの移行ということで、移行元サーバには以下のような物が稼働していました。

最終的な方針

私達のチームでは最終的に以下の方針で移行を進めていきました。

  • ミニマムなところから移行し、お題の必須項目を完璧にやる
    • これができたら+αをやっていく
  • 具体的な方針
    • サーバ切替時にはメンテナンスを入れる
    • バージョンアップは無理せず, CentOS7.4のデフォルトパッケージでyumインストールされるものを利用する

覚えている感じのタイムスケジュール

今回は競技時間が10:30 ~ 17:00でした。

11:30 頃まで

自己紹介と移行元サーバの把握をしていました。また、リーダーの提案でgithubリポジトリを作成し、issueで進捗管理をすることに。(これとても良かった) また、予算がいくらくらいあるのかを担当者に確認し、現行の+-20%程度にしてくれという回答をもらいました。 この時点でAzureを使うと冗長化できなさそうかな〜みたいな話をしていました。

13:00 頃まで

途中ご飯を食べながら方針を決め始め、それぞれの役割分担を決定。このときはまだ、無停止でサーバ切り替えできないか模索していました。確か、MySQLを旧新サーバでレプリケーションしてデータ移行させれば無停止でいけるんじゃ?みたいな議論をしていたと思います。

担当者にはDNSTTLを60秒にしてもらうことと、サイトでなんらかの作業がある場合は14時までに実施してもらうよう連絡していました。(商品追加の作業があると言っていた気がする)

14:30 頃まで

チームとしてはそれぞれの移行をやっていましたが、MySQLのrootが取れないことが判明。root取れないとレプリケーションが組めないし、root取るためにはMySQLの再起動が必要なのでここで無停止を諦め、メンテナンスを入れてrootを乗っ取ることに(14:00頃)

私はメールサーバの移行をしていまして、saslを触ったことがなかったので、そこを一旦無視してPostfixDovecotの移行をやっていました。たぶんここらへんで/etc/postfixと/etc/Dovecotをごっそり移し替えて起動するくらいまではできていたような気がする。

15:30 頃まで

この頃にEC-CUBE及びメールサーバがほぼほぼ移行完了し、そろそろ切り替えれるんじゃないかみたいな話になっていました。

私はというとsaslをググったらそんなに大変そうじゃなかったので移行元サーバをまるぱくり、間違いがないかpostconf -nやdovecot -nを読んでいたのですが、virtual mailboxの設定をしていないことに気づき、/var/spool/vmail(だったような)の移行を開始。 ディレクトリ自体はそのままrsyncしたんですが、移行元サーバに/var/spool/vmail/をホームディレクトリとするvmailユーザがいたのでやり方に不安を覚えつつ/etc/passwdと/etc/shadow, /etc/groupを移行して、vmailユーザを作成しておきました。(これどうすればよかったのかな…)

16:30 頃まで

担当者に連絡し、16:00からサーバ切り替え作業とDNS切り替え作業を実施。移行が完了

17:00 まで

残りの時間で、id:kani_bさんがAzureのバックアップを作り、okazakiさんを中心に引き継ぎ&実施した内容のドキュメントを作成(Google Docsで作った)、私はドキュメントを手伝いつつlinuxユーザの整備などをしていました。

全体的な感想

ながながと書きましたが、だいたいこんな感じで進めていて、優勝をいただくことができました。 率直に言って最高だった(勝ったから)。 一番良かったのは、必須項目以外はやらない、位の勢いでもろもろを切り捨てる方針で進められたことだと思います。 あとid:kani_bさんのエンジニア視点のマネジメントが最高だった。 ぜひ来年も遊びに行きたいと思います。