🐙

Kind + Argo RolloutsでK8sの社内勉強会を開く予定の話(手順書)

2024/06/06に公開

概要

経緯

GMOメディアへ入社してから半年が経ちました。
全く未経験のK8s構築を現在進行形で手伝っており、知らん知らんといいながら概要勉強会を1回開催。
そんな合間にZennを始めようとしたところ、オーガナイザーになるは、「K8sの勉強会まだ?」となるはで全部やるの無理なので手順書ここに書いちゃえってことで記事にします。

なぜKind + Argo Rolloutsか

K8sの概要勉強会は入社当時付け焼き刃の知識ながらやりました。
しかし、実際にK8sを動かすということは行なっておらず、次の勉強会の題材に悩んでいました。
そんな中、運用チームへのK8s上でのリリース手順説明の際に、Argo RolloutsのBlue/greenデプロイあたりの理解が薄かったように感じました。
なので今回はマニフェストの内容も説明もしつつ、ローカルからArgo Rolloutsのダッシュボードを使いプロモートしてみましょうという勉強会にしようと思いました。

実際にやること

  • kindでシングルノードのクラスター環境を構築
  • blue/greenデプロイのためのpodを準備(今回はnginxとhttpdを準備)
  • Argo RolloutsのダッシュボードでPromoteしてデプロイしてみる

実践

開発環境

弊社のエンジニアは基本的にMac前提のため、brewでインストールします。
他の環境でも同様のソフトウェアがインストールさえできれば、同じことは可能かと思います。
また、今回はDockerを使うためDocker Desktopやlimaなどを導入している前提での話になります。

使用ソフトウェア

Kind
K8sのクラスターをDocker上で再現するソフトウェアです

Kubernetes IN Docker
略してKindらしいっす
https://kind.sigs.k8s.io/

Argo Rollouts
K8sでBlue/Greenやcanaryリリースをしやすくするソフトウェアです

余談ですがこのタコみてーなやつ好きです
https://argoproj.github.io/rollouts/

具体的な手順

必要なアプリケーションのインストール

Kind

brew install kind

kubectl

brew install kubectl

ArgoRollouts

brew install argoproj/tap/kubectl-argo-rollouts

kustomizeはkubectl kustomizeでもいけるっぽいので今回はなし

Kindによるクラスターの作成

今回はKindメインの勉強会ではないので、設定等はリポジトリとして準備してしまいました
git cloneしていただき、以下コマンドからクラスターを作成してください

https://github.com/Xantibody/argorollouts_demo

クラスター作成コマンド
今回はargorollout-clusterというクラスターを作成

kind create cluster --config kind/kind-cluster-config.yaml --name argorollout-cluster

作成が終了したら念のため、以下のコマンドでクラスターができたか確認

kind get clusters

argorollout-clusterがあれば大丈夫です

ArgoRolloutのインストール

ArgoRolloutをargorollout-clusterへインストールします。
ここでkubectlが登場します。
弊社ではGUI上からの操作が主になると思いますが、基本的にK8sへの操作はkubectlを使います。

まず、ArgoRolloutのネームスペース、argo-rollouts を作成しましょう

kubectl create namespace argo-rollouts

これでできました

以下コマンドを打つとargo-rolloutsが追加されたことがわかります

kubectl get namespaces

では次はArgo Rolloutsをapplyしましょう
-nはネームスペース指定、-fはファイル指定です
本来はローカルのマニフェストを参照してapplyすることが多いですが、今回はArgoRolloutの公式のクイックスタートに載っていた方法を使います

kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

nginxとServiceのリソースをapply

せっかくなのでnginxのネームスペースも作成しましょう

kubectl create namespace nginx

そうしたらプロジェクトのルートで以下コマンドでnginxのrolloutとサービスをapplyしましょう

kubectl apply -k ./

以下でPodが立ち上がったことが確認できます

kubectl get pods -n nginx

kubectl apply-kはkustomizeというマニフェストを合体したり項目の一部を書き換えたりしてくれるコマンドで、今回はルートにあるkustomization.yaml を参照して複数のマニフェストを合体してます

実際に出力されるyamlをみてみましょう

kubectl kustomize

このコマンドで以下のようなyamlが出来上がります

apiVersion: v1
kind: Service
metadata:
  name: nginx-active
  namespace: nginx
spec:
  ports:
  - nodePort: 30080
    port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-preview
  namespace: nginx
spec:
  ports:
  - nodePort: 30100
    port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: nginx-rollout
  namespace: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy:
    blueGreen:
      activeService: nginx-active
      autoPromotionEnabled: false
      previewService: nginx-preview
      scaleDownDelaySeconds: 30
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.19.6
        name: nginx

---で区切られると別のマニフェストとして判別されるため、一度にapplyしても問題ありません
yamlのkind:項目を確認するとRolloutが1つとServiceが2つ計3つのyamlがapplyされています
このKindはリソースの種類を表しているため、今回はRolloutが1、Serviceが2のリソースが作られました

では今回podとして作成されたイメージはどれかというと、ここに記載されているimageとなります
弊社ではここをECRで管理しているため、実際は該当するECRのリポジトリのURLになるはずです

    spec:
      containers:
      - image: nginx:1.19.6
        name: nginx

podの台数はreplicas: 2とあるので2台になります

そして、このRolloutで重要なのがここです

  strategy:
    blueGreen:
      activeService: nginx-active
      autoPromotionEnabled: false
      previewService: nginx-preview
      scaleDownDelaySeconds: 30

blueGreen
strategyの中にblueGreenを定義すればデプロイ方法がblueGreenとなります
他にはCanaryもあります

activeService, previewService
青 → 緑へ入れ替えてデプロイするのですが、そのアクセスするためのサービスを指定しています
active: 青
previe: 緑

デプロイが終われば緑がactiveで表示されます

autoPromotionEnabled
previewでデプロイが完了すると自動でプロモートします
今回は望ましくないのでfalseにします

scaleDownDelaySeconds
プロモートに成功し、新しい環境がactiveになった後も古い環境のpodをここで設定した秒数残します

新しいrolloutリソース(httpd)のapply

ではhttpdのrolloutをapplyしましょう

kubectl apply -f update-rollout.yaml

状態は次の手順で確認します

active, previewの確認

ではそれぞれがローカルで立ちあがってるかアクセスしてみましょう
activeがWelcome to nginx!
previewがIt works!
になっていたら成功です

nginx-active: http://localhost:30080
nginx-preview: http://localhost:30100

ダッシュボードからプロモート

Argo Rolloutのダッシュボードを起動してみましょう

kubectl argo rollouts dashboard

http://localhost:3100/rollouts
でダッシュボードへアクセスできるはずです

Promoteボタンを押下してnginx-rolloutを確認してみましょう
(画像は間違えてリビジョンが増えてしまっています)

ここで書いてある秒数はscaleDownDelaySecondsに書いてある秒数になります
時間が切れれば自動的に最新版でない方のPodがスケーリングしてなくなります

プロモートの確認

ではもう一度Activeをみてみましょう
前回はnginxの画面だったはずですが、httpdに代わっているはずです
nginx-active: http://localhost:30080

また、previewがなくなっているのでPodの合計数も2台になっています

kubectl get pods -n nginx

これで一通りArgoを使ったblue/greenデプロイは完了になります

感想

この記事は当初こんなに長くするつもりがなかったため、冗長になってしまったなぁ〜と反省しています
手順書として使おうと執筆したため、この勉強会も少し長々とやりすぎかな。。。となりそうな予感はしています
次回はもう少し軽い記事を書くようにしようと思いました
作るの大変だと続かないですしね

参考

GMOメディアテックブログ

Discussion