この記事は WESEEK Advent Calendar 2020 25日目の記事です。
はじめに
皆さん Kubernetes (以後 k8s) 使ってますよね!最近では本番環境上でも k8s を採用する事例を見かけるようになってきました。
今回は前向きな夢の話ではなく、ちょっと泥臭いお話です。
Sorry Page って何?
下記の画像のような「サービスがメンテナンス中だよ」ということを訪問者にお伝えするページです。
サンプルは弊社で提供しているサービスの GROWI.cloud の Sorry Page です。
宣伝: GROWI.cloud は、Markdown で書ける wiki GROWI を簡単に使い始めることができるサービスです。GROWI や同時編集機能を使うための HackMD を構築する手間を大幅に削減できますので、GROWI.cloud を是非ご利用ください。
なんでやろうと思ったの? (モチベーション)
k8s を運用していくにあたって、「落ちないサービス」や「メンテナンス時間が発生しないサービス」を構築することが理想的だとは思います。(だって、そういう仕組みが用意されているんだもの)
ですが、どうしても一回ユーザからのアクセスを止めてから作業を実施した方が安全なこともあります。(なるべく止めないように試行錯誤するにしたとしても)
それに加え、いざというときにアクセスを止める手段があるという保険的な安心感も得られます。
Sorry Page イメージの作り方
では Sorry Page のイメージを作るための準備を進めていきましょう。
こんな感じのディレクトリ構成でファイルを用意します。
.
├── README.md
├── assets
│ ├── css
│ │ └── Sorry Page に必要な CSS
│ ├── favicon.ico
│ ├── img
│ │ └── Sorry Page に必要な 画像
│ ├── js
│ └── Sorry Page に必要な JS
├── docker
│ ├── Dockerfile
│ └── nginx
│ └── front.conf.template
├── index.html
└── kubernetes
└── deployment.yaml
各種ファイルの内容を紹介していきます。
index.html
, assets
は Sorry Page 自体の HTML, CSS, JS などを書いておきます。
Dockerfile
は基本的に nginx イメージをベースに nginx 用のコンフィグファイル、index.html, assets が含まれるように COPY や ADD をしています。
# HOW TO BUILD:
# $ docker build -t growi-cloud-sorry: -f docker/Dockerfile .
FROM weseek/nginx-auth-ldap:xxxxx
LABEL maintainer="XXX XXXX <xxxxxxx>"
LABEL description="This image is used for running to serve application files"
LABEL app=growi-cloud
LABEL role=release
LABEL component=nginx
COPY docker/nginx/front.conf.template /etc/nginx/conf.d/default.conf.template
COPY . /usr/share/nginx/html/
# kubernetes のヘルスチェック用のファイル
RUN touch /usr/share/nginx/html/.health-check
front.conf.template
は /usr/share/nginx/html
配下のファイルを配信できるシンプルな設定にしています。
# BASED ON nginx:1.13.6-alpine /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
gzip off;
# Cache-controlを付ける
add_header Cache-Control "max-age=0, public";
location / {
root /usr/share/nginx/html;
# redirect to https if accessed via http
if ($http_x_forwarded_proto = "http") { return 301 https://$host$request_uri; }
add_header Cache-Control "max-age=0, public";
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
kubernetes
ディレクトリ配下は、k8s クラスタに Sorry Page イメージを deploy するときに使う manifest です。
deployment.yaml
の image の部分は example.com
で置換しています。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: growi-cloud-sorry
name: growi-cloud-sorry
namespace: growi-cloud
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: growi-cloud-sorry
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: growi-cloud-sorry
spec:
containers:
- image: example.com/growi/growi-cloud-sorry:master
imagePullPolicy: Always
name: growi-cloud-sorry-demo
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
restartPolicy: Always
イメージのビルド
Dockerfile
の中にコメントとして書きましたが、作成したプロジェクト用のディレクトリトップで docker build
を実行します
$ docker build -t growi-cloud-sorry -f docker/Dockerfile .
k8s クラスタにデプロイして、Sorry Page に誘導する
想定する構成は下記の通りです。色々と省略していますが、サービスに対するアクセスの導線は ユーザ -> Ingress -> Service -> Pod
という流れでリクエストが受け渡される、という前提とします。
deployment.yaml
を k8s クラスタに apply して、Sorry Page イメージを deploy します
kubectl apply -f kubernetes/deployment.yaml
反映されると、下記の図のように GROWI.cloud Sorry Page Pod に向け変えができるような状態になります。
この状態で GROWI.cloud Service の内容を kubectl edit ...
で書き換えることで、向け先を変えます。
Service は selector
の部分を growi-cloud-sorry
に書き換えます。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: growi-cloud # <- ここを growi-cloud-sorry に書き換える
(省略)...
アクセス先の切替方法
ここは非常に議論を呼びそうですが、 GKE Ingress の書き換えを実施すると反映に多少時間がかかるので、切替方法は用途に応じて実施するのが良いと思います。
- 即座にメンテ画面に変えたい場合は Service を書き換えて切り替える
- 時間に余裕がある場合(計画メンテなど)には GKE Ingress 側を書き換えて切り替える
最後に
今回は下記の流れで Sorry Page イメージの紹介をしました。
- Sorry Page イメージの作り方
- 作った Sorry Page イメージを k8s クラスタにデプロイする方法
- Sorry Page Pod へのアクセス先の切り替え方法
いざというときには助かるかもしれませんが、なるべく Sorry Page イメージに頼らないで、サービス運用ができるように目指して行きたいですね