自动化运维已经是必不可少的一环,经历过生产上各种版本问题,简单是痛心疾首,忍不住拿此开刀,希望借此帮助提升国人的技术实力。
编写此文献给今天30岁的自己。
自动化运维包含两部分:自动化构建跟自动化部署。
常用的工具是大家耳熟能详地jenkins跟docker,但是不好用,不简单,不牛逼!
此篇讲解实例 函数式自动化部署elk方案,将在下期讲解函数式自动化构建spring boot方案。
自动化部署这里介绍的工具是nixops: https://nixos.org/nixops/manual/
这里的核心不是介绍工具,所以我们从底层讲解,后期会专门介绍nixops之大杀器。
自动化部署需要载体,所以产生了不同的隔离级别。
nixops支持三种隔离级别:
1. 环境隔离(nix-env)
2. 进程隔离(nix-container)
3. 资源隔离(nixos virtualbox)
大家常见的docker就是进程隔离, 虚拟机就是资源隔离。
有了函数式运维,我们所需要的隔离90%以上只需要nix-env环境隔离就可以解决,甚至nix-container的进程隔离也是完全不需要虚拟化的,简单强大。
nix-container将在后续nixops使用篇介绍.
不得不说,docker老矣。大家要问,如日中天的docker有哪些不好?
第一: 部署友好度。
你觉得用root装软件是个很安全的操作吗?
但是nix-env不一样,只需建个目录便于所有用户共享即可
第二: 资源利用率
我就简单的部署个jar包,就得启动虚拟化技术,损耗实在太大了点,性能也是极大的浪费。
但是nix-env不一样,通过环境隔离,与系统无缝集成
第三: 资源透明度
如果在一台机器上安装相同的多个节点服务,这里就涉及复杂的端口映射,甚至locahost跟主机都是调试一大障碍。
但是nix-env不一样,直接原生应用开干,简单强大,不需要那么复杂
第四: 版本管理
docker的强项不就是版本管理么?NO!如果1.0代码改动一小点,它还是1.0,还是1.0。。。
但是nix-env不一样,它对所有内容进行sha计算,轻松智能多版本,函数式就是不可变,1.0也能多版本
第五:依赖管理
如果一个系统库不提供二进制版本,那么需要自己构建。
如果在docker中构建,需要额外的一整套构建环境
如果不在docker中构建,系统的库依赖哪些是docker需要的呢?
有了函数式运维nix,所有的软件都是包含了依赖关系,并且构建与部署分离。
第六: 学习门槛
学习docker需要学习专有的语法,虽然不是很难。调试也极其困难。
nix-env仅仅只是一个命令行工具,轻轻松松解决问题。
忍不住 来一句,世界本不应该如此复杂。。。
现实中的自动化部署常用的问题有哪些?
第一: 需要配置大量主从服务端,严重侵入系统。已知的有puppet, cloudera manager。
第二: 不支持离线功能。已知的有ansible/salt需要安装大量的python包才可以使用,离线之伤痛!
第三: 要学习特有的各种模块及技术。由于不是函数式,要处理复杂度,确实不能怪它们。
什么是函数式运维?
在函数式运维的体系里面,软件包即值,配置即状态。软件包是不可变的,稍弱改动软件包之后产生了一个新的软件包。
那么函数式运维有啥好处呢?
由于软件包无状态,配置即状态 ,所以很轻松建立了配置驱动编程的体系。对于配置,加上严格的版本控制,自然就有了代码即文档的效果。由于软件包即值,配置多版本管理,从一个环境传递到另一个环境是那么自然 。对于软件的多版本,即是不同的值那么简单。由于函数式的不可变,中间过程相同输入产生的输入只用处理一次,后续可复用。如果服务器直接提供二进制构建,即不需要源码构建进行软件包安装,否则重新编译一次后续复用,大大提高构建效率。
开始今天的正题: 一键搞定elk函数式部署
1. 部署方案简单设计(抽象大于实现)
2. 部署方案运行过程(好东西就是玩)
3. 部署方案代码分析(github源码精彩讲解)
部署方案简单设计 :
我经常说抽象大于实现。很多人不明白。大家都笑话我说不写代码,光靠脑袋想么?
抽象大于实现的意义大于,使程序具有美感,非常自然,让人一眼就能明白。
这里就以抽象大于实现的思想来思考问题。
为了达到离线部署功能,我们将部署分解成三部分:打包,部署,启动。
打完包之后,可以离线拷贝到其它机器上进行一键部署后启动。
所有我们的代码分为elk.package.sh, elk.deploy.sh, elk.start.sh
1. elk.package.sh: 打包是自动化的,从构建服务器自动同步打包
nix-channel --add https://nixos.org/channels/nixpkgs-unstable
nix-channel --update
2. elk.deploy.sh: 部署是可以离线的,并且完全零配置
3. elk.start.sh启动是可以远程调试及传参的,并且支持同一机器多节点服务
一下子就轻松搞定了。那么需要多少行代码呢?不到200行。
部署方案运行过程 :
项目源码: https://github.com/clojurians-org/my-env
部署脚本: run.sh.d/elk-example/{createvm.sh, package.sh, deploy.sh, start.sh}
第0步: 环境准备
第1步: 安装三台虚拟机(可选)-createvm.sh
第2步: 打包elk依赖-package.sh
第3步: 部署elk组件-deploy.sh
第4步: 启动elk服务-start.sh
第0步: 环境准备
;; 没有安装nix的请自行安装: https://nixos.wiki/wiki/Nix_Installation_Guide
a. 安装git
b. 同步代码
第1步: 安装三台虚拟机 (可选,如已有机器集群可跳过)
创建三台虚拟机
[larluo@larluo-nixos:~/my-env]$ cat run.sh.d/elk-example/createvm.sh
set -e
my=$(cd -P -- "$(dirname -- "${BASH_SOURCE-$0}")" > /dev/null && pwd -P) && cd $my/../..
echo -e "\n==== bash nix.sh create-vm nixos-elk-001" && bash nix.sh create-vm nixos-elk-001
echo -e "\n==== bash nix.sh create-vm nixos-elk-002" && bash nix.sh create-vm nixos-elk-002
echo -e "\n==== bash nix.sh create-vm nixos-elk-003" && bash nix.sh create-vm nixos-elk-003
第2步: 打包elk
添加函数式自动化构建channel:
同步下载软件包(配置文件同名时,以elasticsearch优先级最高,后续优化)
[larluo@larluo-nixos:~/my-env]$ cat run.sh.d/elk-example/package.sh
set -e
my=$(cd -P -- "$(dirname -- "${BASH_SOURCE-$0}")" > /dev/null && pwd -P) && cd $my/../..
echo -e "\n==== bash nix.sh export nix.gettext-0.19.8.1" && bash nix.sh export nix.gettext-0.19.8.1
echo -e "\n==== bash nix.sh export nix.elasticsearch-6.2.4" && bash nix.sh export nix.elasticsearch-6.2.4
nix-env --set-flag priority 0 elasticsearch-6.2.4
echo -e "\n==== bash nix.sh export nix.logstash-6.2.4" && bash nix.sh export nix.logstash-6.2.4
echo -e "\n==== bash nix.sh export nix.kibana-6.2.4" && bash nix.sh export nix.kibana-6.2.4
第3步: 部署elk
部署至远程服务器:
[larluo@larluo-nixos:~/my-env]$ cat run.sh.d/elk-example/deploy.sh
my=$(cd -P -- "$(dirname -- "${BASH_SOURCE-$0}")" > /dev/null && pwd -P) && cd $my/../..
# create user op:op
echo -e "\n==== bash nix.sh create-user 192.168.56.101" && bash nix.sh create-user 192.168.56.101
echo -e "\n==== bash nix.sh create-user 192.168.56.102" && bash nix.sh create-user 192.168.56.102
echo -e "\n==== bash nix.sh create-user 192.168.56.103" && bash nix.sh create-user 192.168.56.103
# install nix
echo -e "\n==== bash nix.sh install 192.168.56.101 tgz.nix-2.0.4" && bash nix.sh install 192.168.56.101 tgz.nix-2.0.4
echo -e "\n==== bash nix.sh install 192.168.56.102 tgz.nix-2.0.4" && bash nix.sh install 192.168.56.102 tgz.nix-2.0.4
echo -e "\n==== bash nix.sh install 192.168.56.103 tgz.nix-2.0.4" && bash nix.sh install 192.168.56.103 tgz.nix-2.0.4
# install gettext for envsubst
echo -e "\n==== bash nix.sh install 192.168.56.101 nix.gettext-0.19.8.1" && bash nix.sh install 192.168.56.101 nix.gettext-0.19.8.1
echo -e "\n==== bash nix.sh install 192.168.56.102 nix.gettext-0.19.8.1" && bash nix.sh install 192.168.56.102 nix.gettext-0.19.8.1
echo -e "\n==== bash nix.sh install 192.168.56.103 nix.gettext-0.19.8.1" && bash nix.sh install 192.168.56.103 nix.gettext-0.19.8.1
# install elasticsearch
echo -e "\n==== bash nix.sh import 192.168.56.101 nix.elasticsearch-6.2.4" && bash nix.sh import 192.168.56.101 nix.elasticsearch-6.2.4
echo -e "\n==== bash nix.sh import 192.168.56.102 nix.elasticsearch-6.2.4" && bash nix.sh import 192.168.56.102 nix.elasticsearch-6.2.4
echo -e "\n==== bash nix.sh import 192.168.56.103 nix.elasticsearch-6.2.4" && bash nix.sh import 192.168.56.103 nix.elasticsearch-6.2.4
# install logstash
echo -e "\n==== bash nix.sh install 192.168.56.101 nix.logstash-6.2.4" && bash nix.sh install 192.168.56.101 nix.logstash-6.2.4
echo -e "\n==== bash nix.sh install 192.168.56.102 nix.logstash-6.2.4" && bash nix.sh install 192.168.56.102 nix.logstash-6.2.4
echo -e "\n==== bash nix.sh install 192.168.56.103 nix.logstash-6.2.4" && bash nix.sh install 192.168.56.103 nix.logstash-6.2.4
# instal kibana
echo -e "\n==== bash nix.sh import 192.168.56.101 nix.kibana-6.2.4" && bash nix.sh import 192.168.56.101 nix.kibana-6.2.4
echo -e "\n==== bash nix.sh import 192.168.56.102 nix.kibana-6.2.4" && bash nix.sh import 192.168.56.102 nix.kibana-6.2.4
echo -e "\n==== bash nix.sh import 192.168.56.103 nix.kibana-6.2.4" && bash nix.sh import 192.168.56.103 nix.kibana-6.2.4
选择一台机器进行检查
第4步: 启动elk
[larluo@larluo-nixos:~/my-env]$ cat run.sh.d/elk-example/start.sh
set -e
my=$(cd -P -- "$(dirname -- "${BASH_SOURCE-$0}")" > /dev/null && pwd -P) && cd $my/../..
# start elasticsearch-6.2.4
export ES_ALL="192.168.56.101:9200,192.168.56.102:9200,192.168.56.103:9200"
echo -e "\n==== bash nix.sh start 192.168.56.101:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor"
bash nix.sh start 192.168.56.101:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor
echo -e "\n==== bash nix.sh start 192.168.56.102:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor"
bash nix.sh start 192.168.56.102:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor
echo -e "\n==== bash nix.sh start 192.168.56.103:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor"
bash nix.sh start 192.168.56.103:9200 elasticsearch-6.2.4 --all ${ES_ALL} --cluster.id monitor
# start kibana-6.2.4
echo -e "\n==== bash nix.sh start 192.168.56.101:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}" && bash nix.sh start 192.168.56.101:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}
echo -e "\n==== bash nix.sh start 192.168.56.102:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}" && bash nix.sh start 192.168.56.102:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}
echo -e "\n==== bash nix.sh start 192.168.56.103:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}" && bash nix.sh start 192.168.56.103:5601 kibana-6.2.4 --elasticsearchs ${ES_ALL}