L B T

记 录 过 去 的 经 验

环境信息

  • Mysql 5.7 之后版本支持多主一从

配置步骤

分别在Master_1和Master_2上导出需要同步的数据库

分别在Master_1和Master_2上执行以下命令,导出需要同步的数据库备份

Master_1
mysqldump -uroot -p123456 --master-data=2 --single-transaction --databases  --add-drop-database  db1  > db1.sql
Master_2
mysqldump -uroot -p123456 --master-data=2 --single-transaction --databases  --add-drop-database  db2  > db2.sql

备份完成后,将备份数据拷贝到从库服务器上面

阅读全文 »

Mysql 主从同步基本原理

复制的基本过程如下:

  1. Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;

  2. Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程,根据请求信息,读取指定日志指定位置之后的日志信息,返回给Slave 的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;

  3. Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”;

  4. Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容,获得在Master端真实执行的那些可执行的内容,并在自身执行。

双主情况下,禁止同时写入,建议还是按照主从的方式工作,防止数据冲突。双主场景下,主要是切换主备方便。

阅读全文 »

模板中需要循环中循环,{% for i in alist %},假如i是个元组或列表,需要继续循环:

{% for i in alist %}
{% with temp=I %}
{% for k in temp %}

{% endfor %}
{% endwith %}
{%endfor%}

或使用如下方式,data = [[1,2],[3,4]]:

{% for l in data%}

{% for temp in l % }
{% if forloop.first % }
'{{temp}}',
{% else %}
{{temp}}
{% endif %}
{% endfor %}

{%endfor%}

class Question(models.Model):
question_text=models.CharField(max_length=200)
pub_date=models.DateTimeField('datepublished')

def__str__(self):
returnself.question_text

class Choice(models.Model):
question=models.ForeignKey(Question,on_delete=models.CASCADE)
choice_text=models.CharField(max_length=200)
votes=models.IntegerField(default=0)

def__str__(self):
returnself.choice_text


上例中,Choice引用了Question作为外键,在模板中通过Question对象获取所有引用了Question对象的Choice对象,可以使用以下方法:

{% for choice in question.choice_set.all %}
<li>{{choice.choice_text}}</li>
{%endfor%}

使用question.choice_set.all的方式获取所有引用question对象的Choice对象实例

HCL AppScan(原名IBM Security AppScan)是原IBM的Rational软件部门的一组网络安全测试和监控工具,2019年被HCL技术公司收购。AppScan旨在在开发过程中对Web应用程序的安全漏洞进行测试。

阅读全文 »

环境信息

  • Centos 7
  • logstash 8.8

一个 Logstash 管道(pipeline) 至少要包含 2 个组件: inputoutput,可以包含可选组件 filter [2]

  • input - 负责从数据源获取数据
  • filter - 负责按照配置修改数据
  • output - 负责将数据写入目标存储,如 Elasticsearch

安装

Logstash 官方安装文档

yum 安装

$ sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

$ cat /etc/yum.repos.d/logstash.repo
[logstash-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

$ sudo yum install logstash

$ systemctl enable --now logstash

运行 Logstash 后,可以使用最基本的 Logstash Pipeline 测试 Logstash 运行是否正常

/usr/share/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }'
  • -e - 选项用来在 command line 中指定配置

运行之后在 shell 中输入内容,Logstash 会为数据添加元数据后输出到 stdout,表明 Logstash 运行正常

hello world
{
"@timestamp" => 2023-07-21T02:52:50.191084777Z,
"host" => {
"hostname" => "worker1"
},
"message" => "hello world",
"@version" => "1",
"event" => {
"original" => "hello world"
}
}

logstash 服务默认端口 5044

阅读全文 »

环境信息

  • elasticsearch 8.8.2

Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene [1] 基础之上。 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库 — 无论是开源还是私有。

但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。 [1]

Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

Elasticsearch 将所有的功能打包成一个单独的服务,这样你可以通过程序与它提供的简单的 RESTful API 进行通信, 可以使用自己喜欢的编程语言充当 web 客户端,甚至可以使用命令行(去充当这个客户端)。

Elasticsearch 官方安装文档

Elasticsearch 官方安装包下载路径

Elasticsearch 是 面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引 每个文档的内容,使之可以被检索。在 Elasticsearch 中,我们对文档进行索引、检索、排序和过滤—而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。 [2]

Elasticsearch 使用 JSON 作为文档的序列化格式 [2]

Elasticsearch 集群内的原理

端口说明

elasticsearch 主要使用以下端口

  • 9200 - elasticsearch 服务的监听端口,客户端访问 9200 和 Elasticsearch 进行通信。
  • 9300 - 集群中的节点通过 9300 端口彼此通信,如果这个端口没有开,节点将无法形成一个集群

Elasticsearch 配置文件说明

Elasticsearch 的主要配置文件为,配置文件路径可以用环境变量 ES_PATH_CONF 指定。 [8]

  • elasticsearch.yml
  • jvm.options
  • log4j2.properties

Elasticsearch 已经有了 很好 的默认值,特别是涉及到性能相关的配置或者选项。 如果你有疑问,最好就不要动它。我们已经目睹了数十个因为错误的设置而导致毁灭的集群, 因为它的管理者总认为改动一个配置或者选项就可以带来 100 倍的提升。 [8]

配置文件格式支持 YAML扁平 格式 [8]

YAML 格式示例

YAML
path:
data: /var/lib/elasticsearch
logs: /var/log/elasticsearch

discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com

扁平 格式示例

flattened
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

discovery.seed_hosts: ["192.168.1.10:9300", "192.168.1.11", "seeds.mydomain.com"]

集群及节点名称

Elasticsearch 默认启动的集群名字叫 elasticsearch生产环境中建议修改集群名称,防止其他使用默认集群名称的节点意外加入集群 [8]

同样,最好也修改你的节点名字。就像你现在可能发现的那样, Elasticsearch 会在节点启动的时候随机给它指定一个名字。你可能会觉得这很有趣,但是当凌晨 3 点钟的时候, 你还在尝试回忆哪台物理机是 Tagak the Leopard Lord 的时候,你就不觉得有趣了。

更重要的是,这些名字是在启动的时候产生的,每次启动节点, 它都会得到一个新的名字。这会使日志变得很混乱,因为所有节点的名称都是不断变化的[8]

elasticsearch.yml
cluster.name: elasticsearch
node.name: elasticsearch_005_data

网络配置

监听接口相关配置

elasticsearch.yml
# 多网卡情况下,建议指定 IP 地址,以防止集群使用网络不通的 IP。#
# 如果需要监听多个 IP 地址,使用以下配置
# network.host: ["127.0.0.1", "192.168.1.1"]
network.host: 0.0.0.0
http.port: 9200

阅读全文 »

策略使用 HCL 或是 JSON 语法编写,描述了一个人类用户或是应用程序允许访问 Vault 中哪些路径。[1]

策略管理

创建策略

命令格式

$ vault policy write policy-name policy-file.hcl

以下示例创建一个只读策略

$ cat readonly_policy.hcl 
path "kv/*" {
capabilities = ["read"]
}

$ vault policy write readonly_policy readonly_policy.hcl


更新策略使用和创建策略一样的命令,使用的是已有的策略名

查看策略

$ vault policy list
default
readonly_policy
root

读取策略内容

$ vault policy read readonly_policy
path "kv/*" {
capabilities = ["read"]
}

关联策略

创建 token 时关联策略

使用以下命令在创建 token 时附加策略,否则创建的 token 默认关联当前身份(如 token)的策略

$ vault token create -policy=readonly_policy -policy=logs

Key Value
--- -----
token hvs.CAESICUghHrXAe3mFG9YEnEq8IXdtGPN-63VRRxqPOEzidpvGh4KHGh2cy5RMUhkbmU1M2FFdk52a3lFRTNiMmR6Um8
token_accessor iRixdShkSeHNTgS5JBLWW2Ta
token_duration 768h
token_renewable true
token_policies ["default" "logs" "readonly_policy"]
identity_policies []
policies ["default" "logs" "readonly_policy"]

关联策略时,如果关联的策略不存在,创建 token 只会给出相关策略不存在的 warnning,创建 token 不会失败

使用新建的 token 登陆并尝试更新相关键

$ vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key Value
--- -----
token hvs.CAESICUghHrXAe3mFG9YEnEq8IXdtGPN-63VRRxqPOEzidpvGh4KHGh2cy5RMUhkbmU1M2FFdk52a3lFRTNiMmR6Um8
token_accessor iRixdShkSeHNTgS5JBLWW2Ta
token_duration 767h55m32s
token_renewable true
token_policies ["default" "logs" "readonly_policy"]
identity_policies []
policies ["default" "logs" "readonly_policy"]

读取键,可以看到只能读取键值,无法写入

$ vault kv list
Not enough arguments (expected 1, got 0)
~/vault_policy $ vault kv list kv
Error listing kv: Error making API request.

URL: GET http://127.0.0.1:8200/v1/kv?list=true
Code: 403. Errors:

* 1 error occurred:
* permission denied


$ vault kv get kv/ms/fm/qzx/qzapp/api/config
===== Data =====
Key Value
--- -----
db_host 127.0.0.1
db_type mysql
db_user password
tk test key


$ vault kv put kv/ms/fm/qzx/qzapp/api/config key=value
Error writing data to kv/ms/fm/qzx/qzapp/api/config: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/kv/ms/fm/qzx/qzapp/api/config
Code: 403. Errors:

* 1 error occurred:
* permission denied

参考链接

Vault 中文参考

脚注

环境信息

  • Centos 7
  • Redis 6

redis Cluster 部署

下载已经编译好的 redis6-cluster 安装文件

wget https://s.csms.tech/redis6-cluster.tar
tar -xf redis6-cluster.tar -C /usr/local/

本示例安装 3 master 3 slave 的 redis cluster,假设使用端口为 7380-7385。数据存放路径为 /data/redis/7380,日志路径为 /data/logs/redis-cluster/7380/,其他端口的 redis 服务配置以此类推,主要是修改对应端口。

创建服务启动需要的数据目录及日志目录

for i in 1 2 3 4 5 0 ; do mkdir -p /data/redis/738${i} ; done

for i in 1 2 3 4 5 0 ; do mkdir -p /data/logs/redis-cluster/738${i} ; done

7380 服务使用如下配置文件

7380.conf
bind 0.0.0.0
protected-mode no
port 7380
tcp-backlog 511
timeout 600
tcp-keepalive 60
daemonize yes
supervised no
pidfile /var/run/redis_7380.pid
loglevel notice
logfile /data/logs/redis-cluster/7380/redis.log
databases 16
always-show-logo yes
save ""
stop-writes-on-bgsave-error no
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/7380
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass redisPassword
masterauth redisPassword
maxclients 30000
maxmemory-policy volatile-lru
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
cluster-enabled yes
cluster-node-timeout 5000
cluster-require-full-coverage no
slowlog-log-slower-than 3000
slowlog-max-len 200
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 0 0 0
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

若要根据以上 7380 端口的服务配置文件复制出其他服务端口的配置文件,可以参考以下命令

cp 7380.conf 7381.conf
sed -i 's/7380/7381/g' 7381.conf

cp 7380.conf 7382.conf
sed -i 's/7380/7382/g' 7382.conf

分别启动服务(7380-7385)

/usr/local/redis6-cluster/src/redis-server /usr/local/redis6-cluster/7380.conf

阅读全文 »

环境信息

  • Kubernetes 1.24
  • Vault 1.14.0

kv

Key/Value 机密引擎是一个通用的键值存储,用于在 Vault 使用的物理存储中存储任意秘密。该后端可以以两种模式之一运行 [1]

  • kv v1 - 可以将其配置为存储密钥的单个值,只有最近写入的值会被保存下来
  • kv v2 - 开启版本控制并存储每个键的一定数量版本的值。默认保留 10 个版本的值。

kv Version 1

Version 1 的 KV Secret Engine 相比 v2 版本,有以下限制:

  • 不能使用 vault kvmetadatapatch 命令
  • 使用 vault kv put 写入的值会覆盖之前的内容,即只保存了最后一次写入的值。

启用 version 1 的 kv 存储,没有 -version 选项时默认开启 version 1 版本的 kv:

$ vault secrets enable -version=1 kv

与其他 Secret Engine 不同,kv 机密引擎不会强制执行 TTL 过期。即使设置了 ttl,kv Secret Engine 也不会自行删除数据。 [1]

写入数据

$ vault kv put kv/mycorp/mydepartment/myproject/myapp/myapp-api/config db_type=mysql
Success! Data written to: kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

$ vault kv put kv/mycorp/mydepartment/myproject/myapp/myapp-api/config db_host=127.0.0.1
Success! Data written to: kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

$ vault kv put kv/mycorp/mydepartment/myproject/myapp/myapp-api/config db_port=3306
Success! Data written to: kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

列出键

$ vault secrets list
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_e5c17df6 per-token private secret storage
identity/ identity identity_f0404cf8 identity store
kv/ kv kv_618be90b n/a
sys/ system system_053aea79 system endpoints used for control, policy and debugging
transit/ transit transit_aaaaf63d n/a


$ vault kv list kv
Keys
----
mycorp/

$ vault kv list kv/mycorp
Keys
----
mydepartment/

$ vault kv list kv/mycorp/mydepartment
Keys
----
myproject/

$ vault kv list kv/mycorp/mydepartment/myproject/myapp/myapp-api
Keys
----
config

$ vault kv list kv/mycorp/mydepartment/myproject/myapp/myapp-api/config
No value found at kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

读取键值

$ vault kv get kv/mycorp/mydepartment/myproject/myapp/myapp-api/config
===== Data =====
Key Value
--- -----
db_port 3306

以上输出中,键 kv/mycorp/mydepartment/myproject/myapp/myapp-api/config 的内容为 db_port=3306,之前写入的其他数据被覆盖,只保留有最后一个写入

删除键

$ vault kv delete kv/mycorp/mydepartment/myproject/myapp/myapp-api/config
Success! Data deleted (if it existed) at: kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

$ vault kv get kv/mycorp/mydepartment/myproject/myapp/myapp-api/config
No value found at kv/mycorp/mydepartment/myproject/myapp/myapp-api/config

阅读全文 »

Policy

Vault 模拟了一个文件系统,Vault 中的所有信息,包括 Secret、配置等,都是依照各自的路径来使用和授权的。 [1]

使用 Vault 策略,可以使用声明式的语法来赋予或者禁止对特定路径的特定操作。Vault 策略默认情况下拒绝一切访问,所以一个空的策略不会赋予对系统的任何访问权限。 [1]

身份认证及授权流程

策略语法

策略使用 HCL 或者 Json 语法编写,描述了一个人或者应用程序允许访问 Vault 中的哪些路径 [1]

参考链接

Vault 中文参考手册-策略

脚注

环境信息

  • centos7 5.4.212-1.el7
  • kubernetes Server Version: v1.25.0
  • Helm 3.10.0

安装

  1. 下载 需要的版本

    wget https://get.helm.sh/helm-v3.10.0-linux-amd64.tar.gz
  2. 解压

    tar -xf helm-v3.10.0-linux-amd64.tar.gz
  3. 在解压目中找到 helm 程序,移动到需要的目录中

    cp linux-amd64/helm /usr/local/bin/
  4. 验证

    $ helm version
    version.BuildInfo{Version:"v3.10.0", GitCommit:"ce66412a723e4d89555dc67217607c6579ffcb21", GitTreeState:"clean", GoVersion:"go1.18.6"}

常见用法

查看已安装的 release

helm ls

helm ls -A

卸载

$ helm ls -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
cert-manager cert-manager 1 2022-11-01 09:57:11.373366484 +0800 CST failed cert-manager-v1.7.1 v1.7.1
rancher cattle-system 1 2022-11-01 10:05:07.370131566 +0800 CST failed rancher-2.6.9 v2.6.9

$ helm uninstall rancher -n cattle-system
W1101 10:21:32.764269 11113 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W1101 10:21:34.043445 11113 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W1101 10:21:39.809766 11113 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
release "rancher" uninstalled

查看导入的 repo

$ helm repo ls
NAME URL
rancher-stable https://releases.rancher.com/server-charts/stable
jetstack https://charts.jetstack.io
hashicorp https://helm.releases.hashicorp.com

搜索/查看可用的 repo

$ helm search repo hashicorp/vault
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/vault 0.25.0 1.14.0 Official HashiCorp Vault Chart
hashicorp/vault-secrets-operator 0.1.0 0.1.0 Official Vault Secrets Operator Chart

查看可用的 releases

$ helm search repo hashicorp/vault -l
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/vault 0.25.0 1.14.0 Official HashiCorp Vault Chart
hashicorp/vault 0.24.1 1.13.1 Official HashiCorp Vault Chart
hashicorp/vault 0.24.0 1.13.1 Official HashiCorp Vault Chart
hashicorp/vault 0.23.0 1.12.1 Official HashiCorp Vault Chart
hashicorp/vault 0.22.1 1.12.0 Official HashiCorp Vault Chart
hashicorp/vault 0.22.0 1.11.3 Official HashiCorp Vault Chart

安装

$ helm install vault hashicorp/vault --version 0.25.0
NAME: vault
LAST DEPLOYED: Mon Jul 10 14:59:13 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
Thank you for installing HashiCorp Vault!

Now that you have deployed Vault, you should look over the docs on using
Vault with Kubernetes available here:

https://www.vaultproject.io/docs/


Your release is named vault. To learn more about the release, try:

$ helm status vault
$ helm get manifest vault

环境信息

  • Kubernetes 1.24
  • Vault 1.14.0

Vault 简介

Vault 架构及基础概念

Vault 的架构图如下 [1]

从以上架构图可以看到,几乎所有的 Vault 组件都被统称为 Barrier (屏障)

Vault 架构可以大体分为三个部分: [7]

  • Sotrage Backend - 存储后端
  • Barrier - 屏障层
  • HTTPS API - API 接口

常用概念

Storage Backend - Vault 自身不存储数据,因此需要一个存储后端(Storage Backend),存储后端对 Vault 来说是不受信任的,只用来存储加密数据。 [8]

Initialization - Vault 在首次启动时需要初始化(Initialization),这一步会生成一个 Master Key(加密密钥)用于加密数据,只有加密完成的数据才能保存到 Storage Backend

Unseal - Vault 启动后,因为不知道 Master Key (加密密钥)所以无法解密数据(可以访问 Storage Backend 上的数据),这种状态被称为 Sealed(已封印),在能解封(Unseal)数据之前,Vault 无法进行任何操作。Unseal 是获取 Master Key 明文的过程,通过 Master Key 可以解密 Encryption Key 从而可以解密存储的数据 [6]

Master Key - Encryption Key (用来加密存储的数据,加密密钥和加密数据被一同存储) 是被 Master Key(主密钥) 保护(加密),必须提供 Master Key,Vault 才能解密出 Encryption Key,从而完成数据解密操作。Master Key 与其他 Vault 数据被存放在一起,但使用另一种机制进行加密:解封密钥 ,解封密钥默认使用 沙米尔密钥分割算法 生成 Key Shares [9]

Key Shares - 默认情况下,Vault 使用 沙米尔密钥分割算法Master Key 的解封密钥分割成五个 Key Shares(分割密钥),必须要提供其中任意的三个 Key Shares 才能重建 Master Key,以完成 Unseal(解封)操作

Key Shares(分割密钥)的总数,以及重建 Master Key(主密钥)最少需要的分割密钥数量,都是可以调整的。 沙米尔密钥分割算法 也可以关闭,这样主密钥将被直接提供给管理员,管理员可直接使用它进行解封操作。

认证系统及权限系统处理流程

在解密出 Encryption Key 后,Vault 就可以处理客户端请求了。 HTTPS API 请求进入后的整个流程都由 Vault Core 管理,Core 会强制进行 ACL 检查,并确保 Audit logging(审计日志)完成记录。

客户端首次连接 Vault 时,需要首先完成身份认证,Vault 的 Auth Method 模块有很多的身份认证方法可选

  • 用户友好的认证方法,适合管理员使用,包括: user/password云服务商ldap 等,在创建用户的时候,需要为用户绑定 Policy,给予适合的权限
  • 应用友好的方法,适合应用程序使用,包括: public/private keystokenkubernetesjwt

身份验证请求经 Core 转发给 Auth Method 进行认证,Auth Method 判定请求身份是否有效并返回关联的策略(ACL Policies)的列表。

ACL PoliciesPolicy Store 负责管理与存储,Core 负责进行 ACL 检查,ACl 的默认行为是 Deny,意味着除非明确配置 ACL Policy 允许某项操作,否则该操作将被拒绝。

在通过 Auth Method 进行认证,并返回了没有问题的 ACL Policies 后,Token Store 会生成并管理一个新的 Token,这个 凭证 会返回给客户端,用于客户端后续请求的身份信息。Token 都存在一个 lease(租期)。Token 关联了相关的 ACL Policies,这些策略将被用于验证请求的权限。

请求经过验证后,将被路由到 Secret Engine,如果 Secret Engine 返回了一个 secretCore 将其注册到 Expiration Manager,并给它附件一个 Lease IDLease ID 被客户端用于更新(renew)或者吊销(revoke)它得到的 secret。如果客户端允许租约(lease) 到期,Expiration Manager 将自动吊销(revoke) 这个 secret

Secret Engine

Secret Engine 是保存、生成或者加密数据的组件,非常灵活。有的 Secret Engin 只是单纯的存储与读取数据,比如 kv(键值存储)就可以看作一个加密的 Redis。而其他的 Secret Engine 则可能连接到其他的服务并按需生成动态凭证等。

阅读全文 »

环境信息

  • CentOS Linux release 7.9.2009 (Core)
  • yum-3.4.3

yum 命令示例

查询指定命令来自哪个安装包

$ yum whatprovides ip
iproute-4.11.0-30.el7.x86_64 : Advanced IP routing and network device configuration tools
Repo : base
Matched from:
Filename : /sbin/ip

rpm 查询已安装文件来自哪个安装包

$ rpm -qf /sbin/ip
iproute-4.11.0-30.el7.x86_64

仅下载安装包而不进行安装操作

如果只下载安装包而不进行安装,可以使用 yumdownloader 命令,此命令来自安装包 yum-utils,如果不存在可以安装 yum-utils

yumdownloader <package-name>

以上下载指定的安装包而不安装,安装包会下载到当前目录

常见错误

The GPG keys listed for the “MySQL 5.7 Community Server” repository are already installed but they are not correct for this package

解决方法

修改对应 yum 源的配置文件,将其中的配置 gpgcheck=1 改为 gpgcheck=0,以此跳过 key 验证

Prometheus 抓取 Nginx 运行时指标,主要有以下方法:

  • Nginx 通过自己的 stub_status 页面 (需要 with-http_stub_status_module 模块支持) 暴露出了一些 Nginx 运行时的指标,较为简单,在 Prometheus 中对应的 Metrics 也少。nginx_exporter 主要就是获取 stub_status 中内建的指标。
  • 可以通过 nginx-vts-exporter 监控 Nginx 更多的指标,但 nginx-vts-exporter 依赖于 Nginx 编译安装是添加的第三方模块 nginx-module-vts 来实现,指标更为丰富。建议使用此种监控方式。

环境信息

  • Centos 7
  • Nginx stable 1.24.0
  • nginx-vts-exporter v0.10.3
  • nginx-module-vts v0.2.2

安装配置 nginx-vts-exporter 和 nginx-module-vts 来监控 Nginx Metrics

Nginx 编译安装 nginx-module-vts 模块

Nginx 编译安装 `nginx-module-vts` 模块

Nginx 安装了 nginx-module-vts 后,可以通过以下配置暴露运行时的指标

status.conf
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_host on;


server{
listen 8081;
server_name localhost;
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}

重启 Nginx 后,访问 http://localhost:8081/status 即可查看到 Nginx 运行时的指标

安装 nginx-vts-exporter

nginx-vts-exporter github 官网

wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
tar -xf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
cp nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter /usr/bin/

创建 systemd 管理配置文件 /usr/lib/systemd/system/nginx-vts-exporter.service

/usr/lib/systemd/system/nginx-vts-exporter.service

[Unit]
Description=nginx-vts-exporter
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/nginx-vts-exporter \
-nginx.scrape_timeout 10 \
-nginx.scrape_uri http://127.0.0.1:8081/status/format/json
Restart=on-failure
[Install]
WantedBy=multi-user.target

启动服务,默认监听端口为 9913

systemctl enable --now nginx-vts-exporter

浏览器访问 localhost:9913/metrics 即可看到 nginx-vts-exporter 暴露出来的 Metrics

之后 Prometheus 可通过 9913 端口抓取监控数据。

环境信息

  • AlertManager 0.24.0

部署配置 AlertManager

AlertManager 是一个专门用于实现告警的工具,可以实现接收 Prometheus 或其它应用发出的告警信息,并对这些告警信息进行 分组抑制 以及 静默 等操作,然后通过 路由 的方式,根据不同的告警规则配置,分发到不同的告警路由策略中。 [1]

AlertManager 常用的功能主要有:

  • 抑制 - 抑制是一种机制,指的是当某一告警信息发送后,可以停止由此告警引发的其它告警,避免相同的告警信息重复发送。
  • 静默 - 静默也是一种机制,指的是依据设置的标签,对告警行为进行静默处理。如果 AlertManager 接收到的告警符合静默配置,则 Alertmanager 就不会发送该告警通知。
  • 发送告警 - 支持配置多种告警规则,可以根据不同的路由配置,采用不同的告警方式发送告警通知。
  • 告警分组 - 分组机制可以将详细的告警信息合并成一个通知。在某些情况下,如系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警信息合并为一个告警通知,从而避免一次性发送大量且属于相同问题的告警,导致无法对问题进行快速定位。

部署 AlertManager

本文部署配置基于 K8S 上安装 Prometheus 并监控 K8S 集群

在名为 prometheus-server-confConfigMap 中为 AlertManager 创建配置文件 alertmanager.yml,并将其挂载到 AlertManager 容器中

alertmanager.yml
global:
resolve_timeout: 5m

route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 5m
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://localhost:8080/alert_manager_webhook'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']

使用为 Prometheus 创建的 PVC 作为 AlertManager 的持久存储,参考以下配置部署 AlertManager

apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus-pod
namespace: prometheus
labels:
app: prometheus-server
spec:
replicas: 1
selector:
matchLabels:
app: prometheus-server
template:
metadata:
labels:
app: prometheus-server
spec:
containers:
- name: prometheus
image: prom/prometheus
args:
- "--storage.tsdb.retention.time=12h"
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus/"
ports:
- containerPort: 9090
resources:
requests:
cpu: 500m
memory: 500M
limits:
cpu: 1
memory: 1Gi
volumeMounts:
- name: prometheus-config-volume
mountPath: /etc/prometheus/
- name: prometheus-storage-volume
mountPath: /prometheus/
subPath: prometheus
- name: grafana
image: grafana/grafana
ports:
- containerPort: 3000
volumeMounts:
- name: prometheus-storage-volume
mountPath: /var/lib/grafana
subPath: grafana
- image: prom/alertmanager:v0.24.0
name: alert-manager
ports:
- containerPort: 9093
args:
- "--config.file=/etc/alertmanager/alertmanager.yml"
- "--web.external-url=http://alert-manager.example.com/"
- '--cluster.advertise-address=0.0.0.0:9093'
- "--storage.path=/alertmanager"
resources:
limits:
cpu: 1000m
memory: 512Mi
requests:
cpu: 1000m
memory: 512Mi
readinessProbe:
httpGet:
path: /-/ready
port: 9093
initialDelaySeconds: 5
timeoutSeconds: 10
livenessProbe:
httpGet:
path: /-/healthy
port: 9093
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- name: prometheus-storage-volume
mountPath: /alertmanager
subPath: alertmanager
- name: prometheus-config-volume
mountPath: /etc/alertmanager
volumes:
- name: prometheus-config-volume
configMap:
defaultMode: 420
name: prometheus-server-conf

- name: prometheus-storage-volume
persistentVolumeClaim:
claimName: prometheus-pvc
---
apiVersion: v1
kind: Service
metadata:
name: prometheus-service
namespace: prometheus
spec:
ports:
- name: prometheus-port
port: 8090
protocol: TCP
targetPort: 9090
- name: grafana-port
port: 3000
targetPort: 3000
- name: alert-manager-port
port: 9093
targetPort: 9093
selector:
app: prometheus-server

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-ui
namespace: prometheus

spec:
ingressClassName: nginx
rules:
- host: prometheus.example.com
http:
paths:
- backend:
service:
name: prometheus-service
port:
number: 8090
path: /
pathType: Prefix
- host: grafana.example.com
http:
paths:
- backend:
service:
name: prometheus-service
port:
number: 3000
path: /
pathType: Prefix
- host: alert-manager.example.com
http:
paths:
- backend:
service:
name: prometheus-service
port:
number: 9093
path: /
pathType: Prefix

部署成功后,从 AlertManager 的域名访问,可以看到 AlertManager 的 web UI

阅读全文 »

如上图所示,在每个数据中心部署单独的 Prometheus Server,用于采集当前数据中心监控数据。并由一个中心的 Prometheus Server 负责聚合多个数据中心的监控数据。这一特性在 Promthues 中称为 Federation (联邦集群)。

Prometheus Federation (联邦集群)的核心在于每一个 Prometheus Server 都包含一个用于获取当前实例中监控样本的接口 /federate。对于中心 Prometheus Server 而言,无论是从其他的 Prometheus 实例还是 Exporter 实例中获取数据实际上并没有任何差异。

以下配置示例在中心 Prometheus Server 配置其抓取其他 Prometheus Server 的指标,必须至少有一个 match 配置,以指定要抓取的目标 Prometheus Server 的 Job 名称,可以使用正则表达式匹配抓取任务

scrape_configs:
- job_name: 'federate'
scrape_interval: 15s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="prometheus"}'
- '{__name__=~"job:.*"}'
- '{__name__=~"node.*"}'
static_configs:
- targets:
- '192.168.77.11:9090'
- '192.168.77.12:9090'

__name__ 是 Prometheus 特殊的预定义标签,表示指标的名称
使用以下配置采集目标 Prometheus Server 的所有指标

params:
'match[]':
- '{job=~".*"}'

cAdvisor 是 Goolgle 开发的用来监控容器运行指标的工具,使用 Go 语言开发。Kubelet 集成了 cAdvisor 来监控采集 Pod 中的容器的运行指标。 [1]

可以直接使用 vAdvisor 配合 Prometheus 来监控 Docker/Containerd 容器运行指标,并配合 Prometheus 及 Grafana 进行图形展示或告警

环境信息

  • cAdvisor version v0.47.0 (c7714a77)
  • Docker Engine - Community 20.10.9

在 host 上二进制安装部署 cAdvisor

下载二进制包,即可直接运行程序

wget https://github.com/google/cadvisor/releases/download/v0.47.0/cadvisor-v0.47.0-linux-amd64

chmod +x cadvisor-v0.47.0-linux-amd64

./cadvisor-v0.47.0-linux-amd64

运行之后,默认监听 8080 端口,启动后访问 UI : http://localhost:8080。Prometheus 会读取 http://localhost:8080/metrics 暴露的指标。

cAdvisor metrics

cAdvisor metrics 官方说明

cAdvisor 主机节点中可以使用以下命令列出收集到的指标

curl localhost:8080/metrics

监控容器是否在运行中

cAdvisor 的指标 container_last_seen 记录了最后一次检测到容器运行时的时间 (Gauge),如果容器停止运行,这个值会停留在最后一次观察到容器运行的时间,可以通过此指标,使用以下表达式来监控容器是否在运行

container_last_seen - container_last_seen offset 1m == 0

脚注

安装

执行以下命令安装 Go 环境

Go 安装包下载地址

wget https://go.dev/dl/go1.14.15.linux-amd64.tar.gz

tar -xf go1.14.15.linux-amd64.tar.gz -C /usr/local/

echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bash_profile

source ~/.bash_profile

执行 go 命令

$ go version
go version go1.20.5 linux/amd64

常见错误

bad ELF interpreter

安装后执行 go 报错

-bash: /usr/local/go/bin/go: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

问题原因 为下载的 go 与运行的目标系统不兼容,比如下载了 x86 的安装包,安装到了 64 位的 OS 上。