L B T

记 录 过 去 的 经 验

同一个域名使用不同的 HTTPS 重定向规则

在 Cloudflare 中,配置的规则 (比如 自动 HTPTPS 重写 功能) 对所有使用了 Cloudflare 加速的域名都生效。

此时假如有 2 个二级域名 d1.abc.comd2.abc.com,都启用了 Cloudflare 加速功能,此时开启 自动 HTPTPS 重写 功能,则使用 HTTP 协议访问,都会被重定向到 HTTPS。假如域名 d2.abc.com 不想进行 HTTPS 重定向,即使用 HTTP 访问 d2.abc.com 不重定向到 https://d2.abc.com。要实现此功能,参考以下步骤

  1. 首先在 SSL/TLS –> 边缘证书开启 自动 HTPTPS 重写 功能,关闭 始终使用 HTTPS 功能

  2. 自动 HTPTPS 重写 中配置规则,参考下图,定义规则名称,选择 自定义筛选表达式,在表达式中配置筛选条件匹配 d2.abc.com,在下面的设置中 关闭 自动 HTPTPS 重写 功能

通过以上配置即可实现,同一个域名的不同子域名有不同的重定向规则。其他类似需求也可参考此思路配置

阅读全文 »

环境信息

  • Python 3
  • Django 4

request 常用参数及方法

  • request.method : 返回当前请求的 HTTP 方法(GET、POST、PUT、DELETE 等)。

  • request.path : 返回请求的路径部分(不包括域名和查询参数)。

  • request.GET : 包含所有 GET 请求参数的字典。

  • request.GET.get('param_name') : 用于从 GET 请求中获取指定参数的值。

  • request.POST : 包含所有 POST 请求参数的字典。

  • request.POST.get('param_name') : 用于从 POST 请求中获取指定参数的值。

  • request.FILES : 包含所有上传文件的字典。

  • request.COOKIES : 包含所有请求的 Cookie 的字典。

  • request.session : 一个表示当前会话的对象,可以用于访问和存储会话数据。

  • request.user : 表示当前登录用户的对象。

  • request.body : 访问请求的主体内容(即请求的正文部分)。主体内容通常用于传输 POST 或 PUT 请求中的数据,如表单数据、JSON 数据等。

  • request.META : 包含有关请求的所有元数据的字典,如请求的 IP 地址、浏览器信息等。

  • request.is_secure() : 返回一个布尔值,表示请求是否通过 HTTPS。

  • request.is_ajax() : 返回一个布尔值,表示请求是否为 AJAX 请求。

  • request.get_full_path() : 返回包含完整路径和查询参数的字符串。

  • request.build_absolute_uri() : 根据当前请求构建完整的绝对 URL。

  • request.get_host() : 返回请求的主机部分。

  • request.get_port() : 返回请求的端口号。

  • request.get_raw_uri() : 返回原始的请求 URI。

  • request.get_signed_cookie() : 用于获取已签名的 Cookie 值。

  • request.get_host() : 返回请求的主机部分。

环境信息

  • Centos 7
  • Docker 19.03.15

docker 配置容器日志 rotate

docker daemon 方式配置容器日志 rotate

编辑 docker daemon 配置文件 /etc/docker/daemon.json (若不存在则新建),添加以下内容,用来配置 docker containers 的日志轮转

/etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}

重启 docker 服务生效

systemctl restart docker

根据以上配置,当容器日志大小达到 100m,即对其进行 rotate,并保留最多 3 个日志文件。

使用 OS 系统服务 logrotate 进行容器日志 rotate

Linux 系统中有专门用来做日志 rotate 的 服务 logrotate,可直接使用此服务做 log rotate

配置针对 docker 的 logrotate 配置

/etc/logrotate.d/docker
/var/lib/docker/containers/*/*.log {
daily
rotate 5
copytruncate
missingok
compress
delaycompress
maxsize 100M
minsize 1024k
}

使用 copytruncate 的方式做日志 totate 时,会先拷贝日志文件为 totate 日志文件,然后 truncate 日志,确保 totate 过程中,日志文件不变并一直保持打开状态。

阅读全文 »

环境信息

  • Python 3.11
  • Django 4.1

使用方法

在 Django 4.1 中,使用静态文件的方法与之前的版本相同。以下是使用静态文件的步骤:

  1. settings.py 中设置静态文件目录:

    settings.py
    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
    BASE_DIR / "static",
    ]
    • STATIC_URL 是静态文件 URL 的前缀。
    • STATICFILES_DIRS 是一个列表,其中包含要在其中查找静态文件的目录。
  2. 在 HTML 文件中使用静态文件

    {% load static %}
    <!DOCTYPE html>
    <html>
    <head>
    <title>My Static File Example</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
    </head>
    <body>
    <img src="{% static 'images/logo.png' %}" alt="My logo">
    <script src="{% static 'js/script.js' %}"></script>
    </body>
    </html>

    在上面的示例中,我们使用了 Django 模板语言的 {% static %} 标记来引用静态文件。{% load static %} 指令必须在使用 {% static %} 标记之前加载,以确保 Django 能够正确解析它们。

  3. 运行 collectstatic 命令:
    当您准备部署您的 Django 应用程序时,您需要将静态文件收集到一个单独的目录中,以便可以轻松地在生产服务器上提供它们。您可以使用 Django 的 collectstatic 命令来完成此操作。在命令行中运行以下命令:

    python manage.py collectstatic

    Django 将在 STATIC_ROOT 目录中创建一个新的静态文件目录,并将您的静态文件从 STATICFILES_DIRS 中指定的目录复制到该目录中。您可以在 settings.py 文件中设置 STATIC_ROOT 目录的路径

DTL 语法

load static

参考说明

block.super

用来从父 block 中继承选项

{% load static %}

{% block extrahead %}
{{ block.super }}
<link href="{% static 'bootstrap/css/bootstrap.css' %}" rel="stylesheet" />
<link href="{% static 'bootstrap/css/base.css' %}" rel="stylesheet" />
{% endblock %}

include

假设有两个 HTML 文件:header.htmlcontent.html
header.html 包含页面的头部内容。

header.html
<!-- header.html -->
<header>
<h1>My Website</h1>
<nav>
<!-- 导航栏内容 -->
</nav>
</header>

content.html 包含页面的主要内容。

content.html
<!-- content.html -->
<section>
<h2>Welcome to our website!</h2>
<p>This is the main content of the page.</p>
</section>

现在,可以在另一个 HTML 文件中使用 {% include %} 标签来包含这些内容。

main_template.html
<!-- main_template.html -->
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
{% include 'header.html' %}

<div class="content">
{% include 'content.html' %}
</div>

<footer>
<!-- 页脚内容 -->
</footer>
</body>
</html>

在这个示例中,{% include 'header.html' %}{% include 'content.html' %} 标签会将相应的模板文件的内容包含在 main_template.html 中。这样,就可以在一个模板中包含另一个模板的内容了。

url 反向解析

在模板中不推荐使用 url 硬编码,建议使用 url 反向解析功能,在 urls.py 中定义 url 时,给 url 命名,在模板中 可以使用反向解析使用 url,避免使用 url 硬编码。需要在 urls.py 中配置 app_name = 'polls',否则会因为 namespace 不清楚而报错:'polls' is not a registered namespace

from django.urls import path
from . import views

app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]

以上事例中,name='index' 为 url 命名,在模板中通过以下方式使用 url 名称 [1]

<a href="{% url 'polls:index' %}">首页</a>
阅读全文 »

环境信息

  • Django 4.4
  • Modular Admin v1.4.0

常见错误

because its MIME type (‘text/html’) is not a supported stylesheet MIME type

使用 Django 模板语法加载 index.html 中的静态文件后,有个 app.css 文件请求 404,Console 中报错: because its MIME type ('text/html') is not a supported stylesheet MIME type

问题原因 在 Modular Admin 代码中搜索 app.css,除了 index.html 引用了此文件,js/app.js 也引用了此文件。在 Django 中使用次模板,需要修改此处的路径正确。

常用修改事项说明

菜单项的展开标签

要在页面中让菜单处于展开状态,需要给菜单应用 active open 的 class

<li>
<a href="">
<i class="fa fa-area-chart"></i> Charts <i class="fa arrow"></i>
</a>
<ul class="sidebar-nav">
<li>
<a href="charts-flot.html"> Flot Charts </a>
</li>
<li>
<a href="charts-morris.html"> Morris Charts </a>
</li>
</ul>
</li>
<li class="active open">
<a href="">
<i class="fa fa-table"></i> Tables <i class="fa arrow"></i>
</a>
<ul class="sidebar-nav">
<li class="active">
<a href="static-tables.html"> Static Tables </a>
</li>
<li>
<a href="responsive-tables.html"> Responsive Tables </a>
</li>
</ul>
</li>
<li>
<a href="forms.html">
<i class="fa fa-pencil-square-o"></i> Forms </a>
</li>

环境信息

  • Kibana 8.8

常用概念

Spaces

在 Kibana 中,一个 space 相当于一个新的的 Kibana 实例,它分割了 Kibana 中的资源,使它和其他 space 隔离。 [3]

Kibana 默认的 Space 为 Default

Roles

Roles 是一个权限集,可以将 Roles 分配给 users、*system accounts*。可以自定义 roles,或者使用系统内置的 roles。以下是一些常用的 built-in roles

  • kibana_admin - 超级管理员组,绑定到这个组的用户对 Kibana 拥有完全权限,包括管理 Spaces

Users

user 可以绑定到一个或者多个 roles

阅读全文 »

环境信息

  • Kibana 8.8

Space 管理

创建 Space 参考

space 不能隔离 roleuser,这属于 Elasticsearch 的安全功能,roleuser 对整个 Kibana 实例都可见,不与特定的 space 关联。也不能隔离 index,因为这是 Elasticsearch 中的资源

space 隔离以下资源:

  • data view - 不同 space 中的 data view 互不可见。
  • Dashboard

Roles 管理

创建 role 参考

内置 role:

  • view - 此角色拥有对所有 Kibana space 的 只读权限。如果想要创建对 Kibana 所有 space 拥有只读权限的用户,只需要将用户绑定到此角色即可。

Users 管理

创建 role 参考

创建只读用户

Kibana 内置的 view 角色拥有对所有 Kibana space 的 只读权限。如果想要创建 对 Kibana 所有 space 拥有只读权限 的用户,只需要将用户绑定到此角色即可。

如果需要创建对特定 space 拥有只读权限的用户,可以参考以下步骤:

  1. 创建针对特定 space 具有只读权限的 role,如下图,创建 ops space 拥有只读权限的 role
  2. 创建用户并绑定到新建的 role

data view

创建 data view

Discover 管理

修改 Discover 中默认显示的最大文档数量

Discover 中默认最多显示 500 条文档,如果 Elasticsearch 中索引的文档数量超过500,默认不显示,也无法通过 Kibana 搜索到。要修改此值,参考以下步骤

  1. 找到 Discover 页面的右上角的 Options 按钮,点击弹出的 View Discover settings
  2. Space Settings 中,找到选项 Maximum rows per table,起默认值为 500,修改此值

KQL

KQL(Kibana Query Language)是 Kibana 中用于进行查询的查询语言。KQL 可以帮助用户在 Kibana 的 “Discover”(发现)页面、”Visualize”(可视化)页面以及 “Dashboard”(仪表盘)页面等地方快速构建查询,并过滤和分析数据。

参考链接

Kibana 官方文档

环境信息

  • elasticsearch 8.8.2

集群状态

查看集群健康状态

Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 集群健康 , 它在 status 字段中展示为 greenyellow 或者 red

  • green - 所有的主分片和副分片都正常运行
  • yellow - 所有主分片都正常运行,但不是所有的副本分片都正常运行
  • red - 有主分片没能正常运行

分片 概念说明

$ curl 'http://localhost:9200/_cluster/health'
{"cluster_name":"elasticsearch","status":"green","timed_out":false,"number_of_nodes":1,"number_of_data_nodes":1,"active_primary_shards":1,"active_shards":1,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":0,"active_shards_percent_as_number":100.0}

$ curl 'http://localhost:9200/_cluster/health?pretty'
{
"cluster_name" : "elasticsearch",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 1,
"active_shards" : 1,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}

查看集群节点信息

使用 _cat/nodes API 可以获取集群中所有节点的信息,包括它们的 IP 地址、堆内存使用情况、CPU 使用情况等。

# curl -u elastic:XhScf5Jqw -XGET 'http://172.31.25.229:9200/_cat/nodes?pretty'
172.31.25.229 58 98 9 1.86 2.27 2.36 dilm - node-1
172.31.30.249 54 98 10 2.05 2.12 2.30 dilm - node-2
172.31.21.225 65 91 0 0.00 0.04 0.05 dfilmrt * node-3

# curl -u elastic:XhScf5Jqw -XGET 'http://172.31.25.229:9200/_cat/nodes?v'
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.31.25.229 51 99 10 2.11 2.33 2.37 dilm - node-1
172.31.30.249 49 99 9 1.96 2.06 2.25 dilm - node-2
172.31.21.225 40 91 0 0.03 0.04 0.05 dfilmrt * node-3

输出信息说明

  • heap.percent - JVM 堆内存使用的百分比。这是节点分配给 Java 虚拟机堆的内存使用量的百分比。
  • ram.percent - 节点的物理内存(RAM)使用率的百分比
  • cpu - 节点的CPU使用率百分比
  • node.role - 节点的角色。各个字母含义如下
    • d - 代表数据节点 Data Node。负责存储数据,执行与数据相关的操作,如 CRUD(创建、读取、更新、删除)、搜索和聚合。
    • i - 代表摄取节点 Ingest Node。用于预处理文档,然后再将其索引到 Elasticsearch 中,它们可以运行摄取管道,这些管道可以执行各种转换,如提取数据、转换数据格式、添加信息等。
    • l - 代表机器学习节点 Machine Learning Node。机器学习节点专门用于运行Elasticsearch的机器学习功能,它们可以分析数据,识别模式,执行异常检测等。
    • m - 代表主节点 Master Node。主节点负责管理集群的全局状态,例如哪些索引存在,哪个节点是哪个索引的一部分等,它们还负责集群重新分片、索引创建、删除等操作。
    • r - 代表远程集群客户端节点 Remote Cluster Client Node。这些节点用于连接到远程集群,它们使得可以从一个集群中执行跨集群搜索和其他操作
    • t - 代表转换节点 Transform Node。转换节点用于运行 Elasticsearch 中的转换任务,这些任务可以将现有的 Elasticsearch 索引数据重新整理和汇总成新的索引。
  • * - 表示这个节点是当前的主节点。

使用 _nodes/stats 查看集群中所有节点的详细状态和统计信息

# curl -u elastic:XhScf5JqwVsSQwHe -XGET 'http://172.31.25.229:9200/_nodes/stats?pretty'
{
"_nodes" : {
"total" : 3,
"successful" : 3,
"failed" : 0
},
"cluster_name" : "es-cluster",
"nodes" : {
"TrQqg_8HTDiKBt6t8Z1JVw" : {
"timestamp" : 1699941330544,
"name" : "node-1",
"transport_address" : "172.31.25.229:9300",
"host" : "172.31.25.229",
"ip" : "172.31.25.229:9300",
"roles" : [
"ingest",
"master",
"data",
"ml"
],
"attributes" : {
"ml.machine_memory" : "133483876352",
"xpack.installed" : "true",
"ml.max_open_jobs" : "20"
},
"indices" : {
"docs" : {
"count" : 1725702315,
"deleted" : 0
},
"store" : {
"size_in_bytes" : 1766657662877
},
"indexing" : {
"index_total" : 28053218,
"index_time_in_millis" : 6610781,
"index_current" : 1,
"index_failed" : 0,
"delete_total" : 0,
"delete_time_in_millis" : 0,
"delete_current" : 0,
"noop_update_total" : 0,
"is_throttled" : false,
"throttle_time_in_millis" : 0
},
...

参考以下命令查看指定节点的详细状态和统计信息,Endpoint 格式参考 _nodes/{nodeId}/stats?pretty

# curl -u elastic:XhScf5JqwVsSQwHe -XGET 'http://172.31.25.229:9200/_nodes/TrQqg_8HTDiKBt6t8Z1JVw/stats?pretty' 
{
"_nodes" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"cluster_name" : "es-cluster",
"nodes" : {
"TrQqg_8HTDiKBt6t8Z1JVw" : {
"timestamp" : 1699941591263,
"name" : "node-1",
"transport_address" : "172.31.25.229:9300",
"host" : "172.31.25.229",
"ip" : "172.31.25.229:9300",
"roles" : [
"ingest",
"master",
"data",
"ml"
],
"attributes" : {
"ml.machine_memory" : "133483876352",
"xpack.installed" : "true",
"ml.max_open_jobs" : "20"
},
"indices" : {
"docs" : {
"count" : 1726608289,
"deleted" : 0
},
"store" : {
"size_in_bytes" : 1768415039992
},
"indexing" : {
"index_total" : 29016441,
"index_time_in_millis" : 6829570,
"index_current" : 0,
"index_failed" : 0,
"delete_total" : 0,
"delete_time_in_millis" : 0,
"delete_current" : 0,
"noop_update_total" : 0,
"is_throttled" : false,
"throttle_time_in_millis" : 0
},

获取集群级别的信息和统计数据

/?pretty 参数的主要作用为通过添加缩进和换行增强输出的可读性

$ curl 'http://localhost:9200/?pretty'
{
"name" : "b5f96e32c638",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "UAiC0qVVT-Ov4nJFvoE1HA",
"version" : {
"number" : "8.8.2",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "98e1271edf932a480e4262a471281f1ee295ce6b",
"build_date" : "2023-06-26T05:16:16.196344851Z",
"build_snapshot" : false,
"lucene_version" : "9.6.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}

阅读全文 »

环境信息

  • Centos7 3.10.0-1062.9.1.el7
  • elasticsearch 8.8.2

elasticsearch 下载

elasticsearch 下载页面

安装 elasticsearch

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.8.2-linux-x86_64.tar.gz
tar -xzf elasticsearch-8.8.2-linux-x86_64.tar.gz
cd elasticsearch-8.8.2/

启动

./bin/elasticsearch

首次启动 Elasitcsearch 时,安全特性默认被启用,以下的安全选项会自动配置: [2]

  • 认证鉴权功能会被启用,并且会为默认的超级用户 elastic 产生一个密码
  • 生成 TLS 证书,并配置证书以启用 TLS 功能
  • 为 Kibana 产生一个 enrollment key,有效期 30 分钟

要以 daemon 的形式运行 Elasticsearch,使用 -d 选项,使用 -p 选项将 PID 记录到一个文件里面

./bin/elasticsearch -d -p pid

RPM 安装 Elasticsearch 官方参考文档不同版本具有不同的配置,根据版本选择对应配置

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

$ cat /etc/yum.repos.d/elasticsearch.repo
[elasticsearch]
name=Elasticsearch 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=0
autorefresh=1
type=rpm-md

$ yum install --enablerepo=elasticsearch elasticsearch

配置文件示例

elasticsearch.yml
cluster.name: es-cluster1
node.name: es-cluster1-node1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

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

discovery.seed_hosts: ["172.31.26.116", "172.31.19.164", "172.31.21.3"]
cluster.initial_master_nodes: ["es-cluster1-node1", "es-cluster1-node2", "es-cluster1-node3"]

xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.security.http.ssl.enabled: false

加入节点到集群

默认情况下,只有同一个主机上的节点才能在 没有其他配置的情况下 加入到集群。如果要让另一个主机上的节点加入到新启动的节点的集群中,需要更改配置,首先要修改 Elasticsearch 的监听地址,确保另一台主机能连接它(不是默认监听的 localhost[2]

加入开启了安全功能的集群

要将新节点加入到开启了安全功能的集群,首先要创建一个 enrollment token。在集群中的任一节点上执行以下命令,创建 enrollment token

bin/elasticsearch-create-enrollment-token -s node

要加入集群的节点上,使用以下命令启动 Elasticsearch,使用 --enrollment-token 传递 enrollment token

bin/elasticsearch --enrollment-token <enrollment-token>

新节点上的 Elasticsearch 会自动在 config/certs 下面生成证书和 Key

阅读全文 »

环境信息

  • elasticsearch 8.8.2

安全相关配置管理

更新 transport ssl 证书

在启用安全配置(xpack.security.enabled: true)的情况下,Elasticsearch 集群节点间通信(transport 默认端口 9300)必须使用 TLS (xpack.security.transport.ssl.enabled: true)。默认使用的证书文件位于 /etc/elasticsearch/certs/。若需要更新或者重新生成此证书,可以参考以下步骤

  1. 生成 CA,如果已有 CA 可跳过此步骤。此命令会生成一个 CA 证书文件,默认名称为 /usr/share/elasticsearch/elastic-stack-ca.p12。根据提示使用 证书密码,如果不配置密码,使直接Enter
    elasticsearch-certutil ca
  2. 为 Elasticsearch 生成 TLS 证书,证书使用 CA 进行签名,根据提示输入 CA 证书密码等信息,如果无密码,使直接Enter 键。默认生成文件 /usr/share/elasticsearch/elastic-certificates.p12
    elasticsearch-certutil cert --ca elastic-stack-ca.p12
  3. 执行以下命令,将 CA 证书密码和服务器证书密码写入 /etc/elasticsearch/elasticsearch.keystore
    # elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
    Setting xpack.security.transport.ssl.keystore.secure_password already exists. Overwrite? [y/N]y
    Enter value for xpack.security.transport.ssl.keystore.secure_password:

    # elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
    Setting xpack.security.transport.ssl.truststore.secure_password already exists. Overwrite? [y/N]y
    Enter value for xpack.security.transport.ssl.truststore.secure_password:
  4. 将上面生成的 CA 证书服务器证书 以及 证书密码文件 拷贝到 Elasticsearch 集群的所有节点的 /etc/elasticsearch/certs/ 下,并修改权限
    chmod 660 /etc/elasticsearch/certs/*
    chown root:elasticsearch /etc/elasticsearch/certs/*
  5. 重启 Elasticsearch 集群的所有节点
    systemctl restart elasticsearch
  6. 检查集群状态
    # curl --user newadmin:password localhost:9200/_cluster/health?pretty
    {
    "cluster_name" : "es-cluster1",
    "status" : "green",
    "timed_out" : false,
    "number_of_nodes" : 3,
    "number_of_data_nodes" : 3,
    "active_primary_shards" : 18,
    "active_shards" : 37,
    "relocating_shards" : 0,
    "initializing_shards" : 0,
    "unassigned_shards" : 0,
    "delayed_unassigned_shards" : 0,
    "number_of_pending_tasks" : 0,
    "number_of_in_flight_fetch" : 0,
    "task_max_waiting_in_queue_millis" : 0,
    "active_shards_percent_as_number" : 100.0
    }

重置用户密码

可以使用以下命令,创建新的超级管理员账号。首先要 确保集群状态正常

elasticsearch-users useradd newadmin -p password -r superuser

接下来使用刚刚创建的账号密码对原有的账号(如 elastic) 进行密码重置

# curl -s --user newadmin:password -XPUT "http://localhost:9200/_security/user/elastic/_password?pretty" -H 'Content-Type: application/json' -d '{
"password": "password1"
}'


密码重置成功后,尝试使用新账号密码访问集群

# curl --user elastic:password1 localhost:9200/_cluster/health?pretty
{
"cluster_name" : "es-cluster1",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 19,
"active_shards" : 39,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
阅读全文 »

530 Login incorrect

报错信息: 登录时报错 530 Login incorrect
错误原因

/etc/pam.d/vsftpd
auth  required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed 

默认情况下,/etc/vsftpd/ftpusers里面的用户是被拒绝登录的,确保要登录的用户不在此文件中

/etc/pam.d/vsftpd
auth       required    pam_shells.so  

此配置指定,只允许登录shell为/etc/shells中的shell的用户登录
如果用户shell为/sbin/nologin,则不允许登录,可改为pam_nologin.so

阅读全文 »

环境信息

  • Centos 7
  • Vsftpd 3.0.2

vsftpd虚拟用户通过映射系统用户权限的方式,使虚拟用户具有和本地系统用户一样的权限,或者灵活的控制虚拟用户的权限(不和本地用户权限相同,不能高于本地权限),达到访问权限的灵活控制,同时防止大批vsftpd用户添加到系统账号库中,使系统用户管理变动臃肿。

阅读全文 »

场景

远程登录 windows 失败,报错:

由于没有远程桌面授权服务器可以提供许可证,远程会话连接已断开,请跟服务器管理员联系

解决方法

  1. 打开 cmd,执行以下命令远程登录无法登录的 Windows 主机
    mstsc /v:1.1.1.1 /admin
  2. 打开注册表


3. 找到路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\GracePeriod.如果超过120天后RCM下面会有一个GracePeriod,先备份这项注册表,再删除除了默认的的注册表项。

  1. 重启电脑后生效.

环境信息

  • Centos 7
  • predixy-1.0.5

安装

下载地址, clone或下载最新的版本或指定版本下载后解压

yum install libstdc++-static -y
cd predixy-1.0.5
make
cp src/predixy /usr/local/bin/

需要依赖 libstdc++-static, 否则make会报错:
/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
make[1]: *** [predixy] Error 1
make[1]: Leaving directory `/root/predixy-1.0.5/src’
make: *** [default] Error 2

配置文件说明

  • predixy.conf,整体配置文件,会引用下面的配置文件

  • cluster.conf,用于Redis Cluster时,配置后端redis信息

  • sentinel.conf,用于Redis Sentinel时,配置后端redis信息

  • auth.conf,访问权限控制配置,可以定义多个验证密码,可每个密码指定读、写、管理权限,以及定义可访问的健空间

  • dc.conf,多数据中心支持,可以定义读写分离规则,读流量权重分配

  • latency.conf, 延迟监控规则定义,可以指定需要监控的命令以及延时时间间隔

启动

predixy /predixy/conf/predixy.conf

使用默认的配置文件predixy.conf, predixy将监听地址0.0.0.0:7617,后端的redis是Redis Cluster 127.0.0.1:6379

环境信息

  • 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对象实例