GitLab完整指南:从安装到CI/CD流水线

GitLab完整指南:从安装到CI/CD流水线

一、GitLab简介

1.1 什么是GitLab?

GitLab是一个开源的DevOps平台,提供完整的源代码管理、CI/CD流水线、代码审查、问题跟踪等功能。

GitLab的核心功能:

  • 源代码管理:基于Git的版本控制
  • CI/CD:内置持续集成和持续部署
  • 代码审查:Merge Request和代码评审
  • 问题跟踪:Issue跟踪和管理
  • 安全扫描:静态应用安全测试(SAST)
  • Kubernetes集成:与容器编排平台无缝集成

1.2 GitLab版本对比

版本 特点 适用场景
GitLab CE(社区版) 开源免费 小团队、个人项目
GitLab EE(企业版) 商业功能 大型企业
GitLab.com SaaS托管 不愿自建服务器
GitLab Runner CI/CD执行器 分布式构建

1.3 GitLab架构


┌─────────────────────────────────────────────────────────┐
│                     GitLab Architecture                      │
├─────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────────────────────────────────────┐    │
│   │              GitLab Rails Application              │    │
│   │  - Web UI                                         │    │
│   │  - API                                             │    │
│   │  - Git Repository Manager                         │    │
│   └─────────────────────────────────────────────────┘    │
│                           │                                 │
│              ┌────────────┼────────────┐                │
│              │            │            │                │
│              ▼            ▼            ▼                │
│        ┌─────────┐  ┌─────────┐  ┌─────────┐       │
│        │ PostgreSQL │  │  Redis   │  │  Gitaly  │       │
│        │ (数据库)  │  │ (缓存)   │  │ (Git存储)│       │
│        └─────────┘  └─────────┘  └─────────┘       │
│                                                             │
│   ┌─────────────────────────────────────────────────┐    │
│   │              GitLab Runner                       │    │
│   │  - 执行CI/CD任务                                │    │
│   │  - 支持Docker、Kubernetes执行器                 │    │
│   └─────────────────────────────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────┘

二、安装GitLab

2.1 系统要求

最低配置:

  • CPU:2核心
  • 内存:4GB
  • 磁盘:10GB(建议20GB以上)
  • 系统:Ubuntu 22.04/20.04
  • 推荐配置:

  • CPU:8核心
  • 内存:16GB
  • 磁盘:100GB SSD
  • 系统:Ubuntu 22.04 LTS

2.2 安装步骤

#### 2.2.1 安装依赖


# 更新系统
sudo apt update
sudo apt upgrade -y

# 安装必要依赖
sudo apt install -y curl ca-certificates apt-transport-https gnupg lsb-release

#### 2.2.2 添加GitLab仓库


# 添加GitLab官方仓库
curl -fsSL "https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/pool/jammy/main/g/gitlab-ce/gitlab-ce_16.6.0-ce.0_amd64.deb" -o /tmp/gitlab-ce.deb

# 或者使用官方仓库脚本
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash

#### 2.2.3 安装GitLab CE


# 安装GitLab CE
sudo EXTERNAL_URL="http://gitlab.example.com" apt install -y gitlab-ce

# 启动GitLab
sudo gitlab-ctl reconfigure

#### 2.2.4 配置GitLab


# 编辑配置文件
sudo nano /etc/gitlab/gitlab.rb

# 主要配置项:
external_url 'http://gitlab.example.com'  # 修改为你的域名

# 邮箱配置
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "noreply@example.com"
gitlab_rails['smtp_password'] = "your_password"

# 重新配置
sudo gitlab-ctl reconfigure

2.3 Docker安装GitLab


# 创建数据目录
mkdir -p /srv/gitlab/{config,logs,data}

# 运行GitLab容器
docker run -d \
  --name gitlab \
  --hostname gitlab.example.com \
  -p 80:80 \
  -p 443:443 \
  -p 22:22 \
  -v /srv/gitlab/config:/etc/gitlab \
  -v /srv/gitlab/logs:/var/log/gitlab \
  -v /srv/gitlab/data:/var/opt/gitlab \
  --restart always \
  gitlab/gitlab-ce:latest

# 等待GitLab完全启动(可能需要10-15分钟)
docker exec gitlab gitlab-ctl status

# 获取初始密码
docker exec gitlab cat /etc/gitlab/initial_root_password

三、GitLab基本配置

3.1 初始化设置

首次登录后,需要完成以下设置:

1. 修改管理员密码http://gitlab.example.comroot 登录 - 修改为强密码

2. 配置管理员邮箱Admin Area → Settings → General

3. 配置SMTP邮箱Admin Area → Settings → Outbound emails

3.2 创建用户和组


# 使用GitLab Web界面创建:

# 1. 创建Group(组)
# Groups → New Group
# Group name: development
# Visibility: Private

# 2. 创建User
# Admin Area → Users → New User
# Name: John Doe
# Email: john@example.com
# Username: john

# 3. 将用户添加到组
# Groups → development → Members
# Add member: john
# Role: Developer

3.3 创建项目


# 方法1:通过Web界面创建

# 1. 点击 "New project"
# 2. 选择 "Create blank project"
# 3. 填写项目信息:
#    - Project name: my-project
#    - Visibility: Private
#    - Initialize repository with a README: Yes

# 方法2:推送现有代码

# 克隆空仓库
git clone http://gitlab.example.com/development/my-project.git

# 创建项目文件
cd my-project
echo "# My Project" > README.md

# 提交并推送
git add .
git commit -m "Initial commit"
git push -u origin main

3.4 配置SSH密钥


# 1. 生成SSH密钥
ssh-keygen -t ed25519 -C "your_email@example.com"

# 2. 查看公钥
cat ~/.ssh/id_ed25519.pub

# 3. 在GitLab中添加公钥
# User Settings → SSH Keys → Add new key

# 4. 测试连接
ssh -T git@gitlab.example.com

四、GitLab CI/CD详解

4.1 .gitlab-ci.yml基础配置


# .gitlab-ci.yml

stages:
  - build
  - test
  - deploy

# 定义变量
variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

# 构建阶段
build:
  stage: build
  image: docker:20.10
  services:
    - docker:20.10-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_TAG .
    - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
    - docker push $IMAGE_TAG
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main
    - develop

# 测试阶段
test:
  stage: test
  image: python:3.11
  before_script:
    - pip install -r requirements.txt
  script:
    - pytest --cov=app --cov-report=xml
  coverage: '/TOTAL.*\s+(\d+%)$/'
  artifacts:
    reports:
      junit: test-results.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml
  only:
    - branches
    - merge_requests

# 部署阶段
deploy:
  stage: deploy
  image: alpine:latest
  script:
    - echo "Deploying to production..."
    - kubectl set image deployment/myapp myapp=$IMAGE_TAG -n production
  environment:
    name: production
    url: https://myapp.example.com
  only:
    - main
  when: manual

4.2 CI/CD模板


# .gitlab-ci.yml - 完整模板

stages:
  - lint
  - build
  - test
  - security
  - deploy

variables:
  # Docker配置
  DOCKER_TLS_CERTDIR: ""

  # Node.js配置
  NODE_VERSION: "20"

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
    - .cache/

# 代码检查
lint:
  stage: lint
  image: node:${NODE_VERSION}-alpine
  before_script:
    - npm ci
  script:
    - npm run lint
    - npm run format:check
  only:
    - merge_requests
    - branches

# 构建Docker镜像
build:
  stage: build
  image: docker:20.10
  services:
    - docker:20.10-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - |
      if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
        TAG="latest"
      else
        TAG="$CI_COMMIT_SHORT_SHA"
      fi
      docker build -t $CI_REGISTRY_IMAGE:$TAG .
      docker push $CI_REGISTRY_IMAGE:$TAG
  rules:
    - if: $CI_COMMIT_BRANCH
      exists:
        - Dockerfile

# 单元测试
test:unit:
  stage: test
  image: node:${NODE_VERSION}-alpine
  before_script:
    - npm ci
  script:
    - npm run test:unit
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
  artifacts:
    reports:
      junit: junit.xml
  only:
    - merge_requests
    - branches

# 集成测试
test:integration:
  stage: test
  image: node:${NODE_VERSION}-alpine
  services:
    - postgres:15-alpine
    - redis:7-alpine
  variables:
    POSTGRES_DB: test
    POSTGRES_USER: test
    POSTGRES_PASSWORD: test
    DATABASE_URL: postgres://test:test@postgres:5432/test
    REDIS_URL: redis://redis:6379
  before_script:
    - npm ci
  script:
    - npm run test:integration
  artifacts:
    reports:
      junit: junit-integration.xml
  only:
    - merge_requests
    - branches

# 安全扫描
security:dependency-scanning:
  stage: security
  image: registry.gitlab.com/security-products/dependency-scanning:3
  allow_failure: true
  variables:
    DS_EXCLUDED_PATHS: "node_modules,vendor"
  artifacts:
    reports:
      dependency_scanning: gl-dependency-scanning-report.json
  only:
    - main
    - merge_requests

security:sast:
  stage: security
  image: registry.gitlab.com/security-products/sast:3
  allow_failure: true
  artifacts:
    reports:
      sast: gl-sast-report.json
  only:
    - main
    - merge_requests

# 部署到测试环境
deploy:staging:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: staging
    url: https://staging.example.com
  script:
    - kubectl config use-context staging
    - kubectl set image deployment/web web=$CI_REGISTRY_IMAGE:latest -n staging
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

# 部署到生产环境(手动确认)
deploy:production:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: production
    url: https://example.com
  script:
    - kubectl config use-context production
    - kubectl set image deployment/web web=$CI_REGISTRY_IMAGE:latest -n production
  when: manual
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

4.3 CI/CD变量配置

在GitLab中配置CI/CD变量:

1. 进入 Settings → CI/CD → Variables

变量名 保护 类型
`CI_REGISTRY` `registry.example.com` Variable
`CI_REGISTRY_USER` `gitlab-ci` Variable
`CI_REGISTRY_PASSWORD` `xxx` Masked
`DOCKER_PASSWORD` `xxx` Masked
`KUBE_CONFIG` `xxx` File

4.4 Runner配置


# /etc/gitlab-runner/config.toml

concurrent = 4
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "docker-runner"
  url = "https://gitlab.example.com"
  token = "REGISTRATION_TOKEN"
  executor = "docker"

  [runners.cache]
    MaxUploadedArchiveSize = 0

  [runners.docker]
    tls_verify = false
    image = "docker:20.10"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

五、GitLab最佳实践

5.1 Git工作流


# Feature Branch Workflow

# 1. 创建功能分支
git checkout -b feature/new-login

# 2. 开发并提交
git add .
git commit -m "Add login functionality"

# 3. 推送分支
git push -u origin feature/new-login

# 4. 创建Merge Request
# 访问GitLab创建MR

# 5. 代码审查后合并
# 合并后删除分支
git branch -d feature/new-login
git push origin --delete feature/new-login

5.2 项目结构规范


my-project/
├── .gitlab/
│   ├── ci/
│   │   ├── templates/
│   │   │   ├── build.yml
│   │   │   ├── test.yml
│   │   │   └── deploy.yml
│   └── issue_templates/
│       ├── bug_report.md
│       └── feature_request.md
├── .gitlab-ci.yml
├── README.md
├── CHANGELOG.md
├── docs/
├── src/
├── tests/
├── docker/
│   ├── Dockerfile
│   └── docker-compose.yml
└── k8s/
    ├── deployment.yaml
    └── service.yaml

5.3 安全最佳实践


# 限制变量暴露
variables:
  SECRET_API_KEY: $SECRET_API_KEY  # 仅在受保护分支可用

# 使用受保护变量
deploy:
  stage: deploy
  script:
    - echo $SECRET_API_KEY | base64 -d | kubectl apply -f -
  only:
    refs:
      - main
    variables:
      - $CI_COMMIT_TAG

六、常见问题解决

6.1 Runner连接失败


# 1. 检查Runner状态
sudo gitlab-runner status

# 2. 查看Runner日志
sudo gitlab-runner verify

# 3. 重新注册Runner
sudo gitlab-runner unregister "runner-name"
sudo gitlab-runner register

6.2 CI/CD失败排查


# 1. 查看作业日志
# 访问:CI/CD → Pipelines → 选择Pipeline → 查看作业

# 2. 本地调试
gitlab-runner exec docker build

# 3. 常见原因:
# - 变量未配置
# - 依赖下载超时
# - 权限不足
# - Docker镜像不存在

6.3 仓库推送权限问题


# 1. 检查远程URL
git remote -v

# 2. 使用SSH URL
git remote set-url origin git@gitlab.example.com:group/project.git

# 3. 检查SSH密钥
ssh -T git@gitlab.example.com

# 4. 配置凭据
git config --global credential.helper store

七、总结

本文详细介绍了GitLab的安装、配置和CI/CD实践。

核心要点:

1. 掌握GitLab架构和组件 2. 学会安装和基础配置 3. 熟练使用GitLab CI/CD 4. 遵循Git工作流最佳实践 5. 加强安全配置

下一步学习:

  • GitLab Kubernetes集成
  • GitLab高级安全功能
  • GitLab性能优化
  • 多项目管理工作流
  • 相关资源:

  • GitLab官方文档:https://docs.gitlab.com/
  • GitLab CI/CD文档:https://docs.gitlab.com/ci/
  • GitLab Runner文档:https://docs.gitlab.com/runner/

发表回复

后才能评论