ソルトでデプロイする



これまで、多くの企業で展開すると大きな問題が発生し、数日、数週間、特に無視された場合は数か月かかることがあります。 しかし、状況は絶望的ではありません。 この困難な作業に役立つツールと実践が数多くあります。 しかし、これらのツールはほとんどの場合1〜2日で習得されず、締め切りが迫っています。



あなたは通常何が欲しいですか:



これはすべて、Djangoプロジェクトの例について、Salt + Vagrantの束で実現します。 しかし、Pythonだけでなく他の言語でも、ほとんどの手法は開発者に役立ちます。





ソースへのリンクをすぐに提供します: bitbucket.org/awnion/salt-django-deploy



ソルトとは?



Saltに精通している場合は、このセクションをスキップできます。



Saltはクラスター管理(クラスターオーケストレーション)のための非常に強力なツールですが、私の個人的な意見では、1台のマシンで使用しても十分に正当化され、過剰になりません(大まかに言うと、チームに1人の開発者しかいなければ、これは使用すべきではありませんバージョン管理システム)。



ソルト状態は、マシンがどの状態にあるべきかを記述するsls拡張子を持つYAMLファイルです。 たとえば、このファイルはここにある必要があり、このサービスは起動されている必要があり、このユーザーはそのような権限を持っている必要があります。 Saltでは、システムユーティリティ(apt、rpm、cron、initスクリプト、さまざまな構成)の状態を維持できるだけでなく、たとえば、そのようなユーザーがRabbitMQに存在するかどうか、最新バージョンのgitリポジトリ、すべてのパッケージが存在するかどうかを確認できますvirtualenvなど。 条件の完全なリストは、ここdocs.saltstack.com/ref/states/allにあり、私の意見では非常に印象的です。



塩に関するいくつかの事実






開発設定



私の意見では、優れた便利な開発環境の重要性を過大評価することは困難です。 ただし、「すべてを自分用に」設定するには、数日または1週間かかる場合があります。 これらの日を将来同僚に保存し、1つのコマンドでプロジェクトの現在のバージョンを上げることができる構成を作成しましょう。

git clone <repo_url> && cd <repo_name> && vagrant up
      
      





さて、これは実際には3つのチームですが、もっと簡単にできるなら-私はあなたの手を振る。



したがって、 Vagrantで dev構成を構築します(Vagrantに精通していない人のために、お会いすることを強くお勧めします)。

 mkdir my_app && cd my_app git init vagrant init
      
      





Vagrantのgitリポジトリと設定がmy_appフォルダーに表示されました。



次に、 Vagrantfileの内容を次のものに置き換えます。

 Vagrant.configure("2") do |config| config.vm.box = "precise64" config.vm.hostname = "dev-my-app" config.vm.network :private_network, ip: '3.3.3.3' config.vm.synced_folder "salt/roots/salt", "/srv/salt/" config.vm.synced_folder "salt/roots/pillar", "/srv/pillar/" config.vm.provision :salt do |salt| salt.minion_config = "salt/minion" salt.run_highstate = true end end
      
      







この構成では、Ubuntuでゲストマシンを作成できます。ホスト名とIPを設定する構成で、どのフォルダーを同期するかを決定し、saltを使用してマシンを目的の状態にすることを示しました(ところで、プロジェクトのルートはデフォルトになりますゲストマシンの/ vagrantフォルダーと同期されます)。



ここで何が起こっているかについて詳しく知ることができます



これで、状態を説明する準備が整いました。 次の内容のソルト/ミニオンファイルを作成します。

 file_client: local
      
      







実際、このマシンはその状態自体を保存すると言います。 デフォルトでは、saltはマスターサーバーから状態ファイルを取得するように構成され、ローカルでは/ var / cache / saltのどこかにのみキャッシュします。 したがって、カスタムが必要ない場合は、prodマシン上のこのファイルはほとんど必要ありません。



次に、2つのフォルダーを作成します。

 mkdir -p salt/roots/pillar mkdir -p salt/roots/salt
      
      





最初の変数はさまざまな変数を格納し、2番目の変数はゲストマシンの状態フォルダーです。



ファイルsalt / roots / salt / top.slsを作成します

 base: 'dev-my-app': - nginx - python - supervisor
      
      







ご想像のとおり、slsはyamlに非常に似ています。 しかし、ここでの主な違いは、slsはすべての結果を伴うjinjaテンプレートでもあることです(後で実際にメリットがあることがわかります)。



baseは、仮想クラスターの状態構成の名前です。 dev-my-appは、ゲストマシンのホスト名です。 ここでは、パターンマッチングが使用されます。つまり、「dev- *」を指定できます。以下のすべての状態は、dev-alpha、dev-foobarなどのすべてのマシンに適用されます。 以下は、説明する必要がある州のリストです。



python、nginx、supervisorの宣言された状態を作成します。



salt / roots / salt / python.sls

 #    ,   python  python-virtualenv # ,    --      python: pkg: - installed - names: - python - python-virtualenv
      
      







salt / roots / salt / nginx.sls

 #    nginx     ,   require # ,   service     pkg nginx: pkg: - installed service: - running - reload: True #   reload - require: - pkg: nginx
      
      







salt / roots / salt / Supervisor.sls

 supervisor: pkg: - installed service: - running - require: - pkg: supervisor
      
      







そのため、「 vagrant up 」をすでに実行できます。 この手順では、Ubuntuイメージをダウンロードし(イメージキャッシュにまだない場合)、そこにsaltをインストールし、状態の同期を開始します。

これで、ゲストマシンにpython、supervisor、nginxができました。

vagrant sshを介してマシンにアクセスするか、 3.3.3.3にアクセスして確認できます。



これまでのところ、すべてがシンプルに思えます。 続ける:



柱変数を作成します。



塩/根/柱/top.sls

 base: 'dev-my-app': - my-app
      
      







塩/根/柱/ my-app.sls

 my_app: gunicorn_bind: 127.0.0.1:8000 dns_name: dev.my-app.com venv_dir: /home/vagrant/my_app_env work_dir: /vagrant
      
      





最初のファイルは、dev-my-appホストにmy-app configから変数が割り当てられていることを示しています。 2番目のファイルは、実際の変数そのものです。



次に、Djangoアプリケーションの構成状態用のフォルダーを作成します。

 mkdir -p salt/roots/salt/my_app
      
      







salt / roots / salt / my_app / init.sls

 {% set my_app = pillar['my_app'] %} my_app.venv: virtualenv.managed: - name: {{ my_app['venv_dir'] }} - system_site_packages: False - require: - pkg: python my_app.pip: pip.installed: - bin_env: {{ my_app['venv_dir'] }} - names: - Django==1.6 - gunicorn==18.0 - require: - virtualenv: my_app.venv my_app.nginx.conf: file.managed: - name: /etc/nginx/sites-enabled/my_app.conf - source: salt://my_app/nginx.my_app.conf - context: #    pillar,        bind: {{ my_app['gunicorn_bind'] }} dns_name: {{ my_app['dns_name'] }} - template: jinja - makedirs: True - watch_in: - service: nginx my_app.supervisor.conf: file.managed: - name: /etc/supervisor/conf.d/my_app.conf - source: salt://my_app/supervisor.my_app.conf - context: app_name: my_app bind: {{ my_app['gunicorn_bind'] }} gunicorn: {{ my_app['venv_dir'] }}/bin/gunicorn directory: {{ my_app['work_dir'] }} workers: {{ grains['num_cpus'] * 2 + 1 }} #     - template: jinja - makedirs: True my_app.supervisor: supervisord.running: - name: my_app - watch: - file: my_app.supervisor.conf - require: - pip: my_app.pip - pkg: supervisor
      
      







ヒント :依存関係、require、watchなどを構築する場合、状態はランダムな順序でチェックされることに注意してください。 この記事を作成するとき、私はこの種の間違いを犯しました。djangoおよびgunicornパッケージは、まだ作成されていないvirtualenvにインストールしようとしました。



salt / roots / salt / my_app / nginx.my_app.conf

 server { listen 80; server_name {{ dns_name }} _; location / { proxy_pass http://{{ bind }}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
      
      







salt / roots / salt / my_app / supervisor.my_app.conf

 [program:{{ app_name }}] command={{ gunicorn }} {{ app_name }}.wsgi:application -b {{ bind }} -w {{ workers }} directory={{ directory }} user=nobody autostart=true autorestart=true redirect_stderr=true
      
      







新しく作成された状態をsalt / roots / salt / top.slsに追加します

 base: 'dev-my-app': - nginx - python - supervisor - my_app # <----
      
      







ほぼ完了です。 しかし、最も重要なことはありません-架空のDjangoアプリケーションのコードです。 次のように空のテストDjangoプロジェクトを作成しましょう。

 vagrant provision
      
      







このプロセスには数分かかります(ほとんどの場合、djangoとgunicornはvirtualenvにインストールされます)。



プロビジョニングが機能したら、ゲストマシンに移動します。

 vagrant ssh
      
      







内部では次のことを行います。

 /home/vagrant/my_app_env/bin/django-admin.py startproject my_app /vagrant exit
      
      







また、ホストマシンでvagrant provisionを実行し、hostsファイルですべてが機能することを確認するために、一時的にメモします。

 dev.my-app.com 3.3.3.3
      
      







ブラウザーでdev.my-app.comにアクセスすると、すべてがうまくいけば、うまくいきました!



開発構成が構築されます。 コミットできます。



友人にプロジェクトで遊びを与えたい場合、彼はgit clonevagrant upを行うだけです。 さらに、この架空の友人は、プロジェクト自体のソースコードを受け取るだけでなく、それがどのように展開されるかについてのアイデアも持っています。



とりわけ、デフォルトでは、プロジェクトはgunicorn +スーパーバイザーの制御下で独立してスピンします。 しかし、リモートでリモートにしたい場合や、お気に入りのオートリロードコードの変更を返したい場合はどうでしょうか? 質問なし:

 vagrant ssh supervisorctl stop my_app /home/vagrant/my_app_env/bin/python /vagrant/manage.py runserver
      
      







これでコードを安全に編集でき、すべての変更がdjangoサーバーに自動的に反映されます。

また、ホストが一時的に調整されている場合、同じdjangoサーバーがdev.my-app.comからのリクエストに応答します。



製品構成



それで、最も重要なことに到達しました。 prod-my-appにデプロイすることを想定しています。



次に、salt-master(以下、単にマスター)用に別のサーバーがある状況での展開オプションを検討します。



マスター構成にコピーし、 / srv / salt / top.slsに追加します

  'prod-my-app': - nginx - python - supervisor - my_app
      
      







または、私たちの場合、これを行うことができます:

 base: '*-my-app': - nginx - python - supervisor - my_app
      
      







次に、 / srv / pillar / top.slsファイルで同じことを行います

 base: '*-my-app': - my-app
      
      







/srv/pillar/my_app.slsでは 、レイアウトマップに従って変数を変更します。



prod-my-appでsalt-minionを設定します。 ソルトミニオンをソルトマスターに接続します (実行方法はこちらをご覧ください)。

ウィザードで、構成のアプリケーションを開始できます。

 sudo salt prod-my-app state.highstate
      
      







残っているもの:


マスターへの構成の配信


rsyncからgitへの方法はたくさんあります。 それはすべてあなたの国内政策に依存します。



prod-my-appへのプロジェクトソースの配信


ここでも、多くのオプションがあります。 個人的には、私はこれを行います:saltをprod-my-appでサポートし、ハッシュがピラーに保存されている特定のコミットでgitリポジトリをサポートします。変更された場合、saltは作業の最後にデプロイメントスクリプトを実行します。



正直なところ、これは最良の方法ではありませんが、最も簡単な方法です。 理想的には、たとえばネイティブパッケージを作成するか、プライベートpypiを作成します。



参照資料



www.saltstack.com

www.vagrantup.com

hynek.me/talks/python-deploymentsは、Pythonプロジェクトのデプロイメントに関する要約のセットを含む非常に役立つ記事です。



PS

残念なことに、多くのことを逃さなければなりませんでした。さもないと、記事が途方もなく大きなサイズに膨らんでしまいます。 明らかなもの、またはドキュメントで見つけやすいものを見逃そうとしました。 ただし、コメントで質問してください。



All Articles