前端自動化集成部署交付實踐

image

前言

隨着先後端分離應用模式的推廣,前端項目可獨立部署維護上線,再也不僅僅將前端開發後打包的文件直接丟到一個文件目錄下就完事大吉了,如今對前端來講也須要了解運維的相關知識,本文旨在介紹一些相關的運維概念以及一些前端運維的實踐。html

CI/CD

cicd

持續集成

continuous integration 持續集成是一種軟件實踐,流程爲:開發 => 打包 => 集成 => 測試

持續交付

continuous delivery 持續交付是一種軟件工程手法,流程爲:測試 => 發佈

持續部署

continous deployment 持續部署是在持續交付的管道中發佈版本給最終用戶的一種軟件工程流程,流程爲:發佈 => 部署上線

持續集成、持續交付、持續部署是發佈流程的不一樣階段前端

Docker

docker

容器 + 鏡像

docker 是一個開源的應用容器引擎。開發者能夠打包本身的應用到容器裏面,而後遷移到其餘機器的 docker 應用中;開發者能夠快速製做一個本身自定義的鏡像,快速分享,也能夠上傳到鏡像庫進行存取和管理;容器之間相互隔離不衝突,硬件資源共享。

Docker in Docker

容器內僅部署 docker 命令行工具(做爲客戶端),實際執行交由宿主機內的 docker-engine(服務器)

Jenkins

jenkins

概念

Jenkins 是一個基於Java語言開發的CI持續構建工具,主要用於持續、自動的構建/測試軟件項目。它能夠執行你預先設定好的設置和腳本,也能夠和 Git工具作集成,實現自動觸發和定時觸發器構建。

Gitlab

gitlab

概念

gitlab既是一種服務,也是一種軟件。既能夠在gitlab.com上去租用服務,也能夠下載gitlab阮籍你本身搭建服務

Nginx

nginx

概念

Nginx採用C進行編寫,處理靜態文件,索引文件以及自動索引;打開文件描述符緩衝。無緩存的反向代理加速,簡單的負載均衡和容錯。FastCGI,簡單的負載均衡和容錯。模塊化的結構。

Nginx是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務vue

Nexus

nexus

概念

製品倉庫: 構建過程的輸出物,包括軟件包,測試報告,應用配置文件等可在服務器上直接 運行或可查看二進制形式的文件,一般稱之爲二進制軟件製品。具備版本管理,歷史管理,權限校驗等功能。

Nexus可在本身的局域網內搭建本身的遠程倉庫服務器,稱爲私服,私服服務器便是公司內部的maven遠程倉庫,私服還充當一個代理服務器,可從互聯網中央倉庫自動下載node

  • proxy 本地倉庫,一般咱們會部署本身的構件到這一類型的倉庫。好比公司的第二方庫
  • hosted 代理倉庫,它們被用來代理遠程的公共倉庫,如maven中央倉庫
  • group 倉庫組,用來合併多個hosted/proxy倉庫,當你的項目但願在多個repository使用資源時就不須要屢次引用了,只須要引用一個group便可

Ansible

ansible

概念

ansible是基於Python開發的自動化運維工具。其優點在於能夠批量操做,基本原理是經過ansible的核心進行經過ssh傳輸的通訊進行相關的分發處理,進行user與host的通訊

Modules

執行命令的功能模塊,Ansible2.3版本爲止,共有1039個模塊。還能夠自定義模塊react

Inventory

管理主機的清單,默認是/etc/ansible/hosts文件linux

Playbook

任務劇本(又稱任務集),編排定義Ansible任務集的配置文件,由Ansible順序依次執行,yaml格式nginx

Plugins

插件,模塊功能的補充,常有鏈接類型插件,循環插件,變量插件,過濾插件,插件功能用的較少git

API

提供給第三方程序調用的應用程序編程接口github

實踐

操做環境: linux/centos7web

操做內容: 一臺 gitlab + jenkins + ansible 服務器推送多臺 nginx 服務器

docker

  1. 安裝依賴
yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 使用阿里雲源安裝
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install docker-ce
  1. 啓動docker
systemctl start docker

systemctl enable docker
  1. 可配置阿里雲容器鏡像加速器

阿里雲容器鏡像服務

gitlab + jenkins + ansible

安裝jenkins

  1. 安裝防火牆
yum install firewalld systemd -y
service firewalld start
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="xxx.xx.x.x/16" accept"
systemctl reload firewalld
  1. 編寫Dockerfile
FROM jenkins/jenkins
USER root
# 清除了基礎鏡像設置的源,切換成阿里雲源
RUN echo '' > /etc/apt/sources.list.d/jessie-backports.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie main contrib non-free" > /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian jessie-updates main contrib non-free" >> /etc/apt/sources.list \
  && echo "deb http://mirrors.aliyun.com/debian-security jessie/updates main contrib non-free" >> /etc/apt/sources.list
# 更新源並安裝缺乏的包
RUN apt-get update && apt-get install -y libltdl7
ARG dockerGid=999

RUN echo "docker:x:${dockerGid}:jenkins" >> /etc/group
  1. 構建jenkins鏡像
docker build -t local/jenkins .
  1. 啓動鏡像

新建/home/jenkins/目錄,將jenkins目錄外掛到宿主機內

mkdir /home/jenkins

chown -R 1000 /home/jenkins/

鏡像建立容器並啓動

docker run -itd --name jenkins -p 8080:8080 -p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /home/jenkins:/var/jenkins_home \
--restart always \
--user root local/jenkins
  1. 啓動jenkins

釋放8080和50000端口

firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --add-port=50000/tcp --permanent

systemctl reload firewalld
  1. 初始化jenkins配置
修改密碼 => 下載插件 => 重啓容器

初始化jenkins後會有一個初始密碼,可經過docker exec -it jenkins /bin/bash進入容器後查看cat /var/jenkins_home/secrets/initialAdminPassword

  1. 配置公鑰私鑰

進入jenkins容器,經過ssh-keygen生成公鑰私鑰

docker exec -it jenkins /bin/bash
ssh-keygen -t rsa

進入~/.ssh查看id_rsa和id_rsa.pub,爲jenkins配置

系統管理 => 安全 => Manage Credentials => 全局 => 添加憑據 => 選擇SSH Username with private key

cicd01

cicd02

cicd03

  1. 配置node環境
系統管理 => 全局工具配置 => NodeJS

cicd04

  1. 新建任務
首頁 => 左側導航 => 新建任務 => 源碼管理 + 構建環境 + 構建

cicd05

cicd06

構建這裏選擇執行shell,可將命令寫入其中,這裏鏡像名稱一般爲jenkins服務器地址,後邊加時間戳能夠避免重名

set -e
timestamp=`date '+%Y%m%d%H%M%S'`

node -v
npm -v

rm -rf node_modules package-lock.json

npm install

npm run build

(docker ps | grep ansible) && (docker rm -f ansible)

# 編譯docker鏡像
docker build -t xxx.xx.xx.xxx:8082/fe/nginx-fe-$timestamp .

# 推送docker鏡像到製品庫
docker push xxx.xx.xx.xxx:8082/fe/nginx-fe-$timestamp

docker run -id --name ansible ansible:t1

docker exec -i ansible ansible-playbook --syntax-check /root/playbook.yml

docker exec -i ansible ansible-playbook -e "timestamp=$timestamp" /root/playbook.yml

docker rm -f ansible
  1. 登陸製品庫

修改daemon.json

vi /etc/docker/daemon.json

{
    "insecure-registries": [
        "xxx.xx.xx.xxx:8082",
        "xxx.xx.xx.xxx:8081"
    ]
}

重啓docker

systemctl daemon-reload
systemctl restart docker

docker login登陸

docker exec -it jenkins /bin/bash

docker login 服務器ip:端口
exit

安裝gitlab

  1. 拉取gitlab鏡像
docker pull gitlab/gitlab-ce
  1. 建立gitlab容器

建立gitlab工做目錄

mkdir /home/gitlab

啓動gitlab容器

docker run -itd -p 443:443 \
-p 8899:8899 \
-p 333:333 \
--name gitlab \
--restart always \
-v /home/gitlab/config:/etc/gitlab \
-v /home/gitlab/logs:/var/log/gitlab \
-v /home/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce
  1. 修改防火牆
firewall-cmd --zone=public --add-port=333/tcp --permanent
firewall-cmd --zone=public --add-port=8899/tcp --permanent

systemctl reload firewalld
  1. 修改gitlab配置文件

修改配置文件

vi /home/gitlab/config/gitlab.rb

exteranl_url 'http://外部訪問域名/地址:端口'
gitlab_rails['gitlab_ssh_host'] = 'SSH外部訪問域名/地址'
gitlab_rails['gitlab_shell_ssh_port'] = SSH端口

修改ssh端口

docker exec -it gitlab /bin/bash

vi /assets/sshd_config
vi /etc/ssh/sshd_config

重啓gitlab

docker restart gitlab
  1. 啓動gitlab
宿主機:端口 => 修改密碼

修改gitlab密碼

docker exec -it gitlab /bin/bash

gitlab-rails console production

user = Uer.where(id:1).first
user.password = "xxxxx"
user.password_confirmation = "xxxxx"

user.save!

quit
  1. 配置jenkins的公鑰
登陸gitlab => 點擊頭像 => 設置 => SSH密鑰

將jenkins中查到的~/.ssh/id_rsa.pub添加到gitlab的ssh密鑰中

cicd07

  1. 在前端項目根目錄下添加Dockerfile
FROM nginx:1.15-alpine
COPY dist /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
  1. 新建倉庫 + 配置webhook

新建倉庫後,配置webhook,可經過git相關命令進行自動化部署,可參考這篇文章[[後端]gitlab之webhook自動部署](https://www.jianshu.com/p/00b...,github的webhook配置可參考這篇Jenkins與Github集成 webhook配置

安裝nexus

  1. 拉取nexus鏡像
docker pull sonatype/nexus3
  1. 建立nexus容器

建立nexus工做目錄

mkdir /home/nexus && chown -R 200 /home/nexus

啓動容器

docker run -d -p 8081:8081 -P 8082:8082 \
--name nexus \
-v /home/nexus:/nexus-data \
--restart always \
sonatype/nexus3
  1. 修改防火牆
firewall-cmd --zone=public --add-port=8081/tcp --permanent
firewall-cmd --zone=public --add-port=8082/tcp --permanent
  1. 啓動nexus

查看日誌

docker logs -f nexus
  1. 修改配置
進入nexus => 修改密碼

cicd08

cicd09

  1. 建立私服
齒輪圖標 => Repositories => Create repository => 填寫表單

cicd10

cicd11

安裝ansible

  1. 建立ansible工做目錄
mkdir /home/ansible-file && cd /home/ansible-file

mkdir ssh
touch Dockerfile
touch hosts
touch playbook.yml
  1. 將配置的公鑰私鑰放入ssh文件夾下
cp -r ~/.ssh/* /home/ansible-file/ssh/
  1. 編輯Dockerfile
FROM centos:7
RUN yum -y install wget curl vim openssh-clients
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum clean all
RUN yum makecache

COPY ssh /root/.ssh/

RUN chmod 755 ~/.ssh/
RUN chmod 600 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
RUN yum -y install ansible

COPY hosts /etc/ansible/

RUN sed -i 's/^#host_key_checking = False/host_key_checking = False/' /etc/ansible/ansible.cfg
RUN ansible --version

COPY playbook.yml /root/
  1. 編輯hosts 多臺服務器ip
[fe-servers]
xxx.xx.xx.xxx
xxx.xx.xx.xxx
xxx.xx.xx.xxx
  1. 編輯playbook
---
- hosts: all
  remote_user: root
  vars: 
    timestamp: 20200806165833
  tasks:
    - name: docker pull new images
      shell: 'chdir=~ docker pull xxx.xx.xx.xxx:8082/fe/nginx-fe-{{timestamp}}
    - name: docker rmf
      shell: 'chdir=~ docker ps | grep xxx && docker rm -f xxx'
      ignore_errors: true
    - name: docker run
      shell: 'chdir=~ docker run -p 80:80 -itd --name xxx xxx.xx.xx.xxx:8082/fe/nginx-fe-{{timestamp}}'

nginx

  1. 拉取nginx鏡像
docker pull nginx
  1. 建立nginx容器

建立nginx工做目錄

mkdir /home/nginx

啓動容器

docker run -itd -p 80:80 --name xxx \
-v /home/nginx/html:/usr/share/nginx/html \
-v /home/nginx/logs:/var/log/nginx \
--restart always \
nginx
  1. 公鑰私鑰

使用ssh-keygen建立公鑰私鑰

ssh-keygen -t rsa

在.ssh文件夾下建立authorized_keys,將jenkins的公鑰放入其中

cd .ssh/
touch authorized_keys

vi authorized_keys
  1. 登陸製品庫

修改daemon.json

vi /etc/docker/daemon.json

{
    "insecure-registries": [
        "xxx.xx.xx.xxx:8082",
        "xxx.xx.xx.xxx:8081"
    ]
}

重啓docker

systemctl daemon-reload
systemctl restart docker

docker login登陸

docker exec -it nginx /bin/bash

docker login 服務器ip:端口
exit

結果

example

總結

前端自動化部署可在內部開發及後續上線工程中進行運維控制,對前端來講也是愈來愈重要的能力,總體流程:

前端git提交 => gitlab/github更新 => 觸發webhook命令 => jenkins構建 => nexus製品庫生成 => ansible分發 => 多臺nginx交付

對於gitlab來講還有不一樣stage進行的不一樣階段的cicd全流程服務,具體可根據團隊的需求進行個性化的定製,若是後期項目龐大,好比採用了微前端架構對不一樣框架如angular、react、vue進行不一樣層次部署交付,可配合k8s(ps: 感興趣的同窗,可參看這篇文章[]())等進行更爲嚴格的開發上線流程控制。

總之,在大前端的趨勢下,前端延伸的方向也更爲多樣,對於咱們的要求也會愈來愈多,工程化、智能化、可視化等等,要在某一領域有所建樹,咱們都還要不斷努力才行,加油!與君共勉!

參考

感謝

在此,特別感謝碼雲前端王聖鬆大佬的分享,此爲其我的歷程分享一位00後前端2年經驗的成長曆程,感興趣的同窗能夠關注一波

相關文章
相關標籤/搜索