SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

開発現場からお届け! Wantedlyのプロダクトを育て、支える技術

オペレーションとルールを統一化し、Kubernetesを使った変化に強いインフラを構築

開発現場からお届け! Wantedlyのプロダクトを育て、支える技術 第2回

アプリケーション固有の方言をなくす

 Dockerとルールを決めることで、アプリケーション固有の方言をなくしていきます。コンテナは使用されるライブラリや言語などを1つのプロセスに内包します。そのため、中身がRuby、Go、Python、Java、C++、etc……と、どの言語で作られていたとしても、コンテナの利用者はあくまでもdocker runを実行するだけです。また、ホストのサーバーや他のアプリケーションとの依存関係をある程度排除するため、自分たちが欲しい環境を手に入れることができます。詳しくは、「Docker を Production で使い続ける理由(Wantedly Engineer Blog)」をご確認ください。

ルールを決める

 サービス数が50を超え、エンジニアの人数も増えた状況では、暗黙知のままセットアップ作業を実施してもすぐに破綻してしまいます。新しくチームに参加したエンジニアのモチベーションが一番高いgit cloneの直後に、セットアップが難しいようではやる気を失ってしまいます。こうしたケースをできる限り防ぐため、一定のルールを設けた上でコンテナ化させて立ち向かっています。

  • WebアプリケーションのヘルスチェックやステータスのURLは統一にする(/ping)
  • script/hogehogeで同じ方法で実行
    • script/ci-*はCI環境で実行される
    • script/k8s-*はKubernetes環境で実行される
    • それ以外は、ローカル環境で実行される
  • セットアップにはscript/bootstrapのスクリプトを使用する
  • サーバーの起動にはscript/serverのスクリプトを使用する

 このように、プロジェクトに後から加わるアプリケーションエンジニアもscript/hogehogeを確認するだけで基本を押さえることができます。

 また、READMEもかなりシンプルに保つことができます。

README.md
  myapp
  =================

  [![Build Status](https://travis-ci.org/koudaiii/myapp.svg?branch=master)](https://travis-ci.org/koudaiii/myapp)

  CodeZine Sample Application

  * [Requirement](#requirement)
  * [Usage](#usage)
  * [Deployment](#deployment)
     * [Console](#console)
     * [Migrate](#migrate)
     * [Cron](#cron)
  * [Author](#author)
  * [License](#license)

  Requirement
  -------------

  - homebrew
    - nodenv
    - rbenv
    - ruby-build
    - postgresql
    - docker
    - kubectl
    - minikube

  See `.ruby-version` and `.node-version` files for versions in use.

  Usage
  -------------

  - Bootstrap

  ```shell-session
  $ script/bootstrap

    CodeZine Sample Application

      開発者のための実装系Webマガジン

    + Environment variable file (.env) found.
    + nodenv found.
    + node 8.3.0 found.
    + yarn found.
    + Installing npm packages.
      > yarn install
    + npm packages installation completed.
    + PostgreSQL is running.
    + ruby 2.4.1 fonud.
    + Installing gems.
    + Gem installation completed.

    セットアップ完了

    Run 'script/server'
    And you can see 'open localhost:5000'
  ```

  - Run

  ```shell-session
  $ script/server
  ```

  `$ open http://localhost:5000`


  Deployment
  -------------

  - locally(Using Minikube)

  use https://github.com/kubernetes/minikube

  ```shell-session
  $ minikube status
  minikube: Stopped
  localkube:
  kubectl:

  $ minikube start
  Starting local Kubernetes v1.7.0 cluster...
  Starting VM...


  $ kubectl config current-context
  minikube
  ```

  ```shell-session
  # Create Namespace
  $ kubectl create -f kubernetes/namespace.yaml

  # Create nginx.conf
  $ kubectl create -f kubernetes/nginx-config.yaml

  # Create dotenv
  $ kubectl create -f kubernetes/dotenv.yaml

  # Create HorizontalPodAutoscaler
  $ kubectl create -f kubernetes/myapp-hpa.yaml

  # Create Service
  $ kubectl create -f kubernetes/myapp-svc.yaml

  # Create Database
  $ kubectl create -f kubernetes/db/
  service "postgres" created
  deployment "postgres" created

  # Create Deployment
  $ kubectl create -f kubernetes/myapp.yaml
  ```

  ```shell-session
  # Open Browser
  $ minikube service myapp -n myapp
  ```

  ### Console

  ```shell-session
  $ script/k8s-console
  ```

  ### Migrate

  ```shell-session
  $ script/k8s-migrate
  ```

  ### Cron

  ```shell-session
  $ kubectl create -f kubernetes/jobs/myapp-job.yaml
  cronjob "myapp-job" created

  $ kubectl get cronjob -n myapp
  NAME        SCHEDULE       SUSPEND   ACTIVE    LAST-SCHEDULE
  myapp-job   */15 * * * *   False     0         <none>
  ```

  Author
  -------------

  [@koudaiii](https://github.com/koudaiii)

  License
  -------------

  [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)

 今回は、OS Xを対象にscript/bootstrapで簡単なセットアップと実行環境のチェックを行い、script/serverを実行します。

#!/usr/bin/env bash
#
# bootstrap
#
# Get Ready to Develop CodeZine
set -eu
set -o pipefail

#
# Error
#
error_exit() {
  echo ""
  echo_red "  Fix the issue and run again."
  exit 1
}

echo_red() {
  RED="\033[0;31m"
  NC="\033[0m" # No Color
  echo -e "${RED}$1${NC}"
}

#
# Welcome To CodeZine Sample Application
#
echo ""
echo "  CodeZine Sample Application"
echo ""
echo "    開発者のための実装系Webマガジン"
echo ""

#
# Creating Environment Variable File
#
if test ! -f .env
then
  echo "  + Creating .env"
  cp .env.sample .env
else
  echo "  + Environment variable file (.env) found."
fi

#
# Check for nodenv
#
if test ! $(which nodenv)
then
  echo "  + Installing nodenv..."
  brew install node-build nodenv
else
  echo "  + nodenv found."
fi

#
# Check for Node
#
NODE_VERSION=$(cat .node-version 2>/dev/null)
if node --version | grep $NODE_VERSION > /dev/null 2>&1
then
  echo "  + node $NODE_VERSION found."
else
  echo_red "  x node $NODE_VERSION required."
  echo "    To install with nodenv"
  echo "    $ nodenv install $NODE_VERSION"
  nodenv install $NODE_VERSION
fi

#
# Check for yarn
#
if test ! $(which yarn)
then
  echo "  + Installing yarn..."
  npm install yarn
else
  echo "  + yarn found."
fi

#
# Install NPM packages
#
echo "  + Installing npm packages."
echo "    > yarn install"
if ERROR=`yarn install 2>&1`
then
  wait
  echo "  + npm packages installation completed."
else
  wait
  echo_red "  x npm packages installation failed."
  echo $ERROR
  error_exit
fi

#
# Check for Postgres
#
postgres_is_running() {
  ps aux | grep -v "grep" | grep "postgres" > /dev/null 2>&1
}
if postgres_is_running
then
  echo "  + PostgreSQL is running."
else
  echo_red "  x PostgreSQL not found"
  echo "    Follow this instruction:"
  echo "      http://postgresapp.com"
  error_exit
fi

#
# Creating for Ruby
#
RUBY_VERSION=`cat .ruby-version`

if rbenv versions | grep $RUBY_VERSION > /dev/null 2>&1
then
  echo "  + ruby $RUBY_VERSION fonud."
else
  if rbenv install --list | grep $RUBY_VERSION > /dev/null 2>&1
  then
    echo "    > ruby-build can build ruby $RUBY_VERSION"
  else
    echo "    > brew upgrade ruby-build"
    brew upgrade ruby-build
  fi

  echo "    > ruby install $RUBY_VERSION"
  rbenv install $RUBY_VERSION

  echo "    > bundler install"
  gem install bundler
fi

#
# Install Gems
#
echo "  + Installing gems."
if ERROR=`bundle install --quiet --jobs=4 --without production qa 2>&1`
then
  wait
  echo "  + Gem installation completed."
else
  wait
  echo_red "  x Gem installation failed."
  echo $ERROR
  error_exit
fi

#
# Startup instructions
#
echo ""
echo "  セットアップ完了"
echo ""
echo "  Run 'script/server'"
echo "  And you can see 'open localhost:5000'"
echo ""

exit 0

 script/bootstrapを実行すると、アプリケーションを起動するためのミドルウェアのセットアップが行われます。

$ script/bootstrap

  CodeZine Sample Application

    開発者のための実装系Webマガジン

  + Environment variable file (.env) found.
  + nodenv found.
  + node 8.3.0 found.
  + yarn found.
  + Installing npm packages.
    > yarn install
  + npm packages installation completed.
  + PostgreSQL is running.
  + ruby 2.4.1 fonud.
  + Installing gems.
  + Gem installation completed.

  セットアップ完了

  Run 'script/server'
  And you can see 'open localhost:5000'
#!/bin/bash -x

set -e

bundle exec foreman start

 フロントエンドとしてWebpackのサーバーを、バックエンドとしてRailsのサーバーをそれぞれ起動する必要があります。複数のプロセスを一度に制御できるForemanを利用し、script/serverではこのForemanを呼び出すだけにしています。Foremanは、Procfileというファイルを元にプロセスを起動させます。

rails: bundle exec puma -C config/puma.rb
webpack: bin/webpack-dev-server

次のページ
Kubernetesのマニフェストの解説

この記事は参考になりましたか?

開発現場からお届け! Wantedlyのプロダクトを育て、支える技術連載記事一覧

もっと読む

この記事の著者

坂部 広大(Wantedly, inc.)(サカベ コウダイ)

 Wantedlyの基盤改善および保守運用をしているインフラエンジニア。ツールを作ったり、Web Applicationを作ったり、社内情報システムの整備をしたりしています。 WANTEDLY TECH BOOKを書いています。 Site Twitter Facebook Github Wantedly Engineers Blog

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10428 2017/09/29 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー