gitlab部署与基本使用

环境

  • 系统:centos7
  • 内核:3.10.0-693.el7.x86_64
  • 配置:4G/8G

软件包

https://packages.gitlab.com/gitlab/gitlab-ce

选择自己需要的包

下载安装

1、rpm安装

[root@localhost ~]# wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-10.2.3-ce.0.el7.x86_64.rpm 
[root@localhost ~]# rpm -ivh gitlab-ce-10.2.3-ce.0.el7.x86_64.rpm

2、yum安装

配置yum环境

[root@localhost ~]# cat /etc/yum.repos.d/gitlab.repo
[gitlab-ce]
name=gitlab-ce   
baseurl=http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7   
repo_gpgcheck=0   
gpgcheck=0   
enabled=1   
gpgkey= 
[root@localhost ~]# yum clean all
[root@localhost ~]# yum -y install gitlab-ce

3、自动安装

[root@localhost ~]# curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

依赖关系安装

安装curl、policycoreutils、openssh-server、openssh-clients,安装postfix以便发送邮件

[root@localhost ~]# yum install curl policycoreutils openssh-server openssh-clients postfix  -y

关闭防火墙firewalld

修改gitlab配置文件

[root@localhost ~]# egrep -v "^$|^#" /etc/gitlab/gitlab.rb 
external_url 'http://192.168.192.148'

重新配置应用程序,每次修改配置文件都要执行此命令,重新加载配置文件

[root@localhost ~]# gitlab-ctl reconfigure

gitlab管理

启动

[root@localhost ~]# gitlab-ctl start

关闭

[root@localhost ~]# gitlab-ctl stop

状态

[root@localhost ~]# gitlab-ctl status

重启

[root@localhost ~]# gitlab-ctl restart

列出所有服务

[root@localhost ~]# gitlab-ctl service-list

显示配置

[root@localhost ~]# gitlab-ctl show-config

默认配置文件位置说明

  • 主配置文件:/etc/gitlab/gitlab.rb

  • 日志地址:/var/log/gitlab

  • 服务地址:/var/opt/gitlab

  • 仓库地址:/var/opt/gitlab/git-data

gitlab页面操作

访问

192.168.192.48默认端口80,首次登陆需要为root用户创建一个不少于8位的密码

关闭注册,避免一些不必要的麻烦

项目和群组有一定的关联性,一般以群组区分不同的项目

创建群组

未分类

群组创建名称最好是一个可识别的名称,根据重要等级不同,可以选择不同的可见性

创建项目

未分类

选择关联的组,后边指定项目名称,可见等级根据不同的项目可以做调整

创建用户

未分类

邮箱中会收到一个邮件,用户通过此邮件进行密码设置

未分类

关联用户、组,给与用户不同的权限

未分类

添加测试文件

未分类

在下方写入相关代码

未分类

未分类

下载代码

安装git

[root@localhost ~]# yum -y install git

未分类

可以git表示部署成功

gitlab-创建简单的项目

1.新建目录

$ mkdir testproject
$ cd testproject

2.新建项目文件

$ touch README.md

3.初始化项目

$ git init

4.添加远程仓库:

$ git remote add origin [email protected]:deploy/testproject.git
  git remote add origin [email protected]:<组>/<项目名称>.git

远程仓库必须存在此组。  

5.加入需要版本管理的文件

$ git add ./README.md
$ git commit -am 'init project'

6.提交

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 202 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)

7.在gitlab dashboard就可以看到项目已经提交成功

未分类

Docker Compose实例之nginx反向代理GitLab

在上一篇文章(Docker快速搭建GitLab私有仓库)中探索了如何用docker实现最简单的GitLab服务。但是现实场景中往往会遇到复杂的情况和需求,光用docker指令可能就比较繁琐了。

举个例子???? 如下图所示,在一个服务器上要部署一个GitLab,N个其它服务(那N个服务或许还要与GitLab进行隔离),如果用docker 指令一个一个的run起来,管理起来可就麻烦了。 网络示意图

未分类

当然docker作为流行工具,不会让我们那么累,我们借助Docker Compose的文件来描述这个多容器的配置,并通过一条命令就能启动这些容器。

Docker Compose 的配置文件 docker-compose.yml 如下:

version: '3.6'
services:
  gitlab: # gitlab服务名
    container_name: gitlab-site # gitlab 容器名
    image: gitlab/gitlab-ce:latest
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.com'  # git域名
        unicorn['worker_timeout'] = 60
        unicorn['worker_processes'] = 2
        nginx['enable'] = true
        nginx['client_max_body_size'] = '250m'
        nginx['redirect_http_to_https'] = true
        nginx['ssl_certificate'] = "/etc/ssl/gitlab.example.com.crt" # 加密证书文件
        nginx['ssl_certificate_key'] = "/etc/ssl/gitlab.example.com.key"
        nginx['ssl_ciphers'] = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
        nginx['ssl_prefer_server_ciphers'] = "on"
        nginx['ssl_protocols'] = "TLSv1.1 TLSv1.2"
        nginx['ssl_session_cache'] = "builtin:1000  shared:SSL:10m"
        nginx['listen_addresses'] = ["0.0.0.0"]
        nginx['http2_enabled'] = true
    volumes:
      - "/srv/gitlab/config:/etc/gitlab"         # 此处使用的是绝对路径
      - "/srv/gitlab/logs:/var/log/gitlab"
      - "/srv/gitlab/data:/var/opt/gitlab"
      - "/srv/ssl:/etc/ssl"                         # 加密证书文件路径映射
    networks:
      - git-network  # 使用 git-network 网络,与 other-network 相隔离
other-app: # 用 nginx 模拟的其它服务
    container_name: other-app-nginx
    image: nginx:stable-alpine
    volumes:
      - "./nginx-conf-site:/etc/nginx/conf.d:ro"     # 此处使用的是相对路径
      - "./contents:/usr/share/nginx/html/sites:ro" # 相对的是 docker-compose.yml 的位置
    networks:
      - other-network   # 使用 other-network 网络,与 git-network 相隔离
  nginx-reverse:  # nginx 反向代理服务
    container_name: nginx-reverse
    depends_on:    # 反向代理依赖的服务名
      - gitlab  
      - other-app
    image: nginx:stable-alpine
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - "./nginx-conf-reverse:/etc/nginx/conf.d:ro"  # 此处使用的是相对路径
      - "/srv/ssl:/etc/ssl:ro"   # 此处使用的是绝对炉具
    networks:  # nginx反向代理使用的网络
      - git-network     # gitlab使用的网络
      - other-network  # 其它app使用的网络
networks:  # 声明网络
  git-network:  
  other-network:
nginx反向代理的配置文件1: git-reverse.conf ,放在与docker-compose.yml 所在目录相对的 nginx-conf-reverse 目录下,作用是将对 https://gitlab.example.com 的访问进行转发

server{
    listen      443 ssl http2;    # 监听 443 端口
    listen [::]:443 ssl http2;
    server_name gitlab.example.com;

    ssl_certificate        /etc/ssl/gitlab.example.com.crt;
    ssl_certificate_key    /etc/ssl/gitlab.example.com.key;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;

    location / {
      proxy_pass https://gitlab-site;   # 转发给名为 "gitlab-site" 的 容器
    }
}

nginx反向代理的配置文件2: other-reverse.conf ,放在与docker-compose.yml 所在目录相对的 nginx-conf-reverse 目录下, 作用是将对 http://other.example.com 的访问进行转发

server{
    listen      80;   # 监听 80 端口
    server_name other.example.com;  # 其它服务的域名
    location / {
      proxy_pass http://other-app-nginx;  # 转发到"其它"服务
    }
}
本例中的“其它服务”由一个nginx静态网站模拟,其配置文件other-site.conf放在与docker-compose.yml 所在目录相对的 nginx-conf-site 目录下:

server {
    listen 80;
    server_name other.example.com;
    location / {
        root   /usr/share/nginx/html/sites/other-site;
        index  index.html;
    }
}

当然,上述配置中用 nginx 模拟的“其它服务” 可以是任意的网络服务,你不需要的话,把这部分删掉也没问题。

最后,执行一个指令

sudo docker-compose up -d

GitLab服务、其它服务、Nginx反向代理 就会依次启动起来。

使用Docker和GitLab构建一个CI/CD Pipeline

本文主要讲述了如何在GitLab上使用Docker镜像构建一个CI/CD的Pipeline。

现如今持续集成(CI)和持续交付(CD)大家已经不陌生了,它们是为了辅助你的产品/工程项目能够更快、更容易地运行最新版本。在这篇文章中,我将讲述如何使用Docker镜像和GitLab的CI/CD工具构建一个Pipeline,在一个VPS/KVM Linux服务器上进行部署。

前提要求

  • 对Linux、Docker以及CI/CD有基本的了解。
  • GitLab帐号(免费计划即可)。
  • 一台具备SSH访问权限的Linux服务器(非root用户即可)。我使用的是带有LAMP技术栈的Ubuntu 16.04 LTS系统。
  • 装有SSH和LFTP的轻量级Docker镜像。

在开始之前,你需要确保:

  • 你已经登录GitLab
  • 你是某个project/repository的拥有者
  • 你能够在本地机器通过Git访问这个repo进行pull和push操作

我用的是GitKraken,一个Git GUI工具,能够较为方面的进行Git操作。

关于GitLab的CI/CD

GitLab提供了一种通过Docker和Shared Runners处理CI/CD Pipeline的简单方法。每次运行Pipeline时,GitLab都会创建一个独立的虚拟机并构建一个Docker镜像。Pipeline可以使用YAML配置文件进行配置,一个Pipeline可以有多个job,但如果job太多,Pipeline的运行时间就较长。我们肯定不希望这样,因为使用免费计划,每月最多可以有2000分钟的构建时间。

“GitLab.com上的Shared Runners以自动缩放模式运行,由DigitalOcean提供支持。自动缩放意味着减少启动构建的等待时间,并为每个项目建立隔离虚拟机,从而最大限度地提高安全性。”
——来自GitLab文档中的描述

为GitLab的runner创建SSH密钥

注意:即使你的服务器上已有具备SSH访问方式,还是建议你为CI/CD创建一套新的密钥,同时为部署流程创建一个新的非root用户。

我们将在Docker容器中通过SSH连接我们的服务器,这就意味着我们不能输入用户密码(即非交互式登录),因此我们需要在本地计算机中创建无密码的SSH密钥对。通常我会创建一个2048字节的RSA密钥,因为这足够安全。

$ ssh-keygen rsa -b 2048

输入以上命令,跟随创建步骤,如果对创建步骤有疑问,使用man ssh-key。记住不要为密钥对设置密码。创建完成后,我们需要把私钥导入我们的服务器:

$ ssh-copy-id -i /path/to/key user@host

现在你可以尝试通过以下命令连接:

$ ssh -i /path/to/key user@host

连接过程应该不会让你输入密码。这个私钥我们后面会使用到。

选择Dockerfile

我使用Docker Hub来存放我的定制化Dockerfile,这个Dockerfile将基于Alpine构建一个安装有OpenSSH和LFTP的轻量级镜像(大约8Mb)。在GitLab的CI/CD中我们需要使用这个镜像来运行Pipeline的job和脚本,镜像越轻量意味着下载镜像的时间就越少。你可以用你自己的镜像或者用我的Dockerfile。

Pipleline的配置

在正式构建前,你需要在你repo的根目录创建一个”.gitlab-ci.yml”文件。接下来我将解释我使用的配置文件,如果有兴趣,你可以先到GitLab官网阅读配置文件格式以及所有可以使用的配置项。

我的配置文件如下:

image: jimmyadaro/gitlab-ci-cd:latest
Deploy:
stage: deploy
only:
— ‘master’
when: manual
allow_failure: false
before_script:
#Create .ssh directory
— mkdir -p ~/.ssh
#Save the SSH private key
— echo “$SSH_PRIVATE_KEY” > ~/.ssh/id_rsa
— chmod 700 ~/.ssh
— chmod 600 ~/.ssh/id_rsa
— eval $(ssh-agent -s)
— ssh-add ~/.ssh/id_rsa
script:
#Backup everything in /var/www/html/
— ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa $USERNAME@$HOST “zip -q -r /var/backups/www/01-Deploy-$(date +%F_%H-%M-%S).zip /var/www/html/”
#Deploy new files to /var/www/html
— lftp -d -u $USERNAME, -e ‘set sftp:auto-confirm true; set sftp:connect-program “ssh -a -x -i ~/.ssh/id_rsa”; mirror -Rnev ./ /var/www/html — ignore-time — exclude-glob .git* — exclude .git/; exit’ sftp://$HOST
— rm -f ~/.ssh/id_rsa
— ‘echo Deploy done: $(date “+%F %H:%M:%S”)’

让我们逐行看看配置文件的每一步都在做什么。

image: jimmyadaro/gitlab-ci-cd:latest

这行将告诉runner从Docker Hub上拉取并运行最新版本的容器。你可以在这里设置你想要使用的镜像,但别忘了给镜像安装OpenSSH和LFTP。

Deploy:

这行设置了pipeline的job名字,创建一个job必须设置这行内容。

stage: deploy

这行设置了job的stage名字,如果你需要运行多个stage,例如“backup”、“build”、“deploy”等,stage名字将帮助你识别当前Pipeline处于什么状态。由于我不需要其他stage,所以我只用了一个job,并且这个job只有一个stage。对于job和stage的名字可以任意设置,例如你的job可以叫“ASDF”,stage可以叫“GHJK”,不过如果你有多个stage,你肯定需要鉴别不同的stage,因此我建议还是规范化这些名字。

only:
— ‘master’

这行表示Pipeline只有当你repo的master分支收到一个更新(例如git merge)时才会被触发。因此,我建议开发使用其他分支(例如development、wip等),然后使用master分支作为“产品分支”。

when: manual

这行表示你需要进入你的project的CI/CD配置中手动触发整个部署流程。当然,这一步是可以跳过的,只是我更喜欢手动触发Pipeline。如果去掉这行,你所选分支(本例中为master)的任何改动都会触发一次Pipeline。

allow_failure: false

这行表示如果你的Pipeline中有其他stage,当一个job中发生错误时,不允许继续执行剩余任务。这是一个可选配置。

before_script:
#Create .ssh directory
— mkdir -p ~/.ssh
#Save the SSH private key
— echo “$SSH_PRIVATE_KEY” > ~/.ssh/id_rsa
— chmod 700 ~/.ssh
— chmod 600 ~/.ssh/id_rsa
— eval $(ssh-agent -s)
— ssh-add ~/.ssh/id_rsa

before_script单元设置的所有命令都会在执行主单元(main script)之前执行。如你所见,每行shell命令需要用短横线(“-“)指定。上面的命令将把我们刚刚生成的SSH私钥保存到容器默认的SSH路径下,这样我们就可以免密连接我们的服务器。

刚刚生成的私钥将作为Protected变量保存在我的project的CI/CD配置中,在GitLab的web UI上,点击Settings > CI/CD > Variables将看到这个变量。同样,我将服务器地址和部署使用的用户名(非root用户)也使用Protected变量保存。

未分类

script:
#Backup everything in /var/www/html/
— ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa $USERNAME@$HOST “zip -q -r /var/backups/www/01-Deploy-$(date +%F_%H-%M-%S).zip /var/www/html/”
#Deploy new files to /var/www/html
— lftp -d -u $USERNAME, -e ‘set sftp:auto-confirm true; set sftp:connect-program “ssh -a -x -i ~/.ssh/id_rsa”; mirror -Rnev ./ /var/www/html — ignore-time — exclude-glob .git* — exclude .git/; exit’ sftp://$HOST
— rm -f ~/.ssh/id_rsa
— ‘echo Deploy done: $(date “+%F %H:%M:%S”)’

script下的内容就是GitLab的runner执行的主单元。首先,我会连接到我的服务器将所有内容备份到一个ZIP文件中,这个ZIP文件将使用当前时间(格式为yyyy-mm-dd_hh-mm-ss)进行命名:

— ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa $USERNAME@$HOST “zip -q -r /var/backups/www/01-Deploy-$(date +%F_%H-%M-%S).zip /var/www/html/”

注意:你需要在你的服务器上安装ZIP CLI。

在将/var/www/html备份后,使用LFTP连接到我的服务器并且上传最新的repo文件。这里我用的是SFTP,FTP配置有点不一样:

— lftp -d -u $USERNAME, -e ‘set sftp:auto-confirm true; set sftp:connect-program “ssh -a -x -i ~/.ssh/id_rsa”; mirror -Rnev ./ /var/www/html — ignore-time — exclude-glob .git* — exclude .git/; exit’ sftp://$HOST

使用mirror -Rnev ./ /var/www/html让LFTP上传./(我repo的根目录)下的所有文件到我服务器的/var/www/html路径下。上面部分参数的意思如下:

  • -u设置了我们sftp://$HOSTSSH用户名。
  • -e用于设置执行命令(使用单引号进行配置)。
  • -R用于设置reverse mirror。
  • -n表示只上传新的文件。
  • -e用于删除在我们源中不存在的文件。
  • -v用于配置verbose日志。
  • ignore-time将在决定是否下载时忽略时间。
  • exclude-glob .git*将会排除任何目录中匹配.git*的所有文件(例如.gitignore以及.gitkeep)。你可以在这里设置其他文件匹配方式。
  • exclude .git/这个配置将会保证不上传我们repo中的git文件。
  • exit将会停止LFTP和SSH执行。

注意:所有在我们服务上但是不在我们repository中的文件将被删除,记住上面所述的’源’指的就是我们GitLab的repository。

最终,脚本会在shared runner的容器中删除我们的私钥(这是一个安全措施),并且输出带有当前时间的结束语句。

— rm -f ~/.ssh/id_rsa
— ‘echo Deploy done: $(date “+%F %H:%M:%S”)’

以上部分就是我配置文件的所有内容。在GitLab中一个成功的Pipeline执行流程如下图所示:

未分类

运行Docker镜像

未分类

Pipeline的最终状态

结论

我尝试了一些其他的方式,例如使用rsync替代LFTP、使用多阶段以及缓存依赖(我能够重用SSH密钥)的Jobs、使用Docker的ENTRYPOINT和CMD等等,但我发现上面描述的方式对我来说是最快和最容易的。

GitLab在重置用户密码 – 找回root密码

摘要

忘记密码对于这个不喜欢记密码又强迫症不喜欢用一个密码走天下的人来说和吃饭一样平凡的发生着

首先切换到git用户

su git -

注意下面的高亮行

git@57aab1253afd:~/gitlab$ bundle exec rails console production
Loading production environment (Rails 4.2.6)
irb(main):001:0> user = User.find_by(email: '[email protected]')
=> #<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$p2Nw/sU6SQqPT8CL69.4LumT8Cw7cEIZoyG4m2SbdLt...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2016-07-09 08:22:03", last_sign_in_at: "2016-07-09 08:22:03", current_sign_in_ip: "192.168.16.1", last_sign_in_ip: "192.168.16.1", created_at: "2016-07-09 08:14:01", updated_at: "2016-07-09 08:22:03", name: "Administrator", admin: true, projects_limit: 100, skype: "", linkedin: "", twitter: "", authentication_token: "qtJhBiNuMUHaA_2UFYyZ", theme_id: 2, bio: nil, failed_attempts: 0, locked_at: nil, username: "root", can_create_group: true, can_create_team: false, state: "active", color_scheme_id: 1, notification_level: 1, password_expires_at: nil, created_by_id: nil, last_credential_check_at: nil, avatar: nil, confirmation_token: nil, confirmed_at: "2016-07-09 08:14:01", confirmation_sent_at: nil, unconfirmed_email: nil, hide_no_ssh_key: false, website_url: "", notification_email: "[email protected]", hide_no_password: false, password_automatically_set: false, location: nil, encrypted_otp_secret: nil, encrypted_otp_secret_iv: nil, encrypted_otp_secret_salt: nil, otp_required_for_login: false, otp_backup_codes: nil, public_email: "", dashboard:0, project_view: 0, consumed_timestep: nil, layout: 0, hide_project_limit: false, unlock_token: nil, otp_grace_period_started_at: nil, ldap_email: false, external: false>
irb(main):002:0> user.password = 'LookBack'
=> "LookBack"
irb(main):003:0> user.password_confirmation = 'LookBack'
=> "LookBack"
irb(main):004:0> user.save
=> true
irb(main):005:0>

未分类

GitLab在重置用户密码 – 找回root密码

下面是重置docker环境下的gitlab的用户密码

[root@DS-VM-Node58 ~]# sed -n '/- DB_/p' /data/docker-compose.yml 
    - DB_ADAPTER=mysql2
    - DB_HOST=127.0.0.1
    - DB_PORT=****
    - DB_USER=******
    - DB_PASS=************
    - DB_NAME=******
[root@DS-VM-Node58 ~]# docker exec -it gitlab_server bash         
root@DS-VM-Node58:/home/git/gitlab# mysql -u****** -p************ ****** -h127.0.0.1 -e "select id,email,encrypted_password,username from users where username ='root';"
+----+-------------------+--------------------------------------------------------------+----------+
| id | email             | encrypted_password                                           | username |
+----+-------------------+--------------------------------------------------------------+----------+
|  1 | [email protected] | $2a$10$UPq7XEJVAxuX19q40H8CdeDAVriMVoKSlodqxhO6Vo4Wa7TH6oyKW | root     |
+----+-------------------+--------------------------------------------------------------+----------+
root@DS-VM-Node58:/home/git/gitlab# bundle exec rails console production
Loading production environment (Rails 4.2.6)
irb(main):001:0> user = User.find_by(id: '1')
=> #<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$UPq7XEJVAxuX19q40H8CdeDAVriMVoKSlodqxhO6Vo4...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 3, current_sign_in_at: "2017-03-15 12:19:22", last_sign_in_at: "2017-03-15 12:17:25", current_sign_in_ip: "172.30.0.57", last_sign_in_ip: "172.30.0.57", created_at: "2017-03-15 11:46:27", updated_at: "2017-03-15 21:07:57", name: "Administrator", admin: true, projects_limit: 100, skype: "", linkedin: "", twitter: "", authentication_token: "y--EW2jDrxezMezm6wUN", theme_id: 2, bio: nil, failed_attempts: 0, locked_at: nil, username: "root", can_create_group: true, can_create_team: false, state: "active", color_scheme_id: 1, notification_level: 1, password_expires_at: nil, created_by_id: nil, last_credential_check_at: nil, avatar: nil, confirmation_token: nil, confirmed_at: "2017-03-15 11:46:27", confirmation_sent_at: nil, unconfirmed_email: nil, hide_no_ssh_key: false, website_url: "", notification_email: "[email protected]", hide_no_password: false, password_automatically_set: false, location: nil, encrypted_otp_secret: nil, encrypted_otp_secret_iv: nil, encrypted_otp_secret_salt: nil, otp_required_for_login: false, otp_backup_codes: nil, public_email: "", dashboard: 0, project_view: 0, consumed_timestep: nil, layout: 0, hide_project_limit: false, unlock_token: nil, otp_grace_period_started_at: nil, ldap_email: false, external: false>
irb(main):002:0> user.password = 'LookBack.dwhd.org'
=> "LookBack.dwhd.org"
irb(main):003:0> user.password_confirmation = 'LookBack.dwhd.org'
=> "LookBack.dwhd.org"
irb(main):004:0> user.save!
=> true
irb(main):005:0> #按Ctrl+D键退出
root@DS-VM-Node58:/home/git/gitlab# mysql -u****** -p************ ****** -h127.0.0.1 -e "select id,email,encrypted_password,username from users where username ='root';"
+----+-------------------+--------------------------------------------------------------+----------+
| id | email             | encrypted_password                                           | username |
+----+-------------------+--------------------------------------------------------------+----------+
|  1 | [email protected] | $2a$10$dVahm7BERhs1eLD41h1kNe65OAM3YGLcQSUUnocWkvde6BDVjMGWe | root     |
+----+-------------------+--------------------------------------------------------------+----------+
root@DS-VM-Node58:/home/git/gitlab# exit
exit
[root@DS-VM-Node58 ~]#

参考地址:https://docs.gitlab.com/ee/security/reset_root_password.html

未分类

GitLab 批量导入项目( 迁移 )

1、gitlab 作为代码仓库存储, 可能会由于各种原因问题,对项目进行大批量的迁移;

2、怎么迁移更快呢? 下面 orange 就给你说说,让你实现批量项目快速迁移;

(1)在原来的代码或项目存储的位置进行打包(/vat/opt/gitlab/git-data/repositories);

# tar czvf group_xxx.tar.gz   group_xxx/*

(2) 将打包好的项目组迁移到目的地,进行代码还原,并显示在另一个gitlab;

# cp group_xxx.tar.gz /var/opt/gitlab/git-data/repository-import-2018-8-09/

(3) 创建目录用于存放 group_xxx包的相关project并解压到该目录

# mkdir /var/opt/gitlab/git-data/repository-import-2018-8-09/new_group -p
# tar xf group_xxx.tar.gz -C /var/opt/gitlab/git-data/repository-import-2018-8-09/new_group

(4) 解决目录权限问题

# chown -R git.git  /var/opt/gitlab/git-data/repositor*

(5) 开始执行代码或项目迁移

# gitlab-rake gitlab:import:repos['/var/opt/gitlab/git-data/repository-import-2018-8-09/']

注意

(1) 存储打包后的代码目录(/var/opt/gitlab/git-data/repository-import-2018-8-09/)以及将要被还原代码的目录(/var/opt/gitlab/git-data/repositories) 都应该授权git用户及组;

(2) 如果存在group_xxx 或者group_xxx/group_xxx2/group_xxx3,需要在/var/opt/gitlab/git-data/repository-import-2018-8-09/目录中创建树结构;
如:
#mkdir -p /var/opt/gitlab/git-data/repository-import-2018-8-09/group_xxx/group_xxx2/group_xxx3

在团队中使用GitLab中的Merge Request工作模式

在工作中使用Git已有5年多的时间了,Git分布式的工作机制以及强大的分支功能使得在团队中推广使用没有受到什么阻碍。一直以来都是采用的分支管理模式,我把项目的开发分为三个阶段:开发、测试和上线。

一、分支管理模式

1、开发阶段

  1. 除了master分支创建一个供所有开发人员开发的dev分支;

  2. 开发人员在dev分支上进行工作,随时随地commit,每天push一次到服务器;

  3. push代码前需要进行pull操作,因为有可能在之前有别的成员先进行了push操作,如果有冲突还需要进行冲突解决;

  4. 每天上班后所有成员对dev进行pull操作,获取所有成员push的代码,有冲突需要解决;

  5. 团队Leader每天将dev合并一次到master。

2、测试阶段

  1. 测试进入后就需要添加test分支;

  2. 在开发人员将代码push到dev分支后,可以在dev基础上创建test分支,测试人员以test分支搭建测试环境,开始测试;

  3. 开发人员在接受到bug后,直接在测试分支上修改,然后让测试人员进行验证;

  4. 每天团队Leader将测试分支上修改的bug合并到dev分支上,这样所有团队成员当天修复的bug都会在第二天被团队其他人pull下来;

  5. 团队Leader每天将dev合并一次到master。

3、上线阶段

  1. 系统上线后试运行阶段会存在两种改动:bug和优化需求,bug通常当天解决晚上部署,优化需求通常周末部署;

  2. bug当天能修复的就直接在test分支上修复,然后进行测试,验证通过后合并到master;

  3. bug当天不能修复的就针对该bug创建一个分支,修复完后合并到test分支进行测试,验证通过后合并到master;

  4. 每个优化需求都以master分支为基础创建一个feature分支,完成后合并到dev分支,开发人员可以先交叉测试,然后将dev合并到test进行测试,验证通过后合并到master;

  5. master始终是一个干净的,可发布的分支。

二、Merge Request模式

一直以来,都觉得Merge Request模式遥不可及,只有做开源软件才会采用这种模式,没想到这么快就已经在团队中开始推行使用了,先看一张图来了解下Merge Request的开发流程:

未分类

  1. 需求或是Bug都是用Issue来表示;

  2. 虽然Issue不支持多层级,但结合里程碑、标签等还是可以很好的对任务和Bug进行管理;

  3. 管理员和团队成员都可以进行Issue的创建;

  4. 任务的接收者对Issue创建Merge Request;

  5. 完成任务后推送代码到Merge Request对应的分支;

  6. 管理员对代码进行Merge。

相比较传统的分支管理模式,Merge Request可以给我们带来下面几个好处:

  1. 重要分支设置为受保护,杜绝了有些问题代码被提交了,但项目经理不知道的情况;

  2. 每个任务都有一个对应的分支,互相隔离,所有的代码改动有据可查;

  3. 开发人员不用在分支间切换和合并,更专注于开发。

下面以一个示例来介绍Merge Request的工作流程

1、设置重要分支受保护

未分类

在上图中的位置可以将所有的重要分支设置为受保护,重要的分支通常是master、release、test等。

2、创建Issue

未分类

任务创建后,开发人员就可以对该任务创建Merge Request了,如下图:

未分类

  • 创建Merge Request时会创建针对这个任务对一个分支;
  • 分支名称的格式为:任务编号-[任务标题中出现的英文和数字],当然分支名称也可以自行修改;
  • 分支的Source为该项目设置的主分支,主分支可以在设置/General/General project settings/Default Branch进行设置。

3、使用你熟悉的工具拉取Merge Request对应的分支到本地进行代码修改,修改完成后,Push代码到服务器,代码推送后,管理员在Merge Request页面可以看到Merge按钮,如下图:

未分类

点击右边的Resole WIP status后,Merge按钮就可以使用

未分类

如果勾选Remove source brance,当Merge后,服务器端会删除创建的分支。Merge完成,会关闭关联的任务,但并不是每一次推送都可以非常顺利,有时会有冲突,当本地代码和服务器代码不一致时,会出现解决冲突的按钮,解决冲突后才能进行Merge

未分类

代码Merge后,开发人员就可以按照同样的流程做下一个任务了。

三、思考

  • 如果系统上线后有紧急Bug需要处理,这个流程应该怎样去调整?
  • 每个任务都在单独分支并行开发,这是如果A和B都以来C开发的一个模块,应该怎么解决?
  • 理论上Issue管理员和开发人员都可以进行创建,什么样的Issue可以有开发人员来创建?

四、总结

  • 任何一种模式或工作方式的改变,总会打破一些人的舒适区,我们应该学会走出舒适区,拥抱变化;
  • 尝试新的东西肯定会遇到各种问题,先执行,然后再持续优化改进,逐步达到最优状态;
  • 从团队试用的情况来看,暂时没有出现水土不服的情况。

gitlab 403 forbidden 并发引起ip被封问题解决方法

步骤:

  • 打开/etc/gitlab/gitlab.rb文件。
  • 查找gitlab_rails[‘rack_attack_git_basic_auth’]关键词。
  • 取消注释
  • 修改ip_whitelist白名单属性,加入Gitlab部署的IP地址。
gitlab_rails[‘rack_attack_git_basic_auth’] = {
‘enabled’ => true,
‘ip_whitelist’ => [“127.0.0.1″,”Gitlab部署的IP地址”],
‘maxretry’ => 300,
‘findtime’ => 5,
‘bantime’ => 60
}
  • 配置好后,执行gitlab-ctl reconfigure即可。

修复群晖 GitLab 升级失败的问题

如果你最近使用群晖套件中心的 GitLab( 9.4.4-0050 ) ,并且勾选转换数据库( MariaDB => postgresql ),那么你很可能遇到丢失数据的问题( Version: 10.6.4-0051 ).表现为打开 GitLab 首页提示设置 root 密码,登录后台显示所有项目丢失.

故障的原因是群晖”借鉴”的 MySQL to PostgreSQL Converter 项目存在一些问题 .群晖内的具体路径为/volume1/@appstore/Docker-GitLab/mysql-postgresql-converter/db_converter.py,转换时会发生UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0x9c错误.截至目前尚有 30 个 PR 未处理.群晖科技在自家稳定版产品中未确认方案普适性,原项目首页强调 use with care 被无视,置客户数据安全于不顾,最终导致悲剧发生.后续我会专门谈一谈为什么 synology NAS 是危险的产品,选购群晖是对数据的不负责行为.本篇只说怎么找回你宝贵的数据.

修改 docker 环境变量,使用原 MariaDB 数据库

1.使用 admin 组的账户登录群晖 SSH .警告: 如果你不知道这步怎么操作,本修复指南可能对你来说较复杂,极易出现数据丢失.请向技术人员求助.

2.如果之前没有执行过备份( bundle exec rake gitlab:backup:create RAILS_ENV=production ),那么执行下备份.路径类似/volume1/docker/gitlab/.

3.为 gitlab_user 授权.如果不熟悉 SQL 可以在套件中心中安装 phpMyAdmin ,然后在权限中增加用户账户的 host name 为 172.17.0.% .

4.测试数据库权限:

docker exec -it synology_gitlab bash  # 进入容器终端
mysql -u gitlab_user -p -h 172.17.0.1 -P 3307  # 测试数据库链接情况
exit  # 退出容器

5.套件中心 => 已安装 => GitLab => 停止.

6.docker => synology_gitlab => 编辑 => 环境变量

DB_PORT 3307
DB_TYPE mysql
DB_HOST 172.17.0.1

7.套件中心 => 已安装 => GitLab => 启动.

修复数据库故障

GitLab 官方明确表示不推荐使用 MariaDB / MySQL 数据库. 群晖由于某种原因仍然在使用 MariaDB 10 .本部分重点解决各类数据库问题.

1.停止 GitLab 服务service gitlab stop.
2.登录 MariaDB 或直接使用 phpMyAdmin .让数据库支持长索引.

use gitlab;
SET storage_engine=INNODB;
SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda, innodb_large_prefix=1;
SET GLOBAL log_bin_trust_function_creators = 1;

3.转换原有数据使用 utf8mb4 编码.注意下面的命令每一条的回显都要作为 SQL 语句再执行.

SELECT CONCAT('ALTER TABLE `', TABLE_NAME,'` ROW_FORMAT=DYNAMIC;') AS 'Copy & run these SQL statements:' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="gitlab" AND TABLE_TYPE="BASE TABLE" AND ROW_FORMAT!="Dynamic";

回显类似

ALTER TABLE `abuse_reports` ROW_FORMAT=DYNAMIC;
ALTER TABLE `appearances` ROW_FORMAT=DYNAMIC;
ALTER TABLE `application_settings` ROW_FORMAT=DYNAMIC;
ALTER TABLE `audit_events` ROW_FORMAT=DYNAMIC;
ALTER TABLE `award_emoji` ROW_FORMAT=DYNAMIC;
ALTER TABLE `boards` ROW_FORMAT=DYNAMIC;
ALTER TABLE `broadcast_messages` ROW_FORMAT=DYNAMIC;
ALTER TABLE `chat_names` ROW_FORMAT=DYNAMIC;
ALTER TABLE `chat_teams` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_build_trace_section_names` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_build_trace_sections` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_builds` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_group_variables` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_job_artifacts` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_pipeline_schedule_variables` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_pipeline_schedules` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_pipeline_variables` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_pipelines` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_runner_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_runners` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_stages` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_trigger_requests` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_triggers` ROW_FORMAT=DYNAMIC;
ALTER TABLE `ci_variables` ROW_FORMAT=DYNAMIC;
ALTER TABLE `cluster_platforms_kubernetes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `cluster_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `cluster_providers_gcp` ROW_FORMAT=DYNAMIC;
ALTER TABLE `clusters` ROW_FORMAT=DYNAMIC;
ALTER TABLE `clusters_applications_helm` ROW_FORMAT=DYNAMIC;
ALTER TABLE `container_repositories` ROW_FORMAT=DYNAMIC;
ALTER TABLE `conversational_development_index_metrics` ROW_FORMAT=DYNAMIC;
ALTER TABLE `deploy_keys_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `deployments` ROW_FORMAT=DYNAMIC;
ALTER TABLE `emails` ROW_FORMAT=DYNAMIC;
ALTER TABLE `environments` ROW_FORMAT=DYNAMIC;
ALTER TABLE `events` ROW_FORMAT=DYNAMIC;
ALTER TABLE `feature_gates` ROW_FORMAT=DYNAMIC;
ALTER TABLE `features` ROW_FORMAT=DYNAMIC;
ALTER TABLE `fork_network_members` ROW_FORMAT=DYNAMIC;
ALTER TABLE `fork_networks` ROW_FORMAT=DYNAMIC;
ALTER TABLE `forked_project_links` ROW_FORMAT=DYNAMIC;
ALTER TABLE `gcp_clusters` ROW_FORMAT=DYNAMIC;
ALTER TABLE `gpg_key_subkeys` ROW_FORMAT=DYNAMIC;
ALTER TABLE `gpg_keys` ROW_FORMAT=DYNAMIC;
ALTER TABLE `gpg_signatures` ROW_FORMAT=DYNAMIC;
ALTER TABLE `group_custom_attributes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `identities` ROW_FORMAT=DYNAMIC;
ALTER TABLE `issue_assignees` ROW_FORMAT=DYNAMIC;
ALTER TABLE `issue_metrics` ROW_FORMAT=DYNAMIC;
ALTER TABLE `issues` ROW_FORMAT=DYNAMIC;
ALTER TABLE `keys` ROW_FORMAT=DYNAMIC;
ALTER TABLE `label_links` ROW_FORMAT=DYNAMIC;
ALTER TABLE `label_priorities` ROW_FORMAT=DYNAMIC;
ALTER TABLE `labels` ROW_FORMAT=DYNAMIC;
ALTER TABLE `lfs_objects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `lfs_objects_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `lists` ROW_FORMAT=DYNAMIC;
ALTER TABLE `members` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_request_diff_commits` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_request_diff_files` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_request_diffs` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_request_metrics` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_requests` ROW_FORMAT=DYNAMIC;
ALTER TABLE `merge_requests_closing_issues` ROW_FORMAT=DYNAMIC;
ALTER TABLE `milestones` ROW_FORMAT=DYNAMIC;
ALTER TABLE `namespaces` ROW_FORMAT=DYNAMIC;
ALTER TABLE `notes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `notification_settings` ROW_FORMAT=DYNAMIC;
ALTER TABLE `oauth_access_grants` ROW_FORMAT=DYNAMIC;
ALTER TABLE `oauth_access_tokens` ROW_FORMAT=DYNAMIC;
ALTER TABLE `oauth_applications` ROW_FORMAT=DYNAMIC;
ALTER TABLE `oauth_openid_requests` ROW_FORMAT=DYNAMIC;
ALTER TABLE `pages_domains` ROW_FORMAT=DYNAMIC;
ALTER TABLE `personal_access_tokens` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_authorizations` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_auto_devops` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_custom_attributes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_features` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_group_links` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_import_data` ROW_FORMAT=DYNAMIC;
ALTER TABLE `project_statistics` ROW_FORMAT=DYNAMIC;
ALTER TABLE `projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `protected_branch_merge_access_levels` ROW_FORMAT=DYNAMIC;
ALTER TABLE `protected_branch_push_access_levels` ROW_FORMAT=DYNAMIC;
ALTER TABLE `protected_branches` ROW_FORMAT=DYNAMIC;
ALTER TABLE `protected_tag_create_access_levels` ROW_FORMAT=DYNAMIC;
ALTER TABLE `protected_tags` ROW_FORMAT=DYNAMIC;
ALTER TABLE `push_event_payloads` ROW_FORMAT=DYNAMIC;
ALTER TABLE `redirect_routes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `releases` ROW_FORMAT=DYNAMIC;
ALTER TABLE `routes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `schema_migrations` ROW_FORMAT=DYNAMIC;
ALTER TABLE `sent_notifications` ROW_FORMAT=DYNAMIC;
ALTER TABLE `services` ROW_FORMAT=DYNAMIC;
ALTER TABLE `snippets` ROW_FORMAT=DYNAMIC;
ALTER TABLE `spam_logs` ROW_FORMAT=DYNAMIC;
ALTER TABLE `subscriptions` ROW_FORMAT=DYNAMIC;
ALTER TABLE `system_note_metadata` ROW_FORMAT=DYNAMIC;
ALTER TABLE `taggings` ROW_FORMAT=DYNAMIC;
ALTER TABLE `tags` ROW_FORMAT=DYNAMIC;
ALTER TABLE `timelogs` ROW_FORMAT=DYNAMIC;
ALTER TABLE `todos` ROW_FORMAT=DYNAMIC;
ALTER TABLE `trending_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `u2f_registrations` ROW_FORMAT=DYNAMIC;
ALTER TABLE `uploads` ROW_FORMAT=DYNAMIC;
ALTER TABLE `user_agent_details` ROW_FORMAT=DYNAMIC;
ALTER TABLE `user_custom_attributes` ROW_FORMAT=DYNAMIC;
ALTER TABLE `user_synced_attributes_metadata` ROW_FORMAT=DYNAMIC;
ALTER TABLE `users` ROW_FORMAT=DYNAMIC;
ALTER TABLE `users_star_projects` ROW_FORMAT=DYNAMIC;
ALTER TABLE `web_hook_logs` ROW_FORMAT=DYNAMIC;
ALTER TABLE `web_hooks` ROW_FORMAT=DYNAMIC;');

4.转换原有数据使用新的表空间( tablespace )格式.注意下面的命令每一条的回显都要作为 SQL 语句再执行.

SET foreign_key_checks = 0;
SELECT CONCAT('ALTER TABLE `', TABLE_NAME,'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;') AS 'Copy & run these SQL statements:' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="gitlab" AND TABLE_COLLATION != "utf8mb4_general_ci" AND TABLE_TYPE="BASE TABLE";

回显类似

ALTER TABLE `abuse_reports` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `appearances` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `application_settings` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `audit_events` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `award_emoji` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `boards` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `broadcast_messages` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `chat_names` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `chat_teams` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_build_trace_section_names` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_build_trace_sections` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_builds` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_group_variables` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_job_artifacts` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_pipeline_schedule_variables` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_pipeline_schedules` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_pipeline_variables` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_pipelines` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_runner_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_runners` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_stages` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_trigger_requests` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_triggers` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `ci_variables` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `cluster_platforms_kubernetes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `cluster_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `cluster_providers_gcp` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `clusters` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `clusters_applications_helm` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `container_repositories` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `conversational_development_index_metrics` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `deploy_keys_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `deployments` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `emails` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `environments` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `events` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `feature_gates` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `features` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `fork_network_members` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `fork_networks` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `forked_project_links` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `gcp_clusters` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `gpg_key_subkeys` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `gpg_keys` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `gpg_signatures` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `group_custom_attributes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `identities` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `issue_assignees` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `issue_metrics` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `issues` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `keys` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `label_links` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `label_priorities` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `labels` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `lfs_objects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `lfs_objects_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `lists` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `members` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_request_diff_commits` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_request_diff_files` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_request_diffs` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_request_metrics` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_requests` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `merge_requests_closing_issues` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `milestones` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `namespaces` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `notes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `notification_settings` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `oauth_access_grants` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `oauth_access_tokens` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `oauth_applications` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `oauth_openid_requests` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `pages_domains` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `personal_access_tokens` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_authorizations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_auto_devops` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_custom_attributes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_features` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_group_links` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_import_data` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `project_statistics` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `protected_branch_merge_access_levels` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `protected_branch_push_access_levels` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `protected_branches` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `protected_tag_create_access_levels` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `protected_tags` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `push_event_payloads` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `redirect_routes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `releases` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `routes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `schema_migrations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `sent_notifications` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `services` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `snippets` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `spam_logs` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `subscriptions` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `system_note_metadata` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `taggings` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `tags` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `timelogs` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `todos` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `trending_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `u2f_registrations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `uploads` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `user_agent_details` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `user_custom_attributes` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `user_synced_attributes_metadata` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `users_star_projects` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `web_hook_logs` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `web_hooks` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
SET foreign_key_checks = 1;

5.执行数据库限制任务.

bundle exec rake add_limits_mysql RAILS_ENV=production

6.修改数据库迁移任务.由于 GitLab 官方要求不允许跨多个小版本升级,所以我们会遇到一些奇怪的错误,这里给出一些修复方案,我只遇到了一个.

Mysql2::Error: Index column size too large. The maximum column size is 767 bytes.: CREATE UNIQUE INDEX `index_lfs_file_locks_on_project_id_and_path`  ON `lfs_file_locks` (`project_id`, `path`)

解决方案:

use gitlab;
DROP TABLE lfs_file_locks;
# db/migrate/20180116193854_create_lfs_file_locks.rb
# create_table :lfs_file_locks do |t| 修改为
create_table :lfs_file_locks, options: 'ROW_FORMAT=DYNAMIC'  do |t|

7.执行数据库迁移.

bundle exec rake db:migrate

预编译资源

bundle exec rake gettext:compile RAILS_ENV=production
bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
bundle exec rake cache:clear RAILS_ENV=production

备份与恢复

bundle exec rake gitlab:backup:create RAILS_ENV=production  # 你会找到一个类似 /home/git/data/backups/1531046569_2018_07_14_10.6.4_gitlab_backup.tar 的文件
bundle exec rake gitlab:backup:restore RAILS_ENV=production

Gitlab 8.x runner安装与配置

介绍

  Gitlab 8.x之后默认集成了Gitlab CI,意味着支持了持续集成相关功能。每一次集成操作都需要对应的runner来跑代码构建、测试、发布等操作。Runner实际上就是为Gitlab的持续集成指定一个环境。

安装

官方文档地址:https://docs.gitlab.com/runner/install/
  Gitlab Runner的版本需要跟Gitlab对应,这里有一个对照表。最新的版本对照表中并没有Gitlab8.X对应的Runner版本,查了一下Gitlab8.X对应的Runner版本为1.X,所以这里选择runner 1.11.2版本。

  这里运行Gitlab与Runner的环境均为CentOS,之前尝试在windows上安装runner,对接Linux上的Gitlab,发现在Gitlab runner运行的控制台出现乱码问题。

0. 准备

在opt下创建gitlab-runner目录并进入该目录,后续执行的操作与所有的资源都放在这个目录中

cd /opt
mkdir gitlab-runner
cd gitlab-runner/

1. 下载

下载安装资源到gitlab-runner目录中

sudo wget https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/v1.11.2/binaries/gitlab-ci-multi-runner-linux-386

2. 添加运行权限

sudo chmod +x gitlab-ci-multi-runner-linux-386

3. 创建用户

sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

4. 安装

./gitlab-ci-multi-runner-linux-386 install --user=gitlab-runner --working-directory=/opt/gitlab-runner
sudo gitlab-ci-multi-runner-linux-386 start

配置

  经过上面的步骤,Runner就已经跑起来了,剩下的还需要Runner与项目对接起来。Runner的类型分为Shared, specific and group Runners。这里选择specific类型,即单独的项目使用。

  在Gitlab项目的setting-runner中,配置过程中会使用到url和token如下所示:

未分类

1.运行register命令

./gitlab-ci-multi-runner-linux-386 register

之后就按照提示就行了

2.输入url地址
3.输入token
4.输入描述,任意即可
5.输入标签,这里直接Enter跳过
6.选择Runner executor,这里选择shell

到这里就已经注册成功了,输入./gitlab-ci-multi-runner-linux-386 list就能看到上面的注册的条目。

官方文档地址:https://docs.gitlab.com/runner/register/index.html

其它

  上面两个步骤做完后,此时按理说Gitlab就能调用Runner跑持续集成了,实际当中还会碰到其它问题,整理如下。

权限问题

  如果在Gitlab的Build控制台上报无法创建文件夹、无法运行bash等,证明创建的GitLab Runner权限不够。
此时,我这里是修改GitLab Runner的权限跟root保持一致。

vim /etc/passwd

通过上面命令可以编辑用户对应的权限,我这里打开默认为gitlab-runner:x:601:601:GitLab Runner:/home/gitlab-runner:/bin/bash,权限组修改为跟root的一致gitlab-runner:x:0:0:GitLab Runner:/home/gitlab-runner:/bin/bash。(root的权限组名为0)

这里在另外一台机器上还碰到这样修改了也不好使的问题,最终gitlab-runner install的时候,直接指定为root,而不新创建用户。

环境问题

由于Runner运行需要环境支撑,比如git、node、npm等,需要在Runner所在的服务器上准备好所有的依赖。

Linux Node安装

# 下载
wget https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz
# 解压
tar -xf  node-v8.11.3-linux-x64.tar.xz
# 建立软链接,实现全局访问
ln -s /opt/gitlab-runner/node-v8.11.3-linux-x64/bin/node /usr/local/bin/node
ln -s /opt/gitlab-runner/node-v8.11.3-linux-x64/bin/npm /usr/local/bin/npm

此时,输入node -v就能看到node的版本了。

使用软连接方式可能对非root用户无效,可以转而使用配置环境变量的方式

# 修改配置文件
vim /etc/profile
#set for nodejs,新增NODE_HOME并放到PATH上
export JAVA_HOME=/opt/soft/java
export NODE_HOME=/opt/gitlab-runner/node-v8.11.3-linux-x64  
export CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin:$NODE_HOME/bin

在vim环境下点击i进入插入状态,编辑完成后按Esc键,然后输入 :wq 按回车保存退出。
备注:内外环境还需修改NPM的镜像源,比如修改为npm config set registry https://registry-npm.daojia-inc.com/

附录 部分GitLab-Runner常用命令

1.gitlab-runner帮助:gitlab-runner –help

2.gitlab-runner指定命令帮助:gitlab-runner –help

3.注册runner:gitlab-runner register

4.注销runner:gitlab-runner unregister

5.当前运行的runner:gitlab-runner list

6.启动runner:gitlab-runner start

7.停止runner:gitlab-runner stop

8.重启runner:gitlab-runner restart

9.查询runner状态:gitlab-runner status