ERA 在线部署

系统初始化

1.安装Debian11初始化文档初始化

1
2
3
#必装
apt install -y conntrack ipset socat ebtables ipvsadm
apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

一、k8s集群部署

1.安装kubekey

1
2
3
4
5
6
7
export KKZONE=cn
wget https://github.com/kubesphere/kubekey/releases/download/v3.0.13/kubekey-v3.0.13-linux-amd64.tar.gz
tar -xf kubekey-v3.0.13-linux-amd64.tar.gz
mv kk /usr/local/bin/

#查看支持k8s版本
kk version --show-supported-k8s

2.编辑配置文件

参考:https://github.com/kubesphere/kubekey/blob/master/README_zh-CN.md

修改对应IP账号密码
config-v1.24.7-online.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

apiVersion: kubekey.kubesphere.io/v1alpha2
kind: Cluster
metadata:
name: k8s-jy
spec:
hosts:
- {name: cn098, address: 200.0.0.98, internalAddress: 200.0.0.98, user: root, password: "ycsc_2023"}
- {name: cn099, address: 200.0.0.99, internalAddress: 200.0.0.99, user: root, password: "ycsc_2023"}
- {name: cn100, address: 200.0.0.100, internalAddress: 200.0.0.100, user: root, password: "ycsc_2023"}
- {name: gpu002, address: 200.0.241.2, internalAddress: 200.0.241.2, user: root, password: "ycsc_2023"}
roleGroups:
etcd:
- cn098
- cn099
- cn100
control-plane:
- cn098
- cn099
- cn100
worker:
- cn098
- cn099
- cn100
- gpu002
controlPlaneEndpoint:
## Internal loadbalancer for apiservers
internalLoadbalancer: kube-vip

domain: lb.cluster.local
address: "200.0.1.90"
port: 6443
kubernetes:
version: v1.24.7
clusterName: cluster.local
autoRenewCerts: true
containerManager: containerd
etcd:
type: kubeadm
network:
plugin: calico
kubePodsCIDR: 10.233.64.0/18
kubeServiceCIDR: 10.233.0.0/18
## multus support. https://github.com/k8snetworkplumbingwg/multus-cni
multusCNI:
enabled: false
registry:
privateRegistry: ""
namespaceOverride: ""
registryMirrors: []
insecureRegistries: []
addons: []

4.部署

1
kk create cluster -f config-v1.24.7-online.yaml

5.安装 bash-completion(可选)

1
2
3
4
5
6
7
8
9
10
# 安装 bash-completion
apt -y install bash-completion

# 将 completion 脚本添加到你的 ~/.bashrc 文件
echo 'source <(kubectl completion bash)' >>~/.bashrc

# 将 completion 脚本添加到 /etc/bash_completion.d 目录
kubectl completion bash >/etc/bash_completion.d/kubectl

#重启生效

7. 对接NFS存储(可选)

7.1 格式化硬盘,并且设置共享

1
2
3
4

#格式化硬盘为xfs格式
mkfs.xfs /dev/sdb
mkdir /opt/nfs-data

fstab中设置自动挂载

1
2
#/dev/sdb
UUID=7a8c2445-7103-4591-9b73-2db3757a8e6e /opt/nfs-data xfs defaults 0 0

挂载确认格式、uuid、及挂载位置

1
2
mount -a
lsblk -f

7.2 配置NFS服务器,允许Kubernetes节点访问NFS共享

将以下内容添加到/etc/exports文件中:

1
/opt/nfs-data *(rw,sync,no_root_squash,no_subtree_check)

重启NFS服务使配置生效:

1
2
3
4
5
6
7
8
9
10
#创建相关文件夹
mkdir -p /opt/nfs-data/k8s-sc/retain
mkdir -p /opt/nfs-data/k8s-sc/delete

#启动服务,设置自启
systemctl restart nfs-server
systemctl enable nfs-server

#在各节点上运行测试通信
showmount -e cn098

7.3 k8s安装nfs存储类插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mkdir nfs ; cd nfs
git clone https://github.com/kubernetes-csi/csi-driver-nfs.git

cd csi-driver-nfs

#相关镜像代理,替换tag下载(可选)

ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/csi-node-driver-registrar:v2.9.0
ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/csi-provisioner:v3.6.1
ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/csi-snapshotter:v6.3.1
ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/livenessprobe:v2.11.0
ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/nfsplugin:v4.5.0
ctr -n k8s.io i pull k8s.dockerproxy.com/sig-storage/snapshot-controller:v6.3.1

ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/csi-node-driver-registrar:v2.9.0 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.9.0
ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/csi-provisioner:v3.6.1 registry.k8s.io/sig-storage/csi-provisioner:v3.6.1
ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/csi-snapshotter:v6.3.1 registry.k8s.io/sig-storage/csi-snapshotter:v6.3.1
ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/livenessprobe:v2.11.0 registry.k8s.io/sig-storage/livenessprobe:v2.11.0
ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/nfsplugin:v4.5.0 registry.k8s.io/sig-storage/nfsplugin:v4.5.0
ctr -n k8s.io i tag k8s.dockerproxy.com/sig-storage/snapshot-controller:v6.3.1 registry.k8s.io/sig-storage/snapshot-controller:v6.3.1

ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/csi-node-driver-registrar:v2.9.0
ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/csi-provisioner:v3.6.1
ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/csi-snapshotter:v6.3.1
ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/livenessprobe:v2.11.0
ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/nfsplugin:v4.5.0
ctr -n k8s.io i rm k8s.dockerproxy.com/sig-storage/snapshot-controller:v6.3.1

./deploy/install-driver.sh v4.5.0 local

cd ../..

7.4 创建存储类

1
vim nfs-sc-delete.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-delete
provisioner: nfs.csi.k8s.io
parameters:
server: 200.0.0.98
share: /opt/nfs-data/k8s-sc/delete
# csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
# csi.storage.k8s.io/provisioner-secret-name: "mount-options"
# csi.storage.k8s.io/provisioner-secret-namespace: "default"
reclaimPolicy: Delete
allowVolumeExpansion: True
volumeBindingMode: Immediate
#mountOptions:
# - nfsvers=4.1

1
vim nfs-sc-retain.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-retain
provisioner: nfs.csi.k8s.io
parameters:
server: 200.0.0.98
share: /opt/nfs-data/k8s-sc/retain
# csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
# csi.storage.k8s.io/provisioner-secret-name: "mount-options"
# csi.storage.k8s.io/provisioner-secret-namespace: "default"
reclaimPolicy: Retain
allowVolumeExpansion: True
volumeBindingMode: Immediate
#mountOptions:
# - nfsvers=4.1

7.5 使用kubectl apply命令创建存储类:

1
2
3
4
kubectl apply -f nfs-sc-delete.yaml
kubectl apply -f nfs-sc-retain.yaml

kubectl get sc

7.6 设置默认存储类:

1
2
3
4
5
6
7
8
#标记
kubectl patch storageclass nfs-retain -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

#取消
kubectl patch storageclass nfs-retain -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

kubectl get storageclass

二、KubeVirt部署

目前era限制版本为0.56.0版本

2.1 验证服务器是否支持虚拟化

1
2
3
4
5
6
7
8
9
10
11
12
13
virt-host-validate qemu


QEMU: Checking for hardware virtualization : PASS
QEMU: Checking if device /dev/kvm exists : PASS
QEMU: Checking if device /dev/kvm is accessible : PASS
QEMU: Checking if device /dev/vhost-net exists : PASS
QEMU: Checking if device /dev/net/tun exists : PASS
. . .


#若未全部pass,请检查BIOS中开启VT-d和虚拟化支持

2.2 安装

1
2
3
4
5
6
7
8
9
mkdir kubevirt ; cd kubevirt
# Deploy the KubeVirt operator
wget https://github.com/kubevirt/kubevirt/releases/download/v0.56.0/kubevirt-operator.yaml -O 1-kubevirt-operator.yaml
kubectl apply -f 1-kubevirt-operator.yaml
# Create the KubeVirt CR (instance deployment request) which triggers the actual installation
wget https://github.com/kubevirt/kubevirt/releases/download/v0.56.0/kubevirt-cr.yaml -O 2-kubevirt-cr.yaml
kubectl apply -f 2-kubevirt-cr.yaml
# wait until all KubeVirt components are up
kubectl -n kubevirt wait kv kubevirt --for condition=Available

2.3 开启相关特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

cat > 3-kubevirt-enable-feature-gate.yaml << 'EOF'
---
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
configuration:
developerConfiguration:
featureGates:
- LiveMigration
- DataVolumes
- ExpandDisks
EOF

kubectl apply -f 3-kubevirt-enable-feature-gate.yaml

2.4 virtctl客户端工具安装

1
2
wget https://github.com/kubevirt/kubevirt/releases/download/v0.56.0/virtctl-v0.56.0-linux-amd64 -O /usr/local/bin/virtctl
chmod +x /usr/local/bin/virtctl

2.5 卸载(可选)

1
2
3
4
5
6
7
kubectl delete -n kubevirt kubevirt kubevirt --wait=true # --wait=true should anyway be default
kubectl delete apiservices v1.subresources.kubevirt.io # this needs to be deleted to avoid stuck terminating namespaces
kubectl delete mutatingwebhookconfigurations virt-api-mutator # not blocking but would be left over
kubectl delete validatingwebhookconfigurations virt-operator-validator # not blocking but would be left over
kubectl delete validatingwebhookconfigurations virt-api-validator # not blocking but would be left over
kubectl patch crd/kubevirts.kubevirt.io -p '{"metadata":{"finalizers":[]}}' --type=merge
kubectl delete -f 1-kubevirt-operator.yaml --wait=false

三、CDI部署

3.1 安装 CDI

目前era限制版本为1.52.0版本

1
2
3
4
5
mkdir cdi ; cd cdi
wget https://github.com/kubevirt/containerized-data-importer/releases/download/v1.52.0/cdi-operator.yaml -O 1-cdi-operator.yaml
kubectl apply -f 1-cdi-operator.yaml
wget https://github.com/kubevirt/containerized-data-importer/releases/download/v1.52.0/cdi-cr.yaml -O 2-cdi-cr.yaml
kubectl apply -f 2-cdi-cr.yaml

3.2 服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat > 3-expose-cdi-uploadproxy.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: cdi-uploadproxy-nodeport
namespace: cdi
labels:
cdi.kubevirt.io: "cdi-uploadproxy"
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 31001
protocol: TCP
selector:
cdi.kubevirt.io: cdi-uploadproxy
EOF

kubectl apply -f 3-expose-cdi-uploadproxy.yaml

四、GPU插件支持

https://github.com/NVIDIA/kubevirt-gpu-device-plugin/

4.1 安装

1
2
3
4
5
6
7
8
9
cd kubevirt
mkdir gpu ; cd gpu
wget https://github.com/NVIDIA/kubevirt-gpu-device-plugin/archive/refs/tags/v1.2.4.tar.gz
tar -xf v1.2.4.tar.gz
cp kubevirt-gpu-device-plugin-1.2.4/manifests/nvidia-kubevirt-gpu-device-plugin.yaml 0-vidia-kubevirt-gpu-device-plugin.yaml
kubectl apply -f 0-vidia-kubevirt-gpu-device-plugin.yaml

#使用以下命令确定 GPU 的供应商 ID 和设备 ID
lspci -nn | grep -i nvidia

4.2 直通模式

1. 在KVM主机上启用IOMMU和黑名单新驱动程序

1
2
3
4
5
6
7
8
9
$ vim /etc/default/grub
# line 6: add (if AMD CPU, add [amd_iommu=on])
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb intel_iommu=on quiet iommu=pt modprobe.blacklist=nouveau"
GRUB_DISABLE_RECOVERY="true"

将“intel_iommu=on modprobe.blacklist=nouveau”附加到“GRUB_CMDLINE_LINUX”

1
2
3
grub2-mkconfig -o /boot/grub2/grub.cfg
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
reboot

重新启动后,使用以下命令验证是否启用了 IOMMU

1
2
3
dmesg | grep -E "DMAR|IOMMU"
#验证新版是否已禁用
dmesg | grep -i nouveau

2. 启用 vfio-pci 内核模块

使用以下命令确定 GPU 的供应商 ID 和设备 ID

1
lspci -nn | grep -i nvidia

在下面的示例中,供应商 ID 为 10de,设备 ID 为 1b38

1
2
$ lspci -nn | grep -i nvidia
04:00.0 3D controller [0302]: NVIDIA Corporation GP102GL [Tesla P40] [10de:1b38] (rev a1)

更新 VFIO 配置

1
echo "options vfio-pci ids=vendor-ID:device-ID" > /etc/modprobe.d/vfio.conf

考虑到供应商 ID 为 10de,设备 ID 为 1b38,命令将如下所示

1
2
echo "options vfio-pci ids=10de:20f1,10de:1b38" > /etc/modprobe.d/vfio.conf

更新配置以在重新加载后加载 VFIO-PCI 模块

1
2
echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf
reboot

验证是否已为 GPU 加载 VFIO-PCI 驱动程序

1
lspci -nnk -d 10de:

下面的输出显示“正在使用的内核驱动程序”是“vfio-pci”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@gpu002 ~]# lspci -nnk -d 10de:
34:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
35:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
36:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
37:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
9b:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
9c:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
9d:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia
9e:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:20b5] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1533]
Kernel driver in use: vfio-pci
Kernel modules: nouveau, nvidia_drm, nvidia

3. 校验节点gpu支持情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
yum -y install jq
kubectl get node gpu002 -o json | jq '.status.allocatable'

{
"cpu": "63600m",
"devices.kubevirt.io/kvm": "1k",
"devices.kubevirt.io/tun": "1k",
"devices.kubevirt.io/vhost-net": "1k",
"ephemeral-storage": "434034624Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "1027098306574",
"nvidia.com/GA100_A100_PCIE_80GB": "8",
"pods": "110"
}

4.3.声明GPU,Kubevirt 加入白名单

1
2
3
4
5
6
7
#显卡名称查看
kubectl logs -f -n kube-system nvidia-kubevirt-gpu-dp-daemonset-*
kubectl describe nodes | grep nvidia.com

cp kubevirt-gpu-device-plugin-1.2.0/examples/kubevirt-featuregate-cm.yaml 1-kubevirt-featuregate-cm.yaml

vim 1-kubevirt-featuregate-cm.yaml

修改设备相关对应关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: kubevirt.io/v1alpha3
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
imagePullPolicy: IfNotPresent
certificateRotateStrategy: {}
configuration:
permittedHostDevices:
pciHostDevices:
# whitelist the permitted devices here
- pciVendorSelector: "10DE:20B5"
resourceName: "nvidia.com/GA100_A100_PCIE_80GB"
externalResourceProvider: true
mediatedDevices:
- mdevNameSelector: "GRID A100-1Q"
resourceName: "nvidia.com/GRID_A100-1Q"
imagePullPolicy: IfNotPresent
developerConfiguration:
featureGates:
- GPU

应用:

1
kubectl apply -f 1-kubevirt-featuregate-cm.yaml

注意不可删除,可apply,删除会删除整个kubevirt

4.5 创建gpu虚机测试

vim test-gpu.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
gpus:
- deviceName: nvidia.com/GV100GL_TESLA_V100_PCIE_16GB
name: gpu1

interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=

启动

1
2
3
4
5
6
kubectl apply -f test-gpu.yaml
kubectl get vm
virtctl start testvm
virtctl console testvm
#退出console
ctrl+]

五、MariaDB部署

5.1 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir mariadb ; cd mariadb
cat >> 0-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
storageClassName: nfs-retain

EOF

5.2 创建配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
cat >> 1-configMap.yaml << "EOF"
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-config
data:
my.cnf: |
[mysqld]
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid

#user=mysql

character-set-server=utf8mb4
collation-server=utf8mb4_bin

default-time-zone = '+8:00'

#server-id
server_id=1

#禁止名称解析
skip_name_resolve=ON

#不区分大小写
lower_case_table_names = 1

#最大连接数,当max_connections设置太小时(默认151),MySQL可能会报错Too many connections。
#当max_connections设置太大时(1000以上),>操作系统可能忙于线程间的切换而失去响应。
#每个连接都会消耗一定内存,最大连接数占上限连接数(show global status like 'Max_used_connections';)的85%左右,
#如果发现比例在10%以下,MySQL服务器连接上线就设置得过高了。
#Max_used_connections / max_connections = 0.85
max_connections = 2048

#指mysql服务器端和客户端在一次传送数据包的过程当中最大允许的数据包大小。
#max_allowed_packet 最大值是1G(1073741824),如果设置超过1G,>查看最终生效结果也只有1G。
max_allowed_packet = 1G

#当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)
#即可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,
#如果线程重新被请求,那么请求>将从缓存中读取,
#如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能。
#根据并发连接数进行配置,这里假设并发连接数为 1000。
thread_cache_size = 64

#物理内存大小的70%-80%,如果服务器上只运行MySQL,则可以将此值增加到90%,这里假设服务器内存为 8GB。
innodb_buffer_pool_size = 6G

# 增加 innodb_log_buffer_size,提高写入性能。
innodb_log_buffer_size = 16M

# 设置innodb_io_capacity,并启用O_DIRECT,提高IO性能。
innodb_io_capacity = 2000
innodb_flush_method = O_DIRECT

#innodb只读压缩
innodb_read_only_compressed = 0

#innodb可以把每个表的数据单独保存。
innodb_file_per_table=ON

#禁用或启用中继日志,只要不再需要,立即自动清除。默认值为 1(已启用)
relay_log_purge = ON
#定义relay_log的位置和名称,如果值为空,则默认位置在数据文件的目录,文件名为host_name-relay-bin.nnnnnn
relay_log=relay-bin
#定义relay_log_index的位置和名称
relay_log_index=relay-bin.index

#是否打开慢查询日志
slow_query_log=ON
#慢查询时间为5s,根据实际业务情况进行配置。
long_query_time = 5
#慢查询文件位置,将日志文件放在独立的 SSD 盘上。
slow-query-log-file=/var/lib/mysql/slow.log

#binlog日志格式
binlog_format=ROW
#启用二进制日志记录,指定文件名
log_bin=bin-log
#启用二进制日志记录,指定文件名
log_bin_index=bin-log.index
#定义了mysql清除过期日志的时间。默认值为0,表示“没有自动删除”。单位天
expire_logs_days=7
#复制服务器从源服务器接收的更新是否应记录到副本自己的二进制日志。
log_slave_updates=ON

#日志的存放位置
log_error = /var/lib/mysql/mysqld.log
#log_warnings 为0,表示不记录告警信息。
#log_warnings 为1,表示告警信息写入错误日志。
#log_warnings 大于1,表示各类告警信息,例如有关网络故障的信息和重新连接信息写入错误日志。(默认为2)
#log_warnings=2

#GTID严格模式
gtid_strict_mode=ON

#从库幂等模式
slave_exec_mode= IDEMPOTENT

#slave忽略同步的数据库
replicate-ignore-db=information_schema,performance_schema

#半同步
rpl_semi_sync_master_enabled=on
rpl_semi_sync_slave_enabled=on

#会话事务状态跟踪
session_track_state_change = ON
session_track_transaction_info = CHARACTERISTICS
session_track_system_variables='autocommit,character_set_client,character_set_connection,character_set_results,time_zone,last_gtid'

#
# include *.cnf from the config directory
#
#!includedir /etc/my.cnf.d

EOF

5.3 创建有状态服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
cat >>2-statefulSet.yaml << "EOF"
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
spec:
replicas: 1
serviceName: mariadb
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb:10.9
env:
- name: MYSQL_ROOT_PASSWORD
value: '4y6Cu%946*!TXY'
volumeMounts:
- name: mariadb-storage
mountPath: /var/lib/mysql
- name: mariadb-config
mountPath: /etc/mysql/my.cnf
subPath: my.cnf
volumes:
- name: mariadb-storage
persistentVolumeClaim:
claimName: mariadb-data
- name: mariadb-config
configMap:
name: mariadb-config
items:
- key: my.cnf
path: my.cnf

EOF

5.4 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat >> 3-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: mariadb
labels:
app: mariadb
spec:
ports:
- name: mariadb
port: 3306
protocol: TCP
targetPort: 3306
nodePort: 30001
selector:
app: mariadb
type: NodePort

EOF

5.5 应用

1
2
3
4
kubectl apply  -f 0-pvc.yaml
kubectl apply -f 1-configMap.yaml
kubectl apply -f 2-statefulSet.yaml
kubectl apply -f 3-service.yaml

六、Nacos服务部署

6.1 登陆数据库,创建nacos用户及库,并导入初始化sql

1
2
3
4
5
use mysql;
create database nacos CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
create user 'nacos'@'%' identified by '!EdkeJwrtDN45^';
grant all privileges on nacos.* to 'nacos'@'%';
flush privileges;

6.2 创建nacos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
mkdir nacos; cd nacos
cat >> 1-nacos-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: nacos
labels:
app: nacos
spec:
replicas: 1
selector:
matchLabels:
app: nacos
template:
metadata:
labels:
app: nacos
spec:
containers:
- name: nacos
image: nacos/nacos-server:v2.2.0
env:
- name: MODE
value: "standalone"
- name: SPRING_DATASOURCE_PLATFORM
value: "mysql"
- name: MYSQL_SERVICE_HOST
value: "200.0.0.98"
- name: MYSQL_SERVICE_PORT
value: "30001"
- name: MYSQL_SERVICE_DB_NAME
value: "nacos"
- name: MYSQL_SERVICE_USER
value: "nacos"
- name: MYSQL_SERVICE_PASSWORD
value: "!EdkeJwrtDN45^"
ports:
- containerPort: 8848
name: client-port
- containerPort: 9848
name: client-rpc
- containerPort: 9849
name: raft-rpc
- containerPort: 7848
name: old-raft-rpc


EOF

6.3 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cat >> 2-nacos-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: nacos
labels:
app: nacos
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
ports:
- port: 8848
name: server
targetPort: 8848
nodePort: 30002
- port: 9848
name: client-rpc
targetPort: 9848
- port: 9849
name: raft-rpc
targetPort: 9849
## 兼容1.4.x版本的选举端口
- port: 7848
name: old-raft-rpc
targetPort: 7848
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer
selector:
app: nacos


EOF

6.3 数据库中导入预定义sql,见附件

初始化sql:
mysql-schema.sql

6.4 应用

1
2
kubectl apply  -f 1-nacos-deployment.yaml
kubectl apply -f 2-nacos-service.yaml

6.5 创建era命名空间

![](_v_images/20230227115412128_20323.png =1241x)

6.6 在era命名空间中导入附件配置

![](_v_images/20230227115516361_6927.png =810x)

nacos配置:
nacos_config_export_20230423155621.zip

七、MinIO部署

7.1 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat >> 0-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: minio-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
storageClassName: nfs-retain

EOF

7.2 创建deployment文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cat >> 1-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio
spec:
replicas: 1
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: minio/minio:RELEASE.2022-06-11T19-55-32Z
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- minio server /data --console-address ":9000" --address ":9001"
env:
- name: MINIO_ROOT_USER
value: admin
- name: MINIO_ROOT_PASSWORD
value: 'c!%892w@MWE^T*'
ports:
- name: web
containerPort: 9000
protocol: "TCP"
- name: api
containerPort: 9001
protocol: "TCP"
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: minio-data
EOF

7.3 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat >> 2-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: minio
labels:
app: minio
spec:
ports:
- name: web-port
port: 9000
protocol: TCP
targetPort: 9000
nodePort: 30004
- name: api-port
port: 9001
protocol: TCP
targetPort: 9001
nodePort: 30005
type: NodePort
selector:
app: minio
EOF

7.4 应用

1
2
3
kubectl apply  -f 0-pvc.yaml
kubectl apply -f 1-deployment.yaml
kubectl apply -f 2-service.yaml

7.5 配置桶及用户

1
2
3
4
5
6
7
8
9
10
11
era
era
E$y*uY7@&39gW6

Access Key

BNXMD8gbbM4Q2NoX
Secret Key

0fRkiYeJ63wMHz98I3Q7c3fUD1f9QZZW

1.创建桶

![](_v_images/20230227103232369_29801.png =536x)

2.创建用户

![](_v_images/20230227114333584_26973.png =559x)

3.创建权限策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::era/*"
]
}
]
}

![](_v_images/20230227114629100_1990.png =553x)

4.用户绑定权限

![](_v_images/20230227114727497_21480.png =858x)

5.创建用户令牌并记录

![](_v_images/20230227111406643_8560.png =769x)

1
2
3
4
5
6
Access Key:

0psoK6mqbPynGQuh
Secret Key:

fBWc4MZzPL94DQ8k1l2JsN5MERfrSD2R

![](_v_images/20230227114800001_7048.png =578x)

八、Redis部署

8.1 创建配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
cat >> 0-configMap.yaml << "EOF"
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
# Redis配置文件示例。
#
# 请注意,为了读取配置文件,Redis必须以文件路径作为第一个参数来启动:
#
# ./redis-server /path/to/redis.conf

# 关于单位的注意事项:当需要内存大小时,可以以通常的格式1k 5GB 4M来指定它,依此类推:
#
# 1k => 1000字节
# 1kb => 1024字节
# 1m => 1000000字节
# 1mb => 1024 * 1024字节
# 1g => 1000000000字节
# 1gb => 1024 * 1024 * 1024字节
#
# 单位不区分大小写,因此1GB 1Gb 1gB都相同。

################################## INCLUDES ###################################

# 在此处包含一个或多个其他配置文件。 如果您具有可用于所有Redis服务器的标准模板,但还需要自定义一些每服务器设置,则此功能很有用。
# 包含文件可以包含其他文件,因此请明智地使用它。
#
# 注意admin或Redis Sentinel的命令"CONFIG REWRITE"不会重写选项"include"。
# 由于Redis始终使用最后处理的行作为配置指令的值,因此最好将include放在此文件的开头,以避免在运行时覆盖配置更改。
#
# 如果您反而对使用include覆盖配置选项感兴趣,则最好将include作为最后一行。
#
# include /path/to/local.conf
# include /path/to/other.conf

################################## MODULES #####################################

# 在启动时加载模块。 如果服务器无法加载模块,它将中止。 可以使用多个loadmodule指令。
#
# loadmodule /path/to/my_module.so
# loadmodule /path/to/other_module.so

################################## NETWORK #####################################

# 默认情况下,如果未指定"bind"配置指令,则Redis侦听来自服务器上所有可用网络接口的连接。
# 可以使用"bind"配置指令仅侦听一个或多个所选接口,然后侦听一个或多个IP地址。
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~警告~~~如果运行Redis的计算机直接暴露于Internet,则绑定到所有接口都是危险的,并且会将实例暴露给Internet上的所有人。因此,默认情况下,
# 我们取消注释以下bind指令,这将强制Redis仅侦听IPv4环回接口地址(这意味着Redis将只能接受来自正在运行同一台计算机的客户端的连接)。
#
# 如果您确定要立即侦听所有接口,请仅注意以下几行。
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind *

# 保护模式是安全保护的一层,目的是避免访问和利用Internet上打开的Redis实例。
#
# 启用保护模式时,如果:
#
# 1)服务器未使用"bind"指令显式绑定到一组地址。
# 2)未配置密码。
#
# 服务器仅接受来自通过IPv4和IPv6回送地址127.0.0.1和::: 1以及来自Unix域套接字的客户端的连接。
#
# 默认情况下启用保护模式。 仅当您确定您希望其他主机的客户端连接到Redis时,
# 即使未配置身份验证,也不会使用"bind"指令显式列出一组特定的接口,才应禁用它。
protected-mode no

# 接受指定端口上的连接,默认为6379(IANA# 815344)。
# 如果指定了端口0,则Redis将不会在TCP套接字上侦听。
port 6379

# TCP listen() backlog.
#
# 在每秒请求数很高的环境中,您需要大量backlog(积压),以避免客户端连接速度慢的问题。
# 请注意,Linux内核会以无提示的方式将其截断为/proc/sys/net/core/somaxconn的值,
# 因此请确保同时提高somaxconn和tcp_max_syn_backlog的值,以获得所需的效果。
tcp-backlog 511

# Unix socket.
#
# 指定用于监听传入连接的Unix套接字的路径。 没有默认值,因此在未指定Redis的情况下,Redis不会在Unix套接字上侦听。
#
# unixsocket /tmp/redis.sock
# unixsocketperm 700

# 客户端闲置N秒后关闭连接(0禁用)
timeout 0

# TCP keepalive.
#
# 如果非零,请在没有通信的情况下使用SO_KEEPALIVE向客户端发送TCP ACK。 这很有用,原因有两个:
#
# 1)检测死亡的同伴。
# 2)从中间的网络设备的角度来看,使连接保持活动状态。
#
# 在Linux上,指定的值(以秒为单位)是用于发送ACK的时间段。
# 请注意,关闭连接需要两倍的时间。
# 在其他内核上,期限取决于内核配置。
#
# 此选项的合理值是300秒,这是从Redis 3.2.1开始的新Redis默认值。
tcp-keepalive 300

################################# TLS/SSL #####################################

# 默认情况下,禁用TLS / SSL。 要启用它,可以使用"tls-port"配置指令来定义TLS侦听端口。
# 要在默认端口上启用TLS,请使用:
#
# port 0
# tls-port 6379

# 配置X.509证书和私钥,用于对连接的客户端,主服务器或集群对等服务器进行身份验证。 这些文件应为PEM格式。
#
# tls-cert-file redis.crt
# tls-key-file redis.key

# 配置DH参数文件,启用Diffie-Hellman(DH)密钥交换。
#
# tls-dh-params-file redis.dh

# 配置CA证书捆绑包或目录以认证TLS/SSL客户端和对等方。 Redis需要其中至少一项的显式配置,并且不会隐式使用系统范围的配置。
#
# tls-ca-cert-file ca.crt
# tls-ca-cert-dir /etc/ssl/certs

# 默认情况下,TLS端口上的客户端(包括副本服务器)需要使用有效的客户端证书进行身份验证。
#
# 可以使用此伪指令禁用身份验证。
#
# tls-auth-clients no

# 默认情况下,Redis副本不尝试与其主服务器建立TLS连接。
#
# 使用以下指令在复制链接上启用TLS。
#
# tls-replication yes

# 默认情况下,Redis群集总线使用纯TCP连接。 要为总线协议启用TLS,请使用以下指令:
#
# tls-cluster yes

# 明确指定要支持的TLS版本。 允许的值不区分大小写,包括"TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"(OpenSSL> = 1.1.1)或任意组合。
# 要仅启用TLSv1.2和TLSv1.3,请使用:
#
# tls-protocols "TLSv1.2 TLSv1.3"

# 配置允许的密码。 有关此字符串的语法的更多信息,请参见ciphers(1ssl)联机帮助页。
#
# 注意:此配置仅适用于<= TLSv1.2。
#
# tls-ciphers DEFAULT:!MEDIUM

# 配置允许的TLSv1.3密码套件。 有关此字符串的语法(尤其是TLSv1.3密码套件)的语法的更多信息,请参见ciphers(1ssl)联机帮助页。
#
# tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256

# 选择密码时,请使用服务器的首选项而不是客户端的首选项。 默认情况下,服务器遵循客户端的首选项。
#
# tls-prefer-server-ciphers yes

################################# GENERAL(通常) #####################################

# 默认情况下,Redis不会作为守护程序运行。 如果需要,请使用"是"。
# 注意,Redis守护进程将在/var/run/redis.pid中写入一个pid文件。
daemonize no

# 如果从upstart或systemd运行Redis,Redis可以与您的supervision(监督) tree进行交互。 选项:
# supervised no - 没有supervision(监督)互动
# supervised upstart - 通过将Redis置于SIGSTOP模式来发出信号
# supervised systemd - 通过将READY = 1写入$ NOTIFY_SOCKET来产生信号
# supervised auto - 根据UPSTART_JOB或NOTIFY_SOCKET环境变量检测upstart或systemd方法

# 注意:这些supervision(监督)方法仅表示"过程已准备就绪"。
# 他们无法使您的主管连续不断地进行ping操作。
supervised no

# 如果指定了pid文件,则Redis会在启动时将其写入指定位置,并在退出时将其删除。
#
# 当服务器在非守护进程中运行时,如果未在配置中指定任何pid文件,则不会创建该文件。
# 守护服务器时,即使未指定,也会使用pid文件,默认为"/var/run/redis.pid"。
#
# 尽最大努力创建一个pid文件:如果Redis无法创建它,那么一切正常,服务器将正常启动并运行。
pidfile /var/run/redis_6379.pid

# 指定服务器的详细级别。
# 这可以是以下之一:
# debug (很多信息,对于开发/测试很有用)
# verbose (很多很少有用的信息,但不会像调试级别那样混乱)
# notice (适度冗长,可能在生产中需要什么)
# warning (仅记录非常重要/重要的消息)
loglevel notice

# 指定日志文件名。 空字符串也可以用于强制Redis登录标准输出。
# 请注意,如果您使用标准输出进行日志记录但进行守护进程,则日志将发送到/dev/null
logfile ""

# 要启用登录到系统记录器的功能,只需将'syslog-enabled'设置为yes,然后根据需要更新其他syslog参数。
# syslog-enabled no

# 指定系统日志标识。
# syslog-ident redis

# 指定系统日志工具。 必须是USER或在LOCAL0-LOCAL7之间。
# syslog-facility local0

# 设置数据库数量。 默认数据库为DB 0,您可以使用SELECT <dbid>在每个连接的基础上选择一个不同的数据库,
# 其中dbid是介于0和'databases'-1之间的数字
databases 16

# 默认情况下,仅当开始记录到标准输出并且标准输出为TTY时,Redis才会显示ASCII艺术logo。
# 基本上,这意味着logo通常仅在交互式会话中显示。
#
# 但是,可以通过将以下选项设置为yes,来强制执行4.0之前的行为并始终在启动日志中显示ASCII艺术logo。
always-show-logo yes

################################ SNAPSHOTTING(快照) ################################
#
# 将数据库保存在磁盘上:
#
# save <seconds> <changes>
#
# 如果同时发生了给定的秒数和给定的针对数据库的写操作数,则将保存数据库。
#
# 在下面的示例中,行为将是保存:
# 900秒(15分钟)后,如果至少更改了1个键
# 300秒(5分钟)后,如果至少更改了10个按键
# 60秒后,如果至少更改了10000个键
#
# 注意:您可以通过注释掉所有"保存"行来完全禁用保存。
#
# 也可以通过添加带有单个空字符串参数的save指令来删除所有先前配置的保存点,如以下示例所示:
#
# save ""

save 900 1
save 300 10
save 60 10000

# 默认情况下,如果启用了RDB快照(至少一个保存点)并且最新的后台保存失败,Redis将停止接受写入。
# 这将使用户(以一种困难的方式)意识到数据无法正确地持久存储在磁盘上,否则,可能没人会注意到并且会发生一些灾难。
#
# 如果后台保存过程将再次开始工作,则Redis将自动允许再次写入。
#
# 但是,如果您设置了对Redis服务器和持久性的适当监视,则可能要禁用此功能,以便即使磁盘,权限等出现问题,Redis也将继续照常工作。
stop-writes-on-bgsave-error yes

# 转储.rdb数据库时使用LZF压缩字符串对象?
# 默认情况下将其设置为"是",因为它几乎总是胜利。
# 如果要在保存子项中保存一些CPU,请将其设置为"no",但是如果您具有可压缩的值或键,则数据集可能会更大。
rdbcompression yes

# 从RDB版本5开始,在文件末尾放置了CRC64校验和。
# 这使得该格式更能抵抗损坏,但是在保存和加载RDB文件时会付出一定的性能损失(大约10%),因此可以禁用该格式以获得最佳性能。
#
# 在禁用校验和的情况下创建的RDB文件的校验和为零,这将指示加载代码跳过该校验。
rdbchecksum yes

# 转储数据库的文件名
dbfilename dump.rdb

# 删除没有启用持久性的实例中复制使用的RDB文件。 默认情况下,此选项是禁用的,
# 但是在某些环境中,出于法规或其他安全方面的考虑,应将RDB文件由主数据库持久存储在磁盘上以提供副本,
# 或将RDB文件由副本存储在磁盘上以加载它们以进行初始同步。
# 尽快删除。 请注意,此选项仅在同时禁用AOF和RDB持久性的实例中起作用,否则将被完全忽略。
#
# 获得相同效果的另一种方法(有时是更好的方法)是在主实例和副本实例上都使用无盘复制。 但是,对于副本,无盘并非始终是一种选择。
rdb-del-sync-files no

# 工作目录。
#
# 数据库将被写入该目录内,文件名使用"dbfilename"配置指令在上面指定。
#
# 也将在此目录中创建"仅追加文件"。
#
# 请注意,您必须在此处指定目录,而不是文件名。
dir ./

################################# REPLICATION(复制) #################################

# 主副本复制。 使用copyof可以使Redis实例成为另一个Redis服务器的副本。 尽快了解有关Redis复制的几件事。
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis复制是异步的,但是您可以将主服务器配置为在似乎未与至少给定数量的副本连接时停止接受写操作。
# 2) 如果复制链接在相对较短的时间内丢失,则Redis副本能够与主副本执行部分重新同步。
# 您可能需要根据需要将复制积压大小(请参阅此文件的下一部分)配置为合理的值。
# 3) 复制是自动的,不需要用户干预。 网络分区副本之后,副本会自动尝试重新连接到母版并与它们重新同步。
#
# replicaof <masterip> <masterport>

# 如果主服务器受密码保护(使用下面的"requirepass"配置指令),
# 则可以在开始复制同步过程之前告诉副本服务器进行身份验证,否则主服务器将拒绝副本请求。
#
# masterauth <master-password>
#
# 但是,如果使用Redis ACL(对于Redis版本6或更高版本),并且默认用户无法运行PSYNC命令和/或其他复制所需的命令,
# 这还不够。 在这种情况下,最好配置一个特殊用户以用于复制,并这样指定masteruser配置:
#
# masteruser <username>
#
# 指定了masteruser时,副本将使用新的AUTH形式针对其主服务器进行身份验证:AUTH <用户名> <密码>。

# 当副本断开与主数据库的连接时,或者仍在进行复制时,副本可以以两种不同的方式起作用:
#
# 1) 如果复制副本服务过时的数据设置为"是"(默认值),则复制副本仍将回复客户端请求,
# 可能包含过期数据,或者如果这是第一次同步,则数据集可能只是空的。
#
# 2) 如果复制副本服务过时的数据设置为"否",则复制副本将对所有命令发出错误"与主机进行同步"错误,
# 但对INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE, UNSUBSCRIBE,
# PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST, HOST: and LATENCY.
#
replica-serve-stale-data yes

# 您可以配置副本实例以接受或不接受写入。 针对副本实例进行写操作可能对存储某些临时数据很有用(
# 因为与主实例重新同步后,写入副本上的数据很容易删除),但是如果客户端由于配置错误而向其进行写操作,也可能导致问题。
#
# 由于Redis 2.6默认情况下,副本是只读的。
#
# 注意:只读副本并非旨在向Internet上不受信任的客户端公开。 它只是防止实例滥用的保护层。
# 默认情况下,只读副本仍会导出所有管理命令,例如CONFIG,DEBUG等。
# 在一定程度上,您可以使用'rename-command'隐藏所有管理/危险命令来提高只读副本的安全性。
replica-read-only yes

# 复制同步策略:磁盘或套接字。
#
# 仅能接收差异而无法继续复制过程的新副本和重新连接的副本需要执行所谓的"完全同步"。 RDB文件从主数据库传输到副本数据库。
#
# 传输可以两种不同的方式发生:
#
# 1) 磁盘备份: Redis主服务器创建一个新过程,将RDB文件写入磁盘。 后来,文件由父进程逐步传输到副本。
# 2) 无盘:Redis主服务器创建一个新进程,该进程将RDB文件直接写入副本套接字,而完全不接触磁盘。
#
# 使用磁盘支持的复制,在生成RDB文件时,一旦生成RDB文件的当前子级完成工作,就可以将更多副本排入队列并与RDB文件一起使用。
# 如果使用无盘复制,则一旦传输开始,新的副本将排队,并且当当前副本终止时将开始新的传输。
#
# 使用无盘复制时,主服务器在开始传输之前等待一段可配置的时间(以秒为单位),以希望多个副本可以到达并且传输可以并行化。
#
# 对于慢速磁盘和快速(大带宽)网络,无盘复制效果更好。
repl-diskless-sync no

# 启用无盘复制后,可以配置服务器等待的延迟,以生成通过套接字将RDB传输到副本的子代。
#
# 这很重要,因为一旦传输开始,就无法为到达下一个RDB传输的新副本提供服务,因此服务器会等待一段时间才能让更多副本到达。
#
# 以秒为单位指定延迟,默认为5秒。 要完全禁用它,只需将其设置为0秒,传输就会尽快开始。
repl-diskless-sync-delay 5

# -----------------------------------------------------------------------------
# 警告:RDB无盘加载是实验性的。 因为在此设置中,副本不会立即在磁盘上存储RDB,所以它可能会导致故障转移期间的数据丢失。
# 在与主机的初始同步阶段,如果I/O错误,则RDB无盘负载+ Redis模块不处理I/O读取也可能导致Redis中止。 仅在执行自己的操作时使用。
# -----------------------------------------------------------------------------
#
# 副本可以直接从套接字加载从复制链接读取的RDB,也可以将RDB存储到文件中,并在从主服务器完全获取文件后读取该文件。
#
# 在许多情况下,磁盘的速度比网络慢,并且存储和加载RDB文件可能会增加复制时间(甚至会增加主服务器的"写时复制"内存和从属缓冲区)。
# 但是,直接从套接字解析RDB文件可能意味着我们必须在接收到完整的rdb之前刷新当前数据库的内容。 因此,我们有以下选择:
#
# "disabled" - 不要使用无盘负载(首先将rdb文件存储到磁盘)
# "on-empty-db" - 仅在完全安全时才使用无盘加载。
# "swapdb" - 直接从套接字解析数据时,在RAM中保留当前数据库内容的副本。 请注意,这需要足够的内存,如果没有足够的内存,则可能会杀死OOM。
repl-diskless-load disabled

# 副本以预定义的时间间隔将PING发送到服务器。 可以使用repl_ping_replica_period选项更改此间隔。 默认值为10秒。
#
# repl-ping-replica-period 10

# 以下选项为以下项设置复制超时:
#
# 1)从副本的角度来看,在SYNC期间进行批量传输I/O。
# 2)从副本(数据,Ping)的角度来看,主超时。
# 3)从主服务器角度来看,副本超时(REPLCONF ACK ping)。
#
# 确保该值大于为repl-ping-replica-period指定的值非常重要,否则,每当主服务器和副本之间的通信量较低时,都会检测到超时。
#
# repl-timeout 60

# 在SYNC之后禁用副本套接字上的TCP_NODELAY?
#
# 如果选择"是",则Redis将使用更少的TCP数据包和更少的带宽将数据发送到副本。
# 但这会增加数据出现在副本端的延迟,对于使用默认配置的Linux内核,此延迟最多可达40毫秒。
#
# 如果选择"否",将减少数据在副本侧出现的延迟,但将使用更多带宽进行复制。
#
# 默认情况下,我们针对低延迟进行了优化,但是在通信量非常高的情况下,或者当主服务器和副本距离很多跳时,将其设置为"是"可能是个好主意。
repl-disable-tcp-nodelay no

# 设置复制backlog(积压)大小。 待办事项是一个缓冲区,当副本断开连接一段时间后,该缓冲区会累积副本数据,
# 因此当副本想要重新连接时,通常不需要完全重新同步,但是部分重新同步就足够了,只需传递副本的部分数据即可 断开连接时错过。
#
# 复制待办事项越大,副本可以断开连接并在以后能够执行部分重新同步的时间越长。
#
# 仅在至少连接一个副本后才分配backlog(积压)。
#
# repl-backlog-size 1mb

# 在主服务器一段时间不再连接副本后,backlog(积压)的事务将被释放。 以下选项配置了从断开最后一个副本的时间开始到释放待办事项缓冲区所需的秒数。
#
# 请注意,副本永远不会释放backlog(积压)的超时,因为它们可能会在以后升级为主副本,
# 并且应该能够与副本正确"部分重新同步":因此,它们应始终累积backlog(积压)。
#
# 值0表示从不释放backlog(积压)。
#
# repl-backlog-ttl 3600

# 副本优先级是Redis在INFO输出中发布的整数。 如果主服务器不再正常工作,Redis Sentinel会使用它来选择要升级为主服务器的副本。
#
# 优先级低的副本被认为更适合升级,例如,如果有三个副本的优先级分别为10、100和25,Sentinel将选择优先级为10的副本,这是最低的。
#
# 但是,特殊优先级0会将副本标记为不能执行主角色,因此Redis Sentinel永远不会选择优先级为0的副本进行升级。
#
# 默认情况下,优先级为100。
replica-priority 100

# 如果连接的副本少于N个,且延迟小于或等于M秒,则主服务器可能会停止接受写入。
#
# N个副本必须处于"联机"状态。
#
# 以秒为单位的延迟必须小于等于指定值,该延迟是根据从副本接收到的最后一次ping计算得出的,通常是每秒发送一次。
#
# 此选项不能保证N个副本将接受写操作,但是如果没有足够的副本可用,则会将丢失写操作的暴露窗口限制为指定的秒数。
#
# 例如,至少需要3个滞后<= 10秒的副本,请使用:
#
# min-replicas-to-write 3
# min-replicas-max-lag 10
#
# 将其中一个设置为0将禁用该功能。
#
# 默认情况下,min-replicas-to-write设置为0(禁用功能),min-replicas-max-lag设置为10。

# Redis主服务器能够以不同方式列出附加副本的地址和端口。 例如,"INFO复制"部分提供了此信息,Redis Sentinel使用此信息以及其他工具来发现副本实例。
# 该信息可用的另一个位置是主服务器的"ROLE"命令的输出。
#
# 通常通过以下方式获取副本列出的IP和地址:
#
# IP: 通过检查副本用于与主服务器连接的套接字的对等地址来自动检测该地址。
# Port: 该端口在复制握手期间由副本进行通信,通常是副本用来侦听连接的端口。
#
# 但是,当使用端口转发或网络地址转换(NAT)时,实际上可以通过不同的IP和端口对访问该副本。
# 副本可以使用以下两个选项,以便向其主服务器报告特定的IP和端口集,以便INFO和ROLE都将报告这些值。
#
# 如果只需要覆盖端口或IP地址,则无需同时使用这两个选项。
#
# replica-announce-ip 5.5.5.5
# replica-announce-port 1234

############################### KEYS TRACKING(KEYS跟踪) #################################

# Redis为客户端的值缓存实现服务器辅助的支持。
# 这是使用无效表实现的,该无效表使用1600万个插槽记住哪些客户端可能具有某些键子集。
# 依次使用此命令是为了向客户端发送无效消息。 请了解有关此功能的更多信息,请检查以下页面:
#
# https://redis.io/topics/client-side-caching
#
# 为客户端启用跟踪时,假定所有只读查询都已缓存:这将强制Redis将信息存储在失效表中。 修改密钥后,此类信息将被清除,并将无效消息发送到客户端。
# 但是,如果工作量主要由读取决定,Redis可以使用越来越多的内存来跟踪许多客户端获取的密钥。
#
# 因此,可以为失效表配置最大填充值。 默认情况下,它设置为1M键,一旦达到此限制,Redis将开始撤消失效表中的键,
# 即使它们没有被修改,只是为了回收内存:这反过来将迫使客户端使缓存无效。 价值观。
# 基本上,表的最大大小是要在服务器端用来跟踪有关谁缓存内容的信息的内存与客户端将缓存的对象保留在内存中的能力之间进行权衡的。
#
# 如果将值设置为0,则表示没有限制,Redis将在失效表中保留所需数量的键。
# 在"统计信息"信息部分中,您可以在每个给定的时间找到有关失效表中密钥数量的信息。
#
# 注意:在广播模式下使用键跟踪时,服务器端未使用任何内存,因此此设置无用。
#
# tracking-table-max-keys 1000000

################################## SECURITY ###################################

# 警告:由于Redis的速度非常快,外部用户每秒可以在一个现代化的设备上尝试高达100万个密码。
# 这意味着您应该使用非常安全的密码,否则密码很容易破解。
# 请注意,由于该密码实际上是客户端和服务器之间的共享机密,并且不应由任何人记住,
# 因此该密码可以很容易地由/dev/urandom或其他方式中的长字符串组成,因此请使用冗长且不可猜测的内容 密码不会有暴力攻击。

# Redis ACL用户的定义如下:
#
# user <username> ... acl rules ...
#
# 例如:
#
# user worker +@list +@connection ~jobs:* on >ffa9203c493aa99
#
# 特殊用户名"默认"用于新连接。 如果该用户具有"nopass"规则,则新连接将立即被认证为"默认"用户,
# 而无需通过AUTH命令提供任何密码。 否则,如果未将"默认"用户标记为"nopass",
# 则连接将以未认证状态启动,并且需要AUTH(或HELLO命令AUTH选项)才能进行认证并开始工作。
#
# 描述用户可以执行的操作的ACL规则如下:
#
# on 启用用户:可以验证为该用户。
# off 禁用用户:不再可以与此用户进行身份验证,但是已经身份验证的连接仍然可以使用。
# +<command> 允许执行该命令
# -<command> 禁止执行该命令
# +@<category> 允许执行此类中具有有效类别的所有命令,例如@ admin,@ set,@ sortedset等,等等,
# 请参阅server.c文件中的完整列表,其中描述和定义了Redis命令表 。
# 特殊类别@all表示所有命令,但是当前在服务器中存在,并且将来会通过模块加载。
# +<command>|subcommand 允许使用本来禁用的命令的特定子命令。 注意,这种形式不允许像-DEBUG|SEGFAULT那样为负数,而只能以"+"开头。
# allcommands +@all的别名。 注意,这意味着可以执行将来通过模块系统加载的所有命令。
# nocommands -@all的别名。
# ~<pattern> 添加可以在命令中提及的键模式。 例如~*允许所有键。 该模式是类似于KEYS之一的球形样式的模式。
# 可以指定多个模式。
# allkeys ~*的别名。
# resetkeys 刷新允许的键模式列表。
# ><password> 将此密码添加到用户的有效密码列表中。
# 例如> mypass将"mypass"添加到列表中。
# 此指令清除"no pass"标志(请参阅下文)。
# <<password> 从有效密码列表中删除此密码。
# nopass 用户的所有设置密码都将被删除,并且该用户被标记为不需要密码:这意味着每个密码都将对该用户起作用。
# 如果此指令用于默认用户,则每个新连接都将立即通过默认用户进行身份验证,而无需任何显式的AUTH命令。
# 请注意,"resetpass"指令将清除此情况。
# resetpass 刷新允许的密码列表。 此外,删除"nopass"状态。 在"重置密码"之后,
# 用户将没有关联的密码,并且没有添加一些密码(或稍后将其设置为"nopass")就无法进行身份验证的方法。
# reset 执行以下动作: resetpass, resetkeys, off, -@all. 用户返回到创建后立即具有的相同状态。
#
# ACL规则可以以任何顺序指定:例如,您可以以密码,标志或密钥模式开头。 但是请注意,加法和减法规则将根据订购顺序进行更改。
# 例如,请参见以下示例:
#
# user alice on +@all -DEBUG ~* >somepassword
#
# 这将允许"alice"使用除DEBUG命令之外的所有命令,因为+ @ all将所有命令添加到了alice可以使用的命令集中,并且后来删除了DEBUG。
# 但是,如果我们颠倒两个ACL规则的顺序,结果将是不同的:
#
# user alice on -DEBUG +@all ~* >somepassword
#
# 现在,当alice在允许的命令集中还没有命令时,DEBUG被删除,之后又添加了所有命令,因此用户将能够执行所有操作。
#
# 基本上,ACL规则是从左到右处理的。
#
# 有关ACL配置的更多信息,请参阅Redis网站https://redis.io/topics/acl

# ACL日志
#
# ACL日志跟踪与ACL相关的失败命令和身份验证事件。 ACL日志可用于对ACL阻止的失败命令进行故障排除。
# ACL日志存储在其中并消耗内存。 它的长度没有限制。您可以使用ACL LOG RESET回收内存,也可以在下面设置最大长度。
acllog-max-len 128

# 使用外部ACL文件
#
# 除了在此文件中配置用户外,还可以使用仅列出用户的独立文件。 两种方法不能混合使用:
# 如果在此处配置用户并同时激活外部ACL文件,则服务器将拒绝启动。
#
# 外部ACL用户文件的格式与redis.conf内部用来描述用户的格式完全相同。
#
# aclfile /etc/redis/users.acl

# 重要说明:从Redis 6开始,"requirepass"只是新ACL系统之上的兼容性层。 选项效果将只是为默认用户设置密码。
# 客户端仍然可以像往常一样使用AUTH <password>进行身份验证,或者如果它们遵循新协议,
# 则可以使用AUTH default <password>进行更明确的身份验证:两者都可以使用。
#
# requirepass foobared
requirepass 26Rgj^86*SN7y%

# 命令重命名(不建议使用)。
#
# ------------------------------------------------------------------------
# 警告:尽可能避免使用此选项。 而是使用ACL从默认用户中删除命令,并将其仅放置在您出于管理目的而创建的某些admin用户中。
# ------------------------------------------------------------------------
#
# 可以在共享环境中更改危险命令的名称。 例如,可以将CONFIG命令重命名为一些难以猜测的名称,以便它仍可用于内部使用的工具,但不适用于一般客户。
#
# 示例:
#
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#
# 也可以通过将命令重命名为空字符串来完全终止命令:
#
# rename-command CONFIG ""
#
# 请注意,更改登录到AOF文件或传输到副本的命令的名称可能会导致问题。

################################### CLIENTS ####################################

# 设置同时连接的最大客户端数。 默认情况下,此限制设置为10000个客户端,
# 但是,如果Redis服务器无法配置进程文件限制以允许指定的限制,
# 则允许的最大客户端数将设置为当前文件限制减去32(因为Redis保留了 内部使用的文件描述符很少)。
#
# 一旦达到限制,Redis将关闭所有新连接,并发送错误消息"已达到最大客户端数"。
#
# maxclients 10000

############################## MEMORY MANAGEMENT ################################

# 设置内存使用限制为指定的字节数。
# 当达到内存限制时,Redis将尝试根据所选的逐出策略来删除密钥(请参阅maxmemory-policy)。
#
# 如果Redis无法根据该策略删除密钥,或者如果该策略设置为'noeviction',
# 则Redis将开始对将使用更多内存的命令(例如SET,LPUSH等)进行错误回复,并会 继续回复诸如GET之类的只读命令。
#
# 当将Redis用作LRU或LFU缓存,或为实例设置硬盘限制(使用"noeviction"策略)时,此选项通常很有用。
#
# 警告:如果您将副本附加到实例上且maxmemory处于打开状态,则从使用的内存数量中减去提供副本所需的输出缓冲区的大小,
# 以便网络问题/重新同步不会触发收回密钥的循环,反过来,副本的输出缓冲区已满,有被驱逐的DEL密钥触发了更多密钥的删除,
# 依此类推,直到数据库完全清空。
#
# 简而言之...如果您附加了副本,建议您设置maxmemory的下限,
# 以便系统上有一些可用RAM用于副本输出缓冲区(但是如果策略为'noeviction',则不需要这样做) 。
#
# maxmemory <bytes>

# MAXMEMORY POLICY:达到maxmemory时,Redis将如何选择要删除的内容。 您可以从以下行为中选择一种:
#
# volatile-lru -> 使用近似的LRU驱逐,只有具有过期集的key。
# allkeys-lru -> 使用近似的LRU退出任何key。
# volatile-lfu -> 使用近似的LFU驱逐,只有具有过期集的key。
# allkeys-lfu -> 使用近似的LFU退出任何key。
# volatile-random -> 删除具有过期设置的随机key。
# allkeys-random -> 删除随机key,任何key。
# volatile-ttl -> 删除最接近到期时间(较小的TTL)的key
# noeviction -> 不要逐出任何东西,只需在写操作中返回错误。
#
# LRU表示最近最少使用
# LFU表示最少使用
#
# LRU,LFU和volatile-ttl均使用近似随机算法实现。
#
# 注意:使用上述任何策略时,如果没有合适的退出键,Redis将在写入操作中返回错误。
#
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# 默认为:
#
# maxmemory-policy noeviction

# LRU,LFU和最小TTL算法不是精确算法,而是近似算法(以节省内存),因此您可以调整它的速度或准确性。
# 对于默认情况,Redis将检查五个键并选择最近使用的键,您可以使用以下配置指令更改样本大小。
#
# 默认值5产生足够好的结果。 10非常接近真实的LRU,但是会花费更多的CPU。 3更快,但不是很准确。
#
# maxmemory-samples 5

# 从Redis 5开始,默认情况下,副本将忽略其maxmemory设置(除非在故障转移后或手动提升为主副本)。
# 这意味着密钥的移出将仅由主服务器处理,将DEL命令作为副本在主计算机侧逐出,将DEL命令发送到副本。
#
# 此行为可确保主副本和副本副本保持一致,这通常是您想要的,但是,如果副本副本是可写的,
# 或者您希望副本副本具有不同的内存设置,并且您确定对副本副本执行的所有写入都是幂等的 ,那么您可以更改此默认设置(但请务必了解您在做什么)。
#
# 请注意,由于默认情况下该副本不会退出,所以它可能会比使用maxmemory设置的一组内存占用更多的内存(
# 某些缓冲区在副本上可能会更大,或者数据结构有时会占用更多内存,依此类推)。
# 因此,请确保您监视副本,并确保副本具有足够的内存,以便在主副本达到配置的最大内存设置之前,永远不会达到真正的内存不足状态。
#
# replica-ignore-maxmemory yes

# Redis有两种回收过期密钥的方法:访问时发现这些密钥已过期,以及在后台,称为"活动过期密钥"。
# 缓慢地,交互地扫描密钥空间,以查找要回收的过期密钥,以便可以释放已过期且不久之后将不再访问的密钥的内存。
#
# 过期周期的默认工作将尝试避免在内存中保留超过百分之十的过期密钥,并尝试避免消耗超过总内存的25%并增加系统延迟。
# 但是,可以将通常设置为"1"的过期"努力"增加到更大的值,直到值"10"。
# 系统将以其最大值使用更多的CPU,更长的周期(并且从技术上讲可能会引入更多的延迟),并将减少仍然存在于系统中的已过期密钥的数量。
# 在内存,CPU和延迟之间进行权衡。
#
# active-expire-effort 1

############################# LAZY FREEING(懒惰释放) ####################################

# Redis有两个删除键的原语。 一种称为DEL,它是对象的阻塞删除。 这意味着服务器停止处理新命令,以便以同步方式回收与对象关联的所有内存。
# 如果删除的键与一个小对象相关联,则执行DEL命令所需的时间非常短,可与Redis中的大多数其他O(1)或O(log_N)命令相提并论。
# 但是,如果键与包含数百万个元素的聚合值关联,则服务器可能会阻塞很长时间(甚至几秒钟)以完成操作。
#
# 由于上述原因,Redis还提供了非阻塞删除原语,例如UNLINK(非阻塞DEL)以及FLUSHALL和FLUSHDB命令的ASYNC选项,以便在后台回收内存。
# 这些命令在固定时间内执行。 另一个线程将尽可能快地在后台逐渐释放对象。
#
# FLUSHALL和FLUSHDB的DEL,UNLINK和ASYNC选项是用户控制的。
# 由应用程序的设计决定何时使用一个或另一个是一个好主意。 但是,Redis服务器有时必须删除键或刷新整个数据库,这是其他操作的副作用。
# 特别是在以下情况下,Redis会独立于用户调用删除对象:
#
# 1) 逐出时,由于maxmemory和maxmemory策略配置,以便在不超出指定的内存限制的情况下为新数据腾出空间。
# 2) 因为到期:必须从内存中删除具有相关生存时间的密钥(请参阅EXPIRE命令)。
# 3) 由于将数据存储在可能已经存在的键上的命令的副作用。 例如,当RENAME命令被另一旧密钥内容替换时,它可能会删除它。
# 同样,SUNIONSTORE或SORT with STORE选项可能会删除现有密钥。 SET命令本身会删除指定键的所有旧内容,以便将其替换为指定的字符串。
# 4) 在复制期间,当副本与其主副本执行完全重新同步时,将删除整个数据库的内容,以便加载刚传输的RDB文件。
#
# 在上述所有情况下,默认设置都是以阻塞方式删除对象,就像调用DEL一样。
# 但是,您可以专门配置每种情况,以便使用以下配置指令以非阻塞方式释放内存,例如调用UNLINK的情况。

lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no

# 对于将用户代码DEL调用替换为UNLINK调用并不容易的情况,也可以使用以下配置指令将DEL命令的默认行为修改为与UNLINK完全相同:

lazyfree-lazy-user-del no

################################ THREADED I/O #################################

# Redis主要是单线程的,但是有一些线程操作,例如UNLINK,缓慢的I/O访问和其他在侧线程上执行的操作。
#
# 现在,还可以在不同的I/O线程中处理Redis客户端套接字的读写。
# 由于特别慢的写入速度,因此Redis用户通常使用流水线以加快每个内核的Redis性能,并生成多个实例以扩大规模。
# 使用I/O线程可以轻松地将Redis加速两次,而无需求助于实例的流水线处理或分片。
#
# 默认情况下,线程处于禁用状态,我们建议仅在具有至少4个或更多内核的计算机上启用该功能,并至少保留一个备用内核。
# 使用8个以上的线程不太可能有很大帮助。
# 我们还建议仅在确实存在性能问题时才使用线程I/O,Redis实例可以使用很大一部分CPU时间,否则就没有必要使用此功能。
#
# 例如,如果您有四个核的core,请尝试使用2或3个I/O线程,如果您有8个核,请尝试使用6个线程。 为了启用I/O线程,请使用以下配置指令:
#
# io-threads 4
#
# 将io-threads设置为1只会照常使用主线程。
# 启用I/O线程后,我们仅将线程用于写操作,即对write(2)系统调用进行线程化,并将客户端缓冲区传输到套接字。
# 但是,也可以通过将以下配置指令设置为yes来启用读取线程和协议解析功能:
#
# io-threads-do-reads no
#
# 通常,线程读取无济于事。
#
# 注意1:无法在运行时通过CONFIG SET更改此配置伪指令。 启用SSL时,Aso此功能当前不起作用。
#
# 注意2:如果要使用redis-benchmark测试Redis加速,请确保还以线程模式运行基准测试本身,使用--threads选项匹配Redis thead的数量,
# 否则您将无法使用 注意到改进。

############################## APPEND ONLY MODE(追加模式) ###############################

# 默认情况下,Redis异步将数据集转储到磁盘上。 此模式在许多应用程序中已经足够好,
# 但是Redis进程问题或电源中断可能会导致几分钟的写入丢失(取决于配置的保存点)。
#
# 仅附加文件是一种替代的持久性模式,可提供更好的持久性。 例如,使用默认数据fsync策略(请参阅配置文件中的稍后内容),
# Redis可能在服务器断电等严重事件中丢失一秒钟的写入,如果Redis进程本身发生错误,则一次写入将丢失一次,但是 操作系统仍在正常运行。
#
# 可以同时启用AOF和RDB持久性,而不会出现问题。
# 如果启动时启用了AOF,则Redis将加载AOF,即具有更好持久性的文件。
#
# 请检查http://redis.io/topics/persistence了解更多信息。

appendonly no

# 仅附加文件的名称(默认值:"appendonly.aof")

appendfilename "appendonly.aof"

# fsync()调用告诉操作系统将数据实际写入磁盘,而不是等待输出缓冲区中的更多数据。
# 有些操作系统确实会刷新磁盘上的数据,而另一些操作系统只会尝试尽快完成该操作。
#
# Redis支持三种不同的模式:
#
# no: 不要fsync,只要让OS在需要时刷新数据即可。 Faster 始终:每次写入仅附加日志后,fsync。 慢,最安全。 everysec:每秒仅同步一次fsync。 妥协。
#
# 默认值为"everysec",因为这通常是速度和数据安全性之间的正确折衷。
# 您可以了解是否可以将其放松为"no",这将使操作系统在需要时刷新输出缓冲区,
# 以获得更好的性能(但是如果您可以忍受某些数据丢失的想法,
# 请考虑使用默认的持久性模式 (即快照),或者相反,使用"总是",该速度非常慢,但比秒安全。
#
# 更多详细信息,请查看以下文章:
# http://antirez.com/post/redis-persistence-demystified.html
#
# 如果不确定,请使用"everysec"。

# appendfsync always
appendfsync everysec
# appendfsync no

# 当AOF fsync策略设置为always或everysec,并且后台保存进程(后台保存或AOF日志后台重写)对磁盘执行大量I/O时,
# 在某些Linux配置中,Redis可能会阻塞太长时间 fsync()调用。
# 请注意,目前尚无此修复程序,因为即使在其他线程中执行fsync也将阻止我们的同步write(2)调用。
#
# 为了减轻此问题,可以使用以下选项,以防止在进行BGSAVE或BGREWRITEAOF时在主进程中调用fsync()。
#
# 这意味着当另一个孩子正在保存时,Redis的持久性与"appendfsync none"相同。
# 实际上,这意味着在最坏的情况下(使用默认的Linux设置)可能会丢失多达30秒的日志。
#
# 如果您有延迟问题,请将其设为"是"。 否则,从耐久性的角度来看,将其保留为"否"是最安全的选择。

no-appendfsync-on-rewrite no

# 自动重写仅附加文件。
# 当AOF日志大小增加指定百分比时,Redis可以自动重写日志文件,隐式调用BGREWRITEAOF。
#
# 它是这样工作的:Redis会在最近一次重写后记住AOF文件的大小(如果自重新启动以来未发生任何重写,则使用启动时AOF的大小)。
#
# 将此基本大小与当前大小进行比较。 如果当前大小大于指定的百分比,则触发重写。
# 另外,您需要指定要重写的AOF文件的最小大小,这对于避免重写AOF文件非常有用,即使达到百分比增加,但它仍然很小。
#
# 指定零百分比以禁用自动AOF重写功能。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 当AOF数据重新加载到内存中时,在Redis启动过程中可能会发现AOF文件在末尾被截断。
# 这可能在运行Redis的系统崩溃时发生,尤其是在没有data = ordered选项的情况下挂载ext4文件系统时(
# 但是当Redis本身崩溃或中止但操作系统仍然可以正常工作时,这不会发生)。
#
# Redis在发生这种情况时可能会退出并显示错误,也可能会加载尽可能多的数据(当前为默认值),
# 如果发现AOF文件在末尾被截断,则会重新启动。 以下选项控制此行为。
#
# 如果aof-load-truncated设置为yes,则将加载截短的AOF文件,并且Redis服务器将开始发出日志以将事件通知用户。
# 否则,如果该选项设置为no,则服务器将中止并显示错误并拒绝启动。
# 如果将该选项设置为no,则用户需要在重新启动服务器之前使用"redis-check-aof"实用程序修复AOF文件。
#
# 请注意,如果在中间发现AOF文件已损坏,则服务器仍将退出并出现错误。 仅当Redis尝试从AOF文件读取更多数据但找不到足够的字节时,此选项才适用。
aof-load-truncated yes

# 重写AOF文件时,Redis可以使用AOF文件中的RDB前同步码来更快地进行重写和恢复。 启用此选项后,重写的AOF文件由两个不同的节组成:
#
# [RDB file][AOF tail]
#
# 加载时,Redis会识别AOF文件以"REDIS"字符串开头并加载带前缀的RDB文件,然后继续加载AOF尾部。
aof-use-rdb-preamble yes

################################ LUA SCRIPTING(LUA脚本) ###############################

# Lua脚本的最大执行时间(以毫秒为单位)。
#
# 如果达到了最大执行时间,则Redis将记录脚本在允许的最大时间后仍在执行中,并将开始以错误答复查询。
#
# 当长时间运行的脚本超过最大执行时间时,仅SCRIPT KILL和SHUTDOWN NOSAVE命令可用。
# 第一个可用于停止尚未调用写命令的脚本。
# 第二种是在脚本已发出写命令但用户不想等待脚本自然终止的情况下关闭服务器的唯一方法。
#
# 将其设置为0或负值以无警告地无限执行。
lua-time-limit 5000

################################ REDIS CLUSTER ###############################

# 普通Redis实例不能属于Redis集群; 只有作为群集节点启动的节点可以。 为了将Redis实例作为群集节点启动,请在不注释以下内容的情况下启用群集支持:
#
# cluster-enabled yes

# 每个群集节点都有一个群集配置文件。 该文件不适合手工编辑。 它由Redis节点创建和更新。
# 每个Redis群集节点都需要一个不同的群集配置文件。
# 确保在同一系统上运行的实例没有重叠的集群配置文件名。
#
# cluster-config-file nodes-6379.conf

# 群集节点超时是一个节点必须不可达的毫秒数,才能将其视为故障状态。
# 其他大多数内部时间限制是节点超时的倍数。
#
# cluster-node-timeout 15000

# 如果发生故障的主副本的数据看起来太旧,它将避免启动故障转移。
#
# 没有一种简单的方法可以使副本实际上具有其"数据寿命"的准确度量,因此执行以下两项检查:
#
# 1) 如果存在多个能够进行故障转移的副本,则它们会交换消息,以便尝试利用具有最佳复制偏移量(处理了更多来自主数据库的数据)的副本来获得优势。
# 副本将尝试按偏移量获取其等级,并将一个与它们的等级成比例的延迟应用于故障转移。
#
# 2) 每个单个副本都会计算与其母版之间最后一次交互的时间。
# 这可以是最后收到的ping或命令(如果主服务器仍处于"已连接"状态),也可以是自从与主服务器断开连接以来经过的时间(如果复制链接当前已关闭)。
# 如果最后一次交互太旧,副本将完全不会尝试故障转移。
#
# 用户可以调整点"2"。 具体而言,如果自从上次与主服务器进行交互以来,经过的时间大于以下时间,则副本将不执行故障转移:
#
# (node-timeout * replica-validity-factor) + repl-ping-replica-period
#
# 因此,例如,如果节点超时为30秒,并且副本有效性因子为10,并且假定默认的repl-ping-replica-period值为10秒,
# 则副本将无法尝试进行故障转移,如果它不能 与主对话时间超过310秒。
#
# 较大的副本有效性因子可能会使数据过旧的副本无法对主副本进行故障转移,而值太小可能会使群集根本无法选择副本。
#
# 为了获得最大可用性,可以将复制品有效性因子设置为0,这意味着,复制品将始终尝试对主数据库进行故障转移,而不考虑它们与主数据库的最后一次交互。
# (但是,他们将始终尝试应用与其偏移等级成比例的延迟)。
#
# 零是唯一能够确保所有分区恢复正常后,群集将始终能够继续运行的值。
#
# cluster-replica-validity-factor 10

# 群集副本能够迁移到孤立的主数据库,即那些没有工作副本的主数据库。
# 这样可以提高群集抵御故障的能力,因为如果没有工作副本,孤立的主节点在发生故障的情况下将无法进行故障转移。
#
# 仅当旧的主副本仍存在至少给定数量的其他工作副本时,副本副本才会迁移到孤立的主副本。
# 这个数字是"移民壁垒"。 迁移障碍为1表示仅当副本数据库的主副本上至少有1个其他工作副本时,副本副本才会迁移。
# 它通常反映出集群中每个主数据库所需的副本数。
#
# 默认为1(副本仅在其主数据库保留至少一个副本时迁移)。 要禁用迁移,只需将其设置为非常大的值即可。
# 可以设置为0,但仅对调试和生产危险有用。
#
# cluster-migration-barrier 1

# 默认情况下,如果Redis Cluster节点检测到至少发现一个哈希槽(没有可用的节点正在为其提供服务),它们将停止接受查询。
# 这样,如果集群部分关闭(例如,不再覆盖哈希槽的范围),则所有集群最终将变得不可用。
# 重新覆盖所有插槽后,它将自动返回可用状态。
#
# 但是有时您希望集群的子集正常工作,以继续接受对仍覆盖的部分键空间的查询。 为此,只需将cluster-require-full-coverage选项设置为no。
#
# cluster-require-full-coverage yes

# 此选项设置为yes时,可防止副本在主服务器发生故障时尝试对其主服务器进行故障转移。 但是,主服务器仍然可以执行手动故障转移(如果被迫执行)。
#
# 这在不同的情况下很有用,尤其是在多个数据中心操作的情况下,如果我们希望在完全DC故障的情况下不对一侧进行升级,则这是不希望的。
#
# cluster-replica-no-failover no

# 此选项设置为yes时,只要集群认为自己拥有插槽,就可以在集群处于关闭状态时为节点提供读取流量。
#
# 这在两种情况下很有用。 第一种情况是在节点故障或网络分区期间应用程序不需要数据一致性时。
# 缓存的一个例子,只要节点拥有数据,它就应该能够为它服务。
#
# 第二个用例是用于不符合建议的三个分片但希望启用集群模式并在以后扩展的配置。
# 如果没有设置此选项,则在1或2分片配置中的主服务器中断会导致整个集群的读/写中断,只有在设置了该选项的情况下,才会发生写中断。
# 如果没有法定人数的主持人,则插槽所有权不会自动更改。
#
# cluster-allow-reads-when-down no

# 为了设置您的集群,请确保阅读文档
# 可从http://redis.io网站获得。

########################## CLUSTER DOCKER/NAT support ########################

# 在某些部署中,Redis Cluster节点的地址发现失败,这是因为地址经过NAT限制或端口被转发(典型情况是Docker和其他容器)。
#
# 为了使Redis Cluster在这样的环境中工作,需要一个静态配置,其中每个节点都知道其公共地址。 以下两个选项用于此范围,分别是:
#
# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-bus-port
#
# 每个命令都向节点指示其地址,客户端端口和集群消息总线端口。 然后将信息发布在总线数据包的标头中,以便其他节点将能够正确映射发布信息的节点的地址。
#
# 如果未使用上述选项,则将使用常规的Redis群集自动检测。
#
# 请注意,重新映射后,总线端口可能不在客户端端口+ 10000的固定偏移处,因此您可以根据重新映射的方式指定任何端口和总线端口。
# 如果未设置总线端口,通常将使用10000的固定偏移量。
#
# 示例:
#
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380

################################## SLOW LOG ###################################

# Redis Slow Log是一个用于记录超过指定执行时间的查询的系统。
# 执行时间不包括与客户端交谈,发送回复等I/O操作,而是实际执行命令所需的时间(
# 这是命令执行的唯一阶段,在该阶段线程被阻塞并且可以 在此期间不满足其他要求)。
#
# 您可以使用以下两个参数配置慢速日志:一个告诉Redis,为了使命令被记录,执行时间要超过多少微秒,而另一个参数是慢速日志的长度。
# 记录新命令时,最旧的命令将从记录的命令队列中删除。

# 以下时间以微秒表示,因此1000000等于一秒。 请注意,负数将禁用慢速日志记录,而零值将强制记录每个命令。
slowlog-log-slower-than 10000

# 此长度没有限制。 请注意,它将消耗内存。
# 您可以使用SLOWLOG RESET回收慢速日志使用的内存。
slowlog-max-len 128

################################ LATENCY MONITOR(延迟监视) ##############################

# Redis延迟监视子系统会在运行时对不同的操作进行采样,以收集与Redis实例的潜在延迟源相关的数据。
#
# 通过LATENCY命令,该信息可供打印图形并获取报告的用户使用。
#
# 系统仅记录在等于或大于通过delay-monitor-threshold配置指令指定的毫秒数内执行的操作。 当其值设置为零时,等待时间监视器将关闭。
#
# 默认情况下,延迟监视是禁用的,因为如果您没有延迟问题,通常不需要它,并且收集数据会对性能产生影响,尽管影响很小,但是可以在大负载下进行测量。
# 如果需要,可以在运行时使用命令"CONFIG SET delay-monitor-threshold <milliseconds>"轻松启用延迟监视。
latency-monitor-threshold 0

############################# EVENT NOTIFICATION(活动通知) ##############################

# Redis可以将关键空间中发生的事件通知给发布/订阅客户端。
# 此功能记录在http://redis.io/topics/notifications
#
# 例如,如果启用了键空间事件通知,并且客户端对存储在数据库0中的键"foo"执行了DEL操作,则将通过Pub / Sub发布两条消息:
#
# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo
#
# 可以在一组类中选择Redis将通知的事件。 每个类都由一个字符标识:
#
# K 键空间事件,以__keyspace@<db>__前缀发布。
# E 键事件,以__keyevent@<db>__前缀发布。
# g 通用命令(非类型专用),例如DEL,EXPIRE,RENAME,...
# $ 字符串命令
# l 列出命令
# s 设定指令
# h 哈希命令
# z 排序集命令
# x 过期事件(每次密钥过期时生成的事件)
# e 驱逐事件(驱逐密钥以获取最大内存时生成的事件)
# t 流命令
# m 按键缺失事件(注意:它不包含在"A"类中)
# A g$lshzxet的别名,以便"AKE"字符串表示所有事件(由于键丢失事件的独特性质,这些键事件被排除在"A"之外)。
#
# "notify-keyspace-events"将由零个或多个字符组成的字符串作为参数。 空字符串表示已禁用通知。
#
# Example: to enable list and generic events, from the point of view of the
# event name, use:
#
# notify-keyspace-events Elg
#
# Example 2: to get the stream of the expired keys subscribing to channel
# name __keyevent@0__:expired use:
#
# notify-keyspace-events Ex
#
# 默认情况下,所有通知均被禁用,因为大多数用户不需要此功能,并且该功能会有一些开销。 请注意,如果您未指定K或E中的至少一个,则不会传递任何事件。
notify-keyspace-events ""

############################### GOPHER SERVER #################################

# Redis包含RFC 1436(https://www.ietf.org/rfc/rfc1436.txt)中指定的Gopher协议的实现。
#
# Gopher协议在90年代后期非常流行。 它是Web的替代方法,服务器和客户端的实现是如此简单,以至于Redis服务器只有100行代码才能实现这种支持。
#
# 您现在如何使用Gopher? 好吧,Gopher从未真正死过,最近出现了一种运动,目的是使Gopher具有更多层次结构的内容(仅由纯文本文档组成)得以复活。
# 有些人希望使用更简单的互联网,另一些人则认为主流互联网已变得过于可控,为想要一点新鲜空气的人们创造替代空间很酷。
#
# 无论如何,在Redis诞生10周年之际,我们给了它Gopher协议作为礼物。
#
# - - 怎么运行的? ---
#
# Redis Gopher支持使用Redis的内联协议,特别是两种仍然非法的内联请求:空请求或任何以"/"开头的请求(没有以这样的斜杠开头的Redis命令)。
# 正常的RESP2/RESP3请求完全超出了Gopher协议实现的范围,并且通常也得到满足。
#
# 如果在启用Gopher时打开与Redis的连接,并向其发送"/ foo"之类的字符串,则如果存在名为"/ foo"的密钥,则会通过Gopher协议为其提供服务。
#
# 为了创建一个真正的Gopher"hole"(Gopher对话中Gopher站点的名称),您可能需要类似以下的脚本:
#
# https://github.com/antirez/gopher2redis
#
# - - 安全警告 - -
#
# 如果您打算将Redis放在服务器Gopher页面的公共访问地址上,请确保为实例设置密码。
# 设置密码后:
#
# 1. Gopher服务器(启用后,默认情况下未启用)仍将通过Gopher提供内容。
# 2. 但是,在客户端进行身份验证之前无法调用其他命令。
#
# 因此,请使用'requirepass'选项保护您的实例。
#
# 要启用Gopher支持,请取消注释以下行,并将选项从no(默认)设置为yes。
#
# gopher-enabled no

############################### ADVANCED CONFIG ###############################

# 当哈希条目数较少且最大条目数不超过给定阈值时,将使用内存高效的数据结构对其进行编码。 可以使用以下指令配置这些阈值。
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

# 列表也以特殊方式编码,以节省大量空间。
# 每个内部列表节点允许的条目数可以指定为固定的最大大小或最大元素数。
# 对于固定的最大大小,请使用-5到-1,表示:
# -5:最大大小:64 Kb <-不建议用于正常工作负载
# -4:最大大小:32 Kb <-不推荐
# -3:最大大小:16 Kb <-可能不建议
# -2:最大大小:8 Kb <-好
# -1:最大大小:4 Kb <-好
# 正数表示每个列表节点最多存储_exactly_个元素。
# 最高性能的选项通常是-2(8 Kb大小)或-1(4 Kb大小),但是如果您的用例是唯一的,请根据需要调整设置。
list-max-ziplist-size -2


# 列表也可能被压缩。
# 压缩深度是从列表的*each*侧到*exclude*压缩的快速列表ziplist节点的数量。为了快速执行 push/pop 出操作,列表的开头和结尾始终未压缩。 设置为:
# 0: 禁用所有列表压缩
# 1: 深度1表示"直到头上有1个节点之后,才开始压缩"
# So: [head]->node->node->...->node->[tail]
# [head], [tail] will always be uncompressed; inner nodes will compress.
# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
# 这里的2表示:不要压缩head或head-> next或tail-> prev或tail,而是压缩它们之间的所有节点。
# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
# 等
list-compress-depth 0

# 集仅在一种情况下具有特殊的编码:当集仅由字符串组成,这些字符串恰好是基数10中的整数,范围为64位有符号整数。
# 以下配置设置设置了大小限制,以便使用此特殊的内存节省编码。
set-max-intset-entries 512

# 与散列和列表类似,对排序集也进行了特殊编码,以节省大量空间。 仅当排序集的长度和元素低于以下限制时,才使用此编码:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

# HyperLogLog稀疏表示字节数限制。 限制包括16个字节的标头。 当使用稀疏表示的HyperLogLog超过此限制时,它将转换为密集表示。
#
# 大于16000的值是完全没有用的,因为那时候密集表示的存储效率更高。
#
# 建议的值是〜3000,以便在不减慢PFADD的情况下获得节省空间编码的优点,而PFADD的稀疏编码为O(N)。
# 当不关心CPU但空间很大时,该值可以提高到10000,并且数据集由基数在0-15000范围内的许多HyperLogLog组成。
hll-sparse-max-bytes 3000

# 流宏节点的最大大小/项目。 流数据结构是一个大节点的基数树,它对内部的多个项目进行编码。
# 使用此配置,可以配置单个节点的大小(以字节为单位),以及在添加新的流条目时切换到新节点之前它可能包含的最大项目数。
# 如果以下任何设置被设置为零,则该限制将被忽略,例如,可以通过将max-bytes设置为0并将max-entries设置为所需值来仅设置最大整体限制。
stream-node-max-bytes 4096
stream-node-max-entries 100

# 主动重新哈希处理每100毫秒CPU时间使用1毫秒,以帮助重新哈希主Redis哈希表(将顶级键映射到值的一个哈希表)。
# Redis使用的哈希表实现(请参见dict.c)执行一次懒惰的重新哈希处理:您在要进行哈希处理的哈希表中运行的操作越多,
# 执行的哈希处理"步骤"就越多,因此,如果服务器空闲,则哈希处理将永远不会完成 散列表使用更多的内存。
#
# 默认值是每秒使用10毫秒的毫秒数来主动重新哈希主字典,并在可能的情况下释放内存。
#
# 如果不确定:
# 如果您有严格的延迟要求,请使用"activerehashing no",并且在您的环境中,Redis可以不时地以2毫秒的延迟答复查询不是一件好事。
#
# 如果您没有如此严格的要求,但希望在可能的情况下尽快释放内存,请使用"activerehashing yes"。
activerehashing yes

# 客户端输出缓冲区限制可用于出于某些原因强制断开那些没有足够快地从服务器读取数据的客户端(
# 常见原因是Pub/Sub客户端无法像发布者所产生的那样快地消费消息。 他们)。
#
# 可以为三种不同类别的客户端设置不同的限制:
#
# normal -> 普通客户,包括MONITOR客户
# replica -> 复制客户端
# pubsub -> 客户订阅了至少一个pubsub频道或模式
#
# 每个client-output-buffer-limit指令的语法如下:
#
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
#
# 一旦达到硬限制,或者达到软限制并且在指定的秒数内(连续)保持达到此限制,客户端将立即断开连接。
# 因此,例如,如果硬限制为32兆字节,软限制为16兆字节/ 10秒,则如果输出缓冲区的大小达到32兆字节,客户端将立即断开连接,
# 但是如果客户端达到16兆字节,则也将断开连接 并持续超过限制10秒钟。
#
# 默认情况下,普通客户端不受限制,因为它们不会在不询问的情况下(以推送方式)接收数据,而是在请求之后才接收数据,
# 因此只有异步客户端可能会创建这样一种场景:请求数据的速度比读取数据的速度快。
#
# 相反,对pubsub和副本客户端没有默认限制,因为订阅者和副本以推送方式接收数据。
#
# 可以通过将硬限制或软限制设置为零来禁用它们。
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# 客户端查询缓冲区累积新命令。 默认情况下,它们被限制为固定数量,以避免协议去同步(例如,由于客户端中的错误)会导致查询缓冲区中的未绑定内存使用。 # 但是,如果您有非常特殊的需求,例如巨大的multi / exec请求等,则可以在此处进行配置。
#
# client-query-buffer-limit 1gb

# 在Redis协议中,批量请求(即表示单个字符串的元素)通常限制为512 mb以上。 但是,您可以在此处更改此限制。
#
# proto-max-bulk-len 512mb

# Redis调用一个内部函数来执行许多后台任务,例如在超时时关闭客户端连接,清除从未请求的过期密钥等。
#
# 并非所有任务都以相同的频率执行,但是Redis根据指定的"hz"值检查要执行的任务。
#
# 默认情况下,"hz"设置为10。提高该值将在Redis空闲时使用更多的CPU,但是同时当有多个键同时到期时,它将使Redis的响应速度更快,并且可以使用 更精确。
#
# 范围在1到500之间,但是值通常不能超过100。 大多数用户应该使用默认值10,并且仅在要求非常低延迟的环境中才将其提高到100。
hz 10

# 通常,与连接的客户端数量成比例的HZ值很有用。 例如,这有助于避免每次后台任务调用处理过多的客户端,从而避免延迟尖峰。
#
# 由于默认的默认HZ值保守地设置为10,Redis提供并默认启用了使用自适应HZ值的能力,当有许多连接的客户端时,该值将暂时升高。
#
# 启用动态HZ时,实际配置的HZ将用作基准,但是一旦连接了更多客户端,实际将使用配置的HZ值的倍数。
# 这样,空闲实例将占用很少的CPU时间,而忙碌的实例将具有更高的响应速度。
dynamic-hz yes

# 当孩子重写AOF文件时,如果启用以下选项,则每生成32 MB的数据,文件就会进行同步处理。 为了将文件更多地提交到磁盘并避免大的延迟尖峰,这很有用。
aof-rewrite-incremental-fsync yes

# 当redis保存RDB文件时,如果启用以下选项,则每生成32 MB数据将对文件进行fsync处理。 为了将文件更多地提交到磁盘并避免大的延迟尖峰,这很有用。
rdb-save-incremental-fsync yes

# 可以调整Redis LFU逐出(请参阅maxmemory设置)。
# 但是,最好从默认设置开始,仅在研究了如何提高性能以及LFU键随时间的变化后才进行更改,可以通过OBJECT FREQ命令进行检查。
#
# Redis LFU实现中有两个可调参数:计数器对数因子和计数器衰减时间。 重要的是在更改两个参数之前先了解它们的含义。
#
# LFU计数器每个密钥只有8位,最大值是255,因此Redis使用具有对数行为的概率增量。 给定旧计数器的值,当访问一个键时,计数器以这种方式递增:
#
# 1. A random number R between 0 and 1 is extracted.
# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1).
# 3. The counter is incremented only if R < P.
#
# 默认的lfu-log-factor是10。这是一个表格,该表格显示频率计数器如何随着具有不同对数因子的不同访问次数而变化:
#
# +--------+------------+------------+------------+------------+------------+
# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
# +--------+------------+------------+------------+------------+------------+
# | 0 | 104 | 255 | 255 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 1 | 18 | 49 | 255 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 10 | 10 | 18 | 142 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 100 | 8 | 11 | 49 | 143 | 255 |
# +--------+------------+------------+------------+------------+------------+
#
# 注意:上表是通过运行以下命令获得的:
#
# redis-benchmark -n 1000000 incr foo
# redis-cli object freq foo
#
# 注意2:计数器的初始值为5,以便使新对象有机会累积命中数。
#
# 计数器衰减时间是必须经过的时间(以分钟为单位),以便将密钥计数器除以2(如果值小于等于10,则递减)。
#
# lfu-decay-time的默认值为1。特殊值0表示每次碰巧扫描计数器都会使其衰减。
#
# lfu-log-factor 10
# lfu-decay-time 1

########################## ACTIVE DEFRAGMENTATION(主动碎片整理) #######################
#
# 什么是主动碎片整理?
# -------------------------------
#
# 通过主动(在线)碎片整理,Redis服务器可以压缩内存中小量分配和释放数据之间剩余的空间,从而可以回收内存。
#
# 碎片是每个分配器(幸运的是,Jemalloc发生的情况)和某些工作负载都会发生的自然过程。
# 通常,需要重新启动服务器以减少碎片,或者至少清除所有数据并重新创建。
# 但是,由于Oran Agra为Redis 4.0实现了此功能,因此在服务器运行时,此过程可以在运行时以"热"方式进行。
#
# 基本上,当碎片超过一定级别时(请参阅下面的配置选项),Redis将开始通过利用某些特定的Jemalloc功能在连续的内存区域中创建值的新副本(
# 以了解分配是否导致碎片,并 将其分配到更好的位置),同时将释放数据的旧副本。
# 对于所有键,以增量方式重复此过程将导致碎片恢复到正常值。
#
# 重要事项:
#
# 1. 默认情况下,此功能是禁用的,并且仅当您编译Redis以使用我们随Redis的源代码提供的Jemalloc副本时才起作用。
# 这是Linux构建的默认设置。
#
# 2. 如果没有碎片问题,则无需启用此功能。
#
# 3. 一旦遇到碎片,您可以在需要时使用命令"CONFIG SET activedefrag yes"启用此功能。
#
# 配置参数能够微调碎片整理过程的行为。 如果您不确定它们的含义,最好不要更改默认值。

# 启用主动碎片整理
# activedefrag no

# 启动主动碎片整理的最小碎片浪费
# active-defrag-ignore-bytes 100mb

# 启动活动碎片整理的最小碎片百分比
# active-defrag-threshold-lower 10

# 我们最大程度地努力下的最大碎片百分比
# active-defrag-threshold-upper 100

# 在达到下限阈值时使用最小的CPU碎片整理工作
# active-defrag-cycle-min 1

# 在达到上限阈值时使用最大的精力进行碎片整理
# active-defrag-cycle-max 25

# 将在主字典扫描中处理的set / hash / zset / list字段的最大数量
# active-defrag-max-scan-fields 1000

# 默认情况下,将启用用于清除的Jemalloc后台线程
jemalloc-bg-thread yes

# 可以将Redis的不同线程和进程固定到系统中的特定CPU,以最大化服务器的性能。
# 这不仅可以在不同的CPU中固定不同的Redis线程,而且还可以确保将在同一主机上运行的多个Redis实例固定到不同的CPU。
#
# 通常,您可以使用"taskset"命令执行此操作,但是在Linux和FreeBSD中,也可以直接通过Redis配置进行此操作。
#
# 您可以固定服务器/ IO线程,生物线程,aof重写子进程和bgsave子进程。 指定cpu列表的语法与taskset命令相同:
#
# Set redis server/io threads to cpu affinity 0,2,4,6:
# server_cpulist 0-7:2
#
# Set bio threads to cpu affinity 1,3:
# bio_cpulist 1,3
#
# Set aof rewrite child process to cpu affinity 8,9,10,11:
# aof_rewrite_cpulist 8-11
#
# Set bgsave child process to cpu affinity 1,10,11
# bgsave_cpulist 1,10-11

EOF

8.2 创建deployment文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
cat >> 1-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:6
ports:
- containerPort: 6379
command:
- "sh"
- "-c"
- "redis-server /etc/redis.conf"
volumeMounts:
- name: redis-config
mountPath: /etc/redis.conf
subPath: redis.conf
volumes:
- name: redis-config
configMap:
name: redis-config
items:
- key: redis.conf
path: redis.conf

EOF

8.3 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat >> 2-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
spec:
ports:
- name: redis
port: 6379
protocol: TCP
targetPort: 6379
nodePort: 30003
type: NodePort
selector:
app: redis

EOF

8.4 应用

1
2
3
kubectl apply  -f 0-configMap.yaml
kubectl apply -f 1-deployment.yaml
kubectl apply -f 2-service.yaml

九、部署kube-prometheus

9.1 下载解压,修复监控

1
2
3
4
5
wget https://ghproxy.com/https://github.com/prometheus-operator/kube-prometheus/archive/refs/tags/v0.12.0.zip
unzip v0.12.0.zip
cd kube-prometheus-0.12.0/manifests
#替换所有granfana版本为9.0.2
sed -i 's|9.3.2|9.0.2|g' grafana-*

1.配置kubeControllermanagerService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mkdir repair-prometheus ;
cat >> repair-prometheus/kubeControllermanagerService.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
labels: #定义这个service的标签,因为kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml里面定义了这个标签
app.kubernetes.io/name: kube-controller-manager
name: kube-controller-manager
namespace: kube-system #名称空间是kube-system
spec:
selector: #这个标签选择器表示我们要关联到kube-controller-manager-master的pod上
component: kube-controller-manager #kubectl get pods kube-controller-manager-master -n kube-system --show-labels
ports:
- name: https-metrics #service端口名称,这个名称要与ServiceMonitor的port名称一致
port: 10257
targetPort: 10257 # kube-controller-manager-master的pod的端口
EOF

2.配置kubeSchedulerService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat >> repair-prometheus/kubeSchedulerService.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
labels: #定义这个service的标签,因为kubernetesControlPlane-serviceMonitorKubeScheduler.yaml里面定义了这个标签
app.kubernetes.io/name: kube-scheduler
name: kube-scheduler
namespace: kube-system #名称空间是kube-system
spec:
selector: #这个标签选择器表示我们要关联到kube-scheduler的pod上
component: kube-scheduler # kubectl get pods kube-scheduler-master -n kube-system --show-labels
ports:
- name: https-metrics #service端口名称,这个名称要与ServiceMonitor的port名称一致
port: 10259
targetPort: 10259 #kube-scheduler-master的端口
EOF

3.修改绑定ip(可选,master节点都需执行)

还有一点,kube-scheduler-master和kube-controller-manager这2个pod启动的时候默认绑定的地址是127.0.0.1,所以普罗米修斯通过ip去访问
就会被拒绝,所以需要修改一下,我们知道这2个系统组件是是以静态pod的方式启动的,所以进入到master节点的静态pod目录
如果我们不指定静态pod目录时在哪里,可以通过kubelet查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

[root@master manifests]# systemctl status kubelet.service | grep '\-\-config'
└─429488 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5

[root@master manifests]# grep static /var/lib/kubelet/config.yaml
staticPodPath: /etc/kubernetes/manifests #这就是静态pod的目录
[root@master manifests]#

[root@master ~]# cd /etc/kubernetes/manifests
[root@master manifests]# grep 192 kube-scheduler.yaml
- --bind-address=192.168.118.131 #修改127.0.0.1为主机的ip,修改为0.0.0.0也行
host: 192.168.118.131 #其实保持默认127.0.0.1也行
host: 192.168.118.131 #其实保持默认127.0.0.1也行
[root@master manifests]#

[root@master manifests]# vim kube-controller-manager.yaml
- --bind-address=192.168.118.131 #修改127.0.0.1为主机的ip,修改为0.0.0.0也行
host: 192.168.118.131 #其实保持默认127.0.0.1也行
host: 192.168.118.131 #其实保持默认127.0.0.1也行
[root@master manifests]#

#发现修改后scheduler和controller-manager pod消失了,一直也没有重新创建pod
#所以重启kubelet后pod都正常了
[root@master manifests]# systemctl restart kubelet.service

9.2 配置prometheus持久化

1
vim prometheus-prometheus.yaml

添加

1
2
3
4
5
6
7
8
storage: #这部分为持久化配置
volumeClaimTemplate:
spec:
storageClassName: nfs-retain
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi

9.3 存储时长配置为30天

1
vim prometheusOperator-deployment.yaml

添加

1
- storage.tsdb.retention.time=30d # 在这添加time参数

9.4 Grafana配置持久化

1.建立grafana-pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat >> grafana-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-pvc
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: nfs-retain
EOF

2.修改grafana-deployment.yaml

1
vim grafana-deployment.yaml

把emptydir存储方式改为pvc方式:

1
2
3
- name: grafana-storage
persistentVolumeClaim:
claimName: grafana-pvc

9.5 创建服务暴露

1.暴露grafana

1
vim grafana-service.yaml

添加

1
2
	nodePort: 30006
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer

2.暴露Prometheus

1
vim prometheus-service.yaml

修改

1
2
3
4
5
6
7
8
9
10
11
ports:
- name: web
port: 9090
targetPort: web
nodePort: 30007
- name: reloader-web
port: 8080
targetPort: reloader-web
nodePort: 30008
type: NodePort

3.暴露Alert Manager

1
vim alertmanager-service.yaml

修改

1
2
3
4
5
6
7
8
9
10
11
ports:
- name: web
port: 9093
targetPort: web
nodePort: 30009
- name: reloader-web
port: 8080
targetPort: reloader-web
nodePort: 30010
type: NodePort

9.6 自定义DashboardPage文件JS

修改grafana-deployment.yaml

1
vim grafana-deployment.yaml

把emptydir存储方式改为pvc方式:

1
2
3
4
5
6
7
8
9
10
11
- name: dashboardpage-js-volume
mountPath: /usr/share/grafana/public/build/DashboardPage.53b203c85adb3a57b1ac.js
subPath: DashboardPage.53b203c85adb3a57b1ac.js


- name: dashboardpage-js-volume
configMap:
name: grafana-dashboardpage-js-configmap
items:
- key: DashboardPage.53b203c85adb3a57b1ac.js
path: DashboardPage.53b203c85adb3a57b1ac.js

![](_v_images/20230226003837612_11533.png =693x)

修改grafana.ini
vim grafana-config.yaml

1
2
3
4
5
6
[security]
allow_embedding = true
[auth.anonymous]
enabled = true
[users]
default_theme = light

9.7 安装

上传DashboardPage附件:
DashboardPage.53b203c85adb3a57b1ac.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cd ../..
kubectl create ns monitoring
#将附件DashboardPage.53b203c85adb3a57b1ac.js上传服务器
kubectl create configmap -n monitoring grafana-dashboardpage-js-configmap --from-file=DashboardPage.53b203c85adb3a57b1ac.js

kubectl apply --server-side -f kube-prometheus-0.12.0/manifests/setup
kubectl wait \
--for condition=Established \
--all CustomResourceDefinition \
--namespace=monitoring
kubectl apply -f kube-prometheus-0.12.0/manifests/


#镜像下载
ctr -n k8s.io i pull k8s.dockerproxy.com/kube-state-metrics/kube-state-metrics:v2.7.0
ctr -n k8s.io i pull k8s.dockerproxy.com/prometheus-adapter/prometheus-adapter:v0.10.0
ctr -n k8s.io i tag k8s.dockerproxy.com/kube-state-metrics/kube-state-metrics:v2.7.0 registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.7.0
ctr -n k8s.io i tag k8s.dockerproxy.com/prometheus-adapter/prometheus-adapter:v0.10.0 registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.10.0
ctr -n k8s.io i rm k8s.dockerproxy.com/kube-state-metrics/kube-state-metrics:v2.7.0
ctr -n k8s.io i rm k8s.dockerproxy.com/prometheus-adapter/prometheus-adapter:v0.10.0

9.8 部署完毕后无法访问,删除网络策略

1
kubectl delete networkpolicy --all -n monitoring

9.9 访问

1
2
3
4
5
6
7
8
#Prometheus
通过 http://174.1.0.98:30007/ 访问

#Grafana
通过 http://174.1.0.98:30006/ 访问并使用默认的 grafana 用户:密码 admin:admin

#Alert Manager
通过 http://174.1.0.98:30009/ 访问

9.10 导入模板,配置亮色主题

模板:
pageinfo-1668405034945.json

![](_v_images/20230313122509763_28393.png =1091x)
![](_v_images/20230313122521689_31570.png =603x)
![](_v_images/20230313122543495_21901.png =530x)
![](_v_images/20230313122618215_12330.png =762x)

十、era后端部署

10.1 登陆数据库,创建era用户及库

1
2
3
4
5
use mysql;
create database era CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
create user 'era'@'%' identified by '&V#^hjmp9%44G@';
grant all privileges on era.* to 'era'@'%';
flush privileges;

导入附近sql模板:
era-prod.sql

10.2 修改bootstrap.yml配置文件nacos地址

vim bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /api/v1
spring:
application:
name: era-admin
jackson:
time-zone: GMT+8
# 默认属性系列化策略:always、non_null、non_empty、non_absent、use_default..
default-property-inclusion: always
# date 类型以时间戳返回
serialization:
write-dates-as-timestamps: true
# 序列化返回空对象
FAIL_ON_EMPTY_BEANS: false
cloud:
nacos:
username: nacos
password: nacos
discovery:
# 服务注册地址
server-addr: nacos.default.svc.cluster.local:8848
namespace: ea2ee798-43db-4b50-8033-baf43599aea5

# server-addr: 10.36.160.102:8848
# namespace: dev
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
file-extension: yml
#指定共享配置,且支持动态刷新
extension-configs:
- data-id: application.yml
refresh: true
- data-id: sys-config.yml
refresh: true
- data-id: kubeconfig.yml
refresh: true
- data-id: message.yml
refresh: true

10.3 修改nacos相关配置

![](_v_images/20230227115633947_11263.png =827x)

10.4 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir era-back;cd era-back
cat >> 1-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: era-back-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: nfs-retain

EOF

10.5 创建deployment文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
cat >> 2-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: era-back
spec:
replicas: 1
selector:
matchLabels:
app: era-back
template:
metadata:
labels:
app: era-back
spec:
hostAliases:
#- ip: "10.17.10.31"
# hostnames:
# - "mail.superfluidity.com.cn"
- ip: "200.0.1.90"
hostnames:
- "lb.cluster.local"
containers:
- name: era-back
image: openjdk:11
imagePullPolicy: IfNotPresent
command:
- /bin/bash
- -c
- cd /usr/src/myapp && java -jar -Duser.timezone=GMT+08 era-admin.jar
#- sleep 99999
securityContext:
privileged: true
ports:
- name: web
containerPort: 8080
protocol: "TCP"
volumeMounts:
- mountPath: /usr/src/myapp
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: era-back-pvc
EOF

10.6 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat >> 3-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: era-back-svc
labels:
app: era-back
spec:
ports:
- name: web-port
port: 8080
protocol: TCP
targetPort: 8080
nodePort: 30011
type: NodePort
selector:
app: era-back

EOF

10.7 应用

1
2
3
kubectl apply  -f 1-pvc.yaml
kubectl apply -f 2-deployment.yaml
kubectl apply -f 3-service.yaml

10.8 复制era-back.jar包及bootstrap.yml文件至pvc


era-admin.jar

10.9 重启服务

1
2
kubectl delete -f 2-deployment.yaml
kubectl apply -f 2-deployment.yaml

十一、era前端部署

11.1 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir era-front;cd era-front
cat >> 1-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: era-front-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: nfs-retain

EOF

11.2 创建deployment文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cat >> 2-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: era-front
spec:
replicas: 1
selector:
matchLabels:
app: era-front
template:
metadata:
labels:
app: era-front
spec:
containers:
- name: era-front
image: nginx:1.23.1
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
protocol: "TCP"
volumeMounts:
- name: data
mountPath: /etc/nginx/conf.d
subPath: conf.d
- name: data
mountPath: /webs
subPath: webs
volumes:
- name: data
persistentVolumeClaim:
claimName: era-front-pvc

EOF

11.3 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat >> 3-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: era-front-svc
labels:
app: era-front
spec:
ports:
- name: web-port
port: 80
protocol: TCP
targetPort: 80
nodePort: 30012
type: NodePort
selector:
app: era-front

EOF

11.4 应用

1
2
3
kubectl apply  -f 1-pvc.yaml
kubectl apply -f 2-deployment.yaml
kubectl apply -f 3-service.yaml

11.5 复制era-front.conf包及era-front前端文件至pvc

附件:
era-front.conf

test.tar.gz

11.6 重启服务

1
2
kubectl delete -f 2-deployment.yaml
kubectl apply -f 2-deployment.yaml

十二、era镜像服务部署

12.1 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir era-images;cd era-images
cat >> 1-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: era-images-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
storageClassName: nfs-retain

EOF

12.2 创建deployment文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cat >> 2-deployment.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: era-images
spec:
replicas: 1
selector:
matchLabels:
app: era-images
template:
metadata:
labels:
app: era-images
spec:
containers:
- name: era-images
image: nginx:1.23.1
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
protocol: "TCP"
volumeMounts:
- name: data
mountPath: /etc/nginx/conf.d
subPath: conf.d
- name: data
mountPath: /images
subPath: images
volumes:
- name: data
persistentVolumeClaim:
claimName: era-images-pvc

EOF

12.3 创建服务暴露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat >> 3-service.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
name: era-images-svc
labels:
app: era-images
spec:
ports:
- name: web-port
port: 80
protocol: TCP
targetPort: 80
nodePort: 30013
type: NodePort
selector:
app: era-images

EOF

12.4 应用

1
2
3
kubectl apply  -f 1-pvc.yaml
kubectl apply -f 2-deployment.yaml
kubectl apply -f 3-service.yaml

12.5 复制era-images.conf包至pvc


era-images.conf

12.6 重启服务

1
2
kubectl delete -f 2-deployment.yaml
kubectl apply -f 2-deployment.yaml

十三、(可选)监控系统部署

13.1 数据创建相关库及用户

1
2
3
4
5
create database zabbix character set utf8mb4 collate utf8mb4_bin;
use mysql;
create user 'zabbix'@'%' identified by '4GtJvRS%La76iB';
grant all privileges on zabbix.* to 'zabbix'@'%';
FLUSH PRIVILEGES;

13.2 创建命名空间

1
2
3
4
5
6
7
mkdir zabbix;cd zabbix
cat >> 0-namespace.yaml << "EOF"
apiVersion: v1
kind: Namespace
metadata:
name: zabbix
EOF

13.3 创建pvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat >> 1-pvc.yaml << "EOF"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: zabbix-pvc
namespace: zabbix
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: nfs-retain

EOF

13.4 部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
cat >> 2-zabbix-web-service.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: zabbix-web-service
namespace: zabbix
spec:
replicas: 1
selector:
matchLabels:
app: zabbix-web-service
template:
metadata:
labels:
app: zabbix-web-service
spec:
containers:
- name: zabbix-web-service
image: zabbix/zabbix-web-service:ubuntu-6.0-latest
ports:
- containerPort: 10053
env:
- name: ZBX_ALLOWEDIP
value: "::/0"
securityContext:
capabilities:
add:
- SYS_ADMIN
volumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true
- name: zabbix-data
mountPath: /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
subPath: DejaVuSans.ttf
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: zabbix-data
persistentVolumeClaim:
claimName: zabbix-pvc

---
apiVersion: v1
kind: Service
metadata:
name: zabbix-web-service
namespace: zabbix
spec:
selector:
app: zabbix-web-service
ports:
- name: zabbix-web-service
port: 10053
targetPort: 10053
nodePort: 30053
type: NodePort

EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
cat >> 3-zabbix-server-mysql.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: zabbix-server-mysql
namespace: zabbix
spec:
replicas: 1
selector:
matchLabels:
app: zabbix-server-mysql
template:
metadata:
labels:
app: zabbix-server-mysql
spec:
containers:
- name: zabbix-server-mysql
image: zabbix/zabbix-server-mysql:ubuntu-6.0-latest
ports:
- containerPort: 10051
env:
- name: DB_SERVER_HOST
value: "mariadb.default.svc.cluster.local"
- name: DB_SERVER_PORT
value: "3306"
- name: MYSQL_DATABASE
value: "zabbix"
- name: MYSQL_USER
value: "zabbix"
- name: MYSQL_PASSWORD
value: "4GtJvRS%La76iB"
- name: MYSQL_ROOT_PASSWORD
value: "4y6Cu%946*!TXY"
- name: ZBX_WEBSERVICEURL
value: "http://zabbix-web-service.zabbix.svc.cluster.local:10053/report"
- name: ZBX_JAVAGATEWAY_ENABLE
value: "true"
- name: ZBX_JAVAGATEWAY
value: "zabbix-java-gateway.zabbix.svc.cluster.local:10052"
- name: ZBX_STARTREPORTWRITERS
value: "2"
- name: ZBX_TIMEOUT
value: "30"
- name: ZBX_UNREACHABLEPERIOD
value: "120"
- name: ZBX_CACHESIZE
value: "512M"
- name: ZBX_HISTORYCACHESIZE
value: "128M"
- name: ZBX_HISTORYINDEXCACHESIZE
value: "128M"
- name: ZBX_TRENDCACHESIZE
value: "128M"
- name: ZBX_VALUECACHESIZE
value: "256M"
volumeMounts:
- name: zabbix-data
mountPath: /usr/lib/zabbix
subPath: zabbix-scripts
- name: localtime
mountPath: /etc/localtime
readOnly: true
- name: zabbix-agent
image: zabbix/zabbix-agent:ubuntu-6.0-latest
imagePullPolicy: IfNotPresent
env:
- name: ZBX_HOSTNAME
value: "Zabbix server"
- name: ZBX_SERVER_HOST
value: "127.0.0.1"
- name: ZBX_STARTAGENTS
value: "3"
- name: ZBX_UNSAFEUSERPARAMETERS
value: "1"
- name: ZBX_TIMEOUT
value: "10"
ports:
- containerPort: 10050
name: zabbix-agent
protocol: TCP
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: zabbix-data
persistentVolumeClaim:
claimName: zabbix-pvc
---
apiVersion: v1
kind: Service
metadata:
name: zabbix-server-mysql
namespace: zabbix
spec:
selector:
app: zabbix-server-mysql
ports:
- name: zabbix-server
port: 10051
targetPort: 10051
nodePort: 30051
type: NodePort

---
apiVersion: v1
kind: Service
metadata:
name: zabbix-server-agent
namespace: zabbix
spec:
selector:
app: zabbix-server-mysql
ports:
- name: zabbix-agent
port: 10050
targetPort: 10050

EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
cat >> 4-zabbix-web-nginx-mysql.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: zabbix-web-nginx-mysql
namespace: zabbix
spec:
replicas: 1
selector:
matchLabels:
app: zabbix-web-nginx-mysql
template:
metadata:
labels:
app: zabbix-web-nginx-mysql
spec:
containers:
- name: zabbix-web-nginx-mysql
image: zabbix/zabbix-web-nginx-mysql:ubuntu-6.0-latest
ports:
- containerPort: 8443
- containerPort: 8080
env:
- name: DB_SERVER_HOST
value: "mariadb.default.svc.cluster.local"
- name: DB_SERVER_PORT
value: "3306"
- name: MYSQL_DATABASE
value: "zabbix"
- name: MYSQL_USER
value: "zabbix"
- name: MYSQL_PASSWORD
value: "4GtJvRS%La76iB"
- name: MYSQL_ROOT_PASSWORD
value: "4y6Cu%946*!TXY"
- name: ZBX_SERVER_HOST
value: "zabbix-server-mysql.zabbix.svc.cluster.local"
- name: PHP_TZ
value: "Asia/Shanghai"
volumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true
- name: zabbix-data
mountPath: /usr/share/zabbix/assets/fonts/DejaVuSans.ttf
subPath: DejaVuSans.ttf
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: zabbix-data
persistentVolumeClaim:
claimName: zabbix-pvc
---
apiVersion: v1
kind: Service
metadata:
name: zabbix-web-nginx-mysql
namespace: zabbix
spec:
selector:
app: zabbix-web-nginx-mysql
ports:
- name: zabbix-front
port: 8080
targetPort: 8080
nodePort: 30080
type: NodePort

EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
cat >> 5-zabbix-java-gateway.yaml << "EOF"
apiVersion: apps/v1
kind: Deployment
metadata:
name: zabbix-java-gateway
namespace: zabbix
spec:
replicas: 1
selector:
matchLabels:
app: zabbix-java-gateway
template:
metadata:
labels:
app: zabbix-java-gateway
spec:
containers:
- name: zabbix-java-gateway
image: zabbix/zabbix-java-gateway:ubuntu-6.0-latest
ports:
- containerPort: 10052
volumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true
volumes:
- name: localtime
hostPath:
path: /etc/localtime

---
apiVersion: v1
kind: Service
metadata:
name: zabbix-java-gateway
namespace: zabbix
spec:
selector:
app: zabbix-java-gateway
ports:
- name: zabbix-java-gateway
port: 10052
targetPort: 10052
nodePort: 30052
type: NodePort

EOF

13.5 应用

1
2
3
4
5
6
kubectl apply  -f 0-namespace.yaml
kubectl apply -f 1-pvc.yaml
kubectl apply -f 2-zabbix-web-service.yaml
kubectl apply -f 3-zabbix-server-mysql.yaml
kubectl apply -f 4-zabbix-web-nginx-mysql.yaml
kubectl apply -f 5-zabbix-java-gateway.yaml

13.6 复制字体进pvc

附件:
DejaVuSans.ttf

13.7 各物理节点部署agent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
yum -y remove epel-release zabbix-release
cat > /etc/yum.repos.d/zabbix.repo << 'EOF'
[zabbix]
name=Zabbix Official Repository - $basearch
baseurl=http://mirrors.cloud.tencent.com/zabbix/zabbix/6.0/rhel/7/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591

[zabbix-debuginfo]
name=Zabbix Official Repository debuginfo - $basearch
baseurl=http://mirrors.cloud.tencent.com/zabbix/zabbix/6.0/rhel/7/$basearch/debuginfo/
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591
gpgcheck=1

[zabbix-non-supported]
name=Zabbix Official Repository non-supported - $basearch
baseurl=http://mirrors.cloud.tencent.com/zabbix/non-supported/rhel/7/$basearch/
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
gpgcheck=0
EOF

cat > /etc/yum.repos.d/zabbix-agent2-plugins.repo << 'EOF'
[zabbix-agent2-plugins]
name=Zabbix Official Repository (Agent2 Plugins) - $basearch
baseurl=http://mirrors.cloud.tencent.com/zabbix/zabbix-agent2-plugins/1/rhel/7/$basearch/
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
gpgcheck=0
EOF

yum -y install zabbix-agent2

#替换参数,ServerActive指向zabbix server地址200.0.1.90:30051
sed -i 's@^Server=127.0.0.1@#Server=127.0.0.1@' /etc/zabbix/zabbix_agent2.conf
sed -i 's@^ServerActive=127.0.0.1@ServerActive=200.0.1.90:30051@' /etc/zabbix/zabbix_agent2.conf
sed -i 's@^Hostname=Zabbix server@#Hostname=Zabbix server@' /etc/zabbix/zabbix_agent2.conf
sed -i 's@^# HostnameItem=system.hostname@# HostnameItem=system.hostname\n\nHostnameItem=system.hostname@' /etc/zabbix/zabbix_agent2.conf
sed -i 's@^# HostMetadataItem=@# HostMetadataItem=\n\nHostMetadataItem=system.uname@' /etc/zabbix/zabbix_agent2.conf
sed -i 's@^# UnsafeUserParameters=0@# UnsafeUserParameters=0\n\nUnsafeUserParameters=1@' /etc/zabbix/zabbix_agent2.conf

systemctl restart zabbix-agent2
systemctl enable zabbix-agent2

tail -f /var/log/zabbix/zabbix_agent2.log

13.8 设置zabbix自动发现

![](_v_images/20230303115029819_18034.png =1216x)

13.9 修复默认

![](_v_images/20230305233258302_30922.png =853x)