最近因公司發(fā)展需要尺栖,增加了一些go語言開發(fā)嫡纠,對項目要求使用jenkins+go+docker自動部署上線。6.12更新了使用nginx負載均衡延赌,以及docker-compose文件除盏。
一、安裝jenkins
1挫以、安裝Jenkins者蠕,詳情見centos使用docker搭建jenkins,jenkins使用方法見jenkins的安裝和使用
2掐松、jenkins安裝go插件踱侣,Go plugin
安裝該插件,點擊 “系統(tǒng)管理” -> “管理插件” -> “可選插件” -> 選擇 “Go Plugin” -> 點擊最下邊 “直接安裝” 即可完成安裝甩栈。
3泻仙、配置go插件
系統(tǒng)管理” -> “Global Tool Configuration” -> “Go” -> “新增 Go”
二、在搭建jenkins的服務器和要構建上傳的應用服務器均安裝go環(huán)境
1量没、下載安裝包
wget [https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz](https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz)
2玉转、解壓縮安裝
tar -C /home/service -zxvf go1.12.4.linux-amd64.tar.gz
3、配置環(huán)境變量
vim /etc/profile
export GOROOT=/home/service/go
export PATH=$PATH:$GOROOT/bin
source /etc/profile
4殴蹄、測試
[root@bogon /]# go version
go version go1.12.4 linux/amd64
三究抓、jenkins配置
1、新建任務go選擇構建一個自由風格的軟件項目袭灯,java選擇構建一個maven項目
2刺下、配置git路徑和git賬號密碼和分支,或者git密鑰
3稽荧、構建環(huán)境選擇
4橘茉、構建執(zhí)行shell,先選擇執(zhí)行shell姨丈,再選擇ssh畅卓。
# 配置 GOPATH
export GOPATH="$JENKINS_HOME/golang_workspace"
export GOBINPATH="$GOPATH/bin"
export PATH="$PATH:$GOBINPATH"
export GO111MODULE=on
export GOPROXY=https://goproxy.io
#export GOPROXY="https://athens.azurefd.net"
# 執(zhí)行 go get & build 命令
#創(chuàng)建 $GOPATH目錄
mkdir -p $GOPATH
# 輸出當前時間
date
#構建可執(zhí)行二進制文件
CGO_ENABLED=0 GOARCH=amd64 go build -o bh-go-server-user server.go
#將可執(zhí)行二進制文件傳輸?shù)綉梅掌?#ssh root@172.16.3.41 'bash -x -s' < /home/golang/bh-go-server-user/run.sh
rsync server root@172.16.3.41:/home/golang/bh-go-server-user/
rsync config/server.pem root@172.16.3.41:/home/golang/bh-go-server-user/config
rsync config/server.key root@172.16.3.41:/home/golang/bh-go-server-user/config
四、應用服務器配置
1蟋恬、在上傳到服務器的路徑下創(chuàng)建config目錄
[root@bogon bh-go-server-user]# tree
.
├── config
│ ├── config.env #配置啟動可執(zhí)行二進制文件的配置文件
│ ├── server.key #openssl
│ └── server.pem #openssl
├── run.sh #運行腳本
└── server #可執(zhí)行二進制文件
1 directory, 5 files
2翁潘、配置config.env
3、在shell出已經用rsync將二進制文件server和pem和key傳輸?shù)搅藨梅掌?為什么用rsync而不用scp歼争,因為rsync覆蓋已存在文件速度上有優(yōu)勢拜马,最重要的是rsync可以覆蓋正在運行的二進制文件渗勘,而scp不行。
4俩莽、執(zhí)行二進制文件
./server
5旺坠、利用run.sh腳本執(zhí)行二進制文件
6、run.sh腳本編寫
DATE=$(date +%Y%m%d%H%M%S)
DIR=/home/golang/bh-go-server-user
JARFILE=server
if [ ! -d $DIR/backup ];then
mkdir -p $DIR/backup
fi
cd $DIR
pid=`ps -ef | grep ./server | grep -v grep | awk '{print $2}'`
echo "---------------"
for id in $pid
do
kill -9 $id
echo "killed $id"
done
echo "---------------"
echo "授予當前用戶權限"
echo "執(zhí)行....."
cp $JARFILE backup/$DATE$JARFILE
cd $DIR
nohup ./$JARFILE > run.log &
if [ $? = 0 ];then
sleep 20
tail -n 50 /home/golang/bh-go-server-user/run.log &
fi
cd backup/
ls -lt|awk 'NR>5{print $NF}'|xargs rm -rf
echo "執(zhí)行成功"
7豹绪、后面我又更改了啟動方式价淌,使用dockerfile創(chuàng)建鏡像,并利用docker-compose啟動瞒津。
腳本yun.sh
#DATE=$(date +%Y%m%d%H%M%S)
DATE=$(date +%Y%m%d%H)
DIR=/home/golang/bh-go-server-user
JARFILE=bh-go-server-user
logfile=/home/log/bh/bh-go-server-user
log=bh-go-server-user.log
if [ ! -d $DIR/backup ];then
mkdir -p $DIR/backup
fi
cd $DIR
# pid=`ps -ef |grep ./bh-go-server-user | grep -v grep | awk '{print $2}'`
# echo "---------------"
# for id in $pid
# do
# kill -9 $id
# echo "killed $id"
# break
# done
echo "---------------"
echo "授予當前用戶權限"
echo "執(zhí)行....."
cp $JARFILE backup/$DATE$JARFILE
cd $DIR
docker build --rm -t bh-go-server-user .
cd $logfile
cp $log backup/$DATE$log
cd $DIR
docker-compose up > /home/log/bh/bh-go-server-user/bh-go-server-user.log &
if [ $? = 0 ];then
sleep 20
tail -n 50 /home/log/bh/bh-go-server-user/bh-go-server-user.log
fi
cd /home/log/bh/bh-go-duoduoke/backup/
ls -lt|awk 'NR>7{print $NF}'|xargs rm -f
cd $DIR/backup/
ls -lt|awk 'NR>5{print $NF}'|xargs rm -f
echo "執(zhí)行成功"
8蝉衣、dockerfile文件
之前我是用busybox作為基礎鏡像的,因為busybox鏡像只有十幾k大小巷蚪,后面發(fā)現(xiàn)可能有些依賴沒有有些接口不行就換成centos鏡像了病毡。
FROM centos
LABEL RoES roes@163.com
WORKDIR /root
ADD ./bh-go-server-user ./bh-go-server-user
ADD ./config ./config
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
EXPOSE 51003
ENTRYPOINT ["./bh-go-server-user"]
9、使用docker-compose啟動屁柏,docker-compose.yml配置文件如下:
version: "3"
services:
server1:
image: bh-go-duoduoke
hostname: server1
restart: on-failure
volumes:
- "./config/config.env:/root/config/config.env"
ports:
- "8097:8097"
server2:
image: bh-go-duoduoke
hostname: server2
restart: on-failure
volumes:
- "./config/config1.env:/root/config/config.env"
ports:
- "18097:8097"
server3:
image: bh-go-duoduoke
hostname: server3
restart: on-failure
volumes:
- "./config/config1.env:/root/config/config.env"
ports:
- "28097:8097"
10啦膜、nginx負載均衡
根據(jù)自己nginx版本判斷ssl on是否需要開啟
upstream duomaike {
server 127.0.0.1:8097 weight=3;
server 127.0.0.1:18097;
server 127.0.0.1:28097;
#server 127.0.0.1:38097;
}
server
{
listen 80;
#listen [::]:80;
server_name api.example.com;
index index.html index.htm index.php default.html default.htm default.php;
root /home/wwwroot/api.example.com;
#return 301 https://api.example.com$request_uri;
include rewrite/other.conf;
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
include enable-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log /home/wwwlogs/api.example.com.log;
# api網關
location /V1 {
#add_header Access-Control-Allow-Origin admin.duomaike.top;
#add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
#add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_http_version 1.1;
# 開啟對http1.1支持
proxy_set_header Connection "";
# 設置Connection為空串,以禁止傳遞頭部到后端
proxy_connect_timeout 600s;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffer_size 512k;
proxy_buffers 4 512k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 512k;
proxy_pass http://duomaike;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server
{
listen 443 ssl http2;
#listen [::]:443 ssl http2;
server_name api.example.com localhost;
index index.html index.htm index.php default.html default.htm default.php;
root /home/wwwroot/api.example.com;
# ssl on;
ssl_certificate /usr/local/nginx/conf/go_ssl/api.example.com.pem;
ssl_certificate_key /usr/local/nginx/conf/go_ssl/api.example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
ssl_session_cache builtin:1000 shared:SSL:10m;
# openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
#ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;
include rewrite/other.conf;
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
include enable-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log /home/wwwlogs/api.example.com.log;
# api網關
location / {
proxy_http_version 1.1;
# 開啟對http1.1支持
proxy_set_header Connection "";
# 設置Connection為空串,以禁止傳遞頭部到后端
proxy_connect_timeout 600s;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffer_size 512k;
proxy_buffers 4 512k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 512k;
proxy_pass http://duomaike;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}