晨曦's Blog

This is a window to the soul

关于 DroneDocker in Docker (dind) 解决方案,本人历经 2天尝试了各种解决方案,最终解决方案为 volumes 挂载,已在本文体现

为什么

为什么?为什么要使用 GogsDrone?答案是习惯!!!

工作中一般使用 GIT 管理工具为 gitlab,自有开源项目一般都是使用的 github,自有私有项目之前一直用 gitee;玩 Nas 也有好几年了,最初也想过在 Nas 上通过 docker 搭建 gitlab 无奈配置不过硬

怎么说呢?了解 Gogs 是在它出来的那一段时间,但是也一直没有用过。最近心血来潮还是想自己在 Nas 上做一个 GIT 私有服;于是挑中了 GogsGitea,鉴于两个服务属于同源最后选择了 Gogs

Gogs

关于 Gogs 的安装我这里就不过多的赘述,可以看下面的两个文档

Gogs Github

Gogs Docker

这需要说明的是 Gogs 支持 MySQL, PostgreSQL, SQLite3, MSSQLTiDB;目前我使用的是 MySQL,关于 Mysql 的安装部署可以查看官方文档这里也不过多赘述

Mysql 安装文档

对于在群晖 Docker 中去管理 Mysql 的工具这里我推荐 adminer 安装文档如下

adminer 安装文档

最后我要说的是一个是端口映射的问题,一个是卷映射的问题,如下图


最后直接访问:http://192.168.1.2:10080 就 OK 了

这里贴出一下整个 Gogs 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// /data/gogs/conf/app.ini

APP_NAME = Gogs
RUN_USER = git
RUN_MODE = prod

[database]
DB_TYPE = mysql
HOST     = 192.168.1.2:3306 // mysql地址端口
NAME     = gogs
USER = root
PASSWD   = password // mysql密码
SSL_MODE = disable
PATH = data/gogs.db

[repository]
ROOT = /data/git/gogs-repositories
publish
[server]
DOMAIN           = 192.168.1.2 // 访问域名
HTTP_PORT       = 10080 // http端口
ROOT_URL         = http://192.168.1.2/ // 访问域名
DISABLE_SSH = false
SSH_PORT         = 10022 // SSH端口
START_SSH_SERVER = false
OFFLINE_MODE = false

[mailer]
ENABLED = false

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION   = true // 禁止注册,只能有管理员能加账号
ENABLE_CAPTCHA         = true
REQUIRE_SIGNIN_VIEW   = true // 默认跳转到登录页

[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false

[session]
PROVIDER = file

[log]
MODE = file
LEVEL = Info
ROOT_PATH = /app/gogs/log

[security]
INSTALL_LOCK = true
SECRET_KEY = security

到此为止,我们就完成了 Gogs 的所有安装

Drone

Drone 安装

为什么?为什么要使用 Drone 还是因为习惯。因为在使用 Gitlab 的时候使用的 CI/CD 都是 gitlab 自带的 gitlab ci;所以这里我们也需要一个 CI/CD 的工具于是我选择了 Drone,当然市场上 CI/CD 的工具是比较多的

Drone 安装这里我们参考官方文档

Gogs 单机安装文档

Docker 命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run \
-d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /volume1/docker/drone:/data \
-e DRONE_GIT_ALWAYS_AUTH=false \
-e DRONE_GOGS_SERVER=http://192.168.1.2:10080 \
-e DRONE_SERVER_HOST=http://192.168.1.2:10800 \
-e DRONE_DATABASE_DRIVER=mysql \
-e DRONE_DATABASE_DATASOURCE="root:password@tcp(192.168.1.2:3306)/drone?parseTime=true" \
-p 80:80 \
-p 443:443 \
--name=drone \
drone/drone:latest

这里贴别强调一下 /var/run/docker.sock:/var/run/docker.sock 的挂载是必不可少的,因为后面的 DIND 会用到,另外因为我使用了 Mysql 所以上面 DRONE_DATABASE_DRIVER 配置为 mysql

接下来访问 http://192.168.1.2:10800 就会出现 Drone 登录界面,账号为 Gogs 管理员账号,这两个账号相通,而且也会自动同步 Gogs 项目

.drone.yml

在编辑.drone.yml 之前我们需要在 drone 管理界面对项目设置

这里需要设置项目为受信任项目,如果 Project settings 未显示,则表示当前用户在 Drone 不是管理员可以更改数据库授权为管理员

1
UPDATE `users` SET `user_admin` = '1' WHERE `user_id` = '1';

接下来我们编写.drone.yml,对于.drone.yml 编写我们以 Spring Boot 项目为例,首先我们需要编辑 DockerFile

1
2
3
4
5
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/hello-1.0.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

接下来我们编辑.drone.yml,关于.drone.yml 请参考.drone.yml 文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kind: pipeline
name: default

steps:
- name: build
image: maven:3.5-jdk-8
commands:
- mvn package -B -Dmaven.test.skip=true # 打包跳过测试

- name: publish
image: docker:dind
volumes:
- name: docker
path: /var/run/docker.sock # dind挂载来自Drone容器/var/run/docker.sock
commands:
- docker login --username=* --password=* registry.cn-shenzhen.aliyuncs.com
- docker build -t spring-boot:master .
- docker tag spring-boot:master registry.cn-shenzhen.aliyuncs.com/new/spring-boot:master
- docker push registry.cn-shenzhen.aliyuncs.com/new/spring-boot:master

volumes:
- name: docker
host:
path: /var/run/docker.sock # 这里挂载Drone容器所在/var/run/docker.sock,当然Drone容器/var/run/docker.sock来自于群晖宿主机/var/run/docker.sock

通过上面我们定义了两步,build 利用 mavenSpring Boot 进行了打包操作;publish 利用 dind 将打包好的 jar 包通过 DockerFile 打包成镜像并推送到镜像仓库,这里说一下我使用的镜像仓库是阿里云

这里也请注意 WebHook 的地址为上面安装的 Drone 地址请注意填写正确

下面我们看一下 Drone 执行过程

到这里我们就告一段落了


以上就是群晖对接整个 GogsDrone 过程

最近在开发一个项目是用的 eggjs 同时又需要对接到微信公众平台,所以记录下自己 Egg 对接微信的过程

验证 Token

我们知道在微信开发时都需在公众开发配置中对 Token 验证一次,接下来谈谈验证的步骤

第一步确定验证 URL

比如我的是 https://www.jakehu.me/wechat,那么先对 eggjs 路由改造

1
2
3
4
5
// app/router.js

module.exports = app => {
app.router.get('/wechat', app.controller.wechat.index);
};

改造完路由后我们还必须对安全这块进行设置,屏蔽对路由 /wechatcsrf 验证

1
2
3
4
5
6
7
// config/config.default.js

config.security = {
csrf: {
ignore: '/wechat',
},
};

第二步编写验证 Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// app/controller/wechat.js

async index () {
const query = this.ctx.request.query;
const signature = query.signature;
const timestamp = query.timestamp;
const nonce = query.nonce;
const echostr = query.echostr;
   if (await this.check(timestamp, nonce, signature, 'token')) {
this.ctx.body = echostr;
} else {
this.ctx.body = 'It is not from weixin';
}
}

async check (timestamp, nonce, signature, token) {
const tmp = [ token, timestamp, nonce ].sort().join('');
const currSign = crypto.createHash('sha1').update(tmp).digest('hex');
return (currSign === signature);
}

然后就可以在开发者配置进行验证就好了

注:上面代码中的 token 即为你在开发者配置页面中填写的 token

接入开发

第一步安装必要组件

这里我们用到了 co-wechat 插件

1
npm i co-wechat -s

安装后对插件进行配置

1
2
3
4
5
6
7
// config/config.default.js

config.wechat = {
token: 'token',
appid: 'appid',
encodingAESKey: 'encodingAESKey',
};

编写对接代码

首先是 Controller 的编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// app/controller/wechat.js

const wechat = require('co-wechat');
module.exports = app => {
class WechatController extends app.Controller { }

// 因为 Egg 需要用类的形式来组织,而 wechat 是通过 middleware 方法来生成中间件
WechatController.prototype.wechat = wechat({
token: 'token',
appid: 'appid',
encodingAESKey: 'encodingAESKey',
}).middleware(async (message, ctx) => {
console.log(message);
return { type: 'text', content: 'Hello world!' };
});

return WechatController;
};

其次我们对路由再进行改造

1
2
3
4
5
// app/router.js

module.exports = app => {
app.router.post('/wechat', app.controller.wechat.wechat);
};

到此就结束了,完美对接!!!


完美对接!!!

环境

公司的 GIT 环境一直是用 Gitlab 跑在阿里云的 Docker 环境中的,Gitlab 的配置并没有做更改,然而今天发现突然报 Forbidden 而且还时好时坏。通过查看官方文档【Rack Attack】发现可能是项目太多并发太高触发了 IP 屏蔽

解决方案

根据官方的文档【Rack Attack】【IP whitelist】可有如下三种方法解决:

  1. 添加 IP 白名单
  2. 扩大每个 IP HTTP authentication 次数
  3. 直接关闭 Rack Attack

实践

  1. 添加 IP 白名单

步骤:

  • vi /etc/gitlab/gitlab.rb
  • 查找 rack_attack_git_basic_auth
  • gitlab_rails['rack_attack_git_basic_auth'] 取消注释
  • 修改 ip_whitelist 白名单将 gitlab 部署主机 IP 地址加入
    'ip_whitelist' => ["127.0.0.1","172.16.7.21"],
  • 最后执行 gitlab-ctl reconfigure 重载配置

在添加白名单后发现问题依然存在,于是在上述完成后继续第二种方式

  1. 扩大每个 IP HTTP authentication 次数

步骤:

  • maxretry 调整为 200

最后配置如下:

1
2
3
4
5
6
7
gitlab_rails['rack_attack_git_basic_auth'] = {
'enabled' => true,
'ip_whitelist' => ["127.0.0.1","172.16.7.21"],
'maxretry' => 200,
'findtime' => 60,
'bantime' => 3600
}

再次执行 gitlab-ctl reconfigure 重载配置

完美解决!!!

前记

最近在做微信开发本地测试,需要用到 80 端口;鉴于 Eggjs 默认端口为 7001,于是开始了一场 Eggjs 绑定 80 端口之战

Scripts

scripts 改造,将 dev 命令改为如下:

1
"dev": "egg-bin dev --port=80",

问题一

当运行 npm run dev 之后出现下面问题

1
bind EACCES null:80, code: EACCES

绑定 80 端口失败,看来是权限不够

解决方案:sudo 高权限运行

问题二

当运行 sudo npm run dev 之后出现下面问题

1
sudo: npm:找不到命令

看来是 bin 下面没有可执行文件

解决方案:ln -s

1
2
3
4
5
6
7
$ which npm
> /home/jakehu/.nvm/versions/node/v8.12.0/bin/npm
$ sudo ln -s /home/jakehu/.nvm/versions/node/v8.12.0/bin/npm /usr/bin/npm

$ which node
> /home/jakehu/.nvm/versions/node/v8.12.0/bin/node
$ sudo ln -s /home/jakehu/.nvm/versions/node/v8.12.0/bin/node /usr/bin/node

最后只需要运行 sudo npm run dev 就可以了


如果出现 bind EADDRINUSE null:80, code: EADDRINUSE 错误,表示有程序占用 80 端口,pkill 掉即可

虽然度娘是一个垮掉的搜索引擎,但是谁叫它在强国是垄断的存在呢。谈谈 Hexo 部署在 Github Pages 怎么提交 Sitemap 给百度。

Sitemap

因为 Github Pages 禁止百度爬虫所以这里我们不做过多的说明,无疑这种方式是行不通的

自动推送

目前在用的一种推送方式

1
自动推送是百度搜索资源平台为提高站点新增网页发现速度推出的工具,安装自动推送JS代码的网页,在页面被访问时,页面URL将立即被推送给百度

安装方式也很简单,只需要在页面中加入以下 JS 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>

主动推送 (实时)

我们重点来说说主动推送

首先我们这里需要安装一下生成 sitemap 的包

1
npm i hexo-generator-baidu-sitemap -s

新建文件 push_sitemap_to_baidu.php,这里我们通过 PHP 来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
// 解析xml
$file = "./public/baidusitemap.xml";
$xml = simplexml_load_file($file);
$urls = array();
foreach ($xml as $key => $value) {
$url = array();
$url = (array) $value->loc;
$urls[] = current($url);
}
// 调用百度API
$api = 'http://data.zz.baidu.com/urls?site=https://www.jakehu.me&token=***';
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
// 返回结果记录
$time = date("Y-m-d H:i:s");
$content = $time . " --- " . $result . PHP_EOL;
$file = "push_sitemap.log";
$fp = fopen($file, "a+") or die("fail to open the file");
fwrite($fp, $content);
fclose($fp);

最后会在根目录下生成 push_sitemap.log 日志文件

然后改造 package.json 如下

1
2
3
"scripts": {
"push": "hexo cl && hexo g && gulp && hexo d && php -f push_sitemap_to_baidu.php"
}

这条命令包含了清理生成压缩部署推送Sitemap,关于 gulp 压缩部分可看这里【点击查看】

最后我们可以直接运行命令进行部署和推送 npm run push,或者将 push 改为 start 直接运行 npm start 即可

Headless Chrome

什么是 Headless Chrome

Chrome59 中开始搭载 Headless Chrome。这是一种在无需显示 headless 的环境下运行 Chrome 浏览器的方式。从本质上来说,就是不用 Chrome 浏览器来运行 Chrome 的功能!它将 ChromiumBlink 渲染引擎提供的所有现代 Web 平台的功能都带入了命令行。

intoli

开始安装之前我们来了解一下这家公司

我们(intoli)是一家在数据采集,处理和分析方面具有深厚专业知识的咨询机构。

安装

intoli 在其博客上介绍了几种安装 Headless Chrome 的方式,我们采用如下方式安装:

1
curl https://intoli.com/install-google-chrome.sh | bash

安装完成提示:

1
Successfully installed Google Chrome!

intoli 安装文档

运行 chrome

我们可以通过如下命令来启动 Chrome,同时将博客截图保存

1
google-chrome-stable --no-sandbox --headless --disable-gpu --screenshot https://www.jakehu.me

Chromedriver

chromedriver 可以前往淘宝镜像下载,同时通过下面命令进行验证:

1
2
3
4
./chromedriver
Starting ChromeDriver 73.0.3683.68 (47787ec04b6e38e22703e856e101e840b65afe72) on port 9515
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.

如果有如上输出则表示驱动正常运行

最近心血来潮想鼓捣鼓捣爬虫于是玩起了 pyspider,不过在启动的时候却遇到了一些小问题。

1
2
3
ValueError: Invalid configuration:
- Deprecated option 'domaincontroller': use 'http_authenticator.domain_controller' instead.

最后定位在了 wsgidav3.x 问题,pyspider 会默认安装 wsgidav3.x,解决办法为先把 3.x 卸载,再装 2.xpip install wsgidav 会默认安装 2.x 我安装的是 2.4.1

1
2
pip uninstall wsgidav  
pip install wsgidav

如果安装的 wsgidav 本还是 3.x, 可以在卸载这个版本之后,在安装命令后面加上具体版本号

1
python -m pip install wsgidav==2.4.1

前记

Kubeadm 是一个工具,通过提供 kubeadm initkubeadm join 来作为创建 Kubernetes 集群的最佳实践 “快速路径”

简单理解就跟 Docker swarm 差不多吧,KubeadmGA 版本都已经发布了,那还等什么呢?

部署

资源版本
  1. CentOS 7.6 64
  2. Kubernetes version: v1.13.2
  3. Docker version 18.06

这里为什么使用 Docker 18.06 是因为 kubeadm now properly recognizes Docker 18.09.0 and newer, but still treats 18.06 as the default supported version.

所以我们默认还是使用 18.06

服务器

这里我们使用 CentOS 7.6 64,同时测试环境为阿里云服务器

IP Address Hostname CPU Memory
172.16.1.86 Master 2C 4G
172.16.1.87 Node1 2C 4G
172.16.1.88 Node2 2C 4G

这里注意一下服务器系统,目前官方已支持 Ubuntu 16.04+Debian 9CentOS 7RHEL 7

配置

关闭防火墙

1
2
3
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
systemctl stop firewalld && systemctl disable firewalld

设定 /etc/hosts

1
2
3
172.16.1.86 Master
172.16.1.87 Node1
172.16.1.88 Node2

禁用 Swap

1
swapoff -a && sysctl -w vm.swappiness=0

将配置中 net.bridge.bridge-nf-call-iptables 被设为 1

1
2
3
4
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
安装 Docker

在 3 台服务器上都安装上 Docker,此次实验 Docker 版本:Docker version 18.06

Centos Docker 安装文档

安装完成启动 Docker

1
systemctl enable docker.service
安装 K8s

在 3 台服务器上配置 YUM 源为阿里镜像源

1
2
3
4
5
6
7
8
9
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

您需要在每台机器上都安装以下的软件包:

  1. kubeadm: 用来初始化集群的指令。
  2. kubelet: 在集群中的每个节点上用来启动 podcontainer 等。
  3. kubectl: 用来与集群通信的命令行工具。
1
2
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet && systemctl start kubelet

版本:Kubernetes version: v1.13.2

Master

Master 节点上配置 kubelet 所需的 cgroup 驱动

1
2
3
cat <<EOF >  /var/lib/kubelet/kubeadm-flags.env
KUBELET_EXTRA_ARGS=--cgroup-driver=cgroupfs
EOF

需要重启 kubelet

1
2
systemctl daemon-reload
systemctl restart kubelet

k8s.gcr.io 镜像本地化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
kubeadm config images list //查看所需要的镜像

// 编辑脚本从hub获取镜像
vim k8s.sh

#!/bin/bash
docker pull coredns/coredns:1.2.6
docker tag coredns/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6
docker rmi coredns/coredns:1.2.6
images=(
kube-apiserver:v1.13.2
kube-controller-manager:v1.13.2
kube-scheduler:v1.13.2
kube-proxy:v1.13.2
pause:3.1
etcd:3.2.24
)
for imageName in ${images[@]} ; do
docker pull mirrorgooglecontainers/$imageName
docker tag mirrorgooglecontainers/$imageName k8s.gcr.io/$imageName
docker rmi mirrorgooglecontainers/$imageName
done

// 编辑脚本权限
chmod +x k8s.sh

// 执行脚本
./k8s.sh

初始化 Master

1
kubeadm init --kubernetes-version=v1.13.2 --pod-network-cidr=10.244.0.0/16

配置 kubectl 认证信息

1
2
3
4
5
6
7
8
# 非root用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# root用户
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

安装网络插件 flannel

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Node

Node 镜像本地化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 编辑脚本从hub获取镜像
vim k8s.sh

#!/bin/bash
images=(
kube-proxy:v1.13.2
pause:3.1
)
for imageName in ${images[@]} ; do
docker pull mirrorgooglecontainers/$imageName
docker tag mirrorgooglecontainers/$imageName k8s.gcr.io/$imageName
docker rmi mirrorgooglecontainers/$imageName
done

// 编辑脚本权限
chmod +x k8s.sh

// 执行脚本
./k8s.sh

将节点加入集群

1
kubeadm join 172.16.1.86:6443 --token xxx --discovery-token-ca-cert-hash xxx
Dashboard

未完待续…


题外话:

安装过程中可以用 tail -f 100 /var/log/messages 查看日志,便于找到问题所在

前记

说说本地环境 Deepin 15.8Python2Python3 共存

问题

问题如下:

1
2
3
4
5
6
$ pip3
Traceback (most recent call last):
File "/usr/local/bin/pip3", line 7, in <module>
from pip._internal import main
ModuleNotFoundError: No module named 'pip._internal'

1
2
3
4
5
6
$ pip
Traceback (most recent call last):
File "/usr/local/bin/pip", line 7, in <module>
from pip._internal import main
ModuleNotFoundError: No module named 'pip._internal'

pippip3 均不可使用

解决

1
2
3
4
5
6
7
8
9
10
11
$ sudo easy_install pip
Searching for pip
Best match: pip 10.0.1
Adding pip 10.0.1 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip3.6 script to /usr/local/bin
Installing pip3 script to /usr/local/bin

Using /usr/local/lib/python2.7/dist-packages
Processing dependencies for pip
Finished processing dependencies for pip

完美解决

公共包的处理

解决方案是将公共包打包在 runner 服务器上,其他模块打包时自动应用公共包.gitlab-ci.yml 如下:

1
2
3
4
5
6
stages:
- deploy
maven-build:
stage: deploy
script:
- mvn install

注册中心地址

Eureka 地址应为 http://[service name]:[port]/eureka

切记 http 协议

runner 提权

gitlab-runner 装好后并不能通过 CI 执行,因为 gitlab-runner 是通过 gitlab-runner 用户及用户组运行的,并不是 ROOT 权限,所以这里就需要对 gitlab-runner 用户进行提权

说到提权这里说两种方式

  1. usermod
1
2
3
usermod -ag root gitlab-runner // 将gitlab-runner用户加入root用户组

// 不过这种方式我没有成功,我使用的是第二种方式
  1. /etc/passwd
1
2
3
4
vi /etc/passwd
gitlab-runner:x:997:993:GitLab Runner:/home/gitlab-runner:/bin/bash // 修改前
gitlab-runner:x:0:0:GitLab Runner:/home/gitlab-runner:/bin/bash // 修改后


未完待续

0%