作者归档:RAE

Gitlab从13版本升级至16及迁移docker容器操作

背景: 因gitlab存在漏洞需升级至最新版本,当前发布的最新版本为16.8.0-ee。当前服务的安装方式是通过传统的yum方式,为了日后升级方便,这次将迁移至docker 容器运行。

整个过程分为以下部分:

  • GitLab 备份
  • Docker 迁移部署
  • 还原备份
  • GitLab 版本升级
  • 功能验证

一、备份

1.1 仓库备份

Gitlab 的备份相对比较简单,直接使用以下命令即可:

sudo gitlab-rake gitlab:backup:create

注意,备份的过程非常漫长请耐心等待(当然取决于你的所有仓库大小) 备份好的文件存放在:/var/opt/gitlab/backups 也就是Gitlab 的安装目录,一般情况下是这个,如果找不到则需要自行百度一下。备份文件类似这样 1705434707_2024_01_17_13.4.3-ee_gitlab_backup.tar。备份的路径如果找不到,可以在/etc/gitlab/gitlab.rb 中的gitlab_rails['backup_path']找到。

1.2 配置文件备份

  • 备份所有的配置文件 /etc/gitlab/*
  • 备份nginx配置文件 /var/opt/gitlab/nginx/*

1.3 停止服务

sudo gitlab-ctl stop

二、迁移部署

docker 容器部署也相对比较简单,官方文档:GitLab Docker images | GitLab,当然官方的操作是很复杂的,这里我们使用docker-compose 来部署就非常简单。

2.1 创建Docker目录

首先,我们先建好目录,来保存Docker我们的数据:

cd /data/gitlab # 这里切换到你实际保存的路径
mkdir data
mkdir etc
mkdir log
mkdir backups
###################################################
ll
drwxr-xr-x. 2 root root 4096 1月  20 21:38 backups
drwxr-xr-x. 2 root root 4096 1月  20 21:38 data
drwxr-xr-x. 2 root root 4096 1月  20 21:40 etc
drwxr-xr-x. 2 root root 4096 1月  20 21:38 log

然后,把刚才在1.2中的配置移到这里的etc 目录中来,如:

# pwd
/data/gitlab/etc

# ll
-rw-------. 1 root root 111413 1月  21 00:01 gitlab.rb
-rw-------. 1 root root  18896 1月  21 00:01 gitlab-secrets.json
drwxr-xr-x. 2 root root   4096 1月  21 00:01 trusted-certs

2.2 创建容器

我们使用docker-compose 来创建文件,先切换到你的dockerfiles目录,没有可以自己建一个。

特别注意:切记一步到位!版本一定是你当前服务器的版本!!

特别注意:切记一步到位!版本一定是你当前服务器的版本!!

特别注意:切记一步到位!版本一定是你当前服务器的版本!!

首先,查看当前版本号命名为:

cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
# 以下输出的就是你当前的版本号
13.4.3-ee

然后,创建gitlab.yml 配置文件,参考以下文件即可。

cd /data/dockerfiles/
vim gitlab.yml

gitlab.yml 配置文件:

version: '3.6'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:13.4.3-ee.0' # 注意:这里的版本号与上面输出的必须一致!
    restart: always
    hostname: 'gitlab'
    container_name: 'gitlab'
    privileged: true
    environment:
      TZ: 'Asia/Shanghai'
      GITLAB_OMNIBUS_CONFIG: |
        # 以下的配置文件从 /etc/gitlab/gitlab.rb 里面复制过来即可
        # 以下是作者的服务器配置,不建议照搬!
        external_url 'http://192.168.1.1'
        puma['port'] = 8010
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
        gitlab_rails['gitlab_default_theme'] = 2
        gitlab_rails['object_store']['enabled'] = false
        gitlab_rails['object_store']['connection'] = {}
        gitlab_rails['object_store']['storage_options'] = {}
        gitlab_rails['object_store']['proxy_download'] = false
        gitlab_rails['object_store']['objects']['artifacts']['bucket'] = nil
        gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = nil
        gitlab_rails['object_store']['objects']['lfs']['bucket'] = nil
        gitlab_rails['object_store']['objects']['uploads']['bucket'] = nil
        gitlab_rails['object_store']['objects']['packages']['bucket'] = nil
        gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = nil
        gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = nil
        gitlab_rails['manage_backup_path'] = true
        gitlab_rails['backup_path'] = "/var/gitlab/backups"
        gitlab_rails['backup_archive_permissions'] = 0644
        gitlab_rails['backup_keep_time'] = 432000 
        git_data_dirs({
          "default" => {
          "path" => "/var/gitlab/data"
          }
        })
    ports:
      - '8090:80' # 端口号映射,服务器默认是80,这里建议先改成8080升级成功后再改回来。
    volumes: # 以下是在2.1中创建好的目录
      - '/data/gitlab/etc:/etc/gitlab'
      - '/data/gitlab/log:/var/log/gitlab'
      - '/data/gitlab/data:/var/gitlab/data'
      - '/data/gitlab/backups:/var/gitlab/backups'
    shm_size: '256m'

2.3 启动容器

docker-compose -f gitlab.yml up -d

查看运行情况

# docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                             PORTS                                   NAMES
222ae262217d        gitlab/gitlab-ee:13.4.3-ee.0   "/assets/wrapper"        17 seconds ago      Up 11 seconds (health: starting)   22/tcp, 443/tcp, 0.0.0.0:8090->80/tcp   gitlab

第一次启动比较慢,耐心等待几分钟。(这里作者等了8分钟)

等待过程中,可以使用以下命令查看容器的运行日志情况。

docker logs -f --tail 100 gitlab

这里有时间可以继续往下看,或者查看第四点先。

启动完成后在浏览器访问验证是否启动成功:http://127.0.0.1:8090

file

看到这里已经成功跑起来了,咱们先不着急登录,继续按照下面的步骤把恢复一下备份先。

三、还原备份文件

3.1 复制备份文件

1.1中备份好的文件复制到2.1中的目录:/data/docker/backups

cp 1705765212_2024_01_20_13.4.3-ee_gitlab_backup.tar /data/gitlab/backups/

这里复制过程也是比较漫长的,作者这里有几十个G的大小,耐心等待一下。

等待过程可以先跳到执行4.1 进行docker镜像下载。

3.2 执行还原

执行以下命令:

# 1.进入容器
docker exec -it gitlab /bin/bash

# 2.停止服务
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# 查看服务是否正常停止
sudo gitlab-ctl status |grep down
# down: puma: 57s, normally up; run: log: (pid 872) 2008s
# down: sidekiq: 1846s, normally up; run: log: (pid 899) 2003s

# 3.查看备份文件
cd /var/gitlab/backups
ls
# 1705765212_2024_01_20_13.4.3-ee_gitlab_backup.tar

# 4.执行还原,注意这里文件名不需要【_gitlab_backup.tar】
gitlab-rake gitlab:backup:restore BACKUP=1705765212_2024_01_20_13.4.3-ee
# Unpacking backup....

恢复过程还需要输入3次的yes,

之后还是继续漫长的等待····

3.3 还原验证

还原结束后,重启服务并检查是否正常。

sudo gitlab-ctl restart
sudo gitlab-rake gitlab:check SANITIZE=true

最后登录进去查看各个仓库及功能是否正常。

至此,Gitlab迁移至docker 容器完成! 接下来进行升级操作。

四、版本升级

首先,版本是不能一步到位升级上去的。 需要遵循小版本逐步升级,官方提供升级路径,输入你当前的版本号就可以了。Upgrade Path (gitlab-com.gitlab.io)

例如作者这里的是13.4.7 ,选择升级方式为docker,官方给出的结果是这样的。

file

4.1 镜像下载

我们把官网的升级路径做成一个脚本文件,先把容器镜像先下载下来。

vim gitlab-docker.sh

#!/bin/bash
docker pull gitlab/gitlab-ee:13.8.8-ee.0
docker pull gitlab/gitlab-ee:13.12.15-ee.0
docker pull gitlab/gitlab-ee:14.0.12-ee.0
docker pull gitlab/gitlab-ee:14.3.6-ee.0
docker pull gitlab/gitlab-ee:14.9.5-ee.0
docker pull gitlab/gitlab-ee:14.10.5-ee.0
docker pull gitlab/gitlab-ee:15.0.5-ee.0
docker pull gitlab/gitlab-ee:15.4.6-ee.0
docker pull gitlab/gitlab-ee:15.11.13-ee.0
docker pull gitlab/gitlab-ee:16.1.6-ee.0
docker pull gitlab/gitlab-ee:16.3.7-ee.0
docker pull gitlab/gitlab-ee:16.7.3-ee.0
docker pull gitlab/gitlab-ee:16.8.0-ee.0

4.2 逐一升级

首先,停止容器。

docker-compose -f gitlab.yml stop

然后修改gitlab.yml 的容器版本

version: '3.6'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:13.8.8-ee.0'  # 根据上面的版本号顺序逐一修改
# ... 这里省略其他....

附:从13.4.7版本升级到16.8.0版本过程版本

13.8.8 => 13.12.15 => 14.0.12 => 14.3.6 => 14.9.5 => 14.10.5 => 15.0.5 => 15.4.6 => 15.11.13 => 16.1.6 => 16.3.7 => 16.7.3 => 16.8.0

重启容器

docker-compose -f gitlab.yml up -d

# 看看容器日志有没有什么异常或报错
docker logs -f -t --tail 100 gitlab

特别注意:一定要留意后台迁移任务是否都已经执行完毕,只有全部执行完毕后才能继续操作。

查看后台迁移状态地址:http://127.0.0.1:8090/admin/background_migrations

后台迁移状态

等待升级完成后,进入系统查看功能是否正常。正常后依此类推,重复以上操作即可。

4.3 定时备份

docker-compose 跑的 GitLab 如果需要用 crontab 方式来进行备份的话,docker-compose exec 后面记得加 -T:

-T 为不分配 TTY,如果不加的话,利用 crontab 来运行会报: the input device is not a TTY
docker-compose exec -T gitlab gitlab-backup create

Android Studio Markdown 开启实时预览功能

Markdown 插件中明确说明了不支持Android Studio,引用原文:

  • Live HTML preview (except Android Studio, see issue and workaround).

原因是Android Studio 不支持 JCEF,但好在有地方可以设置,参考以下步骤:

  1. Find action (ctrl + shift + A / command + shift + A)
  2. Search for ChooseBoot Java Runtime for the IDE
  3. Select the latest version in the "New:" dropdown – e.g. 11.0.12+7-b1504.27 JetBrains Runtime with JCEF
  4. OK
  5. Restart

Android中常用的设计模式

本文参考来自:《Java设计模式:23种设计模式》

设计原则

在我们日常编程中,常见的面向对象设计原则有以下几大原则,能够帮助在面向对象过程设计出合理的结构。减少对象之间的耦合,方便业务扩展。

  • 开放封闭原则
  • 单一职责原则
  • 里氏替换原则
  • 依赖倒置原则
  • 接口隔离原则
  • 合成复用原则
  • 迪米特法则

开放封闭原则

开闭原则指的是: 软件实体应当对扩展开放,对修改关闭。这里的软件实体可以是:项目中划分出的模块、类与接口、方法。
开放封闭的含义是: 当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
举个例子: 我们购买商品付款的时候有多种支付渠道如支付宝、微信。付款的流程是一致的,但付款方式是根据不同,我们可以定一个支付接口play();接口内部维护付款流程,外部实现支付接口来实现不同的付款方式,以后提供新的付款方式也不需要修改源代码了,所以他就满足了开放封闭原则。

单一职责原则

单一职责原则:这里的职责是指类变化的原因,单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。
该原则提出对象不应该承担太多职责,如果一个对象承担了太多的职责,至少存在以下两个缺点:
一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力;
当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费。

Kotlin 常用配置

Kotlin Parcelable 自动生成配置

code>@Parcelize</code注解框架

plugins {
    id 'kotlin-parcelize'
}
import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class VideoBean(var url: String?) : Parcelable

ViewBinding

buildFeatures {
    viewBinding = true
}

MVVM 依赖包


// kotlin coroutines + livedata + view model
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'

Kotlin 编译出现 Internal error: unexpected lint return value -1 的解决方法

在一次Java和Kotlin混合编译时这样的错误:

Execution failed for task ':kotlin:extractDebugAnnotations'.
> A failure occurred while executing com.android.build.gradle.internal.lint.AndroidLintWorkAction
   > Internal error: unexpected lint return value -1

原因排查:去除所有Java的类,一个个类进行编译排查后发现只要引用了import androidx.annotation.xxx; 的注解时都编译失败。

原因分析:kotlin是100%兼容Java的,可能由于编译插件版本导致。

解决方案:

将原来的kotlin gradle插件版本降级。

修改根目录build.gradle 文件:


// 编译失败的配置
plugins {
    // ...省略其他
    id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
}

// 修改后的配置
plugins {
    // ...省略其他
    id 'org.jetbrains.kotlin.android' version '1.6.21' apply false
}

WSL使用教程

安装CentOS

1、下载镜像:
https://github.com/wsldl-pg/CentWSL/releases
2、下载完后一定要解压后打开。

卸载系统服务

1、wslconfig /l 查看已经安装的系统
2、wslconfig /u CentOS7 卸载系统

systemctl 无法使用问题

mv /usr/bin/systemctl /usr/bin/systemctl.old
curl https://github.com/gdraheim/docker-systemctl-replacement/blob/master/files/docker/systemctl.py > /usr/bin/systemctl
chmod +x /usr/bin/systemctl

Windows VMware 安装CentOS7

安装系统

镜像下载:http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/

本文使用的是CentOS-7-x86_64-Minimal-2009.iso 无界面版本

安装过程:
1、安装时选择自动分区
2、一定要设置用户名和密码,还有root用户

此处省略其他安装过程···

系统配置

网络配置

按安装好后无法访问网络,需要手动设置DNS,主要修改ONBOOT=yesDNS1=114.114.114.114

cd /etc/sysconfig/network-scripts/
vi ifcfg-ens32                      # 这里有可能不一样根据自己文件,ifcfg-ens开头的

TYPE=Ethernet                    # 网卡类型:为以太网
PROXY_METHOD=none                # 代理方式:关闭状态
BROWSER_ONLY=no                  # 只是浏览器:否
BOOTPROTO=dhcp                   # 网卡的引导协议:DHCP
DEFROUTE=yes                 # 默认路由:是 
IPV4_FAILURE_FATAL=no             # 是不开启IPV4致命错误检测:否
IPV6INIT=yes                 # IPV6是否自动初始化: 是
IPV6_AUTOCONF=yes               # IPV6是否自动配置:是
IPV6_DEFROUTE=yes               # IPV6是否可以为默认路由:是
IPV6_FAILURE_FATAL=no             # 是不开启IPV6致命错误检测:否
IPV6_ADDR_GEN_MODE=stable-privacy       # IPV6地址生成模型:stable-privacy 
NAME=ens33                  # 网卡物理设备名称
UUID=42773503-99ed-443f-a957-66dbc1258347   # 通用唯一识别码
DEVICE=ens33                 # 网卡设备名称
ONBOOT=yes                  # 是否开机启动, 可用systemctl restart network重启网络
DNS1=114.114.114.114

systemctl restart network 重启网络服务

固定IP地址配置

我们在开发使用过程中需要用SSH来连接,虚拟机最好是固定一个IP地址,过程如上,修改ifcfg-ens32配置信息如下:

ifconfig 先查看自己获取的动态IP是多少,然后再修改。

BOOTPROTO="static"                # 静态获取
# 以下的IP地址根据自己分配的VMware地址来确定
IPADDR="172.24.60.126"
NETMASK="255.255.240.0"
GATEWAY="172.24.48.1"
DNS1="223.5.5.5"
DNS2="114.114.114.114"

yum源的配置

cd /etc/yum.repo s.d/
# 备份当前的配置
mkdir backup
mv *.repo ./backup
# 拉取阿里云镜像包
curl http://mirrors.aliyun.com/repo/Centos-7.repo -o Centos-7-aliyun.repo
yum clean all # 清空缓存
yum makecache # 生成缓存

yum的下载速度飞起了

安装VmwareTool

官方文档:https://docs.vmware.com/cn/VMware-Workstation-Pro/16.0/com.vmware.ws.using.doc/GUID-08BB9465-D40A-4E16-9E15-8C016CC8166F.html

1、在菜单栏点击虚拟机安装VMwareTool

file

2、整合整个安装过程

yum -y install perl gcc make kernel-headers kernel-devel # 安装Perl
reboot #重启
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
cd /tmp/
tar zxpf /mnt/cdrom/VMwareTools # 这里按Tab 自动补全当前的版本
cd /tmp/vmware-tools-distrib/   # 解压的目录
./vmware-install.pl # 接下来的提示全部按回车

开启文件共享

首先在虚拟机中配置文件夹共享

file

挂载文件夹

cd /mnt
mkdir rae # 这个是共享文件夹的名称,名字随便起
vmware-hgfsclient #查看共享
vmhgfs-fuse .host:/SharedFolder /mnt/rae # 挂载:物理机的SharedFolder文件挂载到虚拟机的rae目录中

自动挂载

vi /etc/fstab
.host:/SharedFolder /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults 0 0
mount -a

开启SSH

参考文章:https://www.cnblogs.com/ZeroSunny/p/14900454.html

yum install net-tools #网络工具netstate

免密登录:将本机的公钥复制到虚拟机的~/.ssh/authorized_keys ,修改权限:

chmod 700 .sshchmod 600 authorized_keys

问题总结

Nginx出现目录访问权限问题
关闭SELINUX: vim /etc/selinux/config 修改:SELINUX=disabled

docker端口无法访问
打开IP端口转发: sysctl -w net.ipv4.ip_forward=1

CentOS 命令

防火墙

开启防火墙

systemctl start firewalld

开启端口号

firewall-cmd --zone=public --add-port=80/tcp --permanent

  • –zone #作用域
  • –add-port=80/tcp #添加端口,格式为:端口/通讯协议
  • –permanent #永久生效,没有此参数重启后失效

查看端口号

firewall-cmd --list-ports

重启防火墙

firewall-cmd --reload

文件操作

删除文件夹

rm -rf youdir

解压ZIP

yum install zip unzip

unzip filename

SSH 复制文件

scp LocalFile UserName@RemoteIP:RemoteFile

VIM常用命令

  • dd:剪切当前行
  • yy:复制当前行
  • nyy:n表示大于1的数字,复制n行

其他常用命令

route -n 查看路由
ifconfig 查看IP
cat /etc/sysconfig/network-scripts/ifcfg-ens33 查看IP配置

服务器空间清理

服务器空间爆满的时候,要清理一些垃圾文件,以下整理常用的操作。

查看磁盘空间占用情况命令

cd /
# -h 友好的文件大小展示
# -d 1 扫描深度 1 表示只扫描当前目录下的大小
du -hd 1

会显示以下结果

4.0K    ./mnt
35M ./opt
0   ./sys
4.0K    ./media
40M ./etc
147M    ./boot
16K ./lost+found
4.0G    ./usr
0   ./proc
0   ./dev
23G ./var
9.2M    ./run
4.0K    ./data
1.2G    ./root
4.0K    ./srv
6.5M    ./tmp
46G .

排查过程:一步步查看占用空间比较大的目录,逐一击破。

Docker 垃圾文件清理

移除没有使用的镜像

docker image prune

检查Volumn占用情况

有些已经删除的容器残留下来的Volumn

# 查看卷
$ docker volume ls

DRIVER              VOLUME NAME
local               179a41a06fd1846903f09af979347c35dca7eabdd33f2a2a323e694011013b48
local               3fd4c3dce22b080e45234a13ba80492370e4a1db0ba9fd4992f9ef80e1254d33
local               5964c9d8a7ac6623b4cf629448b33a4ebdf99ada7b867f4d76f93998d9db6767
local               5b8a1d868aabaa35628f1ff36879b465b20eccab891f27672f9a3fa5147b6d49
local               5ff014d431df3144a0ab5b7c58bf4c3e5efd7a0313d31f2f6b473cb1eef38139

# 移除没有使用的
$ docker volume prune

Deleted Volumes:
5b8a1d868aabaa35628f1ff36879b465b20eccab891f27672f9a3fa5147b6d49
5ff014d431df3144a0ab5b7c58bf4c3e5efd7a0313d31f2f6b473cb1eef38139
65cb3e5ea0f8e24010c59d89fb02e75b19c3f2927fcc834bbaf48a1bb6c4b160
cbbca6df34a0ec0182e6682c87e21a31e0b21c980aa0f4297618d8cb5693872f
e21b0c710c575977a48f13f87b08ef2dd3f4037818332f1b09e71ffb4cd6ed37
179a41a06fd1846903f09af979347c35dca7eabdd33f2a2a323e694011013b48
3fd4c3dce22b080e45234a13ba80492370e4a1db0ba9fd4992f9ef80e1254d33
5964c9d8a7ac6623b4cf629448b33a4ebdf99ada7b867f4d76f93998d9db6767

Total reclaimed space: 8.489 GB

如何修改jar的class文件

在项目中遇到需求想要从已经打包好的jar修改其中的类来扩展功能怎么办?大概分为以下步骤:

  • 反编译jar从class文件拿到Java源码
  • 修改源码后生成class文件
  • 替换class文件
  • 重新打包

1、反编译

执行以下命令解压jar文件

jar -xvf X.jar

反编译jar得到源码

使用工具 jadx-gui,下载地址:https://github.com/skylot/jadx

file

找到要修改的类复制Java源码。

注意:如果不想下载工具可以自己在AndroidStudio里面直接复制源码

2、编译项目

在AndroidStudio 新建项目,修改源码后进行编译。执行assemble编译任务后在/build/intermediates/javac/release/classes 找到生成好的class文件

3、替换class文件重新打包

把class 文件替换回去后,执行以下命名进行打包

cd 到刚才解压的目录里面
jar -cvf YOUR.jar ./

至此已完成新的jar文件。

详情参考文章