Glide Note

glidenote's blog

「Docker/Kubernetes 実践コンテナ開発入門」がProduction環境でDockerを運用している人間にも良書だった





TL;DR



ProductionDocker

KubernetesDocker for Mac/Windows201807KubernetesKubernetes

Docker


Docker
  • JAWS-UG コンテナ支部で登壇経験あり
  • Dockerに関する基本的な知識は習得済み
  • Amazon ECSを利用して2年ほど前からProduction環境でDocker運用中
  • Kubernetesは理解不足
  • 役職が変わってここ1年くらいからDockerと周辺技術の最新情報がキャッチアップ出来てない 😓

目次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.Dockerの基礎
2.Dockerコンテナのデプロイ
3.実用的なコンテナの構築とデプロイ
4.Swarmによる実践的なアプリケーション構築
5.Kubernetes入門
6.Kubernetesのデプロイ・クラスタ構築
7.Kubernetesの発展的な利用
8.コンテナの運用
9.より軽量なDockerイメージを作る
10.Dockerの様々な活用方法

Appendix-A セキュリティ
Appendix-B Dockerでの開発を支援するツール・サービス
Appendix-C 主要コマンドまとめ

書評

Docker


DockerWeb

Kubernetes


KubernetesMinikube Kubernetes Docker for Mac/Windows(Stable)Kubernetes KubernetesKubernetes





使



Alpine Linux

DockerVagrant?




Amazon ECSAWS


BashZsh !!


Command-line completion | Docker Documentation


2018




Docker/Kubernetes 


Docker/Kubernetes

Docker/KubernetesOK


参考

GoReplayを導入して、Production環境へのリクエストを複製し、Staging環境に転送する仕組みを作った



TL;DR



GoReplayProductionStagins

Production

2016Docker

GoReplay



GoReplay




Go

(Nginx+RailsGoReplay)

libpcap tpcdump(OSI layer2)

GoReplay  gor listen  gor replay 21  

gor listen App  gor replay 

gor replay 
 


 

https://github.com/buger/goreplay/wiki
 





Shadow Proxy







()


Shadow Proxy






ProductionStaging

Production frontend1GoReplayStaging frontendProduction

Production staging aggregator   staging BigQuery 

Production110%

echo()100%10%

SupervisordGoReplay

StagingbugsnagSlackPost

1
sudo gor --input-raw :8080 --output-http "http://stating901.example.com|10%"

GoReplay利用時のベンチマーク

nginx + echo-nginx-module を利用して、GoReplayの複製割合に応じてどれくらいパフォーマンスが劣化するか下記のような形でベンチマークを取得。

1
ab -n 10000 -c 100 http://hogemoge.example.com/hello

0%はGoReplayの利用無し、100%の場合はGoReplayで全トラフィックを複製して転送する。

  0% 10% 20% 50% 100%
RPS 2254.49 1944.42 1782.10 1403.82 1023.71

GoReplayで転送率を100%にして、全トラフィックを複製かけるとパフォーマンスが劣化するので、インフラを増強しておく必要あり。


ここから余談で、どうしてShadow Proxyを導入しなかったのか過去の経験と個人的な意見をちょっと書いてみる。

リクエストを複製するShadow Proxyの話

リクエストを複製するShadow Proxyと呼ばれるものは昔から存在します。

Shadow Proxy利用時の一般的な構成

Shadow Proxyの問題点(※1)

  • 構成的にロードバランサの次あたりに存在(リクエスト処理する構成の前段の方に存在)するので非常に高い信頼性が求められる。
  • 構成的に全リクエストがShadow Proxyを経由し、backendのサーバに到達するため、Shadow Proxyがボトルネックになりやすい。
  • インフラの構成的にサービスの全リクエストを処理する必要があるので、気軽に利用出来ない。稼働中のサービスに後から投入しにくい
  • 全リクエストがShadow Proxyを通過する構成になっていると、Shadow Proxyが落ちるとサービス全部落ちる
  • 上記を解消しShadow Proxyを安定的に稼働しようとすると、インフラが複雑化して障害点が増えやすい

※1 2年以上前の経験から得た知見なので、もしかして今は違うかもしれませんが。

この仕組みを作ったおかげで、Production環境のリクエストを利用し事前に動作検証が出来るので、今年は事故も心理的な負担がだいぶ減ったと思う。

AWS Application Load Balancer + Amazon ECS でDockerのホットデプロイ環境を構築した

TL;DR

  • AWS Application Load Balancer(以下ALB) + Amazon ECS でDockerのホットデプロイ環境を構築した
  • ALBのTarget GroupとECSのServiceを紐付けることで、ALB配下のコンテナの入れ替えが自動で行われるようになる

ALB(!!)



GitHub + CircleCI

Docker RepoAmazon EC2 Container Registry(ECR)

DeployGitHubCircleCIDocker Pushecs-deployDocker


ALBECS@inokara ALBDynamic Port Mapping


Amazon ECS  AWS Application Load Balancer  - XP

Amazon ECS  AWS Application Load Balancer 2 AWS CLI   - XP






ALB80,443

node.js3000




CircleCIecs-deploy

ALB





ecs-deployCircleCIAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY region-r us-west-1
1
2
3
4
5
ecs-deploy \
-c クラスター名 \
-n サービス名 \
-i xxxxxxxxxxxx.dkr.ecr.us-west-1.amazonaws.com/kaizenplatform/kaizen-xxxxxxxx:947 \
-t 300

docker pushecs-deploy1









ecs-deploy 6


ALBECS ALB便

Dynamic Port Mapping

参考

Alpine LinuxなDockerイメージにServerspecを実行する環境を作った

TL;DR

  • Alpine LinuxなDockerイメージにServerspecを実行する環境をMacとCircleCI上に作った
  • CircleCI環境では lxc-attach コマンドが必要なので、spec_helper.rb で環境差を吸収するようにした
  • 今後よく利用しそうなので、流用しやすい形でGithubに置いておいた

前提


Kaizen Platform, Inc.Docker ImageAmazon LinuxAlpine Linux Alpine Linux@stormcat24

DockerServerspecsshdsshknife-solosshServerspec

Alpine Linuxknife-soloDockerfile (Dockerfile) knife-solosshdsshServerspecdocker-api 



Mac OS X  

ProductVersion: 10.11.6

Ruby 2.3.0

Docker 1.12.0
 


CircleCI  

Ruby 2.3.0

Docker 1.9.1-circleci-cp-workaround
 


serverspec 2.36.0

docker-api 1.31.0



1
2
3
4
5
6
7
8
9
10
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── circle.yml
└── spec
    ├── docker
    │   └── package_spec.rb
    └── spec_helper.rb

Gemfile

Gemfileを用意して bundle install

1
2
3
4
5
source 'https://rubygems.org'

gem 'rake'
gem 'serverspec'
gem 'docker-api'

Dockerfile

Dockerfileを用意。debugしやすいようにbashだけ導入

1
2
3
FROM alpine:3.4

RUN apk add --no-cache bash

tagは docker-alpine-serverspec-sample としてbuild。

1
docker build -t docker-alpine-serverspec-sample .

Serverspec各種ファイル

serverspec-init で各種ファイルを作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
⇒  serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 2

 + spec/
 + spec/localhost/
 + spec/localhost/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

生成されるsampleのテストは利用しないので削除

1
rm -rf spec/localhost

ローカル用の spec_helper.rb

1
2
3
4
5
6
7
8
9
require 'serverspec'
require 'docker'

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
image = Docker::Image.build_from_dir('.')
set :docker_image, image.id

Excon.defaults[:ssl_verify_peer] = false

テストファイルの追加

ディレクトリの作成し、Dockerfileのパッケージインストールに対応するテスト spec/docker/package_spec.rb を追加

1
mkdir -p spec/docker/
1
2
3
4
5
require 'spec_helper'

describe package('bash') do
  it { should be_installed }
end

Serverspecの実行

テストの準備が整ったので、Serverspecを流してみる。

1
bundle exec rake spec

問題がなければ下記のようになる。

1
2
3
4
5
Package "bash"
  should be installed

Finished in 1.61 seconds (files took 0.67509 seconds to load)
1 example, 0 failures

CircleCI上での実行

ローカルに続いて、CircleCI環境でも動くようにする。

circle.yml の用意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
machine:
  timezone: UTC
  ruby:
    version: 2.3.0
  services:
    - docker

dependencies:
  pre:
    - bundle install

test:
  pre:
    - docker version
    - docker info
    - docker build -t ${CIRCLE_PROJECT_REPONAME} . :
        timeout: 1200
    - docker run ${CIRCLE_PROJECT_REPONAME} &
    - sleep 5
  override:
    - bundle exec rspec
    - docker ps -a
    - docker images

CircleCI でも動くようにspec_helper.rbの修正

公式ドキュメント に記載されているようにCircleCIのDockerでは docker exec が利用できず、 lxc-attach コマンドを利用しないといけないので、spec_helper.rb でMacとの環境差を吸収し、同じコマンドでServerspecが流せるようにする。

元同僚の@ngs自身のブログに書いていたのでそれを利用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'serverspec'
require 'docker'

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
image = Docker::Image.build_from_dir('.')
set :docker_image, image.id

Excon.defaults[:ssl_verify_peer] = false

# https://circleci.com/docs/docker#docker-exec
if ENV['CIRCLECI']
  module Docker
    class Container
      def exec(command, opts = {}, &block)
        command[2] = command[2].inspect # ['/bin/sh', '-c', 'YOUR COMMAND']
        cmd = %Q{sudo lxc-attach -n #{self.id} -- #{command.join(' ')}}
        stdin, stdout, stderr, wait_thread = Open3.popen3 cmd
        [stdout.read, [stderr.read], wait_thread.value.exitstatus]
      end
      def remove(options={})
        # do not delete container
      end
      alias_method :delete, :remove
      alias_method :kill, :remove
    end
  end
end

これで、Mac上でもCircleCI上でも同じ

1
bundle exec rake spec

でテストが実行できるようになった。

↑の画像のように、イメージのサイズが非常に小さいAlpine Linuxに切り替えてからbuildもtestもすぐに完了するので生産性が高くなった。

参考

Mackerelのページを瞬時に開くAlfred Workflowを作った


Mackerel









AlfredWorkflow


glidenote/alfred-mackerel-page-workflow


使README ( bow)

関連