Slide 1

Slide 1 text

EKSにシュッと入門 〜GKEからの移行〜 #jawsug_ct #12 @sakajunquality

Slide 2

Slide 2 text

who am i

Slide 3

Slide 3 text

- SRE at eureka, Inc. - インフラ全般 + MLOps? - ErgoDox/Arch Linux @sakajunquality

Slide 4

Slide 4 text

スライドは後ほど公開するので、 スライドの写真撮影はご遠慮くださ い

Slide 5

Slide 5 text

About eureka

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Pairs Infrastructure

Slide 8

Slide 8 text

Pairs Infrastructure - サービスの大部分がAWS - 一部でGCPも使っている - ML/DWH/分析環境など

Slide 9

Slide 9 text

k8s in eureka

Slide 10

Slide 10 text

k8s in eureka - 5 Clusters - 4 GKE Clusters - 1 EKS Cluster - 絶賛検証中 - Applications - ML Recommend Model - Moderation Microservice - Slackbot - Redash - Spinnaker

Slide 11

Slide 11 text

Managed k8s Services

Slide 12

Slide 12 text

Managed k8s Services - Google Kubernetes Engine - Amazon EKS - Azure Kubernetes Service - Oracle Container Service - IBM Cloud Kubernetes Service - etc.

Slide 13

Slide 13 text

Managed k8s Services といってもGKEとEKSしかさわったことがないので、 GKEと比べつつEKSに入門的な感じで進めていきます

Slide 14

Slide 14 text

Why EKS?

Slide 15

Slide 15 text

- マネージドk8s - AWSの既存リソースが使える - インターフェイス的になれている (for me) Why EKS?

Slide 16

Slide 16 text

Cluster Master/Worker

Slide 17

Slide 17 text

- マスター(コントロールプレーン)はGKE/EKSともにマネージド Master GKE(Regional) EKS

Slide 18

Slide 18 text

Worker - GKEはマネージド - GCE的には見えるけど - EKSはユーザー管理 - オートスケーリンググループとか - 具体的には後述

Slide 19

Slide 19 text

Create Clusters

Slide 20

Slide 20 text

Creating Cluster - AWS/GCPの両方触るので、クラスターそのものはterraformで作ります - EKSをぱぱっと試したい場合やterraform不慣れな場合は、 - 公式ドキュメン トのGetting Startedがおすすめです - https://docs.aws.amazon.com/eks/latest/userguide/getting-started.h tml - CloudFormationのテンプレートもあるので気軽に利用できます

Slide 21

Slide 21 text

// インフラのgitリポジトリ . └── terraform ├── README.md ├── aws ├── datadog └─── gcp terraform - (少し話がそれますが) - エウレカではterrafomでAWSやGCPのリソースを管理しています。

Slide 22

Slide 22 text

terraform EKS EKSがGAになってすぐにterraformは対応してます

Slide 23

Slide 23 text

Creating GKE Cluster - resource: google_container_cluster - https://www.terraform.io/docs/providers/google/r/container_cluster.html

Slide 24

Slide 24 text

Creating EKS Cluster - resource: aws_eks_cluster - https://www.terraform.io/docs/providers/aws/guides/eks-getting-started. html - ワーカーノードを自分で構築しなければならないのため、 - 起動設定やオートスケールグループなどリソースが多いです - 順番に手順に従うと構築できます - 既存VPCを使う場合は、適宜必要なリソースを使用してください

Slide 25

Slide 25 text

- あまりにもコードが多くなったので割愛しました<(_ _)> Creating Cluster

Slide 26

Slide 26 text

Connect to Cluster

Slide 27

Slide 27 text

// login $ gcloud auth login // set project $ gcloud config set project // set credential $ gcloud container clusters get-credentials --zone=asia-northeast1-a Connecting GKE Cluster gcloudのcliを使用して認証情報を取得します。

Slide 28

Slide 28 text

Connecting GKE Cluster 2 とりあえず、つなげているか確認してみましょう $ kubectl get nodes NAME STATUS ROLES AGE VERSION gke-prod-my-cluster-default-pool-55afabbf-5483 Ready 3d v1.10.4-gke.0 gke-prod-my-cluster-default-pool-55afabbf-75pl Ready 3d v1.10.4-gke.0 gke-prod-my-cluster-default-pool-55afabbf-z6nm Ready 3d v1.10.4-gke.0

Slide 29

Slide 29 text

Connect to EKS Cluster EKSの場合は、kubernetes-clの他にheptio-authenticator-awsが必要 認証が通らないときはここで間違ってる可能性あり $ curl -o heptio-authenticator-aws https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/bin/darwin/amd64/heptio-authenticator-aws $ chmod +x heptio-authenticator-aws // 適当にパスを通す https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html

Slide 30

Slide 30 text

// ~/.kube/my-eks-config apiVersion: v1 clusters: - cluster: server: certificate-authority-data: name: kubernetes contexts: - context: cluster: kubernetes user: aws name: aws current-context: aws kind: Config preferences: {} users: Connect to EKS Cluster 2 https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html // つづき - name: aws user: exec: apiVersion: client.authentication.k8s.io/v1alpha1 command: heptio-authenticator-aws args: - "token" - "-i" - ""

Slide 31

Slide 31 text

Connect to EKS Cluster 3 $ export KUBECONFIG=$KUBECONFIG:~/.kube/my-eks-config $ kubectl get nodes No resources found // まだワーカーが認識されていない クラスターのコンフィグを使ってみる https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html

Slide 32

Slide 32 text

ちなみに - Makefileでクラスターを切り替えられるようにしたら割と便利です。 - EKS/GKEの切り替えだけじゃなくprod/devクラスターの切り替え等

Slide 33

Slide 33 text

Add Workers to EKS

Slide 34

Slide 34 text

Add Workers to EKS - EKSはワーカーノードをクラスターで管理していないので、 - 認識させる必要がある

Slide 35

Slide 35 text

Add Worker to EKS 2 // aws-auth-cm.yaml apiVersion: v1 kind: ConfigMap metadata: name: aws-auth namespace: kube-system data: mapRoles: | - rolearn: username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html

Slide 36

Slide 36 text

Add Worker to EKS 4 applyすると認識される $ export KUBECONFIG=$KUBECONFIG:~/.kube/my-eks-config $ kubectl apply -f aws-auth-cm.yaml $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-10-251-13-223.ec2.internal Ready 1d v1.10.3 ip-10-251-14-141.ec2.internal Ready 1d v1.10.3 // 現れた https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html

Slide 37

Slide 37 text

Add Worker to EKS 5 ASGでワーカー数増やすと増える https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html $ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-10-251-13-14.ec2.internal Ready 1m v1.10.3 ip-10-251-13-223.ec2.internal Ready 1d v1.10.3 ip-10-251-14-141.ec2.internal Ready 1d v1.10.3 ip-10-251-14-62.ec2.internal Ready 2m v1.10.3 // 増えた

Slide 38

Slide 38 text

クラスターの作成まとめ - GKEのほうがコマンドラインで完結するので、楽 - aws eks get-credential みたいなサブコマンドがほしい - EKSのワーカーもAWSなれてたらきっとわかる

Slide 39

Slide 39 text

Create Sample App

Slide 40

Slide 40 text

Create Sample App - クラスターを作ったのでアプリをデプロイしてみる - 今回使うのは単純なステートレスのWebアプリケーション - DBも使わず超シンプル化してますが、実際に似たようなものを本番運用しています App (HTTP Server) LoadBalacner

Slide 41

Slide 41 text

SampleApp: App package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hell World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8888", nil) }

Slide 42

Slide 42 text

SampleApp: Dockerfile FROM golang:1.10.3-alpine as build WORKDIR /go/src/github.com/sakajunquality/hello-go-docker COPY main.go main.go RUN go install -v ./... FROM alpine RUN apk add --no-cache ca-certificates COPY --from=build /go/bin/hello-go-docker /usr/local/bin/hello-go-docker CMD ["hello-go-docker"] ※ 本番運用はroot以外のユーザーで動かすなどちゃんとしましょう

Slide 43

Slide 43 text

// build $ docker build -t hello-go-docker:v1 --rm --no-cache . // run $ docker run -d -p 8888:8888 hello-go-docker:v1 // test $ curl localhost:8888 > Hell World // clean up $ docker kill ... Build && Run Locally

Slide 44

Slide 44 text

Deployment

Slide 45

Slide 45 text

Deployment ではこのアプリケーションをディプロイします to GKE & EKS

Slide 46

Slide 46 text

Deployment 1. Push Image 2. Deploy Image 3. Create Loadbalancer

Slide 47

Slide 47 text

Push Image

Slide 48

Slide 48 text

Push Image: Repository - リモートのリポジトリにプッシュする - それぞれのクラウドにあるプライベートリポジトリを使う - GCP - GCR - AWS - ECR - Dockerhubとかでもいいけどね - クレデンシャルがめんどくさい

Slide 49

Slide 49 text

// Push to GCR $ docker tag hello-go-docker:v1 gcr.io//hello-go-docker:v1 $ docker push gcr.io/pairs-dev/hello-go-docker:v1 // gcloud docker -- push はdeprecated Push Image GCR

Slide 50

Slide 50 text

Push Image ECR // Push to ECR $ docker tag hello-go-docker:v1 .dkr.ecr.us-east-1.amazonaws.com/hello-docker-go:v1 $ $(aws ecr get-login --no-include-email --region us-east-1) $ docker push .dkr.ecr.us-east-1.amazonaws.com/hello-docker-go:v1

Slide 51

Slide 51 text

Deploy Image

Slide 52

Slide 52 text

apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: name: hello-docker-go name: hello-docker-go namespace: my-space spec: replicas: 3 template: metadata: labels: name: hello-docker-go Manifest: deployment.yaml

Slide 53

Slide 53 text

Manifest: deployment.yaml (続き) ※ 簡略化のためにnginx等のWebサーバーは省いています ※ また、本番ではreadinessProbeやlivenessProbeでコンテナへのヘルスチェックを入れたほうが良いです spec: containers: - name: web image: gcr.io//hello-go-docker:v1 ports: - name: web containerPort: 8888

Slide 54

Slide 54 text

Deploy to GKE $ kubectl apply -f deployment.yaml $ kubectl get deployment -n my-space NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-docker-go 3 3 3 3 2m $ kubectl get pods -n my-space NAME READY STATUS RESTARTS AGE hello-docker-go-74b879d74d-2rvfs 1/1 Running 0 2m hello-docker-go-74b879d74d-gdff4 1/1 Running 0 2m hello-docker-go-74b879d74d-hdzh9 1/1 Running 0 2m

Slide 55

Slide 55 text

Deploy to GKE $ kubectl apply -f deployment.yaml $ kubectl get deployment -n my-space NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-docker-go 3 3 3 3 2m $ kubectl get pods -n my-space NAME READY STATUS RESTARTS AGE hello-docker-go-74b879d74d-2rvfs 1/1 Running 0 2m hello-docker-go-74b879d74d-gdff4 1/1 Running 0 2m hello-docker-go-74b879d74d-hdzh9 1/1 Running 0 2m _人人人人人 _ > これだけ <  ̄YYYYY ̄ 当たり前だけど・・・

Slide 56

Slide 56 text

- ECRを使うように変更する Deploy to EKS 1 spec: containers: - name: web image: < account num >.dkr.ecr.us-east-1.amazonaws.com/hello-docker-go:v1 // 変えるのはここだけ! ports: - name: web containerPort: 8888

Slide 57

Slide 57 text

Deploy to EKS 2 $ kubectl apply -f deployment.yaml $ kubectl get deployment -n my-space NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-docker-go 3 3 3 3 16s $ kubectl get pods -n my-space NAME READY STATUS RESTARTS AGE hello-docker-go-78b99465fd-68ghq 1/1 Running 0 19s hello-docker-go-78b99465fd-ksk4z 1/1 Running 0 19s hello-docker-go-78b99465fd-tqh2c 1/1 Running 0 19s

Slide 58

Slide 58 text

Deploy to EKS 2 $ kubectl apply -f deployment.yaml $ kubectl get deployment -n my-space NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-docker-go 3 3 3 3 16s $ kubectl get pods -n my-space NAME READY STATUS RESTARTS AGE hello-docker-go-78b99465fd-68ghq 1/1 Running 0 19s hello-docker-go-78b99465fd-ksk4z 1/1 Running 0 19s hello-docker-go-78b99465fd-tqh2c 1/1 Running 0 19s _人人人人人 _ > 全く同じ <  ̄YYYYY ̄ 当たり前だけど・・・

Slide 59

Slide 59 text

アプリケーションのデプロイまでできた - とりあえず、アプリケーションをデプロイするところまで完成 - アプリケーションをアップデートする場合は、コンテナイメージを作り直して、マニ フェストを更新するとローリングアップデートが走ります

Slide 60

Slide 60 text

LoadBalancer

Slide 61

Slide 61 text

LoadBalancer - 次にロードバランサーを作成 - L7のロードバランサーでSSL Terminationしたい - 証明書はロードバランサーに委ねたい App (HTTP Server) LoadBalacner HTTPS HTTP

Slide 62

Slide 62 text

- GCP - L4 TCP LoadBalancer - Service/LoadBalancer - L7 HTTP LoadBalancer - Service/NodePort + Ingress - AWS - Classic Load Balancer (CLB) - Service/LoadBlancer - Application Load Balancer (ALB) - Service/NodePort + Ingress(期待) - => できるらしいです!ごめんなさい k8s Resource for LoadBalancer

Slide 63

Slide 63 text

- 固有のリソースが多くなるのでQiitaとかで適宜調べましょう - https://qiita.com/apstndb/items/9d13230c666db80e74d0 k8s Resource Reference

Slide 64

Slide 64 text

まずはGKE + HTTP Loadbalancerでサービスを公開してみます Create Loadbalancer w/ GKE Kubernetes Engine Cloud Load Balancing +

Slide 65

Slide 65 text

apiVersion: v1 kind: Service metadata: labels: name: hello-docker-go name: hello-docker-go namespace: my-space spec: type: NodePort ports: - port: 80 targetPort: 8888 selector: name: hello-docker-go GKE service.yaml

Slide 66

Slide 66 text

apiVersion: extensions/v1beta1 kind: Ingress metadata: name: hello-docker-go namespace: my-space annotations: kubernetes.io/tls-acme: "true" kubernetes.io/ingress.class: "gce" kubernetes.io/ingress.global-static-ip-name: "" // GCP上で用意した固定IPの名前 kubernetes.io/ingress.allow-http: "true" ingress.gcp.kubernetes.io/pre-shared-cert: "< my-ssl-cert >" // GCP上のSSL証明書 spec: backend: serviceName: hello-docker-go servicePort: 80 GKE ingress.yaml

Slide 67

Slide 67 text

$ kubectl get svc -n my-space NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-docker-go NodePort 10.59.248.225 80:32337/TCP 10m $ kubectl get ing -n my-space NAME HOSTS ADDRESS PORTS AGE hello-docker-go * 35.xxx.yyy.zzz 80 10m GKE 確認

Slide 68

Slide 68 text

まともにドメインをあててないので証明書エラー出てますが、 無事にサービスが公開されました GKE 確認

Slide 69

Slide 69 text

- HTTPのヘルスチェックが通っていない - クラスターで「HTTP 負荷分散」が無効になっている - といったことが考えられます GKE Ingressが作られてないときは・・・

Slide 70

Slide 70 text

つぎにEKS + ELBの構築を行っていきます Create Loadbalancer w/ GKE +

Slide 71

Slide 71 text

EKS service.yaml apiVersion: v1 kind: Service metadata: labels: name: hello-docker-go name: hello-docker-go namespace: my-space annotations: service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: service.beta.kubernetes.io/aws-load-balancer-ssl-cert: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01" // ここは柔軟に

Slide 72

Slide 72 text

EKS service.yaml つづき ... spec: type: LoadBalancer ports: - port: 443 targetPort: 8888 selector: name: hello-docker-go

Slide 73

Slide 73 text

なんか作られない・・・ $ kubectl describe svc hello-docker-go -n my-space Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 6s (x2 over 11s) service-controller Ensuring load balancer Warning CreatingLoadBalancerFailed 6s (x2 over 11s) service-controller Error creating load balancer (will retry): failed to ensure load balancer for service my-space/hello-docker-go: could not find any suitable subnets for creating the ELB

Slide 74

Slide 74 text

annotation? - subnetを指定するannotation? - ないぞ・・・

Slide 75

Slide 75 text

なんか作られない・・・

Slide 76

Slide 76 text

なるほど https://github.com/kubernetes/kops/issues/2608

Slide 77

Slide 77 text

やってみる - VPCでpublic subnetにtagをつけてみる ※ 実際にはterraformで管理しています

Slide 78

Slide 78 text

・・・できた $ kubectl describe svc hello-docker-go -n my-space ・・・ Events: Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 6m service-controller Ensuring load balancer Normal EnsuredLoadBalancer 6m service-controller Ensured load balancer // 今度はエラー出ていない $ kubectl get svc -n my-space -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR hello-docker-go LoadBalancer 172.20.249.16 xxxxxxxxxx.us-east-1.elb.amazonaws.com 80:31378/TCP 6m name=hello-docker-go

Slide 79

Slide 79 text

ちゃんとしたドメインをあてていないので、相変わらず証明書エラーになっています が、無事に公開できました できた!

Slide 80

Slide 80 text

ELB側でも確認

Slide 81

Slide 81 text

- IngressでALBがつくれる - => サンプルCLBですみません ALBを使いたい場合は・・・?

Slide 82

Slide 82 text

Build/Deploy

Slide 83

Slide 83 text

Build/Deploy - GCP - ContainerBuilder - AWS - CodeBuild / CodePipeline - CircleCI/TravisCI etc. Container Builder CodeBuild CodePipeline

Slide 84

Slide 84 text

Conclusion

Slide 85

Slide 85 text

- タイトルにシュッとっと書いた割に長めのスライドになってしまいました - このスライドを見つつも、公式のGettingStartedを一度やってみることをおすす めします - https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html - AWSユーザーにはECSと比較したほうがよかったですかね・・? Conclusion

Slide 86

Slide 86 text

Conclusion - マニフェスト上は、annotationの違いはあるものの、複数のクラウド間を共通の 仕組みでオーケストレーションできるのは良い - 逆に言うとannotationで吸収できている - 各クラウドの知識は結局必要だけどね - k8s自体が信頼性がそれなりにあるのでEKSどんどん使っていきたい - EKSの今後のアップデートに期待 - コンソールの充実とか

Slide 87

Slide 87 text

Conclusion as of 21 June 2018 - 東京リージョンはよ! - Fargate EKSサポートも期待!

Slide 88

Slide 88 text

Questions

Slide 89

Slide 89 text

Questions http://slack.k8s.io/

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

Appendix - https://www.slideshare.net/AmazonWebServicesJapan/jaws-days-20180313-amazon-container-services - https://cloudplatform.googleblog.com/2018/06/Regional-clusters-in-Google-Kubernetes-Engine-are-now-genera lly-available.html - https://www.publickey1.jp/blog/18/awskubernetesamazon_eks.html - https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html