使用GitLab自带的CI/CD功能在远程服务器部署项目(三)

前置内容:

通过Docker Compose部署GitLab和GitLab Runner(一)

使用GitLab自带的CI/CD功能在本地部署项目(二)

目录

一、在GitLab服务器上生成私钥与公钥

二、将公钥拷贝到应用服务器上

[三、将私钥给到Docker Executor使用](#三、将私钥给到Docker Executor使用)

1.在GitLab页面上设置全局的与SSH命令相关的CI/CD变量

2.在GitLab页面上设置全局的阿里云私人镜像仓库相关的CI/CD变量

3.编写.gitlab-ci.yml文件

四、验证

五、总结


要想在GitLab Runner容器中通过Docker Executor将eshop.webapi镜像部署到远程应用服务器上,最关键的步骤就是要能够在Docker Executor 内通过ssh命令免密操作应用服务器上的docker进行部署,如下面的结构图所示。

ssh免密的核心就是通过私钥和公钥与想要连接的客户端建立连接,省去了需要用户输入客户端登录密码的步骤。那我们这个案例具体的实现步骤如下:

(1)在GitLab服务器上生成私钥与公钥

(2)将公钥拷贝到应用服务器上,并把公钥内容写入authorized_keys文件

(3)将私钥给到Docker Executor使用

下面将详细展开说明这三个步骤,尤其是步骤三很关键。

一、在GitLab服务器上生成私钥与公钥

在GitLab服务器上执行以下命令,会在/root/.shh/目录下生成两个文件,它们就是**私钥 (id_rsa) 与公钥 (id_rsa.pub)**文件

ssh-keygen -t rsa

注意:如果之前就已经生成过,就没必要执行这个命令重新生成了,它会覆盖原有的私钥公钥信息,会导致无法连接到曾经免密登录过的其他客户端。

二、将公钥拷贝到应用服务器上

在GitLab服务器上执行以下命令将公钥拷贝到应用服务器上:

scp /root/.ssh/id_rsa.pub root@172.24.142.64:/root/.ssh/id_rsa_gitlab.pub

在应用服务器上执行以下命令,将GitLab服务器的公钥内容写入authorized_keys文件

cat /root/.ssh/id_rsa_gitlab.pub >> /root/.ssh/authorized_keys

在GitLab服务器上执行以下命令,可以发现不用输入用户名密码就可以登录到应用服务器了

ssh 172.24.142.64

三、将私钥给到Docker Executor使用

通过上面两步操作之后,GitLab服务器已经可以使用自己的私钥通过ssh免密登录到应用服务器了。那GitLab Runner容器中的Docker Executor如果能拿到这个私钥,是不是也就能够ssh到应用服务器执行各种操作啦?我将通过以下步骤来实现这个方案:

(1)在GitLab页面上设置全局的与SSH命令相关的CI/CD变量;

(2)在GitLab页面上设置全局的阿里云私人镜像仓库相关的CI/CD变量;

(3)编写.gitlab-ci.yml文件,引用全局的CI/CD变量,将eshop.webapi镜像推送到阿里云私人镜像仓库,ssh到应用服务器从阿里云私人镜像仓库下载镜像并部署该镜像容器。

接下来将详细介绍这些步骤的操作过程。

1.在GitLab页面上设置全局的与SSH命令相关的CI/CD变量

可以参考GitLab官方的ssh key文档:Using SSH keys with GitLab CI/CD | GitLab

(1)将GitLab服务器的私钥内容设置成全局的CI/CD变量

使用以下命令查看私钥内容,然后复制它们

cat /root/.ssh/id_rsa

在GitLab页面上,通过 【Admin Area → Settings → CI/CD → Variables → Expand → Add Variable】菜单路径,执行添加私钥全局变量操作,如图所示:

注意:粘贴私钥内容后,一定要按回车符,添加新行

(2)将应用服务器SSH_KNOWN_HOSTS设置成全局的CI/CD变量

在GitLab服务器上使用以下命令收集应用服务器(IP:172.24.142.64)公钥相关内容,并复制它们:

ssh-keyscan 172.24.142.64

在GitLab页面上,通过 【Admin Area → Settings → CI/CD → Variables → Expand → Add Variable】菜单路径,执行添加SSH_KNOWN_HOSTS全局变量操作,如图所示:

注意:粘贴ssh-keyscan生成的内容后,一定要按回车符,添加新行

(3)将应用服务器IP设置成全局的CI/CD变量

与ssh相关的全局变量添加成功,如图所示:

2.在GitLab页面上设置全局的阿里云私人镜像仓库相关的CI/CD变量

如何使用阿里云私人镜像仓库,网上资料非常多,请大家自行学习,本篇文章不作介绍。假设你已经有了自己的阿里云私人镜像仓库,那么需要设置成全局变量的无非就是镜像仓库名称、用户名、密码,使用上述的方法:在GitLab页面上,通过 【Admin Area → Settings → CI/CD → Variables → Expand → Add Variable】菜单路径,继续添加这些全局变量,如图所示:

当然,读者可以试着使用其他云厂商镜像仓库(腾讯云,华为云等),也可以尝试使用私有部署的Harbor镜像仓库。

3.编写.gitlab-ci.yml文件

我们已经添加了6个全局的CI/CD变量:

重新修改上一篇文章介绍的使用.Net8开发的EShop.WebApi项目的.gitlab-ci.yml文件内容,文件中将会使用到上面定义的6个全局变量,如下:

stages:
  - build
  - deploy


variables:
  ## 镜像版本号      
  Docker_ImageTag: "latest"


  ## 镜像名称
  Docker_Image: "eshop.webapi:$Docker_ImageTag" 


  ## 阿里云镜像名称
  Ali_Docker_Image: "$Ali_Docker_Registry/eshop/$Docker_Image"


build:
  stage: build
  script:
    ## 构建镜像  
    - docker build -f "./EShop.WebApi/Dockerfile" -t $Docker_Image .


    ## 将镜像标记为阿里云镜像名称
    - docker tag $Docker_Image $Ali_Docker_Image
    
    ## 登录阿里云私人镜像仓库
    - docker login -u $Ali_Docker_UserName --password "$Ali_Docker_Password" $Ali_Docker_Registry
    
    ## 将镜像推送到阿里云镜像仓库
    - docker push $Ali_Docker_Image
  only:
    - main  



deploy:
  stage: deploy
  before_script:
  
    ## 安装ssh-agent
    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    
    ## 将GitLab服务器私钥添加到ssh-agent代理中
    - chmod 400 "$SSH_PRIVATE_KEY"
    - ssh-add "$SSH_PRIVATE_KEY"
    
    ## 创建~/.ssh目录
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    
    ## 创建SSH_KNOWN_HOSTS
    - cp "$SSH_KNOWN_HOSTS" ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts


  script:
    ## 使用ssh免密登录应用服务器,执行部署eshop.webapi容器命令
    - ssh -t $ESHOP_SERVER_IP "(docker stop EShop.WebApi && docker rm EShop.WebApi || echo 'Container EShop.WebApi not found, skipping removal.') && docker login -u $Ali_Docker_UserName --password "$Ali_Docker_Password" $Ali_Docker_Registry && docker run -d --name EShop.WebApi -p 9527:80 $Ali_Docker_Image"
  only:
    - main

在.gitlab-ci.yml文件中我们通过ssh登录到应用服务器,然后使用docker命令进行部署,当然也可以使用docker compose命令部署,甚至可以使用k8s来部署,以后有机会将继续介绍如何通过k8s来部署。

关于ssh-agent的知识,可以参考这篇文章:了解ssh代理:ssh-agent_eval ssh-agent-CSDN博客

四、验证

在GitLab的EShopWebApi仓库页面手动执行Pipeline:

Pipeline执行成功之后,可以看到镜像已经推送到了阿里云镜像仓库:

并且应用服务器上已经部署了eshop.webapi容器:

在浏览器上输入接口地址:http://172.24.142.64:9527/WeatherForecast,可以看到返回的信息:

至此,通过GitLab自带的CI/CD实现远程服务器部署应用大功告成!

五、总结

远程部署的核心在于能够使用ssh命令免密登录到应用服务器执行部署命令。

相关推荐
Amelio_Ming5 小时前
Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决
linux·运维·ssh
A ?Charis18 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
IT-民工2111021 小时前
CI/CD 实践总结
运维·ci/cd·自动化
Diamond技术流1 天前
从0开始学习Linux——远程连接工具
linux·学习·centos·ssh·xshell·ftp
秋说1 天前
开源代码管理平台Gitlab如何本地化部署并实现公网环境远程访问私有仓库
gitlab·源代码管理
极小狐1 天前
驭码上新,AI Code Review、基于代码库的知识问答,让研发起飞
gitlab·devsecops·devops·极狐gitlab·安全合规
蚊子不吸吸2 天前
DevOps开发运维简述
linux·运维·ci/cd·oracle·kubernetes·gitlab·devops
恒创科技HK2 天前
ssh和ssl的区别在哪些方面?
运维·ssh·ssl
上烟雨心上尘2 天前
通过 ssh config 快速免密连接服务器
运维·服务器·ssh
老攀呀2 天前
CI/CD 的概念
ci/cd