この記事は公開されてから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名に置き換えてください。
aws-auth.yaml
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クラスタの値に変更してください。
~/.kube/config
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: 80
ImageTagは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に組み込むことができます。それらについてはまた次のブログで紹介しようと思います!
ハマりポイント(というか情報量が少なく概念を理解するのが難しい)はいくつかありましたが、なかなか面白いツールでした!