まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

2020年振り返り

1月〜2月

  • opsworksで動いてたサービスをECS Fargateに移行
  • 新規サービスをECS Fargateで構築

3、4月

  • kinesisまわりのコスト効率化でScala書く

5、6月

  • AWS WAF

7、8月

  • EMR on Spark
  • external secrets導入

9月

  • EKS移行に向けてシニアYAMLエンジニア
  • Argo CDぶっこわれたのなおす
  • ECSからEKS本番移行

10月、11月

  • EKS移行後の問題潰し
  • テックブログ書いたり登壇資料まとめたり
  • App Mesh backendsの負荷分散検証
  • Nginx -> CloudFlont移行検証でScala書く

12月

  • EKS移行後改めてDatadogを整理

EKSのArgo CDでIRSAを使いつつaws-load-balancer-controllerをApplicationとしてHelm Chartをsourceでインストールする

aws-load-balancer-controllerが起動しない

以下のエラーが出て起動しない。 alb-load-balancer-controllerのときと違うのは、CRDが必要になったのでそれを入れないといけないってのがポイント!

{
  "level":"error",
  "ts":1606359399.366636,
  "logger":"setup",
  "msg":"unable to create controller",
  "controller":"TargetGroupBinding",
  "error":"no matches for kind \"TargetGroupBinding\" in version \"elbv2.k8s.aws/v1beta1\""
}

kustomization.yaml

Kustomizeならremote targetsで入れられるのでそれでやる。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  # remote targetsを使ってCRDをinstallするのがポイント
  - github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=v0.0.36
  - aws-load-balancer-controller.yaml

aws-load-balancer-controller.yaml

IRSAのために、valuesでannotationsを渡すのがポイント! parametersを使って渡すと、HelmのtemplateでtoYAMLが効かなくて反映されなかった

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: aws-load-balancer-controller
  namespace: argocd
spec:
  source:
    repoURL: https://aws.github.io/eks-charts
    targetRevision: 1.0.8
    chart: aws-load-balancer-controller
    helm:
      releaseName: aws-load-balancer-controller
      parameters:
      - name: "clusterName"
        value: "eks-your-cluster"
      - name: "serviceAccount.name"
        value: "aws-load-balancer-controller"
      values: |
        serviceAccount:
          annotations:
            eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/aws-load-balancer-controller

Terraform

巷にはeksctlを使ってiam作成するサンプルが多くてちょっとハマった。number_of_role_policy_arnsがないとダメなのは厳しいけど、多分、moduleの書き方の都合だとは思うので、従うしかない。 policyはdocumentにjsonで用意されてるので、iam-policy-json-to-terraformを使って変換した。便利!!

module "load_balancer_controller_iam" {
  source                        = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
  version                       = "3.4.0"
  create_role                   = true
  role_name                     = "aws-load-balancer-controller"
  provider_url                  = replace(module.eks_cluster.cluster_oidc_issuer_url, "https://", "")
  number_of_role_policy_arns    = 1 # これがないとダメ(辛い・・)
  role_policy_arns              = [aws_iam_policy.load_balancer_controller.arn]
  oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:aws-load-balancer-controller"]
}

resource "aws_iam_policy" "load_balancer_controller" {
  name_prefix = "load-balancer-controller"
  description = "EKS load balancer controller policy for cluster ${module.eks_cluster.cluster_id}"
  policy      = data.aws_iam_policy_document.load_balancer_controller.json
}

data "aws_iam_policy_document" "load_balancer_controller" {
// ... 省略
// https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2_ga/docs/install/iam_policy.json
// ここから持ってきて変換する
}

Argo CDがSyncしないみたいな状況になったけど直った一部始終

まとめ

  • argocd-application-controllerは1podしかたててはいけない
  • なんかSyncがおかしくなったらargocd-application-controllerの残骸が残ってないか確認する

一部始終

ある日、業務で日々使っているArgo CDの様子がおかしくなって、OutOfSyncが増えて、Sync Statusを見ても1日以上syncingみたいな状況でSyncするには、画面から何回かSynchorizeするとようやくsyncするみたいな状況になった。

argocdのコンポーネントの負荷の問題かなと思って、argocd-application-controllerのresourceを見てみると、CPUが2コアから3コアぐらいいっており、なにかがおかしいとissueを漁ってみると、CPUを異常に食ってるみたいのがあった。

I also realized that the application controller Pod is completely hogging the CPU while this is happening.

github.com

verupすれば直るみたいのもあったので、とりあえずverupしてみたが直らなかった。 redisがなんかおかしいのかと思って、flushDBしてみたがそれもダメだった。

ちなみに、このとき、argocd-application-controllerが なぜか2台立っていた がそういうものだと思いスルーしていた。(が、これが原因だったということがあとから分かった)

NAME                                               READY   STATUS    RESTARTS   AGE
argocd-application-controller-6847958cc6-4ssdm     1/1     Running   0          15m
argocd-application-controller-6847958cc6-vjzwg     1/1     Running   0          15m

改めて、ArgoCDでHA構成するには、argocd-application-controllerの起動オプションを変更したりするといいということが分かり、それも試してみたが、特に変わらず。

argoproj.github.io

相変わらずargocd-application-controllerのCPUが異常に高いので、replicasを10個とかに増やしてみたが、やはりダメだった。

そして、なんかissueないかなと思って、見ていると、こんなissueが・・

github.com

controllerのreplicas増やしちゃダメじゃん!!!!!!!1111!!

ということで、argocd-application-controllerの数を1つにしたら、無事直りました。

Leader Electionの話

この問題は、別の部署の同僚が既に気づいており、issueにもなっていて、教えてもらいました。pod適当に増やせばいいだろって思ってたけど、裏では、こういうLeader Electionの仕組みで整合性が保たれていたんですね。各種controller様には頭が上がりません。

github.com

このissueだと、Leader Electionしても、1podだけしか処理できないから、どうせなら、分散して処理を分け合うみたいな方向がいいなーみたいな流れになっていたと理解しました。

Argo CDでgodaddy/kubernetes-external-secretsをhelmで入れる

godaddyのExternal SecretsをArgo CDのApplicationとして登録しようとしてハマったのでネットの海に放流しておく。

Helmのコマンドでのインストール方法は普通にREADMEにも書いてある。

$ helm repo add external-secrets https://godaddy.github.io/kubernetes-external-secrets/
$ helm install external-secrets/kubernetes-external-secrets

これをArgo CDのApplicationとしてyamlで書くのがパッと分からなくて、ググるとhelmをsourceにするのはrepoURL.gitな例が多くて、chartを指定してるのがArgo CDのHelmのところで見つけられなくてAPI Doc見て分かった。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: external-secrets
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: kube-system
    server: https://kubernetes.default.svc
  source:
    repoURL: https://godaddy.github.io/kubernetes-external-secrets/
    targetRevision: 5.1.0
    chart: kubernetes-external-secrets
    helm:
      releaseName: external-secrets
      parameters:
      - name: env.AWS_REGION
        value: ap-northeast-1

Terraformで最新のECS Optimized AMIのidをとってくる方法

もっといい方法があったので一番下に追記

最新のAMIみたいな情報は今どきはSSMで提供してくれるようになってきています。

Amazon ECS 最適化 AMI バージョン - Amazon Elastic Container Service

aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/recommended --query "Parameters[0].Value" --output text
{
  "schema_version": 1,
  "image_name": "amzn2-ami-ecs-hvm-2.0.20200623-x86_64-ebs",
  "image_id": "ami-08d175f1b493f205f",
  "os": "Amazon Linux 2",
  "ecs_runtime_version": "Docker version 19.03.6-ce",
  "ecs_agent_version": "1.41.0"
}

ただ、valueの値がjson形式なので、data.aws_ssm_parameter.ecs_optimized_ami.valueってやってもjsonencodeされたものが返ってきてしまうので、そのままは使えない

jsondecodeを使う

Valueはjson形式なので、そのままではTerraformでは使えないので、以下のような感じでjsondecodeを使えばいける。

data "aws_ssm_parameter" "ecs_optimized_ami" {
  name = "/aws/service/ecs/optimized-ami/amazon-linux-2/arm64/recommended"
}

resource "aws_launch_configuration" "cluster" {
  name                        = "ecs-cluster-${aws_ecs_cluster.cluster.name}"
  image_id                    = jsondecode(data.aws_ssm_parameter.ecs_optimized_ami.value).image_id
  ...
}

追記: jsondecode不要

エゴサしてたらTwitterで見つけました。ありがとうございます。

docs.aws.amazon.com

この公式ドキュメントにもあるように、image_idなどサブパラメータとして取得できるみたいです。

data "aws_ssm_parameter" "ecs_optimized_ami_image_id" {
  name = "/aws/service/ecs/optimized-ami/amazon-linux-2/arm64/recommended/image_id"
}

resource "aws_launch_configuration" "cluster" {
  name                        = "ecs-cluster-${aws_ecs_cluster.cluster.name}"
  image_id                    = data.aws_ssm_parameter.ecs_optimized_ami_mage_id.value
  ...
}

Spark on EMRで環境変数を渡す方法とちょっと注意点

f:id:masato47744:20200609200247p:plain

公式docには書いてない?かも

spark-env—spark-env.sh ファイルで値を設定します。詳細については、Spark ドキュメントの「Environment Variables」を参照してください。

公式docには、saprk-env.shで設定してくださいぐらいしか書いてなくてパッと分からなかった。リンク先のSparkドキュメント見ても、configurationで設定する方法なども見つけられなかった。

結局、別のAWSのブログ記事に書いてあるやつで、見つけられた。

spark-env.shじゃなくてconfigurationで設定する

こういうconfigを書けばOK

[
    {
      "Classification": "spark-env",
      "Configurations": [
        {
          "Classification": "export",
          "Properties": {
            "JDBC_URL": "'jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=UTF-8'"
          }
        }
      ]
    }
]

ここで設定した環境変数は、/etc/spark/conf/spark-env.sh/usr/lib/spark/conf/spark-env.shに書き込まれるんだけど、単にexport key=valueと追加されるだけなので、valueに=なんかが入っているとバグってしまう。なので、上記のようにシングルクオテーション等でくくっておく必要がある。

2018年の振り返り

1月〜3月

この時期は新サービスリリースに向けて準備したり、インフラの効率化みたいなことに取り込んでた。

そして設定ばっかじゃなくてちゃんとコード書こうと思ってgolangのツール作るみたいなのをやったりしていた。

あとはlocustとGKEで負荷テスト環境作ったり、社内の庶務さんの業務をVBAとかPowershellで自動入力するプログラム書いてたりしてたみたい。

4月〜6月

この時期はインフラエンジニアにジョブチェンジしたときにやりたいと思ってた開発環境をめっちゃ増やしたいと思ってたやつを実現させた。 EKSはまだtokyoにきてなかったのでkube-aws、kopsを検証して結局kopsで立ててECSでたてていた環境をk8sに移行して大量に増やすというのをやっていた。社内環境のことが多かったので社外ブログとかに書いてないからあれだけどこういうのとかで悩んだりしていた。

書くことで返信もらえたりしてとてもよい体験だった。

あとなぜか2年前のこの記事が【AWSしかやったことない人向け】AWSとGCPのネットワークの違いを理解してみよう - まーぽんって誰がつけたの?突然謎のバズりを見せた。

7月〜9月

いざ開発環境増やしても開発者にいきなりkubectl触ってくださいはさすがにうまくいかずに、CI/CDのフローを整えるのに、Jenkinsfileいじったり、golangでデプロイツール触ったりしていた。

あと、この辺りでメンバーの入れ替わりなどもあり、その辺りの引き継ぎなどの業務を整えたりしてた。

ブログ記事とかもこの辺から減っていったりしてる気がする。ただ、勢いでやらせてもらったDocker本のレビューをやらせてもらったのがいい経験になった!

www.mpon.me

あと、SREラウンジに出てなんかもっとちゃんとしようという気持ちになったりした。

あと、アマギフゲットするなどしていたようだ。

10月〜12月

採用とか募集要項とかこれからチームをどうするかとかそういうのにだいぶ時間を使うようになって、分かりやすい機能開発とかはできなかったけど、ちゃんとポストモーテムしようとかそういう流れになったり、datadogのダッシュボード整えようとかSLO決めようとかなんかそういう方向性は決まってきた。あんまり手を動かせてなくて不完全燃焼な気持ちでいつのまにか日々が過ぎてしまっていた期間でもあったなと。

コミットもなんとなく少ない気がする。

f:id:masato47744:20181231211354p:plain

そして、re:Invent 2018に行ったのでさらにいつのまにか日々が過ぎてった12月だった。

re:Inventはコンテナ周りの発表はあまりなかったけど、App Meshはワクワクするやつだったので、詳細を調べてブログにした。

そのあと、コンテナ支部でenvoyを分かりやすく例える一発芸をして、そこそこいいねとかしてもらえたのでやってよかったのかもしれない。

speakerdeck.com

まとめ

去年の2017年はインフラエンジニアになっていくぞと決めた年で、2018年の今年は設定だけじゃなくてミドルウェアみたいなプログラムを書いていくぞと思ってたけど、思ったより書くことができずに1年が終わってた・・まぁミドルウェア書かないといけない課題に辿り着けてないということなんだろうけど。

www.mpon.me

来年はマイクロサービスの可視化あたりをちゃんとやって、サービスメッシュも視野に入れつつまた新しいことに挑戦していきたい。足元をきちんと整えてミドルウェアなどのソフトウェアが必要になるような課題に取り組めるようになりたい。

ALBでhttpをhttpsにリダイレクトできるやつが便利だった

今まではnginxでリダイレクトさせてた

f:id:masato47744:20181018022811p:plain

こんな感じでhttpでアクセスしてきたらhttpsにリダイレクトするっていうのをnginxの設定で書いてました。

if ($http_x_forwarded_proto != https) {
    return 301 https://$host$request_uri;
}

これで困るのは

ALBからのhealth checkはhttpで来るので、health checkも301が返っちゃうということです。

f:id:masato47744:20181018023156p:plain

で、例えばuser agentがELB-healthcheckerで、かつ、httpだったら301じゃなくて200返すとか書けばいいんですが、nginxでand条件のif文書くのは結構大変なのです。(プログラミング言語ではないのでそういうもの) こちらの記事を引用します。こんな感じになっちゃうイメージです。

そこで逃げ道は 文字列結合で判定。

    if ($request_uri = /) { 
      set $test  A; 
    } 

    if ($host ~* teambox.com) { 
      set $test  "${test}B"; 
    } 

    if ($http_cookie !~* "auth_token") { 
      set $test  "${test}C"; 
    } 

    if ($test = ABC) { 
      proxy_pass http://teambox-cms.heroku.com; 
      break; 
    } 

ALBがリダイレクトもサポートした

ALBにはlister_ruleと言って、ホストヘッダーやpathがある特定の文字列だったら、転送先を変えるみたいなことができたんですが、それが固定レスポンスと、リダイレクトを設定できるようになりました。

この図でいうALBのところで、80番ポートに来たのは、443へリダイレクトしてくれるということです! なので、nginx側にredirect設定を書かずにすみます。ヘルスチェックも普通に200が返る。

f:id:masato47744:20181018023245p:plain

terraformの設定

resource "aws_lb_listener_rule" "redirect_http_to_https" {
  listener_arn = "${module.alb_router.http_listener_arn}"
   action {
    # リダイレクトの設定はこれだけでOK
    type = "redirect"
     redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
   condition {
    # こんな感じで全部のリクエストを対象にできる
    field  = "path-pattern"
    values = ["*"]
  }
}

GUIではこんな感じで見えてます

f:id:masato47744:20181018023347p:plain

nginxのテストを気軽にローカル環境でやる方法

nginxの設定は難しい

アプリケーションの開発してたエンジニアにとってnginxの設定をさっと書くのは結構難しいですよね(自分も含めて)。もう試しながらやるしかないと思うので、そんなときに気軽に試せるやり方を紹介。Dockerを使うので、Docker for Macはもちろんインストールしておいてくださいね。

適当にディレクトリ作る

雑にデスクトップにnginxみたいなディレクトリ作る。

mkdir ~/Desktop/nginx

公式のnginxのconfをパクる

# nginx.confをパクる
$ docker run -it nginx:alpine cat /etc/nginx/nginx.conf > ~/Desktop/nginx/nginx.conf
# default.confをパクる
$ docker run -it nginx:alpine cat /etc/nginx/conf.d/default.conf > ~/Desktop/nginx/default.conf

Dockerfileを書く

FROM nginx:alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf

CMD ["nginx", "-g", "daemon off;"]

Makefileを書く

run:
  docker build -t nginx-test .
  docker run -it -p 8080:80 nginx-test

こういうファイル構成になる

➜  ~ tree Desktop/nginx
Desktop/nginx
├── Dockerfile
├── Makefile
├── default.conf
└── nginx.conf

テスト開始

make run するだけ

➜  nginx pwd
/Users/mpon/Desktop/nginx
➜  nginx make run
docker build -t nginx-test .
Sending build context to Docker daemon  6.656kB
Step 1/4 : FROM nginx:alpine
 ---> bb00c21b4edf
Step 2/4 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> 4c5cd27c66a9
Step 3/4 : COPY default.conf /etc/nginx/conf.d/default.conf
 ---> Using cache
 ---> db9944326ade
Step 4/4 : CMD ["nginx", "-g", "daemon off;"]
 ---> Using cache
 ---> e92d1c2f667f
Successfully built e92d1c2f667f
Successfully tagged nginx-test:latest
docker run -it -p 8080:80 nginx-test

http://localhost:8080 にアクセスして、Welcome to nginx!

あとはお好きに

default.confをいじって、再びmake run すればOK

DatadogでECSのagentが切れてないかを監視するやり方

ecs agentとは

ECSの場合、ecs agentがコンテナのスケジューリングやもろもろの仕事をしてくれています。なので、こいつが接続状態になってないと管理外になって死亡ということになります。

github.com

なので、これは結構見ておかないといけないんだけど、それをDatadogで確認するのが簡単そうで、意外と分からなかったので問い合わせて教えてもらったので共有。もちろんdd-agentはインストールされてる前提です。

Datadog上で確認の仕方

Monitors > Check Summary

f:id:masato47744:20181010002610p:plain

aws.ecs.agent_connectedで確認できる

f:id:masato47744:20181010002936p:plain

3台つながってないやついた、やば・・と思ったけど、クリックして詳細を見るとどうやら、検証で立てていた過去のクラスターだった大丈夫そう、みたいなのがわかります。

f:id:masato47744:20181010003419p:plain

アラートを作る方法

Monitors > New Monitor > IntegrationでAmazon ECSを選択。

f:id:masato47744:20181010003632p:plain

Integration Statusのタブを選ぶ

f:id:masato47744:20181010003733p:plain

Slackにきました、やったね

f:id:masato47744:20181010004017p:plain

はぁ、、今週一体俺は何してたんだろうという気持ちに整理をつけるのにtogglがおすすめ

みなさん、もうすぐ2018年が終わりますね(^^)

俺、今週何してたんだろ・・というときありませんか?

うまく言葉に表せないけど、最近何もしてないな・・・みたいな漠然とした不安みたいなものを感じて落ち込んだりします。 関係ないけど、あと、これに似た現象として、あれ?なんでこんな財布の中の金減ってんだろ、何に使ったんだろう・・があります。

自分が何してたのか思い出せなくて落ち込む、そんなときに便利なのが、Togglです。

f:id:masato47744:20181010000235p:plain

まぁ知ってる人は知ってると思いますが、要はやることを入力して時間をトラッキングするやつです。自分で入力してぽちぽちやるので正直めんどくさいっちゃめんどくさいですw こういうDesktopアプリで入力します。

f:id:masato47744:20181010002104p:plain

レポートを見て、あぁちゃんとなんか仕事してたわと思い出して安心する

無料プランでも、色々な期間でやったことの集計結果が見れます。例えばある月の様子。こんな感じでどれくらい働いてたかとか、何に何時間ぐらいかけてたかってのが分かります。

f:id:masato47744:20181010000715p:plain

ある月に何にどれくらいかけてたんだろう?を見れる

で、例えば、ある特定のカテゴリーでどんなことをやっていたかというのをフィルターして一覧して見ることができます。例えばこういう感じ。 うむ、なんだかんだ色々やってたな。あと、今月はxxをどうするかみたいな検討をしてる時間が多かったので、なんかやった気がしなかったのかもという感想を得ます。

f:id:masato47744:20181010000949p:plain

同様に、過去どうだったかを見れるので、その前の月はなんか色々できてた気がするなーと思って見てみると、もう1ページじゃおさまらないぐらい、結構色々やってて、自分やるじゃん、みたいに自信が復活してきます。

Scrapboxにやったことをまとめ続ける

あと漠然とした不安を解消させるためにやってるのがこれ。Scrapboxにざっくりやったことを箇条書きで書いておく。これも個人的におすすめです。

f:id:masato47744:20181010001738p:plain

あとは、アウトプットしたものとかもまとめておく。

まとめ

子供ができてからは、しょっちょう飲みに行くことができなくなったので、財布のお金がなんでこんなに減ってるんだろうみたいなことは起きなくなってきました。

Terraformを書くのに今までAtomを使ってたんだけどVS Codeに鞍替えしてみたらこっちの方がよさそうだった

変えようと思った理由

GitHubという設計図共有サイトがMicrosoftに買収されたのでAtomなくなりそうと思ったからです。ちなみに今までvimとか使いこなせてなくていつもAtom使ってました。 ※この記事は社内に数ヶ月前に書いたやつなのでネタが古いw

なんかreferencesというのがついてる

f:id:masato47744:20181009002545p:plain

referencesをクリックすると

f:id:masato47744:20181009002558p:plain

それを選ぶとそこにjumpします。

tfと打つと補完がいっぱい出てくる

f:id:masato47744:20181009002648p:plain

securty_groupを選ぶとこんな感じで入力される

f:id:masato47744:20181009002658p:plain

【書評】Docker/Kubernetes 実践コンテナ開発入門はまさに「実践」のための本です

今回、レビュアーとして関わらせてもらい、本を頂けたので感想書いていきます。

とにかく内容が充実していて実用的な本です

私自身、業務でもコンテナの運用をやっているのですが各章知らないことがたくさんありました。全部で400ページぐらいあって1人でこの量書くのどれだけ大変だったんだろうという感じです。共著ではないので本全体を通して流れが一貫してると感じました。

f:id:masato47744:20180823023453p:plain

まずはDockerの歴史や意義から始まり、Dockerの操作、Dockerfileでイメージの作り方、docker-composeでコンテナ連携と順を追ってステップアップしていきます。

そして、Swarmでオーケストレーション、さらにSwarmで作ったやつをKubernetesでもやってみようの流れから、ローカルでやっていたものをGKEにデプロイして一通りKubernetesのことが体験できるようになってます。さらに、コンテナのロギングなど本番運用には欠かせない話から、Dockerイメージの軽量化、付録ではなんとFargateを利用するところもついています。もう、訳が分からないよw

ただ、ページ数が多いといっても文字ばかりという訳ではなく、キャプチャやコマンドの実行結果などが貼られていて読むのが辛いという訳でもないです。 本番でDockerを使うようにするための本なので本当は手を動かしながら読み進めていくのがおすすめですが、上記の通り読んでるだけでもコマンドの雰囲気とかが分かるようになってます。

こういう本を書こうとすると、DockerのコマンドやDockerfileの説明するだけで正直Webで見れば分かっちゃうみたいな内容になってしまう場合もあると思うんですが、本書では実際にgoのアプリケーションを書いてDockerイメージにするみたいなところから試しながら進めていくことができます。それだけじゃなくて、実用的な現場で得た経験に基づくコラムなどもたくさん紹介されてるのでおすすめです。例えば、現場でのCMDENTRYPOINTの使い分けとか知りたいですよね。そういうのものせてくれています! あと、サンプルに選ぶ題材のセンスがいいです。

私自身、コンテナの運用はECSやKubernetesしか触ったことがなくSwarmは触れたことがありませんでした。今の流れ的にはSwarmはメインストリームの立ち位置ではないとは思いますが、本書を読んでECSのあの用語ってきっとSwarmのこれから来てるんだ〜とかそういうことも知れて知識の幅が広がった気がします。

個人的には特に「第9章 より軽量なDockerイメージを作る」がオススメです!!COPYADDの違いの説明は色々読んできたつもりですが、今までで一番納得することができました。是非購入してアハ体験してもらいたいですw

各章の説明は@stromcat24さんのDocker/Kubernetes 実践コンテナ開発入門 出版に寄せての方を見てもらうとして、 レビューさせてもらったときの私の読書感想文ものせておくの読者目線での詳細を感じてみたい方はよろしければどうぞ!

読書感想文

1章 Dockerの基礎

Dockerの何がいいのかに軽く触れた後、基礎や歴史の説明もあり、その後、Dockerを利用する意義について詳細に説明している点がよいと思いました。 Dockerは聞いたことあるけど、なんかそろそろ勉強しないといけないなーで止まってる人には、なぜDockerがいいのかというところが重要だと思えた方が、そのさきのDocker For Windows/Macで試してみように進んでもらえるのではないかと思いました。

私は普段はAWSのECSやk8sでDockerコンテナを本番でホストして運用しているのですが、Docker自体のDotCloud社の頃からの歴史や、Mobyプロジェクト、LinuxKitがなんなのかについてあまり知らなかったのでその点でも勉強になりました。おそらく、この辺に経緯は知らなくとも便利なものとしてDockerは使うことができてしまうので、そういった途中から入った方の層にもオススメなのかなと思いました。

第2章 Dockerコンテナのデプロイ

Docker全般の操作、docker-composeでアプリケーションを立ち上げる構成はDockerやったことない人でやってみようという層にはいいと思いました。スクショや出力結果もあるし読んでいるだけで実際に手を動かさなくてもイメージしやすいと思います。 自分が最初つまづいたENTRYPOINTとCMDの違いなども丁寧にコラムで説明してありとてもいいと思いました。

第3章 実用的なコンテナの構築とデプロイ

仮想マシンやインスタンスなどでサーバーアプリケーションを動かしているものをコンテナ化するときにどうすればいいか、最初につまづくのがどういう単位で分離すればいいのかというところだと思います。1コンテナに入れる実用的な粒度について説明されているのがとてもいいと思いました。 あと、Data Volumeコンテナという手法知らなかったので参考になりました。あとECSやk8sしか触ったことがなかったのでDocker Swarmの部分は面白かったです。 とても盛りだくさんな章で参考になりました。

第4章 Swarmによる実践的なアプリケーション構築

基本的なWebサービスを実用的な構成でコンテナオーケストレーションを体験できるのはいいと思いました。実際はMySQLをコンテナで動かすことはそんなにないと思いますが設定を環境変数化するところなどは本番に即していると思います。 あと、Entrykit知りませんでした。あと、mysqlのメタコマンド\G知らなかった・・ Swarm触ったことないので最初TaskのIDというのが何を指すか分からなかったんですが、Taskはdocker swarmでもservice作ったときの一つのコンテナの単位なんですね。ECSしか触ったことなかったので、気づかなかったんですが、ECSってdocker swarmをもとに作られてるんですかね?ECSだけを見ていては気づかなかったことに気づけた気がします。

第5章 Kubernetes入門

Kubernetes全くの初めての人には足りない部分があるかもしれないですが、それをやりだすと溢れてしまうのでこれぐらいでいいと感じました。Swarmで作ったものをKubernetesでやるにはどうするか?という比較ができるので、理解しやすくなるのではないかなと思います。 余裕があれば、便利ツールのkubectxに触れてあると個人的には嬉しいです。ずっと知らずに切り替えやってたので大変だったという思いからです。

第6章 Kubernetesのデプロイ・クラスタ構築

Ingressを使う場合は、ClusterIPでも公開できると思ったんですが、GKEの場合はNodePortにしないとダメなんですね・・(勘違いしてました)

第7章 Kubernetesの発展的な利用

たくさんあるk8sのresourceの中から実践で使うことが多めなresourceが紹介されててよかったです。Helmでインストールするアプリとしてredmineを選んだのはイメージが湧きやすくいいと思いました。Docker for Macで試せるのはいいですね。

第8章 コンテナの運用

確かにロギングまわりは、コンテナになると今までとやり方が変わる部分ですね。章としてまとめてあるのはいいと思いました。 ConfigMapでコンテナ内のファイルを上書きするやり方、Pod AntiAaffinity、ライブリストアなど普段触れることがないことを知れました。

第9章 より軽量なDockerイメージを作る

全体的に知らないことがありとても勉強になりました。他人にもこの章はオススメですと薦めたいなと思いました。scratchの話、apkの詳しい説明などなんとなく通り過ぎてきてしまってたんですが、そういうことだったんだ・・という目から鱗的な内容でした。 あとdocker historyも知りませんでした。 あと、3章出て来たAlpine Linuxのことと、ダイナミックリンクの件は、ここで埋め合わせられてる気がします。

*11 俗に産業廃棄物とも呼ばれます。

これは知らなかった・・使っていきます。

第10章 Dockerの様々な活用方法

cliでdocker使えるというのは、ぼくはDocker始めた頃に気づけなかったので、こういう紹介があるのはいいと思いました。なんとなくDocker == サーバーアプリケーションとして使うんでしょ?みたいに思っちゃってました。あと、hadolint知りませんでした。

まとめ

とにかくコンテナ開発にまつわるエッセンスが全部詰まってると思います。サンプルをもとに実際に手を動かしながら学んでいけるので、コンテナ開発やっていきの皆様におかれましては購入をオススメいたします。

Cloud Native Deep DiveでKubernetesについてディスカッションしてきました #deepcn

Cloud Native Deep Dive #1

事前にアンケートを提出してテーブルごとに分けれてグループディスカッションをする形式のmeetupでホワイトボードを使ってわいわい議論した。ツイートがこれしかできなかったw

テーマ1. k8sのマニフェスト管理・デプロイについて

グループでデプロイ方法をまず紹介しあう。内容はこんな感じ

  • helm template + kubectl apply
  • helm
  • go template
  • Spinnaker

個人的な気づきとしては、

  • マニフェストと一口に言っても、Webアプリケーションなどのデプロイに使うServiceやDeploymentオブジェクトのマニフェスト管理と、クラスターの基本機能ともいえるもの(heapsterやdashboard、Ingress Controllerなど)のマニフェスト管理に分かれるよね
  • helmじゃないとダメなところって何んだろうみたいな議論をしているときに、Deploymentに書く環境変数などもtemplatingしたいみたいなことを言ったら、configMapやsecretsを活用すれば、実はhelmなくてもいけたりしないかなという話にもなって確かにそうかもと思った
  • kubernetesに用意されてるオブジェクトを活用すれば、実は普段書き換えるのってimageのtagぐらいじゃない?みたいな。
  • Spinnakerはmanifest意識せずにぽちぽちと設定してもらうだけでできる。開発メンバーにmanifestの書き方を覚えてもらわなきゃ!って思ってたけど、実はそうでなないかも?と気づかせてもらった。
  • Spinnakerはあと意外と対応してないresourceとかあるんだということ。ただ、話してくれたメンバーはかなり前に使っていただけなので今は分からないとおっしゃってた。

テーマ2. マニフェストファイル、誰が書いてる

やはり共通意見として、アプリケーションの開発メンバー俗に言うDev、インフラメンバー的なOpsでどっち側がデプロイするという議論になった。 この日集まってるのはほとんどOps側の人だったので、マニフェストはやっぱりOps側が書いてるけど、Dev側で管理できるようになるのが理想という話。 もちろん、Devの人には開発に集中してもらいたいので最低限のことぐらいでという気持ち。

でも、他のグループの意見とか聞いてて思ったのは、漠然とDev側ができたらいいよなって思ってたけど、

  • 実際はrequestするmemoryとかCPUで好きなように設定させたら困るよなとか
  • networkPolicyとか真面目にやり始めたら、それを覚えてもらうのはさすがに酷だよな

っていうことに気づいてきた。

漠然とやってもらいたいと思ってはいたけど、実はそれはimageの指定とか環境変数の設定ぐらいで、それ以外はOps側で管理したいよなと思った。

ビアバッシュ & フリーディスカッション

ここではIngress Controllerって何を選べばいいんでしょうかね?みたいな話をしたり、NodeのOSは何使ってますかとかそういう話をした。 あと、OpenShiftの話も聞かせてもらったりしてk8sのことぐらいしか知らなかったので、勉強になった。 Ansibleを使い慣れたメンバーからすると、Helmはまた新しい概念ですぐに組織に導入できないので、まずはAnsibleとJinja2でyamlをジェネレートするという話も聞いて、なるほどそういうフェーズもあるのかという気づきもあった。

meetup参加の感想とデプロイまわりまとめ

研修でやるようなグループディスカッションと違って技術的な内容についてやるグループディスカッションは楽しかったw20分×2もあったのに一瞬で終わった気がする。

何か結論が出たという訳じゃないけど、強いて結論付けるとすれば(当たり前だけど)組織構成、メンバーの習熟度などによって最適解は変わってくるよねという感じ。Kubernetseの機能でもまずは十分強いので、sedだけでも十分戦えるし、最初から最強の形にしなくても、必要になったらhelm使ったりみたいに徐々に選択していけばいいのかなと思った。

あと、セッションを聞くだけの形式じゃなくて、こういう形式のmeetupが増えてくればいいなと思った。

提供してくれたゼットラボさんと運営の主催者のみなさん、ありがとうございました。また次回も参加させてもらいたいです!