YAML 语法格式
YAML(YAML Ain’t Markup Language)是一种专门用于数据序列化的格式,常用于配置文件、数据交换等场景。它以其可读性和简洁性而受到开发者的青睐。YAML设计的目标是易于人类阅读和编写,并且易于与其他编程语言进行交互。下面是YAML语法的详细介绍
基本结构
数据类型 :YAML 支持标量(如字符串、整数、浮点数)、序列(列表)和映射(字典)三种基本数据类型。
缩进 :YAML 使用缩进表示结构层级关系,通常每个层级缩进两个或四个空格(禁止使用制表符)。
标量数据类型
标量(Scalars) 是单个的、不可分割的值。可以是字符串、整数或浮点数。标量可以是单行的值,也可以是多行的值
# 单行字符串 |
多行字符串可以使用字面量样式(|
)或折叠样式(>
):
# 字面量样式保留换行符 |
- 可以显式指定数据类型,例如字符串可以用单引号或双引号包围
- 字符串通常不需要引号,但如果含有特殊字符,则需要使用单引号或双引号。
true
,false
,null
等特定词汇表示布尔值和Null
。- 时间和日期需要遵循ISO格式。
列表(Sequences)
列表(Sequences) 是一组按顺序排列的值(类似于数组或列表),用破折号加空格表示新的元素,每个列表项占一行,也需要正确缩进。
# 列表 |
字典(Mappings)
映射/字典(Mappings) 是键值对的集合(类似于字典或哈希表),用冒号加空格表示键值对,键值对需要正确缩进
# 字典 |
嵌套结构
列表和字典可以嵌套使用,形成复杂的结构
# 嵌套的列表和字典 |
锚点和别名
YAML支持定义锚点(&
)和别名(*
)来重用(引用)文档中的某部分,使用 &
创建一个锚点(alias),之后可以用 *
引用这个锚点。
使用 <<
和 *
来合并已有(引用)的映射。
# 使用锚点和别名 |
注释
使用井号 #
开始一个注释,井号后面的内容将被视为注释,注释内容直到行尾。
多文档支持
一个 YAML 文件可以包含多个文档,每个文档用三个短横线 ---
分隔。
--- |
Prometheus Process exporter 使用
安装部署
为 process-exporter
生成 systemd
服务启动配置文件:
[Unit] |
建议将 process-exporter
的配置写入文件并使用 -config.path
指定配置文件。
配置进程监控
process-exporter
在配置文件中使用模板变量来配置筛选要监控的进程,可以使用的模板变量包括:
变量 | 说明 | 示例 |
---|---|---|
{{.Comm}} |
匹配进程的命令名(不包括路径)。主要来源于 /proc/<pid>/stat 输出中的第二部分命令名是指进程执行时的名称。在 Linux 系统中,可以通过 /proc/<PID>/comm 文件来获取进程的命令名。例如,如果一个进程执行的命令是 /usr/local/bin/php ,那么它的命令名就是 php 。 |
|
{{.ExeBase}} |
匹配进程的可执行文件名,不包括路径 可执行文件名是指进程的完整路径的最后一个部分。例如,如果一个进程的完整路径是 /usr/local/bin/php ,那么它的可执行文件名就是 php 。 |
|
{{.ExeFull}} |
匹配进程的可执行文件的完整路径,例如 /usr/local/php73/bin/php |
|
{{.Username}} |
匹配进程的用户名 | |
{{.Matches}} |
匹配进程的命令行参数列表 | |
{{.StartTime}} |
||
{{.Cgroups}} |
监控系统上的所有进程
要监控系统上的所有进程的运行情况,可以参考以下配置: [1]
process_names: |
- 以上配置会获取到系统上的所有进程(子进程被统计入父进程中)
- 假如配置中有多个匹配项,以上配置不能放到第一个,否则因为其可以匹配到系统中所有的进程,后续配置的匹配不会再有机会生效
监控系统上面指定进程
假如系统中运行了多个 php
的子进程,为了获取到各个子进程的统计数据,可以参考以下配置
process_names: |
使用此配置,可以获取到系统中以下进程的统计数据:
/usr/local/php73/bin/php /home/www/admin/artisan Pulldata
/usr/local/php73/bin/php /home/www/admin/artisan schedule:run
/usr/local/php73/bin/php /home/www/admin/artisan queue:work
除可以获取到以上特定进程的统计数据外,还可以统计到除此之外的其他所有进程的统计数据。
因为配置中匹配进程的顺序的关系,假如系统中还有除此之外的其他
php
进程,那么由最后的{{.Comm}}
统计到的php
进程资源使用数据中不再包含前面 3 个特定进程的资源使用数据。
脚注
Nextcloud 安装配置
Nextcloud All-in-One
Nextcloud All-in-One 在一个 Docker 容器中提供了方便部署和维护的 Nextcloud 方式。[1]
使用 docker compose 部署
为方便后期管理及迁移,建议使用 docker compose
方式部署。docker-compose.yml
参考文件如下: [2]
version: "3" |
使用 docker compose
方式部署注意事项:
name: nextcloud_aio_mastercontainer
: Volume 名称必须是nextcloud_aio_mastercontainer
,否则会报错找不到卷nextcloud_aio_mastercontainer
:It seems like you did not give the mastercontainer volume the correct name? (The 'nextcloud_aio_mastercontainer' volume was not found.). Using a different name is not supported since the built-in backup solution will not work in that case!
启动成功后,根据提示在浏览器中打开 Nextcloud AIO setup
页面并记录页面显示的密码
You should be able to open the Nextcloud AIO Interface now on port 8080 of this server! |
根据页面提示登陆,跟随页面提示进行新实例初始化。
初始化过程中要提供域名,系统会自动为域名颁发证书(使用系统 443 端口映射到容器中的 8443 端口)
默认的 Nextcloud AIO 未部署反向代理,要使用反向代理请参考文档: Reverse Proxy Documentation
脚注
Prometheus 安装配置
环境信息
- Centos 7
- Prometheus Server 2.4
- Node Exporter v1.4.0
- Grafana v9.2.5
安装
在 Docker 中安装 Prometheus Server
创建 Prometheus Server 配置文件,如 /root/prometheus/prometheus.yml
,内容如下 [1]
# my global config |
使用 Docker 启动时挂载此文件,作为 Prometheus Server 的配置文件,之后需要修改配置,可以直接修改此文件。
docker run -d -p 9090:9090 \ |
启动后,可以通过 $Prometheus_IP:9090
访问 Prometheus Server UI
Prometheus Redis exporter 使用
Prometheus ValKey & Redis Metrics Exporter
Prometheus Redis Metrics Exporter 下载页面
redis_exporter 安装
wget https://github.com/oliver006/redis_exporter/releases/download/v1.59.0/redis_exporter-v1.59.0.linux-amd64.tar.gz |
为 redis_exporter
生成 systemd
服务配置文件 /usr/lib/systemd/system/redis_exporter.service
[Unit] |
启动 redis_exporter
服务
# systemctl daemon-reload |
redis_exporter
服务启动后,默认启动 9121
端口提供 Metrics 数据供 Prometheus 抓取。
redis_exporter 配置
redis 实例及认证信息配置
如果要通过一个 redis_exporter
实例监控多个 Redis 实例,可以参照以下配置文件配置 Redis 实例及其认证信息,如果无需密码认证,则保留密码项为空。
|
修改 redis_exporter
启动参数,使其读取上面配置的实例和其认证信息
/usr/bin/redis_exporter -redis.password-file /etc/redis_exporter_pwd_file.json |
配置 Prometheus 抓取 redis_exporter 指标
参考以下配置使用文件发现的方式配置被监控的 Redis 实例
|
targets-redis-instances.yml
文件内容包含 Targets 内容:
- labels: |
向 Telegram 发送消息
环境信息
- Centos 7
- Python 3
在 Telegram 中生成 Bot
首先在 telegram 中搜索
@BotFather
,和其对话,根据提示创建 机器人,记录下生成的token
信息创建新的 Channel 或者 Group 或者将刚刚新建的 Bot 加入已有的 Channel/Group。
获取 ChatGroup ID,可以使用以下方法之一
添加机器人
@getmyid_bot
到 Channel,会自动显示Chat ID
使用以下代码获取
>>> import requests
>>> response = requests.get(f'https://api.telegram.org/bot{token}/getUpdates')
>>> data = response.json()
>>> chat_id = data['result'][0]['message']['chat']['id']
>>> chat_id
-992754669
使用 curl 向 telegram 发送消息
$ curl -v "https://api.telegram.org/bot{token}/sendMessage?text=sa&chat_id=-992754669" |
使用 python 向 telegram 发送消息
使用 requests 库
>>> import requests |
使用 telegram 库
需要安装 python-telegram-bot
pip install --upgrade python-telegram-bot |
发送消息代码
>>> import telegram |
如果需要在非异步环境中(例如 Django 试图函数) 运行以上异步代码,会报错: RuntimeError: There is no current event loop in thread 'Thread-1'
。需要特殊处理,可以使用 asyncio.run()
函数来运行异步代码,它可以在非异步环境中创建一个新的事件循环并运行异步函数。
Django 视图中参考代码如下
def send_message_to_tg(chat_id: int, text: str): |
Nginx 安装及升级
本文档主要做为需要安装或升级 Nginx 版本或者需要重新编译 Nginx 为其添加新模块时的参考。Nginx 服务常用配置说明
环境信息
- Centos 7 5.4.225-1
- nginx stable 1.24.0
编译安装 Nginx
编译安装 Nginx 之前,首先需要安装依赖包 [1]
pcre
cd /tmp |
zlib
cd /tmp |
openssl
cd /tmp |
编译安装 Nginx
下载 Nginx stable 版本编译安装
wget https://nginx.org/download/nginx-1.24.0.tar.gz |
要启用或者停用指定的 Nginx 自带模块,参考 Nginx 编译配置选项说明
此处编译配置添加第三方模块 nginx-module-vts
以支持 Prometheus。执行以下命令编译 Nginx 并添加第三方模块 nginx-module-vts
。Nginx 和 nginx-module-vts 版本兼容列表
wget https://github.com/vozlt/nginx-module-vts/archive/refs/tags/v0.2.2.tar.gz |
编译安装后的软件包,只需要安装好依赖,便可以迁移到其他机器上面使用,本文档编译安装后的软件包下载链接
为 Nginx 配置 systemd 管理配置文件
为了能使用 systemctl
管理源码编译安装的 nginx,可以为其使用以下配置文件将其托管到 systemd
[Unit] |
Prometheus 采集 Nginx 监控数据
参考步骤安装 nginx-module-vts
模块,以支持 Prometheus 采集 Nginx 统计数据。
如果要统计 Nginx 所有的 vhost 数据,则将 nginx-module-vts
模块相关配置放置于 http
模块内,否则可以在只想要监控(统计)的 vhost (server
配置段) 中添加配置。
nginx-module-vts
模块相关配置命令说明:
命令 | 说明 | 用法示例 |
---|---|---|
vhost_traffic_status_zone |
定义 vhost_traffic_status 模块使用的共享内存区域。用于存储虚拟主机的流量统计信息 |
vhost_traffic_status_zone shared_memory_name size; shared_memory_name 是共享内存区域的名称,size 是共享内存区域的大小。 |
vhost_traffic_status_filter_by_host |
按主机名过滤虚拟主机状态信息 默认会将流量全部计算到第一个 server_name 上;启用后,只会显示与请求的主机名匹配的虚拟主机状态信息。 |
vhost_traffic_status_filter_by_host on; |
vhost_traffic_status_filter_by_set_key |
根据自定义键值对来过滤虚拟主机的状态信息 | vhost_traffic_status_filter_by_set_key $host$request_uri; |
vhost_traffic_status_filter_by_set_zone |
过滤器使用的共享内存区域 | |
vhost_traffic_status_display |
用于显示虚拟主机状态信息的格式 支持 json 、CSV 和 html |
vhost_traffic_status_display_format html; |
vhost_traffic_status_display_format |
用于显示虚拟主机状态信息的字段格式。 可以选择显示的字段有:request、status、request_time、request_length、request_method、request_uri、request_length、request_time、request_time_counter、request_time_counter_overflows、request_time_min、request_time_max、request_time_avg、request_time_median、request_time_percentile。 |
vhost_traffic_status_display_format field1 field2 ...; |
为了获取所有域名的统计信息,在 Nginx 的 http
模块内添加以下配置:
http { |
重载配置后查看请求内容:
# curl localhost:8888/status |
统计信息输出结果支持多种格式:
localhost:8888/status/format/json
- Jsonlocalhost:8888/status/format/html
- Htmllocalhost:8888/status/format/jsonp
- Jsonplocalhost:8888/status/format/prometheus
- Prometheuslocalhost:8888/status/format/control
- control
在 Prometheus 中添加以下 Targets 配置抓取 nginx-module-vts
模块暴露出的统计信息
- job_name: "Nginx" |
在 Prometheus 中检查抓取到的数据
常见错误
error while loading shared libraries
Nginx 编译安装成功后,启动报错
$ /usr/local/nginx-1.24.0/sbin/nginx -t |
问题原因 为 Nginx 在系统的库文件路径中未找到已经安装的 libpcre2-8.so.0
库文件。可以通过以下方式验证
- 搜索
libpcre2-8.so.0
,可以看到系统上已经存在此库文件/usr/local/lib/libpcre2-8.so.0
$ find / -name libpcre2-8.so.0
/usr/local/lib/libpcre2-8.so.0 - 检查此库文件是否在系统已加载的库文件中。执行以下命令搜索系统已经加载的库文件,发现没有
/usr/local/lib/libpcre2-8.so.0
$ ldconfig -p | grep libpcre
libpcre32.so.0 (libc6,x86-64) => /lib64/libpcre32.so.0
libpcre16.so.0 (libc6,x86-64) => /lib64/libpcre16.so.0
libpcreposix.so.0 (libc6,x86-64) => /lib64/libpcreposix.so.0
libpcrecpp.so.0 (libc6,x86-64) => /lib64/libpcrecpp.so.0
libpcre.so.1 (libc6,x86-64) => /lib64/libpcre.so.1 - 检查系统共享库文件的查找路径的配置文件
/etc/ld.so.conf
,发现其中不包括路径/usr/local/lib/
,因此位于此路径下的共享库文件无法被搜索到$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
要解决此问题,可以使用以下方法之一:
添加
/usr/local/lib/
到系统共享库查找路径配置文件/etc/ld.so.conf
/etc/ld.so.conf include ld.so.conf.d/*.conf
/usr/local/lib/执行以下命令,使配置生效
ldconfig
设置系统环境变量
LD_LIBRARY_PATH
,这个变量定义了系统共享库的查找目录。将/usr/local/lib
添加到此变量的值中,要永久生效需要将其写入配置文件,如~/.bash_profile
等export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
创建符号链接
ln -s /usr/local/lib/libpcre2-8.so.0 /usr/local/nginx-1.24.0/sbin/libpcre2-8.so.0
或者
ln -s /usr/local/lib/libpcre2-8.so.0 /lib64/libpcre2-8.so.0
SSL modules require the OpenSSL library
执行以下命令执行编译前配置时报错 ./configure: error: SSL modules require the OpenSSL library.
:
# ./configure --prefix=/usr/local/nginx-1.24.0 \ |
此报错原因为未找到 OpenSSL 的库文件。
针对此场景,可以通过在编译配置时指定 OpenSSL 的源码中库文件的具体位置(--with-openssl=/tmp/openssl-1.1.1t
),参考以下命令
./configure --prefix=/usr/local/nginx-1.24.0 \ |
Error 127
Nginx 执行 make
命令时报错: /bin/sh: line 2: ./config: No such file or directory
# ./configure --prefix=/usr/local/nginx-1.24.0 \ |
错误信息表明在编译 nginx 时,make
命令无法找到 OpenSSL 的配置脚本 config
。此脚本位于 OpenSSL 的源码目录中。可以通过 --with-openssl=/tmp/openssl-1.1.1t
指定。
修改编译前的配置命令如下:
./configure --prefix=/usr/local/nginx-1.24.0 \ |
getpwnam(“nginx”) failed
nginx 报错
nginx: the configuration file /usr/local/nginx-1.24.0/conf/nginx.conf syntax is ok |
问题原因 为 nginx
用户不存在,创建 nginx
用户或者修改配置文件,使用已有的用户运行 nginx
参考链接
脚注
Prometheus 指标汇总
环境信息
- Prometheus 2.44.0
- Grafana 9.5.2
- Kubernetes 1.24
Kubernetes 相关指标
Kubernetes 中部署并监控 Kubernetes 集群参考。配置 Prometheus 监控 Kubelet 之后可以采集到 Kubelet 监控指标。
配置 Prometheus 读取 cAdvisor 之后可以通过 cAdvisor 采集到容器相关的监控指标。
指标名称 | 类型 | 说明 | 示例 |
---|---|---|---|
kubelet_pod_start_duration_seconds_count |
Pod 启动的时间 | ||
kubelet_pod_start_duration_seconds_bucket |
Pod 启动的时间的延迟直方图数据 | kubelet_pod_start_duration_seconds_bucket{le="0.5"} |
|
kubelet_running_pods |
运行的 Pod 的数量 | ||
kubelet_running_containers |
运行的 Containers 的数量 | ||
kubelet_runtime_operations_errors_total |
Kubelet 和 CRI 交互产生的错误(类型) | ||
kubelet_started_containers_total |
Kubelet 启动的 Container 总数 | ||
kubelet_started_pods_total |
Kubelet 启动的 Pod 总数 | ||
kubelet_volume_stats_available_bytes |
PV Volume 可以使用的磁盘空间 | ||
kube_node_status_allocatable kube_node_status_capacity |
节点的可分配的 资源 数量 | kube_node_status_allocatable{resource="pods"} 节点可分配的 Pod 的数量 |
|
kubelet_started_pods_total |
Counter |
已启动的 Pod 数量 | |
container_cpu_usage_seconds_total |
Counter |
Container 使用的 CPU | |
container_memory_usage_bytes |
Gauge |
Pod 使用的内存 | container_memory_usage_bytes{namespace="default"} |
kube_pod_container_status_restarts_total |
Counter |
Pod 的重启次数 |
nginx-ingress-controller 相关指标
配置 Prometheus 监控 Ingress-Nginx-Controller 指标 后,Prometheus 可以读取到 Ingress-Nginx-Controller 暴露的监控指标。
Grafana 中配置使用 Ingress-Nginx-Controller 指标示例
指标名称 | 类型 | 说明 | 示例 |
---|---|---|---|
nginx_ingress_controller_requests |
Counter |
Ingress Nginx Controller 接收到的所有请求数,,包括各个状态码 | irate(nginx_ingress_controller_requests[2m]) - 请求速率 |
nginx_ingress_controller_nginx_process_connections |
连接数,包括各个状态码 | ||
nginx_ingress_controller_request_duration_seconds_sum |
请求持续时间的总和 请求持续时间是从请求进入 Ingress 控制器开始,到响应返回给客户端结束的整个时间 |
||
nginx_ingress_controller_request_duration_seconds_count |
请求持续时间的计数。 | 计算平均请求持续时间:平均请求持续时间 = 请求持续时间总和 / 请求持续时间计数 | |
nginx_ingress_controller_ingress_upstream_latency_seconds_sum |
upstream 占用时间的总和 upstream 占用时间是指请求从 Ingress 到达 upstream(backend)服务器的时间 |
||
nginx_ingress_controller_ingress_upstream_latency_seconds_count |
upstream 上游占用时间的计数 | 计算平均上游占用时间:平均上游占用时间 = 上游占用时间总和 / 上游占用时间计数。 |
node 相关指标
主机信息
包括 CPU 架构、内核版本、操作系统类型、主机名等,集中在指标 node_uname_info
中。
CPU
指标名称 | 类型 | 说明 | 示例 |
---|---|---|---|
node_cpu_seconds_total |
Counter |
CPU 使用时间 | node_cpu_seconds_total{mode="idle"} - CPU 空闲时间 |
统计节点 CPU 使用率
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) |
Memory
指标名称 | 类型 | 说明 | 示例 |
---|---|---|---|
node_memory_MemTotal_bytes |
Gauge |
总的内存 | |
node_memory_MemFree_bytes |
Gauge |
空闲内存 | |
node_memory_Cached_bytes |
Gauge |
Cache 内存 | |
node_memory_Buffers_bytes |
Gauge |
Buffers 内存 |
统计节点的 内存使用率
(node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Cached_bytes - node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100 |
Network
指标名称 | 类型 | 说明 | 示例 |
---|---|---|---|
node_network_receive_bytes_total |
Counter |
网卡接收的流量 | |
node_network_transmit_bytes_total |
Counter |
网卡发送的流量 |
网卡流量带宽
irate(node_network_receive_bytes_total{device!~"cni0|docker.*|flannel.*|veth.*|virbr.*|lo",kubernetes_io_hostname=~"$node"}[$prometheusTimeInterval]) |
Django model 使用
环境信息
- Python 3.10
- Django 4.1
在 Project/App 的 models.py
文件中创建 model
,当 model 定义完成,Django 会自动生产一个后台管理接口,允许认证用户添加、更改和删除对象,只需在管理站点上注册模型即可 [1]
创建 model
在 Project/App 的 models.py
文件中创建 model
from django.db import models |
对修改后的 model
进行 migrate
,以使在数据库中变更更改。
python manage.py makemigrations |
model 注册到后台
在 Project/App 的 admin.py
文件中注册 model
from django.contrib import admin |
更多有关 admin 配置方法,请参考 Django admin 配置
xshell 常用配置
婚礼用品
伴手礼选择
伴娘伴手礼
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
香薰、香水 | 香薰礼盒 | |
化妆品 | ||
花果茶 | ||
喜糖礼盒 | 佳偶良缘 喜糖礼盒 |
参考链接:
20款百元左右的高级感伴手礼
伴郎伴手礼
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
茶 | 过宋小湯四季养生礼盒 UMTEA 关心茶礼盒 |
|
葡萄酒 | 名庄95分 蓝风铃甜白葡萄酒 | |
点心 | 马卡龙甜点糕点铁盒 |
VB
根据更新的比特币价格数据和计算,如果每年元旦买入BTC,次年元旦卖出,直到2024年,每年的投资回报率(ROI)如下:
- 2013年买入,2014年卖出的ROI:约 5390.75%
- 2014年买入,2015年卖出的ROI:约 -57.01%
- 2015年买入,2016年卖出的ROI:约 37.21%
- 2016年买入,2017年卖出的ROI:约 131.78%
- 2017年买入,2018年卖出的ROI:约 1243.49%
- 2018年买入,2019年卖出的ROI:约 -72.10%
- 2019年买入,2020年卖出的ROI:约 92.07%
- 2020年买入,2021年卖出的ROI:约 308.63%
- 2021年买入,2022年卖出的ROI:约 62.51%
- 2022年买入,2023年卖出的ROI:约 -58.27%
- 2023年买入,2024年卖出的ROI:约 166.06%
aws cli 命令用法
环境信息
- aws-cli/2.9.15
常见用法
查看 aws
帮助信息
aws help |
查看子命令帮助信息
aws ec2 help |
配置认证信息时指定鉴权信息对应的 Profile
aws configure --profile source-account |
aws
命令常用选项
选项 | 说明 | 示例 |
---|---|---|
--region |
指定区域,aws 区域列表 | aws --region ap-east-1 ec2 describe-instances |
--profile |
指定配置文件名称。当需要同时操作多个账号上面的 S3 目标时,可以为每个账号指定 profile 名称,在后续操作时使用选项 --profile 指定要使用的 Profile |
kubernetes 理论知识点汇总
环境信息
- Kubernetes 1.29
kubeadm 初始化集群
Network setup
组件的 advertise IP 地址选择
Kubernetes 中的组件(如 Kubeadm
、Kube-apiserver
等)在初始化启动时,都需要在节点(主机)上找到一个合适的 IP 作为组件的 advertising
/listening
的地址。[1]
默认情况下,此 IP 是主机上默认路由对应的网卡所在的 IP。
# ip route show |
如果系统上有多个默认路由,组件会尝试使用第一个默认路由对应的网卡所在的 IP。如果系统上没有默认路由,并且未明确为组件配置 IP,组件会初始化失败并退出
组件选择的 IP 地址将会作为 X.509 证书的 SAN(Subject Alternative Name) 的一部分。因此在系统初始化运行之后修改 IP 需要重新签发证书并重启相关组件。
Pod 网段选择
Pod 的网段必须不能和主机网络重叠,如果选用的网络插件的网络和主机的网段重叠,必须为网络插件选择合适的和主机不同的网段,在集群初始化时通过参数 --pod-network-cidr
配置,并在安装网络插件时在其 YAML 文件中修改为对应的网段。 [4]
control-plane-endpoint 参数说明
--control-plane-endpoint
选项用来配置 api-server
的共享地址,可以是域名或者负载均衡器的 IP。 [2]
如果是单主节点的 Kubernetes 集群,想要扩展成为多个 Master 节点(高可用),初始化时没有 --control-plane-endpoint
,是不被支持的。
因此为了后期可以由单个 Master 节点扩展为多个 Master 节点,即高可用,初始化节点时,建议加上此选项配置 api-server
的负载均衡地址。
<– more –>
admin.conf 的重要性
kubeadm init
初始化集群成功后,会产生一个 kubeconfig
文件 /etc/kubernetes/admin.conf
,此配置中包含了一个绑定到 cluster-admin
的 ClusterRole 的组,其拥有对整个集群的控制权,不要将其共享给任何人。[3]
kubeadm init
初始化集群成功后,同时会生成一个名为 super-admin.conf
的 kubeconfig
文件,其中配置的超级用户可以跳过 authorization layer
,比如 RBAC。不要将其共享给任何人。建议将其保存在一个安全的位置。
Node
节点名称
在 Kubernetes 集群中,节点名称(Node Name)唯一的标识一个节点。在一个集群中,不能有多个名称一样的节点,Kubernetes 系统默认同一个 节点名(Node Name) 的实例将具有同样的一个状态和属性 [7]
配置节点为不可调度
将节点标记为 不可调度(unschedulable ) 会阻止系统调度新的 Pod 到节点上,但是不会影响节点上已有的 Pod。
Labels Selectors Annotations
Label 主要用来给 Kubernetes 中的对象添加 可识别属性。 Label 可以提供高效的查询和匹配以选择 Kubernetes 中的对象,Lables 可以在对象创建时或者运行过程中随时做变更。
不具有识别属性的信息 不建议用作 Labels,而是应该写入 Annotations 中。[5]
Label Key 由 2 部分构成:
- (可选的)前缀。系统组件(如
kube-scheduler
,kube-controller-manager
,kube-apiserver
,kubectl
) 或者第三方自动化组件为对象添加 labels 时必须带有前缀(prefix)。kubernetes.io/
andk8s.io/
是为 Kubernetes 核心系统保留的前缀 - (必须的)名字。
Annotations 的 Key 命名规则和 Label Key 基本一致 [6]
集群间通讯流量说明
API Server 到 kubelet
API Server 请求 kubelet
的主要目的包括: [8]
- 获取到 Pods 的日志
- (比如使用
kubectl
) Attach 到 Pods 中的容器 - 提供
kubelet
的端口转发功能。
默认情况下,API 服务器不检查
kubelet
的服务证书。这使得此类连接容易受到中间人攻击, 在非受信网络或公开网络上运行也是 不安全的。
为了对这个连接进行认证,使用--kubelet-certificate-authority
标志给 API 服务器提供一个根证书包,用于kubelet
的服务证书。
API Server 到 nodes, pods 和 services
从 API 服务器到节点、Pod 或服务的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。 这些连接可通过给 API URL 中的节点、Pod 或服务名称添加前缀 https: 来运行在安全的 HTTPS 连接上。 不过这些连接既不会验证 HTTPS 末端提供的证书,也不会提供客户端证书。 因此,虽然连接是加密的,仍无法提供任何完整性保证。 这些连接 目前还不能安全地 在非受信网络或公共网络上运行。 [8]
Kubernetes 支持使用 SSH tunnels 来加密从 API 到 nodes 的链接(目前已经处于废弃状态,推荐使用 Konnectivity service 替代)。
Leases
Kubernetes 使用 Lease API 来更新 kubelet
发送到 Kubernetes API Server 的心跳信息。Kubernetes 中的每一个节点在 kube-node-lease
Namespace 中都有一个 Lease
Object。kubelet
向系统上报心跳的过程,就是在更新对应的 Lease
Object 的 spec.renewTime
字段,Kubernetes 控制平面会使用这个上报的时间戳来决定节点是否可用 [9]
# kubectl describe lease -n kube-node-lease k8s-admin |
Leases 也被用来确保 HA 的组件(类似 kube-controller-manager
和 kube-scheduler
)在同一时刻只有一个实例提供服务,其他实例处于备用状态 [9]
kubelet
串行和并行拉取镜像
Kubelet 默认(同一个节点)串行的拉取镜像,即同一时间只发送一个拉取镜像的请求到 Registry Server,其他的拉取镜像的请求保持等待,直到当前请求处理完成。多个节点上的镜像拉取请求是隔离的,即不同的节点在同一时间是并行的拉取镜像的。 [10]
如果要配置一个节点上的 Kubelet 并行的拉取镜像,可以在 kubelet 的配置中配置 serializeImagePulls
为 false
,前提是 Registry Server 和 CRI 支持并行拉取镜像。
Pod
Pod 状态
Pod 的状态字段(status
) 是一个 PodStatus Object。其中包含 phase
字段。phase
字段描述/记录了 Pod 在其整个生命周期中所处的阶段 [11]
phase
字段可以有以下值:
Value | Description |
---|---|
Pending |
Kubernetes 集群已经接收到创建 Pod 的请求,并且开始调度到节点、下载容器镜像并启动容器,但是有一个或多个容器还未正常运行 |
Running |
Pod 已经被调度到某个节点,并且 Pod 中所有的容器已经被创建,至少其中的一个容器已经处于运行状态或重启中 |
Succeeded |
Pod 中所有的容器都已经成功终止,并且不会再被重启 |
Failed |
Pod 中所有的容器都被终止,但至少有一个容器终止失败,也就是说,容器要么以非零状态码退出或者是被系统终止 |
Unknow |
因为某些原因,Pod 的状态获取不到。这个经常发生在和 Pod 运行的节点通信异常时 |
Pod 中的容器的状态
Kubernetes 会跟踪 Pod 中每个容器的状态。一旦通过 Scheduler 将 Pod 分配到某个 Node,Kubernetes 会通过 CRI 创建 Pod 中的容器。
在 Kubernetes 中,容器可以有以下 3 种状态 [11]
Value | Description |
---|---|
Waiting |
表示容器正在进行必要的操作以正常启动,比如拉取镜像、应用 Secret 数据等。当容器处于此状态时,可以通过 kubectl describe pod 查看输出中对应容器的信息,一般会包含一个 Reason 字段简述 Waiting 的原因 |
Running |
表示容器在正常运行 |
Terminated |
表示容器运行结束或者因为某些原因失败。详细信息可以通过 kubectl describe pod 查看 |
QoS
Kubernetes 会根据 Pod 定义中的 resource requests and limits
将 Pod 划归到某一个 QoS 类中,Kubernetes 将会根据 QoS 类来决定在节点资源不足的情况下,哪些 Pod 将会被优先驱逐(Evict)。目前存在的 QoS 类主要有以下三个 [12]
QoS Class | 说明 | 被驱逐权重 |
---|---|---|
Guaranteed |
Pod 中的 每个容器必须定义 CPU & Mem request 和 limit ,并且 request 的值等于 limit 的值,确保系统会预留定义的资源给 Pod 和其中的容器 |
最后被驱逐 |
Burstable |
Pod 中 至少有一个容器定义了 CPU 或 Mem 的 request 。可以不定义 limit , 如果未定义 limit ,默认可以使用节点上所有可用的资源。 |
中间级别 |
BestEffort |
未定义任何 CPU 或 Mem 的 request 或 limit |
最先被驱逐 |
Memory QoS 基于系统内核的 cgroup v2 实现 [12]
Pod 中如果有个容器因为 Limit 被 kill,系统只会 kill 掉这一个容器并重启之,不会影响其他容器
脚注
- 1.Network setup ↩
- 2.Initializing your control-plane node ↩
- 3.admin.conf ↩
- 4.Installing a Pod network add-on ↩
- 5.Labels and Selectors ↩
- 6.Annotations Key Syntax and character set ↩
- 7.Node name uniqueness ↩
- 8.API server to kubelet ↩
- 9.Node heartbeats ↩
- 10.Serial and parallel image pulls ↩
- 11.Pod phase ↩
- 12.Quality of Service ↩
kubernetes 对象的 yaml 描述语法说明
环境信息
- Centos7 5.4.212-1
- Docker 20.10.18
- containerd.io-1.6.8
- kubectl-1.25.0
- kubeadm-1.25.0
- kubelet-1.25.0
几乎所有的 Kubernetes 对象都包含两个嵌套的对象字段:
spec
- 对象的期望状态(desired state
)的描述信息status
- 对象当前的状态(current state
)
Kubernetes 系统的目标就是不停的调整对象的当前状态(current state
)直到和期望状态(desired state
)匹配。
常用字段说明
必需字段
在想要创建的 Kubernetes 对象所对应的 .yaml
文件中,必须配置的字段如下:[1]
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一标识对象的一些数据,包括一个name
字符串、UID
和可选的namespace
spec
- 你所期望的该对象的状态
metadata
帮助唯一标识对象的一些数据,包括一个 name
字符串、UID
和可选的 namespace
集群中的每一个对象都有一个 名称(name
)来标识在同类资源中的唯一性。name
也用来作为 url 中的资源名称 [2]
每个 Kubernetes 对象也有一个 UID(uid
)来标识在整个集群中的唯一性。
apiVersion: apps/v1 |
标签和选择算符
标签(labels) 是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。[3]
通过 标签选择算符,客户端/用户可以识别一组对象。标签选择算符 是 Kubernetes 中的核心分组原语。
对于某些 API 类别(例如
ReplicaSet
)而言,两个实例的标签选择算符不得在命名空间内重叠, 否则它们的控制器将互相冲突,无法确定应该存在的副本个数。
比较新的资源,例如 Job
、 Deployment
、 ReplicaSet
和 DaemonSet
, 也支持基于集合的需求。
selector: |
matchLabels
是由 {key,value}
对组成的映射。 matchLabels
映射中的单个 {key,value}
等同于 matchExpressions
的元素, 其 key
字段为 key
,operator
为 In
,而 values
数组仅包含 value
。 matchExpressions
是 Pod 选择算符需求的列表。 有效的运算符包括 In
、NotIn
、Exists
和 DoesNotExist
。 在 In
和 NotIn
的情况下,设置的值必须是非空的。 来自 matchLabels
和 matchExpressions
的所有要求都按 逻辑与 的关系组合到一起 – 它们必须都满足才能匹配。
字段选择器
字段选择器(Field selectors) 允许你根据一个或多个资源字段的值 筛选 Kubernetes 资源
下面是一些使用字段选择器查询的例子:
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
下面这个 kubectl
命令将筛选出 status.phase
字段值为 Running
的所有 Pod:
kubectl get pods --field-selector status.phase=Running |
不同的 Kubernetes 资源类型支持不同的字段选择器。 所有资源类型都支持 metadata.name
和 metadata.namespace
字段。 使用不被支持的字段选择器会产生错误
你可在字段选择器中使用 =
、==
和 !=
(=
和 ==
的意义是相同的)操作符。 例如,下面这个 kubectl
命令将筛选所有不属于 default
命名空间的 Kubernetes 服务:
kubectl get services --all-namespaces --field-selector metadata.namespace!=default |
同标签和其他选择器一样, 字段选择器可以通过使用逗号分隔的列表组成一个选择链。 下面这个 kubectl
命令将筛选 status.phase
字段不等于 Running
同时 spec.restartPolicy
字段等于 Always
的所有 Pod:
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always |
你能够跨多种资源类型来使用字段选择器。 下面这个 kubectl
命令将筛选出所有不在 default
命名空间中的 StatefulSet
和 Service
:
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default |
filebeat 使用详解
环境信息
- Filebeat 8.8
Filebeat 启动之后,会根据配置文件中配置的数据收集路径启动 1 个或者多个 inputs
。针对匹配到的每个文件,Filebeat 都会启动一个对应的 harvester
,每个 harvester
读取一个单独的文件内容,并将其中的新内容发送到 libbeat
,libbeat
会整合数据并将其发送到配置的 output
[1]
如果 input
类型为 log
,input
会负责找到配置中匹配到的文件,并为每个文件启动一个 harvester
。每个 input
都运行在自己独立的 Go routine
(例程) 中。 [4]
Filebeat 会将收割(harvest
) 的每个文件的状态存储到 registry
。因此如果要让 Filebeat 从头开始收集数据,只需要删除 registry
文件即可。可以使用命令 filebeat export config
找到 data
目录,registry
位于其中。
安装
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.8.2-x86_64.rpm |
filebeat command-line interface
filebeat
命令常用功能 [3]
子命令 | 说明 | 示例 |
---|---|---|
help |
查看命令帮助信息filebeat help COMMAND_NAME [FLAGS] |
|
export |
导出 配置 等信息 | export 使用 |
modules |
模块管理命令。用来 enable 或者 disable 位于 modules.d 中的 模块 filebeat modules disable MODULE filebeat modules enable MODULE filebeat modules list |
Data collection modules |
run |
启动 filebeat | |
test |
测试配置文件 或者到 output 的连接filebeat test config filebeat test output |
|
version |
显示当前版本信息 |
和田玉知识归纳
和田玉的分类
山料和籽料
按照矿产分类,主要分为籽料与山料两种。
山料,是籽料的前身。
山料
和田玉山料 产自昆仑山脉之中,属于原生矿,被称为 璞玉
从质地上说,有的山料的结构较为粗糙,颗粒比较明显或带石性,不带皮色,油性差,有的山料靠近外部有红糖的颜色。也有结构细密,油润度极好的优质山料。
山料因为没有受到河流的冲刷,自始至终都深藏在岩体中,缺乏外力的打磨,看起来比较干涩,所以外形大多平淡无奇,有棱有角,表面也比较干涩,绺裂现象明显。
籽料
和田玉籽料 是采自河床或者河床泥土中,经过几十万年的侵蚀打磨而得到的玉石。有时又被称为 水籽
籽料是由山料在地质活动时冲刷或滚落到河里,由河水冲刷(还有风化、风干等物理反应一起作用)形成的。籽料产自 河流中下游,是次生矿。产自河流上游的被称为 山流水料。籽料因为长久受到河流的冲刷,一般为卵石形状,表面很光滑圆润,带皮色。
和山料的存在环境不同,导致籽料有了以下特性:
- 籽料常年在河水中浸泡,水流的压力使它的肉质变得更加紧密,水流的冲刷使它变的更加温润油腻,形成了它独特的质地和油润感;
- 河水中存在很多的矿物质和微量元素,长时间的水流冲刷和加压过程中,部分矿物质会沉淀到籽料中,形成各种颜色的籽料皮子。带有皮子的籽料,价格有大大提升
籽料开采出来,外观上看就与鹅卵石一般无二,各个颜色都有,只不过他是和田玉再形成的鹅卵石。仔细观察籽料表面会发现上面密密麻麻都是一些小孔,因为这些小孔跟我们皮肤上的毛孔相似被称之为毛孔或者皮孔。和田玉籽料一般有皮色和皮孔,就算没有皮色,籽料上还是能够找到均匀的毛细孔,这是籽料独有的标志。而山料则没有皮色皮孔。
一般情况下,籽料都会拥有或深或浅的皮色,表面还会有明显的小凹坑(也就是俗称的皮孔),这是玉石长时间在水中冲刷、浸泡和磕碰造成的。而山料由于生长环境固定,不存在皮色和皮孔。
同时,由于籽料长年累月泡在水中,水里的微生物和微量元素会渗入到玉石中,所以会造成局部呈现或黄或红或黑的颜色,也就是 沁色
。而这一点在山料身上,就非常不明显。
籽料的水润度是明显高于山料的,如果比较籽料和山料制作的成品,会很容易发现籽料表面质地非常润泽、光滑、细腻。而山料作品,即使经过抛光处理,表面仍会干涩,缺乏光滑的油润感,这一点用手触摸时尤为明显。
由于 和田玉籽料的密度比山料大,所以同等体积的情况下,籽料相对山料比较重
山料也有很多可以跟顶级籽料相媲美的。比如 1995 年于田县开采的 8 吨和田玉山料,白度细度等各个方面都是顶级。因品质极佳,入市后引起了轰动,后被称之位“95于田料”。时至今日,“95于田料” 在业内也是传说中的料子,被很多业内人士公认为 羊脂级。著名的和氏璧就是一块山料。
和田玉器的市场价格中羊脂玉最高、籽料高、山流水次之、山料更次之。
和田玉结构
和田玉籽料内部结构致密,用肉眼几乎看不到内部结构;而再好的山料,还是能看到其松软质地的结构。
籽料由于有外力的挤压、打磨,所以密度要明显高过山料。籽料的话,无论是青籽还是白籽,内部结构都是致密的,用肉眼几乎看不到内部结构。而山料,无论结构多致密,在强光手电筒下,总是能看到松软的质地结构。
广义的籽料
今天的籽料已不是传统意义上的和田籽料了。在广义和田玉的范围内,籽料也有了更多种类。
新疆产的岫玉籽料
新疆除了有和田玉籽料,还出产一种颜色或绿或黑绿色等,里面也有黑点存在的岫玉。岫玉中品质好的,外观与和田玉籽料很相似,并且在市场上的和田籽料中也能看到相当数量的岫玉籽料,大家要留意。
来自俄罗斯的“籽料”
俄罗斯玉,近年来随着和田料的减少而逐渐成为软玉舞台的有力竞争者。
从玉材来看,俄料95%都是山料,但也有籽料,只是俄料中的“籽料”并未达到籽料定义的产状玉料:籽料由于长期的冲刷搬运碰撞,玉质形态韧性都达到了特别的质感,而俄料中的“籽料”其实没有这个长期的过程,严格意义上只能算和田玉的山流水料。
辽宁产的河磨料
河磨料是国内确切命名的两种籽料之一,另一种是和田籽料。“河磨”,从河里磨出来的玉,名字起得很传神,可能因为河水的冲击力较小,河磨料多见厚皮料。
另外,近几年贵州罗甸也出产白度尚可的软玉,透闪石含量达95%,也是广义和田玉中的一种。罗甸玉石性很重,料子干涩,缺乏油性,其实所谓的“籽料”也只能用来骗骗小白玩友;广西大化玉则是这几年才出现的玉种,也是广义和田玉中的一种,大化玉里有籽料,质地也很细腻,有兴趣的宝友可以玩一玩。