helm: Convert the SSO server to be served over SSL.
[arvados-k8s.git] / arvados / README.md
1 [//]: # Copyright (C) The Arvados Authors. All rights reserved.
2 [//]: #
3 [//]: # SPDX-License-Identifier: Apache-2.0
4
5 # Arvados Helm Chart
6
7 This directory contains a simple Helm chart for Arvados, excluding the Git
8 server and SLURM. It's more or less a port of the Kubernetes config generated
9 by the Arvados Kelda blueprint.
10
11 The files should only be considered an example of what a Kubernetes deployment
12 might look like -- this is my first Helm chart, and there are definitely things
13 that could be cleaner.
14
15 ## Usage
16
17 1. Boot a [GKE cluster](https://console.cloud.google.com/kubernetes/) with at least 3 nodes.
18     - I tested with 3 n1-standard-1 (1 vCPU, 3.75GB RAM) machines on Kubernetes v1.8.8.
19     - It takes a few minutes for the cluster to be initialized.
20
21 2. Reserve a [static IP](https://console.cloud.google.com/networking/addresses) in GCE.
22     - Make sure the IP is in the same region as your GKE cluster, and is of the
23       "Regional" type.
24
25 3. Install `gcloud`, `kubectl`, and `helm` on your development machine.
26    `gcloud` is used to setup the connection to your GKE cluster. `kubectl` is
27    used to interact with the Kubernetes cluster. `helm` is used to deploy to
28    the cluster.
29      - Follow the instructions [here](https://cloud.google.com/sdk/downloads) to install `gcloud`.
30      - `gcloud components install kubectl` to install `kubectl`.
31      - `brew install kubernetes-helm` to install `helm`.
32      - If that doesn't work, see the official installation instructions for
33        [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl)
34        and [helm](https://docs.helm.sh/using_helm/#installing-helm).
35
36 3. Connect to the GKE cluster.
37     - Click the "Connect" button next to your [GKE cluster](https://console.cloud.google.com/kubernetes/).
38     - Execute the "Command-line access" command on your development machine.
39     - Run `kubectl get nodes` to test your connection to the GKE cluster. The
40       nodes you specified in step 1 should show up in the output.
41
42 4. Install `helm` on the cluster.
43     - Run the following commands from your development machine. The last three
44       commands are necessary since GKE clusters use RBAC for authentication, so
45       the default `helm` installation doesn't have sufficient permissions to
46       deploy to the cluster:
47         - `helm init`
48         - `kubectl create serviceaccount --namespace kube-system tiller`
49         - `kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller`
50         - `kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'`
51     - Wait until the `tiller` container's status is "Running" in `kubectl get pods --namespace kube-system`
52     - Test `helm` by running `helm ls`. There shouldn't be any errors.
53
54 5. Generate an SSL certificate.
55     - Run `./cert-gen.sh <STATIC IP>` where `<STATIC IP>` is the IP allocated in step 1.
56
57 6. *Optional*: Trust the generated certificate. By default, browsers treat
58    self-signed certificates as insecure. Therefore, the generated certificate
59    must be manually trusted through the OS settings.  If you skip this step,
60    you'll have to manually override browser SSL warnings when connecting to
61    workbench.
62
63    To do this on On Mac OS:
64    1. Open the "Keychain Access" application.
65    2. Click "File" in the menu at the top left.
66    3. Click "Import Items...".
67    4. Navigate to the generated `cert` and click "Open".
68    5. Double click on the certificate and change the trust level to "Always
69       Trust". The certificate will be named "arvados-test-cert".
70
71 7. Modify the Kubernetes configs to reference your static IP.
72     - Replace all references to the IP `8.8.8.8` with the IP allocated in step 1.
73     - This can be done automatically with the following command:
74         ```
75         grep -lr --exclude README.md '8.8.8.8' . | xargs sed -i '' 's/8.8.8.8/<STATIC IP>/g'
76         ```
77 8. Install the Arvados Kubernetes configs.
78     - Run `helm install --name arvados .`
79     - If you make a change to the Kubernetes manifests and want to reinstall
80       the configs, run `helm delete --purge arvados`, followed by the `helm
81       install` command.
82
83 9. Wait for everything to boot in the cluster. This takes a few minutes from my
84    testing.
85     - `kubectl get pods` should show all the pods as running.
86     - `kubectl get services` shouldn't show anything as `<pending>`.
87         - If some services are stuck in `<pending>` check their status with
88           `kubectl describe service/serviceName` (e.g. `kubectl describe
89           service/arvados-api-server`). If there's an error along the lines of
90           "Specified IP address is in-use and would result in a conflict.",
91           manually delete all entries under "Forwarding rules" and "Target
92           pools" in the [console UI](https://console.cloud.google.com/net-services/loadbalancing/advanced/targetPools/list).
93     - Even after the containers are running, they take a couple minutes to
94       download and install various packages. If some components seem down,
95       check its logs with `kubectl logs <POD NAME>` and see if it's fully
96       initialized. In my testing, the container has been inaccessible for up to
97       10 minutes after starting.
98
99 10. Connect to the Workbench.
100     - Navigate to `https://<STATIC IP>` in your browser.
101
102 11. Destroy the GKE cluster when finished.
103
104 ## Future Work
105
106 - The Arvados Dockerfiles need to be rebuilt so that they have the latest `apt`
107   metadata. As a workaround, some pods, such as `keep-web` are running `apt-get
108   update` when they start.
109 - Set the floating IP through `./values.yaml` and have Helm handling templating
110   it, rather than manually replacing references to the IP.
111     - There may be other values worth templating, such as the number of Keep
112       containers to deploy, or the versions of the Arvados packages to install.
113 - Figure out a better way of setting API tokens. It's currently hardcoded in
114   the config files, and changing it in one location will cause the other
115   references to fail.
116     ```
117     $ grep -r 'thisisnotavery' .
118     ./config/api-server/90-init-db.sh:    bundle exec script/create_superuser_token.rb thisisnotaverygoodsuperusersecretstring00000000000
119     ./config/api-server/90-init-db.sh:    bundle exec get_anonymous_user_token.rb -t thisisnotaverygoodanonymoussecretstring00000000000 || true
120     ./config/sso/90-init-db.sh:    bundle exec script/create_superuser_token.rb thisisnotaverygoodsuperusersecretstring00000000000
121     ./config/sso/90-init-db.sh:    bundle exec get_anonymous_user_token.rb -t thisisnotaverygoodanonymoussecretstring00000000000 || true
122     ./templates/keep-proxy-deployment.yaml:              value: "thisisnotaverygoodanonymoussecretstring00000000000"
123     ./templates/keep-web-deployment.yaml:              value: "thisisnotaverygoodanonymoussecretstring00000000000"
124     ./templates/shell-server-deployment.yaml:              value: "thisisnotaverygoodsuperusersecretstring00000000000"
125     ```
126 - Figure out how to reduce redundant YAML files.
127     - The Nginx SSL proxies (`./templates/keep-web-https.yaml`,
128       `./templates/keep-proxy-https.yaml`, `./templates/ws-https.yaml`) are
129       extremely similar. Only a couple lines related to hostnames and
130       ports different.
131     - The configmap YAMLs are all basically the same.
132     - This might be possible with partials (a Helm templating feature). Or in a
133       different templating language such as ksonnet.
134 - Add SLURM support
135 - Support changing keep-store scale. Right now the scale is set to `replicas:
136   2` in `templates/keep-store-deployment.yaml`. Unfortunately, increasing the scale
137   isn't as simple as changing the number since the hostnames are hardcoded in
138   `config/shell-server/99-init-keep.sh`.
139 - Consider adding healthchecks and readiness checks.
140     - They would make the deployment more robust. Readiness checks would make
141       it so services weren't exposed until they're ready to receive traffic.
142       Healthchecks would make it so containers are restarted when they enter a
143       failure state.
144 - Add minimum CPU and RAM requirements to the containers.
145     - This will prevent out of memory errors, for example. This is especially
146       important if autoscaling is added.
147 - Get the SSL certificate automatically using Lets Encrypt, eliminating the
148   need for the self-signed certificate generated by the `cert-gen.sh` script.
149 - Add SSL to SSO server
150     - It's currently being hosted on only HTTP.