Slide 1

Slide 1 text

Daichi Harada & Jun Sakata JAWS DAYS 2019 2019. 02 . 23 新卒1年目のSREが コンテナをデプロイできるよう になるまでの道のり

Slide 2

Slide 2 text

はじめに

Slide 3

Slide 3 text

Docker やろうぜ お、おす

Slide 4

Slide 4 text

急にどうしたんだろう

Slide 5

Slide 5 text

すべてはここから始まった

Slide 6

Slide 6 text

Daichi Haradaのクジラ漁

Slide 7

Slide 7 text

Daichi Haradaのクジラ漁

Slide 8

Slide 8 text

Daichi Haradaのコンテナとの戦い

Slide 9

Slide 9 text

この話は実話をもとにした フィクションです

Slide 10

Slide 10 text

分量が多く怒涛の勢いで話が進みます が、スライドは後ほど公開予定なので、 合わせてご確認ください。

Slide 11

Slide 11 text

50分もあったので調子に乗りました

Slide 12

Slide 12 text

About Speakers Daichi Harada, eureka Jun Sakata, ex-eureka

Slide 13

Slide 13 text

DAICHI HARADA - @kai_ten_sushi / @dharada1 - SRE at eureka, Inc. - 北海道から遥々上京 - 気づいたら SRE に配属されてしまった! - インフラ経験ゼロからのスタート - Like - #CloudFront - #CostExplorer

Slide 14

Slide 14 text

JUN SAKATA - @sakajunquality - 別のクラウドのエキスパート - SRE at Ubie Inc. - Former SRE at eureka Inc. - Like - #CodeBuild - #Aurora

Slide 15

Slide 15 text

Agenda - Part 1 - Docker - Kubernetes - Part 2 - Container Services on AWS - ECR / ECS / EKS / Fargate - EKS を使ってみた - Part 3 - CI/CD

Slide 16

Slide 16 text

Part 1 Docker and Kubernetes

Slide 17

Slide 17 text

Docker

Slide 18

Slide 18 text

Dockerってしってる? ローカルの開発で使ってる、 docker-composeとかいうやつですか? (しらんけど・・・) ggrks

Slide 19

Slide 19 text

Docker

Slide 20

Slide 20 text

Dockerとは - コンテナ型の仮想環境を作成、配 布、実行するためのプラットフォーム - ミドルウェアのインストールや各種環 境設定をコード化して管理し、 Docker イメージを作成 - Docker さえある環境なら、どこでも同 じイメージを動作させることができる

Slide 21

Slide 21 text

Build Ship Run

Slide 22

Slide 22 text

とりあえず触ってみよう なるほど、わからん!

Slide 23

Slide 23 text

よくあるWebアプリケーションを考えてみよ う

Slide 24

Slide 24 text

こんな感じのコードですね // main.go package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8888", nil) }

Slide 25

Slide 25 text

8888でhttpリッスンして // main.go package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8888", nil) }

Slide 26

Slide 26 text

“Hello, World” と表示する // main.go package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8888", nil) }

Slide 27

Slide 27 text

まずは普通に動かしてみよう Docker使わなくていいんですね

Slide 28

Slide 28 text

(ふつうに go run してみる) $ go run main.go

Slide 29

Slide 29 text

(ログぐらい出せばよかったな・・・) $ go run main.go

Slide 30

Slide 30 text

(別のターミナルで curl と...) $ curl localhost:8888

Slide 31

Slide 31 text

うごいた! $ curl localhost:8888 > Hello, World!

Slide 32

Slide 32 text

じゃあこれを Docker によう ふむ

Slide 33

Slide 33 text

・・・

Slide 34

Slide 34 text

Dockerfile が必要らしい

Slide 35

Slide 35 text

// Dockerfile FROM golang:1.11 WORKDIR /go/src/app COPY . . CMD ["go", “run”, “main.go”] こんな感じですか?

Slide 36

Slide 36 text

これでも動くんだけど、 Go って動かすときちゃんとビルドしてるよ ね? たしかに

Slide 37

Slide 37 text

// Dockerfile FROM golang:1.11 WORKDIR /go/src/app COPY . . RUN go get -d -v ./... RUN go install -v ./... CMD ["app"] どや

Slide 38

Slide 38 text

うごかしてみよう ほい

Slide 39

Slide 39 text

イメージをビルドする $ docker image build -t my-app .

Slide 40

Slide 40 text

ビルドしたのを動かす $ docker container run -p 8888:8888 my-app

Slide 41

Slide 41 text

$ curl localhost:8888 > Hello, World! curl してみる

Slide 42

Slide 42 text

マルチステージビルドを使うとよいよ // Dockerfile FROM golang:1.11-alpine WORKDIR /go/src/app COPY . . RUN go get -d -v ./... RUN go install -v ./... FROM alpine COPY --from=0 /go/src/app /usr/local/bin/app RUN apk --no-cache add ca-certificates CMD ["app"]

Slide 43

Slide 43 text

イメージのサイズを比べてみよう $ docker images | grep my-app my-app latest 9ba39c3836a9 38 minutes ago 801MB my-app-alpine latest 3880eef6c224 5 minutes ago 401MB my-app-multistage latest ce94afe10faf 1 second ago 11.6MB

Slide 44

Slide 44 text

あとこのままだとrootユーザーで動いちゃ うので、ユーザーも指定したほうがベター たしかに

Slide 45

Slide 45 text

(一旦まとめよう・・・)

Slide 46

Slide 46 text

Dockerイメージとは・・・ - コンテナを作成するファイルシステムや設 定をまとめたもの - 親のイメージから層のように重なっていく https://nvisium.com/blog/2014/10/15/docker-cache-friend-or-foe.html

Slide 47

Slide 47 text

Dockerfileとは・・・ - Docker イメージの構成内容を記したもの - 専用の DSL で記述する - FROM でベースイメージを指定し - RUN でビルドなどのコマンドを実行

Slide 48

Slide 48 text

Alpineとは・・・ - 軽量な Linux ディストリビューション - image サイズを小さくできる - glibc が入っていないので注意

Slide 49

Slide 49 text

マルチステージビルドとは・・・ - アプリケーションをビルドするコンテナ / 実行するコンテナ を分離する - 実行するコンテナにはビルドに使うパッケージは入ってなくて OK - Docker Image のサイズを小さくできる - Go や Java などビルドしたらバイナリや jar が出力されるものにはピッタリ

Slide 50

Slide 50 text

Dockerレジストリとは・・・ - DockerHub に代表される、 Docker イメージを管理・共有するしくみ - ソースコードを GitHub などで管理するのに似てる

Slide 51

Slide 51 text

Docker Hubとは・・・ - Docker 社が運営する Docker レジス トリ - FROM golang:1.11 や FROM alpine など書いて Pull される Image は Docker Hub にホストされている https://hub.docker.com/

Slide 52

Slide 52 text

- official マークのものを選ぶと良い DockerHubでのイメージの探し方

Slide 53

Slide 53 text

- クラウド - ECR ( AWS ) - GCR ( Google ) - ACR ( Azure ) - ... - OSS - Harbor - .... DockerHub以外のレジストリ

Slide 54

Slide 54 text

今回はローカルで動かしただけだから 使ってないよ。それはまた今度。  そういえば、Dockerレジストリは使わない んですか?

Slide 55

Slide 55 text

コマンド多くないですか? docker image docker container のように何を操作するかを覚えると良いと 思う

Slide 56

Slide 56 text

$ docker image --help Usage: docker image COMMAND Manage images Commands: build Build an image from a Dockerfile history Show the history of an image import Import the contents from a tarball to create a filesystem image inspect Display detailed information on one or more images load Load an image from a tar archive or STDIN ls List images prune Remove unused images pull Pull an image or a repository from a registry push Push an image or a repository to a registry ... テキトウに--helpすればいいのか

Slide 57

Slide 57 text

なんとなくわかりました (多分) そういえば、Docker は VM とは何が違うん ですか? なんだとおもう?

Slide 58

Slide 58 text

(質問に質問で答えられても )

Slide 59

Slide 59 text

VM vs Container

Slide 60

Slide 60 text

VM vs Container - VM - ホスト上でハードウェアが仮想化され、その上 でゲスト OS が動作 - 必要とする以上のリソースを割り当ててしま い、オーバーヘッドが大きい - OS を立ち上げるため起動時間がかかる - Container - コンテナはホスト OS のカーネルを利用 - リソースのオーバーヘッドが小さい - 起動が速い

Slide 61

Slide 61 text

ざっくりいうと、 「コンテナの方が軽い」 ってことですよね? だいたいそう

Slide 62

Slide 62 text

Build Ship Run

Slide 63

Slide 63 text

(テキトウな先輩だな・・・ )

Slide 64

Slide 64 text

(そういえば、docker-compose.ymlって何者 なんだろう・・・)

Slide 65

Slide 65 text

docker-compose - 複数のコンテナの立ち上げを yaml で記述 - ローカル開発環境で主に利用 - ミドルウェアのコンテナを docker-compose で立ち上げる - MySQL - Elasticsearch - DynamoDB Local - ローカルの go アプリケーションから各コン テナを利用 - いちいち brew install とかしなくていいの で開発者は楽 // docker-compose.yml services: mysql: image: mysql:5.7 environment: MYSQL_USER: datch_datch_go MYSQL_PASSWORD: fake_password ports: - "3306:3306" volumes: - .local/mysql5.7:/var/lib/mysql redis: image: redis:3.2-alpine ports: - "6379:6379" redis-cluster: image: "grokzen/redis-cluster" ports: - "7000-7007:7000-7007" elasticsearch: image: evalphobia/elasticsearch:2.4.0 ports: - "9200:9200"

Slide 66

Slide 66 text

そうか、Docker のおかげで ローカルの開発でも、 MySQLやDynamoDBが使えてたのか!!

Slide 67

Slide 67 text

今はEC2のインスタンスがたくさんいるけ ど、これもコンテナにしたほうがいいんで すか? つぎにその話をしよう

Slide 68

Slide 68 text

Why Docker in Production? - アプリケーション及び、その依存関係をイメージに固めることができる - 環境依存で動かないことがなくなる - イメージとして本番出す前にステージングで確認したりできる - ( The Twelve-Factor App https://12factor.net/ ) - VM を起動するより軽量なので、起動が速い

Slide 69

Slide 69 text

Docker まとめ - Docker とは ? - コンテナ型の仮想化環境 - Docker Image - 構成がまとまったもの - コンテナを作成するファイルシステムや設定をまとめたもの - Dockerfile を書いて build & run - Docker Hub - Docker 社が運営するリポジトリ - 公式の Docker イメージは Docker Hub で探すとよい

Slide 70

Slide 70 text

Docker 完全熟知 ( ̄^ ̄) ドヤッ !

Slide 71

Slide 71 text

Kubernetes Google’s Borg

Slide 72

Slide 72 text

今日は Kubernetesを触ってみよう 最近よくきくあれですね (またしらんけど・・・)

Slide 73

Slide 73 text

少し難しいかもしれないので、 手を動かしながらやっていこう ほーい この前の Docker の続きから

Slide 74

Slide 74 text

CNCF Phippy and Friends https://www.cncf.io/phippy/ を使って話を進めていく

Slide 75

Slide 75 text

こんな絵本が・・・

Slide 76

Slide 76 text

そもそものアプリケーションがあって・・・

Slide 77

Slide 77 text

コンテナとしてイメージに固める

Slide 78

Slide 78 text

本題の Kubernetes

Slide 79

Slide 79 text

Kubernetes

Slide 80

Slide 80 text

What is Kubernetes https://speakerdeck.com/sakajunquality/starting-google-kubernetes-engine-2019

Slide 81

Slide 81 text

つまり、コンテナを動かすのに必要な、 CPU / メモリ / ディスクを管理してくれるや つ、ってことなのかな??? あとはコンテナをどこに配置するかとか、 イメージのデプロイとか。

Slide 82

Slide 82 text

養殖漁業で考えると・・・

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

Small Ikesu Large Ikesu Medium Ikesu

Slide 86

Slide 86 text

...ってことだ!多分

Slide 87

Slide 87 text

どんな構造になってるんだろう

Slide 88

Slide 88 text

k8s Components (Master Node & Worker Node) - Master Node - API Server - k8s cluster のゲートウェイ - etcd - 共有設定の保持とディスカバリに 使う KVS - controller - API Server を利用してクラスタの 状態を監視 & 操作する - Worker Node - docker - Pod を起動する - kubelet - マスターとの通信 - kube-proxy - プロキシ、ロードバランス https://x-team.com/blog/introduction-kubernetes-architecture/

Slide 89

Slide 89 text

k8s Components (Master Node & Worker Node) - Master Node - API Server - k8s cluster のゲートウェイ - etcd - 共有設定の保持とディスカバリに 使う KVS - controller - API Server を利用してクラスタの 状態を監視 & 操作する - Worker Node - docker - Pod を起動する - kubelet - マスターとの通信 - kube-proxy - プロキシ、ロードバランス https://x-team.com/blog/introduction-kubernetes-architecture/ めっちゃムズカシイ

Slide 90

Slide 90 text

一旦内部構造は忘れよう

Slide 91

Slide 91 text

とりあえず重要なことは コントロールプレーン(マスター)が、リソー スの割当などを管理していて、 データプレーン(ワーカー)に実際のコンテ ナが動いてるってことですね!

Slide 92

Slide 92 text

ワーカーノードがいけす! Ikesu Node

Slide 93

Slide 93 text

ワーカーに実際のコンテナがいる Ikesu Node

Slide 94

Slide 94 text

次に概念を見てみよう

Slide 95

Slide 95 text

再び CNCF Phippy and Friends https://www.cncf.io/phippy/

Slide 96

Slide 96 text

Kubernetes は内部のリソースをラベルで管 理している e.g. - name: my-app - ver: v1 そのコンテナをラベルで管理

Slide 97

Slide 97 text

ラベルと同時に、名前空間でも管理してい る e.g. - production - web - datch-area Namespaces

Slide 98

Slide 98 text

- コンテナの集合の単位 - 1 つ以上のコンテナを内包する e.g. - nginx - envoy - php-fpm - fluent-bit Pod

Slide 99

Slide 99 text

ReplicaSet - 同じ仕様の Pod の複数集まった Set が ReplicaSet

Slide 100

Slide 100 text

Service - Pod にアクセスするための経路

Slide 101

Slide 101 text

- Service に外部からアクセスするための 仕組み - e.g. - GCE LB - ALB - annotation でクラウドスペシフィックな 設定を記載 Ingress

Slide 102

Slide 102 text

- データの永続化する際に仕様 - EC2 に EBS をアタッチするノリ Volumes

Slide 103

Slide 103 text

ワケワカラン

Slide 104

Slide 104 text

思ったより覚えること多い

Slide 105

Slide 105 text

カエリタイ

Slide 106

Slide 106 text

例のアプリケーションを Kubernetes にデプロイしてみよう

Slide 107

Slide 107 text

これね // main.go package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8888", nil) }

Slide 108

Slide 108 text

$ docker image tag my-app gcr.io/sakajunquality-public/my-app:v1 $ docker image push gcr.io/sakajunquality-public/my-app:v1 まずはイメージをレジストリに上げる

Slide 109

Slide 109 text

今こういう状態っすね boku-no-macbook container my-app (bin) boku-no-cloud container my-app (bin)

Slide 110

Slide 110 text

チュートリアル用に Kubernetes 作成 $ gcloud container clusters create my-cluster ... $ gcloud container clusters get-credentials my-cluster --zone asia-northeast1-c ...

Slide 111

Slide 111 text

空っぽの箱を作成 boku-no-cloud Kubernetes Cluster

Slide 112

Slide 112 text

チュートリアル用にname空間作成 $ kubectl create namespace tutorial

Slide 113

Slide 113 text

空っぽの空間を作成 boku-no-cloud Kubernetes Cluster namespace

Slide 114

Slide 114 text

// deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: app1 namespace: tutorial labels: app: app1 spec: replicas: 3 selector: matchLabels: app: app1 Pod/ReplicaSetを定義 // 続き template: metadata: labels: app: app1 spec: containers: - name: app1 Image: gcr.io/sakajunquality-public/my-app:v1 ports: - containerPort : 8888 protocol: TCP

Slide 115

Slide 115 text

// deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: app1 namespace: tutorial labels: app: app1 spec: replicas: 3 selector: matchLabels: app: app1 apps/v1のDeploymentでまとめて定義 // 続き template: metadata: labels: app: app1 spec: containers: - name: app1 Image: gcr.io/sakajunquality-public/my-app:v1 ports: - containerPort : 8888 protocol: TCP

Slide 116

Slide 116 text

// deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: app1 namespace: tutorial labels: app: app1 spec: replicas: 3 selector: matchLabels: app: app1 push下イメージを指定 // 続き template: metadata: labels: app: app1 spec: containers: - name: app1 image: gcr.io/sakajunquality-public/my-app:v1 ports: - containerPort : 8888 protocol: TCP

Slide 117

Slide 117 text

// deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: app1 namespace: tutorial labels: app: app1 spec: replicas: 3 selector: matchLabels: app: app1 replicaの数も指定 // 続き template: metadata: labels: app: app1 spec: containers: - name: app1 Image: gcr.io/sakajunquality-public/my-app:v1 ports: - containerPort : 8888 protocol: TCP

Slide 118

Slide 118 text

$ kubectl apply -f deployment.yaml デプロイしてみる

Slide 119

Slide 119 text

今こういう状態っすね boku-no-cloud Kubernetes Cluster namespace Pods container my-app (bin)

Slide 120

Slide 120 text

そう! これを外部からアクセスできるようにする

Slide 121

Slide 121 text

次にserviceの作成 // service.yaml apiVersion: v1 kind: Service metadata: name: app1-service namespace: tutorial annotations: cloud.google.com/neg : '{"ingress": true}' spec: selector: app: app1 ports: - protocol: TCP port: 8081 targetPort: 8888

Slide 122

Slide 122 text

selectorでdeploymentのラベルを指定 // service.yaml apiVersion: v1 kind: Service metadata: name: app1-service namespace: tutorial annotations: cloud.google.com/neg : '{"ingress": true}' spec: selector: app: app1 ports: - protocol: TCP port: 8081 targetPort: 8888

Slide 123

Slide 123 text

$ kubectl apply -f service.yaml サービスの作成

Slide 124

Slide 124 text

多分こんなかんじ boku-no-cloud Kubernetes Cluster namespace Pods container my-app (bin) 8081:8888 service

Slide 125

Slide 125 text

// ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-lb namespace: tutorial spec: rules: - http: paths: - path: / backend: serviceName: app1-service servicePort: 8081 ingressでロードバランサーを定義

Slide 126

Slide 126 text

$ kubectl apply -f ingress.yaml ingressを作成

Slide 127

Slide 127 text

$ kubectl -n tutorial get ingress NAME HOSTS ADDRESS PORTS AGE my-app * aa.bb.xxx.yyy 80 3m ロードバランサーのIPを確認

Slide 128

Slide 128 text

多分こんなかんじ boku-no-cloud Kubernetes Cluster namespace Pods container my-app (bin) 8081:8888 service 80/443:8081 ingress

Slide 129

Slide 129 text

$ curl aa.bb.xxx.yyy > Hello, World! curl してみる

Slide 130

Slide 130 text

おー いんたーねっつに公開された!!!

Slide 131

Slide 131 text

Docker熟知した気持ちになってたけど、ど こで動かすかも考える必要があったの か!

Slide 132

Slide 132 text

なるほど 環境変数はどうやって扱うんですか? configMapやsecretというリソースがあるよ。 今回の場合、my-appがどのポートでリッス ンするか環境変数で指定できても良かっ たかもね

Slide 133

Slide 133 text

container == pod?

Slide 134

Slide 134 text

NO さっきの pod Pod container More practical pod Pod container my-app my-app container nginx container logger

Slide 135

Slide 135 text

理解!

Slide 136

Slide 136 text

ところで何で急に教育熱心になったんで すか? 恩田さん(上司)に怒られました?

Slide 137

Slide 137 text

実は会社やめるんや・・・ えええええええええ (テックリードの座はいただいた)

Slide 138

Slide 138 text

(冷静に、こんなに技術先行なのは、 引き継ぎってことか・・・)

Slide 139

Slide 139 text

困ったらこの本に答えがある https://www.amazon.co.jp/dp/B07HFS7TDT/ https://www.amazon.co.jp/dp/B0721JNVGT/

Slide 140

Slide 140 text

さらばじゃ

Slide 141

Slide 141 text

・・・

Slide 142

Slide 142 text

とりあえず本ポチるか・・・

Slide 143

Slide 143 text

・・・

Slide 144

Slide 144 text

Part 2 Containers on AWS

Slide 145

Slide 145 text

いやな先輩消えたし これから、やってくぞい!

Slide 146

Slide 146 text

う〜ん、パッと見た感じ AWS サービス多くてわからない・・・

Slide 147

Slide 147 text

とりあえず、 調べてみよう

Slide 148

Slide 148 text

AWS Container Services

Slide 149

Slide 149 text

AWS Container Services - Registry - ECR - Orchestration - ECS - EKS - Compute - Fargate - EC2 - Auto Scaling Group - Code* - CodeDeploy - CodeBuild - CodePipeline https://aws.amazon.com/jp/containers/services/

Slide 150

Slide 150 text

ざっくりAWSのコンテナサービス といっても、 何するやつか分類できて その中でも選択肢がある。 って感じなんだな

Slide 151

Slide 151 text

ECR - ECR = Elastic Container Registry - IAM Policy / Role で ECR リソースの利用を細かく制御可能

Slide 152

Slide 152 text

ECR == AWSのDocker Registry

Slide 153

Slide 153 text

ECS / EKS - ECS ( Elastic Container Service ) - 他の AWS サービスとシームレスに連携 - Fargate を使えばサーバの管理が不要 - 起動タイプで EC2 or Fargate を選べる - EKS ( Elastic Container Service for Kubernetes ) - k8s のマネージドサービス - Master のみマネージド - Worker Node は EC2 を立てて運用する - Fargate は未対応 - (AWS のサービスとしては ) ECS より後発

Slide 154

Slide 154 text

ECSとEKS、 どっちを使うか 悩ましい!

Slide 155

Slide 155 text

Fargateに 対応してるとかしてないとか う〜ん、Fargateって、なんだろ?

Slide 156

Slide 156 text

Fargate - Fargate とは - ECS で使えるフルマネージドなコンピューティングエンジン - 課金体系 - 実際に Task を起動していた vCPU / メモリに対する時間単位の課金 - 最近単価が下がったが、 EC2 との価格比較をすると少し割高ではある

Slide 157

Slide 157 text

Fargateのメリット - メリット - 管理コストが減る - コンテナのオートスケールに合わせて EC2 もオートスケールさせる手間が ない - Worker Node がどの AZ に配置されてるか意識する必要がない - 余剰リソースがなくなる - EC2 を使うときはコンテナ全体が使っているより余剰のリソースを確保する 必要がある

Slide 158

Slide 158 text

管理コストも考えると Fargateよさそう!

Slide 159

Slide 159 text

EKS / ECS / Fargate の関係を整理すると ...

Slide 160

Slide 160 text

EKSとECSのControl Plane と Data Plane - Control Plane - コンテナを管理する場所 - どの Node に配置するかなど制御する - AWS のサービスでいうと、 ECS / EKS - Data Plane - コンテナが実行される場所 - Control Plane に各 Node やコンテナの状態をフィードバックする - AWS のサービスでいうと、 Fargate / FC2

Slide 161

Slide 161 text

Fargate、めっちゃいいやつだな

Slide 162

Slide 162 text

CodeBuildとかCodeDeployとかは コンテナに対応してるのかな?

Slide 163

Slide 163 text

Code* (CodeBuild / CodeDeploy / CodePipeline) - CodeBuild - buildspec.yaml に ecr push を書いて ECR への push を行う - CodeDeploy - ECS で Blue/Green Deployment のサポート - CodePipeline - ECR 上のイメージをデータソースとして使える - ビルド環境として使うイメージを ECR で管理できるようになった - これまでは CodeBuild で Docker イメージを管理していた - Deploy Target に ECS も対応

Slide 164

Slide 164 text

コンテナのビルド/デプロイにもちゃんと使 えるんだな

Slide 165

Slide 165 text

改めてEKSを さわってみる

Slide 166

Slide 166 text

Kubernetes 、やりたい

Slide 167

Slide 167 text

というか前任のあいつが Kubernetesで作ったので、 やらざるを得ない!!

Slide 168

Slide 168 text

Why EKS ? - Why not ECS ? - 前任者が既に GKE で一部サービスを稼働させていた - yaml 使いまわしたい - EKS でも途中まで組んだ形跡があった - Why not GKE ? - 既存のアプリケーションが AWS で稼働しておりデータが AWS にある - また、 AWS でしか使えないデータベースを使いたい - e.g. DynamoDB Aurora

Slide 169

Slide 169 text

クラスターを立てる - 公式ドキュメント … getting started を読んでみた - https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started.html

Slide 170

Slide 170 text

VPC / Subnet / Security Group / IAM 設定 ... わかるけど、クラスターが立つまでに やることが多いな。。。。

Slide 171

Slide 171 text

シャッと 簡単にできる方法 ないかな〜

Slide 172

Slide 172 text

Create k8s cluster by eksctl - Go 製の cli アプリ - eksctl create cluster - CloudFormation が裏側で動いてくれる - 一通りよしなにクラスターを作成してくれる - VPC / Subnet - IAM - EKS Cluster - Worker Node (EC2 + ASG) - 検証用途なら最速 - デフォルトだと新規の VPC が作られる - ( 既存の VPC を使うオプションもある ) https://github.com/weaveworks/eksctl

Slide 173

Slide 173 text

ぽちっとな $ eksctl create cluster

Slide 174

Slide 174 text

でかいインスタンスたててもたーーーー ※デフォルトだとオレゴンにて m5.large が 2 台立つ

Slide 175

Slide 175 text

けしけし

Slide 176

Slide 176 text

$ eksctl create cluster \ --name test-cluster \ --region ap-northeast-1 \ --nodes 2 \ --nodes-min 1 \ --nodes-max 2 \ --node-type t2.small スペックをしっかり指定するの巻

Slide 177

Slide 177 text

よし、クラスターができた

Slide 178

Slide 178 text

Nodeも指定したとおり、 t2.smallが2台できてる $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-38-92.ap-northeast-1.compute.internal Ready 1s v1.11.5 ip-192-168-74-18.ap-northeast-1.compute.internal Ready 1s v1.11.5 $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1 443/TCP 1s

Slide 179

Slide 179 text

他には何が作られているんんだろう。。。 気になる。。。

Slide 180

Slide 180 text

nodegroupとcluster、2つのCloudFormationス タックができてるみたいだ。

Slide 181

Slide 181 text

Clusterの方は EKS Clusterと、 それが乗っかる VPC / Subnet / Route Table などなどのネット ワーク周りを作って いる。

Slide 182

Slide 182 text

NodeGroupの方は AsgとLaunch Template を作ってるんだな。 あとは IAM Role / SG / Instance Profileとかの 権限周りか。

Slide 183

Slide 183 text

なにが立てられたか、 ざっくりわかったぞい

Slide 184

Slide 184 text

では、ECRにDockerイメージを Pushしてみよう

Slide 185

Slide 185 text

Build > docker image build -t my-app:1.00 . まずはいつものように docker buildして、っと

Slide 186

Slide 186 text

ECR Login > $(aws ecr get-login --no-include-email --region ap-northeast-1) Login Succeeded ECR への Login コマンドを 取得 & 実行.

Slide 187

Slide 187 text

Tag > docker image tag my-app:1.00 \ xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:1.00 docker tagコマンドで ECRの方にタグを切り

Slide 188

Slide 188 text

Push > docker image push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:1.00 ECR へ Push する!

Slide 189

Slide 189 text

ECRにDocker ImageをPushできたぞい

Slide 190

Slide 190 text

Makefile化すると便利 NAME=my-app TAG=1.00 CONTAINER_PORT=8888 LOCAL_PORT=8888 AWS_ACCOUNT_NUMBER=1234567890 login: ## generate `docker login` command aws ecr get-login --no-include-email --region ap-northeast-1 build: ## docker build docker build -t $(NAME):$(TAG) . run: ## docker run docker run --rm -it -p $(LOCAL_PORT):$(CONTAINER_PORT) $(NAME):$(TAG) tag: ## tag docker tag $(NAME):$(TAG) $(AWS_ACCOUNT_NUMBER).dkr.ecr.ap-northeast-1.amazonaws.com/$(NAME ):$(TAG) push: ## push 事前にAWSコンソールでリポジトリを作っておき、そこへpushする docker push $(AWS_ACCOUNT_NUMBER).dkr.ecr.ap-northeast-1.amazonaws.com/$(NAME ):$(TAG) release: build tag push そういえば、 一連のコマンドは こんな感じで Makefileにしておくと 取り回しやすい

Slide 191

Slide 191 text

よし、つぎは EKS へデプロイしたい!

Slide 192

Slide 192 text

まずはdeployment.yamlを書く

Slide 193

Slide 193 text

ほんで kubectl apply -f deployment.yaml っと $ kubectl apply -f deployment.yaml

Slide 194

Slide 194 text

podが立っている。 $ kubectl get pods NAME READY STATUS RESTARTS AGE golang-sample-app-xxxxxxxxxd-dhgj2 1/1 Running 0 1s golang-sample-app-xxxxxxxxxd-q6pls 1/1 Running 0 1s golang-sample-app-xxxxxxxxxd-zlm25 1/1 Running 0 1s

Slide 195

Slide 195 text

けどこれ、どうやってインターネットからア クセスするんだろう ??

Slide 196

Slide 196 text

そうだ、Serviceを使うんだった

Slide 197

Slide 197 text

えいや service.yaml

Slide 198

Slide 198 text

kubectl apply -f service.yaml $ kubectl apply -f service.yaml

Slide 199

Slide 199 text

TYPE: LoadBalancerのServiceができた! $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE golang-sample-app LoadBalancer 10.100.17.74 hoge.ap-northeast-1.elb.amazonaws.com 80:30498/TCP 3d kubernetes ClusterIP 10.100.0.1 443/TCP 4d

Slide 200

Slide 200 text

EXTERNAL-IP に ELBのDNS名が書かれているぞ $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE golang-sample-app LoadBalancer 10.100.17.74 hoge.ap-northeast-1.elb.amazonaws.com 80:30498/TCP 3d kubernetes ClusterIP 10.100.0.1 443/TCP 4d

Slide 201

Slide 201 text

コンソールで確認すると ELB (Classic) が作られている! $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE golang-sample-app LoadBalancer 10.100.17.74 hoge.ap-northeast-1.elb.amazonaws.com 80:30498/TCP 3d kubernetes ClusterIP 10.100.0.1 443/TCP 4d

Slide 202

Slide 202 text

いったんブラウザでみると

Slide 203

Slide 203 text

(Classic LoadBalancerだけど) 動いてる〜!

Slide 204

Slide 204 text

やったね

Slide 205

Slide 205 text

でも、あれれ、、、

Slide 206

Slide 206 text

Ingressってのが必要じゃなかったっけ? Serviceだけでいいの? Service LoadBalancerだとCLBができる IngressでALBができる 時代はALBなのだよ

Slide 207

Slide 207 text

あと、 セキュリティグループ とか TLS証明書 とかを annotationで指定できるぞい

Slide 208

Slide 208 text

なるほど〜!ありがとうございます!

Slide 209

Slide 209 text

(うるさいなあ)

Slide 210

Slide 210 text

ALBも試しておくか

Slide 211

Slide 211 text

service.yaml はこんな感じで、 Type: NodePortに書き換える。

Slide 212

Slide 212 text

apply $ kubectl apply -f manifest/service.yaml

Slide 213

Slide 213 text

ingress.yaml の annotation で internet-facingなalbをつくる。

Slide 214

Slide 214 text

これをapplyすると、 ingressができる。 $ kubectl apply -f manifest/ingress.yaml ingress.extensions/golang-sample-app created $ kubectl get ing NAME HOSTS ADDRESS PORTS AGE golang-sample-app * hoge.ap-northeast-1.elb.amazonaws.com 80 2m

Slide 215

Slide 215 text

おっ、ALBが Provisioning … になったぞ

Slide 216

Slide 216 text

しばらく待って... ALBでも動いた!

Slide 217

Slide 217 text

Ingressのannotationで色々かけば ALBに証明書とかもあてられる (はず...) - alb.ingress.kubernetes.io/certificate-arn - alb.ingress.kubernetes.io/ssl-policy - etc ... - https://github.com/kubernetes-sigs/aws-alb-ingre ss-controller/blob/master/docs/guide/ingress/ann otation.md

Slide 218

Slide 218 text

ここまでをまとめると

Slide 219

Slide 219 text

まとめ : eksctlでEKS Clusterたててみた - クラスターをたてる - 検証だけなら eksctl でパッと立てられる - CloudFormation でもろもろリソースが用意される - Deployment - Kubernetes なので GKE とおなじ - ALB でインターネットからアクセスさせる - Service:NodePort と Ingress でやる - annotation は AWS 固有の設定を書く

Slide 220

Slide 220 text

検証はできたので、ちゃんとやるか

Slide 221

Slide 221 text

Cluster Management

Slide 222

Slide 222 text

Terraformで、コード管理や!

Slide 223

Slide 223 text

Create k8s cluster by Terraform - Production Ready in eureka - 既存の VPC 上でクラスタ構築したい - リソースは terraform で管理されてる - EKS もなるべく terraform で管理したい

Slide 224

Slide 224 text

Terraform : VPC & Subnet - # VPC resource "aws_vpc" "vpc" { cidr_block = "10.xx.yy.zz/ww" instance_tenancy = "default" enable_dns_support = "true" enable_dns_hostnames = "true" } # Subnet ## Public Subnets resource "aws_subnet" "public_1a" { } resource "aws_subnet" "public_1c" { } ## Private Subnets resource "aws_subnet" "private_1a" { } resource "aws_subnet" "private_1c" { } resource "aws_subnet" "private_1b" { } resource "aws_subnet" "private_1d" { } VPC / Subnet は既存のやつ。

Slide 225

Slide 225 text

Terraform : EKS Cluster resource "aws_eks_cluster" "quality" { name = "cluster-quality" role_arn = "${aws_iam_role.quality-cluster.arn}" vpc_config { security_group_ids = ["${aws_security_group.quality-cluster.id}"] subnet_ids = [ "${aws_subnet.private_1b.id}", "${aws_subnet.private_1d.id}", ] } } EKS Cluster は こんなかんじ だぜ ※ IAM Role / SG を別途書く必要あり

Slide 226

Slide 226 text

次にワーカーノードの追加

Slide 227

Slide 227 text

Terraform : EC2 Auto Scaling Group data "aws_ami" "eks-worker" { filter { name = "name" values = ["eks-worker-*"] } most_recent = true owners = ["xxxxxxxxxxxx"] # Amazon Account ID } resource "aws_launch_configuration" "quality" { associate_public_ip_address = true iam_instance_profile = "${aws_iam_instance_profile.quality-node.name}" image_id = "${data.aws_ami.eks-worker.id}" instance_type = "t2.medium" name_prefix = "terraform-eks-quality" security_groups = ["${aws_security_group.quality-node.id}"] user_data_base64 = "${base64encode(local.quality-node-userdata)}" lifecycle { create_before_destroy = true } } resource "aws_autoscaling_group" "quality" { desired_capacity = 2 launch_configuration = "${aws_launch_configuration.quality.id}" max_size = 2 min_size = 1 name = "terraform-eks-quality" vpc_zone_identifier = [ "${aws_subnet.private_1b.id}", "${aws_subnet.private_1d.id}", ] tag { key = "Name" value = "terraform-eks-quality" propagate_at_launch = true } tag { key = "kubernetes.io/cluster/cluster-quality" value = "owned" propagate_at_launch = true } } ※ Instance Profile / SG などなど別途書く必要あり

Slide 228

Slide 228 text

ちょっと大変。 できるけど、

Slide 229

Slide 229 text

https://docs.aws.amazon.com/eks/latest/user guide/getting-started.html ノードをマスターに認識させたりする

Slide 230

Slide 230 text

No content

Slide 231

Slide 231 text

Nodeを認識させるのにまたひと手間

Slide 232

Slide 232 text

まとめ : Terraformでクラスターを立てる - 既存リソースに組み込むかたちで本番に入れたい - やや分量が増えるが、既存のインフラと同じく terraform でできる - それなりに手間はかかる ※Terraformで作ったALBなどをClusterに 認識させるには、タグとかで頑張る必要 があるので注意だよ

Slide 233

Slide 233 text

ECS

Slide 234

Slide 234 text

そういえば山本さん(別のSRE)が 最近ECSさわってたな どんな感じか、 聞いてみようっと

Slide 235

Slide 235 text

No content

Slide 236

Slide 236 text

ふむ ふむ https://qiita.com/marnie_ms4/items/202deb8f587233a17cca

Slide 237

Slide 237 text

ECS - K8S と似てるけどちょっとちがう概念たち - Cluster / Service / Task Definition / etc ... https://qiita.com/marnie_ms4/items/202deb8f587233a17cca

Slide 238

Slide 238 text

ECSの良さ - AWS のサービスとの密な連携 - CodeDeploy で Blue/Green してくれる - Task ( ≒ k8s でいう Pod) ごとに異なる IAM Role を付与できる - Fargate を使えるのがでかい - EC2 の面倒を見なくてすむ - スケールするとき Service のスケールだけ考えれば良い - EC2 の場合 - Service のスケール時に EC2 もスケールさせるので手間かかる - 常にバッファ積むので余分にお金かかる

Slide 239

Slide 239 text

Fargate いいなあ EKS でも使いたいなー なるほど!ECSは EKSとまた違ったよさがあるんだな

Slide 240

Slide 240 text

Containers on AWS まとめ - ECR - プライベートなコンテナリポジトリ - EKS or ECS - どちらも Control Plane - k8s の生態系に乗りたいか、 AWS の他サービスとなめらかに連携したいか - Fargate - よい

Slide 241

Slide 241 text

AWS 完全熟知 ( ̄^ ̄) ドヤッ!

Slide 242

Slide 242 text

Part 3 CI/CD

Slide 243

Slide 243 text

熟知・・・ あれ・・・ デプロイまわりはどうしたらええんや

Slide 244

Slide 244 text

熟知できてない!! プロダクションに入れるには何かが足りな い!!!

Slide 245

Slide 245 text

一旦現状把握

Slide 246

Slide 246 text

既存のインフラ in eureka - 主力サービスは EC2 が多くコンテナでは動いていない

Slide 247

Slide 247 text

既存のインフラ: CodeBuild - Docker イメージではなく、ビルドの生成物を S3 にアップロード

Slide 248

Slide 248 text

開発者視点のOverview - ChatOps 経由でのデプロイ - @nana prepare {env} {region]-{service} - 差分確認 - 前回 deploy との commit 差分 (GitHub) - 確認して deploy ボタンを押す - デプロイ完了 - Slack 通知

Slide 249

Slide 249 text

SRE視点の既存のOverview - インターフェイスは ChatOps - Slackbot で CodeBuild がキック - ビルド完了後、 bot が CodeDeploy を API 経由で呼び出してデプロイ BotApp RTM API Calls

Slide 250

Slide 250 text

Why not CodePipeline - 1つのリポジトリで複数のものが内包されており、 - master 等のブランチに単純にフックさせるのが難しい pairs-repo JP FE JP BE TW BE KR BE TW FE

Slide 251

Slide 251 text

つぎに未来を考える

Slide 252

Slide 252 text

どうしたらいいのか - できるだけ開発者のインターフェイスを変えない - SOX の遵守

Slide 253

Slide 253 text

せっかくコンテナにするので - ステージングと本番では同じイメージが動く状態にしたい - イメージの脆弱性スキャン - 構成変更の手間を減らしたい

Slide 254

Slide 254 text

イメージの検証 - ステージングでの検証後本番に出せるようになる

Slide 255

Slide 255 text

構成変更の手間 EC2 のゴールデンイメージを作成するのがそれなりに手間

Slide 256

Slide 256 text

構成変更の手間 EC2 のゴールデンイメージを作成するのがそれなりに手間 これがコンテナになると

Slide 257

Slide 257 text

VMとコンテナでの構成管理の違い - Immutable なインフラという思想はそのまま - 構成管理 = Docker Image の変更という世界観になる - ミドルウェアの細かい変更など、全て Docker Image の変更で済む

Slide 258

Slide 258 text

How to Deploy to Kubernetes

Slide 259

Slide 259 text

頼りたくないけど、あいつを頼ってみよう

Slide 260

Slide 260 text

okok Kubernetes ってどうやって、デプロイのフ ロー作ればいいっすか?

Slide 261

Slide 261 text

コンテナ一般 CI/CD

Slide 262

Slide 262 text

Container CI/CD https://speakerdeck.com/sakajunquality/starting-google-kubernetes-engine-2019 コンテナ全般 テストは省略...

Slide 263

Slide 263 text

Container CI/CD https://speakerdeck.com/sakajunquality/starting-google-kubernetes-engine-2019 コンテナ全般

Slide 264

Slide 264 text

GitOps

Slide 265

Slide 265 text

GitOps - Operations by Pull Request https://www.weave.works/blog/gitops-operations-by-pull-request

Slide 266

Slide 266 text

GitOps アプリケーションのリポジトリと、マニフェストのリポジトリを分離 マニフェストリポジトリは常にクラスターの状態と整合性がとれている Application Config

Slide 267

Slide 267 text

“Declarative” が、ポイントなのか! terraform もそうだよなー

Slide 268

Slide 268 text

GitOps それぞれのリポジトリに対して、アプリケーションをビルドする CI と Kubernetes に apply する CI を設定する

Slide 269

Slide 269 text

GitOps on AWS CodeBuild 2つ設定すれば簡単に作れそう 場合によっては CodePipeline も使えそう

Slide 270

Slide 270 text

CodePipeline

Slide 271

Slide 271 text

CodePipeline + Lambda https://aws.amazon.com/blogs/devops/continuous-deployment-to-kubernetes-using-aws- codepipeline-aws-codecommit-aws-codebuild-amazon-ecr-and-aws-lambda/

Slide 272

Slide 272 text

GitOps on AWS? CodePipeline?

Slide 273

Slide 273 text

CodePipelineでもできそうだし GitOpsも試すのも良さそう

Slide 274

Slide 274 text

もう少しいろいろ検討してみよう・・・

Slide 275

Slide 275 text

(今回ここを実装するのは間に合わず)

Slide 276

Slide 276 text

CI/CD まとめ - Kubernetes では GitOps という考えがある - CodePipelines を使うとシンプルなパイプラインも構築できそう - あたらしいワークフローを作りつつも、 - 既存の開発者のインターフェイスはできるだけ変えずにやりたい

Slide 277

Slide 277 text

What’s Next?

Slide 278

Slide 278 text

Monitoring - 監視は大事だよね - Kubernetes そのものの監視 - ノードの監視 - コンテナの監視 - タグとラベルつかう - リソース使用量 - ヘルスチェック - etc ...

Slide 279

Slide 279 text

Logging - ログ、必要だよね - 既存のログと同じように収集して同じように解析したい

Slide 280

Slide 280 text

Service Mesh? マイクロサービス間の可視化

Slide 281

Slide 281 text

Service Mesh? マイクロサービス間の可視化

Slide 282

Slide 282 text

気になるRoadmaps

Slide 283

Slide 283 text

EKS IAM Roles for Pods https://github.com/aws/containers-roadmap/issues/23

Slide 284

Slide 284 text

EKS IAM Roles for Pods https://github.com/aws/containers-roadmap/issues/23 ECSにはあるやつ GKEでも恩恵うけれる?

Slide 285

Slide 285 text

Fargate for EKS https://github.com/aws/containers-roadmap/issues/32

Slide 286

Slide 286 text

Fargate for EKS https://github.com/aws/containers-roadmap/issues/32 Fargate for EKS !!!

Slide 287

Slide 287 text

Managed worker nodes https://github.com/aws/containers-roadmap/issues/139

Slide 288

Slide 288 text

Managed worker nodes https://github.com/aws/containers-roadmap/issues/139 Is this different from “EKS Fargate”?

Slide 289

Slide 289 text

EKS Private Link Support https://github.com/aws/containers-roadmap/issues/22

Slide 290

Slide 290 text

EKS Private Link Support https://github.com/aws/containers-roadmap/issues/22 他のサービスでは進んでるやつ!

Slide 291

Slide 291 text

Takeaways

Slide 292

Slide 292 text

Takeaways - Docker & k8s の基礎 - k8s は覚えること多めだけど - 焦らず 1 個ずつ確実に理解する - AWS のコンテナ関連サービス - ECR - EKS / ECS - Fargate - CI/CD - GitOps - CodePipeline - What’s Next - 監視 / ロギング などまだまだ考えることある - 今後のロードマップ

Slide 293

Slide 293 text

ご清聴ありがとうございました!

Slide 294

Slide 294 text

Appendix

Slide 295

Slide 295 text

Appendix - https://docs.docker.com/ - https://kubernetes.io/docs/home/ - https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started.html - https://github.com/weaveworks/eksctl - https://www.weave.works/blog/gitops-operations-by-pull-request - https://www.slideshare.net/AmazonWebServicesJapan/20180214-aws-black- belt-online-seminar-amazon-container-services