<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>勿知勿畏</title><link>https://www.qinmengfei.cn/</link><description></description><item><title>kubeadm搭建k8s</title><link>https://www.qinmengfei.cn/post/106.html</link><description>&lt;h2 id=&quot;h2-1-hosts&quot;&gt;&lt;a name=&quot;1、 配置hosts&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、 配置hosts&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;cat &amp;gt; /etc/hosts &amp;lt;&amp;lt; EOF
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.10.11 k8s-master-1
10.10.10.12 k8s-master-2
10.10.10.13 k8s-node-1
10.10.10.14 k8s-node-2
10.10.10.15 harbor.qinmengfei.cn
EOF&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、更新内核&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、更新内核&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum --enablerepo=&amp;quot;elrepo-kernel&amp;quot; install -y kernel-lt
grub2-set-default 0
uname -a
reboot&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、配置内核参数&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、配置内核参数&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-4-docker&quot;&gt;&lt;a name=&quot;4、安装docker&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、安装docker&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum -y install docker-ce

systemctl start docker
systemctl enable docker
cat &amp;gt; /etc/docker/daemon.json &amp;lt;&amp;lt; EOF
{
  &amp;quot;registry-mirrors&amp;quot;: [&amp;quot;https://05kr23vq.mirror.aliyuncs.com&amp;quot;]
}
EOF
systemctl daemon-reload
systemctl restart docker&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-5-kubeadm&quot;&gt;&lt;a name=&quot;5、安装kubeadm&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5、安装kubeadm&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
       https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install  -y ipvsadm ipset sysstat conntrack libseccomp
yum install -y kubelet kubeadm kubectl
systemctl start kubelet
systemctl enable kubelet&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-6-&quot;&gt;&lt;a name=&quot;6、提前下载镜像&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;6、提前下载镜像&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;# 6.1使用命令下载
kubeadm config images pull
# 6.2自行下载
docker pull k8s.gcr.io/kube-apiserver:v1.21.1
docker pull k8s.gcr.io/kube-controller-manager:v1.21.1
docker pull k8s.gcr.io/kube-scheduler:v1.21.1
docker pull k8s.gcr.io/kube-proxy:v1.21.1
docker pull k8s.gcr.io/pause:3.4.1
docker pull k8s.gcr.io/etcd:3.4.13-0
docker pull k8s.gcr.io/coredns/coredns:v1.8.0&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-7-&quot;&gt;&lt;a name=&quot;7、初始化&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;7、初始化&lt;/h2&gt;&lt;h3 id=&quot;h3-7-1-&quot;&gt;&lt;a name=&quot;7.1初始化参数到文件 （多主）&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;7.1初始化参数到文件 （多主）&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;kubeadm config print init-defaults &amp;gt; kubeadm-config.yaml
cat kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.5.63
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master-1
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: master:6443
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: 1.21.1
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

# 执行命令部署
kubeadm init --config=kubeadm-config.yaml --upload-certs &lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;h3-7-2-&quot;&gt;&lt;a name=&quot;7.2 单节点初始化&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;7.2 单节点初始化&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;kubeadm init \
--apiserver-advertise-address=10.10.10.11 \
--service-cidr=10.0.0.0/16 \
--kubernetes-version 1.21.1 \
--pod-network-cidr=172.0.0.0/16 &lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2-8-flannel-calico&quot;&gt;&lt;a name=&quot;8、部署网络服务flannel或者calico&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;8、部署网络服务flannel或者calico&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml


wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2024/12/202412270942172477054.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# node节点执行
kubeadm join 10.10.10.15:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:23a3bac6c2aed47037faae1dc241a99607f7f1705316125bc22d78cbb571cae6 

# 其他master 执行
kubeadm join 10.10.10.11:6443 --token gmaio2.m0bf18nx94ans2gv \
    --discovery-token-ca-cert-hash sha256:8f3a03b59854a7df17624d462813629ecfbf4ab18cab667facc9aad758b36006  --experimental-control-plane&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;h2--&quot;&gt;&lt;a name=&quot;拷贝文件到其他节点，配置环境变量，添加节点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;拷贝文件到其他节点，配置环境变量，添加节点&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;echo export KUBECONFIG=/etc/kubernetes/admin.conf &amp;gt;&amp;gt; /etc/profile
source /etc/profile

一、首先在master上生成新的token

kubeadm token create --print-join-command
 kubeadm join 192.168.1.10:6443 –token 42ojpt.z2h5ii9n898tzo36 –discovery-token-ca-cert-hash sha256:7cf14e8cb965d5eb9d66f3707ba20deeadc90bd36b730ce4c0e5d9db80d3625b


二、在master上生成用于新master加入的证书

kubeadm init phase upload-certs --experimental-upload-certs
复制
 [root@master ~]# kubeadm init phase upload-certs –experimental-upload-certs
 Flag –experimental-upload-certs has been deprecated, use –upload-certs instead
 W1228 17:15:02.356743 27154 version.go:98] could not fetch a Kubernetes version from the internet: unable to get URL “https://dl.k8s.io/release/stable-1.txt”: Get https://storage.proxy.ustclug.org/kubernetes-release/release/stable-1.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
 W1228 17:15:02.356872 27154 version.go:99] falling back to the local client version: v1.15.1
 [upload-certs] Storing the certificates in Secret “kubeadm-certs” in the “kube-system” Namespace
 [upload-certs] Using certificate key:
 e799a655f667fc327ab8c91f4f2541b57b96d2693ab5af96314ebddea7a68526


三、添加新node

 kubeadm join 192.168.1.10:6443 –token 42ojpt.z2h5ii9n898tzo36 –discovery-token-ca-cert-hash sha256:7cf14e8cb965d5eb9d66f3707ba20deeadc90bd36b730ce4c0e5d9db80d3625b


四、添加新master，把红色部分加到–experimental-control-plane –certificate-key后。

 kubeadm join 192.168.1.10:6443 –token 42ojpt.z2h5ii9n898tzo36 –discovery-token-ca-cert-hash sha256:7cf14e8cb965d5eb9d66f3707ba20deeadc90bd36b730ce4c0e5d9db80d3625b –experimental-control-plane –certificate-key e799a655f667fc327ab8c91f4f2541b57b96d2693ab5af96314ebddea7a68526

&lt;/code&gt;&lt;/pre&gt;</description><pubDate>Thu, 10 Aug 2023 10:09:36 +0800</pubDate></item><item><title>Linux中的2&amp;gt;&amp;amp;1到底是如何工作的</title><link>https://www.qinmengfei.cn/post/104.html</link><description>&lt;p&gt;在Linux系统中，很多时候会看到命令后面会跟上一个2&amp;gt;&amp;amp;1，但是这个2&amp;gt;&amp;amp;1不是算术表达式，然而它是一个文件重定向命令，文件重定向是&amp;gt;符号，就是左边的内容重定向到右边。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1，文件重定向&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1，文件重定向&lt;/h2&gt;&lt;p&gt;重定向是Linux中的一项功能，因此在执行命令时，可以更改标准的输入/输出设备。任何 Linux 命令的基本工作流程都是它接受输入并提供输出。输出可以输出到控制台，也可以输出到其它文件。下面来看一个简单的例子，把aaa.txt的文件输出到bbb.txt文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# cat aaa.txt&amp;gt;bbb.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261521292212861.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;从上图可以看到控制台输出了报错信息。查看bbb.txt 文件，文件中没有内容，主要是“&amp;gt;”符号代表输出重定向。用于把aaa.txt的内容标准输出到bbb.txt,现在没有aaa.txt文件，则打印出了标准错误，标准错误直接打印到控制台了。接着创建一个aaa.txt文件，再把aaa.txt文件重定向到bbb.txt,可以看到能够把文件内容重定向到bbb.txt中，并且控制台没有打印。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2，文件描述符&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2，文件描述符&lt;/h2&gt;&lt;p&gt; 文件描述符只不过是表示打开的文件的正整数。如果打开了100个文件，将有 100 个文件描述符。唯一需要注意的是，在Unix系统中，一切都是文件。但现在这并不重要，最重要的只需要知道标准输出（stdout）和标准错误（stderr）都有文件描述符。标准输入(stdin）的文件描述符是0，标准输出(stdout)的文件描述符是1，标准错误(stderr)的文件描述符是2.标准错误默认显示在屏幕上。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261522265923606.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3，标准输出重定向&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3，标准输出重定向&lt;/h2&gt;&lt;p&gt;通过1&amp;gt;来标准输出重定向，重定向内容到另外的文件中。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping a.com 1&amp;gt;a.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261523231074999.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;上图可以看出，执行命令报错了，通过标准错误来重定向了，标准错误默认是打印到屏幕上。接下来看一个成功的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping www.baidu.com 1&amp;gt;a.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261525264582780.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;从上图可以看出，把标准输出重定向到了a.txt文件中。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-&quot;&gt;&lt;a name=&quot;4，标准错误重定向&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4，标准错误重定向&lt;/h2&gt;&lt;p&gt;通过使用2&amp;gt;符号来把标准错误重定向到另外一个文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping a.com 2&amp;gt;a.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261526091489936.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;上图可以看出把错误消息重定向到了a.txt 文件中。接着来一个成功而不是错误的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping www.baidu.com 2&amp;gt;a.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261526591539841.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;从上图可以看出标准错误输出，只重定向标准错误到另外一个文件，标准输出是不会重定向的。标准输出默认显示到屏幕上了。&lt;/p&gt;
&lt;h2 id=&quot;h2-5-2-gt-amp-1-&quot;&gt;&lt;a name=&quot;5，2&amp;gt;&amp;amp;1重定向&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5，2&amp;gt;&amp;amp;1重定向&lt;/h2&gt;&lt;p&gt; 啥是“2&amp;gt;&amp;amp;1”重定向呢？指的是把标准错误重定向为和标准输出一样。“1&amp;gt;&amp;amp;2”指的是把标准输出重定向为和标准错误一样。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]#ping a.com&amp;gt;a.a 2&amp;gt;&amp;amp;1  &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261527513231397.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;把标准错误重定向到标准输出，和标准输出一样，接着标准输出重定向了a.a文件，所以最终是把标准错误以及标准输出重定向到了a.a文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping a.com&amp;gt;aa 1&amp;gt;&amp;amp;2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261528279105005.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;1&amp;gt;&amp;amp;2把标准输出重定向到标准错误。意思就是标准输出和标准错误一样，然而标准输出到一个文件aa。标准输出已经重定向到了标准错误，这样标准错误没有重定向到任何地方，只能打印到屏幕上了。&lt;/p&gt;
&lt;p&gt;接着再看一个例子：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping a.com 2&amp;gt;aa 1&amp;gt;&amp;amp;2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261530486098925.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;该命令把标准输出重定向标准错误，接着标准错误又重定向到了aa文件，结果是把标准输出和标准错误都打印到aa文件了。&lt;/p&gt;
&lt;p&gt;最后如何只打印错误消息以及如何只打印正确信息。通过重定向到/dev/null，来丢弃对应的内容，把正确的输出重定向到/dev/null.意思是只打印错误的信息。把标准错误重定向到/dev/null，意思就是把错误丢弃，只显示正确的信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;丢弃错误信息/dev/null&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sharplee ~]# ping v.com 2&amp;gt;/dev/null &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261531315412696.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2&amp;gt;用于重定向错误信息到另外一个文件，1&amp;gt;主要用于标准输出重定向到另外一个文件。2&amp;gt;&amp;amp;1主要用于标准输出和标准错误都定位到输出。&amp;amp;&amp;gt;和&amp;gt;&amp;amp;和2&amp;gt;&amp;amp;1相同。&lt;/strong&gt;&lt;/p&gt;
</description><pubDate>Tue, 26 Apr 2022 15:13:37 +0800</pubDate></item><item><title>Kubernetes 架构</title><link>https://www.qinmengfei.cn/post/103.html</link><description>&lt;h1 id=&quot;h1-etcd&quot;&gt;&lt;a name=&quot;ETCD&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;ETCD&lt;/h1&gt;&lt;p&gt;etcd 是一个快速、分布式、一致的键值存储，用作持久存储 Kubernetes 对象数据（如 pod、replication controllers, secrets, services 等）的后备存储。实际上，etcd 是 Kubernetes 存储集群状态和元数据的唯一地方。唯一直接与 etcd 对话的组件是 Kubernetes API Server。所有其他组件通过 API Server 间接读取和写入数据到 etcd。&lt;/p&gt;
&lt;p&gt;Etcd 还实现了一个监视功能，它提供了一个基于事件的接口，用于异步监控键的更改。一旦密钥被更改，它的观察者就会收到通知。API Server 组件在很大程度上依赖于此来获得通知并将 etcd 的当前状态移动到所需状态。&lt;/p&gt;
&lt;h3 id=&quot;h3-etcd-&quot;&gt;&lt;a name=&quot;etcd 实例的数量应该是奇数吗？&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;etcd 实例的数量应该是奇数吗？&lt;/h3&gt;&lt;p&gt;在 HA 环境中，您通常会运行 3、5 或 7 个 etcd 实例，但为什么呢？由于 etcd 是分布式数据存储，因此可以水平扩展它，但您还需要确保每个实例中的数据是一致的，为此，您的系统需要就状态达成共识。Etcd 为此使用了RAFT 共识算法[1]。&lt;/p&gt;
&lt;p&gt;该算法需要多数（或仲裁）集群才能进入下一个状态。如果您只有 2 个 ectd 实例，如果其中任何一个失败，则 etcd 集群无法转换到新状态，因为不存在多数，并且在 3 个实例的情况下，一个实例可能会失败并且可以达到多数的实例仍然可用。&lt;/p&gt;
&lt;h1 id=&quot;h1-api-server&quot;&gt;&lt;a name=&quot;API Server&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;API Server&lt;/h1&gt;&lt;p&gt;API Server 是 Kubernetes 中唯一与 etcd 直接交互的组件。Kubernetes 以及客户端（kubectl）中的所有其他组件都必须通过 API Server 来处理集群状态。API Server 提供以下功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提供在 etcd 中存储对象的一致方式。&lt;/li&gt;&lt;li&gt;执行这些对象的验证，以便客户端无法存储配置不正确的对象，如果它们直接写入 etcd 数据存储区可能会发生这种情况。&lt;/li&gt;&lt;li&gt;提供 RESTful API 来创建、更新、修改或删除资源。&lt;/li&gt;&lt;li&gt;提供乐观并发锁定，因此在并发更新的情况下，对对象的更改永远不会被其他客户端覆盖。&lt;/li&gt;&lt;li&gt;对客户端发送的请求执行身份验证和授权。它使用插件提取客户端的用户名、用户 ID 和用户所属的组，并确定经过身份验证的用户是否可以对请求的资源执行请求的操作。&lt;/li&gt;&lt;li&gt;如果请求试图创建、修改或删除资源，则执行准入控制[2]。示例：AlwaysPullImages、DefaultStorageClass、ResourceQuota 等。&lt;/li&gt;&lt;li&gt;为客户端实现监视机制（类似于 etcd）以监视更改。这允许调度程序和 Controller Manager 等组件以松散耦合的方式与 API Server 交互。&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1-controller-manager&quot;&gt;&lt;a name=&quot;Controller Manager&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Controller Manager&lt;/h1&gt;&lt;p&gt;在 Kubernetes 中，控制器是监控集群状态的控制循环，然后根据需要进行更改或请求更改。每个控制器都尝试将当前集群状态移动到更接近所需状态。控制器跟踪至少一种 Kubernetes 资源类型，并且这些对象有一个表示所需状态的规范字段。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;控制器示例：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replication Manager（ReplicationController 资源的控制器）&lt;/li&gt;&lt;li&gt;ReplicaSet、DaemonSet 和 Job 控制器&lt;/li&gt;&lt;li&gt;Deployment 控制器&lt;/li&gt;&lt;li&gt;StatefulSet 控制器&lt;/li&gt;&lt;li&gt;node 控制器&lt;/li&gt;&lt;li&gt;service 控制器&lt;/li&gt;&lt;li&gt;endpoints 控制器&lt;/li&gt;&lt;li&gt;namespace 控制器&lt;/li&gt;&lt;li&gt;PersistentVolume 控制器&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;控制器使用监视机制来获得更改通知。他们监视 API Server 对资源的更改并针对每个更改执行操作，无论是创建新对象还是更新或删除现有对象。大多数时候，这些操作包括创建其他资源或自己更新被监视的资源，但是由于使用监视并不能保证控制器不会错过任何事件，它们还会定期执行重新列出操作以确保没有错过了任何东西。&lt;/p&gt;
&lt;p&gt;Controller Manager 还执行生命周期功能，例如命名空间创建和生命周期、事件垃圾回收、终止 pod 垃圾回收、级联删除垃圾回收[3]、节点垃圾回收等。&lt;/p&gt;
&lt;h1 id=&quot;h1-scheduler&quot;&gt;&lt;a name=&quot;Scheduler&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Scheduler&lt;/h1&gt;&lt;p&gt;调度程序是一个控制平面进程，它将 pod 分配给节点。它监视没有分配节点的新创建的 pod，并且对于调度程序发现的每个 pod，调度程序负责为该 pod 找到运行的最佳节点。&lt;/p&gt;
&lt;p&gt;满足 Pod 调度要求的节点称为可行节点。如果没有合适的节点，则 pod 将保持未调度状态，直到调度程序能够放置它。一旦找到可行节点，它就会运行一组函数来对节点进行评分，并选择得分最高的节点。然后它会通知 API Server 有关所选节点的信息，此过程称为绑定。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;节点的选择分为两步：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、过滤所有节点的列表以获取 pod 可以调度到的可接受节点列表。（例如，PodFitsResources 过滤器检查候选节点是否有足够的可用资源来满足 Pod 的特定资源请求）&lt;/li&gt;&lt;li&gt;2、对从第 1 步获得的节点列表进行评分并对它们进行排名以选择最佳节点。如果多个节点得分最高，则使用循环法确保 pod 均匀地部署在所有节点上。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;调度决策需要考虑的因素包括：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 对硬件/软件资源的请求？节点是否报告内存或磁盘压力情况？&lt;/li&gt;&lt;li&gt;该节点是否具有与 pod 规范中的节点选择器匹配的标签？&lt;/li&gt;&lt;li&gt;如果 pod 请求绑定到特定的主机端口，该端口是否已在该节点上占用？&lt;/li&gt;&lt;li&gt;pod 是否容忍节点的污点？&lt;/li&gt;&lt;li&gt;pod 是否指定节点亲和性或反亲和性规则？等。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;调度程序不会指示所选节点运行 pod。Scheduler 所做的只是通过 API Server 更新 pod 定义。API server 通过 watch 机制通知 Kubelet pod 已经被调度。然后目标节点上的 kubelet 服务看到 pod 已被调度到它的节点，它创建并运行 pod 的容器。&lt;/p&gt;
&lt;h1 id=&quot;h1-u5DE5u4F5Cu8282u70B9u7EC4u4EF6&quot;&gt;&lt;a name=&quot;工作节点组件&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;工作节点组件&lt;/h1&gt;&lt;h3 id=&quot;h3-kubelet&quot;&gt;&lt;a name=&quot;Kubelet&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Kubelet&lt;/h3&gt;&lt;p&gt;Kubelet 是在集群中的每个节点上运行的代理，是负责在工作节点上运行的所有内容的组件。它确保容器在 Pod 中运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;kubelet 服务的主要功能有：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、通过在 API Server 中创建节点资源来注册它正在运行的节点。&lt;/li&gt;&lt;li&gt;2、持续监控 API Server 上已调度到节点的 Pod。&lt;/li&gt;&lt;li&gt;3、使用配置的容器运行时启动 pod 的容器。&lt;/li&gt;&lt;li&gt;4、持续监控正在运行的容器并将其状态、事件和资源消耗报告给 API Server。&lt;/li&gt;&lt;li&gt;5、运行容器活性探测，在探测失败时重新启动容器，在容器的 Pod 从 API Server 中删除时终止容器，并通知服务器 Pod 已终止。&lt;/li&gt;&lt;/ul&gt;
&lt;h3 id=&quot;h3-kube-proxy&quot;&gt;&lt;a name=&quot;kube-proxy&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;kube-proxy&lt;/h3&gt;&lt;p&gt;它在每个节点上运行，并确保一个 pod 可以与另一个 pod 对话，一个节点可以与另一个节点对话，一个容器可以与另一个容器通信等。它负责监视 API Server 以了解Service和 pod 定义的更改，以保持整个网络配置的最新状态。当一个Service由多个 pod 时，proxy会在这些 pod 之间负载平衡。&lt;/p&gt;
&lt;p&gt;kube-proxy 之所以得名，是因为它是一个实际的代理服务器，用于接受连接并将它们代理到 Pod，当前的实现使用 iptables 或 ipvs 规则将数据包重定向到随机选择的后端 Pod，而不通过实际的代理服务器传递它们。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、 创建服务时，会立即分配一个虚拟 IP 地址。&lt;/li&gt;&lt;li&gt;2、API Server 通知在工作节点上运行的 kube-proxy 代理已经创建了新服务。&lt;/li&gt;&lt;li&gt;3、每个 kube-proxy 通过设置 iptables 规则使服务可寻址，确保拦截每个服务 IP/端口对，并将目标地址修改为支持服务的 pod 之一。&lt;/li&gt;&lt;li&gt;4、监视 API Server 对服务或其端点对象的更改。&lt;/li&gt;&lt;/ul&gt;
&lt;h3 id=&quot;h3-u5BB9u5668u8FD0u884Cu65F6&quot;&gt;&lt;a name=&quot;容器运行时&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;容器运行时&lt;/h3&gt;&lt;p&gt;专注于运行容器、设置命名空间和容器的 cgroup 的容器运行时称为低级容器运行时，专注于格式、解包、管理和共享images并提供 API 以满足开发人员需求的容器运行时称为高级容器运行时（容器引擎）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;容器运行时负责：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、如果本地不可用，则从镜像注册表中拉取容器所需的容器镜像。&lt;/li&gt;&lt;li&gt;2、将镜像提取到写入时复制文件系统，所有容器层相互重叠以创建合并文件系统。&lt;/li&gt;&lt;li&gt;3、准备容器挂载点&lt;/li&gt;&lt;li&gt;4、从容器镜像设置元数据，例如覆盖 CMD、来自用户输入的 ENTRYPOINT、设置 SECCOMP 规则等，以确保容器按预期运行。&lt;/li&gt;&lt;li&gt;5、更改内核以向该容器分配某种隔离，例如进程、网络和文件系统。&lt;/li&gt;&lt;li&gt;6、提醒内核分配一些资源限制，如 CPU 或内存限制。&lt;/li&gt;&lt;li&gt;7、将系统调用（syscall）传递给内核以启动容器。&lt;/li&gt;&lt;li&gt;8、 确保 SElinux/AppArmor 设置正确。&lt;/li&gt;&lt;/ul&gt;
</description><pubDate>Fri, 22 Apr 2022 18:18:04 +0800</pubDate></item><item><title>Redis 官方可视化工具</title><link>https://www.qinmengfei.cn/post/102.html</link><description>&lt;p&gt;&lt;strong&gt;RedisInsight&lt;/strong&gt; 是一个直观高效的 Redis GUI 管理工具，它可以对 Redis 的内存、连接数、命中率以及正常运行时间进行监控，并且可以在界面上使用 CLI 和连接的 Redis 进行交互（RedisInsight 内置对 Redis 模块支持）：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.redis.com/latest/ri/&quot;&gt;https://docs.redis.com/latest/ri/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;h2--strong-redisinsight-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;RedisInsight 提供的功能：&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;RedisInsight 提供的功能：&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;唯一支持 Redis Cluster 的 GUI 工具；&lt;/p&gt;
&lt;p&gt;可以基于 Browser 的界面来进行搜索键、查看和编辑数据；&lt;/p&gt;
&lt;p&gt;支持基于 SSL/TLS 的连接，同时还可以在界面上进行内存分析；&lt;/p&gt;
&lt;h3 id=&quot;h3--redisinsight-&quot;&gt;&lt;a name=&quot;二、RedisInsight 安装与使用&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;二、RedisInsight 安装与使用&lt;/h3&gt;&lt;h4 id=&quot;h4--strong-1-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;1.物理安装&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;1.物理安装&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;1.1下载 RedisInsight 软件包：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://redis.com/redis-enterprise/redis-insight/#insight-form&quot;&gt;https://redis.com/redis-enterprise/redis-insight/#insight-form&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;[root@Redis ~]# ls
anaconda-ks.cfg  redisinsight-linux64-1.11.0
[root@Redis ~]# mkdir /usr/local/redisinsight
[root@Redis ~]# mv redisinsight-linux64-1.11.0 /usr/local/redisinsight/redisinsight-1.11.0
[root@Redis ~]# chmod +x /usr/local/redisinsight/redisinsight-1.11.0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261535568122381.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.2配置 RedisInsight 的环境变量&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Redis ~]# echo &amp;quot;export REDISINSIGHT_HOST=192.168.1.1&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile
[root@Redis ~]# echo &amp;quot;export REDISINSIGHT_HOST_DIR=/usr/local/redisinsight/.redisinsight&amp;quot; &amp;gt;&amp;gt; ~/.bash_profile
[root@Redis ~]# source ~/.bash_profile&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;REDISINSIGHT_PORT：配置 RedisInsight 的监听端口（default：8001）&lt;/li&gt;&lt;li&gt;REDISINSIGHT_HOST：配置 RedisInsight 的 IP 地址（default：0.0.0.0）&lt;/li&gt;&lt;li&gt;LOG_DIR：配置 RedisInsight 的日志存放路径（default：REDISINSIGHT_HOST_DIR）&lt;/li&gt;&lt;li&gt;REDISINSIGHT_HOST_DIR：配置 RedisInsight 的数据存放路径（default：~/.redisinsight）&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.3启动 RedisInsight 服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Redis ~]# nohup /usr/local/redisinsight/redisinsight-linux64-1.4.0 &amp;amp;  // 后台运行
[root@Redis ~]# ps aux | grep redis            // 查看进程是否存在&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261536554843036.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-2-kubernetes-&quot;&gt;&lt;a name=&quot;2.Kubernetes 安装&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.Kubernetes 安装&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;2.1创建 RedisInsight 的 yaml 文件：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Redis ~]# vim redisinsight.yaml
apiVersion: v1
kind: Service
metadata:
  name: redisinsight-service
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8001
    nodePort: 31888
  selector:
    app: redisinsight
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redisinsight
  labels:
    app: redisinsight
spec:
  replicas: 1
  selector:
    matachLabels:
      app: redisinsight
  template:
    metadata:
      labels:
        app: redisinsight
    spec:
      containers:
      - name: redisinsight
        image: redislabs/redisinsight:1.7.0
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: db
          mountPath: /db
        ports:
        - containerPort: 8001
          protocol: TCP
      volumes:
      - name: db
        emptyDir: {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2）启动 RedisInsight&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[root&lt;a href=&quot;https://github.com/Redis&quot; title=&quot;&amp;#64;Redis&quot; class=&quot;at-link&quot;&gt;@Redis&lt;/a&gt; ~]# kubectl apply -f redisinsight.yaml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261539586437715.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-3-redisinsight-&quot;&gt;&lt;a name=&quot;3.RedisInsight 基本使用&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3.RedisInsight 基本使用&lt;/h3&gt;&lt;p&gt;安装 Redis（已安装可直接跳过）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@Redis ~]# wget https://download.redis.io/releases/redis-6.2.6.tar.gz
[root@Redis ~]# tar zxf redis-6.2.6.tar.gz
[root@Redis ~]# cd redis-6.2.6
[root@Redis redis-6.2.6]# make PREFIX=/usr/local/redis install
[root@Redis redis-6.2.6]# sed -i &amp;#39;/^bind 127.0.0.1/s/127.0.0.1/192.168.1.1/g&amp;#39; redis.conf  # 修改监听 IP
[root@Redis redis-6.2.6]# sed -i &amp;#39;/protected-mode/s/yes/no/g&amp;#39; redis.conf      # 关闭保护模式
[root@Redis redis-6.2.6]# sed -i &amp;#39;/daemonize/s/no/yes/g&amp;#39; redis.conf        # 开启后台运行
[root@Redis redis-6.2.6]# sed -i &amp;#39;/requirepass/s/foobared/123123/g&amp;#39; redis.conf     # 配置密码
[root@Redis redis-6.2.6]# sed -i &amp;#39;/requirepass 123123/s/^#//g&amp;#39; redis.conf      # 将密码前的 # 删除
[root@Redis redis-6.2.6]# cp redis.conf /usr/local/redis/
[root@Redis redis-6.2.6]# /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf   # 启动 R&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261543012658483.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.1 通过配置的 IP 和端口，来访问 RedisInsight 的管理界面：&lt;/strong&gt;&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261543491824383.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261544069659528.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261544422532857.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261545017258477.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.2 在这里可以看到 Redis 的各种信息：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261545392242688.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.3 同时 RedisInsight 还可以在界面上进行操作：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261547112028786.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.4 还可以在界面上对 Redis 使用的内存进行分析：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204261547349133583.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Thu, 21 Apr 2022 21:10:57 +0800</pubDate></item><item><title>Nginx 轻松搞定跨域问题</title><link>https://www.qinmengfei.cn/post/101.html</link><description>&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;分析前准备：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;分析前准备：&lt;/h1&gt;&lt;p&gt;前端网站地址：&lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;服务端网址：&lt;a href=&quot;http://localhost:59200&quot;&gt;http://localhost:59200&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;首先保证服务端是没有处理跨域的，其次，先用postman测试服务端接口是正常的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212030339017382.png&quot; alt=&quot;d82ce86169f66edb033b7eba036be117.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;当网站8080去访问服务端接口时，就产生了跨域问题，那么如何解决？接下来我把跨域遇到的各种情况都列举出来并通过nginx代理的方式解决。&lt;/p&gt;
&lt;h3 id=&quot;h3--4-&quot;&gt;&lt;a name=&quot;跨域主要涉及4个响应头：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;跨域主要涉及4个响应头：&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Access-Control-Allow-Origin 用于设置允许跨域请求源地址 （预检请求和正式请求在跨域时候都会验证）&lt;/li&gt;&lt;li&gt;Access-Control-Allow-Headers 跨域允许携带的特殊头信息字段 （只在预检请求验证）&lt;/li&gt;&lt;li&gt;Access-Control-Allow-Methods 跨域允许的请求方法或者说HTTP动词 （只在预检请求验证）&lt;/li&gt;&lt;li&gt;Access-Control-Allow-Credentials 是否允许跨域使用cookies，如果要跨域使用cookies，可以添加上此请求响应头，值设为true（设置或者不设置，都不会影响请求发送，只会影响在跨域时候是否要携带cookies，但是如果设置，预检请求和正式请求都需要设置）。不过不建议跨域使用（项目中用到过，不过不稳定，有些浏览器带不过去），除非必要，因为有很多方案可以代替。&lt;br&gt;网上很多文章都是直接Nginx添加这几个响应头信息就能解决跨域，当然大部分情况是能解决，还是有很多情况，明明配置上了，也同样会报跨域问题。&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;h2--&quot;&gt;&lt;a name=&quot;什么是预检请求？&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;什么是预检请求？&lt;/h2&gt;&lt;p&gt;当发生跨域条件时候，览器先询问服务器，当前网页所在的域名是否在服务器的许可名单之中，以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复，浏览器才会发出正式的XMLHttpRequest请求，否则就报错。如下图&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212049565290727.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3--&quot;&gt;&lt;a name=&quot;开始动手模拟：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;开始动手模拟：&lt;/h3&gt;&lt;p&gt;Nginx代理端口：22222 ,配置如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
        proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;测试代理是否成功，通过Nginx代理端口2222再次访问接口，可以看到如下图通过代理后接口也是能正常访问&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212051156909218.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;接下来开始用网站8080访问Nginx代理后的接口地址，报错情况如下↓↓↓&lt;/p&gt;
&lt;h4 id=&quot;h4--1-&quot;&gt;&lt;a name=&quot;情况1：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;情况1：&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;Access to XMLHttpRequest at ‘&lt;a href=&quot;http://localhost:22222/api/Login/TestGet&amp;#39;&quot;&gt;http://localhost:22222/api/Login/TestGet&amp;#39;&lt;/a&gt; from origin ‘&lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt; has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212052457213312.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;通过错误信息可以很清晰的定位到错误（注意看标红部分）priflight说明是个预请求，CORS 机制跨域会首先进行 preflight（一个 OPTIONS 请求）， 该请求成功后才会发送真正的请求。这一设计旨在确保服务器对 CORS 标准知情，以保护不支持 CORS 的旧服务器&lt;/p&gt;
&lt;p&gt;通过错误信息，我们可以得到是预检请求的请求响应头缺少了 Access-Control-Allow-Origin，错哪里，我们改哪里就好了。修改Nginx配置信息如下（红色部分为添加部分），缺什么就补什么，很简单明了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
       add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39;;
       proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当满怀欢喜的以为能解决后，发现还是报了同样的问题&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212053345577964.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;不过我们的配置没什么问题,问题在Nginx,下图链接&lt;a href=&quot;http://nginx.org/en/docs/http/ngx_http_headers_module.html&quot;&gt;http://nginx.org/en/docs/http/ngx_http_headers_module.html&lt;/a&gt;&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212054024564073.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;add_header 指令用于添加返回头字段，当且仅当状态码为图中列出的那些时有效。如果想要每次响应信息都携带头字段信息，需要在最后添加always（经我测试，只有Access-Control-Allow-Origin这个头信息需要加always，其他的不加always也会携带回来），那我们加上试试&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
       add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
       proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改了配置后，发现生效了，当然不是跨域就解决了，是上面这个问题已经解决了，因为报错内容已经变了。&lt;/p&gt;
&lt;h4 id=&quot;h4--2-&quot;&gt;&lt;a name=&quot;情况2：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;情况2：&lt;/h4&gt;&lt;p&gt;Access to XMLHttpRequest at ‘&lt;a href=&quot;http://localhost:22222/api/Login/TestGet&amp;#39;&quot;&gt;http://localhost:22222/api/Login/TestGet&amp;#39;&lt;/a&gt; from origin ‘&lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt; has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212055114294842.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;通过报错信息提示可以得知，是跨域浏览器默认行为的预请求（option请求）没有收到ok状态码，此时再修改配置文件，当请求为option请求时候，给浏览器返回一个状态码（一般是204）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
       add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
       if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            return 204;
       }
       proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当配置完后，发现报错信息变了&lt;/p&gt;
&lt;p&gt;情况3：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Access to XMLHttpRequest at ‘&lt;a href=&quot;http://localhost:22222/api/Login/TestGet&amp;#39;&quot;&gt;http://localhost:22222/api/Login/TestGet&amp;#39;&lt;/a&gt; from origin ‘&lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt; has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212055534177091.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;意思就是预请求响应头Access-Control-Allow-Headers中缺少头信息authorization（各种情况会不一样，在发生跨域后，在自定义添加的头信息是不允许的，需要添加到请求响应头Access-Control-Allow-Headers中，以便浏览器知道此头信息的携带是服务器承认合法的，我这里携带的是authorization，其他的可能是token之类的，缺什么加什么），知道了问题所在，然后修改配置文件，添加对应缺少的部分，再试试&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
       add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
       if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
           add_header Access-Control-Allow-Headers &amp;#39;authorization&amp;#39;; #为什么写在if里面而不是接着Access-Control-Allow-Origin往下写？因为这里只有预检请求才会检查
           return 204;
      }
    proxy_pass http://localhost:59200;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此时发现报错问题又回到了情况1&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212056011996727.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;经测试验证，只要if ($request_method = ‘OPTIONS’) 里面写了 add_header ，当为预检请求时外部配置的都会失效，为什么？↓↓。&lt;/p&gt;
&lt;p&gt;官方文档是这样说的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;意思就是当前层级无 add_header 指令时，则继承上一层级的add_header。相反的若当前层级有了add_header，就应该无法继承上一层的add_header。&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212056254222929.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;配置修改如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
        add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
        if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39;;
            add_header Access-Control-Allow-Headers &amp;#39;authorization&amp;#39;;
            return 204;
        }
        proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此时改完发现跨域问题已经解决了，&lt;br&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212056593316048.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;不过以上虽然解决了跨域问题，但是考虑后期可能Nginx版本更新,不知道这个规则会不会被修改，考虑到这样的写法可能会携带上两个 Access-Control-Allow-Origin ，这种情况也是不允许的，下面会说到。所以配置适当修改如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
        if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39;;
            add_header Access-Control-Allow-Headers &amp;#39;authorization&amp;#39;;
            return 204;
        }
        if ($request_method != &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
        }
        proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&quot;h4--4-&quot;&gt;&lt;a name=&quot;情况4：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;情况4：&lt;/h4&gt;&lt;p&gt;比较早期的API可能只用到了POST和GET请求，而Access-Control-Allow-Methods这个请求响应头跨域默认只支持POST和GET，当出现其他请求类型时候，同样会出现跨域异常。&lt;/p&gt;
&lt;p&gt;比如，我这里将请求的API接口请求方式从原来的GET改成PUT，在发起一次试试。在控制台上会抛出错误：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Access to XMLHttpRequest at ‘&lt;a href=&quot;http://localhost:22222/api/Login/TestGet&amp;#39;&quot;&gt;http://localhost:22222/api/Login/TestGet&amp;#39;&lt;/a&gt; from origin ‘&lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt; has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212058373720038.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;报错内容也讲的很清楚，在这个预请求中，PUT方法是不允许在跨域中使用的，我们需要改下Access-Control-Allow-Methods的配置(缺什么加上么，这里我只加了PUT，可以自己加全一点)，让浏览器知道服务端是允许的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen 22222;
    server_name localhost;
    location / {
        if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39;;
            add_header Access-Control-Allow-Headers &amp;#39;content-type,authorization&amp;#39;;
            add_header Access-Control-Allow-Methods &amp;#39;PUT&amp;#39;;#为这么只加在这个if中，不再下面的if也加上？因为这里只有预检请求会校验，当然你加上也没事。
            return 204;
        }
        if ($request_method != &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
        }
        proxy_pass http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里注意一下，改成PUT类型后，Access-Control-Allow-Headers请求响应头又会自动校验content-type这个请求头，和情况3是一样的，缺啥补啥就行了。如果不加上content-type，则会报如下错误。（想简单的话，Access-Control-Allow-Headers和Access-Control-Allow-Methods可以设置为 * ,表示全都匹配。但是Access-Control-Allow-Origin就不建议设置成 * 了，为了安全考虑，限制域名是很有必要的。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212059214785606.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;都加上后，问题就解决了，这里报405是我服务端这个接口只开放了GET，没有开放PUT，而此刻我将此接口用PUT方法去请求，所以接口会返回这个状态码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212059492759621.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;h4--5-&quot;&gt;&lt;a name=&quot;情况5：&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;情况5：&lt;/h4&gt;&lt;p&gt;最后再说一种情况，就是后端处理了跨域，就不需要自己在处理了（这里吐槽下，某些后端工程师自己改服务端代码解决跨域，但是又不理解其中原理，网上随便找段代码黏贴，导致响应信息可能处理不完全，如method没添加全，headers没加到点上，自己用的那个可能复制过来的并不包含实际项目所用到的，没有添加options请求返回状态码等，导致Nginx再用通用的配置就会可能报以下异常）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Access to XMLHttpRequest at ‘&lt;a href=&quot;http://localhost:22222/api/Login/TestGet&amp;#39;&quot;&gt;http://localhost:22222/api/Login/TestGet&amp;#39;&lt;/a&gt; from origin ‘&lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt; has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header contains multiple values ‘*, &lt;a href=&quot;http://localhost:8080&amp;#39;&quot;&gt;http://localhost:8080&amp;#39;&lt;/a&gt;, but only one is allowed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://www.qinmengfei.cn/zb_users/upload/2022/04/202204212100199024627.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;意思就是此刻Access-Control-Allow-Origin请求响应头返回了多个，而只允许有一个，这种情况当然修改配置去掉Access-Control-Allow-Origin这个配置就可以了，不过遇到这种情况，建议Nginx配置和服务端自己解决跨域只选其一。（这里注意如果按我上面的写法，if $request_method = ‘OPTIONS’ 这个里面的Access-Control-Allow-Origin可不能删除，删除!=’OPTIONS’里面的就好了，因为这里如果是预检请求直接就ruturn了，请求不会再转发到59200服务，如果也删除了，就会报和情况1一样的错误。所以为什么说要不服务端代码层面解决跨域，要不就Nginx代理解决，不要混着搞，不然不明白原理的人，网上找一段代码贴就很可能解决不了问题）&lt;/p&gt;
&lt;p&gt;↓ ↓ ↓ ↓ ↓&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;再贴一份完整配置（*号根据自己‘喜好’填写）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
        if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39;;
            add_header Access-Control-Allow-Headers &amp;#39;*&amp;#39;;
            add_header Access-Control-Allow-Methods &amp;#39;*&amp;#39;;
            add_header Access-Control-Allow-Credentials &amp;#39;true&amp;#39;;
            return 204;
        }
        if ($request_method != &amp;#39;OPTIONS&amp;#39;) {
            add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
            add_header Access-Control-Allow-Credentials &amp;#39;true&amp;#39;;
        }
        proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen       22222;
    server_name  localhost;
    location  / {
        add_header Access-Control-Allow-Origin &amp;#39;http://localhost:8080&amp;#39; always;
        add_header Access-Control-Allow-Headers &amp;#39;*&amp;#39;;
        add_header Access-Control-Allow-Methods &amp;#39;*&amp;#39;;
        add_header Access-Control-Allow-Credentials &amp;#39;true&amp;#39;;
        if ($request_method = &amp;#39;OPTIONS&amp;#39;) {
            return 204;
        }
        proxy_pass  http://localhost:59200;
    }
}&lt;/code&gt;&lt;/pre&gt;</description><pubDate>Thu, 21 Apr 2022 20:25:36 +0800</pubDate></item><item><title>宝塔 nginx 配置文件 ssl-301-强制https-引用php</title><link>https://www.qinmengfei.cn/post/100.html</link><description>&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;server&amp;nbsp;{
&amp;nbsp;&amp;nbsp;listen&amp;nbsp;80;
&amp;nbsp;&amp;nbsp;listen&amp;nbsp;443&amp;nbsp;ssl&amp;nbsp;http2;
&amp;nbsp;&amp;nbsp;server_name&amp;nbsp;aaa.com&amp;nbsp;www.aaa.com;
&amp;nbsp;&amp;nbsp;index&amp;nbsp;index.php&amp;nbsp;index.html&amp;nbsp;;
&amp;nbsp;&amp;nbsp;root&amp;nbsp;/www/wwwroot/aaa.com;
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;#SSL-START&amp;nbsp;SSL相关配置，请勿删除或修改下一行带注释的404规则
&amp;nbsp;&amp;nbsp;#error_page&amp;nbsp;404/404.html;
&amp;nbsp;&amp;nbsp;#强制https
&amp;nbsp;&amp;nbsp;if&amp;nbsp;($server_port&amp;nbsp;!~&amp;nbsp;443){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewrite&amp;nbsp;^(/.*)$&amp;nbsp;https://$host$1&amp;nbsp;permanent;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;
&amp;nbsp;
&amp;nbsp;&amp;nbsp;#301-START-301跳转
&amp;nbsp;&amp;nbsp;if&amp;nbsp;($host&amp;nbsp;~&amp;nbsp;&amp;#39;^aaa.com&amp;#39;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;301&amp;nbsp;http://www.aaa.com$request_uri;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;#ssl证书配置
&amp;nbsp;&amp;nbsp;ssl_certificate&amp;nbsp;&amp;nbsp;/www/server/panel/vhost/cert/aaa.com/fullchain.pem;
&amp;nbsp;&amp;nbsp;ssl_certificate_key&amp;nbsp;&amp;nbsp;/www/server/panel/vhost/cert/aaa.com/privkey.pem;
&amp;nbsp;&amp;nbsp;ssl_protocols&amp;nbsp;TLSv1.1&amp;nbsp;TLSv1.2&amp;nbsp;TLSv1.3;
&amp;nbsp;&amp;nbsp;ssl_ciphers&amp;nbsp;ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
&amp;nbsp;&amp;nbsp;ssl_prefer_server_ciphers&amp;nbsp;on;
&amp;nbsp;&amp;nbsp;ssl_session_cache&amp;nbsp;shared:SSL:10m;
&amp;nbsp;&amp;nbsp;ssl_session_timeout&amp;nbsp;10m;
&amp;nbsp;&amp;nbsp;error_page&amp;nbsp;497&amp;nbsp;https://$host$request_uri;
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;#ERROR-PAGE-START&amp;nbsp;错误页配置，可以注释、删除或修改
&amp;nbsp;&amp;nbsp;#error_page&amp;nbsp;404&amp;nbsp;/404.html;
&amp;nbsp;&amp;nbsp;#error_page&amp;nbsp;502&amp;nbsp;/502.html;
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;#PHP-INFO-START&amp;nbsp;PHP引用配置，可以注释或修改
&amp;nbsp;&amp;nbsp;include&amp;nbsp;enable-php-00.conf;
&amp;nbsp;&amp;nbsp;#REWRITE-START&amp;nbsp;URL重写规则引用,修改后将导致面板设置的伪静态规则失效
&amp;nbsp;&amp;nbsp;include&amp;nbsp;/www/server/panel/vhost/rewrite/aaa.com.conf;
&amp;nbsp;
&amp;nbsp;&amp;nbsp;#禁止访问的文件或目录
&amp;nbsp;&amp;nbsp;location&amp;nbsp;~&amp;nbsp;^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;404;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;location&amp;nbsp;~&amp;nbsp;.*\.(gif|jpg|jpeg|png|bmp|swf)$
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires&amp;nbsp;&amp;nbsp;&amp;nbsp;30d;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error_log&amp;nbsp;off;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_log&amp;nbsp;/dev/null;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;location&amp;nbsp;~&amp;nbsp;.*\.(js|css)?$
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires&amp;nbsp;&amp;nbsp;&amp;nbsp;12h;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error_log&amp;nbsp;off;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_log&amp;nbsp;/dev/null;&amp;nbsp;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;access_log&amp;nbsp;/www/wwwlogs/aaa.com.log;
&amp;nbsp;&amp;nbsp;error_log&amp;nbsp;/www/wwwlogs/aaa.com.error.log;
}&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 21 May 2021 16:21:00 +0800</pubDate></item><item><title>frps内网穿透</title><link>https://www.qinmengfei.cn/post/99.html</link><description>&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;# frps内网穿透&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;## 服务端一键安装脚本&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;Github

wget&amp;nbsp;https://raw.githubusercontent.com/MvsCode/frps-onekey/master/install-frps.sh&amp;nbsp;-O&amp;nbsp;./install-frps.sh
chmod&amp;nbsp;700&amp;nbsp;./install-frps.sh
./install-frps.sh&amp;nbsp;install&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Aliyun&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;wget&amp;nbsp;https://code.aliyun.com/MvsCode/frps-onekey/raw/master/install-frps.sh&amp;nbsp;-O&amp;nbsp;./install-frps.sh
chmod&amp;nbsp;700&amp;nbsp;./install-frps.sh
./install-frps.sh&amp;nbsp;install&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Uninstall（卸载）&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;./install-frps.sh&amp;nbsp;uninstall&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Update（更新）&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;./install-frps.sh&amp;nbsp;update
Server&amp;nbsp;management（服务管理器）
Usage:&amp;nbsp;/etc/init.d/frps&amp;nbsp;{start|stop|restart|status|config|version}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;## 二进制安装&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## github地址&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;https://github.com/fatedier/frp/releases&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;##&amp;nbsp; 解压&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;xvf&amp;nbsp;frp_0.34.3_linux_amd64.tar.gz&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## 启动&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;./frps&amp;nbsp;-c&amp;nbsp;frps.ini&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;## docker安装&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## dockerhub地址&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;https://hub.docker.com/r/snowdreamtech/frps&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## 创建配置文件&amp;nbsp;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;vim&amp;nbsp;/etc/frp/frps.ini&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## 启动服务端 frps&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;docker&amp;nbsp;run&amp;nbsp;--restart=always&amp;nbsp;--network&amp;nbsp;host&amp;nbsp;-d&amp;nbsp;-v&amp;nbsp;/etc/frp/frps.ini:/etc/frp/frps.ini&amp;nbsp;--name&amp;nbsp;frps&amp;nbsp;snowdreamtech/frps&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;## 启动个人端 frpc&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;docker&amp;nbsp;run&amp;nbsp;--restart=always&amp;nbsp;--network&amp;nbsp;host&amp;nbsp;-d&amp;nbsp;-v&amp;nbsp;/etc/frp/frpc.ini:/etc/frp/frpc.ini&amp;nbsp;--name&amp;nbsp;frpc&amp;nbsp;snowdreamtech/frpc&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 20px;&quot;&gt;## 配置文件&lt;/span&gt;&lt;/p&gt;&lt;p&gt;服务端&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;#&amp;nbsp;[common]&amp;nbsp;is&amp;nbsp;integral&amp;nbsp;section
[common]
#&amp;nbsp;IPv6的文本地址或主机名必须括起来
#&amp;nbsp;放在方括号里，如&amp;nbsp;&amp;quot;[::1]:80&amp;quot;,&amp;nbsp;&amp;quot;[ipv6-host]:http&amp;quot;&amp;nbsp;或者&amp;nbsp;&amp;quot;[ipv6-host%zone]:80&amp;quot;
#bind_addr&amp;nbsp;=&amp;nbsp;0.0.0.0
bind_port&amp;nbsp;=&amp;nbsp;5000
#用于kcp协议的udp端口，可以与&amp;nbsp;&amp;#39;bind_port&amp;#39;相同
#如果未设置，则在frps中禁用kcp
kcp_bind_port&amp;nbsp;=&amp;nbsp;5000
#&amp;nbsp;面板端口
dashboard_port&amp;nbsp;=&amp;nbsp;7500
#&amp;nbsp;面板账号密码
dashboard_user&amp;nbsp;=&amp;nbsp;admin
dashboard_pwd&amp;nbsp;=&amp;nbsp;Admin12345
#&amp;nbsp;http&amp;nbsp;端口和&amp;nbsp;https&amp;nbsp;端口可以与&amp;nbsp;bind_port&amp;nbsp;相同
vhost_http_port&amp;nbsp;=&amp;nbsp;5001
vhost_https_port&amp;nbsp;=&amp;nbsp;5002
#&amp;nbsp;日志文件
log_file&amp;nbsp;=&amp;nbsp;./frps.log
#&amp;nbsp;debug,&amp;nbsp;info,&amp;nbsp;warn,&amp;nbsp;error
log_level&amp;nbsp;=&amp;nbsp;info
log_max_days&amp;nbsp;=&amp;nbsp;3
#&amp;nbsp;添加&amp;nbsp;token&amp;nbsp;验证
token&amp;nbsp;=&amp;nbsp;Admin1234
#当多人同时使用一台frps服务器时，可以方便地使用http、https类型的子域配置。
subdomain_host&amp;nbsp;=&amp;nbsp;frps.qinmengfei.cn
#只允许frpc绑定您列出的端口，如果您不设置任何内容，将不会有任何限制
#允许端口=1-65535
#如果超过最大值，每个代理中的pool_count将更改为max_pool_count
max_pool_count&amp;nbsp;=&amp;nbsp;50
#&amp;nbsp;如果使用tcp流多路复用，则默认值为true
tcp_mux&amp;nbsp;=&amp;nbsp;true&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;客户端配置&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;[common]
#frps服务端地址
server_addr&amp;nbsp;=&amp;nbsp;freenat.bid
#frps服务端通讯端口，客户端连接到服务端内网穿透传输数据的端口
server_port&amp;nbsp;=&amp;nbsp;7000
#特权模式密钥，客户端连接到FRPS服务端的验证密钥
privilege_token&amp;nbsp;=&amp;nbsp;frp888
#日志存放路径
log_file&amp;nbsp;=&amp;nbsp;frpc.log
#日志记录类别,可选：trace,&amp;nbsp;debug,&amp;nbsp;info,&amp;nbsp;warn,&amp;nbsp;error
log_level&amp;nbsp;=&amp;nbsp;info
#日志保存天数
log_max_days&amp;nbsp;=&amp;nbsp;7
#设置为false，frpc连接frps失败后重连，默认为true不重连
login_fail_exit&amp;nbsp;=&amp;nbsp;false
#KCP协议在弱网环境下传输效率提升明显，但是对frps会有一些额外的流量消耗。
protocol&amp;nbsp;=&amp;nbsp;kcp
#穿透服务名称
[http_dsm]
#穿透协议类型，可选：tcp，udp，http，https，stcp，xtcp
type&amp;nbsp;=&amp;nbsp;http
#本地监听IP，可以是本机IP，也可以是本地的局域网内某IP
local_ip&amp;nbsp;=&amp;nbsp;192.168.1.2
#本地监听端口
local_port&amp;nbsp;=&amp;nbsp;5000
#对传输内容进行压缩，可以有效减小&amp;nbsp;frpc&amp;nbsp;与&amp;nbsp;frps&amp;nbsp;之间的网络流量
use_compression&amp;nbsp;=&amp;nbsp;true
#将&amp;nbsp;frpc&amp;nbsp;与&amp;nbsp;frps&amp;nbsp;之间的通信内容加密传输
use_encryption&amp;nbsp;=&amp;nbsp;true
#自定义域名访问穿透服务，一般域名设置了二级域名泛解析以后，这里填*.freenat.bid即可，*自定义，
custom_domains&amp;nbsp;=&amp;nbsp;dsm.freenat.com&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 20px;&quot;&gt;例子&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;[common]
#&amp;nbsp;服务端地址（域名，IP）
server_addr&amp;nbsp;=&amp;nbsp;frps.qinmengfei.cn
#&amp;nbsp;服务端端口
server_port&amp;nbsp;=&amp;nbsp;5000
authenticate_heartbeats&amp;nbsp;=&amp;nbsp;true
authenticate_new_work_conns&amp;nbsp;=&amp;nbsp;true
authentication_method&amp;nbsp;=&amp;nbsp;token
##&amp;nbsp;token验证
token&amp;nbsp;=&amp;nbsp;Admin1234
[aaa]
type&amp;nbsp;=&amp;nbsp;tcp
local_ip&amp;nbsp;=&amp;nbsp;127.0.0.1
local_port&amp;nbsp;=&amp;nbsp;6379
remote_port&amp;nbsp;=&amp;nbsp;5005&lt;/pre&gt;&lt;p&gt;访问 frps.qinmengfei.cn:5005 即可访问本机6379端口服务&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 15 Apr 2021 11:16:01 +0800</pubDate></item><item><title>vsftpd 一键脚本</title><link>https://www.qinmengfei.cn/post/98.html</link><description>&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;#!/bin/bash
#安装VSFTPD服务并使用匿名用户登录
#关闭sellinux
setenforce&amp;nbsp;0
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/SELINUX=.*/SELINUX=disabled/&amp;#39;&amp;nbsp;/etc/selinux/config
if&amp;nbsp;[&amp;nbsp;$?&amp;nbsp;-ne&amp;nbsp;0&amp;nbsp;]
then
&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;执行命令失败&amp;quot;
fi
#关闭防火墙
systemctl&amp;nbsp;stop&amp;nbsp;firewalld
if&amp;nbsp;[&amp;nbsp;$?&amp;nbsp;-ne&amp;nbsp;0&amp;nbsp;]
then&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;关闭防火墙失败&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;read&amp;nbsp;-p&amp;nbsp;&amp;quot;是否跳过此步？(yes&amp;nbsp;or&amp;nbsp;no)&amp;quot;:no&amp;nbsp;ifs
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;[&amp;nbsp;$ifs&amp;nbsp;-eq&amp;nbsp;&amp;quot;no&amp;quot;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;正在退出此脚本&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fi&amp;nbsp;&amp;nbsp;
else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;关闭防火墙成功&amp;quot;
fi
#yum安装vsftpd
yum&amp;nbsp;-y&amp;nbsp;install&amp;nbsp;vsftpd
if&amp;nbsp;[&amp;nbsp;$?&amp;nbsp;-eq&amp;nbsp;0&amp;nbsp;]
then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;vsftpd安装完成。&amp;quot;
else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;vsftpd安装失败。&amp;quot;
fi
#配置匿名用户
useradd&amp;nbsp;vsftpd&amp;nbsp;-d&amp;nbsp;/home/vsftpd&amp;nbsp;-s&amp;nbsp;/bin/false
mkdir&amp;nbsp;-p&amp;nbsp;/home/vsftpd/ftp1
echo&amp;nbsp;&amp;quot;ftp1&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/loginusers.conf
echo&amp;nbsp;&amp;quot;123456&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/loginusers.conf
db_load&amp;nbsp;-T&amp;nbsp;-t&amp;nbsp;hash&amp;nbsp;-f&amp;nbsp;/etc/vsftpd/loginusers.conf&amp;nbsp;/etc/vsftpd/loginusers.db
chmod&amp;nbsp;777&amp;nbsp;/etc/vsftpd/loginusers.db
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/^.*/#&amp;amp;/&amp;#39;&amp;nbsp;/etc/pam.d/vsftpd
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;2i\auth&amp;nbsp;sufficient&amp;nbsp;/lib64/security/pam_userdb.so&amp;nbsp;db=/etc/vsftpd/loginusers&amp;#39;&amp;nbsp;/etc/pam.d/vsftpd
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;3i\account&amp;nbsp;sufficient&amp;nbsp;/lib64/security/pam_userdb.so&amp;nbsp;db=/etc/vsftpd/loginusers&amp;#39;&amp;nbsp;/etc/pam.d/vsftpd
mkdir&amp;nbsp;/etc/vsftpd/userconf
echo&amp;nbsp;&amp;quot;local_root=/home/vsftpd/ftp1/&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/userconf/ftp1
echo&amp;nbsp;&amp;quot;write_enable=YES&amp;quot;&amp;nbsp;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/userconf/ftp1
chmod&amp;nbsp;777&amp;nbsp;&amp;nbsp;/home/vsftpd/ftp1
chown&amp;nbsp;vsftpd:vsftpd&amp;nbsp;/home/vsftpd/ftp1
#最后修改主配置文件
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/anonymous_enable=YES/anonymous_enable=NO/&amp;#39;&amp;nbsp;/etc/vsftpd/vsftpd.conf
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/#chroot_local_user=YES/chroot_local_user=YES/&amp;#39;&amp;nbsp;/etc/vsftpd/vsftpd.conf
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/#ascii_upload_enable=YES/ascii_upload_enable=YES/&amp;#39;&amp;nbsp;/etc/vsftpd/vsftpd.conf
sed&amp;nbsp;-i&amp;nbsp;&amp;#39;s/#ascii_download_enable=YES/ascii_download_enable=YES/&amp;#39;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;guest_enable=YES&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;guest_username=vsftpd&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;user_config_dir=/etc/vsftpd/userconf&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;allow_writeable_chroot=YES&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;virtual_use_local_privs=YES&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;pasv_min_port=30000&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
echo&amp;nbsp;&amp;quot;pasv_max_port=31000&amp;nbsp;&amp;quot;&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;/etc/vsftpd/vsftpd.conf
systemctl&amp;nbsp;start&amp;nbsp;vsftpd
if&amp;nbsp;[&amp;nbsp;$?&amp;nbsp;-eq&amp;nbsp;0&amp;nbsp;]
then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;vsftpd配置完成。&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;vsftpd服务已启动。&amp;quot;
else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&amp;quot;vsftpd配置失败。&amp;quot;
fi&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 15 Apr 2021 11:13:49 +0800</pubDate></item><item><title>rsync+lsyncd实时同步</title><link>https://www.qinmengfei.cn/post/94.html</link><description>&lt;p&gt;安装 rsync 和 lsyncd&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;yum install rsync lsyncd -y﻿&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;配置 rsync&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;vim /etc/rsyncd.conf&lt;/p&gt;&lt;p&gt;uid = rsync&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 运行进程的用户&lt;/p&gt;&lt;p&gt;gid = rsync&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 运行进程的用户组&lt;/p&gt;&lt;p&gt;port = 873&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 监听端口&lt;/p&gt;&lt;p&gt;fake super = yes&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 无需让rsync以root身份运行，允许接收文件的完整属性&lt;/p&gt;&lt;p&gt;use chroot = no&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 禁锢推送的数据至某个目录, 不允许跳出该目录&lt;/p&gt;&lt;p&gt;max connections = 200&amp;nbsp; &amp;nbsp;# 最大连接数&lt;/p&gt;&lt;p&gt;timeout = 600&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 超时时间&lt;/p&gt;&lt;p&gt;ignore errors&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 忽略错误信息&lt;/p&gt;&lt;p&gt;read only = false&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 对备份数据可读写&lt;/p&gt;&lt;p&gt;list = false&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 不允许查看模块信息&lt;/p&gt;&lt;p&gt;auth users = rsync_backup# 定义虚拟用户，作为连接认证用户&lt;/p&gt;&lt;p&gt;secrets file = /etc/rsync.passwd # 定义rsync服务用户连接认证密码文件路径&lt;/p&gt;&lt;p&gt;[backup]&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 定义模块信息&lt;/p&gt;&lt;p&gt;comment = commit&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 模块注释信息&lt;/p&gt;&lt;p&gt;path = /backup&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 定义接收备份数据目录&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;##创建密码文件&lt;/p&gt;&lt;p&gt;echo &amp;quot;密码“ &amp;gt; /etc/rsyncd.pwd&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;配置lsyncd&amp;nbsp; SSH模式配置文件&lt;/p&gt;&lt;p&gt;vim /etc/lsyncd.conf&lt;/p&gt;&lt;p&gt;####SSH模式配置文件&lt;/p&gt;&lt;p&gt;settings {&lt;/p&gt;&lt;p&gt;&amp;nbsp; logfile = &amp;quot;/var/log/lsyncd.log&amp;quot;,&amp;nbsp; &amp;nbsp; &amp;nbsp;--日志路径&lt;/p&gt;&lt;p&gt;&amp;nbsp; statusFile = &amp;quot;/var/log/lsyncd.status&amp;quot;,&amp;nbsp; --状态文件&lt;/p&gt;&lt;p&gt;&amp;nbsp; pidfile = &amp;quot;/var/run/lsyncd.pid&amp;quot;,&amp;nbsp; &amp;nbsp; &amp;nbsp;--pid文件路径&lt;/p&gt;&lt;p&gt;&amp;nbsp; statusInterval = 1,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--状态文件写入最短时间&lt;/p&gt;&lt;p&gt;&amp;nbsp; nodaemon = false,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --daemon运行&lt;/p&gt;&lt;p&gt;&amp;nbsp; maxProcesses = 1,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --最大进程&lt;/p&gt;&lt;p&gt;&amp;nbsp; maxDelays = 1,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --最大延迟&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;sync {&lt;/p&gt;&lt;p&gt;&amp;nbsp; default.rsyncssh,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--默认rsync+ssh,rsync版本需要升级3以上版本&lt;/p&gt;&lt;p&gt;&amp;nbsp; source = &amp;quot;/home/backup/&amp;quot;,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --源目录&lt;/p&gt;&lt;p&gt;&amp;nbsp; delete = true,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --保持完全同步&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; host = &amp;quot;root@11.22.33.44&amp;quot;,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --远程服务器地址&lt;/p&gt;&lt;p&gt;&amp;nbsp; targetdir = &amp;quot;/home/backup/&amp;quot;,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--目标目录&lt;/p&gt;&lt;p&gt;&amp;nbsp; exclude={ &amp;quot;*.tmp&amp;quot;, &amp;quot;*.bak&amp;quot; },&amp;nbsp; &amp;nbsp; --需排除的文件&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;rsync = {&lt;/p&gt;&lt;p&gt;&amp;nbsp; binary = &amp;quot;/usr/bin/rsync&amp;quot;, --需先安装好rsync&lt;/p&gt;&lt;p&gt;&amp;nbsp; archive = true,&amp;nbsp; &amp;nbsp; &amp;nbsp; --归档&lt;/p&gt;&lt;p&gt;&amp;nbsp; compress = false,&amp;nbsp; &amp;nbsp; &amp;nbsp;--压缩&lt;/p&gt;&lt;p&gt;&amp;nbsp; owner = true,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--属主&lt;/p&gt;&lt;p&gt;&amp;nbsp; perms = true,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--权限&lt;/p&gt;&lt;p&gt;&amp;nbsp; _extra = {&amp;quot;--bwlimit=5120&amp;quot;}, --限速5120KB/S&lt;/p&gt;&lt;p&gt;&amp;nbsp; whole_file = false&lt;/p&gt;&lt;p&gt;&amp;nbsp; },&lt;/p&gt;&lt;p&gt;ssh = {&lt;/p&gt;&lt;p&gt;&amp;nbsp; port = 22&lt;/p&gt;&lt;p&gt;&amp;nbsp; }&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;### rsync 模式配置文件&lt;/p&gt;&lt;p&gt;-- 全局配置&amp;nbsp;&lt;/p&gt;&lt;p&gt;settings {&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 日志文件存放位置&lt;/p&gt;&lt;p&gt;&amp;nbsp; logfile =&amp;quot;/usr/local/lsyncd/var/lsyncd.log&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 状态文件存放位置&lt;/p&gt;&lt;p&gt;&amp;nbsp; statusFile =&amp;quot;/usr/local/lsyncd/var/lsyncd.status&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 将lsyncd的状态写入上面的statusFile的间隔，默认10秒&lt;/p&gt;&lt;p&gt;&amp;nbsp; --statusInterval = 10&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 是否启用守护模式，默认 true&lt;/p&gt;&lt;p&gt;&amp;nbsp; --nodaemon=true&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- inotify监控的事件 ,默认是 CloseWrite,还可以是 Modify 或 CloseWrite or Modify&lt;/p&gt;&lt;p&gt;&amp;nbsp; inotifyMode = &amp;quot;CloseWrite&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 最大同步进程&lt;/p&gt;&lt;p&gt;&amp;nbsp; maxProcesses = 8,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; --累计到多少所监控的事件激活一次同步,即使后面的delay延迟时间还未到&lt;/p&gt;&lt;p&gt;&amp;nbsp; --maxDelays = 1&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;-- 远程目录同步&lt;/p&gt;&lt;p&gt;sync {&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- rsync , rsyncssh , direct 三种模式&lt;/p&gt;&lt;p&gt;&amp;nbsp; default.rsync,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 同步的源目录，使用绝对路径。&lt;/p&gt;&lt;p&gt;&amp;nbsp; source = &amp;quot;/home/wwwroot/attachments&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 定义目的地址.对应不同的模式有几种写法,这里使用远程同步的地址，rsync中的地址&lt;/p&gt;&lt;p&gt;&amp;nbsp; target = &amp;quot;rsync137@192.168.1.137::rsyncd&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 默认 true ，允许同步删除。还有 false, startup, running 值&lt;/p&gt;&lt;p&gt;&amp;nbsp; --delete = true,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 哪些文件不同步&lt;/p&gt;&lt;p&gt;&amp;nbsp; exclude = { &amp;quot;.*&amp;quot; },&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 设置排除不需要同步的文件的列表，&lt;/p&gt;&lt;p&gt;&amp;nbsp;excludeFrom=&amp;quot;/etc/rsync_exclude.lst&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 累计事件，等待rsync同步延时时间，默认15秒,最大累计到1000个不可合并的事件(1000个文件变动),&lt;/p&gt;&lt;p&gt;&amp;nbsp; delay = 15,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- 默认 true 当init = false ,只同步进程启动以后发生改动事件的文件，原有的目录即使有差异也不会同步&lt;/p&gt;&lt;p&gt;&amp;nbsp; --init = true,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; -- rsync 的配置&lt;/p&gt;&lt;p&gt;&amp;nbsp; rsync = {&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; -- rsync 的二进制处理文件&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; binary = &amp;quot;/usr/bin/rsync&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 归档模式&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; archive = true,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 压缩传输&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; compress = true,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 增量&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; verbose = true,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 密码文件&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; password_file = &amp;quot;/etc/rsyncd.pwd&amp;quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-- 其他 rsync 的配置参数, 限速(--bwlimit KBPS),使用 rsync -v 查看详细参数&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; -- _extra&amp;nbsp; = {&amp;quot;--bwlimit=200&amp;quot;}&lt;/p&gt;&lt;p&gt;&amp;nbsp; }&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;lsyncd 配置说明&lt;/p&gt;&lt;p&gt;1、settings 部分 关于lsyncd工具自身的一些选项设置&lt;/p&gt;&lt;p&gt;&amp;nbsp; --: 注释, 因为是lua 语言,所以 --是注释&lt;/p&gt;&lt;p&gt;&amp;nbsp;logfile :&amp;nbsp; &amp;nbsp; 指定lsyncd工具本身运行所产生的日志文件存放位置&lt;/p&gt;&lt;p&gt;&amp;nbsp;statusFile :&amp;nbsp; &amp;nbsp;定义lsyncd监控目录状态文件的存放位置&lt;/p&gt;&lt;p&gt;&amp;nbsp;statusInterval :&amp;nbsp; 隔多少秒记录一次被监控目录的状态&lt;/p&gt;&lt;p&gt;&amp;nbsp;nodaemon=true :&amp;nbsp; 默认是不启用守护模式的&lt;/p&gt;&lt;p&gt;&amp;nbsp;inotifyMode :&amp;nbsp; &amp;nbsp;指定要监控的事件,如,CloseWrite（关闭写入）,Modify（修改）,CloseWrite or Modify, 默认是CloseWrite&lt;/p&gt;&lt;p&gt;&amp;nbsp;maxProcesses :&amp;nbsp; &amp;nbsp;指定同步时进程的最大个数&lt;/p&gt;&lt;p&gt;&amp;nbsp;maxDelays :&amp;nbsp; &amp;nbsp;当事件被命中累计多少次后才进行一次同步&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2、sync 部分 主要用来定义同步时的一些设置,可以同时同步多个目录,只需要在该代码块中事先定义好多个sync即可&lt;/p&gt;&lt;p&gt;&amp;nbsp;default.rsync :&amp;nbsp; 指定lsyncd运行模式,另外,还有&amp;gt;default.direct,default.rsyncssh模式&lt;/p&gt;&lt;p&gt;&amp;nbsp;source :&amp;nbsp; &amp;nbsp; 指定要监控的目录,务必全部用绝对路径&lt;/p&gt;&lt;p&gt;&amp;nbsp;target :&amp;nbsp; &amp;nbsp; 要同步到的目标目录,一般为rsync服务端模块下指定的目录,说明: &amp;#39;rsyncuser@192.168.10.20::bak&amp;#39; , &amp;#39;rsyncuser&amp;#39;:同步的用户在备服务器上设置 ,&amp;#39;192.168.10.20&amp;#39;:备服务器地址, &amp;#39;::backup&amp;#39;:模块名称,同步路径在备服务器上设置&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;init :&amp;nbsp; &amp;nbsp; 为false时表示只同步lsyncd进程启动以后发生改动事件的文件,否则,反之,默认为true&lt;/p&gt;&lt;p&gt;&amp;nbsp;delay :&amp;nbsp; &amp;nbsp;当命中的事件累计到多少时再触发同步&lt;/p&gt;&lt;p&gt;&amp;nbsp;exclude :&amp;nbsp; &amp;nbsp;通过此选项排除掉不需要同步的文件,可用它自己的正则进行匹配&lt;/p&gt;&lt;p&gt;&amp;nbsp;delete&amp;nbsp; &amp;nbsp; 为了保持target与souce完全同步，Lsyncd默认会delete = true来允许同步删除。它除了false，还有startup、running值，请参考 Lsyncd 2.1.x ‖ Layer 4 Config ‖ Default Behavior。&lt;/p&gt;&lt;p&gt;&amp;nbsp;delete = true 默认。 Lsyncd将在目标上删除不在源代码中的任何东西。在启动时以及在正常操作过程中被删除的内容&lt;/p&gt;&lt;p&gt;&amp;nbsp;delete = false Lsyncd不会删除目标上的任何文件。不在启动或正常运行。 （虽然可以覆盖）&lt;/p&gt;&lt;p&gt;&amp;nbsp;delete = &amp;#39;startup&amp;#39; Lsyncd将在启动时删除目标上的文件，但不会进行正常操作。&lt;/p&gt;&lt;p&gt;&amp;nbsp;delete = &amp;#39;running&amp;#39; Lsyncd在启动时不会删除目标上的文件，但会删除那些在正常操作期间被删除的文件&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 14 Apr 2021 15:29:04 +0800</pubDate></item><item><title>centos-7 添加字库</title><link>https://www.qinmengfei.cn/post/93.html</link><description>&lt;p&gt;﻿﻿&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;安装 字体库&lt;/p&gt;&lt;p&gt;yum groupinstall &amp;quot;fonts&amp;quot;&lt;/p&gt;&lt;p&gt;yum -y install fontconfig mkfontscale ttmkfdir&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;安装 source-code-pro 字体&lt;/p&gt;&lt;p&gt;下载ZIP包：sudo wget https://github.com/downloads/adobe-fonts/source-code-pro/SourceCodePro_FontsOnly-1.013.zip&lt;/p&gt;&lt;p&gt;解压：sudo unzip SourceCodePro_FontsOnly-1.013.zip&lt;/p&gt;&lt;p&gt;创建目录：sudo mkdir ~/.fonts&lt;/p&gt;&lt;p&gt;拷贝字体：sudo cp ./SourceCodePro_FontsOnly-1.013/OTF/* ~/.fonts/&lt;/p&gt;&lt;p&gt;生成新的字体缓存：fc-cache -f -v&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;添加windows 字库&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1、先从你本机 C:\Windows\Fonts 拷贝或者网络上下载你想要安装的字体文件（*.ttf文件）到 /usr/share/fonts/windows&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2、修改字体文件的权限，使root用户以外的用户也可以使用&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;cd /usr/share/fonts/windows&lt;/p&gt;&lt;p&gt;chmod 755 *.ttf﻿&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;搜索目录中所有的字体信息，并汇总生成 fonts.scale 文件&lt;/p&gt;&lt;p&gt;ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;在 Font directory list 的部分，添加 1 行，内容为 &amp;lt;dir&amp;gt;/usr/share/fonts/windows/&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;vim /etc/fonts/fonts.conf&lt;/p&gt;&lt;p&gt;&amp;lt;!-- Font directory list --&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;dir&amp;gt;/usr/share/fonts&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;dir&amp;gt;/usr/share/X11/fonts/Type1&amp;lt;/dir&amp;gt; &amp;lt;dir&amp;gt;/usr/share/X11/fonts/TTF&amp;lt;/dir&amp;gt; &amp;lt;dir&amp;gt;/usr/local/share/fonts&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;dir&amp;gt;/usr/share/fonts/windows/&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;dir prefix=&amp;quot;xdg&amp;quot;&amp;gt;fonts&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;!-- the following element will be removed in the future --&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;dir&amp;gt;~/.fonts&amp;lt;/dir&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3、建立字体缓存&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;mkfontscale #（如果提示 mkfontscale: command not found，需自行安装 # yum install mkfontscale ）&lt;/p&gt;&lt;p&gt;mkfontdir&amp;nbsp;&lt;/p&gt;&lt;p&gt;fc-cache&lt;/p&gt;&lt;p&gt;fc-cache -fv ﻿&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 14 Apr 2021 15:26:43 +0800</pubDate></item></channel></rss>