summaryrefslogtreecommitdiff
path: root/doc/administration/gitaly/praefect.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/administration/gitaly/praefect.md')
-rw-r--r--doc/administration/gitaly/praefect.md154
1 files changed, 84 insertions, 70 deletions
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 83c9aa3f013..6193a40ac4f 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -20,21 +20,19 @@ for updates and roadmap.
### Architecture
-For this document, the following network topology is assumed:
+The most common architecture for Praefect is simplified in the diagram below:
```mermaid
graph TB
- GitLab --> Gitaly;
GitLab --> Praefect;
- Praefect --> Praefect-Gitaly-1;
- Praefect --> Praefect-Gitaly-2;
- Praefect --> Praefect-Gitaly-3;
+ Praefect --> Gitaly-1;
+ Praefect --> Gitaly-2;
+ Praefect --> Gitaly-3;
```
Where `GitLab` is the collection of clients that can request Git operations.
-`Gitaly` is a Gitaly server before using Praefect. The Praefect node has three
-storage nodes attached. Praefect itself doesn't store data, but connects to
-three Gitaly nodes, `Praefect-Gitaly-1`, `Praefect-Gitaly-2`, and `Praefect-Gitaly-3`.
+The Praefect node has threestorage nodes attached. Praefect itself doesn't
+store data, but connects to three Gitaly nodes, `Gitaly-1`, `Gitaly-2`, and `Gitaly-3`.
Praefect may be enabled on its own node or can be run on the GitLab server.
In the example below we will use a separate server, but the optimal configuration
@@ -49,41 +47,43 @@ purposes.
In this setup guide we will start by configuring Praefect, then its child
Gitaly nodes, and lastly the GitLab server configuration.
+#### Secrets
+
+We need to manage the following secrets and make them match across hosts:
+
+1. `GITLAB_SHELL_SECRET_TOKEN`: this is used by Git hooks to make
+ callback HTTP API requests to GitLab when accepting a Git push. This
+ secret is shared with GitLab Shell for legacy reasons.
+1. `PRAEFECT_EXTERNAL_TOKEN`: repositories hosted on your Praefect
+ cluster can only be accessed by Gitaly clients that carry this
+ token.
+1. `PRAEFECT_INTERNAL_TOKEN`: this token is used for replication
+ traffic inside your Praefect cluster. This is distinct from
+ `PRAEFECT_EXTERNAL_TOKEN` because Gitaly clients must not be able to
+ access internal nodes of the Praefect cluster directly; that could
+ lead to data loss.
+
#### Praefect
On the Praefect node we disable all other services, including Gitaly. We list each
-Gitaly node that will be connected to Praefect under `praefect['storage_nodes']`.
+Gitaly node that will be connected to Praefect as members of the `praefect` hash in `praefect['virtual_storages']`.
-In the example below, the Gitaly nodes are named `praefect-gitaly-N`. Note that one
+In the example below, the Gitaly nodes are named `gitaly-N`. Note that one
node is designated as primary by setting the primary to `true`.
-`praefect['auth_token']` is the token used to authenticate with the GitLab server,
-just like `gitaly['auth_token']` is used for a standard Gitaly server.
-
-The `token` field under each storage listed in `praefect['storage_nodes']` is used
-to authenticate each child Gitaly node with Praefect.
-
```ruby
-# /etc/gitlab/gitlab.rb
+# /etc/gitlab/gitlab.rb on praefect server
# Avoid running unnecessary services on the Gitaly server
postgresql['enable'] = false
redis['enable'] = false
nginx['enable'] = false
prometheus['enable'] = false
+grafana['enable'] = false
unicorn['enable'] = false
sidekiq['enable'] = false
gitlab_workhorse['enable'] = false
gitaly['enable'] = false
-```
-
-##### Set up Praefect and its Gitaly nodes
-
-In the example below, the Gitaly nodes are named `praefect-git-X`. Note that one node is designated as
-primary, by setting the primary to `true`:
-
-```ruby
-# /etc/gitlab/gitlab.rb
# Prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['rake_cache_clear'] = false
@@ -95,25 +95,27 @@ praefect['enable'] = true
# firewalls to restrict access to this address/port.
praefect['listen_addr'] = '0.0.0.0:2305'
-# virtual_storage_name must match the same storage name given to praefect in git_data_dirs
-praefect['virtual_storage_name'] = 'praefect'
-
-# Authentication token to ensure only authorized servers can communicate with
-# Praefect server
-praefect['auth_token'] = 'praefect-token'
-praefect['storage_nodes'] = {
- 'praefect-gitaly-1' => {
- 'address' => 'tcp://praefect-git-1.internal:8075',
- 'token' => 'praefect-gitaly-token',
- 'primary' => true
- },
- 'praefect-gitaly-2' => {
- 'address' => 'tcp://praefect-git-2.internal:8075',
- 'token' => 'praefect-gitaly-token'
- },
- 'praefect-gitaly-3' => {
- 'address' => 'tcp://praefect-git-3.internal:8075',
- 'token' => 'praefect-gitaly-token'
+# Replace PRAEFECT_EXTERNAL_TOKEN with a real secret
+praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN'
+
+# Replace each instance of PRAEFECT_INTERNAL_TOKEN below with a real
+# secret, distinct from PRAEFECT_EXTERNAL_TOKEN.
+# Name of storage hash must match storage name in git_data_dirs on GitLab server.
+praefect['virtual_storages'] = {
+ 'praefect' => {
+ 'gitaly-1' => {
+ 'address' => 'tcp://gitaly-1.internal:8075',
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN',
+ 'primary' => true
+ },
+ 'gitaly-2' => {
+ 'address' => 'tcp://gitaly-2.internal:8075',
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN'
+ },
+ 'gitaly-3' => {
+ 'address' => 'tcp://gitaly-3.internal:8075',
+ 'token' => 'PRAEFECT_INTERNAL_TOKEN'
+ }
}
}
```
@@ -126,37 +128,40 @@ Next we will configure each Gitaly server assigned to Praefect. Configuration f
is the same as a normal standalone Gitaly server, except that we use storage names and
auth tokens from Praefect instead of GitLab.
-Below is an example configuration for `praefect-gitaly-1`, the only difference for the
+Below is an example configuration for `gitaly-1`, the only difference for the
other Gitaly nodes is the storage name under `git_data_dirs`.
-Note that `gitaly['auth_token']` matches the `token` value listed under `praefect['storage_nodes']`
+Note that `gitaly['auth_token']` matches the `token` value listed under `praefect['virtual_storages']`
on the Praefect node.
```ruby
-# /etc/gitlab/gitlab.rb
+# /etc/gitlab/gitlab.rb on gitaly node inside praefect cluster
# Avoid running unnecessary services on the Gitaly server
postgresql['enable'] = false
redis['enable'] = false
nginx['enable'] = false
prometheus['enable'] = false
+grafana['enable'] = false
unicorn['enable'] = false
sidekiq['enable'] = false
gitlab_workhorse['enable'] = false
+prometheus_monitoring['enable'] = false
# Prevent database connections during 'gitlab-ctl reconfigure'
gitlab_rails['rake_cache_clear'] = false
gitlab_rails['auto_migrate'] = false
+# Replace GITLAB_SHELL_SECRET_TOKEN below with real secret
+gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
+
# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
-# Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
-# Authentication token to ensure only authorized servers can communicate with
-# Gitaly server
-gitaly['auth_token'] = 'praefect-gitaly-token'
+# Replace PRAEFECT_INTERNAL_TOKEN below with a real secret.
+gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN'
# Make Gitaly accept connections on all network interfaces. You must use
# firewalls to restrict access to this address/port.
@@ -164,16 +169,13 @@ gitaly['auth_token'] = 'praefect-gitaly-token'
gitaly['listen_addr'] = "0.0.0.0:8075"
git_data_dirs({
- "praefect-gitaly-1" => {
+ "gitaly-1" => {
"path" => "/var/opt/gitlab/git-data"
}
})
```
-Note that just as with a standard Gitaly server, `/etc/gitlab/gitlab-secrets.json` must
-be copied from the GitLab server to the Gitaly node for authentication purposes.
-
-For more information on Gitaly server configuration, see our [gitaly documentation](index.md#3-gitaly-server-configuration).
+For more information on Gitaly server configuration, see our [Gitaly documentation](index.md#3-gitaly-server-configuration).
#### GitLab
@@ -182,25 +184,29 @@ is done through setting the `git_data_dirs`. Assuming the default storage
is present, there should be two storages available to GitLab:
```ruby
+# /etc/gitlab/gitlab.rb on gitlab server
+
+# Replace PRAEFECT_EXTERNAL_TOKEN below with real secret.
git_data_dirs({
"default" => {
- "gitaly_address" => "tcp://gitaly.internal"
+ "path" => "/var/opt/gitlab/git-data"
},
"praefect" => {
- "gitaly_address" => "tcp://praefect.internal:2305"
+ "gitaly_address" => "tcp://praefect.internal:2305",
+ "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
-gitlab_rails['gitaly_token'] = 'praefect-token'
+# Replace GITLAB_SHELL_SECRET_TOKEN below with real secret
+gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
```
Note that the storage name used is the same as the `praefect['virtual_storage_name']` set
on the Praefect node.
-Also, the `gitlab_rails['gitaly_token']` matches the value of `praefect['auth_token']`
-on Praefect.
+Save your changes and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-Restart GitLab using `gitlab-ctl restart` on the GitLab node.
+Run `gitlab-rake gitlab:gitaly:check` to confirm that GitLab can reach Praefect.
### Testing Praefect
@@ -208,10 +214,18 @@ To test Praefect, first set it as the default storage node for new projects
using **Admin Area > Settings > Repository > Repository storage**. Next,
create a new project and check the "Initialize repository with a README" box.
-If you receive a 503 error, check `/var/log/gitlab/gitlab-rails/production.log`.
-A `GRPC::Unavailable (14:failed to connect to all addresses)` error indicates
-that GitLab was unable to connect to Praefect.
-
-If the project is created but the README is not, then ensure that the
-`/etc/gitlab/gitlab-secrets.json` file from the GitLab server has been copied
-to the Gitaly servers.
+If you receive an error, check `/var/log/gitlab/gitlab-rails/production.log`.
+
+Here are common errors and potential causes:
+
+- 500 response code
+ - **ActionView::Template::Error (7:permission denied)**
+ - `praefect['auth_token']` and `gitlab_rails['gitaly_token']` do not match on the GitLab server.
+ - **Unable to save project. Error: 7:permission denied**
+ - Secret token in `praefect['storage_nodes']` on GitLab server does not match the
+ value in `gitaly['auth_token']` on one or more Gitaly servers.
+- 503 response code
+ - **GRPC::Unavailable (14:failed to connect to all addresses)**
+ - GitLab was unable to reach Praefect.
+ - **GRPC::Unavailable (14:all SubCons are in TransientFailure...)**
+ - Praefect cannot reach one or more of its child Gitaly nodes.