Proxyが存在する環境でkolla-ansibleを使ってOpenStackのAll-in-Oneマシンを作成してみた

## はじめに
この記事では、Proxy環境下でkolla-ansibleを使ったOpenStackのAll-in-Oneマシンを作成するにあたっての留意点をまとめています。

kolla-ansibeを使ったOpenStackの作成方法は、ググると色々出てきますが、いずれもProxyのない環境での構築をベースにしているように見えます。Proxy環境下での作成は大変骨が折れますし、意味不明なエラーが出力されて断念された方(犠牲者)も多いのではないかと感じていました。今回、大いにはまりつつもProxy環境下で作成することができたので、備忘として情報を残しておきたいと思います。  

## 前提
前提として、ここで作成したAll-in-Oneマシンは検証などのテスト用途で作成したものであります。本番環境での利用を想定していないので、あくまで参考手順として利用下さい.


  
簡単ですが、作成環境は以下の通りです。
・サーバー(VM) : 12vCPU / 16GB Mem / 900GB HDD / 2vNIC (VMware ESXi6台上で作成)
・OS : ubuntu 20.4 LTS (枝番なし。20.4.xでは未実施)
・kolla-ansible : 12.3.1.dev46
・OpenStack Release : wallaby  

<font color="Red">(02/12/2022更新) OpenStack Xenaでも同手順となることを確認済</font>

## 手順  
Proxy環境下での構築における重要ポイントだけ列挙していきます。
基本的な作成方法は、[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/) を参考として下さい。

### 1. ubuntu OSへのProxy設定
まず、ubuntuの初期インストール時にProxy設定が行えますので、そちらにProxy設定を入れます。これをやっておくと、aptが通るようになります。当然ながら、Proxyサーバのドメイン名で設定する場合は、インターフェースのIPアドレス登録画面にてDNSサーバのIPアドレスの登録も必要になります。

```
[http or https]://[ユーザー名]:[パスワード]@[Proxyサーバのドメイン名 or IPアドレス]:[ポート番号]

【サンプル】
http://proxy.sample.com:8080
※ユーザー名、パスワード、ポート番号は利用環境毎にあったりなかったりだと思います。
```

### 2. pipへのProxy設定

次に、[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04 - Creating python virtual environment](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/#:~:text=gcc%20libssl%2Ddev-,Creating%20python%20virtual%20environment,-To%20avoid%20conflicts) 手順の実行前に、`/etc/pip.conf`を作成し、下記のProxy設定を書き込みます。

```
[global]
proxy = [http or https]://[ユーザー名]:[パスワード]@[proxyサーバのドメイン名 or IPアドレス]:[ポート番号]
※ユーザー名、パスワード、ポート番号は利用環境毎にあったりなかったりだと思います。
```

### (任意) gitへのProxy設定

`pip install kolla-ansible` でkolla-ansibleをインストールすると、最新のリリースがインストールされます。`pip install git+https://opendev.org/openstack/kolla-ansible@stable/[ブランチ名]` などで、最新以外のリリースをインストールしたい場合は、下記コマンドを実行してgitにもProxyを設定します。

```
$git config --global http.proxy [http or https]://[ユーザー名]:[パスワード]@[proxyサーバのドメイン名 or IPアドレス]:[ポート番号]
$git config --global https.proxy [http or https]://[ユーザー名]:[パスワード]@[proxyサーバのドメイン名 or IPアドレス]:[ポート番号]
※ユーザー名、パスワード、ポート番号は利用環境毎にあったりなかったりだと思います。
```

### 3. pre-install.ymlへのProxy設定

[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04 - Deployment](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/#:~:text=exp%3A~%24%20kolla%2Dgenpwd-,Deployment,-When%20the%20configuration) 手順の実行前に、Ansible Playbook内に下記「★」付き行の追加が必要です。対象ファイルは、基本的な作成手順の通りに作成した場合は`~/wallaby/share/kolla-ansible/ansible/roles/baremetal/tasks/pre-install.yml`となります。

```
110         - name: Install docker apt gpg key
111           environment: ★
112             http_proxy: [http or https]://[ユーザー名]:[パスワード]@[proxyサーバのドメイン名 or IPアドレス]:[ポート番号]　★
113             https_proxy: [http or https]://[ユーザー名]:[パスワード]@[proxyサーバのドメイン名 or IPアドレス]:[ポート番号]　★
114           apt_key:
115             url: "{{ docker_apt_url }}/{{ docker_apt_key_file }}"
116             id: "{{ docker_apt_key_id }}"
117             state: present
118           become: True
```


これをやらないと、`kolla-ansible -i /etc/kolla/all-in-one bootstrap-servers` の実行時に下記のようなエラーが出ます。

```
TASK [baremetal : Install docker apt gpg key] **********************************************************************************************************************************************************
[0;31mfatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to download key at https://download.docker.com/linux/ubuntu/gpg: Request failed: <urlopen error timed out>"} [0m
```

### 4. dockerへのProxy設定

[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04 - Deployment](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/#:~:text=exp%3A~%24%20kolla%2Dgenpwd-,Deployment,-When%20the%20configuration) 手順の`kolla-ansible -i /etc/kolla/all-in-one deploy`コマンドの実行直前で、dockerへProxy設定を行います。手順は[「ubuntu 20.04.1 上でプロキシ環境でdocker を利用する」](https://qiita.com/m-tmatma/items/5718ac5294e6acc61908) が参考になります。

これをやらないと、`kolla-ansible -i /etc/kolla/all-in-one deploy`の実行時に下記のようなエラーが出ます。
(これがProxyのせいだと気が付くまでにとても時間がかかりました・・・)

```
TASK [common : Ensure fluentd image is present for label check] ****************************************************************************************************************************************
[1;30mtask path: /home/xxxxx/wallaby/share/kolla-ansible/ansible/roles/common/tasks/config.yml:26[0m
[0;34mUsing module file /home/xxxxx/wallaby/share/kolla-ansible/ansible/library/kolla_docker.py[0m
[0;34mPipelining is enabled.[0m
[0;34m<localhost> ESTABLISH LOCAL CONNECTION FOR USER: xxxxx[0m
[0;34m<localhost> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-bawiyztivrzsmtncvhvtgpoohrmozoga ; /usr/bin/python3'"'"' && sleep 0'[0m
[0;31mThe full traceback is:[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 1241, in main[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 1116, in ensure_image[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 691, in pull_image[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/api/image.py", line 430, in pull[0m
[0;31m    self._raise_for_status(response)[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/api/client.py", line 270, in _raise_for_status[0m
[0;31m    raise create_api_error_from_http_exception(e)[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/errors.py", line 31, in create_api_error_from_http_exception[0m
[0;31m    raise cls(e, response=response, explanation=explanation)[0m
[0;31mfatal: [localhost]: FAILED! => {[0m
[0;31m    "changed": true,[0m
[0;31m    "invocation": {[0m
[0;31m        "module_args": {[0m
[0;31m            "action": "ensure_image",[0m
[0;31m            "api_version": "auto",[0m
[0;31m            "auth_email": null,[0m
[0;31m            "auth_password": null,[0m
[0;31m            "auth_registry": null,[0m
[0;31m            "auth_username": null,[0m
[0;31m            "cap_add": [],[0m
[0;31m            "cgroupns_mode": null,[0m
[0;31m            "client_timeout": 120,[0m
[0;31m            "command": null,[0m
[0;31m            "detach": true,[0m
[0;31m            "dimensions": {},[0m
[0;31m            "environment": {[0m
[0;31m                "KOLLA_CONFIG_STRATEGY": "COPY_ALWAYS"[0m
[0;31m            },[0m
[0;31m            "graceful_timeout": 10,[0m
[0;31m            "healthcheck": null,[0m
[0;31m            "ignore_missing": false,[0m
[0;31m            "image": "kolla/ubuntu-source-fluentd:wallaby",[0m
[0;31m            "labels": {},[0m
[0;31m            "name": null,[0m
[0;31m            "privileged": false,[0m
[0;31m            "remove_on_exit": true,[0m
[0;31m            "restart_policy": "unless-stopped",[0m
[0;31m            "restart_retries": 10,[0m
[0;31m            "security_opt": [],[0m
[0;31m            "state": "running",[0m
[0;31m            "tls_cacert": null,[0m
[0;31m            "tls_cert": null,[0m
[0;31m            "tls_key": null,[0m
[0;31m            "tls_verify": false,[0m
[0;31m            "tmpfs": null,[0m
[0;31m            "tty": false,[0m
[0;31m            "volumes": null,[0m
[0;31m            "volumes_from": null[0m
[0;31m        }[0m
[0;31m    },[0m
[0;31m    "msg": "'Traceback (most recent call last):\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/client.py\", line 268, in _raise_for_status\\n    response.raise_for_status()\\n  File \"/usr/lib/python3/dist-packages/requests/models.py\", line 940, in raise_for_status\\n    raise HTTPError(http_error_msg, response=self)\\nrequests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/v1.41/images/create?tag=wallaby&fromImage=kolla%2Fubuntu-source-fluentd\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \"/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 1241, in main\\n  File \"/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 1116, in ensure_image\\n  File \"/tmp/ansible_kolla_docker_payload_b9_nm8n4/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 691, in pull_image\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/image.py\", line 430, in pull\\n    self._raise_for_status(response)\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/client.py\", line 270, in _raise_for_status\\n    raise create_api_error_from_http_exception(e)\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/errors.py\", line 31, in create_api_error_from_http_exception\\n    raise cls(e, response=response, explanation=explanation)\\ndocker.errors.APIError: 500 Server Error for http+docker://localhost/v1.41/images/create?tag=wallaby&fromImage=kolla%2Fubuntu-source-fluentd: Internal Server Error (\"Get \"https://registry-1.docker.io/v2/\": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)\")\\n'"[0m
[0;31m}[0m
```

### 5. Docker Hub の Rate Limit 回避

必要なProxy設定は以上となりますが、Docker Hub の Rate Limit によってこれでもまだエラーが出てしまいます。
[Kolla Ansible deploying OpenStack wallaby on Ubuntu 20.04 - Deployment](https://foofunc.com/kolla-ansible-deploying-openstack-wallaby-on-ubuntu-20-04/#:~:text=exp%3A~%24%20kolla%2Dgenpwd-,Deployment,-When%20the%20configuration) 手順の`kolla-ansible -i /etc/kolla/all-in-one deploy`コマンドの実行直前に、[Dockerの公式サイト](https://www.docker.com/)へアクセスし、ユーザーアカウントを作成します。その後、ubuntu上で下記コマンドを実行し、ubuntuマシンがDocker Hubへログインしている状態にします。

```
sudo docker login --username=[Docker Hubで作成したユーザー名]
Password: [Docker Hubで作成したユーザー名のパスワード]
```

Docker Hubへログインしていない場合、下記のようなエラーが出ます。

```
TASK [common : Ensure fluentd image is present for label check] ****************************************************************************************************************************************
[1;30mtask path: /home/xxxxx/wallaby/share/kolla-ansible/ansible/roles/common/tasks/config.yml:26[0m
[0;34mUsing module file /home/xxxxx/wallaby/share/kolla-ansible/ansible/library/kolla_docker.py[0m
[0;34mPipelining is enabled.[0m
[0;34m<localhost> ESTABLISH LOCAL CONNECTION FOR USER: xxxxx[0m
[0;34m<localhost> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-zdsnyhuhqeakfohywfvxwnzxzjqfcgtm ; http_proxy=http://proxy.sample.com:8080 https_proxy=http://proxy.sample.com:8080 /usr/bin/python3'"'"' && sleep 0'[0m
[0;31mThe full traceback is:[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 1241, in main[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 1116, in ensure_image[0m
[0;31m  File "/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py", line 691, in pull_image[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/api/image.py", line 430, in pull[0m
[0;31m    self._raise_for_status(response)[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/api/client.py", line 270, in _raise_for_status[0m
[0;31m    raise create_api_error_from_http_exception(e)[0m
[0;31m  File "/usr/local/lib/python3.8/dist-packages/docker/errors.py", line 31, in create_api_error_from_http_exception[0m
[0;31m    raise cls(e, response=response, explanation=explanation)[0m
[0;31mfatal: [localhost]: FAILED! => {[0m
[0;31m    "changed": true,[0m
[0;31m    "invocation": {[0m
[0;31m        "module_args": {[0m
[0;31m            "action": "ensure_image",[0m
[0;31m            "api_version": "auto",[0m
[0;31m            "auth_email": null,[0m
[0;31m            "auth_password": null,[0m
[0;31m            "auth_registry": null,[0m
[0;31m            "auth_username": null,[0m
[0;31m            "cap_add": [],[0m
[0;31m            "cgroupns_mode": null,[0m
[0;31m            "client_timeout": 120,[0m
[0;31m            "command": null,[0m
[0;31m            "detach": true,[0m
[0;31m            "dimensions": {},[0m
[0;31m            "environment": {[0m
[0;31m                "KOLLA_CONFIG_STRATEGY": "COPY_ALWAYS"[0m
[0;31m            },[0m
[0;31m            "graceful_timeout": 10,[0m
[0;31m            "healthcheck": null,[0m
[0;31m            "ignore_missing": false,[0m
[0;31m            "image": "kolla/ubuntu-source-fluentd:wallaby",[0m
[0;31m            "labels": {},[0m
[0;31m            "name": null,[0m
[0;31m            "privileged": false,[0m
[0;31m            "remove_on_exit": true,[0m
[0;31m            "restart_policy": "unless-stopped",[0m
[0;31m            "restart_retries": 10,[0m
[0;31m            "security_opt": [],[0m
[0;31m            "state": "running",[0m
[0;31m            "tls_cacert": null,[0m
[0;31m            "tls_cert": null,[0m
[0;31m            "tls_key": null,[0m
[0;31m            "tls_verify": false,[0m
[0;31m            "tmpfs": null,[0m
[0;31m            "tty": false,[0m
[0;31m            "volumes": null,[0m
[0;31m            "volumes_from": null[0m
[0;31m        }[0m
[0;31m    },[0m
[0;31m    "msg": "'Traceback (most recent call last):\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/client.py\", line 268, in _raise_for_status\\n    response.raise_for_status()\\n  File \"/usr/lib/python3/dist-packages/requests/models.py\", line 940, in raise_for_status\\n    raise HTTPError(http_error_msg, response=self)\\nrequests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/v1.41/images/create?tag=wallaby&fromImage=kolla%2Fubuntu-source-fluentd\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \"/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 1241, in main\\n  File \"/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 1116, in ensure_image\\n  File \"/tmp/ansible_kolla_docker_payload_qcyrnm88/ansible_kolla_docker_payload.zip/ansible/modules/kolla_docker.py\", line 691, in pull_image\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/image.py\", line 430, in pull\\n    self._raise_for_status(response)\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/api/client.py\", line 270, in _raise_for_status\\n    raise create_api_error_from_http_exception(e)\\n  File \"/usr/local/lib/python3.8/dist-packages/docker/errors.py\", line 31, in create_api_error_from_http_exception\\n    raise cls(e, response=response, explanation=explanation)\\ndocker.errors.APIError: 500 Server Error for http+docker://localhost/v1.41/images/create?tag=wallaby&fromImage=kolla%2Fubuntu-source-fluentd: Internal Server Error (\"toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit\")\\n'"[0m
[0;31m}[0m

```

上記を全て行えば、Proxy環境下でもkolla-ansibleが正常に動作してくれると思います。


### 最後に

その他にも、kolla-ansibleでplaybookを実行中に「sudo しないとこのコマンド打てないよ」というエラーが出ることがありましたが、私の場合はplaybookを再実行することでエラーが出力されることなく、正常に処理が完了されるケースが2回ほどありました。もし同じようなエラーが出る場合は、該当のplaybookの再実行で回避できるかもしれません。(一体なぜそのようなエラーが一時的に出たのかは不明です・・) 

<font color="Red">(02/23/2022更新) 処理が長くなってしまうとsudoのタイムアウトに引っかかり、上記のようなエラーが出る場合があるようです。あらかじめ /etc/sudoers へ「Defaults timestamp_timeout=<タイムアウトまでの時間(分)>」を追加しておけば回避できると思います。</font>

ansible のべき等性のおかげで、同じplaybookを何度も実行できるのは少し心強く感じました。
この記事が、同じ悩みを持つ方の問題解消に役立てれば幸いです。