Debian 环境下安装配置

GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。
它拥有与GitHub类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。

前言

公司目前的开发架构中,使用了gitlab来统一管理上线发布代码的操作。鉴于是之前的前辈搭建的,所以打算自己手动安装一次,来熟悉相关的配置。

安装

中文版gitlab网站:https://www.gitlab.com.cn/installation/
英文版gitlab网站:https://about.gitlab.com/downloads/

选择对应的操作系统

我这里选择 Debian 9 版本,因为要在服务器上进行搭建,长期运行。综合考虑后采用 debian系统,稳定,快速。

开始安装

安装过程非常简单, 按照页面中的执行步骤,依次执行命令即可。

1. 安装配置依赖项

如想使用 Postfix 来收发邮件,在安装期间请选择’Internet Site’. 您也可以用 exim4 或者配置外部的SMTP服务,使用SMTP发送邮件。
上面的安装期间,我没有选择internet site 选择的是本地local

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

2. 添加GitLab仓库,并安装到服务器上

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

安装的过程中会有个蓝色的窗口提示你输入名称,这个是gitlab的访问域名,因为默认通过nginx进行解析的时候,指向的是你配置的这个域名,并且通过80端口。安装完成后可以看nginx的conf文件。

sudo apt-get install gitlab-ce

3. 启动GitLab

这个会加载所有的配置,启动相应的服务。所以说,和网络上其他的安装教程来比,新版本安装起来实在是太爽了。

sudo gitlab-ctl reconfigure

配置

更换域名

未分类

如上图,域名被替换为域名了,但是之前是字符串git@debian…,因为在安装的时候,蓝色窗口弹出的时候直接按了回车使用了默认值。修改方法如下:

打开配置文件

vim /etc/gitlab/gitlab.rb

找到第7行的external_url将值进行修改后保存

3 ## GitLab URL
4 ##! URL on which GitLab will be reachable.
5 ##! For more details on configuring external_url see:
6 ##! https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab
7 external_url 'http://192.168.186.136'

重新启动gitlab,完成域名修改。

gitlab-ctl reconfigure

添加 ssh 公钥

因为在gitlab上使用git命令进行操作,需要进行身份验证,依赖于ssh公钥,所以需要将ssh公钥加入到自己的配置文件中,

ssh-keygen

下面命令得到的内容就是公钥

cat ~/.ssh/id_rsa.pub

CentOS 7.x上gitlab搭建教程(https可用,邮件可用)

知识要求

  • nginx基础知识

搭建感想

注:以下是我搭建gitlab时的思考,需要nginx的基础知识,Docker的基础知识才容易理解,与下面的搭建过程是独立的,不感兴趣可直接略过。

其实gitlab已经搭建并用了一年多了,现在所有的项目管理都通过gitlab完成。但是一直以来都有2个问题:

  • 80端口被系统的nginx占用了,所以只能监听非80端口;
  • 443端口也被系统的nginx占用,所以也一直没增加对https的支持;

最近正在尝试对所有已有的服务Docker化,一方面想让gitlab的搭建更简单些,另一方面也把这两个问题都处理掉。

于是就做了两个Docker容器: nginx和gitlab,相当于nginx和gitlab运行在局域网的不同主机,所以端口上没冲突。nginx是对外的服务器,它做一层反向代理到gitlab就能让gitlab提供对外的服务。
然而。。。这个做法却带来了一个新问题:gitlab需要的是22,80,443端口,80与443通过反向代理解决了,22却没办法解决。因为正常来讲,宿主机的SSH肯定也在使用,所以gitlab的SSH监听端口映射到宿主机会有冲突。

当然了,解决办法还是有的,不过非常繁琐。我们做Docker的目的不就是为了降低布署难度吗?如果使用Docker的配置比在宿主机上还繁琐,那使用起来就没太大意义了。

于是gitlab就没有放在Docker中,而是直接搭在宿主机上。

搭建过程

安装

gitlab的安装是很简单的,先下载安装包:

wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.2.5-ce.0.el7.x86_64.rpm

安装:

rpm -Uvh gitlab-ce-10.2.5-ce.0.el7.x86_64.rpm

配置

gitlab内置了nginx的服务,所以默认会占用80和443端口。一般来说,我们做WEB开发,服务器上早就安装了nginx或者apache,把80和443端口给占了,所以需要做些修改防止冲突。

简单的修改端口是不可行的,比如80改成85,当查看gitlab项目时,下图中的项目地址会变成http://git.papamk.com:85/papamk/groupbill这样,看着就不舒服。启用https则在使用过程中则会出现其他的问题。这里不一一论述,直接说明正确的配置方法。

未分类

具体步骤:

1、首先确保你的服务器已经有运行nginx,并且该nginx监听宿主机的80和443端口。(如果你原来使用的apache,请通过nginx反向代理到apache,这样apache原来的服务仍然可用)。

2、编辑/etc/gitlab/gitlab.rb:

# 编辑对外的域名(gitlab.papamk.com请添加A记录指向本服务器的公网IP):
external_url 'http://gitlab.papamk.com/'

# 禁用`gitlab`内置的`nginx`:
nginx['enable'] = false
# 修改成与nginx运行时的用户一致
web_server['external_users'] = ['www']

修改监听方式和监听地址(如果nginx与gitlab都在宿主机上,不用改也行;如果nginx在docker中,则需要修改)

gitlab_workhorse['listen_network'] = "tcp"
# 下面的172.18.147.173为本机IP,根据实际情况修改,不能为localhost或者127.0.0.1,否则docker访问不到
gitlab_workhorse['listen_addr'] = "172.18.147.173:8181" 

最后执行下面命令让配置生效:

$gitlab-ctl reconfigure

3、配置nginx

增加gitlab.conf的配置(所有需要注意的地方都加了中文注释):

upstream gitlab-workhorse {
  server 172.18.147.173:8181; #根据实际情况修改
}

## Normal HTTP host
server {
  listen 80;
  listen [::]:80 default_server;
  server_name gitlab.papamk.com; ## 修改成自己的域名;
  server_tokens off; ## Don't show the nginx version number, a security best practice
  root /opt/gitlab/embedded/service/gitlab-rails/public;

  ## See app/controllers/application_controller.rb for headers set

  ## Individual nginx logs for this GitLab vhost
  access_log  /home/wwwlogs/gitlab_access.log; # 根据实际情况修改
  error_log   /home/wwwlogs/gitlab_error.log; # 根据实际情况修改

  location / {
    client_max_body_size 0;
    gzip off;

    ## https://github.com/gitlabhq/gitlabhq/issues/694
    ## Some requests take more than 30 seconds.
    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;

    proxy_http_version 1.1;

    proxy_set_header    Host                $http_host;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   $scheme;

    proxy_pass http://gitlab-workhorse;
  }
}

该配置根据官网提供的配置修改而来: https://gitlab.com/gitlab-org/gitlab-recipes/blob/master/web-server/nginx/gitlab-omnibus-nginx.conf。

重启nginx:

$sudo service nginx restart

4、登陆浏览器,这时可以看到安装成功了,如下图所示:

首次登陆会要求重置管理员密码,管理员的默认用户名为root。

未分类

https的支持

1、使用Let’s encrypt申请免费的SSL证书,该项目提供了一个叫certbot/certbot-auto的工具获取证书,执行下面命令获取工具:

$wget https://dl.eff.org/certbot-auto
$chmod +x certbot-auto

执行下面命令生成生成gitlab.papamk.com的证书,其中–agree-tos表示同意协议,–email [email protected]为自己的email。

$./certbot-auto --agree-tos --email [email protected] certonly --webroot -w /opt/gitlab/embedded/service/gitlab-rails/public/ -d gitlab.papamk.com 

执行成功后,可通过以下命令查看下证书位置,nginx需要引用这些文件。(一般位于/etc/letsencrypt/live/gitlab.papamk.com/目录)

$./certbot-auto certificates

2、修改/etc/gitlab/gitlab.rb,对外的URL改为https:

external_url 'https://gitlab.papamk.com'

执行重新配置命令以便让新配置生效:

$gitlab-ctl reconfigure

3、修改前面的nginx的gitlab.conf的配置,全部替换成下面的内容(所有需要注意的地方都加了中文注释):

upstream gitlab-workhorse {
  server 172.18.147.173:8181; #根据实际情况修改
}
## Redirects all HTTP traffic to the HTTPS host
server {
  ## Either remove "default_server" from the listen line below,
  ## or delete the /etc/nginx/sites-enabled/default file. This will cause gitlab
  ## to be served if you visit any address that your server responds to, eg.
  ## the ip address of the server (http://x.x.x.x/)
  listen 0.0.0.0:80;
  listen [::]:80 ipv6only=on default_server;
  server_name gitlab.papamk.com; ## 改成自己的域名
  server_tokens off; ## Don't show the nginx version number, a security best practice
  return 301 https://$http_host$request_uri;
  access_log  /home/wwwlogs/gitlab_access.log; # 根据实际情况修改
  error_log   /home/wwwlogs/gitlab_error.log; # 根据实际情况修改
}
## HTTPS host
server {
  listen 0.0.0.0:443 ssl;
  listen [::]:443 ipv6only=on ssl default_server;
  server_name gitlab.papamk.com; ## 改成自己的域名
  server_tokens off; ## Don't show the nginx version number, a security best practice
  root /opt/gitlab/embedded/service/gitlab-rails/public;

  ## Strong SSL Security
  ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
  ssl on;
  ssl_certificate /etc/letsencrypt/live/gitlab.papamk.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/gitlab.papamk.com/privkey.pem;

  # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
  ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 5m;

  ##   sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
  # ssl_dhparam /etc/ssl/certs/dhparam.pem;

  access_log  /home/wwwlogs/gitlab_access.log; # 根据实际情况修改
  error_log   /home/wwwlogs/gitlab_error.log; # 根据实际情况修改
  location / {
    client_max_body_size 0;
    gzip off;

    ## https://github.com/gitlabhq/gitlabhq/issues/694
    ## Some requests take more than 30 seconds.
    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;

    proxy_http_version 1.1;

    proxy_set_header    Host                $http_host;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-Ssl     on;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   $scheme;
    proxy_pass http://gitlab-workhorse;
  }
}

重启nginx:

$sudo service nginx restart

4、定期更新ssl证书

Let’s encrypt提供的证书,有效期为90天,到期后执行如下命令即可继续使用:

$./certbot-auto renew

将该命令加入到crontab,每小时刷新一次,就不用担心过期了。先将该命令移到系统目录下:

$sudo mv certbot-auto /usr/bin/certbot-auto

然后执行crontab -e,添加一行:

0 */1 * * *  /usr/bin/certbot-auto renew

发送邮件的支持

官网已经给出详细的配置说明和各大邮件服务提供商的示例,不再对配置做说明:
https://docs.gitlab.com/omnibus/settings/smtp.html。

我自己使用163邮箱做测试,而官网示例没有,这里给出参考配置:

gitlab_rails['gitlab_email_from'] = '[email protected]' # 替换成实际的email
gitlab_rails['smtp_enable'] = true                                                      
gitlab_rails['smtp_address'] = "smtp.163.com"                                          
gitlab_rails['smtp_port'] = 465                                                        
gitlab_rails['smtp_user_name'] = "[email protected]" # 替换成实际的email                               
gitlab_rails['smtp_password'] = "xxx"  # 替换成实际的密码                                          
#gitlab_rails['smtp_domain'] = "163.com"                                                
gitlab_rails['smtp_authentication'] = "login"                                          
gitlab_rails['smtp_enable_starttls_auto'] = true                                        
gitlab_rails['smtp_tls'] = true 

一般来说,服务提供商的SMTP邮箱都会限制每日发送次数(250封左右),所以推荐有兴趣的同学用Postfix自建邮箱服务器,或者使用mailgun这种专业的邮件服务提供商。

如果是阿里云上的服务器,作为客户端使用第三方的SMTP配置,会发现被禁止连接SMTP的25端口,需要使用465或者587。

安全相关

  • root的密码建议设置得复杂些;

  • 管理员登陆后,推荐开启注册邮箱验证, 防恶意注册,见:https://docs.gitlab.com/ce/security/user_email_confirmation.html。

Gitlab重置用户密码

自建的Gitlab服务器在阿里云上,阿里云默认屏蔽了对外的25端口连接。每添加新用户,就会反馈重置密码的邮件收不到。解决方法是登录到服务器上用mailq命令找到邮件ID,接着用postcat命令找出链接发给对方完成密码重置工作。

这次的新用户比较奇怪(也可能是gitlab升级),使用postcat获取到的链接无效,无法重置密码。为了让其正常使用,先从管理员身份切换过去并添加SSH公钥。

事后为了解决这个问题,暂时想到两个办法:1. 使用海外的服务器;2. 使用465等SSL加密端口。第一个方法作为备选方案,优先考虑了第二种方案。遗憾的是按照官方文档配置,Gitlab不屈不挠的使用sendmail而非SMTP方式发送邮件。折腾了一个多小时还没弄好,有点心累。

快要放弃的时候转念一想,我需要的是重置密码功能,邮件先放一边吧!于是开始寻找重置用户密码方法,该过程可谓是轻松加愉快,很快就重置了用户的密码。

具体步骤如下:

# 进入gitlab控制台
gitlab-rails console
# 找出用户并重置密码
user = User.find_by(email: '[email protected]')
user.password='1234ABCD'
user.password_confirmation='1234ABCD'
user.save!
# 退出控制台
exit

输出内容示例如下:

[root@localhost gitlab]# gitlab-rails console
Loading production environment (Rails 4.2.8)
irb(main):001:0> user = User.find_by(email: '[email protected]')
=> #<User id:12 @foo>
irb(main):002:0> user.password='1234ABCD'
=> "1234ABCD"
irb(main):003:0> user.password_confirmation='1234ABCD'
=> "1234ABCD"
irb(main):004:0> user.save!
Enqueued ActionMailer::DeliveryJob (Job ID: ea0072d2-5cd5-4b6e-bdad-fa938d977e47) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", gid://gitlab/User/12
=> true

自动化部署之gitlab权限管理–issue管理

1、创建Group,User,Project

创建一个组,组名为java

Group path http://192.168.56.11/java
Visibility Level:    #为权限级别,一般使用Private
Private
Internal
Public

创建一个PM的用户作为项目管理者并加入到java组内

未分类

创建一个项目:

未分类

创建dev1和dev2的用户作为开发者,并加入到项目中

未分类

2、测试dev1,dev2拉取代码库

(1)生成ssh-key

[root@linux-node1 ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Hf3O9F7sS9N04cFUr3Awb/Wec28gTpHYyRZMCzLW9q0 root@linux-node1
The key's randomart image is:
+---[RSA 2048]----+
|        +..o=  .+|
|       . oo*.Oo.o|
|         .o.@.++o|
|         . o.*oo+|
|        S . o.=+=|
|           oE= =*|
|            . ooB|
|              .+o|
|               .+|
+----[SHA256]-----+
[root@linux-node1 ~]# cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLDVIqTAvJtj8Uc+SvhcKOKuDtURt3YBxHo9enUkDjOWtSygLZI4hSrEsnvjHdnxeBGOgjPrxEfMMdNCno4pox7V/8bIU9LRVp2eeQFS+N+bSmbJlTKyODa0tabPwT7URYoiFI3giQamQdA0AwwPCPM/RcXwHJsw4q0O/2woCqNKq2tHaUFBqojd2KvqavzpB+4+AdKJSoabwLhE8dzfjIR/eHY31Y2C/+m9sU504v+R0GsAqr5uifi6Ct9eFvumI54BvHssIpZFZmADTT35b1aP0WSwZb2VEhXjaia8L6h/6ANn1NuHGgYZqNiYT6JILESKbrc7PyJOn9DfHKSMq9 root@linux-node1


(2)将公钥(id_rsa.pub)放进dev1账户中
在admin账户下给dev1,dev2账户设置密码,然后使用dev1登录gitlab,做如下操作添加ssh-key:
测试是否能正常拉取代码库app1

[root@linux-node1 ~]# git clone [email protected]:java/app1.git
Cloning into 'app1'...
The authenticity of host '192.168.56.11 (192.168.56.11)' can't be established.
ECDSA key fingerprint is SHA256:p2lhKmsPQ6K+dWHHvbJg0GV+Ni9VM7vlViKrYsZLP1s.
ECDSA key fingerprint is MD5:22:14:1c:37:de:47:1c:4a:2f:88:b1:dc:e2:d0:02:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.11' (ECDSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
[root@linux-node1 ~]# ll
total 6804
-rw-------.  1 root root     948 Dec  3 01:21 anaconda-ks.cfg
drwxr-xr-x   3 root root      17 Dec 20 15:00 app1
drwxr-xr-x  22 root root   24576 Dec  8 22:16 git-2.7.4
drwxr-xr-x   3 root root      65 Dec  9 01:23 test
-rw-r--r--   1 root root 6918037 Dec  8 22:09 v2.7.4.zip
[root@linux-node1 ~]# cd app1
[root@linux-node1 app1]# ll
total 4
-rw-r--r-- 1 root root 19 Dec 20 15:05 readme

未分类

到此,Linux环境下完成了gitlab的授权管理代码库。

下面以PM用户进行创建开发计划
开发一个官网V1.0版本,包含首页和新闻

(1)创建里程碑(Milestone)

未分类

(2)依次把任务首页,新闻添加到里程碑,并进行任务分配给开发者

未分类

(3)使用dev1用户登录查看,会有任务提示,如图:

未分类

(4)dev1开发者收到任务,进行开发

[root@linux-node1 app1]# git checkout -b shouye    #创建首页分支
Switched to a new branch 'shouye'
[root@linux-node1 app1]# git status
On branch shouye
nothing to commit, working directory clean
[root@linux-node1 app1]# echo "<h1> welcome to www.123.com" > index.html    #进行开发
[root@linux-node1 app1]# ll
total 8
-rw-r--r-- 1 root root 28 Dec 20 15:50 index.html
-rw-r--r-- 1 root root 19 Dec 20 15:05 readme
[root@linux-node1 app1]# git add .
[root@linux-node1 app1]# git commit -m "shouye"    #开发完成,提交本地仓库
[shouye babdcb5] shouye
 1 file changed, 1 insertion(+)
 create mode 100644 index.html
[root@linux-node1 app1]# git push origin shouye    #提交到远程库
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 292 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: 
remote: To create a merge request for shouye, visit:
remote:   http://192.168.56.11/java/app1/merge_requests/new?merge_request%5Bsource_branch%5D=shouye
remote: 
To [email protected]:java/app1.git
 * [new branch]      shouye -> shouye

可以看到有刚才创建的分支,点击”merge request”合并分支请求,之后PM用户登录处理合并请求。此时,一个功能的开发流程就完成。

未分类

未分类

总结:

PM在gitlab创建任务,分配给开发人员
开发人员领取任务后,在本地使用git clone拉取代码库
开发人员创建开发分支(git checkout -b dev),并进行开发
开发人员完成之后,提交到本地仓库(git commit )
开发人员在gitlab界面上申请分支合并请求(Merge request)
PM在gitlab上查看提交和代码修改情况,确认无误后,确认将开发人员的分支合并到主分支(master)
开发人员在gitlab上Mark done确认开发完成,并关闭issue。这一步在提×××并请求时可以通过描述中填写”close #1″等字样,可以直接关闭issue。

用 Docker Compose 搭建 Rails 开发环境

Docker 是目前最热门的容器格式,Docker Compose 是用于管理包含多个 Docker 容器的应用的工具,借助 Docker 和 Docker Compose,我们可以轻松搭建可复现的开发环境。

这篇教程展示如何从零开始用 Docker Compose 搭建 Rails/PostgreSQL 开发环境。

本文主要参考了 Quickstart: Compose and Rails。但原文有一点问题,于是我加上自己的见解写成这篇博客。

安装 Docker

首先,需要在自己的开发机上安装 Docker,你可以在 https://www.docker.com/ 找到适合自己操作系统的 Docker 安装方式。

安装完毕后,可以在命令行中使用 docker 命令:

$ docker --version
Docker version 17.03.1-ce, build c6d412e

创建项目

创建项目目录:

$ mkdir myapp
$ cd myapp

接着,创建一个 Gemfile 文件,包含以下内容:

source 'https://rubygems.org'

gem 'rails', '5.1.0.rc2'

然后,创建一个空的 Gemfile.lock 文件:

$ touch Gemfile.lock

之所以这么做,是因为不希望在主机环境安装 Ruby 和其它依赖,而是都放到镜像中。这两个文件用于在镜像中安装 Rails。

接着,创建一个 Dockerfile 文件,该文件用于定义如何构建 Rails 镜像:

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y curl apt-transport-https && 
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && 
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -y 
  build-essential 
  libpq-dev 
  nodejs 
  ruby 
  ruby-dev 
  tzdata 
  yarn 
  zlib1g-dev

WORKDIR /app

RUN gem install bundler
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app

这个 Dockerfile 基于 Ubuntu 16.04,安装了创建 Rails 项目所需要的基础包,并将项目目录设定在 /app。你可以阅读 https://docs.docker.com/ 学习怎么定制 Dockerfile。

然后,创建一个 docker-compose.yml 文件,该文件用于定义 docker-compose 如何启动应用:

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b 0.0.0.0
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
  db:
    image: postgres

在这个文件里,我们定义了两个服务。web 服务用于运行 Rails,镜像将根据当前目录的 Dockerfile 构建;db 服务用于运行 PostgreSQL 进程,镜像使用 Docker 官方提供的 postgres。你可以在 https://docs.docker.com/compose/compose-file/ 找到其它配置的定义。

接下来,执行以下命令:

$ docker-compose run web rails new . --force --database=postgresql

该命令会在当前目录创建 Rails 项目:

$ ls -l
total 72
-rw-r--r--   1 rei  staff   522  4 25 22:59 Dockerfile
-rw-r--r--   1 rei  staff  1989  4 25 23:02 Gemfile
-rw-r--r--   1 rei  staff  4847  4 25 23:03 Gemfile.lock
-rw-r--r--   1 rei  staff   374  4 25 23:02 README.md
-rw-r--r--   1 rei  staff   227  4 25 23:02 Rakefile
drwxr-xr-x  10 rei  staff   340  4 25 23:02 app
drwxr-xr-x   9 rei  staff   306  4 25 23:03 bin
drwxr-xr-x  14 rei  staff   476  4 25 23:02 config
-rw-r--r--   1 rei  staff   130  4 25 23:02 config.ru
drwxr-xr-x   3 rei  staff   102  4 25 23:02 db
-rw-r--r--   1 rei  staff   206  4 25 22:59 docker-compose.yml
drwxr-xr-x   4 rei  staff   136  4 25 23:02 lib
drwxr-xr-x   3 rei  staff   102  4 25 23:02 log
-rw-r--r--   1 rei  staff    61  4 25 23:02 package.json
drwxr-xr-x   9 rei  staff   306  4 25 23:02 public
drwxr-xr-x  11 rei  staff   374  4 25 23:02 test
drwxr-xr-x   4 rei  staff   136  4 25 23:02 tmp
drwxr-xr-x   3 rei  staff   102  4 25 23:02 vendor

接着,重建 Docker 镜像:

$ docker-compose build

每当修改了 Dockerfile,你都需要重建镜像。如果修改了 Gemfile,还需要先在容器内运行 bundle,然后重建镜像:

$ docker-compose run web bundle
$ docker-compose build

连接数据库

现在我们已经可以让 Rails 跑起来,但还需要修改一些配置让 Rails 连上数据库。默认情况下,Rails 的 development 和 test 环境会连接 localhost 主机上的数据库,根据之前的 docker-compose.yml 配置,我们需要将数据库的主机名改为 db。另外,还需要修改 username 以适配 postgres 镜像的默认配置。修改后的 database.yml 配置如下:

development:
  <<: *default
  database: app_development
  host: db
  username: postgres

test:
  <<: *default
  database: app_test
  host: db
  username: postgres

现在可以启动 Rails 进程了:

$ docker-compose up

如果一切正常,你会看到一些 postgres 的日志,然后是 Rails 启动日志:

web_1  | => Booting Puma
web_1  | => Rails 5.1.0.rc2 application starting in development on http://0.0.0.0:3000
web_1  | => Run `rails server -h` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 3.8.2 (ruby 2.3.1-p112), codename: Sassy Salamander
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

如果你需要运行数据库迁移,可以打开另一个终端运行:

$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

TIP: 以后运行 rails 命令,都需要在前面加上 docker-compose run web。

用浏览器访问 http://localhost:3000 ,你会看到 Rails 的欢迎信息:

未分类

将 Dockerfile docker-compose.yml 与项目文件一并提交到版本控制里,这样新开发者参与项目的时候就可以用 docker-compose up 一键启动开发环境。

mint 18.2(Sonya)安装docker

与ubuntu安装大体一致,参考官网提供的ubuntu安装方式
官方安装 https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/

安装步骤

1、删除原有版本

sudo apt-get remove docker docker-engine docker.io

2、(推荐略过这一步) 现在docker默认的文件系统为overlay2,如果需要使用aufs(早期docker的文件系统),请执行以下命令

sudo apt-get update
sudo apt-get install 
    linux-image-extra-$(uname -r) 
    linux-image-extra-virtual

3、安装docker ce

docker-ce 是docker的社区版,免费使用,有三种方式安装

  • 添加源,使用apt-get安装
  • 下载deb包,使用dpkg安装
  • 使用提供的脚本安装
    这里选择第一种安装方式

使用apt-get安装

安装需要的工具,

sudo apt-get update
sudo apt-get install 
    apt-transport-https 
    ca-certificates 
    curl 
    software-properties-common

添加认证,

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

根据你的硬件架构选择相应的源进行添加,测试机器为amd64架构,docker支持amd64,armhf,s390x等方式,其余架构添加方式参考官网
下面命令中$(lsb_release -cs)查看系统codename,mint基于ubuntu,使用ubuntu的软件源 ,
所以将

sudo add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
   $(lsb_release -cs) 
   stable"

替换为 xenial ,执行以下替代命令

sudo add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
   xenial 
   stable"

更新软件源

sudo apt-get update

测试环境直接安装最新版docker-ce

sudo apt-get install docker-ce

如果是正式环境,可能需要安装指定版本的

sudo apt-get install docker-ce=<VERSION>

如果没有报错,那就大功告成~
跑个hello world

sudo docker run hello-world
Unable to find image ‘hello-world:latest’ locally 
latest: Pulling from library/hello-world 
9a0669468bf7: Pull complete

说明已经获取到官方仓库里的镜像啦~

权限问题

因为安装都是使用sudo即root权限安装,使用的时候,如果没有root权限会提示

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: 巴拉巴拉

/var/run/docker.sock 作用

它是Docker守护进程(Docker daemon)默认监听的Unix域套接字(Unix domain socket),容器中的进程可以通过它与Docker守护进程进行通信 .
把自己加到docker组

sudo usermod -a -G docker $(whoami)

完全退出当前登录用户,使修改生效

安装docker-compose

docker-compose 是个官方提供管理镜像的工具,对镜像进行一些编排,减化docker使用命令等功能  
官方安装:https://docs.docker.com/compose/install/

下载二进制包,可以直接从github获取,参考下面命令,
其中1.18.0 是截止到文章发布日期的最新版本,具体版本后,点击链接查询

sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

添加执行权限

sudo chmod +x /usr/local/bin/docker-compose

大功告成

docker-compose --version
# docker-compose version 1.18.0, build 8dd22a9

.NET Core容器化之多容器应用部署@Docker-Compose

未分类

1. 引言

紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理,然后再介绍多容器应用的部署问题。

2. Why Need Nginx

.NET Core中默认的Web Server为Kestrel。

Kestrel is great for serving dynamic content from ASP.NET, however the web serving parts aren’t as feature rich as full-featured servers like IIS, Apache or Nginx. A reverse proxy-server can allow you to offload work like serving static content, caching requests, compressing requests, and SSL termination from the HTTP server.

Kestrel可以很好的用来为ASP.NET提供动态内容,然而在Web服务方面没有IIS、Apache、Nginx这些全功能的服务器完善。我们可以借助一个反向代理服务器接收来自互联网的HTTP请求并在经过一些初步处理(比如请求的缓存和压缩、提供静态内容、SSL Termination)后将其转发给Kestrel。

未分类

未分类

借助反向代理服务器(本文使用Nginx),不仅可以给我们的Web网站提供了一个可选的附加层配置和防御,而且可以简化负载均衡和SSL设置。而更重要的是,反向代理服务器可以很好的与现有的基础设施进行整合。

3. Hello Nginx

同样我们还是基于Docker来试玩一下Nginx。

//拉取Nginx镜像
$ docker pull nginx
//启动Nginx容器
$ docker run -d -p 8080:80 --name hellonginx nginx

上面我们以后台运行的方式启动了一个命名为hellonginx的nginx容器,其端口映射到宿主机的8080端口,我们现在可以通过浏览器直接访问http://:8080即可看到nginx的欢迎界面。

未分类

至此,一个Nginx容器就启动完毕了。那如何进行反向代理呢?别急,我们一步一步来。

4. 反向代理.NET Core MVC

4.1. 启动Web容器

还记得我们上一篇本地打包MVC项目创建的hellodocker.web的镜像吗?这里我们再启动该镜像创建一个容器:

//启动一个helodocker.web的镜像并命名容器为hellodocker.web.nginx
#  docker run -d -p 5000:5000 --name hellodocker.web.nginx hellodocker.web
160166b3556358502a366d1002567972e242f0c8be3a751da0a525f86c124933
//尝试访问刚刚运行的容器
[root@iZ288a3qazlZ ~]# curl -I http://localhost:5000
HTTP/1.1 200 OK
Date: Sun, 24 Dec 2017 02:48:16 GMT
Content-Type: text/html; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked

OK,我们开放了宿主机的5000端口用来映射我们启动的MVC容器。

4.2. 配置反向代理

下面我们就来配置Nginx来反向代理我们刚启动的Web容器。
要想Nginx成功代理指定的容器内运行的Web网站,首先我们得知道容器对应的IPAddress。使用docker inspect 即可查到。

//查看正在运行的容器列表
$ docker ps 
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                            NAMES
d046b7b878a0        hellodocker.web                "dotnet run"             5 seconds ago       Up 3 seconds        0.0.0.0:5000->5000/tcp           hellodocker.web.nginx

//使用`|`管道操作符加上`grep`过滤操作符可以直接提取我们要查找的关键字
$ docker inspect hellodocker.web.nginx | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "192.168.0.5",
                    "IPAddress": "192.168.0.5",

从上面可以看到我的Web容器运行在宿主机的192.168.0.5:5000。下面我们配置Nginx转发请求到192.168.0.5:5000即可完成反向代理。

Nginx配置反向代理的配置文件路径为:/etc/nginx/conf.d/default.conf。
我们可以通过本地创建一个配置文件挂载到Nginx的容器内部进行反向代理配置。

$ cd demo
$ mkdir nginx
//创建my_nginx.conf文件
$ touch my_nginx.conf
$ vi my_nginx.conf
server {
  listen 80;

  location / {
    proxy_pass http://192.168.0.5:5000;
  }
}

上面我们通过指定listen配置nginx去监听80端口,指定proxy_pass为我们Web容器的IP和端口完成反向代理文件的配置。
接下来就是启动一个新的Nginx容器并通过挂载的方式将配置文件共享到容器内部。

$ docker run -d -p 8080:80 
> -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf 
> nginx
95381aa56a336f65b6d01ff9964ae3364f37d25e5080673347c1878b3a5bb514
/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint elated_mccarthy (5a576d5991dd164db69b1c568c94c15e47ec7c67e43a3dd6982a2e9b83b60e08): Bind for 0.0.0.0:8080 failed: port is already allocated.

我们发现容器启动失败,原因是8080端口被我们刚刚第一次启动的nginx容器占用了。怎么办?两个方法:第一种就是将刚才创建的nginx容器干掉;第二种就是映射到新的端口。这里选择第一种。

$ docker ps
1bd630b60019        nginx                          "nginx -g 'daemon off"   59 minutes ago      Up 59 minutes       0.0.0.0:8080->80/tcp             hellonginx
//使用docker rm <container id>删除容器,指定-f进行强制删除
$ docker rm 1bd630b60019 -f
//重新启动Nginx容器
$ docker run -d -p 8080:80 
> -v $HOME/demo/nginx/my_nginx.conf:/etc/nginx/conf.d/default.conf 
> nginx
793d4c62ec8ac4658d75ea0ab4273a0b1f0a9a68f9708d2f85929872888b121d

启动成功后,我们再在浏览器中访问http://:8080,发现返回的不再是Nginx的默认欢迎页,而是我们启动的Web容器中运行的MVC的首页,说明反向代理配置成功!

未分类

5. Docker Compose让一切更简单

上面的步骤虽然简单,但要分两步进行:第一个就是我们的Web和Nginx要分两次部署,第二个就是我们必须知道Web容器的IP和端口号,以完成反向代理文件的配置。

对于需要多个容器(比如需要Nginx、SqlServer、Redis、RabbitMQ等)协调运行的复杂应用中,使用以上方式进行部署时,很显然会很麻烦,而且还要为各个容器之间的网络连接而苦恼。
还好,Docker体贴的为我们想到了这一点。借助Compose模块,我们可以编写一个docker-compose.yml文件,使用声明性语法启动一系列相互连接的容器,即可一步完成上面的任务。

Docker Compose是一个用来定义和运行复杂应用的Docker工具。使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

5.1. 安装Docker Compose

依次执行以下命令:

$ sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.18.0, build 1719ceb

5.2. 编写第一个docker-compose.yml

dockers-compose.yml文件要定义在我们项目的文件夹下,我们的项目文件夹位于$HOME/demo/HelloDocker.Web。

$ cd $HOME/demo/HelloDocker.Web
$ touch docker-compose.yml
$ vi docker-compose.yml
version: '2'
services:
    hellodocker-web:
        container_name: hellodocker.web.compose
        build: .

    reverse-proxy:
        container_name: reverse-proxy
        image: nginx
        ports:
         - "9090:8080"
        volumes:
         - ./proxy.conf:/etc/nginx/conf.d/default.conf

简单介绍下上面的配置文件,其中定义了两个服务:一个是hellodocker-web,即以我们当前项目目录来构建镜像并启动一个叫hellodocker.web.compose的容器。一个是reverse-proxy,用来使用nginx镜像进行反向代理,其中又通过指定volumes来使用挂载的方式进行配置。

$ touch proxy.conf
$ vi proxy.conf
server {
    listen 8080;

    location / {
      proxy_pass http://hellodocker-web:5000;
    }
}
$ ls
[root@iZ288a3qazlZ HelloDocker.Web]# ls
appsettings.Development.json  Controllers             Models      Startup.cs
appsettings.json              docker-compose.yml      obj         Views
bin                           Dockerfile              Program.cs  wwwroot
bundleconfig.json             HelloDocker.Web.csproj  proxy.conf
[root@iZ288a3qazlZ HelloDocker.Web]#

其中要注意反向代理的配置:proxy_pass http://hellodocker-web:5000;,其中ip部分直接指定的是docker-compose.yml中定义的第一个服务的名称hellodocker-web。
下面我们就来启动Compose:

$ docker-compose up -d
Building hellodocker-web
Step 1 : FROM microsoft/dotnet:latest
 ---> 7d4dc5c258eb
Step 2 : WORKDIR /app
 ---> Using cache
 ---> 98d48a4e278c
Step 3 : COPY . /app
 ---> 0cb9fc540afe
Removing intermediate container 9fecf088f03f
Step 4 : RUN dotnet restore
 ---> Running in 4bb7f34edbbe
  Restore completed in 597.13 ms for /app/HelloDocker.Web.csproj.
  Restoring packages for /app/HelloDocker.Web.csproj...
  Restore completed in 1.76 sec for /app/HelloDocker.Web.csproj.
 ---> 6869609ece23
Removing intermediate container 4bb7f34edbbe
Step 5 : EXPOSE 5000
 ---> Running in a97febf01e5a
 ---> 9b2639862a94
Removing intermediate container a97febf01e5a
Step 6 : ENV ASPNETCORE_URLS http://*:5000
 ---> Running in 4e2f4af28a8d
 ---> 0069661e891a
Removing intermediate container 4e2f4af28a8d
Step 7 : ENTRYPOINT dotnet run
 ---> Running in cbbf08d906f9
 ---> 0bbeef249b30
Removing intermediate container cbbf08d906f9
Successfully built 0bbeef249b30
WARNING: Image for service hellodocker-web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating hellodocker.web.compose ... done
Starting reverse-proxy ... done
//执行docker-compose ps验证启动的服务
$ docker-compose ps
         Name                   Command          State               Ports
---------------------------------------------------------------------------------------
hellodocker.web.compose   dotnet run             Up      5000/tcp
reverse-proxy             nginx -g daemon off;   Up      80/tcp, 0.0.0.0:9090->8080/tcp
//使用curl指令验证nginx的反向代理
$  curl -I http://localhost:9090
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Sun, 24 Dec 2017 04:37:35 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive

可以看到,通过执行curl -I http://localhost:9090验证代理服务器配置成功,我们再通过浏览器访问http://:9090发现正确返回了我们MVC项目的默认首页。

// 查看当前运行的容器
$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                            NAMES
a52830499cff        hellodockerweb_hellodocker-web   "dotnet run"             7 minutes ago       Up 7 minutes        5000/tcp                         hellodocker.web.compose
e1fe109e10bc        nginx                            "nginx -g 'daemon off"   11 minutes ago      Up 4 minutes        80/tcp, 0.0.0.0:9090->8080/tcp   reverse-proxy

我们同时也发现通过docker-compose正确的创建了两个容器hellodocker.web.compose和reverse-proxy。

6. 最后

经过以上的练习,我们对Nginx有了一定的了解,且知道如何进行配置。同时了解了如何借助docker-compose打包运行需要多容器的复杂应用。

使用 logstash + kafka + elasticsearch 实现日志监控

在本文中,将介绍使用 logstash + kafka + elasticsearch 实现微服务日志监控与查询。

服务配置

添加 maven 依赖:

<dependency>
   <groupId>org.apache.kafka</groupId>
   <artifactId>kafka-clients</artifactId>
   <version>1.0.0</version>
</dependency>

添加 log4j2 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <Kafka name="Kafka" topic="mcloud-log">
      <PatternLayout pattern="%date %message"/>
      <Property name="bootstrap.servers">localhost:9092</Property>
    </Kafka>
  </Appenders>
  <Loggers>
    <Root level="debug">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="Kafka"/>
    </Root>
    <Logger name="org.apache.kafka" level="INFO" />
  </Loggers>
</Configuration>

系统配置

Zookeeper-3.4.10

官网: http://zookeeper.apache.org/doc/current/zookeeperStarted.html#sc_InstallingSingleMode

添加配置

在 conf 目录下创建配置文件 zoo.cfg , 并在其中添加以下内容:

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181

启动 ZooKeeper

windows:

bin/zkServer.bat start

Kafka_2.11-1.0.0

官网: http://kafka.apache.org/quickstart

修改日志存储位置

config/server.properties

log.dirs=D:/kafka-logs

启动 Kafka

windows:

bin/windows/kafka-server-start.bat config/server.properties

注:

如果在启动的时候出现以下错误:

错误: 找不到或无法加载主类

需要手动修改 bin/windows/kafka-run-class.bat ,找到以下的代码:

set COMMAND=%JAVA% %KAFKA_HEAP_OPTS% %KAFKA_JVM_PERFORMANCE_OPTS% %KAFKA_JMX_OPTS% %KAFKA_LOG4J_OPTS% -cp %CLASSPATH% %KAFKA_OPTS% %*

将其中的 %CLASSPATH% 添上双引号 => “%CLASSPATH%” 。

Elasticsearch-6.1.1

官网: https://www.elastic.co/downloads/elasticsearch

安装 x-pack

bin/elasticsearch-plugin install x-pack

新增用户:

bin/users useradd mcloud-user

修改角色:

bin/users roles -a logstash_admin mcloud-log-user

注:

系统内置角色:

Known roles: [kibana_dashboard_only_user, watcher_admin, logstash_system, kibana_user, machine_learning_user, remote_monitoring_agent, machine_learning_admin, watcher_user, monitoring_user, reporting_user, kibana_system, logstash_admin, transport_client, superuser, ingest_admin]

启动服务

bin/elasticsearch.bat

Kibana-6.1.1

官网: https://www.elastic.co/downloads/kibana

安装 x-pack

bin/kibana-plugin.bat install x-pack

启动服务

bin/kibana.bat

Logstash-6.1.1

官网: https://www.elastic.co/downloads/logstash

创建配置文件

文档: https://www.elastic.co/guide/en/logstash/current/input-plugins.html

config/logstash.conf

input {     
    logstash-input-kafka {
        topics => ["mcloud-log"]
    } 
}
output {
  elasticsearch { 
    hosts => ["localhost:9200"] 
    user => "mcloud-user"
    password => 123456
  }
}

最终效果

相关服务启动完成后, 登陆 kibana 管理界面,可以看到以下的效果:

未分类

源码

源码: https://github.com/heyuxian/mcloud

使用 Filebeat 收集日志并提交到 logstash 中

安装 Filebeat

此处只介绍 Windows 下面的安装,至于其他系统, 请参考: https://link.jianshu.com/?t=https%3A%2F%2Fwww.elastic.co%2Fguide%2Fen%2Fbeats%2Ffilebeat%2Fcurrent%2Ffilebeat-installation.html

下载并解压后,有两种方式运行,一种是注册为 Windows 服务,另一种是直接通过命令行运行;下面分别介绍两种方式。

注册为 Windows 服务

前提:系统必须有 PowerShell,因为官方安装包中提供的脚本只能在 PowerShell 中运行,若是 win10 系统,可忽略,因为它已经自带了 PowerShell, 否则请下载 PowerShell 并安装。

  1. 下载安装包 点我下载.

  2. 解压到以下目录: C:Program Files 。

  3. 重命名 filebeat–windows 为 Filebeat 。

  4. 以 管理员 身份运行 PowerShell 。

  5. 在 PowerShell 中运行以下命令:

cd 'C:Program FilesFilebeat'
C:Program FilesFilebeat> .install-service-filebeat.ps1

注:

如果此处提示你没有权限,请运行以下的命令注册 Filebeat 服务 :

PowerShell.exe -ExecutionPolicy UnRestricted -File .install-service-filebeat.ps1

到这,已经将 Filebeat 成功注册为系统服务,当下一次开机时它会自动启动,当然你也可以手动通过服务控制面板启动它。

通过命令行运行 Filebeat

通过命令行运行 Filebeat 非常简单,只需将 Filebeat 文件解压到某个目录后,通过以下命令运行:

filebeat -e -c filebeat.yml

配置 Filebeat

日志输入配置

Filebeat 使用了安装目录下的 filebeat.yml 文件进行相关配置。此处我们主要会用到以下的配置:

filebeat.prospectors:
- type: log
# 此处需特别注意,官方默认配置为 false,需要修改为 true
  enabled: true
  paths:
  # 此处配置的是需要收集的日志所在的位置,可使用通配符进行配置
    - D:/logs/*.log

日志输出配置

因为我们使用的是 logstash 收集日志,所以得注释掉默认的 elasticsearch 配置,并取消 logstash 的注释,最终的效果为:

#output.elasticsearch:
  # Array of hosts to connect to.
  #hosts: ["localhost:9200"]

  # Optional protocol and basic auth credentials.
  #protocol: "https"
  #username: "elastic"
  #password: "changeme"
output.logstash:
  # The Logstash hosts
  hosts: ["localhost:5044"]

  # Optional SSL. By default is off.
  # List of root certificates for HTTPS server verifications
  #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]

  # Certificate for SSL client authentication
  #ssl.certificate: "/etc/pki/client/cert.pem"

  # Client Certificate Key
  #ssl.key: "/etc/pki/client/cert.key"

此处仅介绍了最基础的配置,如需查看更多高级配置,请查看:官方文档

关于 Filebeat 的配置已经介绍完毕,下面我介绍 log4j2 的配置。

配置 Log4j2

因为我们使用的是 Filebeat 进行日志收集,所以我们只需要简单的将日志输出到本地文件中即可,这里我将使用 RollingFile 进行相关配置:

log4j-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Properties>
    <Property name="pattern" value="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  </Properties>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="${pattern}"/>
    </Console>
    <RollingFile name="RollingFile" fileName="D:/logs/app.log"
      filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout pattern="${pattern}"/>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
    <Async name="AsyncRollingFile">
      <AppenderRef ref="RollingFile"/>
    </Async>
  </Appenders>
  <Loggers>
    <Root level="DEBUG">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="AsyncRollingFile"/>
    </Root>
  </Loggers>
</Configuration>

配置 logstash

这里我们只需要在加入以下的配置即可:

input {
  beats {
    port => 5044
  }
}

此处的端口需要和 Filebeat 中配置的端口一致。

好了,所有的配置都已经完成,这里就不再重复 kibana 和 elasticsearch 的配置了,如有需要,请查看: https://www.jianshu.com/p/78c5159aace8

运行效果

我们启动其它服务并登陆 kibana 后,就可以看到以下的结果了:

未分类

查看源码

关于 Filebeat 的介绍就到此结束了,关于 logstash 的更多高级功能将在后续文章中一一介绍。

查看源码: https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fheyuxian%2Fmcloud

grep命令实例详解——全局正则表达式输出神器

概述

所有的类linux系统都会提供一个名为grep(global regular expression print,全局正则表达式输出)的搜索工具。grep命令在对一个或多个文件的内容进行基于模式的搜索的情况下是非常有用的。模式可以是单个字符、多个字符、单个单词、或者是一个句子。

当命令匹配到执行命令时指定的模式时,grep会将包含模式的一行输出,但是并不对原文件内容进行修改。

在本文中,我们将会讨论到grep命令实例详解。

实例详解

例1 在文件中查找模式(单词)

在/etc/passwd文件中查找单词linuxtechi

root@Linux-world:~# grep linuxtechi /etc/passwd
linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash
root@Linux-world:~#

例2 在多个文件中查找模式

root@Linux-world:~# grep linuxtechi /etc/passwd /etc/shadow /etc/gshadow
/etc/passwd:linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash
/etc/shadow:linuxtechi:$6$DdgXjxlM$4flz4JRvefvKp0DG6re:16550:0:99999:7:::/etc/gshadow:adm:*::syslog,linuxtechi
/etc/gshadow:cdrom:*::linuxtechi
/etc/gshadow:sudo:*::linuxtechi
/etc/gshadow:dip:*::linuxtechi
/etc/gshadow:plugdev:*::linuxtechi
/etc/gshadow:lpadmin:!::linuxtechi
/etc/gshadow:linuxtechi:!::
/etc/gshadow:sambashare:!::linuxtechi

例3 使用-l参数列出包含指定模式的文件的文件名

root@Linux-world:~# grep -l linuxtechi /etc/passwd /etc/shadow /etc/fstab /etc/mtab
/etc/passwd
/etc/shadow

例4 使用-n参数,在文件中查找指定模式并显示匹配行的行号

root@Linux-world:~# grep -n linuxtechi /etc/passwd
39:linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash

例5 使用-v参数输出不包含指定模式的行

输出/etc/passwd文件中所有不含单词“linuxtechi”的行

root@Linux-world:~# grep -v linuxtechi /etc/passwd

例6 使用^符号输出所有以某指定模式开头的行

Bash脚本将^符号视作特殊字符,用于指定一行或者一个单词的开始。例如输出/etc/passwd文件中所有以“root”开头的行

root@Linux-world:~# grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash

例7 使用$符号输出所有以指定模式结尾的行

输出/etc/passwd文件中所有以bash结尾的行

root@Linux-world:~# grep bash$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash

Bash脚本将美元$符号视作特殊字符,用于指定一行或者一个单词的结尾。

例8 使用-r参数递归地查找特定模式

root@Linux-world:~# grep -r linuxtechi /etc/
/etc/subuid:linuxtechi:100000:65536
/etc/group:adm:x:4:syslog,linuxtechi
/etc/group:cdrom:x:24:linuxtechi
/etc/group:sudo:x:27:linuxtechi
/etc/group:dip:x:30:linuxtechi
/etc/group:plugdev:x:46:linuxtechi
/etc/group:lpadmin:x:115:linuxtechi
/etc/group:linuxtechi:x:1000:
/etc/group:sambashare:x:131:linuxtechi
/etc/passwd-:linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash
/etc/passwd:linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash
............................................................................

上面的命令将会递归的在/etc目录中查找linuxtechi单词

例9 使用grep查找文件中所有的空行

root@Linux-world:~# grep ^$ /etc/shadow

由于/etc/shadow文件中没有空行,所以没有任何输出

例10 使用-i参数查找模式

grep命令的-i参数在查找时忽略字符的大小写。

我们来看一个例子,在passwd文件中查找LinuxTechi单词。

nextstep4it@localhost:~$ grep -i LinuxTechi /etc/passwd
linuxtechi:x:1001:1001::/home/linuxtechi:/bin/bash
nextstep4it@localhost:~$

例11 使用-e参数查找多个模式

例如,我想在一条grep命令中查找linuxtechi和root单词,使用-e参数,我们可以查找多个模式。

root@Linux-world:~# grep -e "linuxtechi" -e "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
linuxtechi:x:1000:1000:linuxtechi,,,:/home/linuxtechi:/bin/bash

例12 使用-f用文件指定待查找的模式

首先,在当前目录中创建一个搜索模式文件grep_pattern,我想文件中输入的如下内容。

root@Linux-world:~# cat grep_pattern
^linuxtechi
root
false$

现在,试试使用grep_pattern文件进行搜索

root@Linux-world:~# grep -f grep_pattern /etc/passwd

未分类

例13 使用-c参数计算模式匹配到的数量

继续上面例子,我们在grep命令中使用-c命令计算匹配指定模式的数量

root@Linux-world:~# grep -c -f grep_pattern /etc/passwd
22

例14 输出匹配指定模式行的前或者后面N行

  • 使用-B参数输出匹配行的前4行
root@Linux-world:~# grep -B 4 "games" /etc/passwd

未分类

  • 使用-A参数输出匹配行的后4行
root@Linux-world:~# grep -A 4 "games" /etc/passwd

未分类

  • 使用-C参数输出匹配行的前后各4行
root@Linux-world:~# grep -C 4 "games" /etc/passwd

未分类

例15 grep搜索目录时,排除某些目录

使用grep搜索目录时,会将一些隐藏目录也给搜进去,比如.git目录,如何在使用grep时排除这些目录

使用 –exclude-dir 选项。

语法

--exclude-dir=DIR
Exclude directories matching the pattern DIR from recursive searches.
  • 单个目录示例
grep -E "http"  ./ -R --exclude-dir=.git
  • 多个目录示例
grep -E "http"  . -R --exclude-dir={.git,res,bin}
  • 多个文件示例排除扩展名为 java 和 js 的文件
grep -E "http"  . -R --exclude=*.{java,js}

例16 使用-L参数列出包含指定模式的文件的文件名

逆转输出,使用-L选项来输出那些不匹配的文件的文件名

grep -L "word" filename
grep -L root /etc/*