一起學Python吧~DevOps工程師必備技能

#!/bin/env python3
#-*- coding:utf8 -*-
#學Python3的第十七天(CI/CD項目)
#*****************Jenkins********************
"""項目所需機器環境
-一臺localgit虛擬機:用來當做程序員敲代碼的服務器
    配置:運行內存500MB即可
    IP:192.168.1.31
-一臺gitserver虛擬機:部署gitlab服務(跟github是一個東西)
    配置:運行內存3.5G~4G推薦4G
    IP:192.168.1.30
-一臺Jenkins虛擬機:部署jenkins(CI交付工具)服務
    配置:運行內存500MB即可
    IP:192.168.1.32
"""
"""CI/CD:持續集成/持續交付
-流程:
    開發部門->交付給測試部->反饋給開發部的同時->交付給運維部
graph LR
d(開發部)--交付-->qa(測試部)
qa--反饋-->d
qa--交付-->o(運維部)
"""
"""程序語言
- 解釋型語言:python / shell / php
- 編譯型語言:C / C++ / Java / Go
    examples:
        [root@jenkins ~]# yum -y install gcc
        [root@jenkins ~]# vim hello.c
        [root@jenkins ~]# cat hello.c 
        #include <stdio.h>
        
        int main(void){
            printf("Hello World!\n");
            return 0;
        }
        [root@jenkins ~]# gcc -o hello hello.c 
        [root@jenkins ~]# ls
        hello  hello.c  jenkins-2.190.1-1.1.noarch.rpm
        [root@jenkins ~]# ./hello 
        Hello World!
"""
"""Jenkins(java寫的)
-是一個CI交付工具:
    graph LR
    d(程序員)--上傳-->g(gitlab)
    j(jenkins服務器)--下載-->g
    a1(應用服務器)--下載-->j
    a2(應用服務器)--下載-->j
    a3(應用服務器)--下載-->j
-由於Jenkins是java寫的,所以需要java環境:
    需要接入互聯網、需要安裝了java

[root@jenkins ~]# yum -y install java-1.8.0-openjdk
[root@jenkins ~]# ls
jenkins-2.190.1-1.1.noarch.rpm     #自行下載
[root@jenkins ~]# rpm -ih jenkins-2.190.1-1.1.noarch.rpm 
警告:jenkins-2.190.1-1.1.noarch.rpm: 頭V4 DSA/SHA1 Signature, 密鑰 ID d50582e6: NOKEY
################################# [100%]
正在升級/安裝...
################################# [100%]
[root@jenkins ~]# systemctl start jenkins
[root@jenkins ~]# systemctl enable jenkins
jenkins.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig jenkins on
[root@jenkins ~]# firefox 192.168.1.32:8080
#訪問http://x.x.x.x:8080 -> 根據提示解鎖 -> 自定義部分,點擊“選擇插件來安裝”,再選“無”後安裝 -> 創建第一個管理員,選右下角“使用admin繼續登陸“ -> 保存並完成 -> 開始使用
[root@jenkins ~]# cat /var/lib/jenkins/secrets/initialAdminPassword 
6b9ab6b453d2429c9468adc30e8ad2fa
"""
"""修改管理員密碼改爲國內鏡像站點安裝插件
首頁 -> Manage Jenkins -> Manage Plugins -> Advanced -> Update Site: https://mirrors.tuna.tsinghua.edu.cn/jenkins/ -> Submit
頁面右上角admin -> configure -> password -> Save
"""
"""安裝插件
Available -> 按ctrl + f搜索 -> 選中Localization: Chinese (Simplified)和Git Parameter -> Install without restart -> 勾選Restart Jenkins when installation is complete and no jobs are running
"""
"""CI/CD流程
***1).程序猿在自己的電腦上編寫代碼
[root@localgit ~]# mkdir myweb
[root@localgit ~]# cd myweb/
[root@localgit myweb]# git init
初始化空的 Git 版本庫於 /root/myweb/.git/
[root@localgit myweb]# echo "<marquee><font color=yellow><h1>Hello world</h1>" > index.html
[root@localgit myweb]# git add .
[root@localgit myweb]# git commit -m 'my site 1.0'
[master(根提交) b984e1d] my site 1.0
 1 file changed, 1 insertion(+)
 create mode 100644 index.html
[root@localgit myweb]# git tag 1.0
[root@localgit myweb]# echo '<h2>my site 2.0</h2>' >> inedx.html
[root@localgit myweb]# git add .
[root@localgit myweb]# git commit -m "my site 2.0"
[master 0e3a6f9] my site 2.0
 1 file changed, 1 insertion(+)
 create mode 100644 inedx.html
[root@localgit myweb]# git tag 2.0

***2).管理員在gitlab上創建項目,類型爲公開,爲組創建.添加昨天創建的普通用戶爲該項目的主程序猿

***3).程序員上傳代碼到gitlab服務器
[root@localgit myweb]# git remote add origin http://192.168.1.30/newgroup/website.git
[root@localgit myweb]# git push -u origin --all
Username for 'http://192.168.1.30': csdnak
Password for 'http://[email protected]': 
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 509 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To http://192.168.1.30/newgroup/website.git
 * [new branch]      master -> master
分支 master 設置爲跟蹤來自 origin 的遠程分支 master。
[root@localgit myweb]# git push -u origin --tags
Username for 'http://192.168.1.30': csdnak
Password for 'http://[email protected]': 
Total 0 (delta 0), reused 0 (delta 0)
To http://192.168.1.30/newgroup/website.git
 * [new tag]         1.0 -> 1.0
 * [new tag]         2.0 -> 2.0
 
***4).配置jenkins下載代碼
[root@jenkins ~]# yum -y install git
#Jenkins網頁操作
新建Item -> 任務名:website / Freestyle project -> 勾選This project is parameterized -> 添加參數 -> Git Parameter => Name: webver / Parameter Type: Branch or Tag  / Default Value: origin/master -> 源碼管理 => Git => Repository URL: http://192.168.1.30/newgroup/website.git / Branches to build:$webver -> 保存

構建:

Build with Parameters -> 選擇相關的tag進行構建。構建完成的內容自動放到了/var/lib/jenkins/workspace目錄
-然後點擊左邊Build with Parameters裏面的1.0->開始構建->2.0->開始構建:
-到Jenkins服務器上查看
[root@jenkins ~]# ls  /var/lib/jenkins/workspace/website
index.html  inedx.html
[root@jenkins ~]# cat /var/lib/jenkins/workspace/website/*
<marquee><font color=yellow><h1>Hello world</h1>
<h2>my site 2.0</h2>

***5).修改工程.將程序下載到子目錄中.配置->源碼管理->Additional Behaviours=>
Checkout to a sub-direcotry:  website-$webver -> 保存後構建測試

***6).修改工程:
    1.將軟件目錄拷貝到/var/www/html/deploy/pkgs
    2.將軟件目錄下的.git隱藏目錄刪除
    3.將軟件目錄打包,便於下載
    4.刪除軟件目錄
    5.計算壓縮包的md5值
    6.生成/var/www/html/deploy/{last_ver,live_ver}兩個文件,分別記錄前一版本號和當前版本號

[root@jenkins ~]# yum -y install httpd    
[root@jenkins ~]# systemctl restart httpd
[root@jenkins ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@jenkins ~]# mkdir -p /var/www/html/deploy/pkgs
[root@jenkins ~]# chown -R jenkins.jenkins /var/www/html/deploy
"""
"""execute shell中添寫的腳本代碼:
deploy_dir=/var/www/html/deploy/pkgs  #定義變量
cp -r website-$webver $deploy_dir   #拷貝軟件目錄到web目錄
cd $deploy_dir  #切換到web目錄
rm -rf website-$webver/.git  #刪除版本庫文件
tar czf website-$webver.tar.gz website-$webver   #打包壓縮
rm -rf website-$webver    #刪除軟件目錄,只保留壓縮包
#計算壓縮包的md5值
md5sum website-$webver.tar.gz |awk '{print $1}' > website-$webver.tar.gz.md5
#生成last_ver和live_ver文件
cd ..
[-f live_ver]&&cat live_ver > last_ver
echo $webver > live_ver
"""
"""自動部署
- /var/www/download:保存下載的壓縮包
- /var/www/deploy:保存live_ver文件和解壓目錄
- /var/www/html/csdnak:指向發不的應用目標
腳本具體作用:
    程序員開發完新版->發佈到gitlab->jenkins構建新項目->deploy.py實現自動部署上線新版本程序
"""
#deploy.py
import wget
import os
import requests
import hashlib
import tarfile

def has_new_ver(ver_url, ver_fname):
    '有新版本返回True,否則返回False'
    # 如果本地沒有版本文件,則爲True
    if not os.path.isfile(ver_fname):
        return True

    # 取出本地版本
    with open(ver_fname) as fobj:
        local_ver = fobj.read()

    # 本地版本與網上版本比較,如果不一致返回True
    r = requests.get(ver_url)
    if local_ver != r.text:
        return True
    else:
        return False

def file_ok(md5_url, fname):
    '如果文件已損壞返回False,否則返回True'
    # 計算本地文件的md5值
    m = hashlib.md5()
    with open(fname, 'rb') as fobj:
        while 1:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)

    # 取出網上的md5值,進行比較
    r = requests.get(md5_url)
    if m.hexdigest() == r.text.strip():
        return True
    else:
        return False

def deploy(app_fname):
    '部署軟件'
    deploy_dir = '/var/www/deploy'
    dest = '/var/www/html/csdnak'
    # 解壓
    tar = tarfile.open(app_fname)
    tar.extractall(path=deploy_dir)
    tar.close()

    # 取出軟件目錄名
    app_dir = app_fname.split('/')[-1]
    app_dir = app_dir.replace('.tar.gz', '')
    app_dir = os.path.join(deploy_dir, app_dir)

    # 如果目標鏈接文件已存在,先刪除
    if os.path.exists(dest):
        os.remove(dest)

    # 創建軟鏈接
    os.symlink(app_dir, dest)


if __name__ == '__main__':
    # 判斷是否有新版本,沒有則退出
    ver_url = 'http://192.168.1.32/deploy/live_ver'
    ver_fname = '/var/www/deploy/live_ver'
    if not has_new_ver(ver_url, ver_fname):
        print('未發現新版本。')
        exit(1)

    # 下載新版本軟件
    r = requests.get(ver_url)
    ver = r.text.strip()  # 把額外的\n刪除,得到版本
    app_url = 'http://192.168.1.32/deploy/pkgs/website-%s.tar.gz' % ver
    down_dir = '/var/www/download'
    wget.download(app_url, down_dir)

    # 校驗。如果下載的文件已損壞,刪除它
    md5_url = app_url + '.md5'
    app_fname = app_url.split('/')[-1]
    app_fname = os.path.join(down_dir, app_fname)
    if not file_ok(md5_url, app_fname):
        os.remove(app_fname)
        print('文件已損壞。')
        exit(2)

    # 部署軟件
    deploy(app_fname)

    # 更新live_ver文件的版本
    if os.path.exists(ver_fname):
        os.remove(ver_fname)

    wget.download(ver_url, ver_fname)

"""項目執行順序(再次強調)
(程序員)localgit->發佈到gitlab服務器上->在jenkins構建新項目->利用以上腳本deploy.py實現自動部署上線新版本程序
"""
#具體過程如下
"""發佈1.0版本
[root@room9pc01 ~]# cd /var/www/
[root@room9pc01 www]# mkdir download
[root@room9pc01 untitled]# ./17.day.py    #執行腳本查看效果
100% [.......................................................................] 4 / 4
[root@room9pc01 www]# ls
cgi-bin  deploy  download  exam  html
[root@room9pc01 www]# ls deploy/
live_ver  website-1.0   #版本號
[root@room9pc01 www]# ls download/
website-1.0.tar.gz    #版本包
[root@room9pc01 www]# ls html/ 
csdnak  #生成的軟連接
[root@room9pc01 www]# firefox http://127.0.0.1/csdnak/   #訪問你的軟鏈接,內容就是1.0版本網頁內容
"""
"""發佈4.0版本(gitlab必須構建了4.0版本)
[root@room9pc01 untitled]# ./17.day.py 
100% [.......................................................................] 4 / 4
[root@room9pc01 www]# ls  deploy/ download/ html/
deploy/:
live_ver  website-1.0  website-4.0         #版本號也多出來一個4.0

download/:
website-1.0.tar.gz  website-4.0.tar.gz       #可以看到多出一個4.0版本包

html/:
csdnak         #鏈接已被重置,直接訪問看效果即可

[root@room9pc01 www]# firefox http://127.0.0.1/csdnak/
"""
#如果想相返回舊版本可以寫一個回滾腳本
"""回滾思路
-取出last_ver版本號,賦值給ver
-構建本地目錄'/var/www/deploy/website-%s' % ver
-把/var/www/html/nsd1906刪除
-創建軟鏈接
"""
#
# def has_new_ver(ver_url, ver_fname):
#     '有新版本返回True,否則返回False'
#     # 如果本地沒有版本文件,則爲True
#     if not os.path.isfile(ver_fname):
#         return True
#
#     # 取出本地版本
#     with open(ver_fname) as fobj:
#         local_ver = fobj.read()
#
# def deploy(app_fname):
#     '部署軟件'
#     deploy_dir = '/var/www/deploy'
#     dest = '/var/www/html/csdnak'
#     # 解壓
#     tar = tarfile.open(app_fname)
#     tar.extractall(path=deploy_dir)
#     tar.close()
#
#     # 取出軟件目錄名
#     app_dir = app_fname.split('/')[-1]
#     app_dir = app_dir.replace('.tar.gz', '')
#     app_dir = os.path.join(deploy_dir, app_dir)
#
#     # 如果目標鏈接文件已存在,先刪除
#     if os.path.exists(dest):
#         os.remove(dest)
#
#     # 創建軟鏈接
#     os.symlink(app_dir, dest)
#
# if __name__ == '__main__':
#     # 校驗。如果下載的文件已損壞,刪除它
#     md5_url = app_url + '.md5'
#     app_fname = app_url.split('/')[-1]
#     app_fname = os.path.join(down_dir, app_fname)
#     if not file_ok(md5_url, app_fname):
#         os.remove(app_fname)
#         print('文件已損壞。')
#         exit(2)
#
#     # 部署軟件
#     deploy(app_fname)
#
#     # 更新live_ver文件的版本
#     if os.path.exists(ver_fname):
#         os.remove(ver_fname)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章