Merge "[GENERAL] Add Andreas Geissler as committer."
[oom/offline-installer.git] / ansible / README.md
1 # Offline Kubernetes deployment with Ansible
2
3 This solution is generic offline deployment for Kubernetes which can host any
4 Kubernetes application in completely offline manner without internet connection.
5
6 It's developed for the purpose of hosting [ONAP](https://www.onap.org/) and proven
7 to work with that. ONAP is a very big Kubernetes application deployed by using
8 [Helm](https://helm.sh/) charts.
9
10 By default this solution supports deploying Kubernetes application with Helm charts.
11
12 ## Ansible execution/bootstrap
13
14 There are two ways how to easily run our ansible playbooks.
15
16 If you already have or can install a docker then you can build the provided `Dockerfile` for the ansible and run playbooks in the docker container.
17
18 Another way to deploy ansible is via chroot environment which is bundled together within this directory.
19
20 ### (Re)build docker image and/or chroot archive
21
22 Inside the docker directory is the `Dockerfile` and `build_ansible_image.sh` script. You can run `build_ansible_image.sh` script somewhere with internet connectivity and it will download all required packages needed for building the ansible docker image and for exporting it into flat chroot environment.
23
24 Note: git must be installed before this script is called
25
26 Built image is exported into `ansible_chroot.tgz` archive in the same (./docker) directory.
27
28 This script has two optional arguments:
29
30 1. ansible version
31 1. docker image name
32
33 Note: if optional arguments are not used, docker image name will be set to `ansible` by default.
34
35 ### Launching ansible playbook using chroot environment
36
37 This is our default and preferred way of running ansible playbooks in an offline environment as there is no dependency on docker to be installed on the system. Chroot environment is already provided by included archive `ansible_chroot.tgz`.
38
39 It should be available in ./docker directory as the end-result of our packaging script or after manual running of `build_ansible_image.sh` referenced above.
40
41 All playbooks can be executed via `./run_playbook.sh` wrapper script.
42
43 To get more info about how the `./run_playbook.sh` wrapper script should be used, run:
44 ```bash
45 ./run_playbook.sh
46 ```
47
48 The main purpose of this wrapper script is to provide ansible to machine where it was bootstrapped w/o need of installing additional packages, for displaying ansible-playbook command help one can run this following help command:
49 ```bash
50 ./run_playbook.sh --help
51 ```
52
53 #### Developers notes from chroot approach
54
55 * There are two scripts which work in tandem for creating and running chroot
56 * First can convert docker image into chroot directory
57 * Second will automate chrooting (necessary steps for chroot to work and cleanup)
58 * Both of them have help - just run:
59
60 ```bash
61 $ cd docker
62 $ ./create_docker_chroot.sh help
63 $ ./run_chroot.sh help
64 ```
65
66 #### Example usage:
67
68 ```
69 $ sudo su
70 $ docker/create_docker_chroot.sh convert some_docker_image ./new_name_for_chroot
71 $ cat ./new_name_for_chroot/README.md
72 $ docker/run_chroot.sh execute ./new_name_for_chroot cat /etc/os-release 2>/dev/null
73 ```
74
75 ### Launching ansible playbook using docker container (ALTERNATIVE APPROACH)
76
77 This option is here just to keep support for the older method which rely on a running docker service. For the offline deployment use the chroot option as indicated above.
78
79 You will not need `ansible_chroot.tgz` archive anymore, but the new requirement is a prebuilt docker image of ansible (based on our `Dockerfile`). It should be available in your local docker repository (otherwise the default name `ansible` may fetch unwanted image from default registry).
80
81 To trigger this functionality and run `ansible-playbook` inside a docker container instead of the chroot environment, you must first set the `ANSIBLE_DOCKER_IMAGE` variable. The value must be a name of the built ansible docker image - built using our provided `Dockerfile`.
82
83 Image name can be obtained again from `docker images` output.
84
85 ```
86 E.g.
87 REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
88 ansible                                    latest              c44633617bfb        2 hours ago         127 MB
89 ```
90
91 Usage is basically the same as with the default chroot way - the only difference is the existence of the env variable:
92
93 ```bash
94 export ANSIBLE_DOCKER_IMAGE=ansible
95 ./run_playbook.sh <args>
96 ```
97
98 or in a single command
99
100 ```bash
101 ANSIBLE_DOCKER_IMAGE=ansible ./run_playbook.sh <args>
102 ```
103
104 ---
105
106 ## Playbooks
107
108 This chapter introduces all playbooks that each can be run independently, however
109 the order of running playbooks is implicitly fixed.
110
111 The complete offline deployment is handled by `site.yml` Ansible playbook.
112 This playbook contains imports for all the other playbooks needed to deploy
113 wanted Kubernetes application:
114   - `upload_resources.yml`
115   - `infrastructure.yml`
116   - `rke.yml`
117   - `application.yml` - this is an application related playbook
118
119 ### Resource upload
120
121 Resource upload(nexus data, docker images, packages, etc.) is handled by playbook `upload_resources.yml`.
122
123 **Preconditions:**
124   - setup nfs server for folder with resources (`resources.tar`) so it can be mounted on infrastructure server.
125
126 ### Infrastructure setup
127
128 Infrastructure deployment consists of:
129   - docker installed on all nodes
130   - dnsmasq docker container setup and start
131   - vncserver docker container setup and start
132   - nexus3 docker container - consists of docker images for application, Rancher and other resources
133   - nginx docker container - serves mainly as proxy for nexus, and also for providing other resources via HTTP/HTTPS
134
135 Infrastructure setup is handled by `infrastructure.yml` playbook.
136
137 **Preconditions**:
138   - resources uploaded to infrastructure server (usually handled by `upload_resources.yml` playbook). All folders from resources should be located in directory defined in `{{ app_data_path }}` variable (e.g. `/opt/onap`).
139
140 ### Kubernetes cluster deployment
141
142 Kubernetes cluster deployment is handled by `rke.yml` playbook.
143
144 **Preconditions**:
145   - infrastructure deployed by running `infrastructure.yml` playbook
146
147 ### Kubernetes application installation
148
149 Application installation is handled by `application.yml` playbook.
150
151 Application is dependent on resources:
152   - images, files, etc. included in resources.tar handled by upload_resources.yml playbook.
153   - Helm charts pointing to those images and files.
154   - Application specific configuration
155
156 Binary resources must be handled to be in place already during packaging and that
157 is instructed in **HERE/TODO**.
158
159 Application Helm charts and configuration can also be packaged into the package itself and is then available on ./application folder. However it can also be
160 copied there after installer package is deployed and before installing the application.
161
162 Application Helm charts and configuration is better described in [application/README.md](./application/README.md)
163
164 **Preconditions**:
165   - Kubernetes cluster must be up and running i.e. `rke.yml` playbook has been run.
166
167 ## Running playbooks
168 To run ansible playbook call `run_playbook.sh` with same arguments as you would
169 call ansible-playbook.
170
171 Script `run_playbook.sh` must be executed from ansible directory to work correctly.
172
173 Example:
174 ```bash
175 ./run_playbook.sh -i application/hosts.yml playbook.yml
176 ```
177
178 ## Deployment
179
180 This chapter describes how to start whole deployment of offline solution from scratch
181 after offline software package is installed (untarred) to target machine from which
182 Ansible will be run towards the target servers. Target servers are already in place
183 and running.
184
185 After offline software package is untarred, locate the ansible directory in there
186 having this README file you are reading.
187
188 ### Preparations
189
190 **SSH keys**:
191
192 In our playbooks we expects to have passwordless login to all ansible administrated nodes.
193 There is a helping playbook created to arrange that. Before setup playbook is executed
194 please insert IPs to inventory file as described below/
195
196 **Inventory**:
197
198 File **./inventory/hosts.yml** is an example inventory file that can be used as a
199 baseline. Copy inventory/hosts.yml file to ./application folder and modify needed
200 parts.
201
202   - `./application/hosts.yml`:
203     ```
204     # This group contains hosts with all resources (binaries, packages, etc.)
205     # in tarball.
206     all:
207       vars:
208         # this key is supposed to be generated during setup.yml playbook execution
209         # change it just when you have better one working for all nodes
210         ansible_ssh_private_key_file: /root/.ssh/offline_ssh_key
211         ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
212
213       children:
214         resources:
215           hosts:
216             resource-host:
217               ansible_host: 10.8.8.5
218
219         # This is group of hosts where nexus, nginx, dns and all other required
220         # services are running.
221         infrastructure:
222           hosts:
223             infrastructure-server:
224               ansible_host: 10.8.8.9
225               #IP used for communication between infra and kubernetes nodes, must be specified.
226               cluster_ip: 10.8.8.9
227
228         # This is group of hosts which are/will be part of Kubernetes cluster.
229         kubernetes:
230           hosts:
231             kubernetes-node-1:
232               ansible_host: 10.8.8.13
233               #ip of the node that it uses for communication with k8s cluster.
234               cluster_ip: 10.8.8.13
235
236         # This is a group of hosts that are to be used as kubernetes control plane nodes.
237         # This means they host kubernetes api server, controller manager and scheduler.
238         # This example uses infra for this purpose, however note that any
239         # other host could be used including kubernetes nodes.
240         # cluster_ip needs to be set for hosts used as control planes.
241         kubernetes-control-plane:
242           hosts:
243             infrastructure-server
244
245         nfs-server:
246           hosts:
247             kubernetes-node-1
248     ```
249
250
251
252 after setting up inventory file helping setup playbook can be executed to arrange passwordless
253 login to all nodes. It make sense to launch it just when root user can't access all nodes in
254 passwordless way using ssh key. If root user has access already with ssh key, please override
255 just ansible_ssh_private_key_file in inventory file accordingly and there is no need to launch
256 setup playbook.
257
258 If there is non-root user with ssh key access configured launch setup.yml in this way:
259
260 ```bash
261 ./run_playbook.sh -i application/hosts.yml setup.yml -u <user> -e ansible_ssh_private_key_file=<key>
262 ```
263 e.g.
264 ./run_playbook.sh -i application/hosts.yml setup.yml -u cloud-user -e ansible_ssh_private_key_file=/root/.ssh/id_rsa
265
266 in case of password login to nodes, run playbook with --ask-pass param
267
268 ```bash
269 ./run_playbook.sh -i application/hosts.yml setup.yml -u <user> --ask-pass
270 ```
271
272 After running that playbook, passwordless login should be arranged for root user
273 using key ~/.ssh/offline_ssh_key which is preconfigured in inventory file.
274
275
276 **Deployment related configuration**:
277
278 Please check and review all options in `group_vars/all.yml` and `group_vars/infrastructure.yml`.
279
280 After inventory is setup and configuration is fine, all other playbooks (except application.yml) could be already be run and empty Kubernetes cluster (without application) could be setup.
281
282 **Application configuration**:
283
284 To deploy also application into Kubernetes, configure application configuration
285 needed by `application.yml` playbook.
286 See instructions on separate README.md file on [application/README.md](./application/README.md).
287
288 ### Run Deployment
289
290 To deploy run:
291 ```bash
292 ./run_playbook.sh -i application/hosts.yml site.yml -e @application/application_configuration.yml
293 ```