
Spinnakerを使ってEKSへの継続的デリバリー環境を構築する
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
みなさんKubernetesクラスタへのデプロイはどのように実施していますか??
小規模環境であれば kubectlを利用した手動デプロイ、もう少し規模が大きい場合は、CodePipeline、CodeBuildなどを利用した自動デプロイにて実施するケースが多いのではないでしょうか。
そんな中、最近のk8s界隈では 俺たちはSpinnakerでデプロイしているぜ!!という声をちらほら聞くようになりました。
ということで今回は、Spinnaker環境の構築方法と、何かできるのかを簡単に紹介したいと思います。
Spinnakerとは
Spinnakerは、Netflix社が開発したマルチクラウド環境への継続的デリバリーツールです。 大雑把に説明すると、CodePipelineの機能、CodeDelpoy(マルチクラウド)の機能、管理対象リソースのViewがあるイメージです。 その他、Pipelineに対しImmutable Infrastructureを強制できたり、カナリアリリースなど高度なデプロイを実現することも可能です。
デプロイ先としてAWS、Azure、GCP、OpenStackなど様々なクラウドプロバイダーを選択することができます。詳細は公式ドキュメントを参照してください。
AWSにデプロイする場合、デプロイ対象となるリソースに応じて以下のいずれか、もしくは複数のプロバイダーを有効にします。
- EC2・・・
provider aws enable - ECS・・・
provider ecs enable - EKS・・・
provider kubernetes enable
今回はEKSをデプロイ対象とした継続的デリバリー環境を構築していきます。
構成イメージ

- EKSクラスタ構築
- Spinnaker環境構築 on EC2(Ubuntu16.04)
- アプリケーション登録
- EKSデプロイ用Pipeline作成
- Pipeline起動
Spinnakerはk8sクラスタ上に構築することもできますが、今回はEC2(Ubuntu16.04)上に構築します。Spinnakerでは簡単なPipelineを作成しEKSクラスタにPodをデプロイするところまで確認しようと思います。
目次
EKSクラスタ構築
まずはEKSクラスタを構築します。今回はeksctlを利用しサクッと構築していきます。
$ eksctl create cluster --name=k8s-cluster --nodes=2 --node-type=t2.medium
2つのWorkerノードをクラスタ化した状態からスタートします。 kubectlでの実行結果は以下のようになります。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-12-64.ap-northeast-1.compute.internal Ready <none> 2m v1.11.5 ip-192-168-64-59.ap-northeast-1.compute.internal Ready <none> 2m v1.11.5 $ kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 8m
PipelineのトリガーとなるECRを作成します。
$ aws ecr create-repository --repository-name spinnaker-test-app
{
"repository": {
"repositoryArn": "arn:aws:ecr:ap-northeast-1:XXXXXXXXXXXX:repository/spinnaker-test-app",
"registryId": "XXXXXXXXXXXX",
"repositoryName": "spinnaker-test-app",
"repositoryUri": "XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app",
"createdAt": 1555259004.0
}
}NginxのイメージをPushしておきます。
$ $(aws ecr get-login --no-include-email --region ap-northeast-1) $ docker pull nginx:1.12 $ docker tag nginx:1.12 XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app:1.12 $ docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app:1.12
Spinnaker環境構築 on EC2(Ubuntu16.04)
Ubuntu16.04 (ami-06c43a7df16e8213c)、インスタンスサイズm5.xlargeのマシンを準備します。IAMロールとしては、AmazonEC2ContainerRegistryReadOnly、AmazonS3FullAccessの権限があればOKです。
Ubuntuに接続し以下を実施します。
Halyardインストール
Spinnakerを管理するためのライブラリであるHalyardをインストールします。
$ curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/linux/InstallHalyard.sh $ sudo bash InstallHalyard.sh $ hal -v 1.19.0-20190412012808
AWS CLIのインストール
AWS CLIをインストールします。
$ sudo apt-get install python $ sudo apt install python-pip $ sudo pip install awscli $ aws --version aws-cli/1.16.140 Python/2.7.12 Linux/4.4.0-1067-aws botocore/1.12.130
kubectlインストール
EKSクラスタに対し各種コマンドを実行するためkubectlをインストールします。
$ curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/kubectl $ chmod +x ./kubectl $ mkdir $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH $ echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc $ kubectl version --short --client Client Version: v1.10.3
aws-iam-authenticatorインストール
EKSクラスタに接続するため aws-iam-authenticatorをインストールします。
$ curl -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator $ chmod +x ./aws-iam-authenticator $ sudo cp ./aws-iam-authenticator /bin/
ConfigMap作成(ローカルマシンで実施)
Spinnaker環境からEKSへの接続を許可するための設定をConfigMapに追加します。この作業はeksctlコマンドを実行したマシンで実施してください。
ConfigMap(aws-auth)を取得します。
$ kubectl get configmap aws-auth -n kube-system -o yaml > aws-auth.yaml
Spinnaker環境から接続できるように設定を追記します。ec2-private-dnsは、今回作成したEC2のプライベートDNS名に置き換えてください。
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::XXXXXXXXXXXX:role/eksctl-k8s-cluster-nodegroup-0-NodeInstanceRole-1760PVA81PZH6
username: system:node:{{EC2PrivateDNSName}}
- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/SpinnakerRole
username: <ec2-private-dns>
groups:
- system:masters
kind: ConfigMap
metadata:
creationTimestamp: "2019-04-14T15:26:31Z"
name: aws-auth
namespace: kube-system
resourceVersion: "595"
selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
uid: ade8c1d0-5ec9-11e9-b4b2-0edc1fad6e02設定を反映します。
$ kubectl apply -f aws-auth.yaml configmap/aws-auth configured
Configファイル作成
Spinnaker環境からEKSクラスタへの接続するための設定を追加します。
Spinnaker環境にてconfigファイルを作成します。endpoint-url、base64-encoded-ca-cert、cluster-nameは、今回作成したEKSクラスタの値に変更してください。
apiVersion: v1
clusters:
- cluster:
server: <endpoint-url>
certificate-authority-data: <base64-encoded-ca-cert>
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
args:
- "token"
- "-i"
- "<cluster-name>"
# - "-r"
# - "<role-arn>"
# env:
# - name: AWS_PROFILE
# value: "<aws-profile>"EKSクラスタ情報が取得できることを確認しておきましょう。
$ kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 24m
Halyardの設定
halコマンドを利用し、クラウドプロバイダーの設定、アカウント登録をおこないます。${AWS_ACCOUNT}は任意の値に変更してください。
$ hal config provider kubernetes enable
$ hal config provider kubernetes account add ${AWS_ACCOUNT} --provider-version v2 --context $(kubectl config current-context)
$ hal config features edit --artifacts true
バックアップストレージの設定
Spinnakerに登録するアプリケーションのメタ情報やPipelineのメタ情報をバックアップするためのストレージを追加します。バックアップストレージはS3を利用します。
$ hal config storage s3 edit \
--region ap-northeast-1
$ hal config storage edit --type s3
$ aws s3 ls | grep spin
2019-04-14 15:59:41 spin-0ee562b8-f76f-4e45-a667-93c5cb68eaa5
ECRの登録
SpinnakerからECRを参照できるよう設定を追加します。
$ export REGION=ap-northeast-1 $ export ADDRESS=https://XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com $ hal config provider docker-registry enable $ hal config provider docker-registry account add spinnaker-registry \ --address $ADDRESS \ --username AWS \ --password-command "aws --region $REGION ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d | sed 's/^AWS://'"
Spinnakerをデプロイ
Spinnakerをデプロイします。まずは、現在利用可能なバージョンを一覧表示します。
$ hal version list + Get current deployment Success + Get Spinnaker version Success + Get released versions Success + You are on version "", and the following are available: - 1.11.12 (Cobra Kai): Changelog: https://gist.github.com/spinnaker-release/29a01fa17afe7c603e510e202a914161 Published: Fri Apr 05 14:55:40 UTC 2019 (Requires Halyard >= 1.11) - 1.12.9 (Unbreakable): Changelog: https://gist.github.com/spinnaker-release/7fa9145349d6beb2f22163977a94629e Published: Fri Apr 05 14:11:44 UTC 2019 (Requires Halyard >= 1.11) - 1.13.3 (BirdBox): Changelog: https://gist.github.com/spinnaker-release/aba784ce73cfe97ec502e12ee0f532f3 Published: Tue Apr 09 14:11:45 UTC 2019 (Requires Halyard >= 1.17)
使用したいバージョンを設定しデプロイします。
$ hal config version edit --version 1.13.3 $ sudo hal deploy apply
Spinnakerへの接続
ローカルマシンで新しいターミナルを起動しSSLで接続します。9000番ポートはWebUI、8084番ポートはApiに対するアクセスになります。
$ ssh -i XX.pem -L 9000:localhost:9000 -L 8084:localhost:8084 ubuntu@XXXXXXXXXX
Spinnakerに接続します。
アプリケーション登録
新規アプリケーションを登録します。
もし、アプーションの作成画面が表示されず、Error fetching applications. Check that your gate endpoint is accessibleのようなエラーメッセージが表示される場合は、Redisを再起動してください。
$ sudo systemctl enable redis-server && sudo systemctl start redis-server $ sudo systemctl restart spinnaker
Name、Owner Emailに任意の値を設定し、Createをクリックします。
Pipeline構築
ECRへのPushをトリガーにEKSクラスタにPodをデプロイするPipelineを構築します。
Pipeline Nameに任意の名前を入力します。
Automated TriggerのAdd Triggerをクリックします。
先ほど設定したECRのイメージを指定します。
画面上部に戻り、Add stageをクリックします。
TypeをDeploy(Manifest)とし、manifest sourceをTextで入力します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- image: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app
name: sample-app
ports:
- containerPort: 80ImageTagはECRをトリガーした部分から引き継がれるため上記で設定する必要はありません。また、今回はmanifestファイルをTextで入力しましたが、GitHubなどからアーティファクトとして取り込むことも可能です。
Save ChangeをクリックしPipelineを保存します。
これで準備が整いました。
Pipeline起動
最後にPipelineの起動を確認してみましょう! 新しいイメージをECRにPushします。
docker pull nginx:1.13 docker tag nginx:1.13 XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app:1.13 docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/spinnaker-test-app:1.13
しばらく待つとPipelineが起動します。
デプロイ完了後はClustersから起動しているPodの状況を確認することができます。
さいごに
SpinnakerによりEKSへの継続的デリバリー環境を構築しました。今回は簡易なPipelineの作成/実行のみ確認しましたが、Spinnakerを利用すれば手動承認やカナリアリリースなど高度なデプロイをPipelineに組み込むことができます。それらについてはまた次のブログで紹介しようと思います!
ハマりポイント(というか情報量が少なく概念を理解するのが難しい)はいくつかありましたが、なかなか面白いツールでした!
















