Ansibleおよびリバースプロキシサーバー





約6か月前、多くのノード(n> 20)から複数(n <= 3)のバトルサーバーまで、リバースプロキシサイトのスキームを開発する必要がありました。 最近、同僚からの同様のリクエストで遭遇しました。 したがって、私は共有し、記事にすべてをまとめることにしました。



記事レベルは初心者向けです。



その結果、新しいノードを追加してドメインのリストを更新するためのシンプルなツールが必要でした。 このようなソリューションからの利益は、サーバーでキャッシュを使用する場合と、ジオロケーションを使用するDNSである必要があります。



リバースプロキシトピックに関する情報の検索は、多くの場合、「nginx to apache」(ローカルapacheまたはリモートアップストリームサーバー)、CDNプロキシサービス(cloudflare、* cdn、cloudfrontなど)の設定に関する記事に由来します。 この場合、これは完全に適切ではありませんでした。

その特徴は、1つまたは2つのサーバーのドメインに(地理的に異なる場所から)多くの異なるIPを提供する必要があることにあります。



この問題を解決するために、必要な異なる場所でいくつかのVPSを購入しました(安い、lowendbox.comとlowendstock.comのおかげですが、必要なベンドウィッチ付き)。 VPSはこれまでCentos-6-x32で使用されていましたが、epelがCentos-7 32-bitのパッケージを展開するとすぐに更新されます。 他のすべてのサーバー操作は、ansibleを使用してリモートで実行されます。



Ansibleプロジェクトの構造



受け入れられている慣行に従って、次のファイル構造があります。



$ find -type f ./roles/update_os/tasks/main.yml ./roles/update_nginx_configs/tasks/main.yml ./roles/update_nginx_configs/files/proxy.conf ./roles/update_nginx_configs/templates/domain.conf.j2 ./roles/update_nginx_configs/handlers/main.yml ./roles/update_hostname/tasks/main.yml ./ansible.cfg ./hosts ./proxy-nodes.yml
      
      



すべてのファイルを見ていきましょう。

./hosts
 [test] localhost ansible_connection=local [centos:children] proxy-nodes [proxy-nodes] xxx.xxx.xxx.xxx ansible_connection=ssh ansible_ssh_user=root ansible_ssh_pass=xxxxxx node_hostname=proxy-node-001.www.co yyy.yyy.yyy.yyy ansible_connection=ssh ansible_ssh_user=root ansible_ssh_pass=yyyyyy node_hostname=proxy-node-010.www.co zzz.zzz.zzz.zzz ansible_connection=ssh ansible_ssh_user=root ansible_ssh_pass=zzzzzz node_hostname=proxy-node-029.www.co
      
      





ここでは、メタグループ[centos]が表示され、グループ[proxy-nodes]は[centos]の子グループとして個別に示されます。

役割とタスクを拡張するために設計された構造。



./ansible.cfg
 [defaults] pipelining = True hostfile = hosts [ssh_connection] ssh_args = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s control_path = ~/.ansible/cp/ansible-ssh-%%h-%%p-%%r
      
      







ここでも特別なことは何もありません。 サーバー構成はrootユーザーから行われるため、パイプラインを安全に有効にできます。



hostfile-コンソールでの作業時に入力パラメーターを減らすため、

ssh_args-ホストのリロードの対話性を減らし、永続的な接続を構成するために、最も重要なのはControlPathです。



ControlPath-一度見たほうが良い
$ Sshの-oのControlMaster =自動-o ControlPersist = 60年代-o UserKnownHostsFile =を/ dev / null -o StrictHostKeyChecking =なし-o IdentitiesOnly = yesの-o ControlPath =を/ tmp / habr.socket root@192.168.124.185

警告:既知のホストのリストに「192.168.124.185」(RSA)を永続的に追加しました。

root@192.168.124.185のパスワード:

最終ログイン:木3月10日22:46:41 2016

[root @ test001〜]#service sshd stop

sshdの停止:[OK]

[root @ test001〜]#終了

ログアウト

192.168.124.185への共有接続が閉じられました。

$ ssh -o ControlPath = / tmp / habr.socket root@192.168.124.185

最終ログイン:2016年3月10日木曜日22:48:12から192.168.124.1

[root @ test001〜]#終了

ログアウト

192.168.124.185への共有接続が閉じられました。

$ ssh root@192.168.124.185

ssh:ホスト192.168.124.185ポート22に接続:接続が拒否されました

$ ssh -o ControlPath = / tmp / habr.socket root@192.168.124.185

最終ログイン:木3月10日22:48:47 2016から192.168.124.1

[root @ test001〜]#service sshd start

sshdの開始:[OK]

[root @ test001〜]#終了

ログアウト

192.168.124.185への共有接続が閉じられました。

$ ssh root@192.168.124.185

警告:既知のホストのリストに「192.168.124.185」(RSA)を永続的に追加しました。

root@192.168.124.185のパスワード:



これにより、accelerate:trueオプションよりも高速に作業できます。 かかわらずドキュメント 、CentOSに6がすでにすっごく長かった ControlPersistで正しく動作し、以前に行ったように、このようpreinstallaを必要としません。



例./prepare-accelerate.ymlでノードを準備し、加速する:プレイブックのtrueオプション./proxy-nodes.yml
 --- - hosts: centos tasks: - name: install EPEL yum: name=epel-release - name: install keyczar yum: name=python-keyczar
      
      







次に、ロールとupdate_osタスクを使用する場合の標準的なプレイブック:



./proxy-nodes.yml
 --- - hosts: proxy-nodes roles: - update_hostname - update_os - update_nginx_configs
      
      







./roles/update_os/tasks/main.yml
 --- - name: repo install EPEL yum: name=epel-release - name: repo install nginx-release-centos-6 yum: state=present name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm - name: packages install some yum: name={{ item }} with_items: - nginx - yum-update - name: packages upgrade all yum: name=* state=latest
      
      







これらのファイルはコメントする必要がないと思います。



ロールupdate_hostname



たまたまノードに名前が付けられているのは偶然です。 ご覧のとおり、hostsファイルには、node_hostnameパラメーターが指定されています。 残念ながら、ansibleはFQDNに応じてホスト名を変更することはまだできないので、あなたは助けなければなりません:



./roles/update_hostname/tasks/main.yml
 --- - name: set hostname hostname: name={{ node_hostname }} - name: add hostname to /etc/hosts lineinfile: dest=/etc/hosts regexp='.*{{ node_hostname }}$' line="{{ ansible_default_ipv4.address }} {{ node_hostname }}" state=present create=yes when: ansible_default_ipv4.address is defined
      
      







現在、ホスト名-fは宣誓しません。つまり、このようなチェックは一部のコントロールパネルに存在します。



ロールupdate_nginx_configs



最後の役割はupdate_nginx_configsです。 ここでは、nginx relodのハンドラーについて説明します。



./roles/update_nginx_configs/handlers/main.yml
 --- - name: reload nginx service: name=nginx state=reloaded
      
      







次のファイルは、httpセクションにキャッシュゾーンを作成し、プロキシ用の将来のドメインを含みます。



./roles/update_nginx_configs/files/proxy.conf
 proxy_cache_path /tmp levels=1:2 keys_zone=PROXY:10m inactive=24h max_size=4g use_temp_path=off; include /etc/nginx/conf.d/proxy/*.conf;
      
      







ドメインのテンプレートは次のようなものです。



./roles/update_nginx_configs/templates/domain.conf.j2
 server { listen {{ ansible_default_ipv4.address }}:80; server_name {{ item.domain }} www.{{ item.domain }}; access_log /var/log/nginx/{{ item.domain }}.access.log main ; error_log /var/log/nginx/{{ item.domain }}.error.log; location / { proxy_pass http://{{ item.remoteip }}:80/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; proxy_connect_timeout 90; proxy_cache PROXY; proxy_cache_valid 200 302 1d; proxy_cache_valid 404 30m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; } }
      
      







ここで特別なことはありません。プロジェクトに対してプロキシとキャッシュの設定が選択されています。 動的パラメーターの中には、ansible_default_ipv4.address、item.domain、item.remoteipの3つしかありません。 最後の2つがどこから来たかは、次のファイルから見ることができます。



./roles/update_nginx_configs/handlers/main.yml
 --- - name: create non existing dir /etc/nginx/conf.d/proxy/ file: path=/etc/nginx/conf.d/proxy/ state=directory mode=0755 - copy: src=proxy.conf dest=/etc/nginx/conf.d/ owner=nginx group=nginx backup=yes - name: re-create domain templates template: src=domain.conf.j2 dest=/etc/nginx/conf.d/proxy/{{ item.domain }}.conf owner=nginx group=nginx backup=yes with_items: - { domain: 'nginx.org' , remoteip: '206.251.255.63' } - { domain: 'docs.ansible.com', remoteip: '104.25.170.30' } notify: reload nginx - name: validate nginx conf command: nginx -t changed_when: false
      
      







最後の手順は次のとおりです。ドメインのディレクトリが存在することを確認し、キャッシュゾーン設定で構成を更新し、with_itemsを使用してサイクル内のすべてのドメインとリモートのペアを調べ、構成を再作成しました。



最後の手順は、構成を検証することです。結果が成功した場合は、nginxの再読み込みハンドラーが起動します。 残念ながら、この検証は、テンプレートの生成時またはproxy.conf構成のコピー時に使用できません。



オプションvalidate = "nginx -t -c%s"、さらにvalidate = "nginx -t -c /etc/nginx/nginx.conf -p%s"は、httpd.confを構成する場合ほど適切ではありません。



行こう!



「ドメインテンプレートの再作成」タスクでドメインのリストを更新または変更する場合、以下を実行します。

ansible-playbook proxy-nodes.yml


追加パラメーターなし。 新しいノードを追加した後、次のコマンドを実行する必要があります。

ansible-playbook proxy-nodes.yml --limit = bbb.bbb.bbb.bbb


新しいノードのIPを指定する場所。



おわりに



Googleに尋ねたところ、ホスティングプロバイダーから同様のサービスについての応答がありませんでした。 ただし、CEOからさまざまなアダルトWebマスターまで、対象読者は大きく異なる場合があります。



したがって、調査の下。



All Articles