はじめに
Kubernetesのエコシステムの中に、CDツールの役割としてSpinnakerが存在しています。今回は、On-Prem環境のKubernetesクラスタ環境で、SpinnakerとKayentaを利用したCanaryリリースの手法を確認します。
環境情報
Kubernetesクラスタ : 1.11.3 (kubeadmで構築済)
Halyard導入マシン : Ubuntu16.04
Halyardバージョン : 1.10.1-20180912131447
Spinnakerバージョン : 1.9.4
前提作業
Halyard Install用マシンを準備
Spinnakerには、InstallerツールのHalyardというものが存在しています。Spinnakerの全機能を使用するために、Halyardが必要です。Halyardを導入するUbuntu16.04を適当に準備します。
kubectl Install
Halyard導入マシンで、kubectlコマンドを実行可能である必要があります。kubectlのバイナリファイルをダウンロードします。
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
実行権限付与して、所定の場所に移動
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubernetes masterから config ファイルを転送
mkdir ~/.kube
scp config sugi@10.44.67.25:/home/sugi/.kube/
実行確認
sugi@qicoo-halyard:~$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
qicoo-k8s-master01 Ready master 1d v1.11.3 10.44.67.21 <none> Ubuntu 16.04.5 LTS 4.4.0-135-generic docker://18.6.1
qicoo-k8s-node01 Ready <none> 1d v1.11.3 10.44.67.22 <none> Ubuntu 16.04.5 LTS 4.4.0-135-generic docker://18.6.1
qicoo-k8s-node02 Ready <none> 1d v1.11.3 10.44.67.23 <none> Ubuntu 16.04.5 LTS 4.4.0-135-generic docker://18.6.1
Minio Install
Spinnakerは、ストレージ領域が必要です。Azure Storage, GCS, Redis, Minio, S3 をサポートしています。On-Premでも使用可能なMinioを採用します。
Minioは、KubernetesにDeploymentとして導入する形にします。なお、制限事項として、SpinnakerはMinioにアクセスするときに、IPアドレスの指定ではなく hostname を指定してアクセスする必要があります。(IPアドレスだとエラーになりました)
色々方法がありますが、Kubernetes内部にMinioを導入して、ClusterIP経由で名前解決をする構成にします。
Minioは、KubernetesでPVCを使用します。事前に準備が必要です。
マニフェストファイルを作成し、applyすることで、Minioをうごかすことが出来ます。
cat <<'EOF' > ~/manifests/minio.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: minio-pv-claim
namespace: minio
annotations:
volume.kubernetes.io/storage-class: "nfs"
labels:
app: minio-storage-claim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
storageClassName: slow
resources:
requests:
storage: 20Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: minio-deployment
namespace: minio
spec:
strategy:
type: Recreate
template:
metadata:
labels:
# Label is used as selector in the service.
app: minio
spec:
# Refer to the PVC created earlier
volumes:
- name: storage
persistentVolumeClaim:
# Name of the PVC created earlier
claimName: minio-pv-claim
containers:
- name: minio
# Pulls the default Minio image from Docker Hub
image: minio/minio
args:
- server
- /storage
env:
# Minio access key and secret key
- name: MINIO_ACCESS_KEY
value: "Y2ADIFUQQQWXPEX9XP0I"
- name: MINIO_SECRET_KEY
value: "wY/9iXSzd3huAPAMd7+h0cDNYCxaLtkyp+cDjoMo"
ports:
- containerPort: 9000
# Mount the volume into the pod
volumeMounts:
- name: storage # must match the volume name, above
mountPath: "/storage"
---
apiVersion: v1
kind: Service
metadata:
name: minio-service
namespace: minio
spec:
type: NodePort
ports:
- port: 9000
targetPort: 9000
nodePort: 32003
protocol: TCP
selector:
app: minio
EOF
kubectl apply -f ~/manifests/minio.yaml
PrometheusOperator導入
Spinnakerを使用したCanary分析を行う場合、Metricを基に分析を行います。現段階で、Canary分析のため以下の3種類がサポートされています
- Stackdriver (GCE)
- Prometheus
- Datadog
今回は、On-Premisでも使用可能な、Prometheusを採用します。Kubernetes内部にPrometheusを作成します
git clone https://github.com/coreos/prometheus-operator.git
cd prometheus-operator/contrib/kube-prometheus
kubectl create -f manifests/ || true
ClusterIPとなっているPrometheusとGrafanaをNodePortとして公開させます。現状は、ClusterIPとなっています。
root@qicoo-k8s-master01(monitoring kubernetes-admin):~/prometheus-operator/contrib/kube-prometheus/manifests# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.110.255.240 <none> 9093/TCP 15m
alertmanager-operated ClusterIP None <none> 9093/TCP,6783/TCP 8m
grafana ClusterIP 10.99.235.238 <none> 3000/TCP 15m
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 15m
node-exporter ClusterIP None <none> 9100/TCP 14m
prometheus-k8s ClusterIP 10.108.141.140 <none> 9090/TCP 14m
prometheus-operated ClusterIP None <none> 9090/TCP 8m
prometheus-operator ClusterIP None <none> 8080/TCP 15m
editで編集します。
kubectl edit -n monitoring svc prometheus-k8s
spec:
clusterIP: 10.108.141.140
ports:
- name: web
port: 9090
protocol: TCP
targetPort: web
nodePort: 32292 <-- here
selector:
app: prometheus
prometheus: k8s
sessionAffinity: None
type: NodePort <-- here
editで編集します。
kubectl edit -n monitoring svc grafana
ports:
- name: http
nodePort: 32036 <-- here
port: 3000
protocol: TCP
targetPort: http
selector:
app: grafana
sessionAffinity: None
type: NodePort <-- here
正常にNodePortでアクセスできます。
root@qicoo-k8s-master01(monitoring kubernetes-admin):~/prometheus-operator/contrib/kube-prometheus/manifests# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.110.255.240 <none> 9093/TCP 22m
alertmanager-operated ClusterIP None <none> 9093/TCP,6783/TCP 15m
grafana NodePort 10.99.235.238 <none> 3000:32036/TCP 22m
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 22m
node-exporter ClusterIP None <none> 9100/TCP 22m
prometheus-k8s NodePort 10.108.141.140 <none> 9090:32292/TCP 22m
prometheus-operated ClusterIP None <none> 9090/TCP 15m
prometheus-operator ClusterIP None <none> 8080/TCP 22m
アクセス確認 (IPアドレスは各環境に合わせて書き換えてください)
Prometheus
http://10.44.67.21:32292/graph
Grafana
http://10.44.67.21:32036/
admin / admin
Halyard構築
Halyardをダウンロードし、Install ShellScript を実行します。
curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh
sudo bash InstallHalyard.sh
実行例
halyard/bin/halyard.bat
halyard/bin/hal
halyard/bin/halyard
hal
update-halyard
~
The halyard daemon isn't running yet... starting it manually...
1.10.1-20180912131447
Would you like to configure halyard to use bash auto-completion? [default=Y]: y
sugi@qicoo-halyard:~$
version確認
sugi@qicoo-halyard:~$ hal -v
1.10.1-20180912131447
bash complete読み込み
. ~/.bashrc
Halyard設定
Cloud Provider
Halyard の Deploy Provier を指定
hal config provider kubernetes enable
account の追加
hal config provider kubernetes account add kubernetes-admin \
--provider-version v2 \
--context $(kubectl config current-context)
artifacts を有効化
hal config features edit --artifacts true
environment
account は、kubectlで使用するuser name を指定します
hal config deploy edit --type distributed --account-name kubernetes-admin
External Storage
minioの SECRET_KEY と ACCESS_KEY, ENDPOINT を変数にいれます
MINIO_SECRET_KEY=wY/9iXSzd3huAPAMd7+h0cDNYCxaLtkyp+cDjoMo
MINIO_ACCESS_KEY=Y2ADIFUQQQWXPEX9XP0I
ENDPOINT=http://minio-service.minio.svc.cluster.local:9000/
Halyardに設定します
echo $MINIO_SECRET_KEY | hal config storage s3 edit --endpoint $ENDPOINT \
--access-key-id $MINIO_ACCESS_KEY \
--secret-access-key
s3 (minio) を使用するように設定します
hal config storage edit --type s3
minioはs3と違ってバージョニングが出来ないため、以下の指定を行います
mkdir ~/.hal/default/profiles/
cat <<'EOF' > ~/.hal/default/profiles/front50-local.yml
spinnaker.s3.versioning: false
EOF
Slack通知を有効化
tokenなどの環境変数設定
TOKEN_FROM_SLACK=himitu
SPINNAKER_BOT=SpinnakerBot
hal config notification slack enable
echo $TOKEN_FROM_SLACK | hal config notification slack edit --bot-name $SPINNAKER_BOT --token
GitHubにアクセスできるように設定
SpinnakerがGitHub上に公開されているManifestsファイルにアクセスできるように、GitHubの認証情報をHalyardに設定します
参考URL
https://www.spinnaker.io/setup/artifacts/github/
- GitHub上でTokenを作成。Scopesはrepo配下全てを選択
- 以下コマンドでfileを作成し、Halyardが読み込み可能な権限で配置しておく (/root配下などはNG)
TOKEN=himitu
mkdir ~/github_tokens
echo $TOKEN > ~/github_tokens/spinnaker_tutorial.txt
変数に設定
TOKEN_FILE=~/github_tokens/spinnaker_tutorial.txt
ARTIFACT_ACCOUNT_NAME=Sugi275
HalyardでGithubを扱う設定を入れます
hal config features edit --artifacts true
hal config artifact github enable
GithubのArtifactを設定します。同一名称で複数登録出来るため、注意。
hal config artifact github account add $ARTIFACT_ACCOUNT_NAME \
--username Sugi275 \
--password \
--token
DockerHubの設定
変数の設定
ADDRESS=index.docker.io
REPOSITORIES=sugimount/spin-kub-v2-demo
USERNAME=sugimount
PASSWORD=himitu
hal config provider docker-registry enable
echo $PASSWORD | hal config provider docker-registry account add sugimount \
--address $ADDRESS \
--repositories $REPOSITORIES \
--username $USERNAME \
--password
Timezoneの設定
使用可能なTimezoneは以下のwikiから選択可能
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
hal config edit --timezone Asia/Tokyo
kayentaを導入
canary を有効化。canaryの分析で利用するkayentaを利用するためにストレージが必要なため、S3互換のMinioを利用します。
そのために、halとしては aws を enable にする必要があります。
hal config canary enable
hal config canary aws enable
canary config をglobalに見せないようにする
hal config canary edit --show-all-configs-enabled false
変数にMinipのAccess key IDなどを設定
MINIO_SECRET_KEY=wY/9iXSzd3huAPAMd7+h0cDNYCxaLtkyp+cDjoMo
MINIO_ACCESS_KEY=Y2ADIFUQQQWXPEX9XP0I
ENDPOINT=http://minio-service.minio.svc.cluster.local:9000/
account追加
echo $MINIO_SECRET_KEY | hal config canary aws account add myawsaccount --bucket spin-bucket --access-key-id $MINIO_ACCESS_KEY --secret-access-key --endpoint $ENDPOINT
Storage accountを使用するよに設定
hal config canary edit --default-storage-account myawsaccount
s3 を有効
hal config canary aws edit --s3-enabled true
metrc provider の指定
Prometheusを使用
hal config canary edit --default-metrics-store prometheus
hal config canary prometheus enable
hal config canary prometheus account add my-canary-prometheus-account --base-url http://prometheus-k8s.monitoring.svc.cluster.local:9090
hal config canary edit --default-metrics-account my-canary-metrics-account
Deploy
HalyardがDeploy可能なSpinnakerの一覧を確認
hal version list
Installに使用するversionを指定します
hal config version edit --version 1.9.4
SpinnakerをDeployします
hal deploy apply
以下コマンドを実行すると、Halyardをインストールしているマシンのlocalhost:9000とlocalhost:8084にSSHフォワードが設定されます。
SpinnakerのDeploy完了直後に実行すると、失敗する場合があります
hal deploy connect
ブラウザで以下URLにアクセスすると、Spinnakerの画面が開きます
memo Spinnakerの削除
KubernetesクラスタからSpinnakerを削除します。Halyardを使用して、再度Spinnakerを行いたい時に、以下コマンドで削除を行う事ができます。
hal deploy clean
参考URL
Halyard
https://www.spinnaker.io/setup/install/halyard/
Minio
https://www.minio.io/
PrometheusOperator
https://github.com/coreos/prometheus-operator