AWSアカウント内の全リージョンのLambda関数リストを出力する

少し前になりますが、AWS Lambdaのランタイムのうち、Node.js 6.10のサポート終了がアナウンスされました。

4月30日にNode.js 6.10のサポートが終了になります - Forums

こういったアナウンスが出たときなどに、自分が関わっているLambda関数の全リストを確認したくなるのですが、複数のAWSアカウントを運用していると、全AWSアカウントの全リージョンをManagement Consoleでポチポチ確認するのは現実的ではありません。
せめて1つのAWSアカウントの全リージョンのLambda関数のリストくらいはパパっと取得したいものです。

というわけで、簡単なシェルスクリプトを書いてみました。

実行するには以下の条件を満たしている必要があります。

  • Bash が実行できる
  • AWS CLI がインストール済み
  • ec2:DescribeRegions や lambda:ListFunctions が実行可能な権限を持ったIAMユーザ or IAMロールのクレデンシャルが設定済み

手元のPCや開発機で実行する前提で書いたので、第1引数にProfile名を渡せばAWS CLIを実行するときのprofileを変更できるようにしました。引数なしで実行すると、[default] profileを使用します。

AWSの全リージョンのリストを取得する

ちょくちょく新リージョンが開設されたりするので、スクリプト内にべた書きでリストアップするのもいかがなものか、と思ってWebを検索していると、こんな記事を見つけました。

dev.classmethod.jp

なるほど!EC2 APIの DescribeRegions ActionでEC2がサポートされているリージョンの一覧を取得する、という方法です。
確かにAWSの公式情報を見てもEC2をサポートしていないリージョンは無いですし、AWSの全リージョンのリストを取得するのはこれでバッチリです。

aws.amazon.com

ちなみに、本日 2019/04/18 時点だと大阪リージョンだけAWS Lambdaをサポートしていないようです。へぇー。

Lambda関数のリストを取得する

こちらはLambdaのAPIにずばり ListFunctions というActionがあり、これを利用します。

list-functions — AWS CLI 1.16.142 Command Reference

AWS CLI の--query オプションで出力内容を FunctionName、Runtime、LastModifiedそしてDescription に絞り、Linuxcolumn コマンドで見た目の整形をしています。columnコマンドで整形せずAWS CLI のTEXT出力形式のまま出力すればタブ区切りになるので、出力結果をExcelなどに展開する場合にはそのほうが都合がよいかもしれません。sort もこのスクリプトの例ではFunctionaNameでソートをかけていますが、LastModified などでソートしてもよいでしょう。
これを、先の手順で取得したAWSの全リージョンに対して for 文内で順次実行しているだけです。

実行結果イメージ

このような感じで、リージョン毎に FunctionName、Runtime、Last Modified、Description をリスト表示します。

$ bash lambda-function-list.bash
[eu-north-1]
---------------------
[ap-south-1]
---------------------
[eu-west-3]
---------------------
[eu-west-2]
FunctionName-A    nodejs8.10  2018-07-24T09:41:13.364+0000
FunctionName-B    nodejs6.10  2018-07-31T10:46:06.598+0000  Description-B
FunctionName-C    nodejs6.10  2018-10-24T03:02:12.718+0000  Description-C
---------------------
[eu-west-1]
FunctionName-D-in_eu-west-1    nodejs6.10  2019-02-07T11:25:14.242+0000 Description D
FunctionName-E-in_eu-west-1    nodejs6.10  2019-02-07T11:21:40.267+0000  
FunctionName-F-in_eu-west-1    nodejs6.10  2019-02-07T11:20:07.790+0000 Description F
---------------------
[ap-northeast-2]
---------------------
[ap-northeast-1]
(以下略)

まとめ

実際に自分が関係しているいくつかのAWSアカウントで実行したところ、結構わさわさNode.js 6.10のLambda関数があることがわかりました😇

「Knativeの歩き方 KubernetesからServerlessを訪ねて」を写経しつつ読んだ

先週、San Franciscoで開催されたGoogle Cloud Nextに参加した。 f:id:kmiya_bbm:20190416233348j:plain

参加できることが決まった3月上旬から、せっかく行くなら予習しとこう!と前から気になっていたKubernetesを調べたり触ってみたりして勉強していた(過去の記事を参照)のだけれど、その中でKubernetes 上にサーバーレス環境を構築するKnative なるOSSがあると知り、興味本位で情報を集めていた。

イムリーにServerless Meetup Tokyo #11 でKnative についての発表があったようで、こちらの資料は概要を掴むのにとても良かった。
入門 Knative 〜KubernetesとServerlessとの出会い〜 / getting started with knative - Speaker Deck

Kubernetes や Knative を調べてからGoogle Cloud Nextに参加したのは結果的には大正解で、今回のNextで発表された Anthos (実際には昨年発表された Cloud Services Platformのリブランドのようだが) はKubernetes を前提としているし、Cloud Run も KubernetesやKnativeをベースとしたサービスだったため、予習しないで行っていたら完全に置いてけぼりだったと思われる。 Cloud Run がとてもおもしろそうだったので、日本に帰ったらKnative と共にもう少し詳しく調べてみよう、と思っていたところにこちらの記事を発見した。

toshi0607.com

出発前の予習でお世話になった資料を作られた方が技術書典 #6 で Knative の本を出されると聞き、早速BOOTHで購入、写経してみた次第。 地方在住の子育て世帯ということもあり都内で週末に行われるイベントにはほとんど参加できないが、こうして手軽に電子版を購入できるのはありがたい。

toshi0607.booth.pm

感想

目次や主な内容については上にリンクを貼った著者様のブログ記事にて言及されているので割愛するが、Knative v0.5 で大きく仕様が変わった Eventing まわりの内容に追従できているのがまずすごい。Eventingについては Nextでもセッションで詳しく取り上げられていたのでこのあたりの動画と合わせて復習すると良さそう。

www.youtube.com

この本はとにかくハンズオンのための説明が丁寧で、写経していて詰まるところはほぼなかった。ほんの一部の手順で思う通りに実行できなかった箇所があった(最後の Kubernetes イベントを拾って表示するところ)ので、勉強のため引き続き調査して解決したい。
また、一部コマンド実行例に誤植があったので記録しておく。p.25 と p.37 の環境変数 KNATIVE_INGRESS を設定する箇所。

$ export KNATIVE_INGRESS=$(kubectl get svc istio-ingressgateway --namespace istio-system --output 'jsonpath={.status.loadBalancer.ingress[0].ip')}

↓

$ export KNATIVE_INGRESS=$(kubectl get svc istio-ingressgateway --namespace istio-system --output 'jsonpath={.status.loadBalancer.ingress[0].ip}')

2019/04/18 追記

著者様が光の速さで正誤表ページを用意しつつ、修正版v1.0.1もリリースしてくださいました!対応速っ!!ありがとうございます!


なんというか、著者様の愛をとても感じる本で、全体を通して構成や文章も商業書籍のようによく練られていて、するする読めてしまった。
するする読めるし写経も詰まることがなかったおかげで、ちゃんと理解できていなかったり知識が定着していない箇所が多そうなので、折に触れて読み返そうと思う。

Knative についてはそれ自体も興味深いが、Cloud RunをはじめTriggerMeshが公開したKubernetes 上にAWS Lambda互換環境を構築するOSS 「Knative Lambda Runtime (KLR)」 など、Knative をベースにして展開されるサービスがとてもおもしろくなりそうなので、この周辺の技術はウォッチしていきたい。

参考資料

Google Cloud Next 19でも Knative関係のセッションがいくつかあったのでリンクを貼っておく。
質疑応答コーナーが面白いセッションもあったが、動画ではカットされていてちょっと残念。

www.youtube.com

www.youtube.com

[コンテナ再入門]Ubuntu 18.04 で写経しつつ「Docker/Kubernetes 実践コンテナ開発入門」を完走した

なんやかんやハマりながらも、なんとかUbuntu18.04で写経しつつ「Docker/Kubernetes 実践コンテナ開発入門」を最後まで読み進めました。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

本についての感想

Docker ~ Docker Compose の内容までは過去にも調べて使ってみたことがあったのですぐに理解できたし、Docker Swarmも初めて触ったけれど書籍の解説がわかりやすく概要をつかむことができた。しかし、5章以降 Kubernetes の内容に入ってからは初めての概念がたくさん出てきて読み進めるのに時間がかかってしまった。それでも、Kubernetes がDocker Swarmよりもさらに運用に有用な機能が多く実装されていることや、Helmなどの便利な周辺ツールがたくさんあること、Google Kubernetes Engine (GKE) がKubernetesを使うにあたってどのくらい便利なのか、などについて、順を追ってわかりやすく書かれていてとても勉強になった。ログの取り回しやCI/CDをどうするのが良いか、など運用上の疑問点についても現時点でのベストプラクティスがまとめられており、導入を進める立場の視点で助かる内容が多かった。 なかなかウェブ上の断片的な記事だけではここまで順を追ってコンテナ~コンテナオーケストレーションの流れや主要なツールの使い方を学ぶことは難しいので、個人的に非常にいいタイミングで良い本に出会えたと思う。

また、書籍内ではコラム内で軽く紹介されていただけだったが、Knative がとても面白そうなので別途調べていこうと思う。

Kubernetes についての所感

オートスケーリングやデプロイの仕組みが非常に洗練されていて、なるほど流行るのも納得、という感じだったが、よく言われるように学習コストは非常に高そうだなという感触を持った。今いるチームはアプリケーションのコードを書く開発者は多くいるが、サーバやネットワークを構築・運用したりシステム監視設計や運用設計をしたりする、いわゆるインフラ寄りのメンバーはほとんどいないし、運用しているアプリケーション自体もまだまだ規模が小さいので、kubernetes を導入したりそもそも開発環境からコンテナ化するメリットに対して導入コストがまだ大きすぎるかなという気がする*1。 なので、チームで導入するタイミングはまだしばらく待ちつつ、個人的には興味深い分野なのでコンテナやオーケストレーションツールの動向を追っていきたいな、という感じ。

*1:うちでは割とサーバーレス構成を採用しているが、これは運用のコスト削減のためなら開発のコスト増は飲めるようなメンバー構成なため

[コンテナ再入門]Ubuntu 18.04 に Kubernetes環境を構築する

Ubuntu18.04で写経しつつ「Docker/Kubernetes 実践コンテナ開発入門」を読み進めている。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

書籍ではDocker for Windows/Mac をサポート対象としており、それ以外のLinuxなどの環境で写経するには自分で環境構築を行う必要がある。
5章からはKubernetesの話題に入っていくのだが、Ubuntu18.04 上にKubernetes環境を構築するのに結構時間がかかったのでメモを残す。

環境

  • ホスト Ubuntu16.04 Desktop 64bit
  • VM: Ubuntu18.04 server 64bit (Vagrant + VirtualBox)
    • Docker 18.09.3

kubeadm のインストール

ウェブでLinux環境へのKubernetes環境構築について検索するといろんな方法がヒットするが、結論としては公式ドキュメントで書かれている通り kubeadm を使って構築した。

kubernetes.io

「Before you begin」の項目のうち、自分のようにローカルPC上の仮想マシンで構築を進める場合、ハマりそうなのは以下の3点かと思う。

  • 2 GB or more of RAM per machine (any less will leave little room for your apps)
  • 2 CPUs or more
  • Swap disabled. You MUST disable swap in order for the kubelet to work properly.

SWAPをOffにするのは、以下のコマンドを実行する。このコマンドではOS再起動時に設定がもとに戻ってしまうが、とりあえず環境構築するには充分である。

sudo swapoff -a

docker はすでにインストール済みとする(関連記事 )。
あとは、ドキュメントに書かれているとおり以下のコマンドを実行して kubelet、kubeadm、 kubectl をインストールできる。

sudo apt-get update
sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
sudo cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

kubeadm で single master cluster を構築する

続いて公式ドキュメントのこのページの作業を進める。

kubernetes.io

Pod間通信用のアドオンが何種類かあって選べるのだが、ウェブで検索していてよく見かけた Flannel を使うことにした(よくわかってない)。
Flannelを使う場合のインストール手順に書かれているとおり、--pod-network-cidr=10.244.0.0/16 とオプションをつけてkubeadm init を実行する。

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

成功すると、その後実行するべきコマンドが表示されるのでその通り実行する(公式ドキュメント内にも記述がある)。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Flannel をインストールする。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

とりあえずここまで作業すれば、書籍の続きの内容であるダッシュボードのインストールに進める。

[コンテナ再入門]ホストにMySQLがインストールされていると、MySQLのコンテナが起動しないことがある

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門 の4章でMySQLのDockerコンテナを立ち上げる手順があるのだが、そこで詰まったのでメモ。

状況

  • ホスト Ubuntu18.04 server 64bit
  • Docker 18.09.3

Docker in Dockerの構成で、mysql:5.7 イメージを元にしたMySQLのDockerコンテナを起動させようとしたところ、起動しては以下のエラーを吐いてコンテナが停止する、という挙動を繰り返した。

$ docker container exec -it manager docker service lslogs todo_mysql_master
todo_mysql_master.1.(略)    | ERROR: mysqld failed while attempting to check config
todo_mysql_master.1.(略)    | command was: "mysqld --verbose --help"
todo_mysql_master.1.(略)    | 
todo_mysql_master.1.(略)    | mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
todo_mysql_master.1.(略)    | mysqld: [ERROR] Fatal error in defaults handling. Program aborted!

「Docker in Docker」「MySQL」「起動しない」といったワードで検索していたところ、こちらの記事を発見。

qiita.com

まんまこのシチュエーションであった。

先に結論

コンテナを実行するホスト(母艦) にMySQLがインストールされていると、priviledged モードを有効にしたコンテナ上でのMySQL起動がAppArmorという強制アクセス制御システムの働きにより阻害されることがある。

何が起きていたか

書籍の手順では、Docker Swarmのような複数台のホストにまたがるコンテナオーケストレーションの挙動を1台のホスト(=読者のノートPCなど)上で再現して体験させるため、Docker in Dockerで「Dockerをホストするためのコンテナ群」の上に「MySQLやNginxなど本来複数台のホストにまたがって展開させたいコンテナ群」を構築することになっていた(3章 3.5.節以降)。
このDocker in Dockerで「Dockerをホストするためのコンテナ群」を構築する際、「Dockerをホストするためのコンテナ群」に本来のホスト(=読者のノートPCなど)とほぼ同じ権限をもたせるためにpriviledged モードを有効にしていたようだ (ようだ、というか、「Dockerをホストするためのコンテナ群」を起動するためのdocker-composeのYAMLファイルにはちゃんとprivileged: trueと書いてあったのだが、あまり意味がわかっておらず読み飛ばしていた。。。)。

docs.docker.com

こちらのドキュメントの「Runtime privilege and Linux capabilities」の項を読むと、priviledged モードというのはコンテナホストのデバイス等にアクセスを許可するためのフラグらしい。これがないと Docker in DockerのようにDockerコンテナ内部からDockerを起動させるような芸当ができない。
基本的にはホストとコンテナ間は疎結合である方が望ましいので、priviledged モードは開発環境以外では使わないものらしい。

AppArmorとは

www.usupi.org

AppArmor とは、プログラム単位でMAC(Mandatory Access Control - 強制アクセス制御) を行うためのセキュリティ機構です。
MACとは、従来のファイルのパーミッションの設定等とは関係なく、 強制的にアクセス制限を設けることができる機構です。

役割としてはSELinuxなどと同じようなもので、AppArmorの場合はプログラム単位で制限がかけられるらしい。 今回は、MySQLがAppArmorの管理対象だったところに Docker in Docker上でさらにMySQLを実行しようとしたため、AppArmorが「許可していないリソース上で MySQL が動作している」と認識して実行をブロックした、ということだったようだ。

対処

前述のQiita記事 Docker で MySQL コンテナーがなぜか起動できない問題 - Qiita に記載されていた2つの解消方法のうち、AppArmor の監視から MySQL を除外する方法を採った。

$ sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

教訓

書籍やハンズオンで環境構築を行う場合は、なるべくまっさらなVMなどを用意してやりましょう。

…そうはいっても毎回そう上手く環境を用意できないかもしれないので、後で同じような状況で詰まる人(将来の自分を含む)の役にたてばと簡単にメモをまとめました。

参考にさせていただいたURL

[コンテナ再入門]Ubuntu 18.04 に Docker Compose をインストールする

kmiya-bbm.hatenablog.com

これの続き。

Docker Composeのインストールも公式ドキュメントに沿って進めればよい。

docs.docker.com

  • Githubのレポジトリで最新のバージョンを確認する。

  • 以下のコマンドで最新版のdocker-composeをダウンロードする

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  • ダウンロードしたdocker-compose に実行権を付与する
$ sudo chmod +x /usr/local/bin/docker-compose
  • 自分の環境では /usr/local/bin にPATHが通ってなかったので、公式ドキュメントの通りシンボリックリンクを張った
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
  • インストールできたか確認する
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

よさそう!

[コンテナ再入門]Ubuntu 18.04 に Docker CE をインストールする

今さらもいいところだが、コンテナを活用した開発フローやアーキテクチャについて基礎から再入門している。 Dockerについては、過去にもちょこちょこ触ってみたり社内のサーバで使ってみたりはしていたものの、ちゃんと実運用できるレベルで理解できていなかったので、勧められた以下の書籍で改めて勉強しなおしている。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

せっかくなので勉強のログをメモしておこうと思う。

Ubuntu 18.04 に Docker CE をインストールする

基本的に公式ドキュメントの「Install using the repository」の手順をなぞるだけ。 docs.docker.com

前準備

  • 古いバージョンのDockerをアンインストールする
$ sudo apt-get remove docker docker-engine docker.io containerd runc

レポジトリを設定する

  • まずは apt パッケージのインデックスを更新する
$ sudo apt update
  • 依存するパッケージをインストールする
$ sudo apt install  apt-transport-https   ca-certificates   curl  gnupg-agent   software-properties-common
  • GPG key の登録
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • stable(安定版) のレポジトリをセットアップする。( nightly や test といった引数を最後のstable の後に追加すればそれらのチャンネルもセットアップされる模様)
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

Docker CEをインストールする

  • レポジトリを追加したので、もう一度 apt パッケージのインデックスを更新する
$ sudo apt update
  • 最新版の Docker CEをインストールする
$ sudo apt install docker-ce docker-ce-cli containerd.io

Dockerを一般ユーザで実行できるようにする

Docker のコマンドを一般ユーザで実行すると権限が足らずエラーが発生する。

$ docker info
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/info: dial unix /var/run/docker.sock: connect: permission denied

これを回避するには、毎回sudoをつけてroot権限で実行するほか、Dockerを実行したい一般ユーザを docker グループに所属させれば良い (と、公式ドキュメントに普通に書いてあった)。

If you would like to use Docker as a non-root user, you should now consider adding your user to the “docker” group with something like:
sudo usermod -aG docker your-user

結果確認

バージョン 18.09.3 がインストールされた。

$ docker version
Client:
 Version:           18.09.3
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        774a1f4
 Built:             Thu Feb 28 06:53:11 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.3
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       774a1f4
  Built:            Thu Feb 28 05:59:55 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Proxyの設定

docs.docker.com

公式ドキュメントを参考に、dockerd (Daemon) にProxyを設定する場合の例。
上記手順でUbuntuにDockerをインストールした場合、systemd でDaemon化されているため、service設定を更新する。

$ sudo mkdir /lib/systemd/system/docker.service.d
$ sudo vi /lib/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTPS_PROXY=http://your.proxy.url:port/"

Proxy設定ファイルを作ったらdockerd を再起動して読み込ませる。

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker.service