ubuntu-14.04下安装KVM虚拟化

ubuntu-server 上安装KVM

一、检查CPU是否支持安装 KVM

egrep -o '(vmx|svm)' /proc/cpuinfo

二、安装KVM所需要的软件包

apt-get install qemu-kvm libvirt-bin virt-manager bridge-utils

注:virt-manager为GUI管理窗口,bridge-utils:用于网络桥接

三、检查安装是否成功

lsmod | grep kvm

四、拉取镜像

wget http://mirrors.ustc.edu.cn/ubuntu-releases/trusty/ubuntu-14.04.4-server-amd64.iso
qemu-img create -f raw /data1/kvm/data/kvm-20160724-01.img 1024G

五、网卡配置参照

cat > /etc/network/interfaces <<OEF
# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto eth1
iface eth1 inet manual

auto br0
iface br0 inet static
address 118.123.9.86
netmask 255.255.255.192
gateway 118.123.9.65
dns-nameservers 144.114.114.114
bridge_ports eth0

auto br1
iface br1 inet static
address 10.10.20.16
netmask 255.255.255.0
gateway 10.10.20.254
bridge_ports eth1
OEF

六、虚拟机安装

virt-install --name kvm-20160725-01     --ram 8196     --vcpus=8,sockets=1,cores=8,threads=1     --arch=x86_64     --os-type=linux     --os-variant=ubuntutrusty     --accelerate --cdrom /data8/kvm/images/ubuntu-14.04.4-server-amd64.iso     --boot menu=on     --disk path=/data8/kvm/data/kvm-20160725-01.img,size=500,cache=writeback,device=disk     --network network=default,model=virtio     --graphics vnc,port=-1,listen=0.0.0.0

kvm iptables转发

#!/bin/bash
pro='tcp'
NAT_Host='125.65.43.197'
NAT_Port=3000
Dst_Host='10.10.20.100'
Dst_Port=22
iptables -t nat -A PREROUTING  -m $pro -p $pro  --dport $NAT_Port -j DNAT --to-destination $Dst_Host:$Dst_Port
iptables -t nat -A POSTROUTING -m $pro -p $pro --dport $Dst_Port -d $Dst_Host -j SNAT --to-source $NAT_Host
#iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -I FORWARD -d 192.168.122.0/24 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

克隆:

virt-clone --original ubuntu-14-tmp --name kvm-20160715-01 --file /data1/kvm/data/kvm-20160715-01.img

在线添加网卡:

virsh attach-interface --domain kvm-20160725-01 --type bridge --source br0 --model virtio --config --live

进入virt-manager

在桌面版的命令窗出入:virt-manager

快速建虚拟机:

修改配置文件:

sudo vim /opt/cd-image/isolinux/isolinux.cfg
# D-I config version 2.0
include menu.cfg
default vesamenu.c32
prompt 0
timeout 1
ui gfxboot bootlogo
sudo vim /opt/cd-image/preseed/ubuntu-bbd-installer.seed 

截取修改的部分

# Static network configuration.
d-i netcfg/get_nameservers string 10.0.0.1
d-i netcfg/get_ipaddress string 10.0.0.171  (只修改此行,为虚拟机ip)
d-i netcfg/get_netmask string 255.255.255.0
d-i netcfg/get_gateway string 10.0.0.1
d-i netcfg/confirm_static boolean true

# from being shown, even if values come from dhcp.
d-i netcfg/get_hostname string bbdtao01 (虚拟机主机名)
d-i netcfg/get_domain string

镜像制作:

mkisofs -r -V "BBD Server Install CD" -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o ubuntu-bbd-installer-bbdhdp02-net162.iso /opt/cd-image/

创建虚拟机:

virt-install --name bbdhdp02 --hvm --ram 20480 --vcpus 2 --disk path=/data/kvm/bbdhdp02.qcow2,size=100 --bridge=br0 --accelerate --vnc --vncport=5982 --cdrom /home/bbd/ubuntu-bbd-installer-bbdhdp02-net162.iso -d

网址信息:

http://zhidao.baidu.com/link?url=inrg0yVfsi4JF_Okeq06FnMCZDGWUSwoJaK0LwxR7wne4-3hcaxiAFk0fod1DYNnFEbF2VIA9_4Fx1LhO9Z8fdjYMJyPlO8HgTsqQFe-JjS
http://www.linuxidc.com/Linux/2011-03/33653p3.htm
https://wiki.xargs.cn/wiki/doku.PHP/linux:kvm:kvm%E6%89%8B%E5%86%8C

Kubernetes DaemonSet的滚动升级

DaemonSet好比Kubernetes集群Node的守护进程,可以保证在每个Node上(或者一部分Node上)都运行同一个Pod。 目前我们的线上环境主要用到以下两个DaemonSet:

  • kube-flannel-ds 这个是部署Kubernetes集群时选用的是flannel network add-on
  • fluent-bit 这个是用来在部署在各个Node上,收集各个Node上容器的日志。我们选用的日志收集方案是EFK(Elasticsearch+Fluent-bit+Kibana),后边有时间再写点fluent-bit的内容

我们目前线上Kubernetes的版本总是落后最新的release版本,例如现在Kubernetes最新是1.7,我们使用1.6.x。但是我们注意到Kubernetes 1.7中很多外部组件、Addon都做了更新。我们在使用1.6.x的过程中会考虑提前升级这些组件,以便于后续顺利将Kubernetes升级到1.7。DaemonSet的升级就是需要考虑的。

滚动升级特性是Kubernetes服务发布的一个很有用的特性,而Kubernetes 1.6+支持DaemonSet的滚动升级,1.7开始支持DaemonSet滚动升级的回滚。下面一起来学习一个DaemonSet的滚动升级。

DaemonSet的升级策略

DaemonSet目前有两种升级策略,可以通过.spec.updateStrategy.type指定:

  • OnDelete: 该策略表示当更新了DaemonSet的模板后,只有手动删除旧的DaemonSet Pod才会创建新的DaemonSet Pod
  • RollingUpdate: 该策略表示当更新DaemonSet模板后会自动删除旧的DaemonSet Pod并创建新的DaemonSetPod

体验DaemonSet的滚动升级

要使用DaemonSet的滚动升级,需要 .spec.updateStrategy.type设置为RollingUpdate。 也可以进一步设置.spec.updateStrategy.rollingUpdate.maxUnavailable,默认值为1; 设置.spec.minReadySeconds默认为0,用于指定认为DaemoSet Pod启动可用所需的最小的秒数。

下面以我们测试环境中的flannel DaemonSet为例,体验从0.7.1升级到0.8.0的过程。

之前0.7.1的manifest文件没有设置更新策略为滚动升级,首先设置一下,同时注意修改flannel镜像版本为0.8.0:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  updateStrategy:
        type: RollingUpdate
  template:
  ......

然后执行:

kubectl apply -f kube-flannel.yml

可以使用下面的命令查看滚动升级状态:

kubectl rollout status ds/kube-flannel-ds -n kube-system
Waiting for rollout to finish: 1 out of 4 new pods have been updated...
Waiting for rollout to finish: 2 out of 4 new pods have been updated...
Waiting for rollout to finish: 3 out of 4 new pods have been updated...
daemonset "kube-flannel-ds" successfully rolled out

缩减docker镜像大小

镜像是 Docker 运维的基本单元。 优化镜像体积,能够:

  • 缩短部署时的下载时间;

  • 提升安全性,因为可供攻击的目标更少;

  • 减少故障恢复时间;

  • 节省存储开销。

正确认识分层和共享

认清与理解 Docker 镜像的层次结构,是进行镜像优化的前提和基础。

分层

docker 镜像的存储结构是分层次的。 无论底层的文件系统(可选可配置)是基于快照还是分块。

镜像构建的过程里,每步操作都产生一个只读的层:可重用,可复制,但是不可修改。 层次叠加,形成了包含历史(history)结构的镜像。 镜像启动后,产生了容器(container)。容器也是一个单独的层,可读写,但是不持久化,易丢失。

共享

共享,以分层为基础。 以一个镜像为祖先,分别用多种方式做不同操作,各自生成新层,则形成多个新的镜像,祖先镜像则成为共享的部分。 继承自共同的祖先,实现了对共同内容的利用。

未分类

镜像优化

对单个镜像体积做优化,采取方式有两类思路:

  • 选择尽可能小的基础镜像

  • 打包尽可能少的内容入镜像

    • 如:去除或减少编译、测试等中间步骤内容

    • 使用单行命令

工程实践中,还要考虑多镜像复用,尽量:

  • 将能复用的部分放进模版镜像。

选择最小化基础镜像,创建模版镜像

基础镜像需要满足的基本条件:

  • 正确的 init 系统。(discuss)

  • 日志。Docker 的应用程序日志一般默认在标准输出,而系统进程仍然会往 /dev/log 写数据。需要有日志处理程序 syslog

  • 后台任务如 cron

  • 工具进程如 sshd(慎重选择)

这些需求,与在传统的服务器和虚拟机上做部署,是相似的。

如果仅仅基于这种相似性,就选择了使用 CentOS/Debian/Ubuntu 做为基础镜像,那么就有问题了。 首先,这些传统发行版的 Docker 镜像并不能符合基础需求; 其次,这些发行版的体积太大。

所有,仍然需要选择较小的发行版制作初始镜像。

市面上可选的有:

  • phusion/baseimage

  • baseimage-amzn

  • Alpine

  • busybox

使用共同的模版镜像

如果有多个业务需要运维,则在公共基础镜像基础上,构建私有的模版镜像。 共同的模版镜像,能够:

  • 实现镜像共享

  • 减少重复工作。解决边缘问题

  • 减少开发时间。专注于上层应用

  • 减少编译时间。

  • 减少部署时间。基于镜像的层共享

模版镜像的目标是抽取业务的公共部分。

持续的审查和优化

上线后,需要经常关注这些问题:

  • 某个组件放在模版镜像中,现在已经很少用到了?或者反之。

  • 新业务使用到某个公共镜像,效果还不错,要不要推而广之?

解决这些问题,还需要经常复审镜像服用的效率。 简单的方案,可以对各类环境中的模版使用情况进行统计,尽量合并相似的镜像,将使用率较高的组件吸收进模版镜像。

常用考评指标:

  • 开发效率

  • 编译效率

  • 传输效率

  • 存储效率

要不要使用 –flatten

–flatten 是现在还是一个测试特性,可以减少镜像总体积,然而与复用的原则有冲突。 需要更加实际情况去做考虑。

  • 要不要使用 –flatten

为什么选择最小的基础镜像(如alpine)之后,应用镜像反而变大了?

这是因为应用程序需要一系列依赖。 如果使用最小的基础镜像,在制作应用镜像时,比如需要去安装依赖。 安装步骤可能会引入更多不必要的元素。 所以反而体积会超过已包含所需依赖的公共镜像。

centos -> app

alpine -> dependencies -> app  # Too much dependencies

ubuntu16.04使用nginx、uwsgi部署django应用

安装相关软件

更新源

sudo apt-get update 
sudo apt-get upgrade

安装虚拟环境

sudo apt-get install Python-virtualenv

安装nginx

sudo apt-get install nginx

安装uwsgi

sudo pip3 install uwsgi

或者

sudo pip3 install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz

安装uwsgi出错就安装

sudo apt-get install python-dev 
sudo apt-get install python3.5-dev

本文用到的软件环境

  • ubuntu 16.04
  • Python 3.5.2
  • Django 1.11.4
  • nginx 1.10.3
  • uwsgi 2.0.15

创建一个普通用户

创建用户组webapps

sudo groupadd –system webapps

创建用户user_test并设置密码

sudo useradd –system –gid webapps –shell /bin/bash –home /webapps/test user_test

passwd user_test

创建用户目录并修改目录权限

mkdir -p /webapps/test

chown user_test /webapps/test/

添加用户user_test sudo权限

在/etc/sudoers添加

user_test ALL=(ALL:ALL) ALL

创建测试应用

切换用户为user_test

su - user_test

cd /webapps/test

创建python虚拟环境,这里指定为3.5版本,并激活

virtualenv -p /usr/bin/python3.5 .

source bin/activate

安装django

pip install django

创建django工程mysite

django-admin startproject mysite

创建应用app

cd mysite

django-admin startapp app

修改mysite/settings.py

将外网ip添加到ALLOWED_HOSTS

ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx', '127.0.0.1']

在INSTALLED_APPS里追加 ‘app’

新建app/static目录

在mysite/settings.py里添加

STATIC_ROOT = os.path.join(BASE_DIR, 'app', 'static')

收集静态文件到app/static目录

python manage.py collectstatic

迁移数据库

python manage.py migrate

创建后台管理用户

python manage.py createsuper

添加视图函数

在app/views.py添加

from django.http import HttpResponse
def index(request):
    return HttpResponse('<h1>Hello World!</h1>')

在mysite/urls.py添加

from app import views
urlpatterns = [
    ...
    url(r'^$', views.index),
]

测试django应用运行是否正常

python manage.py runserver

使用curl命令访问

curl 127.0.0.1:8000

正常会输出 <h1>Hello World!</h1>

Ctrl C 退出

当前所涉及的一些目录

  • 用户目录:/webapps/test
  • 虚拟环境目录: /webapps/test
  • 工程目录:/webapps/test/mysite

配置ngnix

从https://github.com/nginx/nginx/blob/master/conf/uwsgi_params下载到/etc/nginx/conf/目录

新建mysite/test_ngnix.conf文件,内容如下

# the upstream component nginx needs to connect to
upstream testapp {
    server unix:///webapps/test/mysite/mysite.sock; # for a file socket
    #server 127.0.0.1:9090; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      80;
    # the domain name it will serve for
    server_name localhost; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste
    access_log      /webapps/test/mysite/nginx_access.log;
    error_log       /webapps/test/mysite/nginx_error.log;

    # Django media
    location /media  {
        alias /webapps/test/mysite/app/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /webapps/test/mysite/app/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  testapp;
        include     /etc/nginx/conf/uwsgi_params; # the uwsgi_params file you installed
    }
}

将test_ngnix.conf链接到/etc/nginx/sites-enabled/目录

sudo ln -s /webapps/test/mysite/test_ngnix.conf /etc/nginx/sites-enabled/

记得删除自带的default文件,否则输入外网ip看到的是ngnix欢迎页

sudo rm /etc/nginx/sites-enabled/default

这里用到的是unix file socket

所以把用户www-data加到webapps用户组,否则读取socket文件时会有权限问题

sudo usermod -a -G webapps www-data

重启ngnix

sudo /etc/init.d/nginx stop 
sudo /etc/init.d/nginx start

配置uwsgi

新建wsgi.ini, 内容如下

[uwsgi]
#socket = 127.0.0.1:9090
chdir=/webapps/test/mysite
module=mysite.wsgi
master = true
processes=2
threads=2
max-requests=2000
chmod-socket=664
vacuum=true
daemonize = /webapps/test/mysite/uwsgi.log
virtualenv = /webapps/test
gid=webapps
uid=user_test
socket = /webapps/test/mysite/mysite.sock

运行uwsgi

uwsgi –ini wsgi.ini

用浏览器访问外网ip,正常会显示Hello World

使用uwsgi Emperor mode

# create a directory for the vassals
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# symlink from the default config directory to your config file
sudo ln -s /webapps/test/mysite/wsgi.ini /etc/uwsgi/vassals/
# run the emperor
sudo uwsgi --emperor /etc/uwsgi/vassals --uid user_test --gid webapps

Redis报错-ERR max number of clients reached

Redis报错redis报错 ERR max number of clients reached错误
我看啦一下连接数有500多个,可能是因为客户端接入太多
设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

解决方案

更改redis.conf配置文件

maxclients 1000

未分类

Linux系统下通过bash shell脚本实现倒计时的方法

本文主要讲述如何在linux系统下通过bash shell 脚本来实现在屏幕上输出倒计时的方法。

先来看看实现后的脚本,如下:

#!/bin/bash
 # script name: ctimer.sh
 # Author: osetc.com
 # --------------------------------------------------------

row=2
 col=2
 countdown() {
 msg="starting..."
 clear
 tput cup $row $col
 echo -n "$msg"
 l=${#msg}
 l=$(( l+$col ))
 for i in {30..1}
 do
     tput cup $row $l
     echo -n "$i"
     sleep 1
 done
 }
 countdown

首先我们定义了一个名为countdown的shell 函数,在函数里定义了一个msg变量用于在屏幕上显示倒计时信息,clear 命令用于清除屏幕上的历史输出信息,tput cut 命令用于设置屏幕输出信息的位置,最后通过for循环来实现倒计时,并更新输出信息的位置。

执行上面的脚本

$bash ctimer.sh
 Starting...30

如何恢复丢弃的 git stash 数据

不要让 git 命令中的错误抹去你数天的工作

今天我的同事几乎失去了他在四天工作中所做的一切。由于不正确的 git 命令,他把保存在 stash[1] 中的更改删除了。在这悲伤的情节之后,我们试图寻找一种恢复他所做工作的方法,而且我们做到了!

首先警告一下:当你在实现一个大功能时,请将它分成小块并定期提交。长时间工作而不做提交并不是一个好主意。

现在我们已经搞定了那个错误,下面就演示一下怎样从 stash 中恢复误删的更改。

我用作示例的仓库中,只有一个源文件 “main.c”,如下所示:

未分类
Repository with one source file

它只有一次提交,即 “Initial commit”:

未分类
One commit

该文件的第一个版本是:

未分类
First version of the file

我将在文件中写一些代码。对于这个例子,我并不需要做什么大的改动,只需要有什么东西放进 stash 中即可,所以我们仅仅增加一行。“git diff” 的输出如下:

未分类
git-diff output

现在,假设我想从远程仓库中拉取一些新的更改,当时还不打算提交我自己的更改。于是,我决定先 stash 它,等拉取远程仓库中的更改后,再把我的更改恢复应用到主分支上。我执行下面的命令将我的更改移动到 stash 中:

git stash

使用命令 git stash list 查看 stash,在这里能看到我的更改:

未分类
Output of changes in our stash

我的代码已经在一个安全的地方,而且主分支目前是干净的(使用命令 git status 检查)。现在我只需要拉取远程仓库的更改,然后把我的更改恢复应用到主分支上,而且我也应该是这么做的。

但是我错误地执行了命令:

git stash drop

它删除了 stash,而不是执行了下面的命令:

git stash pop

这条命令会在从栈中删除 stash 之前应用它。如果我再次执行命令 git stash list,就能看到在没有从栈中将更改恢复到主分支的之前,我就删除了它。OMG!接下来怎么办?

好消息是:git 并没有删除包含了我的更改的对象,它只是移除了对它的引用。为了证明这一点,我使用命令 git fsck,它会验证数据库中对象的连接和有效性。这是我对该仓库执行了 git fsck 之后的输出:

未分类
Output after executing the git-fsck command on the repository

由于使用了参数 –unreachable,我让 git-fsck 显示出所有不可访问的对象。正如你看到的,它显示并没有不可访问的对象。而当我从 stash 中删除了我的更改之后,再次执行相同的指令,得到了一个不一样的输出:

未分类
Output after dropping changes on stash

现在有三个不可访问对象。那么哪一个才是我的更改呢?实际上,我不知道。我需要通过执行命令 git show 来搜索每一个对象。

未分类
Output after executing the git-show command

就是它!ID 号 95ccbd927ad4cd413ee2a28014c81454f4ede82c 对应了我的更改。现在我已经找到了丢失的更改,我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支,或者直接提交它。如果你得到了你的更改对象的 ID 号,就可以决定以最好的方式,将更改再次恢复应用到主分支上。对于这个例子,我使用 git stash 将更改恢复到我的主分支上。

git stash apply 95ccbd927ad4cd413ee2a28014c81454f4ede82c

另外需要重点记住的是 git 会周期性地执行它的垃圾回收程序(gc),它执行之后,使用 git fsck 就不能再看到不可访问对象了。

搭建自己的git服务器

自己搭建git服务器主要有两个目的:

  • 可用来做一个团队的私有仓库,自己的服务器安全可控
  • 让代码自动同步到服务器,而不是每次用ftp,比较方便

系统 centos6 国外vps

步骤:

1. 安装git

一般服务器都自带git。如果嫌版本低,可以选择卸载重装。

2. 创建用户

groupadd git
adduser git -g git

3.创建authorized_keys文件

cd /home/git
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
cd /home
chown -R git:git git

4. 客户端创建密钥并上传

ssh-keygen -t rsa -C "your_email"

该命令会产生两个文件: id_rsa对应私钥,id_rsa.pub对应公钥。

将id_rsa.pub中的内容写到服务器的authorized_keys文件中。

如果有多个客户端,那么在authorized_keys文件中,一行保存一个客户端的公钥。

5. 创建git仓库

为了方便管理,所有的git仓库都置于同一目录下,假设为/data/gitrepo ,

cd /data
mkdir gitrepo
chown git:git gitrepo

接下来,创建我们的第一个git仓库:sample.git ,
服务器上的Git仓库通常都以.git结尾

cd gitrepo
git init --bare sample.git
// 修改所属用户
chown -R git:git sample.git

6. 克隆仓库到本地

$ git clone git@your-ip:/data/gitrepo/sample.git

7.禁用shell登录

安全性考虑git用户只提供git服务,不让登录到系统。

编辑/etc/passwd文件 找到类似下面的一行:

git:x:503:503::/home/git:/bin/bash

改为

git:x:503:503::/home/git:/sbin/nologin

8. 设置自动更新钩子

设置当有客户端push过来自动更新到指定目录(站点目录)

cd /data/girepo/sample.git/hooks
cp post-receive.sample post-receive
vi post-receive
//添加以下这句到文件
git --work-tree=/data/wwwroot/your-site-dir checkout -f
//保存
:wq

(完)

将代码从Git自动部署到容器

【编者的话】将您的代码从您的Git仓库转移到您的容器可能是一件痛苦的工作。本文介绍了如何实现自动化部署。

有许多方法可以将您的源代码从Git 仓库部署到容器中,包括整个容器的重新部署、通过卷的即时重新部署或“git clone”方法。然而,当涉及到这一过程的自动化和持续部署时,许多开发人员可能会面临其中的复杂性,因为他们需要知道如何正确地将所有应用程序组件与所需的互连点结合起来。

尤其是在容器里,必须管理所构建的堆栈映像来处理CI/CD管道引起的额外复杂性。如果在操作系统、应用服务器堆栈或其依赖项中进行频繁的提交,那么整个容器重新部署可能不是最好的方法。

未分类

为了简化部署自动化,Jelastic准备了一种特殊专用的Git-Push-Deploy包,用于将代码交付到初步构建的容器映像中。这个包实现了许多配置,以便在您的Git应用程序源存储库中自动部署提交的更改,使其能够在最小延迟的情况下进行进一步的测试。

Git-Push-Deploy 细节

Git-Push-Deploy包可以与GitHub和GitLab存储库集成。它是为在Java、PHP、Ruby和Node.js和Python应用源代码中自动提供更新而开发的。可以应用于以下认证的模板:

  • Java – Tomcat 6/7/8/9, TomEE, GlassFish 3/4, Jetty 6/8/9, WildFly 8/9/10, JBoss AS 7, Spring Boot 1.x
  • PHP – Apache 2.4, NGINX 1.10
  • Ruby – Apache 2.4, NGINX 1.10
  • Node.js – Node.js 0.x-6.x
  • Python – Apache 2.4

工作流依赖于项目中使用的编程语言:

  • 对于基于Java的项目,该包将创建一个单独的环境,其中包含Maven构建节点,它将负责与远程Git存储库的交互,从而触发您的应用程序构建及其部署到应用程序服务器。
  • 对于PHP / Ruby /Node.js/python应用中,该包为项目的部署直接在Web服务器的ROOT context上设置了一个管道(这里,认为 Ruby应用程序服务器提供的是一种部署模式,而不是dashboard的context,尽管实际项目位置是相同的)。

这个部署自动化包与4.9.5版本的Jelastic PaaS以及更高版本兼容。要查看和比较可用的管理平台和特定的Jelastic版本,请参考Jelastic Cloud Union目录。

库预配置

对于特定的附加安装,您需要为您的Git帐户提供一个个人的API Token。这可以使包为对应的存储源设置一个webhook,在每次更改代码并使其生效时,来初始化重新部署应用。

我们来生成一个。根据你所使用的Git VCS,GitHub或者GitLab对应以下指示进行操作。

在GitHub上生成Access Token

要为您的GitHub帐户获取您的personal access token,请访问Settings > Personal access tokens然后点 Generate new token按钮。

未分类

在打开的页面中,选定Token description,并选择repo和admin:repohook,在页面底部单击Generate token。

未分类

将生成的access token复制保存起来(因为离开这个页面之后,就不能再被查看)。

未分类

完成这一步之后,开始继续安装Git-Push-Deploy包。

在GitLab上生成Access Token

要在GitLab生成一个personal access token,进入您的帐户settings并切换到Access Tokens。

在这里,指定可选的token名称,它的到期日期(可以留空),并勾选api权限范围。

未分类

点击 Create Personal Access Token按钮。

在打开的页面中,复制并临时将您的访问令牌值存储在其他地方(因为离开本页后您将无法再次看到它)。

未分类

现在,您已经准备好继续安装Git-Push-Deploy包了。

Java项目的额外预配置

如果运行一个基于Java的项目,您需要通过在其结构中添加一个特殊的项目对象模型(POM)文件来开始与Maven构建节点进行适当的交互。
所以,创建一个pom.xml文件在项目源的根目录中,然后必须添加下面的内容:

<project>    
<modelVersion>4.0.0</modelVersion>    
<groupId>com.mycompany.app</groupId>    
<artifactId>my-app</artifactId>    
<version>1.0</version>    
<packaging>war</packaging>    
<build>        
<finalName>${project.artifactId}</finalName>   
</build> 
</project>

可选值:

  • groupId -项目组(例如公司名称)。
  • artifactId-项目的名称。
  • version -应用版本。

其余的参数都应该保持不变。您可以在我们的示例中查看如何配置。

安装Git-Push-Deploy包

Git-Push-Deploy包是一个附加组件,因此它只能安装在一个环境的顶部。我们已经准备了两个独立的环境,分别使用Tomcat和apache-php应用程序服务器来展示不同编程语言的工作流。

如果你打算使用以前创建的环境,请注意这个包将覆盖部署到根目录的应用程序。因此,为了保持已经部署的应用程序,将其移动到用户目录。我们建议创建一个新的环境,然后进行接下来的安装:

1、单击dashboard顶部窗格中的Import按钮,在打开的URL选项卡中插入一个manifest.jps链接:

https://github.com/jelastic-jps/git-push-deploy/blob/master/manifest.jps

未分类

单击Import 继续。

2、在打开的框架中,指定关于源和目标环境的详细信息:

  • Git Repo URL – HTTPS连接到你的应用程序的“repo“(或者 .git或普通视图)。您可以fork我们的示例Hello World应用程序来测试流。
  • Branch – 项目分支。
  • User – 输入您的Git登录帐户。
  • Token –指定您之前为webhook生成创建的 access token。
  • Environment name – 选择要部署应用程序的环境。
  • Nodes – 应用程序服务器名(在选择环境时自动获取)。

未分类

单击“Install ”继续。

3、等一分钟让Jelastic从GitHub获取应用程序资源,配置webhook以进行接下来的部署。

未分类

安装完成后点击“Close“关闭通知框。

4、根据项目类型的不同,会有如下结果:

  • 对于基于Java的基础设施,您将在dashboard中看到一个新的环境,其中包含Maven构建节点;它将在每次更新源代码时,在Web服务器上构建和部署应用程序到Root context下。

未分类

请注意,Maven可能需要花费一些时间来编译一个项目(尽管包安装本身已经完成了),因此您需要等待几分钟才能启动它。这个操作的当前进展可以通过Maven的vcs_update 日志文件实时跟踪。

未分类

  • 对于基于PHP的基础设施(以及其他受支持的语言),您的应用程序将直接部署到所选的服务器Root context上。

请注意,Ruby应用程序服务器的类似项目部分提供了关于使用的部署模式(默认情况下开发)的信息,而不是context,同时实际的应用程序位置也引用了服务器root。

要启动应用程序,请单击web服务器旁边的Open in browser。

未分类

就是这样!现在,您的应用程序的新版本在每次提交到源端时都会自动地发送到应用程序服务器。

不同服务栈的重新部署策略

下面的表列出了在接收到更新后的代码后不同应用服务器的反应。

未分类

为了消除可能的应用程序停机时间,可以使用重新启动更新策略,将其扩展到多个容器中。在这种情况下,所需的更新将按顺序应用到实例中,默认情况下延迟30秒。

通过Git上来测试自动部署

现在让我们来看看这个过程是如何工作的。对源端的代码做一些细微的调整,确保一切都是自动化的:

1、单击您的项目源中的某个项目的Edit this file,并Commit changes——例如,我们将修改HelloWorld启动页面上的文本。

未分类

2、因此,将触发适当的webhook来将所做的更改部署到您的主机环境中——请参考存储库Settings > Webhooks部分以了解详细信息。

未分类

单击此字符串后,您将看到由webhook发起的最近交付的列表,以及它们执行的结果。

3、最后一个检查,返回到您的应用程序页面并刷新(同时记住,Maven可能需要额外的一分钟来构建和部署您的基于Java的项目)。

未分类

就是这样!正如您所看到的,这些修改成功地应用了,因此这个方案按照我们预期的方式工作。

只需更新代码,按照通常的方法进行提交,所有的更改都会自动地推送到您的Jelastic环境中。不需要在进程之间切换,也不需要手动更新,从而消除人为错误,并加速应用程序的上线时间。

原文链接: https://dzone.com/articles/deploy-code-to-containers-from-git-automatically-1 (翻译:edge_dawn)