Skip to content

Latest commit

 

History

History
260 lines (196 loc) · 11.5 KB

cicd-jenkins.md

File metadata and controls

260 lines (196 loc) · 11.5 KB

【CI/CD】虚拟机搭建Jenkins+Docker+Github环境,实现自动部署

机器准备

首先我们得准备一台Linux机器,可以是云服务器,也可以是本地虚拟机,甚至你Mac本机都可以(不建议)

建议用本地虚拟机,Mac用户可以参考 玩转Vagrant -> 榨干Mac Pro的32G内存

一、 安装Jenkins、初始配置

如果以root用户登录,下面的操作全部不需要sudo,我是以vagrant用户登录,所以默认加sudo

Linux — Jenkins doc 看官网的即可

sudo yum install java-11-openjdk # 安装java
sudo yum install jenkins
sudo systemctl enable jenkins
sudo systemctl start jenkins
# 查看jenkins状态,如下为成功状态
sudo systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
   Loaded: loaded (/usr/lib/systemd/system/jenkins.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2022-11-22 12:18:30 UTC; 8s ago
 Main PID: 2776 (java)
   CGroup: /system.slice/jenkins.service
           └─2776 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=%C/jenkins/war --httpPort=8080
# 如果有安装防火墙
# jenkins 默认开启8080端口,需要手动让防火墙放行8080端口,才能对外开放访问界面
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
sudo firewall-cmd --reload

打开主机的浏览器访问如下地址,进入jenkins设置界面

http://your_ip_or_domain:8080
# 比如这台构建机的静态IP被设置为192.168.31.190,访问8080端口进入如下设置界面

按照提示往下走

坐等安装完毕

然后是注册管理员,一路往下操作即可

执行第一个任务,测试下docker,同时拉个node镜像 如果碰到docker无权限的问题,参考之前说过的

docker的架构是C/S架构,使用docker时其实是命令使用socket与docker的守护进程进行通信 在linux中,unix socket属于root用户,因此需要root权限才能访问 但在docker中,提供了一个用户组的概念,可以将执行命令的用户添加到docker用户组中,就可以正常执行docker相关命令

sudo gpasswd -a jenkins docker # 在 Jenkins 中执行的终端用户做 jenkins ,所以我们只需要将 jenkins 加入到 docker 用户组即可
newgrp docker # 更新docker用户组
sudo service docker restart # 重启docker,退出当前用户重新登录即可
sudo service jenkins restart # 重启jenkins

如无意外,构建成功

到此为止,构建机的初始化、docker、jenkins的基础配置都已经完成了,下面配置一下node和git仓库

二、 Jenkins安装Node插件

可以选择在系统层面安装node,也可以直接在jenkins里进行安装,这里选择jenkins插件的方式

  • 系统管理 -> 插件管理 -> 可选插件 -> 搜索node -> 立即安装
  • 系统管理 -> 全局工具配置 -> NodeJs -> 选择对应版本
  • 进入具体项目配置 -> 构建环境 -> 勾上Provide Node & npm bin/ folder to PATH -> 应用/保存

如果需要不同版本的node,建议通过nvmn等管理工具在系统上安装需要的node版本,或者通过docker拉取node镜像

# 下载nvm
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | zsh

# 将nvm添加到环境变量
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

# instal node
nvm install 16.18.1

# install yarn
npm install --global yarn 

注意:如果node、yarn等是在当前vagrant用户安装的,切到 jenkins用户会报command not found,所以更好的办法还是通过docker拉取镜像

三、配置SSH协议,Jenkins访问Git repo

在Github/Gitlab/Gitee上准备一个真实仓库

我准备了一个 vite+vue3 — Github

SSH配置

  • 在Github配置公钥
  • 在Jenkins使用私钥与git进行身份校验
# 由于Jenkins用的是jenkins用户, 所以需要先切换用户再生成
sudo su -s /bin/zsh jenkins
# 在构建机上生成公钥私钥
ssh-keygen -t rsa -C "[email protected]" # 换成自己邮箱

在Github配置公钥

在Jenkins中,私钥密码等认证信息都是以凭证的方式管理的,可以做到全局通用,在配置具体任务时,添加自己的凭证即可

  • 项目配置 -> 源码管理 -> Git -> Credentials , 一步步操作即可

这一步特别注意:复制私钥包含开头的 BEGIN OPENSSH PRIVATE KEY 和结尾的 END OPENSSH PRIVATE KEY

如果填完凭证后,还是获取失败,可以在服务器上执行以下命令,提前拉取一下git仓库

# 将github.com添加到 known_hosts 里
git ls-remote -h [email protected]:amandakelake/cicd-fe.git HEAD

四、Jenkins构建镜像、推送到Docker Hub

先来尝试一下构建docker镜像

4.1 构建镜像

目录中添加Dockerfile文件,并添加如下内容

# 多阶段构建
FROM node:16-alpine as builder

# 设置为工作目录,以下 RUN/CMD 命令都是在工作目录中进行执行
WORKDIR /code

# 提前将依赖移动至目录,利用docker缓存,只要ADD的内容不变,缓存就不会被破坏
ADD package.json yarn.lock ./
RUN yarn

# 全部代码添加到镜像中
COPY . ./
RUN yarn build

# 利用更小的nginx镜像
FROM nginx:alpine
COPY --from=builder /code/dist/ /usr/share/nginx/html/
# nginx 暴露 80端口
EXPOSE 80 
# 启动nginx
CMD ["nginx", "-g", "daemon off;"] 

package.json添加docker:build命令,利用最新Tag作为docker构建镜像的Tag

{
  "scripts": {
    "docker:build": "docker build -t luogc/cicd-fe:$(git describe --tags `git rev-list --tags --max-count=1`) .", 
      "docker:run": "docker run -d -p 8001:80 luogc/cicd-fe:$(git describe --tags `git rev-list --tags --max-count=1`)"
  }
}

git describe --tags $(git rev-list --tags --max-count=1) 命令可用于获取最新 git tag ,得到如v0.0.1的结果

docker:run命令可用于本地查看效果,这里docker内部80端口对外映射到8001端口,访问http://localhost:8001可看到效果

下面尝试一下在Jenkins上执行docker:build命令,将上面的命令复制到项目配置的执行shell,保存后触发一下构建,如无意外会得到Finished: SUCCESS结果

4.2 镜像推送

接下来试一下镜像推送,这里我们直接使用 Docker Hub 来推送管理镜像库

企业出于安全考虑,会构建专属的私有镜像库,常用平台有Nexus,Jfrog,Harbor,感兴趣的可自行搭建试试,反正也就是用vagrant整多一台虚拟机出来

先在 Docker Hub 注册账号然后生成access token

# luogc的token
dckr_pat_CStim7jIMH0qgwKMbCM7KQorjro

拿到token后到虚拟机上尝试一下登录 docker login -u [username]

# 如无意外 -> Login Succeeded
docker login -u luogc
Password:
WARNING! Your password will be stored unencrypted in /home/vagrant/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

先在宿主机本地试一下最简单的推送 docker

docker login # 本地也先登录一下
# 默认推送到Docker Hub
docker push luogc/cicd-fe:v0.0.3

推送Docker Hub速度很慢,很有可能失败,失败会尝试多次重传,这一步失败也没关系

这时候,自建镜像仓库就比较有必要性了,不单单是安全,速度和成功率也很重要

现在来试一下Jenkins的推送,首先要解决的是凭证问题 虽然可以在shell里直接 docker login -u "用户名" -p "密码" 用明文账号和密码来登录,但肯定不安全,所以还是要利用Jenkins的凭据功能,先用上面创建的token新建一个凭据

然后找到项目配置里的构建环境 -> Use secret text(s) or file(s) -> Username and password (separated),用刚才添加的凭据,再给用户名和密码分别起两个名字DOCKER_HUB_LOGIN_USERNAME DOCKER_HUB_LOGIN_PASSWORD,相当于两个隐私的全局变量

把这两个变量直接套到docker login -u "用户名" -p "密码"

docker login -u $DOCKER_HUB_LOGIN_USERNAME -p $DOCKER_HUB_LOGIN_PASSWORD

Jenkins测试一下构建,在控制台看到下面的输出那就是成功了

+ docker login -u **** -p ****
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /var/lib/jenkins/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
Finished: SUCCESS

下面把这三条命令结合起来,让Jenkins完整的跑一圈看看(最终推送失败没关系,主要是想看看能不能跑通整个流程)

docker login -u $DOCKER_HUB_LOGIN_USERNAME -p $DOCKER_HUB_LOGIN_PASSWORD
docker build -t luogc/cicd-fe:$(git describe --tags `git rev-list --tags --max-count=1`) .
docker push luogc/cicd-fe:$(git describe --tags `git rev-list --tags --max-count=1`)

如果推送成功,能在Docker Hub看到对应的镜像

结语

本文完成了Jenkins安装配置、构建推送docker镜像推送的流程,其实就是DevOps概念里的CI(持续集成)这一部分的内容

还没有涉及到后面的CD(持续部署)部分,现在很多大公司都用Kubernetes来进行持续部署(当然,K8S的强大之处并不仅限于部署)

想了解更多Kubernetes的内容,可以从 Kubernetes】集群搭建 开始