Spinnakerを使ってEKSへの継続的デリバリー環境を構築する
みなさん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: 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に組み込むことができます。それらについてはまた次のブログで紹介しようと思います!
ハマりポイント(というか情報量が少なく概念を理解するのが難しい)はいくつかありましたが、なかなか面白いツールでした!