468.md 47.3 KB
Newer Older
Lab机器人's avatar
readme  
Lab机器人 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
# Gitaly

> 原文:[https://docs.gitlab.com/ee/administration/gitaly/](https://docs.gitlab.com/ee/administration/gitaly/)

*   [Architecture](#architecture)
*   [Configure Gitaly](#configure-gitaly)
*   [Run Gitaly on its own server](#run-gitaly-on-its-own-server)
    *   [Network architecture](#network-architecture)
    *   [Install Gitaly](#install-gitaly)
    *   [Configure authentication](#configure-authentication)
    *   [Configure Gitaly servers](#configure-gitaly-servers)
    *   [Configure Gitaly clients](#configure-gitaly-clients)
        *   [Mixed configuration](#mixed-configuration)
    *   [Disable Gitaly where not required (optional)](#disable-gitaly-where-not-required-optional)
*   [Enable TLS support](#enable-tls-support)
    *   [Observe type of Gitaly connections](#observe-type-of-gitaly-connections)
*   [`gitaly-ruby`](#gitaly-ruby)
    *   [Configure number of `gitaly-ruby` workers](#configure-number-of-gitaly-ruby-workers)
*   [Limit RPC concurrency](#limit-rpc-concurrency)
*   [Rotate Gitaly authentication token](#rotate-gitaly-authentication-token)
    *   [Verify authentication monitoring](#verify-authentication-monitoring)
    *   [Enable “auth transitioning” mode](#enable-auth-transitioning-mode)
    *   [Update Gitaly authentication token](#update-gitaly-authentication-token)
    *   [Ensure there are no authentication failures](#ensure-there-are-no-authentication-failures)
    *   [Disable “auth transitioning” mode](#disable-auth-transitioning-mode)
    *   [Verify authentication is enforced](#verify-authentication-is-enforced)
*   [Direct Git access bypassing Gitaly](#direct-git-access-bypassing-gitaly)
*   [Direct access to Git in GitLab](#direct-access-to-git-in-gitlab)
    *   [History](#history)
    *   [How it works](#how-it-works)
    *   [Transition to Gitaly Cluster](#transition-to-gitaly-cluster)
*   [Troubleshooting Gitaly](#troubleshooting-gitaly)
    *   [Checking versions when using standalone Gitaly servers](#checking-versions-when-using-standalone-gitaly-servers)
    *   [`gitaly-debug`](#gitaly-debug)
    *   [Commits, pushes, and clones return a 401](#commits-pushes-and-clones-return-a-401)
    *   [Client side gRPC logs](#client-side-grpc-logs)
    *   [Observing `gitaly-ruby` traffic](#observing-gitaly-ruby-traffic)
    *   [Repository changes fail with a `401 Unauthorized` error](#repository-changes-fail-with-a-401-unauthorized-error)
    *   [Command line tools cannot connect to Gitaly](#command-line-tools-cannot-connect-to-gitaly)
    *   [Gitaly not listening on new address after reconfiguring](#gitaly-not-listening-on-new-address-after-reconfiguring)
    *   [Permission denied errors appearing in Gitaly logs when accessing repositories from a standalone Gitaly server](#permission-denied-errors-appearing-in-gitaly-logs-when-accessing-repositories-from-a-standalone-gitaly-server)
    *   [Praefect](#praefect)

# Gitaly[](#gitaly "Permalink")

[Gitaly](https://gitlab.com/gitlab-org/gitaly)是提供对 Git 存储库的高级 RPC 访问的服务. 没有它,任何 GitLab 组件都无法读取或写入 Git 数据.

在 Gitaly 文档中:

*   **Gitaly 服务器**是指任何本身运行 Gitaly 的节点.
*   **Gitaly 客户端**指的是任何运行向 Gitaly 服务器发出请求的进程的节点. 流程包括但不限于:
    *   [GitLab Rails 应用程序](https://gitlab.com/gitlab-org/gitlab) .
    *   [GitLab 外壳](https://gitlab.com/gitlab-org/gitlab-shell) .
    *   [亚搏体育 app Labhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) .

GitLab 最终用户无法直接访问 Gitaly. Gitaly 仅管理 GitLab 的 Git 存储库访问. 其他类型的 GitLab 数据无法使用 Gitaly 访问.

**警告:**从 GitLab 13.0 起,不支持 Gitaly 对 NFS 的支持. 在 GitLab 14.0 中,计划删除对 NFS 的 Gitaly 支持. 尽快升级到[Gitaly Cluster](praefect.html) .

## Architecture[](#architecture "Permalink")

以下是有关如何使用 Gitaly 的高级体系结构概述.

[![Gitaly architecture diagram](img/eb93aca89ce7486ca89aa5a9f4357617.png)](img/architecture_v12_4.png)

## Configure Gitaly[](#configure-gitaly "Permalink")

Gitaly 服务本身是通过[TOML 配置文件配置的](reference.html) .

要更改 Gitaly 设置,请执行以下操作:

**对于所有 GitLab**

1.  编辑`/etc/gitlab/gitlab.rb`并添加或更改[Gitaly 设置](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676) .
2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

**对于源安装**

1.  编辑`/home/git/gitaly/config.toml`并添加或更改[Gitaly 设置](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example) .
2.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .

以下配置选项也可用:

*   Enabling [TLS support](#enable-tls-support).
*   配置[`gitaly-ruby`工人](#configure-number-of-gitaly-ruby-workers)[数量](#configure-number-of-gitaly-ruby-workers) .
*   Limiting [RPC concurrency](#limit-rpc-concurrency).

## Run Gitaly on its own server[](#run-gitaly-on-its-own-server "Permalink")

默认情况下,Gitaly 与 Gitaly 客户端在同一服务器上运行,并按[上述配置](#configure-gitaly) . 单服务器安装最好由以下默认配置使用:

*   [Omnibus GitLab](https://docs.gitlab.com/omnibus/).
*   GitLab [源代码安装指南](../../install/installation.html) .

However, Gitaly can be deployed to its own server, which can benefit GitLab installations that span multiple machines.

**注意:**配置为在自己的服务器上运行时, [必须先升级](https://docs.gitlab.com/omnibus/update/) Gitaly 服务器,然后才能在群集中的 Gitaly 客户端上[进行升级](https://docs.gitlab.com/omnibus/update/) .

在自己的服务器上设置 Gitaly 的过程是:

1.  [Install Gitaly](#install-gitaly).
2.  [Configure authentication](#configure-authentication).
3.  [Configure Gitaly servers](#configure-gitaly-servers).
4.  [Configure Gitaly clients](#configure-gitaly-clients).
5.  [Disable Gitaly where not required](#disable-gitaly-where-not-required-optional) (optional).

在自己的服务器上运行 Gitaly 时,请注意有关 GitLab 版本的以下内容:

*   从 GitLab 11.4 起,除了[Elasticsearch indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer)之外,Gitaly 能够满足所有 Git 请求,而无需为 Git 存储库数据共享 NFS 挂载.
*   从 GitLab 11.8 开始,Elasticsearch 索引器还使用 Gitaly 进行数据访问. NFS 仍可用于块级 Git 数据的冗余,但仅需安装在 Gitaly 服务器上.
*   从 GitLab 11.8 到 12.2,可以在不使用 NFS 的 Gitaly 设置中使用 Elasticsearch. 为了在这些版本中使用 Elasticsearch,必须在您的 GitLab 配置中启用[存储库索引器](../../integration/elasticsearch.html#elasticsearch-repository-indexer) .
*   [从 GitLab 12.3 开始](https://gitlab.com/gitlab-org/gitlab/-/issues/6481) ,新的索引器是默认的,不需要任何配置.

### Network architecture[](#network-architecture "Permalink")

以下列表描述了 Gitaly 的网络体系结构:

*   GitLab Rails shards repositories into [repository storages](../repository_storage_paths.html).
*   `/config/gitlab.yml`包含从存储名称到`(Gitaly address, Gitaly token)`对的`(Gitaly address, Gitaly token)` .
*   `/config/gitlab.yml``storage name` -> `(Gitaly address, Gitaly token)`映射是 Gitaly 网络拓扑的唯一事实来源.
*   `(Gitaly address, Gitaly token)`对应于 Gitaly 服务器.
*   Gitaly 服务器托管一个或多个存储.
*   一个 Gitaly 客户端可以使用一个或多个 Gitaly 服务器.
*   必须以对**所有** Gitaly 客户端正确解析的方式指定 Gitaly 地址.
*   Gitaly 客户包括:
    *   美洲狮或独角兽.
    *   Sidekiq.
    *   亚搏体育 app Labhorse.
    *   GitLab 外壳.
    *   Elasticsearch 索引器.
    *   Gitaly 本身.
*   一个 Gitaly 服务器必须能够通过其自身发出 RPC 调用**本身** `(Gitaly address, Gitaly token)`在指定的一对`/config/gitlab.yml` .
*   认证通过静态令牌完成,该令牌在 Gitaly 和 GitLab Rails 节点之间共享.

**危险:** Gitaly 服务器不得暴露于公共互联网,因为默认情况下 Gitaly 的网络流量未加密. 强烈建议使用防火墙,以限制对 Gitaly 服务器的访问. 另一种选择是[使用 TLS](#enable-tls-support) .

在以下各节中,我们描述如何使用秘密令牌`abc123secret`配置两个 Gitaly 服务器:

*   `gitaly1.internal`.
*   `gitaly2.internal`.

我们假设您的 GitLab 安装具有三个存储库存储:

*   `default`.
*   `storage1`.
*   `storage2`.

如果需要,一台服务器最多只能使用一个存储库.

**注意:** Gitaly 文档中引用的令牌只是管理员选择的任意密码. 它与为 GitLab API 创建的令牌或其他类似的 Web API 令牌无关.

### Install Gitaly[](#install-gitaly "Permalink")

使用 Omnibus GitLab 在每台 Gitaly 服务器上安装 Gitaly 或从源代码安装它:

*   对于 Omnibus GitLab,请[下载并安装](https://about.gitlab.com/install/)所需的 Omnibus GitLab 软件包,但**不要**提供`EXTERNAL_URL=`值.
*   要从源代码安装,请遵循[Install Gitaly 上](../../install/installation.html#install-gitaly)的步骤.

### Configure authentication[](#configure-authentication "Permalink")

Gitaly 和 GitLab 使用两个共享的机密进行身份验证:

*   一种用于向 Gitaly 验证 gRPC 请求的身份.
*   A second for authentication callbacks from GitLab Shell to the GitLab internal API.

**对于所有 GitLab**

要配置 Gitaly 令牌:

1.  在 Gitaly 客户端上,编辑`/etc/gitlab/gitlab.rb`

    ```
    gitlab_rails['gitaly_token'] = 'abc123secret' 
    ```

2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
3.  在 Gitaly 服务器上,编辑`/etc/gitlab/gitlab.rb`

    ```
    gitaly['auth_token'] = 'abc123secret' 
    ```

4.  [Reconfigure GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure).

有两种方法可以配置 GitLab Shell 令牌.

方法 1:

1.`/etc/gitlab/gitlab-secrets.json`从 Gitaly 客户端复制到 Gitaly 服务器(和任何其他 Gitaly 客户端)上的相同路径.
2.  在 Gitaly 服务器上[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

方法 2:

1.  在 Gitaly 客户端上,编辑`/etc/gitlab/gitlab.rb`

    ```
    gitlab_shell['secret_token'] = 'shellsecret' 
    ```

2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
3.  在 Gitaly 服务器上,编辑`/etc/gitlab/gitlab.rb`

    ```
    gitlab_shell['secret_token'] = 'shellsecret' 
    ```

4.  [Reconfigure GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure).

**对于源安装**

1.`/home/git/gitlab/.gitlab_shell_secret`从 Gitaly 客户端复制到 Gitaly 服务器(和任何其他 Gitaly 客户端)上的相同路径.
2.  在 Gitaly 客户端上,编辑`/home/git/gitlab/config/gitlab.yml`

    ```
    gitlab:
      gitaly:
        token: 'abc123secret' 
    ```

3.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .
4.  在 Gitaly 服务器上,编辑`/home/git/gitaly/config.toml`

    ```
    [auth]
    token = 'abc123secret' 
    ```

5.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .

### Configure Gitaly servers[](#configure-gitaly-servers "Permalink")

在 Gitaly 服务器上,您必须配置存储路径并启用网络侦听器.

如果要减少启用身份验证时发生停机的风险,可以暂时禁用强制实施. 有关更多信息,请参阅有关配置[Gitaly 身份验证](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication)的文档.

**对于所有 GitLab**

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    # /etc/gitlab/gitlab.rb

    # Avoid running unnecessary services on the Gitaly server
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    puma['enable'] = false
    sidekiq['enable'] = false
    gitlab_workhorse['enable'] = false
    grafana['enable'] = false
    gitlab_exporter['enable'] = false

    # If you run a separate monitoring node you can disable these services
    alertmanager['enable'] = false
    prometheus['enable'] = false

    # If you don't run a separate monitoring node you can
    # enable Prometheus access & disable these extra services.
    # This makes Prometheus listen on all interfaces. You must use firewalls to restrict access to this address/port.
    # prometheus['listen_address'] = '0.0.0.0:9090'
    # prometheus['monitor_kubernetes'] = false

    # If you don't want to run monitoring services uncomment the following (not recommended)
    # node_exporter['enable'] = false

    # Prevent database connections during 'gitlab-ctl reconfigure'
    gitlab_rails['rake_cache_clear'] = false
    gitlab_rails['auto_migrate'] = false

    # 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 Gitaly client to Gitaly server.
    gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'

    # Make Gitaly accept connections on all network interfaces. You must use
    # firewalls to restrict access to this address/port.
    # Comment out following line if you only want to support TLS connections
    gitaly['listen_addr'] = "0.0.0.0:8075" 
    ```

2.  对于每个相应的 Gitaly 服务器,将以下内容附加到`/etc/gitlab/gitlab.rb`

    On `gitaly1.internal`:

    ```
    git_data_dirs({
      'default' => {
        'path' => '/var/opt/gitlab/git-data'
      },
      'storage1' => {
        'path' => '/mnt/gitlab/git-data'
      },
    }) 
    ```

    On `gitaly2.internal`:

    ```
    git_data_dirs({
      'storage2' => {
        'path' => '/srv/gitlab/git-data'
      },
    }) 
    ```

3.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
4.  运行`sudo /opt/gitlab/embedded/service/gitlab-shell/bin/check -config /opt/gitlab/embedded/service/gitlab-shell/config.yml`以确认 Gitaly 可以执行对 GitLab 内部 API 的回调.

**对于源安装**

1.  Edit `/home/git/gitaly/config.toml`:

    ```
    listen_addr = '0.0.0.0:8075'

    internal_socket_dir = '/var/opt/gitlab/gitaly'

    [logging]
    format = 'json'
    level = 'info'
    dir = '/var/log/gitaly' 
    ```

2.  对于每个相应的 Gitaly 服务器,将以下内容附加到`/home/git/gitaly/config.toml`

    On `gitaly1.internal`:

    ```
    [[storage]]
    name = 'default'
    path = '/var/opt/gitlab/git-data/repositories'

    [[storage]]
    name = 'storage1'
    path = '/mnt/gitlab/git-data/repositories' 
    ```

    On `gitaly2.internal`:

    ```
    [[storage]]
    name = 'storage2'
    path = '/srv/gitlab/git-data/repositories' 
    ```

3.  Edit `/home/git/gitlab-shell/config.yml`:

    ```
    gitlab_url: https://gitlab.example.com 
    ```

4.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .
5.  运行`sudo -u git /home/git/gitlab-shell/bin/check -config /home/git/gitlab-shell/config.yml`以确认 Gitaly 可以执行对 GitLab 内部 API 的回调.

### Configure Gitaly clients[](#configure-gitaly-clients "Permalink")

最后一步,您必须更新 Gitaly 客户端,使其从使用本地 Gitaly 服务切换为使用刚配置的 Gitaly 服务器.

这可能会有风险,因为任何阻止您的 Gitaly 客户端访问 Gitaly 服务器的操作都将导致所有 Gitaly 请求失败. 例如,任何类型的网络,防火墙或名称解析问题.

此外,如果以前手动启用,则必须[禁用 Rugged](../high_availability/nfs.html#improving-nfs-performance-with-gitlab) .

Gitaly 作以下假设:

*`gitaly1.internal` Gitaly 服务器可以达到`gitaly1.internal:8075`从 Gitaly 客户端,以及 Gitaly 服务器可以读取和写入`/mnt/gitlab/default``/mnt/gitlab/storage1` .
*`gitaly2.internal` Gitaly 服务器可以达到`gitaly2.internal:8075`从 Gitaly 客户端,以及 Gitaly 服务器可以读取和写入`/mnt/gitlab/storage2` .
*   您的`gitaly1.internal``gitaly2.internal` Gitaly 服务器可以相互访问.

除非您使用特殊的[混合配置进行](#mixed-configuration)设置,否则不能将 Gitaly 服务器定义为本地 Gitaly 服务器(不带`gitaly_address` ),而`gitaly_address`一些服务器定义为远程服务器(带`gitaly_address` ).

**对于所有 GitLab**

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    git_data_dirs({
      'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    }) 
    ```

2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
3.  运行`sudo gitlab-rake gitlab:gitaly:check`确认 Gitaly 客户端可以连接到 Gitaly 服务器.
4.  拖尾日志以查看请求:

    ```
    sudo gitlab-ctl tail gitaly 
    ```

**对于源安装**

1.  Edit `/home/git/gitlab/config/gitlab.yml`:

    ```
    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tcp://gitaly1.internal:8075
            path: /some/dummy/path
          storage1:
            gitaly_address: tcp://gitaly1.internal:8075
            path: /some/dummy/path
          storage2:
            gitaly_address: tcp://gitaly2.internal:8075
            path: /some/dummy/path 
    ```

    **注意:** `/some/dummy/path`应该设置为存在的本地文件夹,但是该文件夹中不会存储任何数据. 解决[此问题](https://gitlab.com/gitlab-org/gitaly/-/issues/1282)后,将不再需要[此操作](https://gitlab.com/gitlab-org/gitaly/-/issues/1282) .
2.  Save the file and [restart GitLab](../restart_gitlab.html#installations-from-source).
3.  运行`sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production`确认 Gitaly 客户端可以连接到 Gitaly 服务器.
4.  拖尾日志以查看请求:

    ```
    tail -f /home/git/gitlab/log/gitaly.log 
    ```

尾随 Gitaly 服务器上的 Gitaly 登录时,您应该会看到请求进入.触发 Gitaly 请求的一种可靠方法是通过 HTTP 或 HTTPS 从 GitLab 克隆存储库.

**危险:**如果已针对每个存储库或全局配置了[服务器挂钩](../server_hooks.html) ,则必须将它们移至 Gitaly 服务器. 如果您有多个 Gitaly 服务器,则将服务器挂钩复制到所有 Gitaly 服务器.

#### Mixed configuration[](#mixed-configuration "Permalink")

GitLab 可以与许多 Gitaly 服务器之一驻留在同一服务器上,但是不支持混合本地和远程配置的配置. 以下设置不正确,因为:

*   所有地址都必须可从其他 Gitaly 服务器访问.
*   `storage1`分配了一个`gitaly_address` Unix 套接字,该套接字对于某些 Gitaly 服务器无效.

```
git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
  'storage1' => { 'path' => '/mnt/gitlab/git-data' },
  'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}) 
```

要组合本地和远程 Gitaly 服务器,请为本地 Gitaly 服务器使用一个外部地址. 例如:

```
git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
  # Address of the GitLab server that has Gitaly running on it
  'storage1' => { 'gitaly_address' => 'tcp://gitlab.internal:8075', 'path' => '/mnt/gitlab/git-data' },
  'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}) 
```

`path`只能包含在本地 Gitaly 服务器上的存储分片中. 如果不包含,则默认的 Git 存储目录将用于该存储碎片.

### Disable Gitaly where not required (optional)[](#disable-gitaly-where-not-required-optional "Permalink")

如果您将 Gitaly [作为远程服务](#run-gitaly-on-its-own-server)运行,则可能要禁用默认情况下在您的 GitLab 服务器上运行的本地 Gitaly 服务,而仅在需要时运行它.

仅当您在自定义群集配置中运行 GitLab 时,才在 GitLab 实例上禁用 Gitaly 才有意义,在该配置中,Gitaly 在与 GitLab 实例不同的机器上运行. 在群集中的所有计算机上禁用 Gitaly 并不是有效的配置(某些计算机充当 Gitaly 服务器).

To disable Gitaly on a GitLab server:

**对于所有 GitLab**

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    gitaly['enable'] = false 
    ```

2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

**对于源安装**

1.  Edit `/etc/default/gitlab`:

    ```
    gitaly_enabled=false 
    ```

2.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .

## Enable TLS support[](#enable-tls-support "Permalink")

在 GitLab 11.8 中[引入](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22602) .

Gitaly 支持 TLS 加密. 要与侦听安全连接的 Gitaly 实例进行通信,必须在 GitLab 配置中相应存储条目的`gitaly_address`中使用`tls://` URL 方案.

您必须提供自己的证书,因为不会自动提供. 与每个 Gitaly 服务器相对应的证书必须安装在该 Gitaly 服务器上.

此外,证书(或其证书颁发机构)必须安装在所有以下组件上:

*   Gitaly 服务器,包括使用证书的 Gitaly 服务器.
*   与之通信的 Gitaly 客户.

该过程记录在[GitLab 自定义证书配置中,](https://docs.gitlab.com/omnibus/settings/ssl.html)并在下面重复进行.

请注意以下几点:

*   证书必须指定用于访问 Gitaly 服务器的地址. 如果你是:
    *   通过主机名寻址 Gitaly 服务器,您可以为此使用"公用名"字段,也可以将其添加为"使用者备用名".
    *   通过其 IP 地址寻址 Gitaly 服务器,必须将其作为主题备用名称添加到证书中. [gRPC 不支持在证书中使用 IP 地址作为公用名](https://github.com/grpc/grpc/issues/2691) .
*   您可以同时为 Gitaly 服务器配置未加密的侦听地址`listen_addr`和已加密的侦听地址`tls_listen_addr` . 这使您可以根据需要从未加密的流量逐渐过渡到加密的流量.

要使用 TLS 配置 Gitaly:

**对于所有 GitLab**

1.  为 Gitaly 服务器创建证书.
2.  在 Gitaly 客户端上,将证书(或其证书颁发机构)复制到`/etc/gitlab/trusted-certs`

    ```
    sudo cp cert.pem /etc/gitlab/trusted-certs/ 
    ```

3.  在 Gitaly 客户端上,如下所示在`/etc/gitlab/gitlab.rb`编辑`git_data_dirs`

    ```
    git_data_dirs({
      'default' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
    }) 
    ```

4.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
5.  在 Gitaly 服务器上,创建`/etc/gitlab/ssl`目录,然后在其中复制密钥和证书:

    ```
    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem 
    ```

6.  将所有 Gitaly 服务器证书(或其证书颁发机构)复制到`/etc/gitlab/trusted-certs`以便 Gitaly 服务器在调用自身或其他 Gitaly 服务器时将信任该证书:

    ```
    sudo cp cert1.pem cert2.pem /etc/gitlab/trusted-certs/ 
    ```

7.  编辑`/etc/gitlab/gitlab.rb`并添加:

    ```
    gitaly['tls_listen_addr'] = "0.0.0.0:9999"
    gitaly['certificate_path'] = "/etc/gitlab/ssl/cert.pem"
    gitaly['key_path'] = "/etc/gitlab/ssl/key.pem" 
    ```

8.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .
9.  通过[观察 Gitaly 连接的类型,](#observe-type-of-gitaly-connections)验证通过 TLS 提供服务的 Gitaly 通信.
10.  (可选)通过以下方式提高安全性:
    1.  通过注释或删除禁用非 TLS 连接`gitaly['listen_addr']``/etc/gitlab/gitlab.rb` .
    2.  保存文件.
    3.  [重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

**对于源安装**

1.  为 Gitaly 服务器创建证书.
2.  在 Gitaly 客户端上,将证书复制到系统受信任的证书中:

    ```
    sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
    sudo update-ca-certificates 
    ```

3.  在 Gitaly 客户端上,如下所示在`/home/git/gitlab/config/gitlab.yml`编辑`storages`

    ```
    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tls://gitaly1.internal:9999
            path: /some/dummy/path
          storage1:
            gitaly_address: tls://gitaly1.internal:9999
            path: /some/dummy/path
          storage2:
            gitaly_address: tls://gitaly2.internal:9999
            path: /some/dummy/path 
    ```

    **注意:** `/some/dummy/path`应该设置为存在的本地文件夹,但是该文件夹中不会存储任何数据. 解决[Gitaly 问题#1282](https://gitlab.com/gitlab-org/gitaly/-/issues/1282)之后,将不再需要此操作.
4.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .
5.  在 Gitaly 服务器上,创建或编辑`/etc/default/gitlab`并添加:

    ```
    export SSL_CERT_DIR=/etc/gitlab/ssl 
    ```

6.  在 Gitaly 服务器上,创建`/etc/gitlab/ssl`目录,然后在其中复制密钥和证书:

    ```
    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem 
    ```

7.  将所有 Gitaly 服务器证书(或其证书颁发机构)复制到系统受信任证书文件夹,以便 Gitaly 服务器在调用自身或其他 Gitaly 服务器时将信任该证书.

    ```
    sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
    sudo update-ca-certificates 
    ```

8.  编辑`/home/git/gitaly/config.toml`并添加:

    ```
    tls_listen_addr = '0.0.0.0:9999'

    [tls]
    certificate_path = '/etc/gitlab/ssl/cert.pem'
    key_path = '/etc/gitlab/ssl/key.pem' 
    ```

9.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .
10.  通过[观察 Gitaly 连接的类型,](#observe-type-of-gitaly-connections)验证通过 TLS 提供服务的 Gitaly 通信.
11.  (可选)通过以下方式提高安全性:
    1.  通过注释掉或删除`/home/git/gitaly/config.toml` `listen_addr`来禁用非 TLS 连接.
    2.  保存文件.
    3.  [重新启动 GitLab](../restart_gitlab.html#installations-from-source) .

### Observe type of Gitaly connections[](#observe-type-of-gitaly-connections "Permalink")

可以使用[Prometheus](../monitoring/prometheus/index.html)观察 Gitaly 为生产环境提供服务的连接类型. 使用以下 Prometheus 查询:

```
sum(rate(gitaly_connections_total[5m])) by (type) 
```

## `gitaly-ruby`[](#gitaly-ruby "Permalink")

开发 Gitaly 是为了替代 GitLab 中的 Ruby 应用程序代码.

为了节省时间并避免重写现有应用程序逻辑的风险,我们选择将一些应用程序代码从 GitLab 复制到 Gitaly.

为了能够运行该代码,创建了`gitaly-ruby` ,它是主要 Gitaly Go 流程的" sidecar"流程. 在`gitaly-ruby`中实现的一些示例如下:

*   处理 Wiki 的 RPC.
*   代表用户创建提交的 RPC,例如合并提交.

### Configure number of `gitaly-ruby` workers[](#configure-number-of-gitaly-ruby-workers "Permalink")

`gitaly-ruby`容量比 Go 中实现的 Gitaly 少得多. 如果您的 Gitaly 服务器必须处理大量请求,则仅设置一个活动的`gitaly-ruby`车的默认设置可能不够.

如果您看到 Gitaly 出现`ResourceExhausted`错误,则很可能是您的`gitaly-ruby`能力不足.

您可以使用以下设置来增加 Gitaly 服务器上的`gitaly-ruby`进程数:

**对于所有 GitLab**

1.  Edit `/etc/gitlab/gitlab.rb`:

    ```
    # Default is 2 workers. The minimum is 2; 1 worker is always reserved as
    # a passive stand-by.
    gitaly['ruby_num_workers'] = 4 
    ```

2.  保存文件并[重新配置 GitLab](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

**对于源安装**

1.  Edit `/home/git/gitaly/config.toml`:

    ```
    [gitaly-ruby]
    num_workers = 4 
    ```

2.  保存文件并[重新启动 GitLab](../restart_gitlab.html#installations-from-source) .

## Limit RPC concurrency[](#limit-rpc-concurrency "Permalink")

克隆流量可能会对您的 Gitaly 服务造成很大的压力. 大部分工作在以下任一 RPC 中完成:

*   `SSHUploadPack` (用于 Git SSH).
*   `PostUploadPack` (用于 Git HTTP).

为了防止此类工作负载使您的 Gitaly 服务器不堪重负,您可以在 Gitaly 的配置文件中设置并发限制. 例如:

```
# in /etc/gitlab/gitlab.rb

gitaly['concurrency'] = [
  {
    'rpc' => "/gitaly.SmartHTTPService/PostUploadPack",
    'max_per_repo' => 20
  },
  {
    'rpc' => "/gitaly.SSHService/SSHUploadPack",
    'max_per_repo' => 20
  }
] 
```

这限制了给定 RPC 正在进行的 RPC 调用的数量. 该限制适用于每个存储库. 在上面的示例中:

*   Gitaly 服务器提供服务的每个存储库最多可以同时`PostUploadPack` 20 个`PostUploadPack` RPC 调用,而`SSHUploadPack`则相同.
*   如果另一个请求进入了已用完其 20 个插槽的存储库,则该请求将排队.

您可以使用 Gitaly 日志和 Prometheus 观察此队列的行为:

*   在 Gitaly 日志中,查找字符串(或结构化日志字段) `acquire_ms` . 具有此字段的消息正在报告有关并发限制器的信息.
*   在 Prometheus 中,查找以下指标:

    *   `gitaly_rate_limiting_in_progress`.
    *   `gitaly_rate_limiting_queued`.
    *   `gitaly_rate_limiting_seconds`.

**注意:**尽管 Prometheus 度量标准的名称包含`rate_limiting` ,但它是并发限制器,而不是速率限制器. 如果 Gitaly 客户端非常快地连续发出 1000 个请求,则并发不会超过 1,并且并发限制器无效.

## Rotate Gitaly authentication token[](#rotate-gitaly-authentication-token "Permalink")

在生产环境中轮换凭证通常需要停机,导致停机或两者兼而有之.

但是,您可以旋转 Gitaly 凭据而不会中断服务. 旋转 Gitaly 身份验证令牌涉及:

*   [Verifying authentication monitoring](#verify-authentication-monitoring).
*   [Enabling “auth transitioning” mode](#enable-auth-transitioning-mode).
*   [Updating Gitaly authentication tokens](#update-gitaly-authentication-token).
*   [Ensuring there are no authentication failures](#ensure-there-are-no-authentication-failures).
*   [Disabling “auth transitioning” mode](#disable-auth-transitioning-mode).
*   [Verifying authentication is enforced](#verify-authentication-is-enforced).

如果您在单个服务器上运行 GitLab,则此过程也适用. 在这种情况下," Gitaly 服务器"和" Gitaly 客户端"是指同一台计算机.

### Verify authentication monitoring[](#verify-authentication-monitoring "Permalink")

旋转 Gitaly 身份验证令牌之前,请验证您可以使用 Prometheus 监视 GitLab 安装的身份验证行为. 使用以下 Prometheus 查询:

```
sum(rate(gitaly_authentications_total[5m])) by (enforced, status) 
```

在正确配置了身份验证并且您拥有实时流量的系统中,您将看到以下内容:

```
{enforced="true",status="ok"}  4424.985419441742 
```

可能还存在速率为 0 的其他数字.我们只关心非零数字.

唯一的非零数字应具有`enforced="true",status="ok"` . 如果您还有其他非零数字,则说明您的配置有问题.

`status="ok"`数字反映您当前的请求率. 在上面的示例中,Gitaly 每秒处理大约 4000 个请求.

既然您已经确定可以监视 GitLab 安装的 Gitaly 身份验证行为,则可以开始其余过程.

### Enable “auth transitioning” mode[](#enable-auth-transitioning-mode "Permalink")

通过将 Gitaly 服务器置于"身份验证过渡"模式,从而暂时禁用 Gitaly 服务器上的 Gitaly 身份验证,如下所示:

```
# in /etc/gitlab/gitlab.rb
gitaly['auth_transitioning'] = true 
```

进行此更改后,您的[Prometheus 查询](#verify-authentication-monitoring)应返回如下内容:

```
{enforced="false",status="would be ok"}  4424.985419441742 
```

因为`enforced="false"` ,所以可以安全地开始部署新令牌.

### Update Gitaly authentication token[](#update-gitaly-authentication-token "Permalink")

要在每个 Gitaly 客户端**和** Gitaly 服务器上更新为新的 Gitaly 身份验证令牌,请执行以下操作:

1.  更新配置:

    ```
    # in /etc/gitlab/gitlab.rb

    gitaly['auth_token'] = '<new secret token>' 
    ```

2.  重新启动 Gitaly:

    ```
    gitlab-ctl restart gitaly 
    ```

如果在实施此更改的同时运行[Prometheus 查询](#verify-authentication-monitoring) ,您将看到被`enforced="false",status="denied"`计数器的非零值.

### Ensure there are no authentication failures[](#ensure-there-are-no-authentication-failures "Permalink")

设置新令牌并重新启动所有涉及的服务之后,您将[临时看到以下内容](#verify-authentication-monitoring)的组合:

*   `status="would be ok"`.
*   `status="denied"`.

在所有 Gitaly 客户端和 Gitaly 服务器获取了新令牌之后,应`enforced="false",status="would be ok"` **唯一的非零费率** `enforced="false",status="would be ok"` .

### Disable “auth transitioning” mode[](#disable-auth-transitioning-mode "Permalink")

要重新启用 Gitaly 身份验证,请禁用"身份验证转换"模式. 如下更新您的 Gitaly 服务器上的配置:

```
# in /etc/gitlab/gitlab.rb
gitaly['auth_transitioning'] = false 
```

**警告:**如果不完成此步骤,则**没有 Gitaly 身份验证** .

### Verify authentication is enforced[](#verify-authentication-is-enforced "Permalink")

刷新您的[Prometheus 查询](#verify-authentication-monitoring) . 现在,您应该会看到与开始时相似的结果. 例如:

```
{enforced="true",status="ok"}  4424.985419441742 
```

请注意, `enforced="true"`表示正在执行身份验证.

## Direct Git access bypassing Gitaly[](#direct-git-access-bypassing-gitaly "Permalink")

虽然可以使用 Git 客户端直接访问磁盘上存储的 Gitaly 存储库,但由于不断改进和更改 Gitaly,因此不建议这样做. 这些改进可能会使假设无效,从而导致性能下降,不稳定甚至数据丢失.

Gitaly 进行了优化,例如[`info/refs`广告缓存](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/design_diskcache.md) ,它依赖于 Gitaly 通过官方 gRPC 接口控制和监视对存储库的访问. 同样,Praefect 具有优化功能,例如容错和分布式读取,这些优化取决于 gRPC 接口和数据库来确定存储库状态.

由于这些原因, **直接访问存储库需要您自担风险,并且不受支持** .

## Direct access to Git in GitLab[](#direct-access-to-git-in-gitlab "Permalink")

直接访问 Git 使用 GitLab 中称为" Rugged patch"的代码.

### History[](#history "Permalink")

在 Gitaly 存在之前,现在 Gitaly 客户端用来直接访问 Git 存储库的是:

*   如果是单机 Omnibus GitLab 安装,则在本地磁盘上
*   如果是水平缩放的 GitLab 安装,请使用 NFS.

除了运行简单的`git`命令之外,GitLab 还使用了一个名为[Rugged](https://github.com/libgit2/rugged)的 Ruby 库. Rugged 是围绕[libgit2](https://libgit2.org/)的包装, [libgit2](https://libgit2.org/)是 C 库形式的 Git 的独立实现.

随着时间的流逝,很明显 Rugged(特别是与[Unicorn](https://yhbt.net/unicorn/)结合使用)非常有效. 因为`libgit2`是一个库而不是一个外部进程,所以之间的开销很小:

*   GitLab 应用程序代码试图在 Git 存储库中查找数据.
*   Git 实现本身.

由于 Rugged 和 Unicorn 的组合是如此有效,因此 GitLab 的应用程序代码最终会进行大量重复的 Git 对象查找. 例如,查找`master`在一个请求中提交了十几次. 我们可以编写效率低下的代码而不会降低性能.

当我们将这些 Git 查找迁移到 Gitaly 调用时,我们突然发现每个 Git 查找的固定成本要高得多. 即使 Gitaly 能够重新使用已经在运行的`git`进程(例如,查找提交),您仍然可以:

*   往返于 Gitaly 的网络费用.
*   在 Gitaly 中,是将 Gitaly 连接到`git`进程的 Unix 管道上的写入/读取往返.

使用 GitLab.com 进行测量,我们减少了每个请求的 Gitaly 呼叫次数,直到不再感觉到 Rugged 效率的下降. 这也有助于我们直接在 Git 文件服务器上运行 Gitaly 本身,而不是通过 NFS 挂载. 这给了我们提速,抵消了不再使用 Rugged 带来的负面影响.

不幸的是,GitLab 的其他部署无法像我们在 GitLab.com 上那样删除 NFS,这两个方面都是最糟糕的:

*   NFS 的速度较慢.
*   The increased inherent overhead of Gitaly.

在 Gitaly 迁移项目期间从 GitLab 中删除的代码影响了这些部署. 作为这些基于 NFS 的部署的性能变通办法,我们重新引入了一些旧的 Rugged 代码. 重新引入的代码被非正式地称为" Rugged patch".

### How it works[](#how-it-works "Permalink")

执行直接 Git 访问的 Ruby 方法位于[功能标志的](../../development/gitaly.html#legacy-rugged-code)后面,默认情况下处于禁用状态. 设置功能标记以获得最佳性能并不方便,因此我们添加了一种自动机制,可以直接访问 Git.

当 GitLab 调用具有"加固补丁"的函数时,它将执行两项检查:

*   数据库中是否设置了此补丁程序的功能标志? 如果是这样,功能标记设置将控制 GitLab 对"坚固补丁"代码的使用.
*   如果未设置功能标志,则 GitLab 尝试直接访问 Gitaly 服务器下方的文件系统. 如果可以,它将使用" Rugged patch".

这两个检查的结果都被缓存.

为了查看 GitLab 是否可以直接访问存储库文件系统,我们使用以下启发式:

*   Gitaly 确保文件系统在其根目录中具有一个带有 UUID 的元数据文件.
*   Gitaly 通过`ServerInfo` RPC 将此 UUID 报告给 GitLab.
*   GitLab Rails 尝试直接读取元数据文件. 如果存在,并且 UUID 匹配,则假定我们具有直接访问权限.

默认情况下,在 Omnibus GitLab 中启用直接 Git 访问,因为它会在 GitLab 配置文件`config/gitlab.yml`填写正确的存储库路径. 这满足了 UUID 检查.

### Transition to Gitaly Cluster[](#transition-to-gitaly-cluster "Permalink")

为了消除复杂性,我们必须删除 GitLab 中的直接 Git 访问. 但是,只要某些 GitLab 安装需要 NFS 上的 Git 存储库,我们就无法删除它.

我们在 GitLab 中删除直接 Git 访问的工作有两个方面:

*   减少 GitLab 进行的低效率 Gitaly 查询的数量.
*   说服容错或水平扩展的 GitLab 实例的管理员从 NFS 迁移.

第二个方面是唯一真正的解决方案. 为此,我们开发了[Gitaly Cluster](praefect.html) .

## Troubleshooting Gitaly[](#troubleshooting-gitaly "Permalink")

### Checking versions when using standalone Gitaly servers[](#checking-versions-when-using-standalone-gitaly-servers "Permalink")

使用独立的 Gitaly 服务器时,必须确保它们与 GitLab 的版本相同,以确保完全兼容. 检查您的 GitLab 实例上的**管理区域> Gitaly 服务器** ,并确认所有 Gitaly 服务器都是`Up to date` .

[![Gitaly standalone software versions diagram](img/ba685b05a8bb7c09fe3b58048ac4884e.png)](img/gitlab_gitaly_version_mismatch_v12_4.png)

### `gitaly-debug`[](#gitaly-debug "Permalink")

`gitaly-debug`命令提供用于" Gitaly"和" Git"性能的"生产调试"工具. 它旨在帮助生产工程师和支持工程师调查 Gitaly 性能问题.

如果您使用的是 GitLab 11.6 或更高版本,则此工具应已安装在您的 GitLab / Gitaly 服务器上,位于`/opt/gitlab/embedded/bin/gitaly-debug` . 如果要研究旧版本的 GitLab,可以离线编译此工具,然后将可执行文件复制到服务器:

```
git clone https://gitlab.com/gitlab-org/gitaly.git
cd cmd/gitaly-debug
GOOS=linux GOARCH=amd64 go build -o gitaly-debug 
```

要查看`gitaly-debug`的帮助页面以`gitaly-debug`受支持的子命令列表,请运行:

```
gitaly-debug -h 
```

### Commits, pushes, and clones return a 401[](#commits-pushes-and-clones-return-a-401 "Permalink")

```
remote: GitLab: 401 Unauthorized 
```

您将需要将`gitlab-secrets.json`文件与 Gitaly 客户端(GitLab 应用程序节点)同步.

### Client side gRPC logs[](#client-side-grpc-logs "Permalink")

Gitaly 使用[gRPC](https://grpc.io/) RPC 框架. Ruby gRPC 客户端具有自己的日志文件,当您看到 Gitaly 错误时,该文件可能包含有用的信息. 您可以使用`GRPC_LOG_LEVEL`环境变量控制 gRPC 客户端的日志级别. 默认级别为`WARN` .

您可以使用以下命令运行 gRPC 跟踪:

```
sudo GRPC_TRACE=all GRPC_VERBOSITY=DEBUG gitlab-rake gitlab:gitaly:check 
```

### Observing `gitaly-ruby` traffic[](#observing-gitaly-ruby-traffic "Permalink")

[`gitaly-ruby`](#gitaly-ruby)[`gitaly-ruby`](#gitaly-ruby)的内部实现细节,因此,对`gitaly-ruby`流程内部发生的情况`gitaly-ruby` .

如果已设置 Prometheus 来抓取 Gitaly 进程,则可以通过查询`grpc_client_handled_total``grpc_client_handled_total` `gitaly-ruby`各个 RPC 的请求率和错误代码. 严格来说,此度量标准并未区分`gitaly-ruby`和其他 RPC,但实际上(自 GitLab 11.9 起),Gitaly 本身进行的所有 gRPC 调用都是从 Gitaly 主过程到其`gitaly-ruby`边车之一的内部调用.

假设您的`grpc_client_handled_total`计数器仅观察到 Gitaly,以下查询将显示 RPC 在内部(最有可能)实现为对`gitaly-ruby`调用:

```
sum(rate(grpc_client_handled_total[5m])) by (grpc_method) > 0 
```

### Repository changes fail with a `401 Unauthorized` error[](#repository-changes-fail-with-a-401-unauthorized-error "Permalink")

如果您在自己的服务器上运行 Gitaly,并注意到用户可以成功克隆和获取存储库(通过 SSH 和 HTTPS),但是在未获得`401 Unauthorized`情况下,无法推送到它们或在 Web UI 中对存储库进行更改消息,那么 Gitaly 可能由于拥有[错误的 secrets 文件](#configure-gitaly-servers)而无法通过 Gitaly 客户端进行身份验证.

确认以下所有内容均正确:

*   When any user performs a `git push` to any repository on this Gitaly server, it fails with the following error (note the `401 Unauthorized`):

    ```
    remote: GitLab: 401 Unauthorized
    To <REMOTE_URL>
    ! [remote rejected] branch-name -> branch-name (pre-receive hook declined)
    error: failed to push some refs to '<REMOTE_URL>' 
    ```

*   当任何用户使用 GitLab UI 从存储库添加或修改文件时,该文件都会立即失败,并显示红色`401 Unauthorized`横幅.
*   创建一个新项目并[使用 README 对其进行初始化会](../../gitlab-basics/create-project.html#blank-projects)成功创建该项目,但不会创建 README.
*   [将日志尾随在](https://docs.gitlab.com/omnibus/settings/logs.html) Gitaly 客户端上并重现该错误时,到达`/api/v4/internal/allowed`端点时会出现`401`错误:

    ```
    # api_json.log
    {
      "time": "2019-07-18T00:30:14.967Z",
      "severity": "INFO",
      "duration": 0.57,
      "db": 0,
      "view": 0.57,
      "status": 401,
      "method": "POST",
      "path": "\/api\/v4\/internal\/allowed",
      "params": [
        {
          "key": "action",
          "value": "git-receive-pack"
        },
        {
          "key": "changes",
          "value": "REDACTED"
        },
        {
          "key": "gl_repository",
          "value": "REDACTED"
        },
        {
          "key": "project",
          "value": "\/path\/to\/project.git"
        },
        {
          "key": "protocol",
          "value": "web"
        },
        {
          "key": "env",
          "value": "{\"GIT_ALTERNATE_OBJECT_DIRECTORIES\":[],\"GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE\":[],\"GIT_OBJECT_DIRECTORY\":null,\"GIT_OBJECT_DIRECTORY_RELATIVE\":null}"
        },
        {
          "key": "user_id",
          "value": "2"
        },
        {
          "key": "secret_token",
          "value": "[FILTERED]"
        }
      ],
      "host": "gitlab.example.com",
      "ip": "REDACTED",
      "ua": "Ruby",
      "route": "\/api\/:version\/internal\/allowed",
      "queue_duration": 4.24,
      "gitaly_calls": 0,
      "gitaly_duration": 0,
      "correlation_id": "XPUZqTukaP3"
    }

    # nginx_access.log
    [IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby" 
    ```

要解决此问题,请确认 Gitaly 服务器上的 gitlab [`gitlab-secrets.json`文件](#configure-gitaly-servers)与 Gitaly 客户端上的[文件](#configure-gitaly-servers)匹配. 如果不匹配,请更新 Gitaly 服务器上的密码文件以匹配 Gitaly 客户端,然后[重新配置](../restart_gitlab.html#omnibus-gitlab-reconfigure) .

### Command line tools cannot connect to Gitaly[](#command-line-tools-cannot-connect-to-gitaly "Permalink")

如果使用命令行(CLI)工具连接到 Gitaly 服务器时遇到问题,并且某些操作导致出现`14: Connect Failed`错误消息,则意味着 gRPC 无法访问您的 Gitaly 服务器.

确认您可以通过 TCP 到达 Gitaly:

```
sudo gitlab-rake gitlab:tcp_check[GITALY_SERVER_IP,GITALY_LISTEN_PORT] 
```

如果 TCP 连接失败,请检查您的网络设置和防火墙规则. 如果 TCP 连接成功,则您的网络和防火墙规则正确.

如果您在命令行环境(例如 Bash)中使用代理服务器,则这些代理服务器可能会干扰您的 gRPC 通信.

如果使用 Bash 或兼容的命令行环境,请运行以下命令来确定是否配置了代理服务器:

```
echo $http_proxy
echo $https_proxy 
```

如果这些变量中的任何一个都有值,则您的 Gitaly CLI 连接可能正在通过无法连接到 Gitaly 的代理进行路由.

要删除代理设置,请运行以下命令(取决于哪些变量具有值):

```
unset http_proxy
unset https_proxy 
```

### Gitaly not listening on new address after reconfiguring[](#gitaly-not-listening-on-new-address-after-reconfiguring "Permalink")

当更新`gitaly['listen_addr']``gitaly['prometheus_listen_addr']`值时,Gitaly 可能会在`sudo gitlab-ctl reconfigure`后继续侦听旧地址.

发生这种情况时,执行`sudo gitlab-ctl restart`将解决此问题. 解决[此问题](https://gitlab.com/gitlab-org/gitaly/-/issues/2521)后,将不再需要[此操作](https://gitlab.com/gitlab-org/gitaly/-/issues/2521) .

### Permission denied errors appearing in Gitaly logs when accessing repositories from a standalone Gitaly server[](#permission-denied-errors-appearing-in-gitaly-logs-when-accessing-repositories-from-a-standalone-gitaly-server "Permalink")

如果即使文件权限正确也发生此错误,则 Gitaly 服务器可能正在发生[时钟漂移](https://en.wikipedia.org/wiki/Clock_drift) .

请确保 Gitaly 客户端和服务器已同步,并在可能的情况下使用 NTP 时间服务器保持同步.

### Praefect[](#praefect "Permalink")

Praefect 是 Gitaly 的路由器和事务管理器,并且是运行 Gitaly 集群的必需组件. 有关更多信息,请参见[Gitaly Cluster](praefect.html) .