Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby conf 2016 - Rails Deploy at StraaS.io

gaga5lala
December 23, 2016

Ruby conf 2016 - Rails Deploy at StraaS.io

Slide for ruby conf 2016 lightning talk.

gaga5lala

December 23, 2016
Tweet

Other Decks in Technology

Transcript

  1. Sample architecture Computer Instance Computer Instance L O A D

    B A L A N C E Requests Computer Instance web api payment
  2. Infrasturcture as code => Infrastructure described as code is flexible,

    versionable, human-readable, and testable. Chef
  3. • Chef server • Chef workstation • Chef node •

    Role, env, run list • Cookbook ◦ template ◦ recipe ◦ attributes ◦ data bag Chef
  4. Chef $ knife bootstrap 192.168.11.22 "sudo chef-client"... $ knife ssh

    "name:fe-rails-*" "sudo chef-client" -x app -a cloud_v2.public_ipv4
  5. A deployment automation tool built on Ruby, Rake, and SSH.

    $ cap production deploy:check $ cap production deploy branch_name=master $ cap production deploy:bundle $ cap production deploy:compile_assets $ cap production deploy:migrate $ cap production deploy:restart Capistrano
  6. Deploy pipeline 1. Create an instance 2. Prepare rails environment

    (package, configuration, credential) 3. Execute capistrano task 4. Build instance template & Rolling update
  7. docker 從入門到放棄 Docker —— 從入門到實踐 Why Docker? - A very

    light-weight virtaul machine - Efficient - Quickly scale - Build once, deploy everywhere - NO more “it works on my machine”!!
  8. Build a image from dockerfile $ cap production docker:image:build:os $

    cap production docker:image:build:config $ cap production docker:image:build:web
  9. Push image to docker registry $ docker push gaga5lala/rails:abcde #

    in Google cloud Platform $ gcloud docker --project my_proj push rails:abcde $ cap production docker:push:web
  10. L O A D B A L A N C

    E web N G I N X web 2 fluentd log Requests rollbar agent web N G I N X web 2 fluentd log rollbar agent Docker containers
  11. Deploy pipeline(capistrano) 1. Create an instance 2. Prepare rails environment

    (package, config, credential) 3. Execute capistrano task 4. Build instance template & Rolling update
  12. Deploy pipeline 1. Create an instance 2. Install docker 3.

    $ cap production docker:build:web 4. $ cap production docker:test:web (request response) 5. $ cap production docker:push:web 6. $ cap production docker:run
  13. Scaling? a. Call GCP api? i. snapshot ii. image iii.

    instance template iv. rolling update b. Use kubernetes!
  14. Docker don’t solve... • A running docker container is not

    a reliable service • Where to put your docker images? • Resource management & health check • Manage multiple running docker containers • Rolling update & rollback • High availability & load balancing • Auto-scaling • Config management
  15. What is Kubernetes • Yaml config files • Specify a

    desired state • Observe, diff, act - decoupling between application and kernel/os - service should be self-healing - reconciliation between desired state and current state
  16. containers: - name: fe-rails-cron image: rails:abcde resources: limits: cpu: 2000m

    memory: 2000Mi args: - whenever update && cron start livenessProbe: httpGet: port: 80 initialDelaySeconds: 10 Pod
  17. containers: - name: fe-rails-cron image: rails:abcde resources: limits: cpu: 2000m

    memory: 2000Mi args: - whenever update && cron start livenessProbe: httpGet: port: 80 initialDelaySeconds: 10 Pod
  18. containers: - name: fe-rails-cron image: rails:abcde resources: limits: cpu: 2000m

    memory: 2000Mi args: - whenever update && cron start livenessProbe: httpGet: port: 80 initialDelaySeconds: 10 Pod
  19. Pod containers: - name: fe-rails-cron image: rails:abcde resources: limits: cpu:

    2000m memory: 2000Mi args: - whenever update && cron start livenessProbe: httpGet: port: 80 initialDelaySeconds: 10
  20. apiVersion: extensions/v1beta1 kind: Deployment spec: strategy: type: RollingUpdate replicas: 5

    template: spec: containers: - name: fe-rails-web image: rails:12345 Deployment
  21. apiVersion: extensions/v1beta1 kind: Deployment spec: strategy: type: RollingUpdate replicas: 5

    template: spec: containers: - name: fe-rails-web image: rails:12345 Deployment
  22. apiVersion: extensions/v1beta1 kind: Deployment spec: strategy: type: RollingUpdate replicas: 5

    template: spec: containers: - name: fe-rails-web image: rails:12345 Deployment
  23. Bin Packing Rails Rails Nodejs Nodejs Rails Always run with

    resource (CPU+Mem) limitation Machine Docker Container Loses about 0.4 CPU
  24. Service apiVersion: v1 kind: Service metadata: name: fe-rails spec: selector:

    app: rails stage: production ports: - port: 80 type: LoadBalancer loadBalancerIP: 1.1.1.1
  25. Service apiVersion: v1 kind: Service metadata: name: fe-rails spec: selector:

    app: rails stage: production ports: - port: 80 type: LoadBalancer loadBalancerIP: 1.1.1.1
  26. Service apiVersion: v1 kind: Service metadata: name: fe-rails spec: selector:

    app: rails stage: production ports: - port: 80 type: LoadBalancer loadBalancerIP: 1.1.1.1
  27. Service apiVersion: v1 kind: Service metadata: name: fe-rails spec: selector:

    app: rails stage: production ports: - port: 80 type: LoadBalancer loadBalancerIP: 1.1.1.1 (X) SSL certificate (X) Domain base routing
  28. Service apiVersion: v1 kind: Service metadata: name: fe-rails spec: selector:

    app: rails stage: production ports: - port: 80 type: NodePort (X) SSL certificate (X) Domain base routing ⇒ Ingress
  29. Ingress An Ingress is a collection of rules that allow

    inbound connections to reach the cluster services. - public IP - tls - backend service - health check
  30. apiVersion: extensions/v1beta1 kind: Ingress metadata: name: straas-rails annotations: kubernetes.io/ingress.global-static-ip-name: 1.2.3.4

    spec: tls: - secretName: ${STRAAS_CERT} rules: - host: api.straas.io http: paths: - backend: serviceName: rails-api servicePort: 80 - host: web.straas.io Ingress
  31. apiVersion: extensions/v1beta1 kind: Ingress metadata: name: straas-rails annotations: kubernetes.io/ingress.global-static-ip-name: 1.2.3.4

    spec: tls: - secretName: ${STRAAS_CERT} rules: - host: api.straas.io http: paths: - backend: serviceName: rails-api servicePort: 80 - host: web.straas.io Ingress
  32. apiVersion: extensions/v1beta1 kind: Ingress metadata: name: straas-rails annotations: kubernetes.io/ingress.global-static-ip-name: 1.2.3.4

    spec: tls: - secretName: ${STRAAS_CERT} rules: - host: api.straas.io http: paths: - backend: serviceName: rails-api servicePort: 80 - host: web.straas.io Ingress
  33. Horizontal Pod Autoscaling apiVersion: extensions/v1beta1 kind: HorizontalPodAutoscaler metadata: name: fe-rails-api

    spec: scaleRef: kind: Deployment name: rails-api minReplicas: 2 maxReplicas: 10 cpuUtilization: targetPercentage: 80
  34. Horizontal Pod Autoscaling apiVersion: extensions/v1beta1 kind: HorizontalPodAutoscaler metadata: name: fe-rails-api

    spec: scaleRef: kind: Deployment name: rails-api minReplicas: 2 maxReplicas: 10 cpuUtilization: targetPercentage: 80
  35. Horizontal Pod Autoscaling apiVersion: extensions/v1beta1 kind: HorizontalPodAutoscaler metadata: name: fe-rails-api

    spec: scaleRef: kind: Deployment name: rails-api minReplicas: 2 maxReplicas: 10 cpuUtilization: targetPercentage: 80
  36. Commands $ kuberctl create -f rails.yaml $ kuberctl delete -f

    rails.yaml $ kuberctl replace -f rails.yaml
  37. Deploy pipeline(docker) 1. Create an instance 2. Install docker 3.

    $ cap production docker:build:web 4. Test container running (request response) 5. $ cap production docker:push:web 6. $ cap production docker:run
  38. 1. Create k8s cluster 2. $ cap production docker:build:web 3.

    $ cap production docker:push:web 4. $ cap production k8s:update:yaml 5. $ cap production k8s:db:migrate 6. $ cap production k8s:update Deploy pipeline
  39. K8s help you solve !! • A running docker container

    is not a reliable service • Where to put your docker images? • Resource management & health check • Manage multiple running docker containers • Rolling update & rollback • High availability & load balancing • Auto-scaling • Config management
  40. • Use ruby:2.3-slim as base image • Use k8s secret,

    get rid of chef • Inject config and credential at docker run • Regression test • Scale matrix: QPS • Use shell script to deploy Improvement