GUIのUbuntuを手っ取り早く用意する方法
開発の関係でササッとGUIが使えるLinux環境を用意する必要があり、忘備録がてらブログに起こしました。Macで実行しましたが、Windowsでも問題なく実行できると思います。
事前にMutipassをインストールしておいてください。
※1年以上ぶりの更新になってしまいました。。あっという間過ぎて草
とても簡単で、このフォーラムに書いてあることを実施すればOKです。
cloud-init.yml経由でubuntuを初期設定していること、ubuntuユーザー以外で実行したかったことから、cloud-config.yml
を用意して実施しました。
# package package_update: true package_upgrade: true packages: - ubuntu-desktop # enable GUI - xrdp # connect via RDP users: - name: ユーザー名 groups: admin sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash chpasswd: list: | ユーザー名:パスワード expire: False
以上のファイルを cloud-config.yml
として保存し、Multipassでの起動時にオプションとして渡してあげます。
- CPU4コア
- メモリ6GB
- ディスク128GB
- マシン名ubuntu-desktop
として作成します。
$ multipass launch --cpus 4 --disk 128GB --mem 6GB --name ubuntu-desktop --cloud-init cloud-config.yml
ubuntu-desktopのインストールにかなり時間が掛かりMultipassがタイムアウトのエラーを吐きますが、裏で順調にインストールが続いているのでそのまま待ちます。 作ったVMにログインし、psコマンドなどを使ってインストールプロセスの有無を確認しても良いかもしれません。
作成後、Multipassのlistコマンドを利用して、払い出されているIPを確認します。このIPはマシン内部でのみ有効です。
$ multipass list Name State IPv4 Image ubuntu-desktop Running 192.168.64.9 Ubuntu 20.04 LTS
Remote Desktopクライアントをホストにインストールし、接続してみます。Microsoft公式のクライアントが一番良いのでAppStoreからインストールします。
Add PC
を選択し、先程取得したIPアドレスを PC name:
に入力し、Add
ボタン押下でPCを追加します。
connect
を押下します。
continue
を押下します。
Docker Buildxを利用してマルチアーキテクチャなdockerコンテナを作成する
classmethod 若槻さんの記事 Dockerのマルチアーキテクチャイメージについて調べてみた を読んでマルチアーキテクチャなdockerコンテナを作ってみたくなったので、忘備録として記事を書きます。
ビルドの方法が分からなかったので、dockerの公式サイトを覗くと記載がありました。 Leverage multi-CPU architecture support
Docker Official Imagesの githubリポジトリ を覗くと、対応しているアーキテクチャは2020年4月12日時点で
- ARMv5 32bit (arm32v5) ※非公式
- ARMv6 32bit (arm32v6)
- ARMv7 32bit (arm32v7)
- ARMv8 64bit (arm32v8)
- Linux86-64 (amd64)
- Windows x86-64 (windows-amd64)
- IBM POWER8 (ppc64le) ※非公式
- IBM z Systems (s390x) ※非公式
- x86/i686 (i386) ※非公式
AWSが提供しているa1インスタンスのcpuinfoを見てみると
$ cat /proc/cpuinfo processor : 0 BogoMIPS : 166.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3
と表示されました。ARMのドキュメントを検索すると次のページがヒットしました
ARM Information Center
このページ書かれている内容から、
CPU implementer : 0x41 => ARM Limited. CPU part : 0xd08 => Cortex-A72 processor.
ということが分かりました。Cortex-A72はARMv8アーキテクチャを採用しているCPUなので、問題なくマルチアーキテクチャビルドのコンテナが動くはずです。検証環境が整うことがわかったので今回は、
を実施してみようと思います。
前準備
exprimental featureの有効化
マルチアーキテクチャのコンテナビルドのためには experimental feature(試験的な機能)を有効にする必要があります。Docker Desktopでは、
のように config.json
を記載するエリアがあるので、 Use the Docker command line | Docker Documentation に記載されているJSONを入力します。
もしくは、ホームディレクトリ直下の .docker
ディレクトリに config.json
があるので、同様の内容を記載すればおkです(Linuxでも同じです)。
buildKitのインストール
今回使用する buildx
というプラグインは Moby BuildKit の拡張であるため、BuildKitのインストールが必要になります。
Macであれば
$ brew install buildkit
でもいいですし、公式に則った形でバイナリを /usr/local/bin
配下に設置してもいいでしょう。 buildctl
コマンドが通ればインストール完了です。
$ buildctl NAME: buildctl - build utility USAGE: buildctl [global options] command [command options] [arguments...] VERSION: v0.7.0 COMMANDS: du disk usage prune clean up build cache build, b build debug debug utilities help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug enable debug output in logs --addr value buildkitd address (default: "unix:///run/buildkit/buildkitd.sock") --tlsservername value buildkitd server name for certificate validation --tlscacert value CA certificate for validation --tlscert value client certificate --tlskey value client key --tlsdir value directory containing CA certificate, client certificate, and client key --timeout value timeout backend connection after value seconds (default: 5) --help, -h show help --version, -v print the version
buildxプラグインの追加
次に buildx
というプラグインが必要になるので、 リポジトリ から最新のバイナリをダウンロードします。
ホームディレクトリにある .docker
ディレクトリに cli-plugins
というディレクトリを作成し、先程ダウンロードしたバイナリ docker-buildx
という名前で保存します。
更に実行権限を付与します。
$ chmod a+x ~/.docker/cli-plugins/docker-buildx
以上が終わって、docker buildx
コマンドが通れば利用可能です。
$ docker buildx Usage: docker buildx COMMAND Build with BuildKit Management Commands: imagetools Commands to work on images in registry Commands: bake Build from a file build Start a build create Create a new builder instance inspect Inspect current builder instance ls List builder instances rm Remove a builder instance stop Stop builder instance use Set the current builder instance version Show buildx version information Run 'docker buildx COMMAND --help' for more information on a command.
ビルド
今回は、rubyで実行したら実行マシンの現在時間を出力するコンテナを利用します。Dockerfileは以下の内容を利用します。
FROM ruby:2.6.3 CMD ruby -e "puts Time.now"
普通にビルド&実行をしてみると
$ docker build -t multi-arch-norm -f multi_arch_Dockerfile . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM ruby:2.6.3 ---> d529acb9f124 Step 2/2 : CMD ruby -e "puts Time.now" ---> Running in f6ca4f8d0f5b Removing intermediate container f6ca4f8d0f5b ---> 7a130a088630 Successfully built 7a130a088630 Successfully tagged multi-arch-norm:latest $ docker run -it --rm multi-arch-norm 2020-04-12 12:15:34 +0000
と問題なく実行出来ること分かりました。
ではマルチアーキテクチャモードでビルドを実行してみます。
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t doridoridoriand/multi-arch:latest . multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
どうやら現在の docker driver
ではマルチアーキテクチャのコンテナをビルドできないようです。指示に書いてあるとおり、 docker buildx create --use
を実行します。
$ docker buildx create --use $ ecstatic_roentgen
ランダムな名前でビルド用のコンテナが作成されました。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8ce5fa2759e8 moby/buildkit:buildx-stable-1 "buildkitd" 6 minutes ago Up 6 minutes buildx_buildkit_ecstatic_roentgen0
確かにbuildkitのコンテナが起動していることが分かります。
再度ビルドコマンドを実行します。
$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t doridoridoriand/multi-arch:latest . WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load [+] Building 133.1s (9/9) FINISHED => [internal] booting buildkit 7.3s => => pulling image moby/buildkit:buildx-stable-1 6.5s => => creating container buildx_buildkit_ecstatic_roentgen0 0.7s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 出力が長いので省略
無事ビルドができたようです。ただ、WARNには、
No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
と書かれていることから、コンテナのビルド結果はキャッシュにしか残ってないようです。利用するには --push
オプションでdocker hubにpushするか、--load
オプションでローカルに持ってくるかが必要になるようです。今回は後で別マシンでpullしたいので、docker hubにpushすることにしました。
pushオプションを付けて再度実行したところ、無事にpushされ、単一のイメージタグで、複数のCPUアーキテクチャが利用出来るようになっています。
以下が実際にpushしたdocker imageになります。 multi-arch | Tags
pull&実行
実際に動くか試します。まずはx86-64(amd64)PCで実施します。cpuinfoは
processor : 5 vendor_id : GenuineIntel cpu family : 6 model : 158 model name : Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz 長いので省略
となっています。コンテナをpullして実行してみます。
$ docker pull doridoridoriand/multi-arch:latest $ docker run -it --rm doridoridoriand/multi-arch:latest 2020-04-12 13:54:31 +0000
無事動きました。
次にARM(arm32v8)マシンで実施します。cpuinfoは
$ cat /proc/cpuinfo processor : 0 BogoMIPS : 166.66 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3
となっています。コンテナをpullして実行してみます。
$ sudo docker pull doridoridoriand/multi-arch:latest $ sudo docker run -it --rm doridoridoriand/multi-arch:latest 2020-04-12 14:06:47 +0000
無事実行できました。
まとめ
Dockerがマルチアーキテクチャをサポートしたことで、IntelやAMDのCPU以外でもDockerコンテナを動かす敷居が低くなりました。AWSで言えば、c系インスタンスとa系インスタンスのハイブリット構成でAPIサーバーを構築することも不可能ではなくなったので、実際に採用するかは別として、アーキテクティングの幅が広がったかと思います。
機会があれば、ミドルウェア等で試してみようと思います。
SREと私と時々障害
これは SRE Advent Calendar 2019 25日目の記事です。
世の中はクリスマスですね。特に意識していなくても浮足立ってしまうのは、まだ子供なせいなのでしょうか。
タイトルの付け方が何となく一昔前な気がするかもしれませんが、これしか思いつかなかったのと、結構気に入っているのでこのままでいきます。
注意: この記事はポエムが含まれております
現在とSREになるまでの変遷
現在私はとあるメディアサービスを提供している会社のSREチームでエンジニアとして働いています。所属しているチームは、
- インフラエンジニア(私): 1人
- バックエンドエンジニア: 3人
計4人で構成されています。
ここでSREチームに所属するまでの、私の変遷をご紹介したいと思います。
- 2016年6月~12月 バックエンドエンジニアとして新卒で現在の部署に配属。とあるメッセンジャーアプリのAPIの開発 + Webフロントエンドの開発に従事。
- 2017年3月より、インフラ局に所属。インフラエンジニアに転向し、先輩とともにインフラ業務に従事。12月に先輩が退職し、1人体制となる。
- 2018年1月から、バックエンドエンジニアとしてインフラ業務に従事。
- 2018年10月SREチーム発足。現在に至る。
元々バックエンドエンジニアでしたので、複数のLLを業務レベルで書くことは可能でした。私をインフラに誘ってくれた先輩は以下の理由によりインフラにも向いていそうだなと思ったようです。
インフラも面白そうだなと思っていたので、そこまで迷うこともなく(コーディングから離れることに対する一抹の不安はありましたが)転向をお願いしました。 それから10ヶ月程度、現在の稼働サービスのインフラの状況から、運用に必要な実務レベルでのインフラ知識などを教えていただきました。
ここで転機となったのはその先輩の退職です。
- サービス規模、ユーザー数拡大に負荷増大や、それに伴う既存の設計の問題の露呈
- 老朽化に伴う移行作業
- 最新技術等の導入
- 障害対応業務
バックエンドエンジニアと協力して作業するのはもちろんですが、インフラ視点からのアドバイスをできるのが1人になってしまいました。
またインフラサイドにおける細かな運用業務も基本的には1人になりました。
今までのやり方をそのままやるのでは潰れてしまうので、私はできる限り自動化・容易化することに注力しました。ここでバックエンドエンジニアの力が活きてきました。
改善業務の一部として以下を行いました。
- EC2インスタンスのメンテナンス確認の自動化
- オートスケーリンググループの起動台数状況を自動で定期的に確認
- コストの急増が無いかどうかのチェックスクリプトの作成
- アクセスログの調査補助のスクリプトの作成
半年くらいをかけて、大小様々ですが100個程度のスクリプトを作成しました。このスクリプト達のおかげで、1人でもなんとかなるところまで持ってこられました。
SREの発足
次に転機となったのはSREチームの発足です。Googleが2017年の1月にSRE本のテキストを無料公開し、業界的にも徐々にSREに関して注目が高まっている頃でした。
Site Reliability Engineering book is now available free online: https://t.co/el1vFcm5q4
— SRE Book (@srebook) January 27, 2017
2018年10月頃、開発責任者からSREチームの発足を告げられます。この時私はSREとしてうまく稼働できるかに関してはあまり自信がなく、現状のインフラ+αになる程度ではと思ってました。 これに関しては、SREと活動している現在も、私のミッションは主にインフラ+αなのですが、結果的に問題ないのではと思っています(※後述します)
バックエンドチームから切り離され、SREチームとなったメンバーは手探りで自分たちのミッションを決めていく必要がありました。そこでまずは本家に従おうということで、SRE本のチームでの輪読会を開きます。 ここから現在の開発組織における問題と対応策をみんなで話し合いました。
GoogleがO'Reillyから出版している「Site Reliability Engineering」は非常にボリュームがあり、また全部を輪読してもただの読書会になることが目に見えていたので、重要なところをかいつまみ、担当を割り振って実施しました。
一通りSREとしての先行事例を知ることができたので、次は自分たちの事業部に当てはめる作業になります。あくまでもGoogleの事例は、
「世界的に利用されているサービスを、複数の国と地域にまたがった開発組織を利用して、継続的かつ安定的なサービス運用する」
ために必要な仕組み等が多分に含まれています。
Googleのサービス群に比べれば小規模であり、ほとんどのサービス利用者が国内である、日本向けのサービスを展開している現在の事業部にそのまま当てはめるのは現実的ではありません。 また、SREチームは新規技術の開発というミッションも負っていたので、この時点で通常のSREチーム同様の働きはできなくなりました。
まずはじめにチームとして以下の内容に関して取り組むことになりました。
- SLI/SLOを定義
- 属人化している障害対応をもっと開発チーム全体で満遍なくできるようにする
- 負荷試験の継続的な実施のための整備
- ログ周りの整備可視化の充実化
- トイルの継続的な改善・解消
SLI/SLOを定義に関しては私のミッションの1つだったので、実施背景を説明します。
この時すでにSREという単語が世間的にもある種のバズワードになっており、それに付随する単語も、聞いたことはあるが、具体的にどのようなもの分かっていないという状況だったと思われます。
そこでまずはSREとは何か、何のために存在するのか、目的は何なのかをはっきりさせるため、事業部のエンジニア全員が集まる開発定例にて勉強会を実施し、単語の定義及びミッションの共有の必要があると考え、実施しました。
なお、開発状況及び私自身のミッションの変更などにより、現在は別の担当者に引き継がれております。
状況の変化
現在の事業部の開発はビジネスに寄り添った開発スタイルを採っています。よって開発項目もビジネスの方向性の変更などにより俊敏に変更する必要があります。これ自体はとても素晴らしいことだと思っているので問題は無いのですが、SREチームのメンバーがSRE業務ではなく新規機能開発の方に比重を置かなくてはいけない時間が多くなりました。
またSREチームあるあるなのかもしれませんが、使用ミドルウェアのアップデートなど、定常的なインフラ業務が減っておらず、またインフラエンジニアが私だったこともあり、SREチームというよりは、バックエンドチームの新規機能開発チーム+インフラというような状況になっていました。
私自身も別のサービスのインフラを担当するなど、現在所属している事業部にとどまらず、現在出向している子会社のインフラを全般的に見るようになってきて、別チームと仕事をすることも増えてきました。
現在とこれから
現在はSREチームはKubernetesを利用したマイクロサービス基盤の開発・運用チームとなっております。現在EC2上で動いているアプリケーションも徐々にこのマイクロサービス基盤に移行されていく予定とのことです。
アプリケーションの移行に関しても、インフラエンジニアがメインで関わることなく、 バックエンドエンジニアが主体となって進められる状況を生み出せたことはとても良かったと考えております。
私は現在以下のミッションを実施しております
- カオスエンジニアリングの導入・実施
- 視聴品質の定常的な計測・可視化
- 旧型インフラの改廃
- 他サービスのインフラ・バックエンドエンジニア
インフラ半分SREのようなもの半分といったところでしょうか。
〇〇エンジニアといったロールが元々好きでは無いので(専門性は別にロールが無くても増やすことは出来ると考えているので)、個人的には望ましい状況になってきております。
SREというチームが必要なのではなく、SREの思想を少しでもバックエンドエンジニアが持っていることのほうがとても重要なので、以上のミッションを通して、バックエンドエンジニアにSREの思想及びその根底にあるインフラの知見を布教できればと考えております。
障害の話一度もしませんでしたね。。笑
正直なところ、ここには書けないので面識ある方はランチや飲みなどに誘ってください。話せる範囲で話します笑
AnsibleでKubernetes開発に必要なツールをインストールする
小ネタです。 Kubernetes開発用の作業用サーバーを構築する時に書いたので、何となく書いてみます。 EC2ならユーザーデータとかでやればええやんとかいう正論は受け付けません
一応理由を説明すると、
- 起動時に毎回インストール作業が実行されるのがあまりよろしくない
- インストールされているか否かをチェックするスクリプトを書き始めたら、そもそもユーザーデーターの責務では無い気がした(ユーザーデーターに記述されている内容は、起動時に毎回実行されるべきなはず)
- 様々な資産があり、慣れているAnsibleで書いたほうが良いのでは?
という理由によるものです
インストール内容
作業サーバー(ツール群をインストールする対象のサーバー)のOSはAmazonLinux2を利用しています。今回は以下のツールをインストールしました
最近のツールはバイナリを放り込めば完成するパターンのものが多いので、インストールが楽になりました。 これらツールも例に漏れずバイナリ(もしくは単体のスクリプト)を放り込めばインストールが完了します
できたもの
早速結果を貼っちゃいます
kubectl
kubectx
kubens
eksctl
get_url
と unarchive
が素晴らしいので特筆すべきことは無いのですが、全てバージョン等を指定せず、Ansible実行時の最新を持ってくるように書いています。冪等性をあえて乱すような書き方をしていますが、Kubernetes界隈は開発が活発なので、常に新しいものを使うのが正義であると考え、この形にしています
Kubernetesの作業用サーバーを用意するといった考え方がもう古いような気もしますが、忘備録的にまとめてみました
クラウドベンダーのIPアドレス範囲の調べ方
小ネタです。クラウドベンダーがIPアドレスをどのくらい保有しているのか気になって調査したことがあったので、記事に起こしてみました。
今回調べたクラウドベンダー
今回はIPv4のみ調査しました。IPv6を含めると マンドクセ 膨大になりすぎて後述するスクリプトの計算が終わらないので。
AWS
AWSでは保有しているIPアドレスのCIDRブロックをAPIとして 公開 しています。 ページに記載されているCIDRブロックを計算すればIPアドレス保有数がわかります。 以下のようなコードを書いて個数を調べてみました
※計算時間短縮のため、並列演算をしています。実行するとCPUを使い切る挙動になるのでご注意ください。
試しに実行したところ、
$ ruby show_number_of_aws_ip_address.rb I, [2019-09-28T20:25:00.222308 #61863] INFO -- : Start to parse IP Address ranges of AWS. I, [2019-09-28T20:25:00.786106 #61863] INFO -- : Number of CIDR blocks: 1818 I, [2019-09-28T20:34:05.882460 #61863] INFO -- : Completed to calculate number of IP addresses. Number of IP address of AWS: 93482928
9300万個所有しているようです。多いですね。
GCP
GCPではspfレコードに所有しているIPアドレス一覧を 記載 しています。 シェルで試しに引っ張ってきてみました。
$ netBlockAddr=(`dig -t txt _spf.google.com +short | tr ':' '\n' | grep net | tr ' ' '\n' | grep net`); for i in ${netBlockAddr[@]}; do dig -t txt $i +short; done | tr ' ' '\n' | grep ip4 | tr ':' '\n' | grep -v ip4; 35.190.247.0/24 64.233.160.0/19 66.102.0.0/20 66.249.80.0/20 72.14.192.0/18 74.125.0.0/16 108.177.8.0/21 173.194.0.0/16 209.85.128.0/17 216.58.192.0/19 216.239.32.0/19 172.217.0.0/19 172.217.32.0/20 172.217.128.0/19 172.217.160.0/20 172.217.192.0/19 108.177.96.0/19 35.191.0.0/16 130.211.0.0/22
※shell力がうんこなので、どなたかもっと良い書き方あったら教えて下さい(切実)
$ ruby show_number_of_gcp_ip_address.rb I, [2019-09-28T21:15:23.028779 #91774] INFO -- : Start to parse IP Address ranges of GCP. I, [2019-09-28T21:15:23.678997 #91774] INFO -- : Number of CIDR blocks: 19 I, [2019-09-28T21:15:25.140817 #91774] INFO -- : Completed to calculate number of IP addresses. Number of IP address of GCP: 322816
めちゃくちゃ少ない。。!
本当に合っているのか不安になる少なさですね。GoogleAppEngineに関してはこのリストに入ってない可能性もあるので、もうちょっと調べてみます(多分)
Azure
Azureでは、以前はXMLによるファイル提供での公開だったのですが、その手法が 廃止予定 になり、その代わりとして Service Tag DiscoveryAPI がプレビュー公開されています。今回はService Tag DiscoveryAPIを利用した方法で計算してみます。
以下のスクリプトで調査可能です。
$ ruby show_number_of_azure_json_ip_address.rb I, [2019-09-28T21:27:09.594383 #96119] INFO -- : Start to parse IP Address ranges of Azure. I, [2019-09-28T21:27:10.568397 #96119] INFO -- : Number of CIDR blocks: 17009 I, [2019-09-28T21:29:32.258446 #96119] INFO -- : Completed to calculate number of IP addresses. Number of IP address of Azure: 30981085
特筆すべきはCIDRブロックの多さですね。比較的細かいアドレスレンジを大量に集めているようです。
クラウドベンダーのアドレスをブロックしたいニッチな要求(このご時世実施したらメリットよりデメリットのほうが大きいと思いますが)の時などに参考になればと思います。
IBM CloudやOracle Cloud Platformも、時間を見つけて追加していこうと思います。
AWSにKubernetesクラスタを立てる with eksctl
仕事でKubernetesクラスタを触る機会があったので、家でも触ってみたいと思い、実施したことを忘備録的にまとめます。 AWSのページを確認すると
の2パターンが確認できます。
eksctl
とはWeaveworksがメインで開発している、eksを簡単に構築・運用できるようにするためのコマンドラインツールになります。使用感としてはGCPの gcloud
コマンドに近いとのことです。
( gcloud
コマンド、ちゃんと使ったこと無いので伝聞なのが心苦しいですが。。)
コンソールから実施するタイプの方は、Kuberentes及びAWS CloudFormationなどにある程度慣れている方向けです(結構たいへんです)。
今回は構築・削除を簡単にしたいので、 eksctl
を利用する方式を取ります。
※以下構築方法はあくまでプライベートでの検証用途です。会社の環境で同じ設定をすると、おそらく(というか確実に)インフラ or SRE エンジニアからぶっ飛ばされるので気をつけましょう。
やること
(全然セットアップしてない体で説明を開始します。してあるよって方はスキップでおk)
とりあえずローカル以外でKubernetesを立てるというだけなら、eksctlコマンドを利用すれば驚くほど簡単になっています。
1. IAMユーザーの作成&アクセスポリシーの追加
1.
以下の用にIAMの画面からキーを発行します。
ここでは
ユーザー名: eks-power-access
アクセスの種類: プラグラムによるアクセス
としました。
2.
次にポリシーをアタッチします。本当はダメな設定ですが、スポットの検証用ということでAdministrator権限をつけています。
(これが万一流出するとほぼ確実に不正利用されるので気をつけましょう)
本来ならば、EKSの構築に必要な権限を調べて、それのみアタッチすべきですが、 ちょっと面倒くさかった 作業簡略化のためAdministratorをつけています
3.
最後入力内容を確認しましょう
4.
キーが発行できたらCSVをダウンロードしておきましょう。画面からでも確認できますが、ダウンロードできるものはしておいたほうが何かと確実です。
2. AWS CLIのセットアップ
(正直ここまでセットアップ済みだよ!!って方がほとんどだと思いますが)
aws cliのインストールにはpythonが必要になります。お使いのPCがMacでしたらすでに導入されているので問題ないです。
python3系じゃないとだめだろ!!!馬鹿野郎!!!という方はググって頑張ってください。
pyenvもしくはvirtualenvを入れているという方はおそらく説明不要だと思うので、ここの文章はスキップで問題ないです。
他OSの方も、python導入(Windowsに関しては、スタンドアローンのインストーラーがあるのでpythonを使わなくても使用可能です)に関してはググって頑張ってください。
以下コマンドで導入することができます
$ pip install awscli
Windowsのスタンドアローンインストーラーの方はこちらを参照ください。
3. eksctlのセットアップ
こちらもすぐに終わります。
$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp $ sudo mv /tmp/eksctl /usr/local/bin
$ brew tap weaveworks/tap $ brew install weaveworks/tap/eksctl
$ chocolatey install eksctl
ここに書きましたが、最新コマンドはこちらで確認をお願いします。
補完は好き好きで(あると便利です)
4. 立てちゃう
はい。立てちゃいます。
なんにも考えないで実行すると、以下コマンドになります
$ eksctl create cluster
ですが、このコマンドだと m5.large
インスタンス2台を us-west-2
(オハイオ) リージョンにて、専用VPCを作成して構築することになります。あとクラスタ名がランダムで決まります。
検証用途にこのサイズのインスタンスは大きすぎるので、ある程度指定してあげましょう。
引数で指定してあげることもできますが、設定値はyamlで管理できるので、是非yamlにしましょう。
以下を指定しました。
以下のようなyamlになるかと思われます。
githubにもいくつかサンプルがあるので、是非参考にしてみてください。
作成するには、以下コマンドを実施します。
$ eksctl create cluster --config-file simple-kubernetes-with-eksctl.yml
10分程度で完成しました
$ eksctl create cluster --config-file simple-kubernetes-with-eksctl.yml [ℹ] using region ap-northeast-1 [ℹ] setting availability zones to [ap-northeast-1d ap-northeast-1a ap-northeast-1c] [ℹ] subnets for ap-northeast-1d - public:192.168.0.0/19 private:192.168.96.0/19 [ℹ] subnets for ap-northeast-1a - public:192.168.32.0/19 private:192.168.128.0/19 [ℹ] subnets for ap-northeast-1c - public:192.168.64.0/19 private:192.168.160.0/19 [ℹ] nodegroup "worker00" will use "ami-0dfbca8d183884f02" [AmazonLinux2/1.12] [ℹ] creating EKS cluster "kube00-tokyo" in "ap-northeast-1" region [ℹ] 1 nodegroup (worker00) was included [ℹ] will create a CloudFormation stack for cluster itself and 1 nodegroup stack(s) [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --name=kube00-tokyo' [ℹ] 2 sequential tasks: { create cluster control plane "kube00-tokyo", create nodegroup "worker00" } [ℹ] building cluster stack "eksctl-kube00-tokyo-cluster" [ℹ] deploying stack "eksctl-kube00-tokyo-cluster" [ℹ] building nodegroup stack "eksctl-kube00-tokyo-nodegroup-worker00" [ℹ] --nodes-min=2 was set automatically for nodegroup worker00 [ℹ] --nodes-max=2 was set automatically for nodegroup worker00 [ℹ] deploying stack "eksctl-kube00-tokyo-nodegroup-worker00" [✔] all EKS cluster resource for "kube00-tokyo" had been created [✔] saved kubeconfig as "/Users/dorian/.kube/config" [ℹ] adding role "arn:aws:iam::xxxxxxxxxxxx:role/eksctl-kube00-tokyo-nodegroup-wor-NodeInstanceRole-13QV27O8G46HU" to auth ConfigMap [ℹ] nodegroup "worker00" has 0 node(s) [ℹ] waiting for at least 2 node(s) to become ready in "worker00" [ℹ] nodegroup "worker00" has 2 node(s) [ℹ] node "ip-192-168-19-13.ap-northeast-1.compute.internal" is ready [ℹ] node "ip-192-168-36-85.ap-northeast-1.compute.internal" is ready [ℹ] kubectl command should work with "/Users/dorian/.kube/config", try 'kubectl get nodes' [✔] EKS cluster "kube00-tokyo" in "ap-northeast-1" region is ready
では実際にkubectlコマンドが通るか試してみましょう。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-19-13.ap-northeast-1.compute.internal Ready <none> 8m v1.12.7 ip-192-168-36-85.ap-northeast-1.compute.internal Ready <none> 8m v1.12.7
$ kubectl describe nodes Name: ip-192-168-19-13.ap-northeast-1.compute.internal Roles: <none> Labels: alpha.eksctl.io/cluster-name=kube00-tokyo alpha.eksctl.io/instance-id=i-0d24521d0fc8630ef alpha.eksctl.io/nodegroup-name=worker00 beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=t3.micro beta.kubernetes.io/os=linux failure-domain.beta.kubernetes.io/region=ap-northeast-1 failure-domain.beta.kubernetes.io/zone=ap-northeast-1d kubernetes.io/hostname=ip-192-168-19-13.ap-northeast-1.compute.internal Annotations: node.alpha.kubernetes.io/ttl=0 volumes.kubernetes.io/controller-managed-attach-detach=true CreationTimestamp: Wed, 03 Jul 2019 20:20:37 +0900 Taints: <none> Unschedulable: false Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- OutOfDisk False Wed, 03 Jul 2019 20:25:58 +0900 Wed, 03 Jul 2019 20:20:37 +0900 KubeletHasSufficientDisk kubelet has sufficient disk space available MemoryPressure False Wed, 03 Jul 2019 20:25:58 +0900 Wed, 03 Jul 2019 20:20:37 +0900 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Wed, 03 Jul 2019 20:25:58 +0900 Wed, 03 Jul 2019 20:20:37 +0900 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Wed, 03 Jul 2019 20:25:58 +0900 Wed, 03 Jul 2019 20:20:37 +0900 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Wed, 03 Jul 2019 20:25:58 +0900 Wed, 03 Jul 2019 20:20:47 +0900 KubeletReady kubelet is posting ready status Addresses: InternalIP: 192.168.19.13 ExternalIP: xxx.xxx.xxx.xxx InternalDNS: ip-192-168-19-13.ap-northeast-1.compute.internal ExternalDNS: ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com Hostname: ip-192-168-19-13.ap-northeast-1.compute.internal ~~~~
問題なさそうですね。 では、一通り必要な検証が終わったとして、お金節約のため、クラスタを削除しましょう。以下コマンドで実施できます。
eksctl delete cluster --name kube00-tokyo
$ eksctl delete cluster --name kube00-tokyo [ℹ] using region ap-northeast-1 [ℹ] deleting EKS cluster "kube00-tokyo" [✔] kubeconfig has been updated [ℹ] 2 sequential tasks: { delete nodegroup "worker00", delete cluster control plane "kube00-tokyo" [async] } [ℹ] will delete stack "eksctl-kube00-tokyo-nodegroup-worker00" [ℹ] waiting for stack "eksctl-kube00-tokyo-nodegroup-worker00" to get deleted [ℹ] will delete stack "eksctl-kube00-tokyo-cluster" [✔] all cluster resources were deleted
削除されました。
Kubernetes自体はローカルでも検証することはできますが、クラウドベンダーの機能(AWSで言えばALBIngress, IAMとRBACの連携など)を試すときはサーバー上に構築する必要があります。
eksctlのおかげで、AWSでも簡単に構築できるようになったので、是非試してみてください。
バックエンドの種類を雑に把握する in AWS
ちょっと調査で使用したので、備忘録がてら記事に起こします。
静的サイトホスティングや、アセット系の保存場所S3を使うことはよくあることだと思います。 ですが、S3の静的サイトホスティングを有効にした状態で直接CNAMEやRoute53のエイリアスレコードを貼ってしまうとキャッシュされず、アクセスされるたびに毎回S3にGETが走ってしまうことになります。
個人のサイトなど低頻度アクセスなサイトであればそれほど問題にはなりませんが、商用サービスなどでは以下の問題が生じることがあります。
- 転送容量によっては、CDNを経由しないと高額になる(とはいえ月間150TB以上転送したときに目の当たりにする問題だったりしますが)
- GETリクエストに対する課金がCloudFront経由だった場合より高くなる
- S3のAPIのRateLimitに引っかかる恐れがある(スパイクアクセスが発生したときに問題が表面化すると思われます)
またそもそも論としてS3は多機能ではありますが、メインの機能はストレージサービスですので、コンテンツ配信は別サービスに任せるのがアーキテクチャー的にも吉です。
ですが、以下理由により現在設定されているレコードのバックエンドが、S3直なのかCloudFront経由なのかを調べられない状況が存在します。
以上に対する対応方法として、簡易的にですが、以下の方法を使用することでバックエンドがS3直 or CloudFront経由かを判断できます。
- curlでヘッダを見て判断する
- digで返ってきたIPをnslookupする
curlでヘッダを見て判断する
CloudFront => S3となっているサイトに対してcurlを実行すると以下のような結果が返ってきます。
$ curl -I https://example.com/ HTTP/2 200 content-type: text/html content-length: 1462 date: Sun, 09 Jun 2019 07:44:59 GMT last-modified: Fri, 13 Oct 2017 03:20:02 GMT etag: "ccde8929cea4684f8c27cac3f2060c5f" accept-ranges: bytes server: AmazonS3 x-cache: Hit from cloudfront via: 1.1 d90dc9dxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront) x-amz-cf-pop: NRT53 x-amz-cf-id: W0WBTwtWRofoio0ZqLSabHmPkbR3GtlPXXXXXXXXXXXXXXXXXX==
このときserverには AmazonS3
と入っており、一見バックエンドがS3直と勘違いしそうですが、
x-cache: Hit from cloudfront x-amz-cf-pop: NRT53 x-amz-cf-id: W0WBTwtWRofoio0ZqLSabHmPkbR3GtlPlf_0UudiW7caw62BQ048WQ==
とあるように、CloudFront特有のヘッダがついていることがわかります。 それぞれ
x-cache
: キャッシュのヒット可否及びTTL切れなどの情報x-amz-cf-pop
: どのPOPからレスポンスを受けているかx-amz-cf-id
: リクエストごとに付与されているユニークなID
となっています。 S3直のドメインにて同様にcurlを打つと、
curl -I https://example.com/ HTTP/1.1 200 OK x-amz-id-2: INa97Ph1bsyjvUzPVj8jMxJPiON6ZIWnfXcUs30iyaSqJ46vs+xxxxxxxxxxxxxxxxJ+Evb4= x-amz-request-id: E0000000000000F Date: Sun, 09 Jun 2019 08:01:12 GMT Last-Modified: Tue, 24 Jan 2017 11:03:17 GMT ETag: "0553432f5fbc381066c8aee67a7afadb" Accept-Ranges: bytes Content-Type: text/html Content-Length: 2728 Server: AmazonS3
というヘッダになっておりCloudFrontを挟んだときのような、キャッシュ情報などはありません。
digで返ってきたIPをnslookupする
IPアドレスにはられているDNSレコードを逆引きしてあげることにより、バックエンドがS3かCloudFrontかを知ることができます。
S3がバックエンドの場合、
$ dig example.com +short | xargs nslookup Server: 127.0.1.1 Address: 127.0.1.1#53 Non-authoritative answer: 000.000.000.000.in-addr.arpa name = s3-website-ap-northeast-1.amazonaws.com. Authoritative answers can be found from:
とCNAMEに s3-website-ap-northeast-1.amazonaws.com.
と入ってきます。
CloudFrontが間に挟んである場合、
$ dig exapmle.com +short | head -1 | xargs nslookup Server: 127.0.1.1 Address: 127.0.1.1#53 Non-authoritative answer: 000.000.000.000.in-addr.arpa name = server-000-000-000-000.nrt20.r.cloudfront.net. Authoritative answers can be found from:
とCNAMEに server-000-000-000-000.nrt20.r.cloudfront.net.
と入ってきます。
以上からバックエンドの種類を判断することが可能です。 実際の障害対応とかでは適切な権限を持ったエンジニアが対応するかと思われるので、上の手法を使うことは無いと思いますが、このような手法でもできないことは無いということをお伝えしたく記事にしました。
(ブログ書く頻度が低すぎて文体が毎回変わってますが、そのうち統一します。。)