Fio 命令说明
FIO (Flexible I/O Tester) 是一款功能强大的磁盘性能测试工具,可用于对存储系统进行各种测试和评估。
Github地址 https://github.com/axboe/fio https://tobert.github.io/post/2014-04-17-fio-output-explained.html http://xiaqunfeng.cc/2017/07/12/fio-test-ceph/ https://fio.readthedocs.io/en/latest/fio_doc.html http://linuxperf.com/?p=156
使用说明# fio test file defination
# ini file format
; -- start job file --
[global]
size=1G # 设置测试文件的大小
runtime=30 # 设定运行时间, 如果运行时间之内已经完成了文件大小的写入则会保持文件大小和负载继续写。
bs=4k # 块大小
numjobs=1 # 定义测试的进程数量 默认是1
direct=1 # 是否绕过操作系统的Buffer缓冲区, 1 Enable
ioengine=libaio # io引擎使用libaio模式, 查看可用IO引擎的命令
group_reporting # 汇总信息显示
thread # 使用单进程多线程的模型, 默认是使用多进程模型。
time_based # 用运行时间为基准, 如果时间没有到达指定的值就继续执行相同的操作, 直接到时间满足要求。
[job1]
rw=write
[job2]
rw=read
[job3]
rw=randwrite
[job4]
rw=randread
[job5]
rw=randrw
; -- end job file --
^e1023e
关于硬盘性能 Iostat首先, 在man iostat的时候已经明确的提示了,iostat 的 svctm (也就是硬盘的servicetime)是一个不准确的值, 会在后续的版本中移除, 因为他所依赖的数据来源(/proc/diskstats)中,是从Block Level 出发来进行计算的, 所以svctm其实并不是IO控制器所需要的准确时间, 那么出现了两个问题, 我们能观察的数据是那个? 以及背后的含义是什么?
调度算法 和 读写请求的合并内核会对IO的请求进行合并, 但是这个合并不是一直存在的, 反映到IOstat的指标是 rrqm/s & wrqm/s, 这两个表示对于硬盘的读写请求中, 每秒合并的请求数量; 如果你去查看IO的调度算法, none 算法是完全不合并的, 所以这两列一直都是0.
队列的等待时间iostat中的await一列, 表示请求的等待时间,正常的情况下应该比较低,那么究竟什么情况下才是性能不佳的表现?await 每个I/O的平均耗时是用await表示(blktrace command results: Q2C – 整个IO请求所消耗的时间(Q2I + I2D + D2C = Q2C),相当于iostat的await。),包括了 IO请求在Kernel中的等待时间 + IO请求从内核出发处理完成回到内核的时间,也就是IO time + Service Time。await 一般情况下应该小于10ms , 如果没有或者比较大的情况下 , 应该考虑负载的类型, 来衡量硬盘的负载水平。
mdadmmdadm 已经不怎么更新和开发了默认推荐使用LVMLVM 和 mdadm 在操作系统都是使用的Raid驱动(内核模块)。其实也是可以使用btrfs , 这个测试的结果是 btrfs 的实现和管理成本比 LVM 要少的多。
相关的问题如果说有一个性能的问题, IOPS达不到指定的数值, 思路?首先查看队列深度是不是足够,看svctm时间长不长,看队列长度
/sys/block/sda/nr_requests
一般情况下这个参数是准确的,但是大部分指标都是取决于监控取样周期的。
操作系统默认输出的块大小是 : 256 , 参数可见 :╰─# cat /sys/block/sda/queue/max_sectors_kb256
max_segments表示设备能够允许的最大段的数目。 – 这应该是一个内存或者buffer的分段指标。 (待定)max_sectors_kb表示设备允许的最大请求大小。 – 可改 。max_hw_sectors_kb表示单个请求所能处理的最大KB(硬约束) – 这个是上一个参数的Limit。
Iostat命令的理解iostat -xkt 1rrqm/s wrqm/s - 读写请求的合并数量r/s w/s - 读写请求数量avgrq - 队列长度await - 时延util - 时间度量 , 时间周期之内进行IO操作所占的比例。例如 1 秒的时间之内, 取样的点中有多少是在执行IO操作。
一个例子 , 如果采样的周期为1s, 那么采样的范围之内 , 前面的0.5秒有执行IO的操作, 后面的0.5秒没有执行任何的操作, 那么 最后 Util 现在的结果就是50% 。avgrq也是一直平均值, 在采样周期之内如果前后的状况不一致 也会进行平均。
Shell脚本处理目录或者文件名中的空格
问题:问题是: 罗列指定的目录下面的文件, 符合要求的文件保留, 未匹配的删除。
解决:简单的Bash脚本, 使用ls拿文件名, 使用For + IF判断即可。但是文件的目录中有的文件名是带有空格的, 而Shell 使用空格做分隔符,因此无法正确的处理完整的文件名。解决方案有特别多, 只记录一个我最后使用的方案:使用IFS变量来定义Shell 的默认分隔符, 将空格替换成\n\b.
#!/bin/bash
#
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for number in {1..10}
do
mkdir -pv "dir $number"
done
tree
FILE=`ls`
for i in $FILE;
do
echo "The DirName: $i"
done
IFS=$SAVEIFS
这样就可以拿到名称为dir 1的完整目录名字了,否则会默认吧空格分割的文件名称作为两个目录提取。
⚡ ./delete.sh
.
├── delete.sh
├── dir 1
├── dir 10
├── dir 2
├── dir 3
├── dir 4
├── dir 5
├── dir 6
├── dir 7
├── dir 8
└── dir 9
10 directories, 1 file
The DirName: delete.sh
The DirName: dir 1
The DirName: dir 10
The DirName: dir 2
The DirName: dir 3
The DirName: dir 4
The DirName: dir 5
The DirName: dir 6
The DirName: dir 7
The DirName: dir 8
The DirName: dir 9
Linux中一些常见的性能分析命令
记录性能分析的思路。
最近的这个半年越来越好奇的事情是, 为什么命令会卡住,为什么命令会执行不下去,为什么命令会等待,等等等等。
那么这些问题, 有的是可以有答案的, 目前也不知道的。
已经大概掌握的几个不同的方法以及观测的工具, 大概做一个记录。
Strace命令Strace 命令的常见用法strace命令是用来追踪系统调用的,常见的可以追踪的系统调用需要阅读内核部分的代码。 但是常见的系统调用就是集中, read() , write() , ioctl(), futex() , mmap()大部分的时候 我们都是可以观测到卡住的部分的 , 这种追踪我认为常见的使用场景就是命令卡住了, 或者执行中的程序卡住了。
命令卡住的分析对于命令卡住的情况, 可以使用类似于如下的命令:
strace -f -ttt -s 512 echo "123"
这样的话, 在执行的过程中就可以查看相关的内容,比如常见的卡在了系统调用的某个函数上, 这个可以用来定位,命令打开了那些文件,申请的那些内存地址,打开了什么文件,关闭Socket等等等等。目前我的办法的通过对比这个卡住的命令执行到什么函数出现的问题, 对应的在正常的机器上进行对比,就可以猜到大概的问题出现在了哪里。
已经运行中的程序分析strace -f -ttt -s 512 -p 123
执行进程的PID , 然后strace会attach到进程上, 输出的内容, 也可以查看到当前程序的运行状态。
总结如上面的两种方式,都可以对运行中明显的问题进行观察, 但是如果没有卡在系统调用的部分, 通过这个命令的观察其实是无法查看的, 因为他记录的是应用程序指令陷入到内核态的部分, 但是常见的应用程序基本上都是用户态的,所以这个部分如果是应用卡在用户态上, 观测的信息就比较有限了。
Perf命令Perf简单的分析perf命令的简单分析, 首先是
perf topperf top 可以用来实时的查看应用程序的相关问题, 收集指标的范围是整个操作系统,所以是比较消耗资源的, 输出的结果也是直接可以查看的, 看完了结果打断即可。
perf statperf stat 查看相关的统计信息,如下是一个样例,提供了一些静态的指标。
sudo perf stat
Performance counter stats for 'system wide':
61,167.25 msec cpu-clock # 16.000 CPUs utilized
4,955 context-switches # 81.007 /sec
63 cpu-migrations # 1.030 /sec
930 page-faults # 15.204 /sec
6,266,524,215 cycles # 0.102 GHz (83.32%)
244,046,608 stalled-cycles-frontend # 3.89% frontend cycles idle (83.34%)
66,809,179 stalled-cycles-backend # 1.07% backend cycles idle (83.34%)
818,170,826 instructions # 0.13 insn per cycle
# 0.30 stalled cycles per insn (83.34%)
155,602,840 branches # 2.544 M/sec (83.34%)
1,701,804 branch-misses # 1.09% of all branches (83.33%)
3.823037998 seconds time elapsed
显示的内容是从输入了命令之后的相关信息,主要是一些CPU相关的指标, 比如CPU时钟,上下文交换次数,cpu转移,缺页中断等等等等。
perf recordperf record 我常用的命令是这样的, 他会将记录到的指标输出到当前目录的文件中,然后供report命令来进行分析, 这两个一般来说会合用。
perf record -a -g -F 1000 -p 123
perf record -a -g -F 1000 echo 123
perf record -a -g -F 1000
perf record -a -g -F 1000 -- sleep 60
三个命令会记录相关的指标到当前目录的perf.data文件中。 大小和采样的频率,时间的数量有关。
perf reportperf report 我比较常用的参数就是 使用
perf record --stdio
来直接进行查看, 占用时间百分比比较高的函数,前提是 ,这个命令的运行需要有perf.data.
perf schedperf sched 通常是用来查看cpu调度延时的, 这个用的确实不多, 毕竟cpu调度现在基本上都是cfq, 改的人毕竟还是少数, 所以实际的使用比较少。这个指令常用的如下:
perf sched record
perf sched latency
perf sched report
上面的这些都是我比较常用的命令, 临时抓出来看下。
Perf命令输出火焰图perf 命令输出火焰图需要的是Github上面的一个项目, 这个项目的作者也是写性能之巅的作者。
具体的处理流程如下:
git clone --depth 1 https://github.com/brendangregg/FlameGraph.git
sudo perf script > out.perf
FlameGraph/stackcollapse-perf.pl out.perf > out.folded
FlameGraph/flamegraph.pl out.folded > out.svg
最后输出的out.svg就是结果了,可以通过浏览器来查看。至于查看的方法,其实是看函数所占有的面积, 面积越大说明函数运行的时间越长;那么还有说法是说, 越靠近顶端的应该越尖,如果有顶端比较大的平顶说明可能是有问题的, 这个答案还在求证中。
Kubernetes day2
对于etcd的操作和备份
Etcd的操作 - EtcdctlEtcd的规划
最好用 固态盘, Pod数量比较多的情况下会非常非常慢, 内存要大.
类似于redis 或者 Zookeeper, KV的存储.
支持watch机制,可以通知给node节点的数据变化.
etcd consul zookeeper 的区别
名称
优点
缺点
接口
一致性算法
zookeeper
1.功能强大,不仅仅只是服务发现2.提供watcher机制能实时获取服务提供者的状态3.dubbo等框架支持
1.没有健康检查2.需在服务中集成sdk,复杂度高3.不支持多数据中心
sdk
Paxos
consul
1.简单易用,不需要集成sdk2.自带健康检查3.支持多数据中心4.提供web管理界面
1.不能实时获取服务信息的变化通知
http/dns
Raft
etcd
1.简单易用,不需要集成sdk2.可配置性强
1.没有健康检查2.需配合第三方工具一起完成服务发现3.不支持多数据中心
http
Raft
Etcdctl 的命令
查看etcd的成员清单
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --write-out=table --endpoints="192.168.31.21:2379,192.168.31.22:2379,192.168.31.23:2379" member list
查看etcd的节点状态
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --endpoints="192.168.31.21:2379,192.168.31.22:2379,192.168.31.23:2379" endpoint status -w table
查看etcd存储的数据
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --endpoints="192.168.31.21:2379,192.168.31.22:2379,192.168.31.23:2379" get /registry/ --prefix --keys-only | head
查看etcd中的pod信息
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --endpoints="192.168.31.21:2379,192.168.31.22:2379,192.168.31.23:2379" get /registry/ --prefix --keys-only | grep pod
其他的操作
get / put / del 等基础操作
Watch机制watch机制是通过不断的查看数据,发生变化就主动的通知客户端,v3支持watch固定的key,也可以watch一个范围的数据。
# watch 一个pod的信息, 然后手动delete这个pod , 查看etcd 的watch行为和输出的结果。
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --endpoints="192.168.31.21:2379,192.168.31.22:2379,192.168.31.23:2379" watch /registry/pods/monitoring/node-exporter-889hf
数据备份恢复和WAL日志WAL: watch ahead log - 预写日志, 可以通过预写日志来进行数据库的恢复。WAL记录了整个数据变化的过程,在操作写入数据之前先进行wal日志的写入。
etcd v2 的时候直接复制和备份目录,备份文件的方案etcd v3 的备份和恢复, 使用快照的方式。
备份使用的命令和恢复的命令不太一样, etcdctl vs etcdutl
可以写脚本来进行数据进行备份和恢复。
]$ etcdctl snapshot save
]$ etcdctl snapshot restore
]$ etcdctl snapshot status
]$ etcdctl --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/kubernetes.pem --key=/etc/kubernetes/ssl/kubernetes-key.pem --endpoints="192.168.31.21:2379" snapshot save snap-20211002.db
# 测试尝试恢复到临时的目录,测试用。 目录地址用的是tmp下面的。
]$ etcdutl snapshot restore ./snap-20211002.db --data-dir /tmp/etcd-restore
2021-10-02T12:01:13+08:00 info snapshot/v3_snapshot.go:251 restoring snapshot {"path": "./snap-20211002.db", "wal-dir": "/tmp/etcd-restore/member/wal", "data-dir": "/tmp/etcd-restore", "snap-dir": "/tmp/etcd-restore/member/snap", "stack": "go.etcd.io/etcd/etcdutl/v3/snapshot.(*v3Manager).Restore\n\t/tmp/etcd-release-3.5.0/etcd/release/etcd/etcdutl/snapshot/v3_snapshot.go:257\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.SnapshotRestoreCommandFunc\n\t/tmp/etcd-release-3.5.0/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:147\ngo.etcd.io/etcd/etcdutl/v3/etcdutl.snapshotRestoreCommandFunc\n\t/tmp/etcd-release-3.5.0/etcd/release/etcd/etcdutl/etcdutl/snapshot_command.go:117\ngithub.com/spf13/cobra.(*Command).execute\n\t/home/remote/sbatsche/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:856\ngithub.com/spf13/cobra.(*Command).ExecuteC\n\t/home/remote/sbatsche/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:960\ngithub.com/spf13/cobra.(*Command).Execute\n\t/home/remote/sbatsche/.gvm/pkgsets/go1.16.3/global/pkg/mod/github.com/spf13/cobra@v1.1.3/command.go:897\nmain.Start\n\t/tmp/etcd-release-3.5.0/etcd/release/etcd/etcdutl/ctl.go:50\nmain.main\n\t/tmp/etcd-release-3.5.0/etcd/release/etcd/etcdutl/main.go:23\nruntime.main\n\t/home/remote/sbatsche/.gvm/gos/go1.16.3/src/runtime/proc.go:225"}
2021-10-02T12:01:13+08:00 info membership/store.go:119 Trimming membership information from the backend...
2021-10-02T12:01:13+08:00 info membership/cluster.go:393 added member {"cluster-id": "cdf818194e3a8c32", "local-member-id": "0", "added-peer-id": "8e9e05c52164694d", "added-peer-peer-urls": ["http://localhost:2380"]}
2021-10-02T12:01:13+08:00 info snapshot/v3_snapshot.go:272 restored snapshot {"path": "./snap-20211002.db", "wal-dir": "/tmp/etcd-restore/member/wal", "data-dir": "/tmp/etcd-restore", "snap-dir": "/tmp/etcd-restore/member/snap"}
]$ ls /tmp/etcd-restore/
member
数据恢复的流程:
创建新的etcd集群
停止kubernetes以及其他的依赖etcd 的服务。
停止空白的新的集群
使用备份的文件进行集群的恢复
使用在集群的每个节点恢复相同的备份文件
每个节点启动etcd的集群并且进行验证
启动Kubernetes的相关集群和组件。
查看恢复的结果,验证各个组件的相关服务是否已经正常恢复。
Etcd节点的维护
etcdctl add-etcd
etcdctl del-etcd
资源清单以及API相关的外部服务接口
Container Runtime Interface - CRI
runc
RKT
Container Storage Interface - CSI
Container Network Interface - CNI
Node的相关操作
cordon
uncordon
drain
taint
Harbor Http 安装部署
Harbor的部署记录。
Harbor Info
Harbor 项目地址
Harbor HTTP部署因为是临时使用, 所以直接给了HTTP的权限, 为的是不走公网部署 CEPH Cluster, CEPH在BootStrap之后会默认去公网的镜像仓库尝试Pull镜像并且校验镜像和服务,所以给一个私有的仓库, 直接去找私有仓库就免了公网访问卡集群的正常启动的步骤。
下载解压~]$ wget https://github.com/goharbor/harbor/releases/download/v2.3.2/harbor-offline-installer-v2.3.2.tgz
~]$ mv harbor-offline-installer-v2.3.2.tgz /opt
~]$ tar zxvf /opt/harbor-offline-installer-v2.3.2.tgz
复制修改配置文件~]$ cp /opt/harbor/harbor.yml.tmpl /opt/harbor/harbor.yml
配置默认的存储位置# 注释掉https的部分,如果需要https的话签发一个证书写路径在配置文件中
# 修改默认的存储位置
data_volume: /opt/harbor/image_store
指定Harbor对外提供服务的域名# 修改Harbor的域名或者主机名(需要对应的解析),也可以直接使用IP地址
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: harbor.local
设置harbor Admin的密码可以登录Dashboard 或者 Pull镜像
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345
创建harbor存储镜像的目录# 创建Harbor的存储目录, 可以远程指定到Cephfs上面
~]$ mkdir /opt/harbor/image_store
配置Docker-ce 清华的镜像源这个配置是给Centos / RHEL来使用的,来自清华的Repo Help
# 添加repo文件,和修改配置到Tsinghua repo
~]$ wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
~]$ sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# 安装Docker-ce
~]$ sudo yum install docker-ce
# CENTOS8 STREAM 特殊的配置,需要卸载 podman 和 Buildah
~]$ dnf install -y docker-ce --allowerasing
# 开机启动
~]$ sudo systemctl restart docker && sudo systemctl enable docker
# 安装Docker-compose ,因为CentOS8 默认是没有Docker-compose的 , 按照官网的流程走就可以。
~]$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
~]$ sudo chmod +x /usr/local/bin/docker-compose
~]$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
安装harbor~]$ cd /opt/harbor
/opt/harbor]$ ./install.sh
启动Harbor直接使用Docker-compose启动即可,如果需要的话可以在配置文件中指定镜像扫描器,来进行镜像的漏洞扫描。
# 进入Harbor运行所在的目录
~]$ cd /opt/harbor
# 使用Docker-compose的启动命令,适用于服务停止 或者 Docker 重启的时候, 容器没有正常运行。
~]$ docker-compose up -d -f /opt/harbor/docker-compose.yaml
# 查看容器的启动状态
/opt/harbor]$ docker-compose ps
/opt/harbor]$ watch -n 1 docker-compose ps
# 通过Docker-compose停止harbor
/opt/harbor]$ docker-compose down
验证
打开浏览器,访问harbor的地址 默认的端口80
在所有docker节点上配置不安全的私有仓库,docker login [HARBORIP:PORT]
在所有podman节点上配置不安全的私有仓库,podman login [HARBORIP:PORT]
提示Login Successed, 登录成功,可以正常pull镜像了
Cephadm Bootstrap 阶段使用 Harbor编辑cephadm文件,修改如下的镜像名称,和仓库的前缀这里其实还是需要再测试的, 按照这个脚本的逻辑, 应该会把所有的镜像都从指定的仓库Pull下来,但是我执行的时候只有ceph/ceph:v16一个镜像下来了, 感觉还是有点儿问题的。
DEFAULT_IMAGE = 'harbor.local/ceph/ceph:v16'
DEFAULT_IMAGE_IS_MASTER = False
DEFAULT_IMAGE_RELEASE = 'pacific'
DEFAULT_PROMETHEUS_IMAGE = 'harbor.local/ceph/prometheus:v2.18.1'
DEFAULT_NODE_EXPORTER_IMAGE = 'harbor.local/ceph/node-exporter:v0.18.1'
DEFAULT_ALERT_MANAGER_IMAGE = 'harbor.local/ceph/alertmanager:v0.20.0'
DEFAULT_GRAFANA_IMAGE = 'harbor.local/ceph/ceph-grafana:6.7.4'
DEFAULT_HAPROXY_IMAGE = 'harbor.local/ceph/haproxy:2.3'
DEFAULT_KEEPALIVED_IMAGE = 'harbor.local/ceph/keepalived'
DEFAULT_REGISTRY = 'harbor.local' # normalize unqualified digests to this
Cephadm 使用私有仓库bootstrap~]$ cephadm bootstrap --mon-ip 192.168.1.211 --allow-overwrite \
--registry-url harbor.local \
--registry-username admin \
--registry-password Harbor12345
查看并且清除ceph-bootstrap的历史记录~]$ ls /etc/systemd/system/ceph*
~]$ ls /usr/lib/systemd/system/ceph*
~]$ rm -rf /etc/systemd/system/ceph*
~]$ rm -rf /usr/lib/systemd/system/ceph*
~]$ docker stop `docker ps -a -q`
Kubernetes day1
云原生的定义
云原生一些概念十二因素应用
基准代码: 一份基准代码,多次部署(用同一个代码库进行版本控制)
依赖: 显式的声明和隔离相互之间的依赖
配置: 在环境中存储配置(配置中心,携程的apollo)
后端服务: 后端服务作为一个附加的资源,数据库,中间件等等
构建,发布,运行: 对程序执行构建或者打包,严格分离构建和运行,打镜像编译等等,构建和运行严格的分离
进程: 使用一个或者多个无状态进程运行应用
端口绑定: 通过端口绑定提供服务
并发: 通过进程模型进行扩展
易处理: 快速的启动,优雅的终止,最大程度的保持健壮性。
开发环境与线上环境等价: 尽可能保持Dev,Prelive,Live环境的一致性
日志: 将所有运行中的进程和后台服务的输出流按照的时间顺序统一收集存储和展示(ELK,Fluend,Logstash,Filebeat等等)
管理进程: 一次性管理类型的进程(Onetime Job)应该和正常的常驻进程使用同样的运行环境
Master - APIserverAPIserver提供了Kubernetes各类资源对象的CRUD以及Watch等等的HTTP REST接口,对象包括Pods,Services, ReplicationsControllers等等, 为RESTful操作提供服务,并且为集群状态提供前端,所有的组件都通过前端进行交互。
特点: RESTful风格
APIserver的请求最后会同步到Etcd。
请求APIserver在权限的鉴定完成之后, 可以查看大部分的信息。
端口默认是 6443 可通过启动参数(–secure-port)来进行调整
绑定的IP地址可以通过 –bind-address 在启动的时候指定
端口用于接受客户端,dashboard的外部HTTPBase的请求
Token 以及证书的HTTPbase的校验
基于指定策略的授权
功能:
身份认证
验证权限
验证指令
执行操作
返回结果
Master - Kube-scheduler负责将Pod指定到节点上。
取出Pod需要分配的信息, 先排除不可调度的Node,在可用的Node列表之中选择一个合适的Node,将信息写入etcd。等待Node上面的kubelet进行生成Pod。
Node的Kubelet通过APIserver监听到Pod的相关信息,然后获取Pod的清单,下载镜像,启动Pod, Kubelet每秒Watch-APIserver的信息。
三个默认策略:
LeastRequestedPriority - CPU+MEM直接评分,选择资源目前较低
CalculateNodeLanelPriority - 先匹配标签,在进行评分
BalancedResourceAllocation - 优先分配各项资源的使用率最均衡的节点
队列: PodQueue , NodeList
Master - Kuber-Controller-Manager提供不同的控制器,例如: 集群内的Node, Pod ReplicaCounts, EndPoint, Namespace, ServiceAccount, ResourceQuota等等资源的控制内容,如果发现异常的时候提供自动化的修复流程。确保所有的服务是在预期的状态下运行。
5s检查一次Node的状态
包括多种不同的控制器
检查所有的控制器 和 Node是否符合预期
如果Node 不可达之后 40s会将节点标记为无法访问
标记为无法访问5min之后, 将删除这个节点,同时在其他的节点重建需要的Pod。
Pod的高可用机制: 1. NodeMonitorPeriod: 监视周期 2. NodeMonitorGracePerios: 节点监视观察期 3. PodEvictionTimeout: 超时驱逐的区间
Kube-ProxyKubernetes网络代理,反映了Node上面的Kubernetes中的服务对象的变化,通过管理IPVS或者IPTABLES的规则来进行网络层的实现。
可以通过配置文件来指定IPVS的调度算法, 一般默认是RR, ipvsadm -ln
直接指定kubelet的配置文件选项ipvs:
scheduler: sh
Kubelet
汇报节点的状态
监听API server 上面的pod信息变化,并调用Docker 和 Containerd 创建容器
准备Pod所需要的数据卷
返回Pod的运行状态
在Node节点上进行容器的健康检查
Docker基础知识二周目
Docker Container 基础 。 again …..
Docker使用的六个名称空间
MNT Namespace - 提供文件的挂载和文件系统的隔离
IPC Namespace - 提供进程间通信
UTS Namespace - 提供主机名隔离
PID Namespace - 提供进程以及进程号隔离
Net Namespace - 提供网络隔离
User Namespace - 提供用户以及用户id的隔离
容器的进程ID关系Host -------------------------------- | container ------------------------|
systemd -- containerd -- container-shim -- | nginx-master -- nginx-worker
` -- container-shim -- | nginx-master -- nginx-worker
` -- container-shim -- | mysql-master -- mysql-worker
dockerd -- docker-proxy -- | docker-proxy
` -- docker-proxy -- | docker-proxy
` -- docker-proxy -- | docker-proxy
containerd负责控制容器的进程,主机,用户,挂载的隔离。dockerd 启动的docker-proxy用来管理iptables进行网络的隔离。docker.service 里面指定了调用Containerd的socket生成容器的过程钟,API调用过程使用的是grpc。无论dockerd还是containerd最终使用的都是runc(container runtime) ,一个基于Go语言的容器创建工具, 根据OCI标准来创建容器。
docker-daemon 限制可以限制生成日志的大小
限制日志的大小使用的是 docker的daemon config, 针对的日志的范围,是docker Container 里面的标准输入输出的日志, 这部分日志的存储是在机器的硬盘上, 位置是(/opt/docker-storage/containers , 也就是/var/lib/docker/containers/[CONTAINER_ID]/*.json),
cpu 大约可以分配 1:4 , mem不建议超过物理内存的分配
压测镜像: lorel/docker-stress-ng
Docker的网络结构使用的是宿主机的docker0桥,同时在Host上面生成虚拟网卡veth多个接口 , 在容器中生成eth0的虚拟网卡对, 虚拟机中的两个容器之间使用的是物理地址进行寻址访问,所以这个部分可以通过arp命令来进行验证。
Docker容器的资源限制 - Cgroup可以限制 CPU,MEM,DISKIO,NETIO, PRI,PAUSE/RESUME。 对于Kubernetes可以对集群的Namespace来进行限制资源的规划。
查看内核可以支持的cgroup Flag.
┌─[hayden@HaydenArchDesktop] - [~] - [Sun Sep 05, 00:14]
└─[$] <> zcat /proc/config.gz | grep CGROUP
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_IOCOST=y
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
┌─[hayden@HaydenArchDesktop] - [~] - [Sun Sep 05, 00:14]
└─[$] <> zcat /proc/config.gz | grep MEM | grep CG
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CPUKubernetes 限制是1/1000Core ,Docker是1/10Core, 只需要通过 –cpus 选项指定容器可以使用的 CPU 个数就可以了,并且还可以指定如 1.5 之类的小数。
CPU OverCommit 1:8
MEMMEM的限制单位是M; 同时可以限制Swap的使用,但是限制Swap的使用需要内核的支持,大部分时候还是会关闭掉SWAP, 虽然避免了OOM,但是会影响服务的质量。
MEM 不建议OverCommit
一般情况下 : 分配0.5/1个CPU,mem 2G/4G; 根据业务的不同, 一般会是高可用的部署,两个一起对外提供服务;所以会启动两个容器,不需要提供太高的硬件,符合要求即可。
关于OOM的问题和可以调整的参数(/proc/[PID]/):
oom_adj 取值范围 -17 to +15 , 为了兼容旧程序保留的方式
oom_score 一般是自动计算出来的结果,综合计算的结果, 参考 : CPU时间,存活时间,oom_adj计算之后的结果。
oom_score_adj OOM分数的偏移量,-1000 to +1000, 可以设置-1000表示永远不会被Kill
DISKIODisk OverCommit : 1:1.2
PAUSE\RESUME
Ceph Cluster 04 - CRUSH算法
ceph笔记04
修改CRUSH算法的分配方式基础概念:五种运行图: MON服务维护
Monitor Map - 监控的运行图 MON的状态
OSD Map - OSD的状态, 每隔六秒钟汇报一次状态
PG Map - PG的运行图, PG的状态和映射关系
CRUSH Map - 一致性hash算法,和数据块和osd的分配关系, 动态更新,当客户端请求一个文件的时候,会通过CRUSH算法会根据osd的map创建PG组合的来对文件的存储进行负载和分配。假如有20个osd,创建32重组合分配对应的pg和osd的对应关系,选主从,选分布方式和节点的同步关系,叫做CRUSH Map。
MDS Map - Metadata Map ,元数据和数据文件的映射关系。
5种算法对节点的选择方式
Uniform
List
Tree
Straw - 早期的版本,分布不是特别的均衡,抽签算法
Straw2 - 目前已经发展中的版本, 抽签算法 (Default)
对PG的动态调整默认情况下是动态调整的,但是可以手动调整为给予权重,设置PG分配的倾向,例如1T权重是1,等等等等
查看状态以及调整方式ceph osd df需要关注的值有两个:
weight - 根据磁盘的空间进行的调整,默认自动计算, 可调。
reweight - 磁盘的所有权重相加之后, 单个osd所占用的比例,由于默认的分配是相对概率的平衡,所以分配可能还是会有一些不均衡,通过这个可以进行再次的平衡。
调整的效果就是希望立刻重新平衡PG的数量(需要注意在业务负载低的时候执行) 数据均衡分配。迫使算法动态的更新PG的位置。
调整WEIGHT的值ceph osd crush reweight osd.10 {WEIGHT} # 调整weight值, 越大权重越高,分配的PG数量越大。
调整REWEIGHTceph osd crush reweight {OSD_ID} {REWEIGHT} # 范围是 0 - 1, 也是越大权重越高。
对运行图进行操作
创建一个保存运行图的目录mkdir /cephmap/ceph -pceph osd getcrushmap -o /cephmap/ceph/crushmap # 同时可以做备份使用,将运行图导出到文件中,当需要的时候可以通过这个文件还原。
转换map的二进制格式为文本,Ubuntu 需要安装 crushbase 包。crushtool -d /cephmap/ceph > /cephmap/ceph/crushmap.txt
编辑这个文件主要编辑type部分, 按照不同的调度需求,按照不同的osd,不同主机调度,不同的机架,不同的机柜,不同的PDU,不同的房间,不同的数据中心, 不同的区域城市, 顶层。下面是主机的配置部分。每个主机的算法,osd的分配情况,权重。Rules 副本池的规则里面定义了step take default 基于default配置端里面的规则来进行osd的分配。step chooseleaf firstn 0(按照顺序选择,先选到的就是) type host(按照什么类别进行选择高可用的类型)max_size 副本池配置文件之中可以定义副本数
转换成二进制文件crushtool -c /cephmap/ceph/crushmap.txt -o /cephmap/ceph/crushmap_new
导入查看是否生效ceph osd setcrushmap -i /cephmap/ceph/crushmap_new
查看是否生效ceph osd crush rule dump
创建一个存储池ceph osd pool create magedu-ssdpool 32 32 magedu_ssd_ruleceph pg ls-by-pool magedu-ssdpool | awk ‘{print $1,$2,$15}’
Linux_Ranger_Usage
ranger 备忘
g/ Go root
gh Go home
gg Go to top
G Go bottom
# 文件操作 复制、剪切、删除、粘贴 (针对当前文件或则选择的内容)
yy 复制
dd 剪切
pp 粘贴
F5 复制
F5 剪贴
F8 删除
Delete 删除
# 书签
mX 把当前目录做一个书签 (X 表示任何字符)
'X 跳到X书签代表的目录
# 标签 不同标签可以复制、粘贴、移动
gn 新建一个标签
Alt+N 跳转到N号标签 (代表一个数字)
gt,gT 跳转到前个标签,后个标签
# 排序 对文件和目录列表进行排序,以便查看。
ot 根据后缀名进行排序 (Type)
oa 根据访问时间进行排序 (Access Time 访问文件自身数据的时间)
oc 根据改变时间进行排序 (Change Time 文件的权限组别和文件自身数据被修改的时间)
om 根据修改进行排序 (Modify time 文件自身内容被修改的时间)
ob 根据文件名进行排序 (basename)
on 这个好像和basename差不多(natural)
os 根据文件大小进行排序(Size)
# 重命名 修改文件名有两种模式:当前文件和批量改名
cw 新文件名 -- 修改当前文件名
A -- 在当前文件名后追加文字
I -- 在当前文件名前追加文字
:bulkrename --针对mark过的文件批量改名
# 执行shell命令
! -- 进入命令模式执行shell命令
s -- 同上
# -- 同!,但结果输出到一个pager。相当于 cmd | less
@ -- 同!,但会把选择的文件作为参数放在最后。
S -- 进入一个新的shell。exit后回到当前的ranger
Ceph Cluster 03 - CephFS
ceph笔记03
Cephfs的使用Cephfs的使用条件
当我们需要多个服务来挂载和实时的同步的时候, 使用到CEPHFS,可以实现文件系统的共享。内核里面现在这个时间已经内置cephfs的挂载模块, 可以直接挂载不需要安装。
cephfs运行需要MDS服务,用来存储缓存的文件信息。总体需要创建两个存储池,单独创建一个存储MDS信息的存储池, 同时需要创建一个数据池来提供存储空间。
启用mds的服务 ceph orch mds 2
创建ceph的存储池ceph mds stat
# 创建一个cephfs的metadata池
ceph osd pool create metadata 32 32
# 创建一个cephfs的data池
ceph osd pool create cephfsdata 64 64
# 创建ceph的状态
ceph osd pool ls
ceph -s
# 创建cephfs的文件系统
ceph fs new defaultfs metadata cephfsdata
# 新的版本里面已经不需要手动创建mds和两个对应的存储池了, 只是需要一条命令就可以自动创建。
[ceph: root@ceph01 /]# ceph fs volume create test
[ceph: root@ceph01 /]# ceph fs volume ls
[ceph: root@ceph01 /]# ceph mds stat
# 需要提前获取挂载的Token:
[root@HaydenArchDesktop ceph]# sudo scp root@ceph01:/etc/ceph/ceph.client.admin.keyring /etc/ceph/
[root@HaydenArchDesktop ceph]# mount -t ceph :/ /mnt -o name=admin
[root@HaydenArchDesktop mnt]# mount | grep ceph
192.168.31.11:6789,192.168.31.12:6789,192.168.31.13:6789:/ on /mnt type ceph (rw,relatime,name=admin,secret=<hidden>,acl)
#
# journalctl -f > /mnt/journal.log
# 查看cephfs的写入文件的动作过程。
# 同时使用 tail -f 在另一个窗口中查看文件的内容。 测试写入和查看内容的差距。
用户权限MDS可以启动多个实例,多个实例会自动来负载不同资源的文件元数据的缓存。客户端通过MON节点进行授权 和 获取MDS的的位置。MDS现在最新的版本默认已经是一主一备, 自动会生成高可用的模式。(之前的手动部署多个MDS服务器, 然后指定MDS的角色)
创建一个普通用户来进行身份的验证# 创建一个测试的用户
ceph auth add client.testuser mon 'allow r' mds 'allow rw' osd 'allow rwx pool=cephfsdata'
# 测试所建立的用户的权限,获取认证的keyring
ceph auth get client.testuser
# 导出用户的Keyring, 用来做集群的校验
ceph auth get client.testuser -o ceph.client.testuser.keyring
# 导出用户的key , Kubernetes的挂载会使用到
ceph auth print-key client.testuser > testuser.key
# 验证用户是否可以获取到集群的状态
ceph --user testuser -s
# 将挂载点添加到fstab自动开机挂载
MON01:6789,MON02:6789,.........:/ /mnt ceph defaults,name=testuser,secretfile=/etc/ceph/testuser.key,_netdev 0 0
Dashboard权限# 启用或者禁用账户
[ceph: root@ceph01 /]# ceph dashboard ac-user-enable admin
# 重置Dashboard用户的密码
# Old Version
[ceph: root@ceph01 /]# ceph dashboard set-login-credentials admin -i /etc/ceph/dashboard_password
# New version command.
[ceph: root@ceph01 /]# ceph dashboard -h | grep ac-user
dashboard ac-user-add-roles <username> [<roles>...] Add roles to user
dashboard ac-user-create <username> [<rolename>] [<name>] Create a user. Password read from -i <file>
dashboard ac-user-del-roles <username> [<roles>...] Delete roles from user
dashboard ac-user-delete [<username>] Delete user
dashboard ac-user-disable [<username>] Disable a user
dashboard ac-user-enable [<username>] Enable a user
dashboard ac-user-set-info <username> <name> [<email>] Set user info
dashboard ac-user-set-password <username> [--force- Set user password from -i <file>
dashboard ac-user-set-password-hash <username> Set user password bcrypt hash from -i <file>
dashboard ac-user-set-roles <username> [<roles>...] Set user roles
dashboard ac-user-show [<username>] Show user info
MDS 高可用# 提升默认的主节点的数量, 来提高MDS服务的吞吐量
ceph fs set defaultfs max_mds 2
ceph fs get defaultfs
# 变成两主两备, (设置Rank)
# 参数: mds_standby_replay true
mds_standby_for_name: MDS_NAME
mds_standby_for_rank: 备份指定级别的mds
mds_standby_for_fscid: 指定文件系统ID,会联合rank配置生效,如果指定了rank就是指定文件系统的rank会进行主备,如果未指定就是指定文件系统的所有Rank。
如果是一对一的高可用 , 需要对每个mds进行独立的配置。配置样例: # 配置的结果是mds1主, mds2 备; mds3 主, mds4 备.
[mds.ceph-mds1]
mds_standby_replay = true
mds_standby_for_name = ceph-mds2
mds_standby_for_fscid = defaultfs
[mds.ceph-mds3]
mds_standby_replay = true
mds_standby_for_name = ceph-mds4