ubuntu下gitlab升级 备份 迁移

当前系统环境

  • 操作系统: ubuntu16.0.4
  • 用户名:crisen
  • ip:10.0.1.100
  • 当前gitlab版本: 10.8.5汉化版
  • 升级目标版本:11.0.3

迁移目标环境

  • 操作系统:ubuntu16.0.4
  • 用户名:crisen
  • ip: 10.0.1.101
  • gitlab版本:11.0.3

gitlab升级

使用apt软件包对gitlab进行升级,如果是汉化过的版本,那么升级之后汉化会消失,需要重新汉化

sudo apt update
sudo apt upgrade gitlab-ce

升级的时候因为要下载很多的东西,可能会比较缓慢

gitlab备份

使用gitlab-rake进行备份

sudo gitlab-rake gitlab:backup:create
# 执行此命令之后,会在/var/opt/gitlab/backups目录下生成如下格式的备份文件
#时间戳_日期_gitlab版本_gitlab_backup.tar

backups目录所属用户为git,权限是700,使用普通用户无法进入该目录,使用sudo chmod a+x /var/opt/gitlab/backups命令可以改变用户权限

gitlab迁移

迁移的过程中,首先要注意,目标版本和当前版本必须一致,否则无法迁移,如果想要安装指定版本的gitlab,可以点击此处

迁移准备工作

关闭gitlab服务

sudo gitlab-ctl stop

当前版本为11.0.3,后续的版本中是支持热备份的 不需要管理gitlab-ctl服务

建立gitlab备份并把备份文件拷贝至目标服务器

当前gitlab服务器

生成备份

sudo gitlab-rake gitlab:backup:create #备份 生成了1531204254_2018_07_10_11.0.3_gitlab_backup.tar

改变权限

sudo chmod a+rx /var/opt/gitlab/backups # 修改目录权限

上传备份文件

sudo scp /var/opt/gitlab/backups/1531204254_2018_07_10_11.0.3_gitlab_backup.tar crisen@10.0.1.101:~/ # 上传文件至迁移服务器

目标服务器

修改备份目录权限

sudo chmod a+rx /var/opt/gitlab/backups  #修改backups目录权限

移动文件

sudo mv ~/1531204254_2018_07_10_11.0.3_gitlab_backup.tar  /var/opt/gitlab/backups/  #移动文件至gitlab备份文件目录

修改备份文件所有者

sudo chown git:git 1531204254_2018_07_10_11.0.3_gitlab_backup.tar 

恢复

sudo gitlab-rake  gitlab:backup:restore restore BACKUP=1531204254 

11.7.6版本迁移要加上日期和版本
sudo gitlab-rake gitlab:backup:restore restore BACKUP=1531204254_2018_07_10_11.0.3

迁移过程中如果出现 psql:The database was initialized with LC_COLLATE "zh_Cn.UTF-8", which is not recognized by setlocale(). 使用下面的命令解决

localedef -f UTF-8 -i zh_CN zh_DN.UTF-8

重启gitlab服务

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

至此迁移完成,在restart之后马上访问gitlab可能会出现502错误,属于正常现象,等待1分钟左右访问即可

gitlab安装与汉化

安装

安装环境

  • 操作系统: ubuntu16.0.4(虚拟机)
  • 内存: 4GB
  • 硬盘:80GB
  • 目标gitlab版本: 最新版本,当前为11.0.3

特别说明: 请务必务必保证自己的计算机的内存在4G以

安装必须的依赖

sudo apt update
sudo apt-get install -y curl openssh-server ca-certificates
sudo apt-get install -y postfix

下载安装脚本

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash

安装

sudo EXTERNAL_URL="http://localhost" apt-get install gitlab-ce

启动

sudo gtilab-ctl reconfigure

最后浏览器中输入localhost,成功进入gitlab页面

汉化

查看当前gitlab版本

cat /opt/gitlab/embedded/service/gitlab-rails/VERSION 

我的版本是11.0.3,汉化的时候要注意,下载的安装包和自己的gitlab版本要一致

获取汉化资源

gitlab8.8之前汉化包地址
gitlab8.8之后汉化包地址

选择对应的下载包直接下载,这里我的版本是11.0.3,所以下载11-0-stablezh版本的下载包

请千万要注意当前的gitlab版本 并且确定汉化版和原版的大版本好一致

# 我的版本是11.0.3 所以下载的时候选择11-0-stable 小伙伴们一定要注意下载对应的版本 否则汉化会失败
wget https://gitlab.com/xhang/gitlab/-/archive/11-0-stable-zh/gitlab-11-0-stable-zh.tar
tar -xvf  gitlab-11-0-stable-zh.tar

备份以防万一

sudo  cp -r  /opt/gitlab/embedded/service/gitlab-rails  /opt/gitlab/embedded/service/gitlab-rails.back

汉化

sudo cp -rf gitlab-11-0-stable-zh/* /opt/gitlab/embedded/service/gitlab-rails/

其中有两个文件tmp 和 log 无法覆盖 对汉化无影响

重新配置gitlab并重启

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

执行了sudo gitlab-ctl restart之后 可能会出现短暂的502错误,这是因为gitlab的重启需要一定的时间,等待一分钟左右重新访问gitlab网址即可

如果长时间出现502错误,那么可以试试先关闭gitlab服务 然后reconfigure 最后start

sudo gitlab-ctl stop
sudo gitlab-ctl reconfigure
sudo gitlab-ctl start

最后访问localhost,出现中文界面的gitlab,至此安装与汉化工作结束.

ubuntu appstream错误

因为要做个数据库迁移测试,所以给安装了一个ubutnu16.0.4的本地环境镜像虚拟机,安装结束后执行基本操作

sudo apt update

结果系统告诉我无法获得锁/var/lib/apt/lists/lock,紧接着就是报告了内部错误
错误显示为appstream报错,网上查了一下,appstream是几个主要GNU/Linux提供者之间的协议,目的是为了创造一个Linux上的 共同的软件安装程序以及一个同意的软件安装图形用户界面,还有分享元数据用的.
这里报错错误的原因是,ubuntu16.0.4内置的libappstream是2.0以前的版本,我们必须更新到3.0以上的版本才可以
解决办法很简单,只要安装libappstream3就可以了,在ubuntu下安装非常简单,直接通过apt安装就可以了

通过apt安装appstream

通过apt安装appstream非常简单,执行执行命令就可以了

sudo apt-get purge libappstream3
sudo apt update

最后一切搞定

记一次nginx重定向操作

引言

今天有一个朋友,需要配置一个301重定向,需求是要把xxx.com下所有的请求全部重定向到www.xxx.com 下来.同时xxx.com后面所有的参数全部都要去掉,感觉是非常奇怪的请求,朋友操作很久之后未果,于是就让我帮忙看看,这里是一个非常简单的操作,但是仍然踩了一些坑,于是准备记录一下,避免自己在未来或者其他的人踩坑

配置

首先配置非常简单,这里是nginx服务器,所以只要配置一个rewrite就可以了,配置代码如下(仅显示相关配置代码)


server_name xxx.com www.xxx.com; ........ if ( $host != 'www.xxx.com' ){ rewrite ^.*$ http://www.xxx.com/ permanent; break; }

这里的配置需要注意的是,我在重定向的域名后面加上了/符号,如果不加这个符号,那么像xxx.com/somesting 这样的请求会重定向到http://www.xxx.com/somestring ,也就是说这里会自动的把后面的目录和参数加到重定向域名的后面,就相当于这样的配置

if ( $host != 'www.xxx.com' ){
    rewrite  ^/(.*)$  http://www.xxx.com/$1   permanent;
    break;
}

这里应该是是nginx的一个特性,加上/符号之后就不会有了

遇到的问题

一开始我告诉朋友这个配置的时候,并没有效果,于是我觉得很奇怪,因为在我的印象中,这个配置不可能有问题的,ping一下域名,发现对方有一个隐性url解析,解析是@主机记录,解析的位置是www.xxx.com , 于是这里就非常有意思了,ping www.xxx.com 这个域名的时候,是正确的服务器ip地址,但是ping xxx.com的时候,这个地址就是一个其他无关的地址,所以导致解析没有办法生效.
这里我想说的是,在配置web服务器的时候,域名解析和web服务器配置是相关联的,在一次http请求过程中,首先是查询dns找到域名的主机位置,然后才会把请求转发给服务器,交给服务器接管,这里和操作系统的启动有点类似,bios加载了引导之后才会把控制权交给操作系统.

尾语

这一次经历虽然短暂,但是让我对一个信念认识的更加深刻了 ,条条大路通罗马 , 实现一个重定向配置,不仅仅是可以通过web服务器来解决的,这里就至少有三个解决方案了,首先是通过域名解析的时候,对域名进行隐性的解析能够生效,其次就是配置web服务器了,再者其实可以使用php代码来对请求做处理,多种多样的手法,于是我们怎么配置怎么来了.
不过要说功能更全面的话,还是要了解web服务器最好,比如这里的特殊需求,要xxx.com/somestring 在重定向之后删除后面所有的多余字符串,虽然我不明白这么做的用意是什么,但是这个需求web服务器搞定是没有问题的.
最后坚定一下信仰,nginx作为一个轻量级的服务器其实真的不仅仅是清量那么简单,真的是功能非常齐全的.

使用ssh config配置克隆非22端口的repos

前言

前段时间在本地局域网环境搭建了个gitlab,于是就用反向隧道把局域网的gitlab服务通过云服务器映射到外网了,但是通过ssh协议克隆仓库的时候出现了一点问题,踩了一些坑,于是记录下来,避免有更多的人踩这个坑

环境

  • 域名 gitlab.crisen.org
  • 端口 2222
  • 仓库名称 test
  • 仓库地址 git@git.crisen.org:crisenchou/test.git

遇到的问题

因为我的gitlab服务器是通过反向隧道建立的,所以走的不是22端口,那么直接通过git clone的方式是没有办法进行克隆的,通过查询一些资料,知道了有两种方法来实现这个仓库的克隆

通过ssh config

在~/.ssh目录下,编辑一个config文件

vim ~/.ssh/config

添加下面的内容

Host gitlab
    Hostname git.crisen.org
    Port 2222
    User git

Host 表示别名 Hostname表示服务器地址,可以是ip的形式 Port为端口 User指定用户

接下来只要在本地以下面的形式来克隆仓库就可以了

配置config之后 不能直接克隆仓库地址来克隆 而是下面的命令

git clone git:crisenchou/test.git

这里的gitlab别名 等价于git@git.crisen.org -p2222 所以是上面的命令 而不是直接用地址来克隆
这一步非常关键

通过ssh协议

使用这种方法会更加简单一些,不过要输入的字符多一点,多个仓库的情况下,还是配置来的更好一点,它的命令如下

git clone ssh://git@git.crisen.org:2222/crisenchou/test.git

尾语

我是因为云服务器的内存不够,而且考虑到内网环境下,使用内网的git服务器更加迅速,所以在局域网搭建了gitlab服务器,再加上我在外网的环境下有时候也需要用到这个git服务,索性就自己捣腾了一下,虽然踩坑是无法避免的,但是在踩坑的过程中不断的成长,我觉得才更有意义.

命令行(command not found)

初学者在接触命令行的时候,肯定会经常碰到command not found这样的提示,有些时候可能会因此困惑,我明明是有这个文件的,但是为什么找不到命令呢

windows or *nix

windows下的命令行用起来的感觉差强人意,如果使用命令行还是使用*nix(linux,unix)比较好,这里默认使用linux的bash来进行解释

shell运行命令的方式

bash中,有四种命令可以在终端执行,分别是函数和别名,内建命令,外部命令,以及可执行文件

在windows下的可执行文件是以.exe .bat .sh后缀名结尾的文件,但是在linux下任何文件只要有x可执行权限都可以执行 (x可执行权限表现为使用ls -al命令中出现为最前面的十个字符,分别表示文件类型 拥有者权限 用户组全选 其他用户权限)

函数和别名

在终端下可以通过在shell的配置文件中编写函数来作为命令使用,比如在homestead虚拟机中有一个函数artisan,使用type artisan可以看到artisan的代码

默认的shell文件是/etc/profile 和.profile,而bash的默认配置文件则是/etc/bash.bashrc和.brshrc,其中etc目录下的是全局配置文件, .号开头的是用户专属配置文件

artisan()
{
php artisan "$@"
}

当使用artisan命令的时候,shell会调用php去执行当前目录下的artisan文件,并把所有的参数一起传递过去,通过这个函数,就可以让我们不用每次都输入php artisan "arguments"来工作了

还有一种是别名,比如ll命令,通过内建命令alias命令可以创建别名,比如使用type ll的时候,就可以很清晰的看到
ll is aliased to `ls -alF'

内建命令

内建命令其实就是shell本身中已经编写好的指令,这些指令通常是不能用which查看到的,比如cd history命令等,在命令行使用type 命令可以看到一个命令是什么类型的命令,比如使用

type  history

就能看到输出 history 是shell 内建

history 显示当前用户使用过的所有的命令记录

外部命令

那么接下来外部命令是什么?
在解释外部命令之前,先引入一个词汇环境变量,你应该或多或少的听过它的另一个命令PATH,在终端下输入下列命令就可以看到当前所有的环境变量了, 其实它就是很多路径组成的集合

echo $PATH

如果是windows下 则是echo %PATH%

因为当从终端输入字符之后,shell会执行下面三个步骤
- 判断命令是不是函数或者别名(函数和别名拥有执行的最高优先级)
- 判断命令是不是内建命令
- 在环境变量的所有路径下寻找与命令匹配的文件

如果这些过程都没有找到可执行文件,那么就会返回command not found 或者未找到 xx 命令这样的错误信息了

如果在执行命令的时候,直接指定了完整路径的话,那么shell将不会执行这三个步骤,从而定位到该文件来执行该命令

可执行文件

在linux中,默认的所有的可执行程序都必须有路径才可以执行,其实外部命令也是一个可执行文件,这里为了区分外部命令,定义为带有路径执行的可执行文件,如./a.out 就是一个非常常见的一个可执行文件

a.out 是gcc不加任何参数编译输出的默认的文件

这里我想要表达的是,linux下任何一个文件,给出完整路径后,可以在任何目录下执行,而不依赖于环境变量
比如ls 命令,直接使用ls -al可以列出当前目录下的所有文件,而它所在的路径一般是/bin/ls
所以在终端下输入

/bin/ls -al

ls -al是完全一样的

尾语

当你一个命令不是函数,别名,内建命令,也不是外部命令,也没有给出完整路径 仍然都找不到命令的话,那么就只有两种原因
- 你的计算机里没有安装这个程序
- 你的命令输入错了
最后让command not found都见鬼去吧

记一次数据恢复

引言

今天一位小兄弟准备实现一遍从删库到跑路的创举,于是把数据库里面的所有数据都给清空了,这一番操作可就苦恼我了,数据丢失那可是非常严重的问题,必须要对数据库进行恢复

恢复数据的过程

看到数据库为空的那一瞬间,我的大脑其实是不清醒的,然后那个瞬间我突然想起,我曾经写过一个定时脚本,它会在每天凌晨的三点钟对数据库进行全量备份。
在/var/mysql-backup目录下找到了20180426.sql的备份。于是先恢复一部分数据先,使用mysql的终端执行了下面的命令

mysql -uroot -p
use xxxdatabase;
source /var/mysql-back/20180426.sql

这样就把数据恢复到了晚上凌晨三点的状态,但是仅仅这样还是不够的,发现失去数据的时间为下午3点钟,这就是说从凌晨3点到下午3点整整12个小时的数据全部丢失,这样的损失仍然是无法接受的
于是检查一下/etc/my.cnf,发现我的习惯还是不错的,二进制日志默认开启,那么事情就简单了,只要把这个时间节点的二进制日志导出,继而恢复即可

基于二进制日志对数据库进行恢复

首先找到二进制日志所在的目录/var/mysql/,找到最近的二进制文件名称为mysql-bin.000011,
接下来在命令行下使用mysqlbinlog命令,导出这段时间的记录

ps 这里加上了--no-defaults 参数,因为在我的mysql5.7中 不加这个参数执行会出现mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8mb4'这样的错误

mysqlbinlog  --no-defaults    --start-datetime="2018-04-26 03:00:00" --stop-datetime="2018-04-26 15:00:00"  /data/mysql/mysql-bin.000011 > backup

这样就把这个时间点的数据全部导出到了backup中,然后用输入重定向的方式执行命令
~~~
mysql -u oort -p < backup
~~~~
然后检查了一下数据库,发现数据都回来了,完美的解决了问题

总结

数据是重中之重,定时脚本每天备份是必不可少的操作,然后二进制日志一定要开启,不要在乎那一点点的性能损耗,我们有必要用性能来换取数据库的容灾性。并且在有条件的情况下,请使用多台数据库做主从的操作,来保证数据库的容灾性质,

端口转发与反向隧道

引言

最近了解到一个叫做反向隧道的东西,发现这个可以用来很多黑科技的事情,于是就尝试了一下

准备材料

  • 一台云服务器
  • 一台带有ssh client的计算机

ssh动态端口转发

ssh有三种转发模式,本地端口转发 远程端口转发 动态端口转发,对应的参数分别是 -L -R -D
如果仅仅作为正向代理服务器的话,我们只要使用动态端口转发就可以了(这里只介绍动态端口转发进行科学上网,ssh更详细的用法还是查看手册比较好)

ssh -D  localhost:1991 root@server_ip

这样就在本地的1991端口开启了一个socks代理,接着是配置火狐浏览器的代理功能首选项->设置->手动设置代理

socks主机: localhost
端口: 1991

这样当前计算机就能通过1991端口,转向到云服务器从而获取网络资源了 ,不过这样只能给本机使用,如果希望当前局域网内的所有计算机使用的话,只要稍微改一下地址就可以了,假设本地计算机的ip地址是192.168.10.10,那么使用命令如下

ssh -D 192.168.10.10:1991 root@server_ip

这样在火狐浏览器中的配置就是

sockes主机: 192.168.10.10
端口: 1991

配置到局域网的ip之后,本地局域网内的所有计算机都可以通过这个ip进行代理,但是本机不能使用127.0.0.1的地址进行代理,如果你希望本地使用127.0.0.1 的方式并且局域网的其他计算机也可以访问的话,那么还是上一条命令稍稍做一下修改就可以了

ssh -D 0.0.0.0:1991 root@server_ip

这样本地使用127.0.0.1 或者局域网其他计算机使用192.168.10.10 就都可以使用代理服务器了

0.0.0.0其实不算是一个ip地址,它代表 的是你计算机上所有的ip地址

尾声

工具能够帮助你更好的完成一些复杂的任务,但是基础知识能够让你更加灵活的运用工具。

linux下分割文件

linux下分割文件

在 linux下工作的时候,总是需要对文件进行分割的时候,比如文件太大又或者希望把一段敏感信息分开存储,这个时候linux下强大的split就登场了,split工具分割文件的方式有两种,一种是以行的形式,另外一种是以二进制的形式

split的参数(split 8.25)

  • -a 分割后的文件的前缀
  • -b 以二进制方式分割文件
  • -C 每个输出文件的最大值
  • -d 以数字形式输出文件名
  • -e 不输出空文件
  • -l 以行的形式分割文件
  • -n 生成chuncks输出文件

实际用法

比如有一个文件名为file,大小为4M,那么可以通过下面的命令来切成4片

  • 二进制形式分割
split -b 1M  file

那么就会生成xab xac xad xae四个文件

  • 生成带上数字形式的文件
split -b 1M  -d file

带上了-d参数,那么生成的文件将会是x01 x02 x03 x04

  • 指定生成的文件的前缀
split -b 1M  -d file  suffix

那么生成的文件将会是suffix01 suffix02 suffix03 suffix04

  • 以行的形式分割

如果是文本文件,那么可以用-l 数字以行的形式进行分割

split -l 10 file

合并文件

分割之后必定有合并,否则就好像不怎么完整,不过合并就没有专用的工具了,但是还是一条命令就可以解决的 ,比如分割后的文件是xac xab xac xad四个,那么使用这样的命令

cat x* > newfile

这样新生成的文件newfile和原来的file文件就是一样的,使用md5sum工具可以计算出,他们具有相同的md5值

尾语

通过split工具,我们不仅仅可以单纯的把它当作一种切割文件的工具,其实也可以当作一种加密工具,有些时候自己个人的隐私数据保存成文本十不安全的,加密的话是一种选择,不过我还是更倾向于把文件分割开来,分开存储,需要的之后组合起来就能看到自己想要的数据了。未尝不是一种好的手法。linux下的工具丰富强大,怎么选择还是看个人,不过这一切都需要依靠自己主动的去探索。

利用ssh反向隧道控制内网计算机

引子

今天有个朋友告诉我他们 公司把teamviewer的端口封掉了,所以没有办法在家里控制公司的电脑去完成一些任务,于是就问我怎样进行内网穿透。这个时候我第一时间想到的是,通过在一台有公网ip的服务器上编写socket服务器,然后在客户端利用socket连接到服务器,连接到之后,把从服务器接收到的信息当做命令来执行,这样等于就是开了一个后门,可以实现内网穿透。正在我准备编写socket服务端代码的时候,我的直觉告诉我,这么简单的功能肯定已经有前辈实现了,本着不重复造轮子的良好习惯,于是顺手搜索了一下ssh,于是了解到反向隧道可以实现这个功能。

准备环境

  • 一台具有公网ip的服务器(必须开启sshd服务)
  • 一台unix/linux系列的客户端(必须开启sshd服务)

实现原理

这种手段的实现方式是,通过当前unix/linux客户端向服务器主动的建立一个SSL隧道,然后将服务器上的某个端口转发到当前客户端的22端口上,这样任何一台计算机包括服务器本身,都能使用服务器上开启的某个端口连接到当前的客户端上

实现过程

要先实现这个过程非常简单,现在定义服务器名称为S,服务器的ip地址为SADDR,服务器用户为root,需要开启的端口任意,这里使用7777, 客户端计算机的名称为C,客户端计算机的用户user
在C上使用命令主动的向S建立ssh隧道

ssh -p 22  -qngfNTR 7777:127.0.0.1:22  root@SADDR

这样一条命令就能在客户端C上建立了一条链接服务器S的ssh隧道
然后在S上就可以通过7777端口来连接到客户端C了,使用命令如下

ssh -p 7777 user@127.0.0.1

如果是其他计算机,那么可以使用下面的命令来连接

ssh -p 7777 user@SADDR

这样就完成了从外网利用ssh来访问内网的计算机了,当然ssh的 功能肯定不止这么一点,更多的功能就不多做介绍了,想要掌握更多的知识,最终还是需要自己去探索的。