20200217のAWSに関する記事は14件です。

ec2インスタンスを停止して起動したら中身が別物になった

問題発生の経緯

ec2インスタンスがメンテナンスのため再起動すると通知があった。
そのため、事前に影響を調査してインスタンスを停止・起動すると中身が別のものになってて動いていたサービスが動かなくなってしまった。

原因

起動時のデバイスの自動マウントはetc/fstabで設定できる。

設定内容はこんな感じ(一部省略)

LABEL=/         /             ext3  defaults    1 1

このLABELというのはe2labelでデバイスをラベルにマッピングできる機能を使っている。
例えば以下のように設定したら/dev/sda1というデバイスをLABEL=/hogeという形で参照できる

e2label /dev/sda1 /hoge

問題の原因は停止・起動前に、別のデバイスへ/のラベルをe2labelで割り当ててしまってそのまま放置していたことだった。

EBSで別ボリュームをec2インスタンスにアタッチ → e2labelで別ボリュームにラベルを割り当てる → メンテナンス時に停止・再起動しサーバーの中身が別物になったように見える。

対応

mountコマンドでec2インスタンスにアタッチされていたボリュームをマウントし、中身を確認後、元々ルートにマウントされていたデバイスに再度e2labelで/のラベルを割り当て直した。
その後はec2インスタンスを停止・再起動して元に戻った。

反省点

今回の直接的な原因はe2labelでラベルを割り当て直してそのまま放置していたことである。
作業ログを残していれば原因がすぐ分かったし、作業内容を忘れていたのがまずかった。

後は不要なボリュームをec2にアタッチしていたまま放置していたのもよくなかった。
ここら辺の無駄なリソースはきちんと整理して置かないと後で、必要・不要の判断ができなくなってしまうし、今回のような問題につながってしまうこともある。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSの10分間チュートリアルをやってみる 11. コンテンツを迅速に配信する

こんにちは。トリドリといいます。
新卒で入社した会社でJavaを数年やった後、1年ほど前に転職してからはRailsを中心に使用してアプリケーションの開発をしているしがないエンジニアです。

今回、AWSの勉強をするために公式の10分間チュートリアルをやってみることにしたので、備忘のために記事に残していこうと思います。
AWSに関しては、1年ほど前転職活動をしていた時期にEC2とRDSを少し触っていた以外ほとんど触ったことが無い初心者です。
(ただし、このときにアカウントを作ったので、12ヶ月の無料枠は切れていました)

前回は、AWS Amplify Consoleを使用してReactのアプリケーションをデプロイする「Deploy and host a ReactJS app」をやりました。
今回はS3にアップしたコンテンツをCloudFrontを使用して配信する、「コンテンツを迅速に配信する」をやっていきます。

コンテンツを迅速に配信する

(https://aws.amazon.com/jp/getting-started/tutorials/deliver-content-faster/)
サンプルの静的コンテンツをS3にアップし、コンテンツ配信ネットワーク(CDN)であるCloudFrontを使用して配信します。
CDNとはその名の通り、コンテンツ(ファイル)を配信すること専門のサービスで、アクセス元と近いサーバーから配信するなどの方法で高速・効率的に配信することができるものです。
参考:
https://aws.amazon.com/jp/cloudfront/
https://blog.redbox.ne.jp/what-is-cdn.html
https://www.cdnetworks.co.jp/about/

ステップ 1: コンテンツを準備する

まずは配信するコンテンツを用意します。このチュートリアルでは画像をS3にアップして使用します。

a.

チュートリアルで用意されている画像をダウンロードします。

b.

AWSコンソールからS3を開きます。

c.

S3ダッシュボードから[コンテンツを作成する]を押下します。

チュートリアルに従って、[バケット名]と[リージョン]を入力し、[次へ]を押します。
バケット名は一意にする必要があったり、.-で終わることができないなどのルールがあるので要注意です。

次の[オプションの設定](チュートリアルでは[プロパティの設定]となっていますが名前が変わっているようです)はチュートリアルの通り、どのような設定があるのかを確認してそのまま[次へ]を押します。
image.png

その次の[アクセス許可の設定](チュートリアルでは翻訳ミスかこちらも[プロパティの設定]となっています)は、コンテンツを配信するに当たってパブリックアクセスにする必要があるので、チェックを外します。
image.png
チェックを外すと下記の通りアラートが表示されるので、[了承する]にチェックを入れた上で[次へ]を押します。
image.png

最後に確認した上で、[バケットを作成]を押します。
スクリーンショット 2020-02-17 21.45.31.jpg

d.

作成されたバケットをクリックし、チュートリアルに従って[アップロード]からa.でダウンロードしたファイルを選択し[次へ]を押します。

e.

バケットと同様こちらもパブリックアクセスに設定する必要があるので、チュートリアルの通り[アクセス権限を付与する]を選択した上で[次へ]を押します。

[プロパティを設定する](チュートリアルでは[Set properties (権限の設定)]となっています)では、どのような設定があるのかを確認した上で[次へ] を押します。
スクリーンショット 2020-02-17 21.52.41.jpg

最後に確認した上で、[アップロード]を押し、アップロードします。
image.png

ステップ 2: CloudFront コンソールに入力する

コンテンツがアップロードできたので、CloudFrontで配信の設定をしていきます。

a./b.

AWSコンソールからCloudFrontを開き、[Create Distribution]を押します。

ステップ 3: ウェブディストリビューションを設定する

a.

まずは、配信方法を選択します。
HTTPまたはHTTPSを使用する[Web]とAdobe Flashで使用されるRTMPプロトコルを使用する[RTMP]の選択肢が用意されています。
今回はFlashではないので、[Web]の[Get Started]を押下します。

b.

チュートリアルに従って、[Origin Domain Name]でステップ1.のバケットを選択します。
自動的にいくつかの項目が設定されるので、そのまま[Create Distribution]を押します。
各設定項目の詳細についてはチュートリアルに記載されているのでそちらを参照してください。

ステップ 4: ディストリビューションを作成する

ボタンを押下すると、CloudFrontコンソールに戻り、作成したディストリビューションが[In Progress]のステータスで表示されます。
ステータスが[Deployed]になれば作成は完了です。

ステップ 5: リンクをテストする

実際にhtmlに埋め込んでコンテンツが配信されることをテストします。

a.

チュートリアルのHTMLが正しく表示されない状態になっているようですが、下記HTMLでチュートリアル同様に表示されるはずです。

<html>
<body>
  <p>My CloudFront Test</p>
  <p>My text content goes here.</p>
  <img src='http://ドメイン名/ファイル名'>
</body>
</html>

ドメイン名はCloudFrontで生成されたドメイン名、ファイル名はS3にアップロードしたコンテンツのファイル名で置き換えた上で、チュートリアルの通りmycloudfronttest.htmlという名前で保存します。

b.

保存したHTMLファイルをブラウザで開くと、下記の通りコンテンツが表示されます。
スクリーンショット 2020-02-17 22.35.55.jpg

ステップ 6: ウェブディストリビューションを無効にする

最後に作成したディストリビューションを無効にします。

a./b.

チュートリアルに従って、無効にするディストリビューションを選択した上で[Disable]ー>[Yes, Disable]と押すことでディストリビューションを無効にすることができます。

ステータスが[Deployed]になれば、無効にするのは完了です。
再度HTMLを開くと、次の通り画像が表示されなくなっています。
image.png

まとめ

今回は
- S3にバケットを作成してファイルをアップロードする
- CloudFrontを利用してS3のコンテンツを配信する
の2つをやっていきました。

前回のまとめにも記載したとおり、今回でこの形式でチュートリアルをやってみるのは終わります。
今後も何らかの形で少しずつ書いていければと思うので、また機会があれば読んでいただけると幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NetBackup CloudCatalyst for AWS入門 まとめ

はじめに

今回は過去投稿分のまとめと「NetBackup 8.2 CloudCatalyst構築および復旧ガイド」のご案内となります。

過去記事のまとめ

以下は過去に投稿した記事の一覧になります。

 NetBackup CloudCatalyst for AWS入門 その1 【概要編】
 NetBackup CloudCatalyst for AWS入門 その2 【構築編】
 NetBackup CloudCatalyst for AWS入門 その3 【全損からの復旧編】

ガイドについて

NetBackup CloudCatalyst for AWS入門 その3で記載しておりました「NetBackup 8.2 CloudCatalyst構築および復旧ガイド」ですが、過去記事の内容に加え、スクリーンショットを交えて分かり易く構成しています。
是非、以下からダウンロードしてみて下さい。

 NetBackup 8.2 CloudCatalyst構築および復旧ガイド(Amazon S3利用)

商談のご相談はこちら

本稿からのお問合せをご記入の際には「お問合せ内容」に#GWCのタグを必ずご記入ください。ご記入いただきました内容はベリタスのプライバシーポリシーに従って管理されます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda 実行監視

CloudWatch > アラーム > アラームの作成

メトリクス

名前空間:AWS/Lambda
メトリクス名:Errors
FunctionName:●●●●●●●●●●●●●●●●
統計:最大
期間:1分

条件

しきい値の種類:静的
Errors が次の時:より大きい (>)
... よりも:0
アラームを実行するデータポイント:1 / 1
欠落データの処理:欠落データを見つかりませんとして処理

アクション

通知
アラーム状態のとき、「【AmazonSNSトピック】」に通知を送信します

参考) Amazon SNS のサブスクリプション解除を禁止する方法
https://aws.amazon.com/jp/premiumsupport/knowledge-center/prevent-unsubscribe-all-sns-topic/

名前と説明

名前:●●●●●●●●●●●●●●●●
説明:●●●●●●●●●●●●●●●●

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】Amazon WorkSpacesの起動

仮想ディスクトップ環境を利用したかったので、試しに実行してみました。

無料利用枠について

2020年2月時点での無料利用枠

  • Amazon WorkDocs 30日間無料
  • Amazon WorkDocs&WorkSpaces バンドル
    50GB
  • Amazon WorkSpaces
    40時間

利用料金

リージョン バリュー ルートボリューム ユーザーボリューム 月額料金 時間料金
東京リージョンの場合 2 vCPU、4 GiB メモリ 80 GB 50 GB 47 USD 14 USD/月 + 0.40 USD/時間
バージニア北部の場合 2 vCPU、4 GiB メモリ 80 GB 50 GB 35 USD 9.75 USD/月+ 0.30 USD/時間

東京リージョンを選択すると、日本語のOSが選択できるので、今回は東京リージョンを選択する。

利用方法

AWSのサービスでWorkSpacesを検索する。

今すぐ始めるを選択する。
image.png

言語を選択してから、無料枠対象のWindows10を選択します。

ユーザーの詳細の入力の各欄に必要な情報を入力してください。
image.png

情報を入力したら、WorkSpacesの起動をクリックする。

コンソールの表示

下記の画面が表示されるので、ボタンを押してください。
image.png

ステータスの部分がAVAILABLEになったら、先ほど入力したメールアドレスに招待用のURLが届いているので確認してください。

WorkSpacesへのアクセス

1. ユーザーのプロファイルを入力し、次のリンクから WorkSpaces クライアントをダウンロードします

表題のメッセージの右に記載されているURLをクリックし、パスワードの設定を行います。

下記の画面が表示されるので、接続元となるデバイスを選択し、ダウンロードする。

Amazon WorkSpaces のインストール

ダウンロードしたインストールパッケージをダブルクリックし、インストールを開始します。

image.png

インストール先の選択

下記の2つを選択できますが、今回は、全ユーザーが利用できるようにインストールします。

  • Userに対してインストールする場合(Install just for you)

  • 全ユーザーに対してインストールする場合(Install for all users of this machine)

image.png

日本語に変更

インストールしたWorkSpacesを起動します。
表示が英語の場合は、右上の歯車ボタンで言語設定を変更する事ができます。

Networkについて

右下のネットワークアイコンが警告マークになっている場合、ネットワークの設定が上手く出来ていません。
右上の歯車ボタンを押して、設定を行ってください。
自分の環境では、プロキシの設定が必要だった為、チェックを入れて必要事項を入力しました。

MacでのWorkSpacesへのアクセス

Mac用のパッケージを選択し、ダウンロードします。
ダウンロードが完了したら、パッケージを選択して起動します。

今回は、インストール場所等は全てデフォルトのまま進めます。

 2020-02-11 13.47.08.png

WorkSpacesアプリケーションの起動

先ほどインストールしたアプリケーションを開きます。

英文で
開始するには、管理者に提供された登録コードを入力してください
と記載されているので、メールで案内された登録コードを入力します。

image.png

ユーザー名とパスワードを聞かれるので、入力してログインします。

image.png

英文で
WorkSpaceに簡単に再接続できるように、資格情報を安全に保存しますか?
この設定は、このアプリの[詳細設定]セクションでいつでも変更できます。

と尋ねられるので、どちらかを選択します。

image.png

起動完了

下記のような画面が表示されて、無事、Windows10を起動することができました。
image.png

Andoroid Studioを導入してみる

image.png
WorkSpaces

サクサク進んで2分もあれば起動させることができました。
image.png

ここから設定を選択して、Installを行います。
image.png

問題発生

下記のメッセージが表示されました。

Intel HAXMをインストールできません
HAXMは、ネストされた仮想マシンをサポートしません。
残念ながら、Androidエミュレーターは仮想マシン内からの仮想マシンアクセラレーションをサポートできません。
オプションの一部を次に示します。
  1)テストに物理デバイスを使用する
  2)非仮想化オペレーティングシステムでエミュレータを起動します
  3)ARMシステムイメージに基づいたAndroid仮想デバイスを使用します(これはハードウェアアクセラレーションによる仮想化よりも10倍遅いです)

今回はお試しなので、エラーのまま放置します。

まとめ

簡単にクラウド上で開発環境を構築することが出来ました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】Amazon Sagemaker Studioを利用してみる

Amazon Sagemaker Studioとは?

機械学習のための統合開発環境(IDE)であり、開発者は統合された、生産性を大きく向上する視覚的なインタフェースを使ってコードを書いたり、実験管理をしたり、データを可視化したりデバッグやモニタリングをすることができます。

利用方法

2019年12年30日現在は、プレビュー中なので、「オハイオ」リージョンのみで利用可能です。
 2019-12-29 18.08.04.png

SSOの設定

SSOで開始するを選択すると、登録情報の入力画面が表示されるため、必要項目を入力します。
 2019-12-29 18.09.11.png

登録したメールアドレスに招待のURLが届いているので、クリックして、パスワードを更新する

Amazon Sagemaker Studioの設定

アクセス許可の指定を行います。
今回は、既存の物を利用しないため、新規作成を行いました。
指定するS3バケットへのアクセスは許可しませんでした。
 2019-12-29 18.27.22.png
新規作成すると下記のように新規作成されます。

 2019-12-29 18.25.48.png

Notebook resource configurationについては、デフォルトのまま、選択しておきます。

次に進むと下記のような表示になります。
 2019-12-29 18.31.56.png
「Pending」が終了したら、ユーザーの割り当てボタンを押します。

 2019-12-29 19.59.00.png

先ほど、SSOを設定したユーザーを指定します。

Sagemaker Studioの開始方法

先ほどのSSOの登録をしたEmailアドレスに届いているYour User portal URLのアドレスをクリックしてSSOのアドレスでログインする

ログインすると、下記のような画面が表示され、「Amazon SageMaker Studio」のサービスが選択できるようになっている。

 2019-12-29 22.29.30.png

選択するとサービスの読み込み画面が表示されます。
 2019-12-29 23.15.24.png

SageMaker Studioの実行

左上のを押してLauncherを開く
 2019-12-29 23.51.16.png

NotebookのPython 3のボタンを押して作成する

 2019-12-30 0.01.19.png

データの取得

別紙参照

 2019-12-30 0.39.53.png
 2019-12-30 0.40.03.png

モデルの作成

下記の設定でモデルの生成を行います。

image.png

image.png

モデル生成後

目的を持たずに実験していたので、やる事が思いつかず途方にくれてしまいました。
次、利用する際は、最終的な目標を持ち、モデルを作成しようと思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存のAWS環境の構成情報をCLIでゲットしたい

はじめに

経緯

記事作成の経緯としては、AWS上で動作しているアプリケーションを組織的に展開する必要があり、AWS環境で利用している各種サービスについて、設定情報をダンプする必要がある状況だった。仲間からの「Jsonで全部の情報をダンプ出来たら楽じゃない?」というアイデアに基づき、下記情報を参考に、BatchGetResourceConfigの動作確認をしてみた内容のメモです。
AWS Config が、複数のリソースに対する現在の設定の取得をサポート
BatchGetResourceConfig

環境など

  • aws-cli/1.16.313 Python/3.5.2 Linux/4.4.0-142-generic botocore/1.13.49
  • pip 19.3.1 from /usr/local/lib/python3.5/dist-packages/pip (python 3.5)

※実際に案件でこのコマンドを利用する必要がある場合は、ご自身でもAWSのドキュメントを参照、必要に応じて実機で検証した上で、対応を検討してください。

調査結果

APIの仕様

ざっくりとした概要は以下。

  • Resource TypeおよびResource ID(この2つのセットをResource Keyと呼ぶ)を指定するとAWSマネージメントコンソール上で設定している項目はひととおり、jsonとしてExportしてくれる。(CustomerGatewayで確認した限りは管理コンソールで設定している内容が一通り出力された。)
  • 複数指定可能であり、大量に指定する場合は --cli-input-json オプションを使うと便利。

※ドキュメント
https://docs.aws.amazon.com/config/latest/APIReference/API_BatchGetResourceConfig.html
https://docs.aws.amazon.com/cli/latest/reference/configservice/index.html#cli-aws-configservice

コマンド実行例

単品指定
$ aws configservice batch-get-resource-config --resource-keys resourceType="AWS::EC2::CustomerGateway",resourceId="cgw-01234567abcdefh" --region ap-northeast-1 --profile my-profile1
{
    "baseConfigurationItems": [
        {
            "arn": "arn:aws:ec2:ap-northeast-1:123456789012:customer-gateway/cgw-01234567abcdefh",
            "accountId": "123456789012",
            "configurationItemStatus": "ResourceDiscovered",
            "configurationItemCaptureTime": 1234567890.123,
            "version": "1.3",
            "awsRegion": "Not Applicable",
            "resourceType": "AWS::EC2::CustomerGateway",
            "availabilityZone": "Not Applicable",
            "configuration": "{\"bgpAsn\":\"XXXXXX\",\"customerGatewayId\":\"cgw-01234567abcdefh\",\"ipAddress\":\"192.168.0.123\",\"certificateArn\":null,\"state\":\"available\",\"type\":\"ipsec.1\",\"deviceName\":null,\"tags\":[{\"key\":\"Name\",\"value\":\"My Customer Gateway for XXX\"}]}",
            "resourceId": "cgw-01234567abcdefh",
            "configurationStateId": "1234567890123",
            "supplementaryConfiguration": {}
        }
    ],
    "unprocessedResourceKeys": []
}
$

※細かい値は編集してますが、イメージとして上記のような感じで出力される。
※ConfigurationのValueが主にマネージメントコンソール上での設定項目にほぼ相当していた。(GUIには表示されていた情報で明らかに不足していたのは、どのVPCに属するか、の情報だけ。気づいた限り。)

複数指定
$ aws configservice batch-get-resource-config  --region ap-northeast-1 --profile my-profile1 --cli-input-json file://request.json

※複数していでjson使う場合は上記のように対応。

困ったこと

--cli-input-jsonの用意をするために、Jsonのファイルを一括で作成したい状況だった。
「list-discovered-resourcesコマンドがつかえるかも??」と思い試したところ、便利ではあったが、万能ではなかった。具体的には、--resource-typeとして設定できるものは「Possible values」に定義されているものだけのようであったこと。
list-discovered-resources

とりあえず、サポートされる全リソース(90個)分、shellで実行して、sedで編集してインプット用jsonファイルを用意した。

おわりに

既存アプリの横展開に向けた構成情報の洗い出しという意味では、結局のところ、Lambdaの処理やS3 Select等、設計書情報が必要なものなどものあり、BatchGetResourceConfigだけで賄えるものではなかった(当然)ので、個別のリソースに応じて、ドキュメントを用意してもらったり。get configやdescribeコマンドを実行したりExportしたり、いろいろ細々した作業は発生した。(それぞれ種類や用途が異なるサービスであり、出力したい情報も異なるので当然だと思う。設定だけExportできていればいいもの、スクリプトをExportしなくてはいけないもの、(DB系だと)スキーマ情報をExportしたいもの、等さまざまなので。)
もともとの依頼に対しては、手動作業やいろいろ交えて、何とか完了できたので良しとした。
もっとスマートな対応方法をご存知の方がいらっしゃったら、ぜひ、教えていただきたい!

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda Layersを用いてLambda関数から外部ライブラリを読み込む。Amazon Linux 2のPython環境も整います。(Python3.6、Anaconda)

AWS Consoleにログインし、EC2からAmazon Linux 2を立てます。
image.png
インスタンスタイプはt2.microで、確認と作成ボタンをクリックします。※後述しますが、t2.mediumにしてください。
image.png
セキュリティーグループは各自で設定してください。SSH接続用に22番ポートを開けておきます。
image.png
既存のキーペアを選択、なければ新規作成してください。SSH接続する際に必要です。
image.png
インスタンスの作成中です。インスタンスの表示をクリックします。
image.png
インスタンスの状態がrunning、ステータスチェックが2/2のチェックになったら完了です。
image.png
インスタンスの作成が完了したら、IPv4パブリックIPをコピーして、PuTTYからSSH接続します。
image.png
PuTTYを開いて、Host NameのところにIPアドレスを入力してください。
image.png
Connection->SSH->Authからキーペアを選択します。PuTTYgenを用いて、.pemから.ppkに変換したものを使用します。
image.png
はいをクリックします。
image.png
ec2-userでログインできます。
image.png

ログインしたら、Pythonのバージョンを確認します。いまだにPython2系がデフォルトになっているようです。

$ python
Python 2.7.16 (default, Dec 12 2019, 23:58:22)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()

Anacondaをインストールします。AnacondaのサイトからダウンロードURLをコピーします。
image.png

ダウンロードURLに対してwgetし、bashでインストールします。

$ wget https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh
$ bash Anaconda3-2019.10-Linux-x86_64.sh

Enterで規約を読み、yesを入力。Enterでインストール開始。

Please answer 'yes' or 'no':'
>>> yes

Anaconda3 will now be installed into this location:
/home/ec2-user/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below
Unpacking payload ...
  0%|   | 0/291 [00:00<?, ?it/s]

で止まったままになってしまった。

t2.mediumでできるらしいので、インスタンスの停止、インスタンスタイプの変更を行います。
current latest miniconda sh installer for linux hangs on Unpacking payload step #9345

Anacondaのインストールができたら、Python3.6環境を作成します。

$ /home/ec2-user/anaconda3/bin/conda create -n py36 python=3.6
$ /home/ec2-user/anaconda3/bin/conda init 

インスタンスを再起動し、py36環境でpythonフォルダにライブラリをインストールします。

$ conda activate py36
$ mkdir python
$ pip install -t ./python requests
$ pip install -t ./python ulid-py
$ pip install -t ./python pillow
$ pip install -t ./python numpy
$ pip install -t ./python opencv-python
$ pip install -t ./python opencv-contrib-python
$ pip install -t ./python pandas
$ pip install -t ./python matplotlib
$ pip install -t ./python folium

pythonフォルダをzip化します。

$ zip -r GachiLayers.zip python

zipファイルをS3へアップロードするために、awscliの設定とboto3をインストールします。

$ pip install awscli
$ pip install boto3

AWS Console の IAM からユーザーを作成し、AWS Access Key と Secret Access Key を取得します。
image.png

AmazonS3FullAccessのアクセス権限を与えておきます。
image.png

タグは特になし。
image.png

確認します。
image.png

作成に成功したら、aws configure に必要なAWS Access Key と Secret Access Key を取得できるので、大事に保管しておきます。
image.png

AWS Configureの設定、AWS Access Key と Secret Access Key を入力します。

$ aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json

ZipファイルをS3へアップロードするためのPythonプログラムを作成します。S3バケットを新規作成しておくこと。

$ vi upload.py
import boto3

filename = 'GachiLayers.zip'
s3 = boto3.resource('s3')
obj = s3.Object(<INSERT YOUR BUCKET NAME>, filename)
response = obj.put(Body = open(filename, 'rb'))

実行します。

$ python upload.py

S3にアップロードされていることを確認します。
image.png

AWS Console から Lambda を開き、Layersからレイヤーを作成します。
image.png

作成できました。
image.png

Lambda関数を作成(ランタイムはPython3.6)し、Layerを追加します。
image.png

作成したレイヤーを選択。
image.png

Lamda関数を編集して、ライブラリが読み込まれていることを確認しましょう。

import json
import requests
import ulid
from PIL import Image 
import numpy as np
import cv2
import pandas as pd 
import matplotlib.pyplot as plt
import folium
from folium import plugins

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

テストイベントを作成します。
image.png

実行できれば、ライブラリが読み込まれているはずです。

Response:
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}

お疲れ様でした。終わったらインスタンス消してもいいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

kubernetes the hard way を AWS でやってみた(全文和訳有り)

kubernetes the hard wayをご存じでしょうか?
kuberenetesクラスターを手作業で構築することによってkubernetesへの理解を深めようという意図で作成されたチュートリアルです。

自分は今まで何となくの知識でkubernetesを使っていたので、今回復習のためにkubernetes the hard wayをやってみました。

オリジナルのチュートリアルはGCP環境で構築を行っていますが、有志の方がAWS環境用のチュートリアルを作成されていたので今回はそちらをやってみました。
それとせっかくなのでAWS用チュートリアルの日本語版を作ってみました。

個人的にはやってみてとても勉強になったのでお勧めです。皆さんもよければぜひ。

なお自分は以下のエントリーを見つつチュートリアルをやりました。こちらもとても勉強になるのでぜひ。

Kubernetes The Hard Wayする
Kubernetes: 構成コンポーネント一覧
KubernetesのTLS証明書

※このチュートリアルはオリジナルその日本語訳(GCP環境)、それとこちらのAWS用チュートリアルを基に作成したものであり、私がゼロから作成したものではありません。


kubernetes the hard way (始めに)

Kubernetes Hard Wayでは、Kubernetesの設定を一から進めます。

なので、このラボは、完全に自動化されて管理されたKubernetesクラスタを作るコマンドを探している人のためのものではありません。

このKubernetes The Hard Wayは学習することに最適化されています。
Kubernetesクラスタを立ち上げるための必要な各タスクを確実に理解するための、長い道のりが示されています。

想定読者

本番用のKubernetesクラスタをサポートすることを計画していて、かつ、Kubenretesクラスタのすべての部品がどのように組み合わさっているかを理解したいという人向けです。

今回出来上がるクラスタの詳細

Kubernetes The Hard Wayでは、コンポーネント間のエンドツーエンドの暗号化とRBAC認証ができる、可用性の高いKubernetesクラスタを作ります。

使うコンポーネントとそのバージョン一覧は下記の通りです

Kubernetes 1.15.3
containerd Container Runtime 1.2.9
gVisor 08879266fef3a67fac1a77f1ea133c3ac75759dd
CNI Container Networking 0.8.2
etcd 3.3.10

このチュートリアルではAWSを使用します

では、はじめていきましょう!

01-Prerequisites

Amazon Web Services

このチュートリアルではAmazon Web Service(以下AWS)を利用して、kubernetesクラスターを立ち上げます。
このチュートリアルを通して掛かる費用は、24時間あたり2ドル未満です。

また、今回使用するリソースはAWSの無料枠を超えるので、チュートリアル終了後には作成したリソースをクリーンアップし、不要なコストが発生しないよう注意してください。

Amazon Web Services CLI

以降の手順は、デプロイ用インスタンス(適当なEC2インスタンスを立ち上げる)で実行してください。
このデプロイ用インスタンスはクラスター立ち上げのための各種設定を行うためのものであり、kubernetesクラスターのコンポーネントではありません。

AWS CLIのインストール

AWSの公式ドキュメントに従って、AWS CLIをインストールし、必要な設定を行います。

インストールが終了したら、以下のコマンドでAWS CLIが有効であることを確認します。

aws --version

デフォルトリージョンの設定

このチュートリアルで使用するデフォルトのリージョンを設定します

AWS_REGION=us-west-1
aws configure set default.region $AWS_REGION

tmuxを使ってパラレルにコマンドを打てるようにする

一応おすすめ設定として書かれているので興味がある人は下記を見てみてください。

https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/01-prerequisites.md#running-commands-in-parallel-with-tmux

02-クライアントツールのインストール

この手順ではcfssl, cfssljson, kubectlのインストールを行います。

CFSSLとCFSSLJSONのインストール

cfsslcfssljsonPKIの環境構築とTLSの証明書発行に使います。

OS Xでのインストール

curl -o cfssl https://pkg.cfssl.org/R1.2/cfssl_darwin-amd64
curl -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_darwin-amd64
chmod +x cfssl cfssljson
sudo mv cfssl cfssljson /usr/local/bin/

OS Xを使用し、pre-buildでインストールしようとした場合、問題が生じる場合があります。
その場合はHomebrewを使用してインストールするしてください。

brew install cfssl

Linuxでのインストール

wget -q --show-progress --https-only --timestamping \
  https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 \
  https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64
sudo mv cfssl_linux-amd64 /usr/local/bin/cfssl
sudo mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

確認

cfssl のバージョンが 1.2.0 以上であることを確認します

% cfssl version
Version: 1.2.0
Revision: dev
Runtime: go1.6

(cfssljsonにはバージョンを表示するコマンドがありません)

kubectlのインストール

kubectlはKubernetes API Serverとの通信に使用されるコマンドラインツールです。
今回はバージョン1.15.3以上が必要になります。

OS Xでのインストール

curl -o kubectl https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/darwin/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

Linuxでのインストール

wget https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

確認

インストールされたkubectlのバージョンが1.15.3以上であることを確認します。

% kubectl version --client
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.3", GitCommit:"2d3c76f9091b6bec110a5e63777c332469e0cba2", GitTreeState:"clean", BuildDate:"2019-08-19T12:38:00Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"darwin/amd64"}

03-Provisioning Compute Resources

リソースについての説明は元ネタか、こちらの日本語訳の方を確認してください。
以下、デプロイ用インスタンスで実行するコマンドを記載します。

Networking

VPC

VPC_ID=$(aws ec2 create-vpc --cidr-block 10.240.0.0/24 --output text --query 'Vpc.VpcId')
aws ec2 create-tags --resources ${VPC_ID} --tags Key=Name,Value=kubernetes
aws ec2 modify-vpc-attribute --vpc-id ${VPC_ID} --enable-dns-support '{"Value": true}'
aws ec2 modify-vpc-attribute --vpc-id ${VPC_ID} --enable-dns-hostnames '{"Value": true}'

Subnet

SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id ${VPC_ID} \
  --cidr-block 10.240.0.0/24 \
  --output text --query 'Subnet.SubnetId')
aws ec2 create-tags --resources ${SUBNET_ID} --tags Key=Name,Value=kubernetes

Internet Gateway

INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway --output text --query 'InternetGateway.InternetGatewayId')
aws ec2 create-tags --resources ${INTERNET_GATEWAY_ID} --tags Key=Name,Value=kubernetes
aws ec2 attach-internet-gateway --internet-gateway-id ${INTERNET_GATEWAY_ID} --vpc-id ${VPC_ID}

Route Tables

ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id ${VPC_ID} --output text --query 'RouteTable.RouteTableId')
aws ec2 create-tags --resources ${ROUTE_TABLE_ID} --tags Key=Name,Value=kubernetes
aws ec2 associate-route-table --route-table-id ${ROUTE_TABLE_ID} --subnet-id ${SUBNET_ID}
aws ec2 create-route --route-table-id ${ROUTE_TABLE_ID} --destination-cidr-block 0.0.0.0/0 --gateway-id ${INTERNET_GATEWAY_ID}

Security Groups

SECURITY_GROUP_ID=$(aws ec2 create-security-group \
  --group-name kubernetes \
  --description "Kubernetes security group" \
  --vpc-id ${VPC_ID} \
  --output text --query 'GroupId')
aws ec2 create-tags --resources ${SECURITY_GROUP_ID} --tags Key=Name,Value=kubernetes
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol all --cidr 10.240.0.0/24
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol all --cidr 10.200.0.0/16
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 6443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol icmp --port -1 --cidr 0.0.0.0/0

Kubernetes Public Access - ロードバランサーの作成

  LOAD_BALANCER_ARN=$(aws elbv2 create-load-balancer \
    --name kubernetes \
    --subnets ${SUBNET_ID} \
    --scheme internet-facing \
    --type network \
    --output text --query 'LoadBalancers[].LoadBalancerArn')
  TARGET_GROUP_ARN=$(aws elbv2 create-target-group \
    --name kubernetes \
    --protocol TCP \
    --port 6443 \
    --vpc-id ${VPC_ID} \
    --target-type ip \
    --output text --query 'TargetGroups[].TargetGroupArn')
  aws elbv2 register-targets --target-group-arn ${TARGET_GROUP_ARN} --targets Id=10.240.0.1{0,1,2}
  aws elbv2 create-listener \
    --load-balancer-arn ${LOAD_BALANCER_ARN} \
    --protocol TCP \
    --port 443 \
    --default-actions Type=forward,TargetGroupArn=${TARGET_GROUP_ARN} \
    --output text --query 'Listeners[].ListenerArn'
KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \
  --load-balancer-arns ${LOAD_BALANCER_ARN} \
  --output text --query 'LoadBalancers[].DNSName')

各種インスタンス

Instance Image

IMAGE_ID=$(aws ec2 describe-images --owners 099720109477 \
  --filters \
  'Name=root-device-type,Values=ebs' \
  'Name=architecture,Values=x86_64' \
  'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*' \
  | jq -r '.Images|sort_by(.Name)[-1]|.ImageId')

SSH Key Pair

aws ec2 create-key-pair --key-name kubernetes --output text --query 'KeyMaterial' > kubernetes.id_rsa
chmod 600 kubernetes.id_rsa

Kubernetes コントローラーノード

今回は t3.micro インスタンスを使用します

for i in 0 1 2; do
  instance_id=$(aws ec2 run-instances \
    --associate-public-ip-address \
    --image-id ${IMAGE_ID} \
    --count 1 \
    --key-name kubernetes \
    --security-group-ids ${SECURITY_GROUP_ID} \
    --instance-type t3.micro \
    --private-ip-address 10.240.0.1${i} \
    --user-data "name=controller-${i}" \
    --subnet-id ${SUBNET_ID} \
    --block-device-mappings='{"DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": 50 }, "NoDevice": "" }' \
    --output text --query 'Instances[].InstanceId')
  aws ec2 modify-instance-attribute --instance-id ${instance_id} --no-source-dest-check
  aws ec2 create-tags --resources ${instance_id} --tags "Key=Name,Value=controller-${i}"
  echo "controller-${i} created "
done

Kubernetes ワーカーノード

for i in 0 1 2; do
  instance_id=$(aws ec2 run-instances \
    --associate-public-ip-address \
    --image-id ${IMAGE_ID} \
    --count 1 \
    --key-name kubernetes \
    --security-group-ids ${SECURITY_GROUP_ID} \
    --instance-type t3.micro \
    --private-ip-address 10.240.0.2${i} \
    --user-data "name=worker-${i}|pod-cidr=10.200.${i}.0/24" \
    --subnet-id ${SUBNET_ID} \
    --block-device-mappings='{"DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": 50 }, "NoDevice": "" }' \
    --output text --query 'Instances[].InstanceId')
  aws ec2 modify-instance-attribute --instance-id ${instance_id} --no-source-dest-check
  aws ec2 create-tags --resources ${instance_id} --tags "Key=Name,Value=worker-${i}"
  echo "worker-${i} created"
done

04-Provisioning a CA and Generating TLS Certificates

この手順では、CloudFlareのPKIツールキットである cfsslを使用してPKI基盤をプロビジョニングします。
そして、PKI基盤を利用して認証局を作り、admin用のTLS証明書、etcd、kube-apiserver、kube-controller-manager、kube-scheduler、 kubelet、kube-proxyの各コンポーネント用TLS証明書を生成します。

認証局(CA)の立ち上げ

このステップでは、TLS証明書を生成するための認証局(CA)をプロビジョニングします。

まずは、CA設定ファイル、CA自身の証明書、および秘密鍵を生成します。

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

生成物

ca-key.pem
ca.pem

クライアントとサーバーの証明書発行

このステップでは、各Kubernetesコンポーネントで使うクライアント証明書とサーバー証明書、Kubernetes admin ユーザー用のクライアント証明書を発行します。

Admin用のクライアント証明書

まずは、 admin 用のクライアント証明書と秘密鍵を生成します。

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:masters",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  admin-csr.json | cfssljson -bare admin

生成物

admin-key.pem
admin.pem

Kubeletのクライアント証明書

Kubernetesは、Node Authorizerと呼ばれる特別な用途向けの認可モードを利用します。

これは特にKubeletsからのAPIリクエストの認証を行います。

Node Authorizerの認可のためには、Kubeletは、system:nodes groupの中の system:node:<nodeName> というユーザー名で認証されるように証明書を作成しなければなりません。

このステップでは、KubernetesワーカーノードごとにNode Authorizerの要求を満たす証明書と秘密鍵を発行します。

for i in 0 1 2; do
  instance="worker-${i}"
  instance_hostname="ip-10-240-0-2${i}"
  cat > ${instance}-csr.json <<EOF
{
  "CN": "system:node:${instance_hostname}",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  internal_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PrivateIpAddress')

  cfssl gencert \
    -ca=ca.pem \
    -ca-key=ca-key.pem \
    -config=ca-config.json \
    -hostname=${instance_hostname},${external_ip},${internal_ip} \
    -profile=kubernetes \
    worker-${i}-csr.json | cfssljson -bare worker-${i}
done

生成物

worker-0-key.pem
worker-0.pem
worker-1-key.pem
worker-1.pem
worker-2-key.pem
worker-2.pem

kube-contorller-manager クライアントの証明書

kube-controller-manager クライアントの証明書と秘密鍵を発行します。

cat > kube-controller-manager-csr.json <<EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

生成物

kube-controller-manager-key.pem
kube-controller-manager.pem

kube-proxy クライアントの証明書

kube-proxy クライアント用に証明書と秘密鍵を発行します。

cat > kube-proxy-csr.json <<EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:node-proxier",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-proxy-csr.json | cfssljson -bare kube-proxy

生成物

kube-proxy-key.pem
kube-proxy.pem

kube-scheduler クライアント用の証明書

kube-scheduler クライアント用の証明書と秘密鍵を発行します。

cat > kube-scheduler-csr.json <<EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-scheduler-csr.json | cfssljson -bare kube-scheduler

生成物

kube-scheduler-key.pem
kube-scheduler.pem

Kubernetes API サーバー用証明書

kubernetes-the-hard-way のstatic IPアドレスは、Kubernetes API サーバーの証明書のSAN(subject alternative names、サブジェクトの別名)のリストに含める必要があります。

これにより、外部のクライアントでも証明書を使った検証を行います。

Kubernetes API サーバーの証明書と秘密鍵を生成します。

cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,kubernetes.default \
  -profile=kubernetes \
  kubernetes-csr.json | cfssljson -bare kubernetes

生成物

kubernetes-key.pem
kubernetes.pem

サービスアカウントのキーペア

サービスアカウントの管理のドキュメントにあるように、Kubernetes Controller Managerは、サービスアカウントのトークンの生成と署名をするためにキーペアを使用します。

service-account の証明書と秘密鍵を発行します。

cat > service-account-csr.json <<EOF
{
  "CN": "service-accounts",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  service-account-csr.json | cfssljson -bare service-account

生成物

service-account-key.pem
service-account.pem

クライアントとサーバーの証明書の配置

証明書と秘密鍵をコピーし、各ワーカーインスタンスに配置します。
(配置するもの:CAの証明書、APIサーバの証明書、ワーカーノードの証明書と秘密鍵)

for instance in worker-0 worker-1 worker-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  scp -i kubernetes.id_rsa ca.pem ${instance}-key.pem ${instance}.pem ubuntu@${external_ip}:~/
done

コントローラーインスタンスにも同様に配置します。
(配置するもの:CAの証明書、APIサーバの証明書と秘密鍵、サービスアカウント振り出し用キーペア)

for instance in controller-0 controller-1 controller-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  scp -i kubernetes.id_rsa \
    ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
    service-account-key.pem service-account.pem ubuntu@${external_ip}:~/
done

kube-proxy、kube-controller-manager、kube-scheduler、kubelet のクライアント証明書は次の手順のクライアント認証設定ファイルの生成で使います。

05-Generating Kubernetes Configuration Files for Authentication

この手順では、Kubernetes APIサーバーがKubernetesのクライアントを配置、認証できるようにするためのkubeconfigs(Kubernetes構成ファイル)を生成します。

クライアントの認証設定

まずは、conttoller-managerkubeletkube-proxyscheduler、そしてadminユーザー用のkubeconfigファイルを生成します。

KubernetesのPublic DNSアドレス

各kubeconfigはKubernetes APIサーバと接続できることが要求されます。
高可用性を実現するために、Kubernetes APIサーバの前に設置されている外部ロードバランサーのIPアドレスを使用します。

kubernetes-the-hard-way のDNSアドレスを取得して設定します。

KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \
  --load-balancer-arns ${LOAD_BALANCER_ARN} \
  --output text --query 'LoadBalancers[0].DNSName')

kubeletのkubeconfigsの生成

kubelet用のkubeconfigファイルを生成するときは、kubeletのノード名と同じクライアント証明書を使用する必要があります。
これにより、kubeletがKubernetesのNode Authorizerによって認可されるようになります。

ワーカーノード毎にkubeconfigを生成します。

for instance in worker-0 worker-1 worker-2; do
  kubectl config set-cluster kubernetes-the-hard-way \
    --certificate-authority=ca.pem \
    --embed-certs=true \
    --server=https://${KUBERNETES_PUBLIC_ADDRESS}:443 \
    --kubeconfig=${instance}.kubeconfig

  kubectl config set-credentials system:node:${instance} \
    --client-certificate=${instance}.pem \
    --client-key=${instance}-key.pem \
    --embed-certs=true \
    --kubeconfig=${instance}.kubeconfig

  kubectl config set-context default \
    --cluster=kubernetes-the-hard-way \
    --user=system:node:${instance} \
    --kubeconfig=${instance}.kubeconfig

  kubectl config use-context default --kubeconfig=${instance}.kubeconfig
done

生成物

worker-0.kubeconfig
worker-1.kubeconfig
worker-2.kubeconfig

kube-proxyのkubeconfigの生成

kube-proxyのkubeconfigも生成します。

kubectl config set-cluster kubernetes-the-hard-way \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://${KUBERNETES_PUBLIC_ADDRESS}:443 \
  --kubeconfig=kube-proxy.kubeconfig

kubectl config set-credentials system:kube-proxy \
  --client-certificate=kube-proxy.pem \
  --client-key=kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig

kubectl config set-context default \
  --cluster=kubernetes-the-hard-way \
  --user=system:kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig

kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

生成物

kube-proxy.kubeconfig

kube-controller-managerのkubeconfig

kube-controller-managerのkubeconfigを生成します。

kubectl config set-cluster kubernetes-the-hard-way \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kube-controller-manager.kubeconfig

kubectl config set-credentials system:kube-controller-manager \
  --client-certificate=kube-controller-manager.pem \
  --client-key=kube-controller-manager-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-controller-manager.kubeconfig

kubectl config set-context default \
  --cluster=kubernetes-the-hard-way \
  --user=system:kube-controller-manager \
  --kubeconfig=kube-controller-manager.kubeconfig

kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig

生成物

kube-controller-manager.kubeconfig

kube-schedulerのkubeconfig

kube-schedulerのkubeconfigを生成します。

kubectl config set-cluster kubernetes-the-hard-way \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kube-scheduler.kubeconfig

kubectl config set-credentials system:kube-scheduler \
  --client-certificate=kube-scheduler.pem \
  --client-key=kube-scheduler-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-scheduler.kubeconfig

kubectl config set-context default \
  --cluster=kubernetes-the-hard-way \
  --user=system:kube-scheduler \
  --kubeconfig=kube-scheduler.kubeconfig

kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig

生成物

kube-scheduler.kubeconfig

adminユーザー用のkubeconfig

adminユーザーのkubeconfigを生成します。

kubectl config set-cluster kubernetes-the-hard-way \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=admin.kubeconfig

kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem \
  --embed-certs=true \
  --kubeconfig=admin.kubeconfig

kubectl config set-context default \
  --cluster=kubernetes-the-hard-way \
  --user=admin \
  --kubeconfig=admin.kubeconfig

kubectl config use-context default --kubeconfig=admin.kubeconfig

生成物

admin.kubeconfig

kubeconfigの配布

kubeletkube-proxyのkubecnofigをコピーし、各ワーカーノードに配置します

for instance in worker-0 worker-1 worker-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  scp -i kubernetes.id_rsa \
    ${instance}.kubeconfig kube-proxy.kubeconfig ubuntu@${external_ip}:~/
done

kube-controller-managerkube-schedulerkubeconfigをコピーし、各コントローラーノードに配置します。

for instance in controller-0 controller-1 controller-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  scp -i kubernetes.id_rsa \
    admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig ubuntu@${external_ip}:~/
done

06-Generating the Data Encryption Config and Key

Kubernetesは、クラスタの状態、アプリケーションの設定、秘匿情報などを含むさまざまなデータが格納されます。

Kubernetesは、クラスタ内で保持しているデータを暗号化する機能が提供されています。

このステップでは、Kubernetes Secretsの暗号化に合わせた暗号化鍵と暗号化の設定 を生成します。

暗号化鍵

暗号化に使用する鍵を作成します。

ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)

暗号化の設定ファイル

暗号化の設定のためのencryption-config.yamlを生成します。

cat > encryption-config.yaml <<EOF
kind: EncryptionConfig
apiVersion: v1
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: ${ENCRYPTION_KEY}
      - identity: {}
EOF

このencryption-config.yamlをコピーし、各コントローラーノードに配置します。

for instance in controller-0 controller-1 controller-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  scp -i kubernetes.id_rsa encryption-config.yaml ubuntu@${external_ip}:~/
done

07-Bootstrapping the etcd Cluster

Kubernetesの各コンポーネントはステートレスになっており、クラスタの状態はetcdに格納され管理されています。(つまりetcdが超重要)

この手順では、3ノードのetcdクラスタを構築して、高可用性と安全な外部アクセスを実現します。

準備

このステップのコマンドは、controller-0、controller-1、controller-2の各コントローラインスタンスで実行する必要があります。

以下の様にsshコマンドを使用して各コントローラーノードにログインしてください。

for instance in controller-0 controller-1 controller-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  echo ssh -i kubernetes.id_rsa ubuntu@$external_ip
done

ここからの手順は、直前のコマンドによって出力されたそれぞれのIPアドレスにssh接続して行います。
(つまり3台のインスタンス全てで同じコマンドを実行する必要があります)

tmuxを使って並列にコマンドを走らせる

tmux を使えば、容易に複数のインスタンスで同時にコマンドを実行できます。こちら をご覧ください.

etcdのクラスタメンバーの起動

※繰り返しになりますが、ここからの手順は各コントローラーインスタンスで行ってください※

etcdのダウンロードとインストール

etcdのバイナリをgithubからDLします。

wget -q --show-progress --https-only --timestamping \
  "https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz"

DLしたファイルを展開してetcdサーバーとetcdctlコマンドラインユーティリティを取り出します。

tar -xvf etcd-v3.3.10-linux-amd64.tar.gz
sudo mv etcd-v3.3.10-linux-amd64/etcd* /usr/local/bin/

etcdサーバーの設定

sudo mkdir -p /etc/etcd /var/lib/etcd
sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/

インスタンスの内部IPアドレスは、クライアントのリクエストを受け付けて、etcdクラスタ間で通信するために使います。

現在のEC2インスタンスの内部IPアドレスを取得します。

INTERNAL_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)

各etcdのメンバーは、etcdクラスター内で名前はユニークにする必要があります。
そのため、現在使用しているEC2インスタンスのホスト名をetcdの名前として設定します。

ETCD_NAME=$(curl -s http://169.254.169.254/latest/user-data/ \
  | tr "|" "\n" | grep "^name" | cut -d"=" -f2)
echo "${ETCD_NAME}"

etcd.serviceとしてsystemdのユニットファイルを作成します。

cat <<EOF | sudo tee /etc/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos

[Service]
ExecStart=/usr/local/bin/etcd \\
  --name ${ETCD_NAME} \\
  --cert-file=/etc/etcd/kubernetes.pem \\
  --key-file=/etc/etcd/kubernetes-key.pem \\
  --peer-cert-file=/etc/etcd/kubernetes.pem \\
  --peer-key-file=/etc/etcd/kubernetes-key.pem \\
  --trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-trusted-ca-file=/etc/etcd/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
  --listen-peer-urls https://${INTERNAL_IP}:2380 \\
  --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
  --advertise-client-urls https://${INTERNAL_IP}:2379 \\
  --initial-cluster-token etcd-cluster-0 \\
  --initial-cluster controller-0=https://10.240.0.10:2380,controller-1=https://10.240.0.11:2380,controller-2=https://10.240.0.12:2380 \\
  --initial-cluster-state new \\
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

etcdサーバーの起動

sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd

念押しですが、ここまでのことを、各コントローラーノード controller-0controller-1controller-2で実行してください!

確認

etcdのクラスタの確認しておきます。

sudo ETCDCTL_API=3 etcdctl member list \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/ca.pem \
  --cert=/etc/etcd/kubernetes.pem \
  --key=/etc/etcd/kubernetes-key.pem

出力例

3a57933972cb5131, started, controller-2, https://10.240.0.12:2380, https://10.240.0.12:2379
f98dc20bce6225a0, started, controller-0, https://10.240.0.10:2380, https://10.240.0.10:2379
ffed16798470cab5, started, controller-1, https://10.240.0.11:2380, https://10.240.0.11:2379

08-Bootstrapping the Kubernetes Control Plane

この手順では、3つのインスタンスを使って可用性の高いKubernetesコントロールプレーンを作ります。

合わせて、Kubernetes API Serverを外部クライアントに公開する外部ロードバランサーも作成します。

各ノードに、Kubernetes API ServerScheduler、およびController Managerのコンポーネントをインストールします。

Prerequisites

前のステップと同じくこのステップでも、controller-0controller-1controller-2の各コントローラインスタンスで実行する必要があります。

全てのコントローラーノードにsshコマンドでログインしてコマンドを実行します

※既に各コントローラーノードにログインしている状態であれば、次の「Kubernetesコントロールプレーンのプロビジョニング」に飛んでください※

for instance in controller-0 controller-1 controller-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  echo ssh -i kubernetes.id_rsa ubuntu@$external_ip
done

ここからの手順は、直前のコマンドによって出力されたそれぞれのIPアドレスにssh接続して行います。
(つまり3台のインスタンス全てで同じコマンドを実行する必要があります)

tmuxを使って並列にコマンドを走らせる

tmux を使えば、容易に複数のインスタンスで同時にコマンドを実行できます。こちら をご覧ください.

Kubernetesコントロールプレーンのプロビジョニング

Kubernetesの設定をおくディレクトリを作成します。

sudo mkdir -p /etc/kubernetes/config

KubernetesコントローラーのバイナリのDLとインストール

Kubernetesの公式のリリースバイナリをDLします

wget -q --show-progress --https-only --timestamping \
  "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-apiserver" \
  "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-controller-manager" \
  "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-scheduler" \
  "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl"

DLしたバイナリをインストールします。

chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/

KubernetesAPIサーバーの設定

sudo mkdir -p /var/lib/kubernetes/

sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
  service-account-key.pem service-account.pem \
  encryption-config.yaml /var/lib/kubernetes/

APIサーバーをクラスターのメンバーに知らせるための設定として、インスタンスの内部IPアドレスを使います。

現在のEC2インスタンスの内部IPアドレスを取得します。

INTERNAL_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)

kube-apiserver.serviceのsystemdのユニットファイルを生成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
  --advertise-address=${INTERNAL_IP} \\
  --allow-privileged=true \\
  --apiserver-count=3 \\
  --audit-log-maxage=30 \\
  --audit-log-maxbackup=3 \\
  --audit-log-maxsize=100 \\
  --audit-log-path=/var/log/audit.log \\
  --authorization-mode=Node,RBAC \\
  --bind-address=0.0.0.0 \\
  --client-ca-file=/var/lib/kubernetes/ca.pem \\
  --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
  --enable-swagger-ui=true \\
  --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
  --etcd-cafile=/var/lib/kubernetes/ca.pem \\
  --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
  --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
  --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
  --event-ttl=1h \\
  --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
  --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
  --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
  --kubelet-https=true \\
  --runtime-config=api/all \\
  --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
  --service-cluster-ip-range=10.32.0.0/24 \\
  --service-node-port-range=30000-32767 \\
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

参考:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/

Kubernetesのコントローラーマネージャーの設定

kube-controller-managerのkubeconfigを移動させます。

sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/

kube-controller-manager.serviceのsystemdユニットファイルを生成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-controller-manager \\
  --address=0.0.0.0 \\
  --cluster-cidr=10.200.0.0/16 \\
  --cluster-name=kubernetes \\
  --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
  --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
  --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
  --leader-elect=true \\
  --root-ca-file=/var/lib/kubernetes/ca.pem \\
  --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
  --service-cluster-ip-range=10.32.0.0/24 \\
  --use-service-account-credentials=true \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Kubernetesのschedulerの設定

sudo mkdir -p /etc/kubernetes/config/

kube-schedulerのkubeconfigを移動させます。

sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/

kube-scheduler.yamlを作ります。

cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
  leaderElect: true
EOF

kube-scheduler.serviceのsystemdユニットファイルを生成します。

cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
  --config=/etc/kubernetes/config/kube-scheduler.yaml \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

コントローラーサービスの起動

sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler

Kubernetes APIサーバーは初期化が完了するまで30秒くらいかかります。

コントローラーコンポーネントの状態を確認してみます。

kubectl get componentstatuses

出力

NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok
scheduler            Healthy   ok
etcd-0               Healthy   {"health":"true"}
etcd-2               Healthy   {"health":"true"}
etcd-1               Healthy   {"health":"true"}

やったー! コントロールプレーンが起動しています!

kubelet認証のRBAC

このステップでは、Kubernetes APIサーバーが各ワーカーノードのKubelet APIにアクセスできるようにRBACによるアクセス許可を設定します。

メトリックやログの取得、Pod内でのコマンドの実行には、Kubernetes APIサーバーからKubelet APIへのアクセスが必要です。

このチュートリアルでは、Kubelet ---authorization-modeフラグをWebhookに設定します。
Webhookモードは SubjectAccessReview APIを使用して認証を行います

ここで実行する以下のコマンドはクラスター全体に作用します。このため適当なコントローラーノードにログインして一度だけ実行してください。
以下では念のため、デプロイ用インスタンスからcontroller-0ノードにログインする所から手順を記載しています

external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=controller-0" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

ssh -i kubernetes.id_rsa ubuntu@${external_ip}

kube-apiserver-to-kubeletという名前でClusterRoleを作ります。

このロールに、Kubelet APIにアクセスしてポッドの管理に関連するタスクを実行する権限を付与します。

cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
    verbs:
      - "*"
EOF

Kubernetes APIサーバーは、--kubelet-client-certificateフラグで定義したクライアント証明書を使って、kubernetesユーザーとしてKubeletに対して認証を行います。

system:kube-apiserver-to-kubeletClusterRolekubernetesユーザーにバインドします。

cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kubernetes
EOF

Kubernetesクラスターのパブリックエンドポイントを有効化する

以下のコマンドはデプロイ用インスタンス(各AWSリソースを作成するのに使用したインスタンス)で行ってください。

kubernetes-the-hard-wayロードバランサーのアドレスを取得する

KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \
  --load-balancer-arns ${LOAD_BALANCER_ARN} \
  --output text --query 'LoadBalancers[].DNSName')

HTTPリクエストを作成しKubernetesのVersion情報を取得する

curl -k --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}/version

出力例

{
  "major": "1",
  "minor": "13",
  "gitVersion": "v1.13.4",
  "gitCommit": "c27b913fddd1a6c480c229191a087698aa92f0b1",
  "gitTreeState": "clean",
  "buildDate": "2019-02-28T13:30:26Z",
  "goVersion": "go1.11.5",
  "compiler": "gc",
  "platform": "linux/amd64"
}

09-Bootstrapping the Kubernetes Worker Nodes

このステップでは、3つのKubernetesワーカーノードをブートストラップします。

下記のコンポーネントを各ノードにインストールします。

runc, gVisor, container networking plugins, containerd, kubelet, kube-proxy.

準備

この手順で記載されているコマンドは、worker-0worker-1worker-2の各ワーカーノードで実行する必要があります。

このため、まずはsshコマンドで各ワーカーノードにログインします

for instance in worker-0 worker-1 worker-2; do
  external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

  echo ssh -i kubernetes.id_rsa ubuntu@$external_ip
done

ここからの手順は、直前のコマンドによって出力されたそれぞれのIPアドレスにssh接続して行います。
(つまり3台のインスタンス全てで同じコマンドを実行する必要があります)

tmuxを使って並列にコマンドを走らせる

tmux を使えば、容易に複数のインスタンスで同時にコマンドを実行できます。こちら をご覧ください.

Kubernetesのワーカーノードのプロビジョング

使うライブラリをインストールします。

sudo apt-get update
sudo apt-get -y install socat conntrack ipset

socatはkubectl port-forwardコマンドに必要となります。

ワーカーのバイナリをDLしてインストール

wget -q --show-progress --https-only --timestamping \
  https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.15.0/crictl-v1.15.0-linux-amd64.tar.gz \
  https://storage.googleapis.com/kubernetes-the-hard-way/runsc \
  https://github.com/opencontainers/runc/releases/download/v1.0.0-rc8/runc.amd64 \
  https://github.com/containernetworking/plugins/releases/download/v0.8.2/cni-plugins-linux-amd64-v0.8.2.tgz \
  https://github.com/containerd/containerd/releases/download/v1.2.9/containerd-1.2.9.linux-amd64.tar.gz \
  https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl \
  https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-proxy \
  https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubelet

インストールする先のディレクトリを作ります。

sudo mkdir -p \
  /etc/cni/net.d \
  /opt/cni/bin \
  /var/lib/kubelet \
  /var/lib/kube-proxy \
  /var/lib/kubernetes \
  /var/run/kubernetes

ワーカーのバイナリをインストールします。

chmod +x kubectl kube-proxy kubelet runc.amd64 runsc
sudo mv runc.amd64 runc
sudo mv kubectl kube-proxy kubelet runc runsc /usr/local/bin/
sudo tar -xvf crictl-v1.15.0-linux-amd64.tar.gz -C /usr/local/bin/
sudo tar -xvf cni-plugins-linux-amd64-v0.8.2.tgz -C /opt/cni/bin/
sudo tar -xvf containerd-1.2.9.linux-amd64.tar.gz -C /

CNIネットワーキングの設定

現在のEC2インスタンスのPodのCIDR範囲を取得します。

POD_CIDR=$(curl -s http://169.254.169.254/latest/user-data/ \
  | tr "|" "\n" | grep "^pod-cidr" | cut -d"=" -f2)
echo "${POD_CIDR}"

bridgeネットワークの設定ファイルを作ります。

cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
{
    "cniVersion": "0.3.1",
    "name": "bridge",
    "type": "bridge",
    "bridge": "cnio0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "ranges": [
          [{"subnet": "${POD_CIDR}"}]
        ],
        "routes": [{"dst": "0.0.0.0/0"}]
    }
}
EOF

loopbackネットワークの設定ファイルを作ります。

cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
{
    "cniVersion": "0.3.1",
    "type": "loopback"
}
EOF

containerdの設定

containerdの設定ファイルを作ります。

sudo mkdir -p /etc/containerd/
cat << EOF | sudo tee /etc/containerd/config.toml
[plugins]
  [plugins.cri.containerd]
    snapshotter = "overlayfs"
    [plugins.cri.containerd.default_runtime]
      runtime_type = "io.containerd.runtime.v1.linux"
      runtime_engine = "/usr/local/bin/runc"
      runtime_root = ""
    [plugins.cri.containerd.untrusted_workload_runtime]
      runtime_type = "io.containerd.runtime.v1.linux"
      runtime_engine = "/usr/local/bin/runsc"
      runtime_root = "/run/containerd/runsc"
EOF

信頼できないワークロードはgVisor(runsc)ランタイムが使われます

containerd.service systemdのユニットファイルを作ります。

cat <<EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target

[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity

[Install]
WantedBy=multi-user.target
EOF

Kubeletの設定

WORKER_NAME=$(curl -s http://169.254.169.254/latest/user-data/ \
| tr "|" "\n" | grep "^name" | cut -d"=" -f2)
echo "${WORKER_NAME}"

sudo mv ${WORKER_NAME}-key.pem ${WORKER_NAME}.pem /var/lib/kubelet/
sudo mv ${WORKER_NAME}.kubeconfig /var/lib/kubelet/kubeconfig
sudo mv ca.pem /var/lib/kubernetes/

kubelet-config.yaml設定ファイルを作ります。

cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
  x509:
    clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
  mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
  - "10.32.0.10"
podCIDR: "${POD_CIDR}"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/${WORKER_NAME}.pem"
tlsPrivateKeyFile: "/var/lib/kubelet/${WORKER_NAME}-key.pem"
resolvConf: "/run/systemd/resolve/resolv.conf"
EOF

kubelet.servicesystemdユニットファイルを作ります。

cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service

[Service]
ExecStart=/usr/local/bin/kubelet \\
  --config=/var/lib/kubelet/kubelet-config.yaml \\
  --container-runtime=remote \\
  --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
  --image-pull-progress-deadline=2m \\
  --kubeconfig=/var/lib/kubelet/kubeconfig \\
  --network-plugin=cni \\
  --register-node=true \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Kubernetes Proxyの設定

sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig

Create the kube-proxy-config.yaml configuration file:

cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
  kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
EOF

kube-proxy-config.yaml 設定ファイルを作ります。

cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-proxy \\
  --config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

ワーカーのサービス群の起動

sudo systemctl daemon-reload
sudo systemctl enable containerd kubelet kube-proxy
sudo systemctl start containerd kubelet kube-proxy

念押しですが、ここまでのことを、各ワーカーノード、worker-0worker-1worker-2で実行してください!

確認

現在作業中のインスタンス(ワーカーノード)には、このステップを完了できる権限がありません。
このため、以下のコマンドは任意のコントローラーノードにログインして行ってください。
以下のコマンドは、デプロイ用インスタンス(各AWSリソースを作成する際に使用したインスタンス)からcontroller-0ノードにログインする所から記載してあります。

登録されているKubernetesノードの一覧を表示させます。

external_ip=$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=controller-0" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

ssh -i kubernetes.id_rsa ubuntu@${external_ip}

kubectl get nodes --kubeconfig admin.kubeconfig

出力

NAME             STATUS   ROLES    AGE   VERSION
ip-10-240-0-20   Ready    <none>   51s   v1.13.4
ip-10-240-0-21   Ready    <none>   51s   v1.13.4
ip-10-240-0-22   Ready    <none>   51s   v1.13.4
socat, conntrack, ipsetのそれぞれの役割がよくわかっていない

AWS、GCPともに169.254.169.254というIPアドレスはインスタンスメタデータの取得に使われる

CNIネットワークの設定の所、何やってるかもう一度復習する必要あり

10-Configuring kubectl for Remote Access

このステップでは、adminユーザーのcredenialに基づいた、kubectlコマンドラインユーティリティ用のkubeconfigファイルを生成します。

このステップでは、adminのクライアント証明書の生成に使用したディレクトリと同じディレクトリでコマンドを実行してください

Admin Kubernetes設定ファイル

各kubeconfigは、Kubernetes APIサーバーと接続できる必要があります。

高可用性を実現するために、Kubernetes APIサーバーの前に設置した外部ロードバランサーに割り当てられたIPアドレスを使用します。

adminユーザーとして認証するのに適したkubeconfigファイルを生成します。

KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \
--load-balancer-arns ${LOAD_BALANCER_ARN} \
--output text --query 'LoadBalancers[].DNSName')

kubectl config set-cluster kubernetes-the-hard-way \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://${KUBERNETES_PUBLIC_ADDRESS}:443

kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem

kubectl config set-context kubernetes-the-hard-way \
  --cluster=kubernetes-the-hard-way \
  --user=admin

kubectl config use-context kubernetes-the-hard-way

確認

remoteのKubernetesクラスターのヘルスチェックを確認します。

kubectl get componentstatuses

出力例

NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok
scheduler            Healthy   ok
etcd-1               Healthy   {"health":"true"}
etcd-2               Healthy   {"health":"true"}
etcd-0               Healthy   {"health":"true"}

remoteのKubernetesクラスタのノードの一覧を取得します。

kubectl get nodes

出力例

NAME             STATUS   ROLES    AGE     VERSION
ip-10-240-0-20   Ready    <none>   3m35s   v1.13.4
ip-10-240-0-21   Ready    <none>   3m35s   v1.13.4
ip-10-240-0-22   Ready    <none>   3m35s   v1.13.4

11-Configuring kubectl for Remote Access

ノードにスケジュールされたPodは、ノードのPod CIDR範囲からIPアドレスを受け取ります。

この時点では、ネットワークルートが見つからないため、Podは異なるノードで実行されている他のPodと通信できません。

この手順では、ノードのPod CIDR範囲をノードの内部IPアドレスにマップするための、各ワーカーノードのルートを作成します。

Kubernetesのネットワークモデルの実装は他にもあります。

ルーティングテーブルとルート群

このセクションでは、kubernetes-the-hard-wayVPCネットワーク内でルートを作るために必要な情報を集めます。

通常、この機能はflanne, calico, amazon-vpc-cin-k8s等のCNIプラグインによって提供されます。
これを手作業で行うことにより、これらのプラグインがバックグラウンドで何をしているのかを理解しやすくなります。

まずは各ワーカーインスタンスの内部IPアドレスとPod CIDR範囲を表示させます。

for instance in worker-0 worker-1 worker-2; do
  instance_id_ip="$(aws ec2 describe-instances \
    --filters "Name=tag:Name,Values=${instance}" \
    --output text --query 'Reservations[].Instances[].[InstanceId,PrivateIpAddress]')"
  instance_id="$(echo "${instance_id_ip}" | cut -f1)"
  instance_ip="$(echo "${instance_id_ip}" | cut -f2)"
  pod_cidr="$(aws ec2 describe-instance-attribute \
    --instance-id "${instance_id}" \
    --attribute userData \
    --output text --query 'UserData.Value' \
    | base64 --decode | tr "|" "\n" | grep "^pod-cidr" | cut -d'=' -f2)"
  echo "${instance_ip} ${pod_cidr}"

  aws ec2 create-route \
    --route-table-id "${ROUTE_TABLE_ID}" \
    --destination-cidr-block "${pod_cidr}" \
    --instance-id "${instance_id}"
done

出力例

10.240.0.20 10.200.0.0/24
{
    "Return": true
}
10.240.0.21 10.200.1.0/24
{
    "Return": true
}
10.240.0.22 10.200.2.0/24
{
    "Return": true
}

ルートの確認

各ワーカーインスタンスに対してネットワークルートを確認します。

aws ec2 describe-route-tables \
  --route-table-ids "${ROUTE_TABLE_ID}" \
  --query 'RouteTables[].Routes'

出力例

[
    [
        {
            "DestinationCidrBlock": "10.200.0.0/24",
            "InstanceId": "i-0879fa49c49be1a3e",
            "InstanceOwnerId": "107995894928",
            "NetworkInterfaceId": "eni-0612e82f1247c6282",
            "Origin": "CreateRoute",
            "State": "active"
        },
        {
            "DestinationCidrBlock": "10.200.1.0/24",
            "InstanceId": "i-0db245a70483daa43",
            "InstanceOwnerId": "107995894928",
            "NetworkInterfaceId": "eni-0db39a19f4f3970f8",
            "Origin": "CreateRoute",
            "State": "active"
        },
        {
            "DestinationCidrBlock": "10.200.2.0/24",
            "InstanceId": "i-0b93625175de8ee43",
            "InstanceOwnerId": "107995894928",
            "NetworkInterfaceId": "eni-0cc95f34f747734d3",
            "Origin": "CreateRoute",
            "State": "active"
        },
        {
            "DestinationCidrBlock": "10.240.0.0/24",
            "GatewayId": "local",
            "Origin": "CreateRouteTable",
            "State": "active"
        },
        {
            "DestinationCidrBlock": "0.0.0.0/0",
            "GatewayId": "igw-00d618a99e45fa508",
            "Origin": "CreateRoute",
            "State": "active"
        }
    ]
]

12-Deploying the DNS Cluster Add-on

この手順中、説明とコマンドが食い違っている箇所があったので修正してあります

このステップでは、Kubernetesクラスタ内で動いているアプリケーションに、CoreDNSを使ったDNSベースのサービスディスカバリを提供するDNSアドオンをデプロイします。

DNSクラスターアドオン

corednsクラスターアドオンをデプロイします。

kubectl create -f https://raw.githubusercontent.com/prabhatsharma/kubernetes-the-hard-way-aws/master/deployments/core-dns.yaml

出力

serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.apps/coredns created
service/kube-dns created

kube-dns deploymentによって作られたPodの確認

kubectl get pods -l k8s-app=kube-dns -n kube-system

出力例

NAME                      READY   STATUS    RESTARTS   AGE
coredns-7946767f6-trbvx   1/1     Running   0          42s

確認

busybox deploymentを作成します。

kubectl run busybox --image=busybox:1.28 --restart=Never -- sleep 3600

busybox deploymentによって作られてPodを確認します。

kubectl get pod busybox

出力

NAME       READY     STATUS    RESTARTS   AGE
busybox   1/1       Running   0          45s

busybox pod内からkubernetesserviceのDNS lookupを行います。

kubectl exec -it busybox -- nslookup kubernetes

出力

Server:    10.32.0.10
Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.32.0.1 kubernetes.default.svc.cluster.local

13-Smoke Test

このステップでは、Kubernetesクラスタが正しく機能していることを確認するためのタスクを実行します。

データの暗号化

このステップでは保存されているデータの暗号化を確認します。

generic secretを作ります。

kubectl create secret generic kubernetes-the-hard-way --from-literal="mykey=mydata"

etcdに保存されているkubernetes-the-hard-waysecretをhexdumpします。

external_ip=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=controller-0" \
  --output text --query 'Reservations[].Instances[].PublicIpAddress')

ssh -i kubernetes.id_rsa ubuntu@${external_ip}

controller-0ノードで以下のコマンドを実行します

sudo ETCDCTL_API=3 etcdctl get \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/etcd/ca.pem \
  --cert=/etc/etcd/kubernetes.pem \
  --key=/etc/etcd/kubernetes-key.pem\
  /registry/secrets/default/kubernetes-the-hard-way | hexdump -C

出力

00000000  2f 72 65 67 69 73 74 72  79 2f 73 65 63 72 65 74  |/registry/secret|
00000010  73 2f 64 65 66 61 75 6c  74 2f 6b 75 62 65 72 6e  |s/default/kubern|
00000020  65 74 65 73 2d 74 68 65  2d 68 61 72 64 2d 77 61  |etes-the-hard-wa|
00000030  79 0a 6b 38 73 3a 65 6e  63 3a 61 65 73 63 62 63  |y.k8s:enc:aescbc|
00000040  3a 76 31 3a 6b 65 79 31  3a 7b 8e 59 78 0f 59 09  |:v1:key1:{.Yx.Y.|
00000050  e2 6a ce cd f4 b6 4e ec  bc 91 aa 87 06 29 39 8d  |.j....N......)9.|
00000060  70 e8 5d c4 b1 66 69 49  60 8f c0 cc 55 d3 69 2b  |p.]..fiI`...U.i+|
00000070  49 bb 0e 7b 90 10 b0 85  5b b1 e2 c6 33 b6 b7 31  |I..{....[...3..1|
00000080  25 99 a1 60 8f 40 a9 e5  55 8c 0f 26 ae 76 dc 5b  |%..`.@..U..&.v.[|
00000090  78 35 f5 3e c1 1e bc 21  bb 30 e2 0c e3 80 1e 33  |x5.>...!.0.....3|
000000a0  90 79 46 6d 23 d8 f9 a2  d7 5d ed 4d 82 2e 9a 5e  |.yFm#....].M...^|
000000b0  5d b6 3c 34 37 51 4b 83  de 99 1a ea 0f 2f 7c 9b  |].<47QK....../|.|
000000c0  46 15 93 aa ba 72 ba b9  bd e1 a3 c0 45 90 b1 de  |F....r......E...|
000000d0  c4 2e c8 d0 94 ec 25 69  7b af 08 34 93 12 3d 1c  |......%i{..4..=.|
000000e0  fd 23 9b ba e8 d1 25 56  f4 0a                    |.#....%V..|
000000ea

etcdキーは、k8s:enc:aescbc:v1:key1というプレフィックスになっているはずです。

これは、aescbcプロバイダがkey1という暗号化キーでデータを暗号化したことを表しています。

Deployment - To be run on local laptop

このステップではDeploymentの作成と管理ができているかを確認します。

nginx web serverのdeploymentを作成します。

kubectl create deployment nginx --image=nginx

nginx deploymentによってできたPodを確認します。

kubectl get pods -l app=nginx

出力

NAME                     READY     STATUS    RESTARTS   AGE
nginx-65899c769f-xkfcn   1/1       Running   0          15s

Port Forwarding

このステップでは、port forwardingを使って外部からアプリケーションにアクセスできるかを確認します。

nginx podのフルネームを取得します。

POD_NAME=$(kubectl get pods -l app=nginx -o jsonpath="{.items[0].metadata.name}")

ローカルの8080ポートをnginx Podの80番ポートにフォワードします。

kubectl port-forward $POD_NAME 8080:80

出力

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

別のターミナルからフォワードしたアドレスにHTTPリクエストを投げてみます。

curl --head http://127.0.0.1:8080

出力

HTTP/1.1 200 OK
Server: nginx/1.17.3
Date: Sat, 14 Sep 2019 13:54:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 08:50:00 GMT
Connection: keep-alive
ETag: "5d5279b8-264"
Accept-Ranges: bytes

もとのターミナルに戻ってnginx Podへのフォワーディングを止めます。

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
^C

Logs

このステップでは、コンテナのログの取得ができるかを確認します。

nginx Podのログを表示します。

kubectl logs $POD_NAME

出力

127.0.0.1 - - [14/May/2018:13:59:21 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.52.1" "-"

Exec

このステップではコンテナ内でのコマンド実行ができるかを確認します。

nginxコンテナに入って、nginx -vを実行してnginxのバージョンを表示します。

kubectl exec -ti $POD_NAME -- nginx -v

出力

nginx version: nginx/1.17.3

Services

このステップでは、Serviceを使ったアプリケーションの公開ができるかを確認します。

nginx deploymentをNodePort を使って公開します。

kubectl expose deployment nginx --port 80 --type NodePort

クラスターがクラウドプロバイダーインテグレーションの設定がされていないため、LoadBalancerは使用できません。

この手順では、クラウドプロバイダーインテグレーションの設定は対象外です。

nginx serviceでアサインされたノードのポート取得します。

NODE_PORT=$(kubectl get svc nginx \
  --output=jsonpath='{range .spec.ports[0]}{.nodePort}')

nginxノードポートに外部からアクセスできるようにファイヤーウォールのルール追加します。

aws ec2 authorize-security-group-ingress \
  --group-id ${SECURITY_GROUP_ID} \
  --protocol tcp \
  --port ${NODE_PORT} \
  --cidr 0.0.0.0/0

ワーカーインスタンスから外部IPアドレスを取得します。

INSTANCE_NAME=$(kubectl get pod $POD_NAME --output=jsonpath='{.spec.nodeName}')

もしもあなたが今回クラスターをUS-EAST-1に立ち上げている場合、以下のコマンドを実行してください。

EXTERNAL_IP=$(aws ec2 describe-instances \
    --filters "Name=network-interface.private-dns-name,Values=${INSTANCE_NAME}.ec2.internal" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

US-EAST-1以外のリージョンにクラスターを立ち上げている場合は、以下のコマンドを実行してください。

EXTERNAL_IP=$(aws ec2 describe-instances \
    --filters "Name=network-interface.private-dns-name,Values=${INSTANCE_NAME}.${AWS_REGION}.compute.internal" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

外部IPアドレスとnginxノードポート組わせてHTTPリクエストを投げてみます。

curl -I http://${EXTERNAL_IP}:${NODE_PORT}

出力

HTTP/1.1 200 OK
Server: nginx/1.17.3
Date: Sat, 14 Sep 2019 13:54:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 08:50:00 GMT
Connection: keep-alive
ETag: "5d5279b8-264"
Accept-Ranges: bytes

Untrusted Workloads

gVisorを使って信頼されていないワークロードが動かせるかを確認します。

untrustedPodを作ります。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: untrusted
  annotations:
    io.kubernetes.cri.untrusted-workload: "true"
spec:
  containers:
    - name: webserver
      image: gcr.io/hightowerlabs/helloworld:2.0.0
EOF

確認

このセクションでは、割り当てられたワーカーノードを調べて、untrustedPodがgVisor(runsc)の下で実行されていることを確認します。

untrustedPodが実行されていることを確認します。

kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP           NODE             NOMINATED NODE
busybox                  1/1       Running   0          5m        10.200.0.2   ip-10-240-0-20   <none>
nginx-64f497f8fd-l6b78   1/1       Running   0          3m        10.200.1.2   ip-10-240-0-21   <none>
untrusted                1/1       Running   0          8s        10.200.2.3   ip-10-240-0-22   <none>

untrustedPodが実行されているノードの名前を取得します。

INSTANCE_NAME=$(kubectl get pod untrusted --output=jsonpath='{.spec.nodeName}')

もしもあなたが今回クラスターをUS-EAST-1に立ち上げている場合、以下のコマンドを実行してください。

INSTANCE_IP=$(aws ec2 describe-instances \
    --filters "Name=network-interface.private-dns-name,Values=${INSTANCE_NAME}.ec2.internal" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

US-EAST-1以外のリージョンにクラスターを立ち上げている場合は、以下のコマンドを実行してください。

INSTANCE_IP=$(aws ec2 describe-instances \
    --filters "Name=network-interface.private-dns-name,Values=${INSTANCE_NAME}.${AWS_REGION}.compute.internal" \
    --output text --query 'Reservations[].Instances[].PublicIpAddress')

ワーカーノードにSSH接続します

ssh -i kubernetes.id_rsa ubuntu@${INSTANCE_IP}

gVisorのもとで動いているコンテナの一覧を取得します。

sudo runsc --root  /run/containerd/runsc/k8s.io list
I0514 14:03:56.108368   14988 x:0] ***************************
I0514 14:03:56.108548   14988 x:0] Args: [runsc --root /run/containerd/runsc/k8s.io list]
I0514 14:03:56.108730   14988 x:0] Git Revision: 08879266fef3a67fac1a77f1ea133c3ac75759dd
I0514 14:03:56.108787   14988 x:0] PID: 14988
I0514 14:03:56.108838   14988 x:0] UID: 0, GID: 0
I0514 14:03:56.108877   14988 x:0] Configuration:
I0514 14:03:56.108912   14988 x:0]              RootDir: /run/containerd/runsc/k8s.io
I0514 14:03:56.109000   14988 x:0]              Platform: ptrace
I0514 14:03:56.109080   14988 x:0]              FileAccess: proxy, overlay: false
I0514 14:03:56.109159   14988 x:0]              Network: sandbox, logging: false
I0514 14:03:56.109238   14988 x:0]              Strace: false, max size: 1024, syscalls: []
I0514 14:03:56.109315   14988 x:0] ***************************
ID                                                                 PID         STATUS      BUNDLE                                                           CREATED                          OWNER
3528c6b270c76858e15e10ede61bd1100b77519e7c9972d51b370d6a3c60adbb   14766       running     /run/containerd/io.containerd.runtime.v1.linux/k8s.io/3528c6b270c76858e15e10ede61bd1100b77519e7c9972d51b370d6a3c60adbb   2018-05-14T14:02:34.302378996Z
7ff747c919c2dcf31e64d7673340885138317c91c7c51ec6302527df680ba981   14716       running     /run/containerd/io.containerd.runtime.v1.linux/k8s.io/7ff747c919c2dcf31e64d7673340885138317c91c7c51ec6302527df680ba981   2018-05-14T14:02:32.159552044Z
I0514 14:03:56.111287   14988 x:0] Exiting with status: 0

untrustedPodのIDを取得します。

POD_ID=$(sudo crictl -r unix:///var/run/containerd/containerd.sock pods --name untrusted -q)

untrustedPodの中で動いてるwebserverコンテナのIDを取得します。

CONTAINER_ID=$(sudo crictl -r unix:///var/run/containerd/containerd.sock ps -p ${POD_ID} -q)

gVisorrunscコマンドを使って、webserverコンテナの中で走っているプロセスを表示します。

sudo runsc --root /run/containerd/runsc/k8s.io ps ${CONTAINER_ID}

出力

I0514 14:05:16.499237   15096 x:0] ***************************
I0514 14:05:16.499542   15096 x:0] Args: [runsc --root /run/containerd/runsc/k8s.io ps 3528c6b270c76858e15e10ede61bd1100b77519e7c9972d51b370d6a3c60adbb]
I0514 14:05:16.499597   15096 x:0] Git Revision: 08879266fef3a67fac1a77f1ea133c3ac75759dd
I0514 14:05:16.499644   15096 x:0] PID: 15096
I0514 14:05:16.499695   15096 x:0] UID: 0, GID: 0
I0514 14:05:16.499734   15096 x:0] Configuration:
I0514 14:05:16.499769   15096 x:0]              RootDir: /run/containerd/runsc/k8s.io
I0514 14:05:16.499880   15096 x:0]              Platform: ptrace
I0514 14:05:16.499962   15096 x:0]              FileAccess: proxy, overlay: false
I0514 14:05:16.500042   15096 x:0]              Network: sandbox, logging: false
I0514 14:05:16.500120   15096 x:0]              Strace: false, max size: 1024, syscalls: []
I0514 14:05:16.500197   15096 x:0] ***************************
UID       PID       PPID      C         STIME     TIME      CMD
0         1         0         0         14:02     40ms      app
I0514 14:05:16.501354   15096 x:0] Exiting with status: 0

14-Check images/pods/containers on worker nodes using crictl

ワーカーノードにログインし、リソース一覧を確認します。
この手順は、立ち上がっている3台のワーカーノード全てで実行可能です。

external_ip=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=worker-0" \
  --output text --query 'Reservations[].Instances[].PublicIpAddress')

ssh -i kubernetes.id_rsa ubuntu@${external_ip}

以下のコマンドを実行し、出力を確認します

sudo crictl -r unix:///var/run/containerd/containerd.sock images

出力例

IMAGE                                                  TAG                 IMAGE ID            SIZE
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64   1.14.7              5feec37454f45       10.9MB
gcr.io/google_containers/k8s-dns-kube-dns-amd64        1.14.7              5d049a8c4eec9       13.1MB
gcr.io/google_containers/k8s-dns-sidecar-amd64         1.14.7              db76ee297b859       11.2MB
k8s.gcr.io/pause                                       3.1                 da86e6ba6ca19       317kB
sudo crictl -r unix:///var/run/containerd/containerd.sock pods

出力

POD ID              CREATED             STATE               NAME                        NAMESPACE           ATTEMPT
9a304a19557f7       2 hours ago         Ready               kube-dns-864b8bdc77-c5vc2   kube-system         0
sudo crictl -r unix:///var/run/containerd/containerd.sock ps

出力

CONTAINER ID        IMAGE                                                                     CREATED             STATE               NAME                ATTEMPT
611bfea53997d       sha256:db76ee297b8597fc007b23a90619314b8405bb1df6dcad189df0a123a09e7ecc   2 hours ago         Running             sidecar             0
824f26368efc0       sha256:5feec37454f45d060c5f528c7d0bd4958df39e7ffd2e65ae42aae68bf78f69a5   2 hours ago         Running             dnsmasq             0
f3d35b783af1e       sha256:5d049a8c4eec92b21ca4be399c260166d96569a1a52d497f4a0365bb55c1a18c   2 hours ago         Running             kubedns             0

15-Cleaning Up

この手順では、今まで作ってきたリソースを削除します。

EC2インスタンス

コントローラーノード、ワーカーノードを削除します。

aws ec2 terminate-instances \
  --instance-ids \
    $(aws ec2 describe-instances \
      --filter "Name=tag:Name,Values=controller-0,controller-1,controller-2,worker-0,worker-1,worker-2" \
      --output text --query 'Reservations[].Instances[].InstanceId')
aws ec2 delete-key-pair --key-name kubernetes

Networking

外部ロードバランサー、VPC等のネットワークリソースを削除します。

aws elbv2 delete-load-balancer --load-balancer-arn "${LOAD_BALANCER_ARN}"
aws elbv2 delete-target-group --target-group-arn "${TARGET_GROUP_ARN}"
aws ec2 delete-security-group --group-id "${SECURITY_GROUP_ID}"
ROUTE_TABLE_ASSOCIATION_ID="$(aws ec2 describe-route-tables \
  --route-table-ids "${ROUTE_TABLE_ID}" \
  --output text --query 'RouteTables[].Associations[].RouteTableAssociationId')"
aws ec2 disassociate-route-table --association-id "${ROUTE_TABLE_ASSOCIATION_ID}"

aws ec2 delete-route-table --route-table-id "${ROUTE_TABLE_ID}"
aws ec2 detach-internet-gateway \
  --internet-gateway-id "${INTERNET_GATEWAY_ID}" \
  --vpc-id "${VPC_ID}"
aws ec2 delete-internet-gateway --internet-gateway-id "${INTERNET_GATEWAY_ID}"
aws ec2 delete-subnet --subnet-id "${SUBNET_ID}"
aws ec2 delete-vpc --vpc-id "${VPC_ID}"

おつかれさまでした!
以上でkubernetes the hard wayは終了です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS IoT Coreのコンソールからすべてのモノが消えた

現象

AWS IoT Coreの開発中にAWSの他のサービスのダッシュボードを行き来していたらいつの間にかIoT Coreのダッシュボード上から登録したはずのすべてのモノが消えていた。

何が起こっていたか

ダッシュボードを行き来するうちにAWSのリージョンが切り替わっていたため、IoT Coreのダッシュボードに戻ってきたときに登録したところと別のリージョンの情報を参照していた。

解決策

右上のリージョン選択で正しいリージョンを選択

その他

びっくりしました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lambda内からcloudfrontへのaxiosリクエストが403になる

ニッチなネタですが、同じくお困りの方がいらっしゃったらご参考にどうぞ

アーキテクチャ

cloudfront -> api gateway -> lambda(nuxt)

この環境で

nuxt(axios) -> (out bounds) -> HTTP API(cloudfront)

このようにaxiosを利用して外部のサービスで、そのサービスがcloudfrontを利用している場合、その通信は403となり失敗します。

原因

axiosでリクエストする際に付与しているヘッダー情報に原因がありました。
viaです。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via

これはcloudfrontで付与されて、そのままapi gateway、lambdaへと引き継がれ、axiosのデフォルトヘッダーに設定されていました。

改善

cloudfrontでは多段構成を禁止する仕組みとしてこのviaを利用しているようで、このヘッダーを消すことで無事疎通が可能となりました。

nuxt(plugins)
export default ({ $axios }: Context) => {
  $axios.defaults.headers.common = {}
}

※この例では初期設定値をすべて消しています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

未経験、学生向け、AWSで押さえておいた方がいいサービス

経緯

つくばのニアショアオフィスにてインターン生の採用も決まり、毎年若干名ですが新卒エンジニアも入社してくるので
AWSを勉強する上でのおすすめツール及び業務でAWSを使用すると仮定した時に押さえておいた方がいいサービスを記載
AWS初心者で勉強したい方や、勉強していて業務経験を得られる会社に転職を検討している方向けかなと

前提

AWSのアカウントを開設したが何から手をつけたらいいかわからないとう状態を想定
AWSで意識すべきこととしてまずDNSの基本を学んでおくこと
(あらゆるところに出てくるので・・・)
仕事とプライベートだと毛並みが全く変わってくるのでそれぞれを分けて紹介します。

AWSで何か勉強する時のおすすめ

  • Lightsail
     
     EC2より設定が簡略されており初心者向け
     料金がリーズナブルな部分も勉強向きです

  • Cloud9

 アプリケーションの開発一気にやるならこれがおすすめです。
 すぐにプログラミングの学習ができて、特段面倒な設定も不要です

AWSの基本として押さえておきたいもの

  • EC2
  • S3
  • RDS
  • VPC
  • Route 53

この辺りは業務で間違いなく使用するので押さえておいていただけるといいのかなと

実務を見越して押さえておくと良いもの

  • ElastiCache
  • CloudFront

他にももちろんたくさんあるのですが一旦記載

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS試験対策(⑥セキュリティ)

自分用メモ第6弾。
セキュリティは結構おろそかにする人が多いからここをちゃんとやれば強みになる気がする。テストでの比率も高いから蔑ろにはできない。

AWSアカウントとIAM

AWSアカウントは、AWSとの契約の単位。他のアカウントと課金やネットワーク、セキュリティに干渉できない。家とその家主みたいなイメージ。他の人の家の家計簿は見れないし、家の中の部屋構造とかも見れない
IAMがその中のユーザーみたいなもの。家の住人って感じ。
AWSアカウントのルートユーザーには叶わない。しかしルート使いすぎるのもよくないので、このIAMをつくって権限を与えてあげる。
父「長男は一番偉いから俺と同じくらいなんでもやっていいぞ」
父「次男はほとんどやっていいけど〇〇触っちゃだめな」
んで父を殺して長男に実権を握らす的な。なぜなら父が洗脳されたら家族崩壊するからそうなるまえに殺しとけ、長男を使えって方針。現実に例えるとやべーわこれ。

AWS Organization

複数のAWSアカウントを一元管理できるサービス。ポリシーベース。
二世帯住宅とかだとわかりやすいかも。おじいちゃんがマスターアカウントでお父さんはそこに所属するメンバーアカウント。
おじいちゃんに一括請求が行くように設定できたりする。

IAMユーザーとグループ

ユーザーは5000ユーザーまで作成可能。名前とか所属グループとかそもそもの権限の偉さとか決めれる。生まれたてではなにも権限なし。

グループはユーザーの集合。100グループまで作れる。グループでのログインとかはできない。
ユーザー一人ひとりに権限つけてってもいいが、グループ一回作っちゃえばそこに所属させるだけで同じ権限をたくさんの人につけれる。セキュリティグループと一緒の考え。

使用可能な認証情報

マネジメントコンソールにログインするにはユーザ名とパスワードが必要。MFAという多要素認証にすることもできる。

api操作やAWS CLIを使うにはアクセスキーIDとシークレットアクセスキーが必要。
SOAPリクエストにはX.509証明書が必要…SOAPリクエストってなんだ?
まあ覚え方としては、ソープ行きたいなら証明書必要ってことね…(最悪)

セキュリティを考えるには、パスワードとかキーとかは定期的に更新しようね!
あとプログラムコードに直接記入して外部公開しちゃだめだぞ!噂に聞いた話だとウン万の請求がくるだとか…

パスワードポリシーも設定できる。ルールですね。大文字入れろや〜とか文字数少ねえぞカス〜とかそういうやつ。あと、有効期限とか。

IAMポリシー

要するに、あなたはどこまで触っていいよ〜っていう取り決め。
管理ポリシーとインラインポリシーがある。
管理ポリシーは、複数のユーザ、グループ、ロールに割り当てできる。
インラインポリシーは個々のユーザ、グループ、ロールに直接設定する。
テンプレで管理するか、テンプレでは補えない細かーいところまで設定するか、みたいな違い?
テンプレもAWSが作成、管理してるAWS管理ポリシーと、IAM管理者が定義するカスタマー管理ポリシーがある。

IAMポリシーの記述方法

JSON形式で、記載する。
設定項目は4つ。effect、action、resource、condition。

effect
これから書く操作を許可なのか拒否なのか、allow、denyで書く

action
操作。s3のばけっと作る。とかインスタンス作る。とか。書き込み、読み込みの話。

resource
ARN(アマゾンリソースネーム)で書く。
決り文句として最初に
arn:aws:
が付く。その後にサービス、リージョン、アカウント名、リソース名を記載する。
要するにどこの何かを書く。東京リージョンのs3とか。

conditionは有効になる条件を書く。
要するに対象者。IPがこれな人は上記条件が適用されるよ〜みたいな。

権限の算出方法は、ポリシー(ルール)が何もなければ全拒否。
一つでも拒否があれば拒否。許可のみなら許可。
基本拒否優先って感じ。明示的denyという。

リソースベースのポリシー

今まではユーザー側のポリシーの話。こっちはリソース側のポリシー。s3のアクセスを特定のIPからのみにしたいときに使える。
さっきの4つに加えて、principalが増える。
ここに、対象になるAWSアカウント、ユーザーを書く。どこ所属の誰。
このアカウントのこのユーザーのこのIPの人は、s3のこの部分の読み取り権あげますよー!みたいな感じ。

IAMロール

一番出てくるし重要な気がする。
アプリやAWSサービスに権限を与える仕組み。パスワード認証はなく、一時的にセキュリティ認証作成される。
EC2インスタンスにロールで権限付与すれば、EC2インスタンスのアプリからAWSサービスを操作できるぞ!
さっきいったアクセスキー、シークレットキーの流出リスクですが、ロール使えばアクセスキー不要のため、そもそも流出しないぞ!セキュアだね!
アプリを認証させたいときはアクセスキー使わずにロール設定してしまおう。
IAMロールを使うと、サービスからサービスにアクセスする許可も出せる。LambdaでS3に書き込む処理をしたいとき、その関数にロールつければ実現できる。

IAMロールを使う場合、さっきも出てきたけど一時的にセキュリティ認証情報を付与してくれる。STSという。アクセスキーいらず!って言ったけど、厳密にはSTS君が一時的にアクセスキーを作ってる。しかし一時的だからセキュリティリスクはないって感じ。

switch Role

他の人のAWSアカウントは触れないといったな。あれは嘘だ。
触りたい対象のアカウントにロールを作って、触る側の人にロールをあげれば触れる。
ロールは帽子のマークなので、配達員を連想して、配達員になれば他人の家入れるよっていう覚え方で行こうと思う。
AssumeRoleってやつを呼び出してSTSから一時的にセキュリティ認証してるみたい。
これ使えば一つのアカウントでいろんなアカウントに入れるから便利。

IDフェデレーション(連携)

要するに連携らしいけどパターンがありすぎて覚えるのがしんどい。ツイッターのIDでQiitaにログインできるよみたいな話。どれであっても、ロールによって一時的に認証してる。

表は後で作る

セキュリティサービス

責任共有モデルといって、ここまでがAWS管理、ここまでがユーザー管理というのが決まってる。物理的なサーバ管理はAWS、ユーザのID管理はユーザ側など。

AWS directory service

マネージド型のディレクトリサービス。3タイプある。

Simple ad
AWSクラウド上にあるドメコン。他のドメインとの信頼関係等の追加機能は利用できない。

AWS managed Microsoft ad
既存のオンプレのドメコンと、AWS側のこのドメコンを信頼関係に置くことによって、オンプレのドメコンのユーザーが、AWSのインスタンスにIDそのままで入れる仕組み。拡張機能は使用できる。

AD Connect
既存のオンプレのドメコンと、AWS側のこのドメコンを認証させることで、オンプレのドメコンのユーザーが、AWSマネジメントコンソールにアクセスできる仕組み。

AWS Single Sign_on
SSOはSAML2.0に対応してるクラウドベースのアプリケーションへのシングルサインオンができるサービス。
要するに、一回の認証ですべて使えるようにするよってこと。サービスごとに認証しなくていい。
ADと連携できる。使ったことなくてあんまピンとこないなあ…

Amazon GuardDuty

悪意のある操作や不正な動作を調べてくれる。Lambdaと連携して自動修復実行もできる。

Amazon Inspector

セキュリティ評価サービス。インスタンスの脆弱性とかで評価。使うにはエージェントをインスタンスに入れる。

AWS Shield

DDoS攻撃から守ってくれる盾。スタンダードとアドバンストがある。スタンダードはリフレクション攻撃などの一般的に多いやつから守ってくれる。
アドバンストはアプリケーションも守ってくれる。また、DDoSによってコストが急上昇しても、それに備えるコスト保護がある。

AWS WAF

ウェブアプリケーションファイアーウォールのこと。ウェブアプリケーションを攻撃から守ってくれる。
ちなみにShieldアドバンストを使ってれば無料になる。

AWS KMS

キーマネージャーシステム。
そのまま、鍵の管理をしてくれる。ほかよーわからんです…。

AWS CloudHSM

ハードウェアセキュリティモジュール。なにこれ。わからんけどセキュリティ系(適当)
はい。調べました。KMSと同じで鍵管理してくれるやつ。しかしハードウェア依存であり、セキュリティが高いらしい。米国政府の規格になるレベル。すげーKMSって感じ。

Amazon Macie

機械学習によって、S3のなかの機密データを見つけてくれて、暗号化してくれるんだとか。また、それにアクセスしようとしたユーザの分析もしてくれる。

とりあえず以上。次はネットワーク。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudFrontにキャッシュしたS3上のWordPress記事に独自ドメインでアクセスする

はじめに

最終的には以下のような構成を目指して構築します。
WordPress Architecture.jpg

構築作業の覚書としてQiita記事を作成しておきます。
また、この記事ではRoute53経由で、CloudFrontでキャッシュしたS3上の記事にアクセスする方法を記載します。
WordPress Architecture_2.png

前段のEC2とS3の部分は以下の記事で。
WordPressで作成した記事をS3に連携しエンドポイントでホスティングする

本アーキテクチャのメリット

  • ColoudFront
    • CDNを咬ますことで負荷に強くなったりレンダリング速度が上がる
    • S3、Route53との連携が簡単
  • サーバー容量も気にしなくて良い(訳ではないが、EC2に直接配置するよりはまし)
    • WordPressが稼働できればいいのでインスタンスタイプも小さくてよくなる
  • Route53は可用性100%

構築手順

前提

ドメインをお名前.com等で取得していることが前提になっています。
後述のRoute53で一緒に取得してもいいんですが、すでにお名前.comで取得していたのでそのドメインを使用することにしました。

Route53でホストゾーンを作成する

[ドメイン名]に使用するドメインを入力してホストゾーンを作成します。
Route53.png

ACM(Amazon Certificate Manager)で証明書を作成する

実運用のことを考えるとSSL化は必須なので、SSL証明を用意します。
CloudFrontで使用する場合はバージニアリージョン(us-east-1)で作成する必要があるとのこと。
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html#https-requirements-aws-region

1つも証明書を作成していない場合、以下のような画面が表示されますのでリージョンをバージニア(us-east-1)に変更し [証明書のプロビジョニング] の [今すぐ始める] を押下する。
ACM_1.png

[パブリック証明書] を選択し [次へ] を押下します。
ACM_2.png

[ドメイン名] にドメイン名を入力して [次へ] を押下します。
ACM_3.png

ドメインの検証方法を選択します。
どちらでも検証自体は可能ですが、今回は [DNSの検証] を選択します。
ACM_4.png

入力した内容と相違なければ [確定とリクエスト] を押下します。
ACM_5.png

ここまで設定を行うと、証明書が検証保留中という状態になります。
証明書の発行にはこの検証(今回選択しているのはDNSの検証)を終える必要があるので、各種設定を行いDNSの検証が通るようにしていきます。
DNSの設定値が記載されたCSVファイルでダウンロードできるので、ダウンロードして一旦終了です。

Route53に情報を登録する

ダウンロードしたCSVにDNSに設定するレコード名とCNAMEが記載されているので、先ほど作成したRoute53のホストゾーンにレコードを追加していきます。

  • [Record Name] の値を [名前] に設定
  • [Record Value]の値を [値] に設定

Route53_CNAME.png

お名前.comでネームサーバーを変更する

Route53を使用して名前解決を行えるように、お名前.com側でネームサーバーの変更を行います。
※操作方法は割愛
ネームサーバー名はRoute53で確認できます。
Route53_nameserver.png

ACMで検証が終わったか確認する

DNSへのCNAMEレコード追加とネームサーバーの登録が終われば、通常数分で検証が終わり証明書が発行されるはずです。
なお、ACMの検証猶予は72時間らしいので、もしそれまでに設定ができず検証ができなかった場合は、再度リクエストすればOKみたいです。

もし 72 時間経っても ACM が DNS レコードを検証できず証明書を発行できなかった場合は、リクエストはタイムアウトし、検証状態は Timed out / タイムアウト と表示されます。やり直すには、新たにリクエストを作成する必要があります。

https://aws.amazon.com/jp/blogs/news/easier-certificate-validation-using-dns-with-aws-certificate-manager/

CloudFrontのディストリビューションを作成する

ここからはCloudFrontの構築を行なっていきます。

[Create Distribution] を押下し、Webの方の [Get Started] を押下します。
CloudFront_1.png
CloudFront_2.png

入力画面が表示されるので、以下の内容を設定し [Create Distribution] を押下します。

項目
Origin Domain Name アクセス先のS3バケット
Origin ID Origin Domain NameにS3バケットを指定すると自動的に設定されます
Viewer Protocol Policy Redirect HTTP to HTTPS
Alternate Domain Names(CNAMEs) ドメイン名
SSL Certificate Custom SSL Certificate (example.com)を選択し、先ほどACMで作成した証明書を指定する
Default Root Object index.html(サイト仕様によって異なりますが、デフォルトだとこのファイルになるはず)

するとディストリビューションの作成が始まりますが、これには少し時間がかかるので気長に待ちます。

Route53にレコード追加

ディストビューションが作成されたら、ドメインへのアクセスをCloudFrontに流すためにRoute53の設定を行います。

  • サブドメインを使用しない場合は [名前] は未入力でOK
  • エイリアスは [はい] を選択
  • [エイリアス先] にCloudFrontディストリビューションの [Domain Name]を指定

Route53_A_2.png

画面確認

ここまで設定を行うと、設定したドメインでWordPress記事にアクセスすることができるようになっているはずです。
HelloWorld_2.png

S3のホスティング解除

CloudFrontにキャッシュしたものを参照するようになるので、もうS3でホステイングする意味はありません。
※エンドポイントでのアクセス経路を残しておきたい等のであれば別ですが...
なので、ここまできたらホスティングはOFFにしてしまいましょう。

参考文献

参考にさせていただきました。ありがとうございました。
https://qiita.com/yujiro0102/items/8a58fa92b861edd14547
https://dev.classmethod.jp/cloud/aws/tls-for-s3-web-hosting-with-cloudfront/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む