nfs 服务部署使用
NFS(Network File System 的缩写),它的主要功能是:通过网络、让不同的机器、不同的 OS 可以共享彼此的文件
NFS 服务器可以允许 NFS 客户端将远端 NFS 服务器的共享目录挂载到自己的系统上,当作本地磁盘一样使用
环境信息
- Centos 7
服务安装
服务端安装
安装需要的软件包
yum -y install nfs-utils rpcbind |
创建数据目录
mkdir /data/NFSDataHome |
修改配置文件 /etc/exports
:
/data/NFSDataHome 192.168.1.0/24(rw,sync,insecure,no_subtree_check,no_root_squash) |
相关选项说明:
参数 | 说明 |
---|---|
ro | 只读访问 |
rw | 读写访问 |
sync | 所有数据在请求时写入共享 |
async | nfs 在写入数据前可以响应请求 |
secure | nfs 通过 1024 以下的安全 TCP/IP 端口发送 |
insecure | nfs 通过 1024 以上的端口发送 |
wdelay | 如果多个用户要写入 nfs 目录,则归组写入(默认) |
no_wdelay | 如果多个用户要写入 nfs 目录,则立即写入,当使用 async 时,无需此设置 |
hide | 在 nfs 共享目录中不共享其子目录 |
no_hide | 共享 nfs 目录的子目录 |
subtree_check | 如果共享 /usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认) |
no_subtree_check | 不检查父目录权限 |
all_squash | 无论 NFS 客户端以哪种用户身份访问,均映射为 NFS 服务器的 nfsnobody 用户 |
no_all_squash | 保留共享文件的 UID 和 GID(默认) |
root_squash | 当 NFS 客户端以 root 用户身份访问时,映射为 NFS 服务器的 nfsnobody 用户 |
no_root_squash | 当 NFS 客户端以 root 身份访问时,映射为 NFS 服务器的 root 用户,也就是要为超级用户保留权限。这个选项会留下严重的安全隐患,一般不建议采用。 |
anonuid=xxx | 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 UID |
anongid=xxx | 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 GID |
Centos7 安装使用 Fiddler
Centos 7 上面安装 Fiddler,需要先安装 mono
,并且需要图形桌面系统支持。
Mono(https://github.com/mono/mono) is an open source implementation of Microsoft’s .NET Framework based on the ECMA standards for C# and the Common Language Runtime.
The Mono project is part of the .NET Foundation(https://github.com/dotnet)
环境信息
- Centos 7 3.10.0-1160
- mono-complete-6.8.0
- Fiddler
- Gnome
安装步骤
安装 mono
首先安装 mono-complete
,yum
源 epel
中包含了此安装包
$ yum info mono-complete |
安装 Fiddler
下载 Fiddler 安装包
wget http://www.telerik.com/docs/default-source/fiddler/fiddler-linux.zip |
解压运行 Fiddler
unzip fiddler-linux.zip -d fiddler-linux |
常见错误
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: The type initializer for ‘System.Windows.Forms.XplatUI’ threw an exception. —> System.ArgumentNullException: Could not open display (X-Server required. Check your DISPLAY environment variable)
启动过程中报错,原因为需要桌面系统支持。可以在图形桌面系统中开启 shell,执行启动命令 mono ./Fiddler.exe
SoftEther VPN 使用
环境信息
- Centos7 5.4.221
- SoftEther VPN Server 4.41
- iptables
SoftEther VPN Server 有两种模式,Service Mode
和 User Mode
,本文档安装使用 Service Mode
[1]
Service Mode
- 安装之后以系统服务的形式存在(被管理)User Mode
- 安装之后不存在对应的服务,(管理员)用户直接通过进程管理,程序启动停止需要(管理员)用户手动停止相应进程
安装配置过程
安装
安装依赖包
yum -y install gcc zlib-devel openssl-devel readline-devel ncurses-devel |
参考链接 下载最新的安装包,本文档使用版本 4.41 版本 [2]
wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.41-9782-beta/softether-vpnserver-v4.41-9782-beta-2022.11.17-linux-x64-64bit.tar.gz |
使用以下命令编译生成可执行文件
make |
将编译后的目录移动到 /usr/local/
下,并修改权限
cd .. |
cdn77 api 使用
本文档示例使用 Python3 调用 CDN77 API 的常用方法,CDN77 目前未提供 SDK,只有 REST API。 [1]
常见用法
创建调用 API 时需要的 API Token
读取 CDN resources 列表
>>> api_token = 'sliJJYTUikbdg9798384Kbbj0kj' |
根据 cdn resource id 获取流量统计数据
>>> url = 'https://api.cdn77.com/v3/stats/cdns/traffic' |
脚注
Python3 requests 库使用
环境信息
- python3.10
常见用法
基础用法可以查看系统帮助信息
>>> help(requests) |
requests
发送请求时,会自动创建 requests.Request
,因此发送请求时如果需要发送更多数据,可以查看 Request
类的帮助信息,或者查看 requests.models
获取更多帮助信息,如 headers
,files
等
>>> help(requests.Request) |
例如发送请求时需要添加头部信息
>>> headers = {'Authorization': token, 'User-Agent': 'Python'} |
Request
请求的响应是 ‘requests.models.Response’ 对象的实例。获取 Response
帮助,可以查看以下内容
>>> help(requests.models.Response) |
脚注
python 操作日期及时间
环境信息
- Python 3.10
常见用法
获取前一天所属月份
arrow 模块获取
以下示例使用 arrow
模块获取前一天所属月份 [1]
pip install arrow |
指定参数 months = -1
就可以计算前一个月的时间。往后一个月就是 month=+1
,format
指定时间格式。
获取前一个月的天数
通过模块 calendar
获取
>>> import calendar |
python 代码性能分析工具
环境信息
- python 3.10
pyinstrument 使用
pyinstrument
可以快速找到代码运行最慢的部分,帮助提高代码的性能。支持 Python 3.7+ 且能够分析异步代码,仅需一条命令即可显示具体代码的耗时 [1]
安装
pip install pyinstrument |
命令行使用
在无需更改代码的情况下,直接通过命令行使用 pyinstrument
分析目标代码
$ pyinstrument main.py |
脚注
python 中 json 格式
环境信息
- Python3.10
Python 中操作 json 相关格式,主要使用模块 json
Python 数据类型转换为 json 格式
python 数据类型转换为 json ,主要使用方法 dumps()
>>> adict = {'a': 1, 'b': 'st'} |
json 格式转换为 Python 数据类型
>>> ajson = '[1, 2, 3, 4]' |
docker 运行 mysql
环境信息
- Docker 19.03.15
- Mysql 5.7
配置步骤
下载镜像
docker pull mysql:5.7.31 |
启动容器
启动容器前先在本地创建 Mysql 数据目录以用来持久化 Mysql 数据,如果需要配置文件,可以在本地创建好配置文件挂载到容器的 /etc/mysql/my.cnf
,无需配置文件的话,则只需要将持久化的本地数据目录挂载到容器默认的数据目录 /var/lib/mysql
,本示例中 Mysql 本地持久化数据目录为 /opt/docker_mysql_home/data/
。使用以下命令启动容器
docker run -d --name mysql -v /opt/docker_mysql_home/data/:/var/lib/mysql/ -p 3306:3306 \ |
-e MYSQL_ROOT_PASSWORD=123456
通过环境变量配置 Mysql 初始化后的密码
容器启动后,通过以下命令连接数据库
mysql -h 127.0.0.1 -uroot -p |
Pycharm 常用配置
环境信息
- PyCharm 2022.1 (Professional Edition)
常见配置
快速插入时间
通过配置 Live Template
实现快速插入时间
打开 File > Setting > Editor: Live Templates
选中常用的语言,比如
Python
,点击右上角的+
,添加Live Template
Abbreviation
输入快捷输入的名称,比如currentTime
Description
输入描述信息
Template Text
输入$time$
点击
Edit Variables
配置命令及格式
Define
选择Everywhere
,Apply
让配置生效编辑时输入
currentTime
,可以直接插入当前时间
配置 git 仓库
打开
File
->Settings
->Version Control
->Git
,在Path to Git executable
处选择 git 的安装位置。配置完成之后,点击【Test】
按钮,如果成功,则会显示 Git 版本信息点击
VCS
->Get from Version Control
,输入 Git 仓库的地址和本地目录。
Spinnaker 安装配置
环境信息
- Centos-7 3.10.0-1160
- Docker Engine 19.03.15
- Kubernetes 1.21.2
本文档中涉及服务器的操作,都是在 Kubernetes 集群的 Master 节点上进行。如果在其他服务器启动 Halyard 容器,需要确保容器中可以访问到 Kubernetes 集群的 API Server
安装部署步骤
Install Halyard on Docker and Choose Cloud Providers - Kubernetes
宿主机准备容器数据目录
宿主机创建 local Halyard config directory [1]
mkdir /root/spinnaker_data |
Spinnaker 的部署配置会写入容器目录 /home/spinnaker/.hal
,将此配置映射到宿主机,可保证配置持久化。
拷贝 Kubernetes 集群管理配置文件到 /root/spinnaker_data/.kube/config
[2]
cp /etc/kubernetes/admin.conf /root/spinnaker_data/.kube/config |
Kubernetes 上部署 cert-manager 及使用
环境信息
- Kubernetes 1.24
- cert-manager v1.7.1
随着 HTTPS 不断普及,越来越多的网站都在从 HTTP 升级到 HTTPS,使用 HTTPS 就需要向权威机构申请证书,需要付出一定的成本,如果需求数量多,也是一笔不小的开支。cert-manager 是 Kubernetes 上的全能证书管理工具,如果对安全级别和证书功能要求不高,可以利用 cert-manager 基于 ACME 协议与 Let’s Encrypt 来签发免费证书并自动续期,实现永久免费使用证书。
cert-manager 工作原理
cert-manager 部署到 Kubernetes 集群后,它会 watch 它所支持的 CRD 资源,我们通过创建 CRD 资源来指示 cert-manager 为我们签发证书并自动续期: [1]
解释下几个关键的资源:
Issuer/ClusterIssuer
: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer
与Issuer
的唯一区别就是Issuer
只能用来签发自己所在namespace
下的证书,ClusterIssuer
可以签发任意namespace
下的证书。Certificate
: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对Issuer/ClusterIssuer
的引用。
kubernetes ConfigMap 使用说明
环境信息
- Kubernetes 1.24
ConfigMap
是 Kubernetes 用来向应用 Pod 中注入配置数据的方法。[1]
使用 ConfigMap 数据定义容器环境变量
使用单个 ConfigMap 中的数据定义容器环境变量
- 在
ConfigMap
中将环境变量定义为键值对:kubectl create configmap special-config --from-literal=special.how=very
- 将 ConfigMap 中定义的 special.how 赋值给 Pod 规约中的 SPECIAL_LEVEL_KEY 环境变量。 现在,Pod 的输出包含环境变量
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# 定义环境变量
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# ConfigMap 包含你要赋给 SPECIAL_LEVEL_KEY 的值
name: special-config
# 指定与取值相关的键名
key: special.how
restartPolicy: NeverSPECIAL_LEVEL_KEY=very
。
kubernetes 配置文件说明
环境信息
- Centos7 5.4.212-1
- Docker 20.10.18
- containerd.io-1.6.8
- kubectl-1.25.0
- kubeadm-1.25.0
- kubelet-1.25.0
- kube-flannel
常见配置文件说明
文件/目录 | 说明 | 示例 |
---|---|---|
/etc/kubernetes/{admin.conf, controller-manager.conf, kubelet.conf, scheduler.conf } |
master 管理节点上的管理节点(admin ,controller-manager ,kubelet ,scheduler )配置文件 admin 配置文件具有全局管理员权限,可以跳过 RBAC 权限控制系统,应该禁止其共享。 |
|
/etc/kubernetes/kubelet.conf |
worker 节点上,kubelet 配置文件 |
|
/etc/kubernetes/manifests/ |
管理节点上,管理节点的启动参数配置文件,主要包括 etcd.yaml , kube-apiserver.yaml , kube-controller-manager.yaml , kube-scheduler.yaml 。是静态 Pod 的主要配置路径 |
|
/etc/kubernetes/pki/ |
- 管理节点上,存放所有节点之间的通信证书文件, - worker 节点上,存放集群 CA 证书文件。 只有 ca.crt |
|
/etc/cni/net.d/10-flannel.conflist |
管理节点上,flannel 配置文件 |
TCP 协议
TCP 协议抓包分析
TCP 通信过程中 seq 和 ACK 值说明
TCP 连接通信过程中,client 和 server 端各自维护自己的
seq
。后面一个数据包的seq
是前面一个数据包的seq
加上前面一个数据包的大小。表示发送的字节位置。假如当前连接中,之前一个包
seq = 100
,其发送数据包大小为 0,则当前要发送的数据包的seq = 0
假如当前连接中,之前一个包
seq = 100
,其发送数据包大小为 20,则当前要发送的数据包的seq = 120
TCP 连接通信过程中,client 和 server 端要发送给对方的包的
ACK
的值为:收到的包的seq
+ 收到的包的Len
,此值告知发送方,接收方希望接收到的下一个包的序列号。假如接收方接收到了
seq = 100
,Len = 0
的包,接收方需要发送的ACK = 100 + 1
假如接收方接收到了
seq = 100
,Len = 20
的包,接收方需要发送的ACK = 100 + 20
参考链接
wireshark 抓包工具使用
wiresark 显示过滤器使用方法
Wireshark 提供了两种过滤器
- 捕获过滤器:在抓包之前就设定好过滤条件,然后只抓取符合条件的数据包。
- 显示过滤器:在已捕获的数据包集合中设置过滤条件,隐藏不想显示的数据包,只显示符合条件的数据包。
这两种过滤器所使用的语法是完全不同的,捕捉网卡数据的其实并不是 Wireshark,而是 WinPcap,要按 WinPcap 的规则来,显示过滤器就是 Wireshark 对已捕捉的数据进行筛选。
显示过滤器中常用的关系计算符号
符号 | 说明 | 示例 |
---|---|---|
eq == |
等于 | ip.src==10.10.10.10 ip.src eq 10.10.10.10 |
ne != |
不等于 | ip.src!=10.10.10.10 ip.src ne 10.10.10.10 |
gt > |
大于 | |
lt < |
小于 | |
ge >= |
大于等于 | |
le <= |
小于等于 | |
contains |
包含 | http.host contains com |
显示过滤器中常用的逻辑计算符号
符号 | 说明 | 示例 |
---|---|---|
and && |
与 | http.host contains com && ip.src == 44.199.163.86 http.host contains com and ip.src == 44.199.163.86 |
or || |
或 | |
not ! |
非 |
常用示例
针对 IP 过滤
- 对源地址进行过滤
ip.src == 192.168.0.1
- 对目的地址进行过滤
ip.dst == 192.168.0.1
- 对源地址或者目的地址进行过滤
ip.addr == 192.168.0.1
- 如果想排除以上的数据包,只需要将其用括号囊括,然后使用
!
即可!(ip.addr == 192.168.0.1)
针对协议过滤
针对某种协议的数据包,表达式很简单仅仅需要把协议的名字(必须小写)输入即可
常见协议:tcp
udp
arp
icmp
http
smtp
ftp
dns
msnms
ip
ssl
oicq
bootp
针对端口过滤
- 捕获某一端口的数据包(以 tcp 协议为例)
tcp.port == 80
- 捕获多端口的数据包,可以使用
and
来连接,下面是捕获高于某端口的表达式(以 udp 协议为例)udp.port >= 2048
针对 http 请求的一些过滤实例
- 过滤出请求地址中包含
user
的请求,不包括域名http.request.uri contains "User"
- 精确过滤域名
http.host==baidu.com
- 模糊过滤域名
http.host contains "baidu"
- 过滤请求的 content_type 类型
http.content_type =="text/html"
-过滤 http 请求方法http.request.method=="POST"
- 过滤 tcp 端口
tcp.port==80
http && tcp.port==80 or tcp.port==5566
- 过滤 http 响应状态码
http.response.code==302
- 过滤含有指定 cookie 的 http 数据包
http.cookie contains "userid"
spinnaker 常见用法
环境信息
- Spinnaker 1.29.0
- Kubernetes 1.24.7
Spinnaker 引用 Kubernetes 中的 Namespace
Kubernetes 中的 Namespace,对应 Spinnaker 中的 Application,当 在 Kubernetes 中创建 Namespace ,并在此 Namespace 创建资源后,Spinnaker 会自动读取到此 Namespace,并显示在 Applications 中。
Pipelines 中引用 Docker Registry 类型的触发器
在 Pipelines 中配置 Docker Registry 类型的触发器,并在后面的 Stage 中自动引用。
在要配置的 Pipeline 的
Configuration
部分,配置Automated Triggers
,选择type
为Docker Registry
- Registry Name - 为 Halyard 中配置的 Docker Registry 的认证信息 的名称
- Organization - 对应 Docker Registry (如 Harbor) 中的 Projects
Stage 中使用以下方式引用镜像
image: '${trigger.artifacts[0].reference}'
${trigger}
为镜像名称,当一个镜像名下有多个不同标签的镜像时,${trigger.artifacts[0]
表示第一个镜像,依此类推。${trigger.artifacts[0].reference}
值为第一个镜像的完整镜像名加标签。