陈志军

物来顺应,未来不迎,当时不杂,既过不恋


  • 首页

  • 分类

  • 归档

  • 标签

  • 搜索

Docker Swarm 实践的一些经验总结

发表于 2018-01-08 | 分类于 Docker | 阅读次数

Docker Swarm 实践的一些经验总结

最近弄了一下Docker Swarm。在公司已经把我拉入了黑名单,因为只要我已启动docker公司的mysql就得挂。我也是好奇,正想找问题原因。服务器的密码就已经改了,我是没有机会了。不过在改密码之前,我还是获得一些宝贵的经验,这个我觉得很重要,可以记录下来,自己以后再踩坑的时候可以自己参照下。

环境准备

ubuntu机器一台,centos一台,都安装了docker。docker的版本是Docker version 17.12.0-ce, build c97c6d6。4个spring boot项目:eureka,warehouse,web,booksrv。MySQL使用的是另外一台机器上的安装在hosts(非容器化)。eureka做为注册中心,启动了两个示例。部署方式使用的docker stack。 也有直接使用了docker service。使用了网络overlay,看了网上很多文章,对于网络不太了解就用了原生的,这样方式至少容易理解。创建了overlay网络springcloud-overlay。还是用了java:8-jre-alpine镜像

做了些什么事情

实现了两台机器上的docker容器连通,U机器上的容器,能够访问C机器上的容器。这说明服务容器化是可以实现的。当然我说的是废话,google以及一系列大公司已经完成了k8s的线上实践了。不过我们还是比较小,经验不丰富,所以采用最简单的方式,先跑一下,看能否跑通,之后再说下一步。

实际过程

1. 踩的坑

一开始我是想通过在两台机器上各自暴露eureka端口,然后让eureka互相注册,而在每台机器上都启动容器服务并且注册到每台机器eureka上,这种方式理论模型如下图:

2018-01-08-18-40-02

我们在eureka上是看到了这些服务都有注册到了,而且可以明显看到服务的ip地址是:172.17.0.0/16 区间的。貌似一切很正常,然后我们尝试访问服务,在每个服务日志中基本都是NO instance XXX Exception,不是在eureka已经注册了么,为什么还没有了?eureka应该是根据ip地址加端口来找服务的,这种情况下,如果A服务找到D服务,发现注册中心有注册地址ip,找到了ip地址后(不清楚这里是eureka转发,还是eureka将地址发给A,A再请求),但是根据找到的ip去请求服务,也就是在A服务上去找D的ip地址,因为D在Centos服务器上,所以根本不可能到达。那么请求又怎么可能知道了。明显两者应该在不同的。(突然感觉不对劲,如果两个eureka不能相互注册,注册中心又怎么可能启动多个。。。这里待定,感觉有问题。)再回首想一下,嗯,没问题,我们使用bridge网络的时候,是内网。没错,是内网,我们一般使用eureka都是公网,至少也是两台hosts能够相互连通,在同一个网络下。但是使用docker默认的网络是内网,A机器是无法访问B机器的172.xxx的网络的。

2. swarm方式

在网上找了一圈资料,有在阿里云找到的springcloud项目,并且使用eureka的注册方式,但是他们基于阿里云网络vpc,对于我们不合适,我们是自建机房,尽管没有运维人员去管理。阿里云的方式行不通之后,后来找到swarm,因为我想总有人有这方面(跨主机容器通信)的需求的。刚开始找到了一些是k8s,觉得学习成本有点大,我只是个小java开发,还没强大到那个地步。。。。后来发现swarm好像也可以。一想,swarm毕竟是docker自带的,学习成本应该不大,本且之前也有接触,果断就用swarm做测试。

2.1 创建overlay网络

swarm 其实管理的就是docker容器,一开始我们使用docker swarm init.然后让它称为manager,其它的docker容器只要join就可以了。这点还是很方便。

1
2
3
4
5
docker swarm init

docker swarm join-token manager

docker swarm join-token worker

这种方式就简单的构建了一个swarm了。然后我们首先创建网络。

1
docker network create -d overlay springcloud-overlay

2.2 准备镜像

创建网络后,就开始准备相应的镜像和Dockerfile。根据每个人的环境不同可以准备相应的Dockerfile:

eureka.Dockerfile: 主要作为注册中心用

1
2
3
4
5
FROM java:8-jre-alpine
VOLUME /tmp
ADD ./*.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]

booksrv.Dockerfile: 做一个无需连接数据库的服务提供者

1
2
3
4
5
6
FROM java:8-jre-alpine
VOLUME /tmp
ADD ./*.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]

warehouse.Dockerfile:连接数据库的服务提供者

1
2
3
4
5
FROM java:8-jre-alpine
VOLUME /tmp
ADD ./*.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar","--cacheType=single"]

web.Dockerfile:客户端调用booksrv和warehouse服务的接口

1
2
3
4
5
FROM java:8-jre-alpine
VOLUME /tmp
ADD ./*.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]

在不同的文件夹下将dockerfile文件准备好之后,我们可以使用docker build -t chenzhijun/imagename .;(chenzhijun/iamgename可以自定义)

2.3 准备yml文件

我们准备好镜像文件之后,可以使用docker stack的方式部署服务。

eureka.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
25
26
27
version: '3'
services:
eureka1:
image: chenzhijun/eureka
networks:
springcloud-overlay:
aliases:
- eureka
ports:
- "1111:1111"
environment:
- ADDITIONAL_EUREKA_SERVER_LIST=http://eureka2:1111/eureka/
eureka2:
image: chenzhijun/eureka
networks:
springcloud-overlay:
aliases:
- eureka
ports:
- "1112:1111"
environment:
- ADDITIONAL_EUREKA_SERVER_LIST=http://eureka1:1111/eureka/

networks:
springcloud-overlay:
external:
name: springcloud-overlay

service.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
25
26
27
28
29
version: '3'
services:
web:
image: chenzhijun/web
networks:
- springcloud-overlay
environment:
- EUREKA_SERVER_ADDRESS=http://eureka1:1111/eureka/,http://eureka2:1111/eureka/
ports:
- "8888"

bookservice:
image: chenzhijun/booksrv
networks:
- springcloud-overlay
environment:
- EUREKA_SERVER_ADDRESS=http://eureka1:1111/eureka/,http://eureka2:1111/eureka/

warehouse:
image: chenzhijun/warehouse
networks:
- springcloud-overlay
environment:
- EUREKA_SERVER_ADDRESS=http://eureka1:1111/eureka/,http://eureka2:1111/eureka/

networks:
springcloud-overlay:
external:
name: springcloud-overlay

我们可以使用docker stack deploy -c eureka.yml(service.yml) eureka(service)。
之后可以使用docker stack ls查看启动了哪些服务,使用docker stack services eureka(service)来查看具体的信息。

这个时候,你可以使用docker ps 来看机器上启动了哪些服务,然后使用docker logs -f containerid来看输出的日志记录。

嗯基本上就可以看到相应的输出。。

docker swarm的另一种服务创建方式:

1
2
3
4
5
6
7
docker service create --name warehouse1 \
--network springcloud-overlay \
--mount type=bind,source=/home/user/jar/notice/warehouse-server.jar,destination=/user/share/jar/app.jar \
--env EUREKA_SERVER_ADDRESS=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/ \
--env MYSQL_SERVER_ADDRESS=mysql:3306 \
-p :30021 \
java:8-jre-alpine java -jar /user/share/jar/app.jar --cacheType=single

一些常见的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

docker stack --hlep;
docker stack ls;
docker stack deploy -c xxx.yml xx-name;
docker stack services xx-name;

docker service --help;

docker network --help;

docker run ;

docker --help;

docker service create --name warehouse1 --network springcloud-overlay
--mount type=bind,source=/home/user/jar/notice/warehouse-server.jar,destination=/user/share/jar/app.jar
--env EUREKA_SERVER_ADDRESS=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
--env MYSQL_SERVER_ADDRESS=mysql:3306
-p :30021 java:8-jre-alpine java -jar /user/share/jar/app.jar --cacheType=single

从命令行参数获取Shell脚本参数

发表于 2018-01-08 | 分类于 Linux | 阅读次数

从命令行参数获取Shell脚本参数

很多时候我们写完脚本都需要指定一些变量,这些变量可能根据实际的环境而值不同。所以如何在 shell 脚本中接收到不同的变量值了?

获取参数

shell 脚本获取参数的方式很多,我只记录我用过的一种:filebeat.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
if [ ! -n "$1" ] ;then
echo "请输入日志文件目录,比如/path/to/xxx.log,输入/path/to:"
exit 1;
fi

echo "日志文件目录:$1" #log_path

if [ ! -n "$2" ] ;then
echo "请输入项目名称,比如customer,notice ...:"
exit 1;
fi

echo "项目名称:$2" #log_type

cd $(pwd)/filebeat
# copy a filebeat.yml to filebeat_log_type.yml
cp config/filebeat.yml config/filebeat_$2.yml
sed -i "s#PATH#$1#g" config/filebeat_$2.yml
sed -i "s#DOCTYPE#$2#g" config/filebeat_$2.yml
nohup ./filebeat -e -c config/filebeat_$2.yml >> logs/$2.log &
tail -f logs/$2.log

shell 文件都是用#!/bin/bash作为第一行,我们在 filebeat.sh 中获取两个参数,如何使用这个脚本了?
sh filebeat.sh param1 param2

param1 我们在脚本中使用$1获取,param2 我们在脚本中使用$2获取,以此类推。

如果要在文件中替换某个特殊文字或者字符如果值中带有/path/to/file,这种带有/的字符,在脚本中可以使用#来转义。之前用的是sed -i "s/path/$1/g" config/file.yml,后来改成sed -i "s#path#$1#g config/file.yml。

参考文档:
http://www.jb51.net/article/56549.htm

https://www.jianshu.com/p/d3cd36c97abc

http://blog.51cto.com/w55554/1223870

使用Docker搭建ELK日志系统

发表于 2017-12-27 | 分类于 ELK | 阅读次数

使用Docker搭建ELK日志系统

之前用本地版本安装了ELK之后,就没有再去弄它了。年底没那么忙,心里一直惦记,所以最近又开始折腾了。去elastic官网看一下,果然版本帝就是版本帝,一周一版本。现在我用的版本是基于6.1.1版本的。

目标

  1. 收集Java日志文件,并且根据文件的不同将日志分类,比如:订单日志,客户日志等。
  2. 日志文件多行处理

总体架构图

2017-12-28-11-23-36

准备镜像

6.0之后官方开始自己维护镜像版本:https://www.docker.elastic.co/。找到需要的ELK镜像地址,pull下来就好了。官方pull下来之后镜像名太长了,所以我将镜像全部重新打了tag,命令:docker tag docker.elastic.co/elasticsearch/elasticsearch:6.1.1 elasticsearch:latest。
使用docker images查看:
2017-12-27-14-49-10

阅读全文 »

Linux如何查看当前占用CPU或内存最多的K个进程

发表于 2017-12-27 | 阅读次数

Linux如何查看当前占用CPU或内存最多的K个进程

一、可以使用以下命令查使用内存最多的K个进程

  1. 方法1:
1
ps -aux | sort -k4nr | head -K

如果是10个进程,K=10,如果是最高的三个,K=3

说明:ps -aux中(a指代all——所有的进程,u指代userid——执行该进程的用户id,x指代显示所有程序,不以终端机来区分)

​ ps -aux的输出格式如下:

1
2
3
4
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root 1 0.0 0.0 19352 1308 ? Ss Jul29 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S Jul29 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Jul29 0:11 [migration/0]

​ sort -k4nr中(k代表从第几个位置开始,后面的数字4即是其开始位置,结束位置如果没有,则默认到最后;n指代numberic sort,根据其数值排序;r指代reverse,这里是指反向比较结果,输出时默认从小到大,反向后从大到小。)。本例中,可以看到%MEM在第4个位置,根据%MEM的数值进行由大到小的排序。

​ head -K(K指代行数,即输出前几位的结果)

​ |为管道符号,将查询出的结果导到下面的命令中进行下一步的操作。

  1. 方法2:top (然后按下M,注意大写)

二、可以使用下面命令查使用CPU最多的K个进程

  1. 方法1:
1
ps -aux | sort -k3nr | head -K
  1. 方法2:top (然后按下P,注意大写)

原文转自:博客园

Elasticsearch 搜索基础

发表于 2017-12-21 | 分类于 Elasticsearch | 阅读次数

Elasticsearch 搜索基础

三大概念

  1. 映射(Mapping):描叙数据在每个字段中如何存储;
  2. 分析(Analysis):全文是如何处理使之可以被搜索;
  3. 领域特定查询语言(QueryDSL):Elasticsearch 查询语言,json格式。

分布式文档存储

发表于 2017-12-21 | 分类于 Elasticsearch | 阅读次数

ES 分布式文档存储

路由文档到分片

创建索引的时候通常我们确定了几个主分片,主分片的数量已经确定,但是输入是存在那个分片?是怎么确定的?是通过一个公司算出来的。

1
shard = hash(routing)%number_of_primary_shards

其中routing默认是文档的id,当然也可以自定义routing的值。

阅读全文 »

使用Travis-CI持续构建Hexo博客

发表于 2017-12-19 | 分类于 Hexo | 阅读次数

使用Travis-CI持续构建Hexo博客

我是用的 Hexo+Github Page 来构建自己的博客。在 Github 创建your_github_name.github.io仓库的时候,可以直接使用your_github_name.github.io作为你的博客域名站点。详细的话,可以自己去 google 下使用 Hexo搭建个人博客。

写本文的原因是因为,每次我在写完一篇总结,提交了push之后。如果要更新到博客上,需要经历的过程就是:

1
2
3
4
5
6
7
8
9
# 提交源文件到仓库
git add .
git commit -m "xxx"
git push origin master

# 发布到博客站点
hexo clean
hexo d -g
# 这里还需要输入github账号,密码。

我觉得如果提交源文件push之后能够直接发布到博客站点就好了。在网上搜了一圈,很多人的资料还是有些缺陷,自己踩了一路坑,所以有了本篇记录。

环境介绍

先介绍下我的博客环境,我用了两个repo:
一个是存博客源码的blog.git,
另一个也就是用来做站点发布的chenzhijun.github.com.git。

网上很多人喜欢用一个库,然后切换分支的做法。之前我也弄过,不过后来发现我经常弄错分支。反正repo不要钱,就无所谓,分开吧。其实就是懒。总之,自己爽就好。

阅读全文 »

elasticsearch-document-data

发表于 2017-12-19 | 分类于 Elasticsearch | 阅读次数

什么是文档

通常情况下,文档类似与对象。在es的术语中文档指的是根对象,或者称为最顶层对象。它被序列化成json存储在es中,并且有一个唯一ID。

字段可以是任何字符,但不能包含时间段

文档的元数据

索引:_index

ES中文档有三个特定的属性:index,type,id;(type可能会在以后的版本中去掉,现在的版本6.0中依然存在)。在es分片中我们提到,数据是存储在索引中的,而索引指的是单个,或者多个分片的逻辑命名空间。索引广义上来说,有点类似我们的数据库database名称。一个库名就对应着一个索引。

索引名字必须小写,不能以下划线开头,不能有逗号

类型:_type

type的含义是将具有相同属性或相似属性的文档集合在一起。它是索引中对数据的逻辑分区。有点类似于我们在数据库中的表。

类型名可以是大小写,不能以下划线开头,不能包含逗号,长度限制在256字符。

唯一ID:_id

如果说空间中的一个点由xyz三轴表示,那么es中的文档位置就由索引,类型,id来确定。Id是一个字符串,你可以自己生成,也可以让ES帮你生成。id类似与表中的主键。

文档还有其它的元数据,但是总的来说,最最重要的就是这三个。毕竟你最重要的还是数据(文档)。

自动生成的 ID 是 URL-safe、 基于 Base64 编码且长度为20个字符的 GUID 字符串。 这些 GUID 字符串由可修改的 FlakeID 模式生成,这种模式允许多个节点并行生成唯一 ID ,且互相之间的冲突概率几乎为零。

你可以这样理解,图书馆有各种书,管理员将书分成了很多类,每一个类下面有个唯一的书编号,知道这些,你就能找到那本特定的书。其中图书馆就是ElasticSearch,各种书就是index,分类就是type,唯一id就是书编号。实际的那本书就是一个文档。

创建索引文档

阅读全文 »

elasticsearch 集群主分片和副本分片

发表于 2017-12-18 | 阅读次数

集群的健康状态查询:

1
curl -XGET 'localhost:9200/_cluster/health?pretty'
1
2
3
4
5
6
7
8
9
10
11
12
{
"cluster_name": "elasticsearch",
"status": "green",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}

status字段是最为重要的,有三个值:green,yellow,red。三者的含义:

  1. green:所有主分片和副分片都能正常运行;
  2. yellow: 所有主分片都能正常运行,但不是所有副分片都能正常运行;
  3. red:有主分片没能正常运行。
阅读全文 »

基于ELK+Filebeat搭建日志中心

发表于 2017-12-12 | 分类于 ELK | 阅读次数

基于ELK+Filebeat搭建日志中心

实验环境

  1. ubuntu 16
  2. jdk 1.8
  3. elasticesearch 6.0, kibana 6.0, logstash 6.0, filebeat 6.0

我也在windows10下安装过,win10下只需要修改filebeat的文件路径配置就可以了。

概念介绍

elastic提供了非常多的工具,官方称为Elastic Stack。它提供了一些解决方案。我们用到的就是其中Stack中的部分工具

  1. Elasticsearch

Elasticsearch 是一个分布式、可扩展开源全文搜索和分析引擎。它能够进行存储,并且能以很快的速度(接近实时)来进行搜索和分析大量的数据。它使用Java编写,底层基于Apache Lucene。

  1. Logstash

Logstash 是一个开源的,服务端数据处理管道。 它可同时从多个源来搜集数据,对数据进行过滤等操作,并且将数据传送到你想要传送的地方进行存储。

  1. Kibana

Kibana 被设计成一个和Elasticsearch共同使用的开源分析和可视化平台,它支持将ES中存储的数据生成多种维度的图等。

  1. Filebeat

Filebeat 是一个轻量级的日志采集器,用于将源数据采集后发送给Logstash,并且Filebeat使用背压敏感协议,以考虑更多的数据量。如果Logstash正在忙于处理数据,则可以让Filebeat知道减慢读取速度。还有很多Beat可以提供选择,有监控网络的Packbeat,指标Metricbeat。各种beat详情:https://www.elastic.co/cn/products/beats

系统架构简图如下:

2017-12-13-09-21-45

阅读全文 »
1…111213…18

180 日志
41 分类
70 标签
RSS
GitHub GitEE
推荐阅读
  • 陈志军的个人站
© 2017 - 2023 陈志军
由 Hexo 强力驱动
主题 - NexT.Muse