婚礼用品
伴手礼选择
伴娘伴手礼
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
香薰、香水 | 香薰礼盒 | |
化妆品 | ||
花果茶 | ||
喜糖礼盒 | 佳偶良缘 喜糖礼盒 |
参考链接:
20款百元左右的高级感伴手礼
伴郎伴手礼
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
茶 | 过宋小湯四季养生礼盒 UMTEA 关心茶礼盒 |
|
葡萄酒 | 名庄95分 蓝风铃甜白葡萄酒 | |
点心 | 马卡龙甜点糕点铁盒 |
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
香薰、香水 | 香薰礼盒 | |
化妆品 | ||
花果茶 | ||
喜糖礼盒 | 佳偶良缘 喜糖礼盒 |
参考链接:
20款百元左右的高级感伴手礼
类别 | 产品类别推荐 | 详情参考 |
---|---|---|
茶 | 过宋小湯四季养生礼盒 UMTEA 关心茶礼盒 |
|
葡萄酒 | 名庄95分 蓝风铃甜白葡萄酒 | |
点心 | 马卡龙甜点糕点铁盒 |
根据更新的比特币价格数据和计算,如果每年元旦买入BTC,次年元旦卖出,直到2024年,每年的投资回报率(ROI)如下:
查看 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 |
Centos 7 默认的内核版本 3.10 在运行 kubernetes 时存在不稳定性,建议升级内核版本到新版本
Centos 7 升级内核kubernetes 目前未实现对 SELinux 的支持,因此必须要关闭 SELinux
sudo setenforce 0 |
配置集群所有节点的防火墙,确保所有集群节点之间具有完全的网络连接。
FORWARD
链的流量*filter |
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-network-cidr
配置,并在安装网络插件时在其 YAML 文件中修改为对应的网段。 [4]
--control-plane-endpoint
选项用来配置 api-server
的共享地址,可以是域名或者负载均衡器的 IP。 [2]
如果是单主节点的 Kubernetes 集群,想要扩展成为多个 Master 节点(高可用),初始化时没有 --control-plane-endpoint
,是不被支持的。
因此为了后期可以由单个 Master 节点扩展为多个 Master 节点,即高可用,初始化节点时,建议加上此选项配置 api-server
的负载均衡地址。
<– more –>
kubeadm init
初始化集群成功后,会产生一个 kubeconfig
文件 /etc/kubernetes/admin.conf
,此配置中包含了一个绑定到 cluster-admin
的 ClusterRole 的组,其拥有对整个集群的控制权,不要将其共享给任何人。[3]
kubeadm init
初始化集群成功后,同时会生成一个名为 super-admin.conf
的 kubeconfig
文件,其中配置的超级用户可以跳过 authorization layer
,比如 RBAC。不要将其共享给任何人。建议将其保存在一个安全的位置。
在 Kubernetes 集群中,节点名称(Node Name)唯一的标识一个节点。在一个集群中,不能有多个名称一样的节点,Kubernetes 系统默认同一个 节点名(Node Name) 的实例将具有同样的一个状态和属性 [7]
将节点标记为 不可调度(unschedulable ) 会阻止系统调度新的 Pod 到节点上,但是不会影响节点上已有的 Pod。
Label 主要用来给 Kubernetes 中的对象添加 可识别属性。 Label 可以提供高效的查询和匹配以选择 Kubernetes 中的对象,Lables 可以在对象创建时或者运行过程中随时做变更。
不具有识别属性的信息 不建议用作 Labels,而是应该写入 Annotations 中。[5]
Label Key 由 2 部分构成:
kube-scheduler
, kube-controller-manager
, kube-apiserver
, kubectl
) 或者第三方自动化组件为对象添加 labels 时必须带有前缀(prefix)。kubernetes.io/
and k8s.io/
是为 Kubernetes 核心系统保留的前缀Annotations 的 Key 命名规则和 Label Key 基本一致 [6]
API Server 请求 kubelet
的主要目的包括: [8]
kubectl
) Attach 到 Pods 中的容器kubelet
的端口转发功能。默认情况下,API 服务器不检查
kubelet
的服务证书。这使得此类连接容易受到中间人攻击, 在非受信网络或公开网络上运行也是 不安全的。
为了对这个连接进行认证,使用--kubelet-certificate-authority
标志给 API 服务器提供一个根证书包,用于kubelet
的服务证书。
从 API 服务器到节点、Pod 或服务的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。 这些连接可通过给 API URL 中的节点、Pod 或服务名称添加前缀 https: 来运行在安全的 HTTPS 连接上。 不过这些连接既不会验证 HTTPS 末端提供的证书,也不会提供客户端证书。 因此,虽然连接是加密的,仍无法提供任何完整性保证。 这些连接 目前还不能安全地 在非受信网络或公共网络上运行。 [8]
Kubernetes 支持使用 SSH tunnels 来加密从 API 到 nodes 的链接(目前已经处于废弃状态,推荐使用 Konnectivity service 替代)。
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 默认(同一个节点)串行的拉取镜像,即同一时间只发送一个拉取镜像的请求到 Registry Server,其他的拉取镜像的请求保持等待,直到当前请求处理完成。多个节点上的镜像拉取请求是隔离的,即不同的节点在同一时间是并行的拉取镜像的。 [10]
如果要配置一个节点上的 Kubelet 并行的拉取镜像,可以在 kubelet 的配置中配置 serializeImagePulls
为 false
,前提是 Registry Server 和 CRI 支持并行拉取镜像。
Pod 的状态字段(status
) 是一个 PodStatus Object。其中包含 phase
字段。phase
字段描述/记录了 Pod 在其整个生命周期中所处的阶段 [11]
phase
字段可以有以下值:
Value | Description |
---|---|
Pending |
Kubernetes 集群已经接收到创建 Pod 的请求,并且开始调度到节点、下载容器镜像并启动容器,但是有一个或多个容器还未正常运行 |
Running |
Pod 已经被调度到某个节点,并且 Pod 中所有的容器已经被创建,至少其中的一个容器已经处于运行状态或重启中 |
Succeeded |
Pod 中所有的容器都已经成功终止,并且不会再被重启 |
Failed |
Pod 中所有的容器都被终止,但至少有一个容器终止失败,也就是说,容器要么以非零状态码退出或者是被系统终止 |
Unknow |
因为某些原因,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 查看 |
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 掉这一个容器并重启之,不会影响其他容器
几乎所有的 Kubernetes 对象都包含两个嵌套的对象字段:
spec
- 对象的期望状态(desired state
)的描述信息status
- 对象当前的状态(current state
)Kubernetes 系统的目标就是不停的调整对象的当前状态(current state
)直到和期望状态(desired state
)匹配。
在想要创建的 Kubernetes 对象所对应的 .yaml
文件中,必须配置的字段如下:[1]
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一标识对象的一些数据,包括一个 name
字符串、UID
和可选的 namespace
spec
- 你所期望的该对象的状态帮助唯一标识对象的一些数据,包括一个 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 启动之后,会根据配置文件中配置的数据收集路径启动 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
命令常用功能 [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%,也是广义和田玉中的一种。罗甸玉石性很重,料子干涩,缺乏油性,其实所谓的“籽料”也只能用来骗骗小白玩友;广西大化玉则是这几年才出现的玉种,也是广义和田玉中的一种,大化玉里有籽料,质地也很细腻,有兴趣的宝友可以玩一玩。
错误场景 :
Pod
状态显示 CrashLoopBackOff
$ kubectl get pods |
查看 Pod
详细信息
$ kubectl describe pod test-centos7-7cc5dc6987-jz486 |
结果显示,Reason
为 BackOff
,Message
显示 Back-off restarting failed container
可能原因 :
Back-off restarting failed container
的原因,通常是因为,容器内 PID 为 1 的进程退出导致(通常用户在构建镜像执行 CMD
时,启动的程序,均是 PID 为1)[1]
容器进程退出(命令执行结束或者进程异常结束),则容器生命周期结束。kubernetes 控制器检查到容器退出,会持续重启容器。针对此种情况,需要检查镜像,是否不存在常驻进程,或者常驻进程异常。
针对此种情况,可以单独使用 docker
客户端部署镜像,查看镜像的运行情况,如果部署后,容器中的进程立马结束或退出,则容器也会随之结束。
定位中也可以使用 kubectl describe pod
命令检查 Pod 的退出状态码。Kubernetes 中的 Pod ExitCode 状态码是容器退出时返回的退出状态码,这个状态码通常用来指示容器的执行结果,以便 Kubernetes 和相关工具可以根据它来采取后续的操作。以下是一些常见的 ExitCode 状态码说明:
ExitCode 0
: 这表示容器正常退出,没有错误。这通常是期望的结果。ExitCode 1
: 通常表示容器以非正常方式退出,可能是由于应用程序内部错误或异常导致的。通常是容器中 pid 为 1 的进程错误而失败ExitCode 非零
: 任何非零的状态码都表示容器退出时发生了错误。ExitCode 的具体值通常是自定义的,容器内的应用程序可以根据需要返回不同的状态码来表示不同的错误情况。你需要查看容器内应用程序的文档或日志来了解具体的含义。ExitCode 137
: 通常表示容器因为被操作系统终止(例如,OOM-killer
)而非正常退出。这可能是由于内存不足等资源问题导致的。ExitCode 139
: 通常表示容器因为接收到了一个信号而非正常退出。这个信号通常是 SIGSEGV
(段错误),表示应用程序试图访问无效的内存。ExitCode 143
: 通常表示容器因为接收到了 SIGTERM
信号而正常退出。这是 Kubernetes 在删除 Pod 时发送的信号,容器应该在接收到该信号后做一些清理工作然后退出。ExitCode 130
: 通常表示容器因为接收到了 SIGINT
信号而正常退出。这是当用户在命令行中按下 Ctrl+C
时发送的信号。ExitCode 255
:通常表示未知错误,或者容器无法启动。这个状态码通常是容器运行时的问题,比如容器镜像不存在或者启动命令有问题。kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock |
选项 | 说明 | 示例 |
---|---|---|
--pod-network-cidr |
指定 pod 的 cidr,安装 CNI 插件时,配置的 CIDR 要和此处一致 | |
--service-cidr |
service 使用的 CIDR |
|
--cri-socket |
配置集群使用的 CRI,不指定时系统会扫描主机,如果有多个可用 CRI,会出现提示 | |
--apiserver-advertise-address |
手动配置 api-server 的 Advertise IP 地址。不配置的情况下,系统默认选择主机上的默认路由对应网卡上面的 IP |
|
--control-plane-endpoint |
配置 api-server 的共享地址,可以是域名或者负载均衡器的 IP单节点的 Master 后期需要扩展为多节点(高可用)时,需要有此配置,否则不支持( kubeadm )扩展 |
kubeadm join 172.31.10.19:6443 --token 8ca35s.butdpihinkdczvqb --discovery-token-ca-cert-hash sha256:b2793f9a6bea44a64640f99042f11c4ff6 \ |
其中的 token
可以在 master 上使用以下命令查看
$ kubeadm token list |
默认情况下,令牌会在 24 小时后过期。如果要在当前令牌过期后将节点加入集群, 则可以通过在控制平面节点上运行以下命令来创建新令牌:
kubeadm token create |
如果你没有 --discovery-token-ca-cert-hash
的值,则可以通过在控制平面节点上执行以下命令链来获取它[1]:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ |
适用版本信息说明
- filebeat 7
- elasticsearch 7
filebeat 7.5.2 上传数据到 Elasticsearch 报错:
# journalctl -f -u filebeat |
此错误原因是由于 Elasticsearch 的集群中打开的分片数量超过了集群的最大分片限制。在 Elasticsearch 中,每个索引由多个分片组成,而集群有一个设置的最大分片数限制。这个限制是为了防止分片数过多导致性能问题。
错误消息 {"type":"illegal_argument_exception","reason":"Validation Failed: 1: this action would add [2] total shards, but this cluster currently has [6924]/[3000] maximum shards open;"}
显示当前集群已有 6924 个分片,超过了 3000 个的限制。
要解决这个问题,可以考虑以下几个选项:
调整 Elasticsearch 集群设置,增加最大分片数限制
可以通过更改 Elasticsearch 配置来增加最大分片数的限制。但请注意,这可能会导致性能问题,尤其是如果硬件资源有限的话。
这可以通过修改 cluster.max_shards_per_node
设置来实现
PUT /_cluster/settings |
获取 Elasticsearch 集群的最大分片数限制
curl -X GET "http://[your_elasticsearch_host]:9200/_cluster/settings?include_defaults=true&pretty" |
删除一些不必要的索引 :如果有些索引不再需要,可以删除它们来减少分片数。
curl -X DELETE "localhost:9200/my_index" |
合并一些小索引:如果有很多小的索引,可以考虑将它们合并为更大的索引,以减少总分片数。
优化现有索引的分片策略:可以优化索引的分片数量,例如,通过减少每个索引的主分片数量。
适用版本信息说明
- filebeat 7
- elasticsearch 7
使用以下 filebeat 配置文件
filebeat.inputs: |
filebeat 启动后报错,elasticsearch 上未创建相应的索引,关键错误信息 Failed to connect to backoff(elasticsearch(http://1.57.115.214:9200)): Connection marked as failed because the onConnect callback failed: resource 'filebeat-7.5.2' exists, but it is not an alias
journalctl -f -u filebeat |
这表明 Filebeat 无法正常连接到 Elasticsearch 集群。出现这个问题的主要原因可能为:
索引/别名冲突: Filebeat 试图创建或使用一个名为 filebeat-7.5.2
的索引或别名,但这个资源在 Elasticsearch 中已存在且不是一个别名。解决方法为 删除或重命名冲突索引
ILM 配置问题
使用此配置文件,解决 索引/别名冲突 问题后,filebeat 运行正常,但是 Elasticsearch 上未创建配置中的索引 logstash-admin-*
,而是将数据上传到了索引 filebeat-7.5.2-*
。这个问题是由 ILM
导致,可以禁用 ILM
。参考以下配置,禁用 ILM
(setup.ilm.enabled: false
)
filebeat.inputs: |
常见选项
选项 | 说明 | 示例 |
---|---|---|
-v |
输出详细信息 | |
-0 |
内容输出到指定文件或设备 | curl -o /dev/null |
-s |
不输出任何信息(http 响应内容除外) | |
-w |
自定义输出内容 | curl -s -o /dev/null -w %{http_code} https://csms.tech |
-I |
只获取响应头部信息 | curl -I https://csms.tech |
--resolve yourdomain.com:443:source_ip |
将 domain:port 解析为指定的 IP |
使用方法参考curl -v -H "Host: admin.test.com" --resolve admin.test.com:443:52.52.2.9 https://admin.test.com |
-H, --header |
自定义 http 请求头部 | -H "Host: admin.test.com" |
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction)
,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
yum install -y nc |
Windows 下需要 下载 netcat 运行程序
下载后直接解压,将 nc.exe
复制到 C:\Windows\System32
目录或将 nc.exe
添加到系统 path 环境变量中
选项 | 说明 | 示例 |
---|---|---|
-v -vvv |
打印详细信息 | |
-t |
使用 TCP 协议,默认为 TCP 协议 | |
-u |
使用 UDP 协议,默认为 TCP 协议 | |
-z |
不发送数据,效果为立即关闭连接,快速得出测试结果 |
注意事项:客户端测试使用
localhost
作为主机名时,会优先被解析为 IPv6 地址,如果端口监听在 IPv4 地址,会导致测试结果不可达
以下输出表示端口可达
# nc -vuz ip/domain 8472 |
以下输出表示端口不可达
# nc -vuz 127.0.0.1 8473 |
wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz |
启动 etcd
# etcd |
# etcd --version |
etcd
创建集群涉及参数说明
name | 说明 | 命令行参数 |
---|---|---|
name |
每个集群成员的唯一名称 | --name=etcd0 |
initial-advertise-peer-urls |
群成员广播给集群其他成员(用于连接本节点)的 URL 默认为 http://IP:2380 |
--initial-advertise-peer-urls=http://10.0.0.10:2380 |
listen-peer-urls |
在这些(一个或多个) URL 上监听其他集群成员的连接请求 通信包括了集群管理任务、数据同步和心跳检测等 |
http://10.0.0.10:2380,http://127.0.0.1:2380 |
listen-client-urls |
该成员监听客户端连接的 URL。 默认端口 2379 | --listen-client-urls=http://10.0.0.10:2379,http://127.0.0.1:2379 |
advertise-client-urls |
该成员广播给客户端的 URL | --advertise-client-urls=http://10.0.0.10:2379 |
initial-cluster |
所有 etcd 成员的初始列表 |
--initial-cluster=etcd0=http://10.0.0.10:2380,etcd1=http://10.0.0.11:2380,etcd2=http://10.0.0.12:2380 |
data-dir |
etcd 数据的存储目录。 |
--data-dir=/var/lib/etcd |
initial-cluster-token |
初始集群的唯一标识符,用于区分不同的 etcd 集群 |
--initial-cluster-token=my-etcd-token |
initial-cluster-state |
初始集群状态,可以是 new 或 existing 。通常在引导新集群时使用 new ,而在添加或删除成员时使用 existing 。 |
--initial-cluster-state=new |
quota-backend-bytes |
etcd 的后端数据库大小的硬限制,默认是 2GB |
--quota-backend-bytes=3000000000 |
cert-file key-file |
用于 HTTPS 的证书和私钥 | --cert-file=/etc/kubernetes/pki/etcd/server.crt --key-file=/etc/kubernetes/pki/etcd/server.key |
trusted-ca-file |
客户端和对等体的验证所需的 CA 证书 | --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt |
client-cert-auth |
启用客户端证书验证,默认为 false |
--client-cert-auth |
listen-peer-urls
和 initial-advertise-peer-urls
的区别说明:
listen-peer-urls
这个参数指定了 etcd
成员应该在哪些地址和端口上监听来自其他 etcd
成员的请求(数据同步、领导选举、集群更改等相关)
主要用途是定义哪个网络接口和端口号应该被 etcd
服务绑定,以便它可以接收来自其他成员的连接
initial-advertise-peer-urls
这个参数告诉 etcd
该如何 通告自己 给集群中的其他成员。这是其他集群成员用来联系此 etcd
成员的地址。
主要用途是 当新成员加入集群时,它需要通知其他成员自己的存在,以及如何与自己通信,因此它必须是个其他节点可达的 Endpoints,如 http://0.0.0.0:2380
就不行。
listen-client-urls
和advertise-client-urls
的区别同理
示例环境说明
主机 | IP | 角色 |
---|---|---|
etcd1 | 172.17.0.2/16 | etcd node |
etcd2 | 172.17.0.3/16 | etcd node |
etcd3 | 172.17.0.4/16 | etcd node |
分别在 3 个节点上执行以下 3 条命令,创建集群
etcd1
执行命令:
etcd --data-dir=data.etcd --name etcd1 \ |
etcd2
执行命令:
etcd --data-dir=data.etcd --name etcd2 \ |
etcd3
执行命令:
etcd --data-dir=data.etcd --name etcd3 \ |
检查节点健康状态
# ENDPOINT=http://172.17.0.3:2380,http://172.17.0.2:2380,http://172.17.0.4:2380 |
# etcdctl version |
Kubernetes 中查看 etcd
集群成员列表使用如下命令
# kubectl exec -n kube-system -it etcd-k8s-master1 -- sh -c "ETCDCTL_API=3 etcdctl member list --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key" |
指定输出格式为 table
# etcdctl member list --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --write-out=table |
输出内容说明如下:
3c087bf12db7a0f
: 集群中每一个成员的唯一 ID。started
: 集群成员的当前状态。started
表示活动的。k8s-master2
: etcd
集群成员的名字,通常与其主机名或节点名相对应https://172.31.30.115:2380
: Peer URLs
,其他 etcd
成员用于与该成员通信的 URL。默认为 本地 IP 的 2380 端口https://172.31.30.123:2379
: Client URLs
,客户端用于与 etcd
成员通信的 URL。默认为 本地 IP 的 2379 端口Is Learner
: 表示该成员是否是一个 learner
。Learner 是 etcd
的一个新功能,允许一个成员作为非投票成员加入集群,直到它准备好成为一个完全参与的成员。false
表示它们都不是 learners
检查单个节点的集群配置状态
# etcdctl --write-out=table endpoint status --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key |
查看所有节点的集群配置状态
# ENDPOINTS=https://172.31.30.115:2379,https://172.31.29.250:2379,https://172.31.30.123:2379 |
containerd
服务默认配置文件为 /etc/containerd/config.toml
#root = "/var/lib/containerd" |
Containerd 有两个不同的存储路径,一个用来保存持久化数据,一个用来保存运行时状态。 [1]
#root = "/var/lib/containerd" |
root
- 用来保存持久化数据,包括 Snapshots, Content, Metadata 以及各种插件的数据。每一个插件都有自己单独的目录,Containerd 本身不存储任何数据,它的所有功能都来自于已加载的插件。state
- 用来保存临时数据,包括 sockets
、pid
、挂载点
、运行时状态
以及不需要持久化保存的插件数据。#oom_score = 0 |
Containerd 是容器的守护者,一旦发生内存不足的情况,理想的情况应该是先杀死容器,而不是杀死 Containerd。所以需要调整 Containerd 的 OOM 权重,减少其被 OOM Kill 的几率。oom_score
其取值范围为 -1000
到 1000
,如果将该值设置为 -1000
,则进程永远不会被杀死,建议 Containerd 将该值设置为 -999
到 0
之间。如果作为 Kubernetes 的 Worker 节点,可以考虑设置为 -999
。
默认的 containerd
服务的配置为 /usr/lib/systemd/system/containerd.service
[Unit] |
Delegate
- 这个选项允许 Containerd 以及运行时自己管理自己创建的容器的 cgroups。如果不设置这个选项,systemd
就会将进程移到自己的 cgroups 中,从而导致 Containerd 无法正确获取容器的资源使用情况。
KillMode
- 这个选项用来处理 Containerd 进程被杀死的方式。默认情况下,systemd
会在进程的 cgroup 中查找并杀死 Containerd 的所有子进程,这肯定不是我们想要的。KillMode
字段可以设置的值如下:
control-group
-(默认值)当前控制组里面的所有子进程,都会被杀掉process
- 只杀主进程。mixed
- 主进程将收到 SIGTERM
信号,子进程收到 SIGKILL
信号none
- 没有进程会被杀掉,只是执行服务的 stop 命令。 需要将 KillMode
的值设置为 process
,这样可以确保升级或重启 Containerd 时不杀死现有的容器。
ctr image pull docker.io/library/nginx:alpine |
$ ctr image ls |
$ ctr image mount docker.io/library/nginx:alpine /mnt |
卸载已挂载的镜像
ctr image unmount /mnt |
ctr container create docker.io/library/nginx:alpine nginx |
容器创建后,并没有开始运行,只是分配了容器运行所需的资源及配置的数据结构,这意味着 namespaces
、rootfs
和容器的配置都已经初始化成功了,只是用户进程(这里是 nginx
)还没有启动,容器(进程)状态的变化由 Task
对象实现,通过命令 ctr task
来管理。
启动 ctr container create
创建的容器
ctr task start nginx |
以上命令启动之前创建的容器 nginx
,未指定其他参数时,容器中的进程在系统前台运行,如需后台运行,可以使用选项 -d
ctr task start nginx -d |
也可以直接使用 run
命令,创建并启动容器
ctr run --rm -d docker.io/library/nginx:alpine nginx1 |
ctr container ls |
查看容器中进程的状态
$ ctr task ls |
查看容器中运行的所有的进程
$ ctr task ps nginx1 |
这里的 PID 是宿主机看到的 PID,不是容器中看到的 PID。
ctr container info nginx |
停止/删除容器中的进程
ctr task delete nginx -f |
以上命令删除/停止容器中的进程,但是并不删除容器,执行以上命令后再执行以下命令,可删除容器
ctr container delete nginx |
ctr 没有 stop 容器的功能,只能暂停或者杀死容器。
ctr task exec -t --exec-id 1 nginx1 sh |
执行 ctr task exec
进入容器,必须制定 --exec-id
,值可以随便指定。
Containerd 相比于 Docker ,多了 Namespace 的概念,使用以下命令,查看所有的 Namespace
$ ctr ns ls |
docker
默认使用 moby
的 Namespace,要使用 ctr
命令查看 docker
创建的容器,需要使用选项 -n moby
指定命名空间,否则 ctr
默认使用 default
命名空间,无法看到 moby
命名空间中的资源
ctr -n moby container ls |
Kubernetes 默认使用 k8s.io
命名空间。
ctr
没有配置或者环境变量可以来配置默认的 Namespace,在 Kubernetes 场景中,可以使用 alias
命令配置 ctr
,使其自动指向 k8s.io
的 Namespace
alias ctr='ctr -n k8s.io' |
prometheus
kubectl create namespace prometheus |
Prometheus 使用 Kubernetes API 从 Nodes、Pods、Deployments 等等中读取所有可用的指标。因此,我们需要创建一个包含读取所需 API 组的 RBAC 策略,并将该策略绑定到新建的 prometheus
命名空间。[1]
prometheusClusterRole.yaml
的文件,并复制以下 RBAC 角色。在下面给出的角色中,可以看到,我们已经往
nodes
,services endpoints
,pods
和ingresses
中添加了get
,list
以及watch
权限。角色绑定被绑定到监控命名空间。如果有任何要从其他对象中检索指标的用例,则需要将其添加到此集群角色中。
apiVersion: rbac.authorization.k8s.io/v1 |
kubectl apply -f prometheusClusterRole.yaml |
要将 Python 脚本打包为 Windows 可运行程序,一种常用的方法是使用 PyInstaller。
pip install pyinstaller |
在命令行中,导航到脚本所在的文件夹并运行以下命令
pyinstaller --onefile test_file.py |
这会生成一个 dist
目录,里面包含一个名为 test_file.exe
的可执行文件。参数 --onefile
确保所有必要的文件都被包含在单一的可执行文件中。
以上方法打包后的文件点击运行后,桌面会弹窗一个 cmd 窗口,如果关闭了此 cmd 窗口,与其关联的程序也会被关闭。为了阻止这个命令行窗口的出现,并让程序在关闭窗口后仍然运行,你需要在使用 PyInstaller 打包时使用 --noconsole
选项。此外,为了使程序在没有任何可视窗口的情况下静默运行(例如,仅在系统托盘中),你还需要使用 --windowed
选项。
pyinstaller --onefile --noconsole --windowed test_file.py |
如果你想要程序在系统托盘中静默运行,并通过系统托盘图标进行交互,那么你需要使用其他库,如
pystray
,来创建系统托盘应用。