基于Ceph分布式存储的Harbor部署方案_harbor ceph-程序员宅基地

技术标签: ceph  harbor  运维架构  

一、总体技术架构

基于单节点部署的Harbor随着存储内容和运行日志的增加,系统的存储空间会趋紧饱和。本文将研究和部署基于Ceph的分布式harbor部署方案。软件安装如下:

Docker:version 1.12.6
Docker-compose: version 1.23.2
Ceph:version 10.2.11
Mysql: version 10.2.14(MariaDB)

在资源划分上harbor分部署集群和ceph集群进行了复用。其中一台服务器作为Nginx负载均衡,另外Harbor节点和Ceph节点进行了一定的服用。其中一台服务器作为共享数据库。其资源分配如下所示:

Nginx ——10.10.13.1
Admin——10.10.13.21
Node0——10.10.13.22
Node1——10.10.13.30
Mysql ——10.10.13.31

需要说明一下,Ceph存储集群搭建,admin作为ceph-deploy和mon,Node0作为OSD0,Node1作为OSD1,并且将创建的cephfs mount到这三个节点上,在这三个节点上部署Harbor服务组成一个镜像仓库集群(这样Harbor就可以直接挂载本地cephfs路径上了)。此外,再提供一个节点Nginx作为负载均衡将请求均衡到这三个节点,最后再提供一个节点Mysql作为外部数据库存储,建议做成HA高可用,鉴于目前资源有限,暂时选用一台服务器作为数据库服务器,后续可以采用容器服务来进行替代。
其总体技术架构如下图所示:
在这里插入图片描述

这里需要说明的是,由于目前资源有限,上述总体技术架构只能保证数据安全,既不会因为Harbor节点本身出现故障,从而导致数据丢失的问题。并且harbor多节点能够共享数据。解决目前现有的单节点harbor系统数据冗余的情况出现数据丢失和存储空间无法扩展的问题。真正在生产系统上应用,还需要注意Harbor集群节点的数据快速同步等问题。真正做到数据实时性访问等。而针对镜像数据共享,实现了多Harbor服务共享后端存储的方式,即通过Ceph分布式存储方案来解决。
在这里插入图片描述

结合上图,每一个Harbor节点上都mount配置好的cephfs,然后配置每一个Harbor服务的各个组件volume都挂载cephfs路径,最后通过统一的入口Nginx负载均衡将流量负载到各个Harbor服务上,来实现整体Harbor集群的"高可用"。

但是还需要注意的是,在本方案中将默认harbor-db数据库组件拆出来,让其连接外部Mysql数据库(默认Harbor会在每个节点上都启动Mysql服务进行数据存储,这样数据就无法实现统一,即使我们将Mysql数据库存储在cephfs上,三个节点共用同一份数据,但是依然不可行,因为Mysql多个实例之间无法共享一份Mysql数据文件。

二、Ceph介绍及部署

Ceph是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。
1、Ceph架构
Ceph主要基于RADOS对象存储系统来实现可靠的、自动修复、自我管理的分布式对象存储系统。上层通过librados封装了一层接口,支持C/C++/Java/Python/Ruby/PHP等。支持三种接口:

Object:有原生的API,而且也兼容Swift和S3的API;
Block:支持精简配置、快照、克隆;
File:Posix接口,支持快照。

在这里插入图片描述
2、Ceph核心组件及概念介绍

Monitor
一个Ceph集群需要多个Monitor组成的小集群,它们通过Paxos同步数据,用来保存OSD的元数据。


OSD
OSD全程Object Storage Device,也就是负责响应客户端请求返回具体数据的进程。一个Ceph集群一般都有多个OSD。


MDS
MDS全称Ceph Metadata Server,是CephFS服务依赖的元数据服务。


Object
Ceph最底层的存储单元是Object对象,每个Object包含元数据和原始数据。


PG
PG全称Placement Groups,是一个逻辑的概念,一个PG包含多个OSD。引入PG这一层其实是为了更好的分配数据和定位数据。


RADOS
RADOS全称Reliable Autonomic Distributed Object Store,是Ceph集群的精华,用户实现数据分配、Failover等集群操作。


Librados
Librados是Rados提供库,因为RADOS是协议很难直接访问,因此上层额RBD、RGW和CephFS都是通过librados访问的,目前提供PHP、Ruby、Java、Python、C和C++支持。


CRUSH
CRUSH是Ceph使用的数据分布算法,类似一致性哈希,让数据分配到预期的地方。


RBD
RBD全称RADOS block device,是Ceph对外提供的块设备服务。


RGW
RGW全称RADOS Gateway,是Ceph对外提供的对象存储服务,接口与S3和Swift兼容。


CephFS
CephFS全称Ceph File System,是Ceph对外提供的文件系统服务。

3、Ceph IO流程及数据分布
在这里插入图片描述
在这里插入图片描述
依据上述流程图所示,其正常IO流程如下:

(1)client创建cluster handle;
(2)client读取配置文件;
(3)client连接上monitor,获取集群map信息;
(4)client读取IO,根据crush map算法请求对应的主OSD数据节点;
(5)主OSD数据节点同时写入另外两个副本节点数据;
(6)等待主节点以及另外两个副本节点写完数据状态;
(7)主节点及副本节点写入状态都成功后,返回给client,IO写入完成。

4、Ceph集群部署
介绍完Ceph相关概念和实现流程,在本次Ceph部署采用四台物理服务器作为Ceph集群节点进行部署。在部署Ceph集群时,需要安装相关的软件及版本如下:

Centos:release 7.4.1708(Core)
Ceph: jewel-10.2.11
Openssh-server: version 7.4
NTP

根据Ceph 官方文档中建议安装一个ceph-deploy管理节点和一个三节点的Ceph存储集群来研究Ceph的基本特性。由于资源有限,所以在解决方案中少用了一个节点,将mon.node1节点的Monitor功能迁移到admin-node节点上,所以集群结构图如下图所示:
在这里插入图片描述
Ceph分布式存储集群有三大组件组成,分为:Ceph Mointor、Ceph OSD、Ceph MDS,MDS非必须安装,只有当使用CephFS文件存储时才需要安装。因此暂时不安装MDS。

4.1 配置节点
为了方便后续安装,以及ssh方式连接各个节点,首先修改各个节点的Hostname以及配置Hosts如下:
在这里插入图片描述
需要在所有节点上都需要进行上述的配置。在配置完成以后,需要ping一下是否可以互相访问。如下图所示:
在这里插入图片描述

4.2 安装部署工具ceph-deploy
Ceph提供部署工具ceph-deploy来方便安装Ceph集群,我们只需要在ceph-deploy节点上安装即可,这里对应的就是admin-node节点。把Ceph仓库添加到ceph-deploy管理节点,然后安装ceph-deploy。根据centos7版本,安装相关依赖库,执行如下命令:

$ sudo yum install -y yum-utils \
&& sudo yum-config-manager --add-repo po https://dl.fedoraproject.org/pub/epel/7/x86_64/ \
&&/ && sudo yum install --nogpgcheck -y epel-release \
&& sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 \
&& sudo rm /etc/tc/yum.repos.d/d.d/.d/dl.fedoraproject.org*


#添加Ceph源:
$ sudo vim /etc/tc/yum.repos.d/c.d/.d/ceph.repo
[Ceph-noarch]
name=Ceph noarch packages
baseurl=rl=http://download.ceph.com/rpm-jewel/el7/noarch
ena
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=ey=https://download.ceph.com/keys/release.asc
pri
priority=1


#安装ceph-deploy
$ sudo yum update && sudo yum install ceph-deploy

4.3 安装NTP和OpenSSH
根据官方建议,在所有Ceph节点上安装NTP服务(特别时Ceph Monitor节点),以免因时钟漂移导致故障。

#yum安装ntp
sudo yum install ntp ntpdate ntp-doc

#校对系统时钟
ntpdate 0.cn.pool.ntp.org

# yum 安装 openssh
$ sudo yum install openssh-server


# 查看ssh版本
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017

4.4 创建Ceph用户
ceph-deploy工具必须以普通用户登录Ceph节点,且此用户拥有无密码使用sudo的权限,因为它需要在安装软件及配置文件的过程中,不必输入密码。官方建议所有Ceph节点上给ceph-deploy创建一个特定的用户,为了方便起见,使用cephd这个账户作为特定的用户,而且每个节点上(admin-node、node0、node1)上都需要创建该账户,并且拥有sudo权限。

# 在Ceph集群各节点进行如下操作

# 创建ceph特定用户
$ sudo useradd -d /home/cephd -m cephd
$ sudo passwd cephd


# 添加sudo 权限
$ echo "cephd ALL = (root)NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephd
$ sudo chmod 0440 /etc/sudoers.d/cephd

接下来在ceph-deploy节点(admin-node)上,切换到cephd用户,生成SSH密钥并把其公钥分发到各Ceph节点上,注意使用cephd账户生成,且提示输入密码时,直接回车,因为它需要免密码登录到各个节点。

# ceph-deploy(admin-node)上执行

# 生成ssh密钥
$ ssh-keygen


# 将公钥复制到node0节点
$ ssh-copy-id cephd@node0


# 将公钥复制到node1节点
$ ssh-copy-id cephd@node1


#测试在ceph-deploy管理节点免密码登录各个节点
$ ssh node0
$ ssh node1

测试没问题,接下来,修改ceph-deploy管理节点上的~/.ssh/config文件,这样无需每次执行ceph-deploy都要指定-usename cephd.这样做同时也简化了ssh和scp的用法。

$ vim ~/.ssh/config
Host node0
    Hostname  node0
    User  cephd

Host node1
    Hostname  node1
    User  cephd

# 禁用selinux
$ sudo vim /etc/selinux/config
SELINUX=disabled   #这里设置为disabled
SELINUXTYPE=targeted

5、Ceph存储集群搭建
经过上述一系列的预检设置后,就可以开始Ceph存储集群的搭建了。集群结构为admin-node(ceph-deploy、Monitor)、node0(osd.0)、node1(osd.1)。首先要提一下的是,如果再安装过程中出现了问题,需要重新操作的时候,需要清理搭建的这个集群的话,可以使用以下命令:

# ceph-deploy(admin-node)上执行

# 清理配置
ceph-deploy purgedata admin node0 node1
ceph-deploy forgetkeys

# 清理Ceph安装包
ceph-deploy purge admin node0 node1

好了,现在开始搭建。首先Cephd用户创建一个目录ceph-cluster并进入到该目录执行如下操作。

#创建执行目录
$ mkdir ~/ceph-cluster  &&  cd ~/ceph-cluster

#创建集群
$ ceph-deploy  new admin

在这里插入图片描述
此时,我们会发现ceph-deploy会在ceph-cluster目录下生成几个文件,ceph.conf为ceph配置文件,ceph-deploy-ceph.log为ceph-deploy日志文件,ceph.mon.keyring为ceph monitor的密钥环。
接下来,我们需要修改ceph.conf配置文件,增加副本数为2,因为我们有两个OSD节点。
在这里插入图片描述
然后,我们需要通过ceph-deploy在各个节点安装ceph

$ ceph-deploy install admin node0 node1

此过程需要等待一段时间,因为ceph-deploy会SSH登录到各node上去,依次执行安装ceph依赖的组件包。
在等待安装完毕之后,接下来需要初始化monitor节点并手机所有密钥。

$ ceph-deploy mon create-initial

执行完毕后,会在当前目录下生成一系列的密钥环,应该是各组件之间访问所需要的认证信息。
在这里插入图片描述
至此,ceph monitor已经成功启动了。接下来需要创建OSD了,OSD是最终数据存储的地方,这里我们准备了两个OSD节点,分别是osd.0和osd.1。官方建议为OSD及其日志使用独立硬盘或者分区作为存储空间,不过由于条件不具备,所以在本地磁盘上创建目录,来作为OSD的存储空间。

# ceph-deploy(admin-node)上执行
$ ssh node0
$ sudo mkdir /var/local/osd0
$ sudo chown -R ceph:ceph  /var/local/osd0
$ exit


$ ssh node1
$ sudo mkdir /var/local/osd1
$ sudo chown -R ceph:ceph /var/local/osd1
$ exit

**注意:**执行chown -R ceph:ceph操作,是将osd0和osd1目录的权限赋予ceph:ceph,否则,接下来执行ceph-deploy osd activate时会出现权限报错。

接下来,需要ceph-deploy节点执行prepare OSD操作,目的时分别在各个OSD节点上创建一些后边激活OSD需要的信息。

$ ceph-deploy osd prepare node0:/var/local/osd0 node1:/var/local/osd1

接下来需要激活 activate OSD.

$ ceph-deploy osd activate node0:/var/local/osd0 node1:/var/local/osd1

最后一步,通过ceph-deploy admin将配置文件和admin密钥同步到各个节点,以便在各个node上使用ceph命令时,无需指定monitor地址和ceph.client.admin.keyring密钥。

$ ceph-deploy admin admin node0 node1

至此,Ceph存储集群已经搭建完毕了。可以查看以下集群是否启动成功。

# 查看集群状态
$ ceph -s

# 查看集群健康状况
$ ceph health

# 查看集群OSD信息
$ ceph osd tree

通过上述的检查,目前ceph集群已经安装部署完成,并且能够正常运行。

6、CephFS文件系统创建

在部署完成ceph集群以后,需要创建CephFS文件系统。具体执行如下:

# 在admin-node(ceph-deploy) 节点操作

# 创建MDS元数据服务器
$ ceph-deploy mds create admin node0 node1

# 查看MDS状态
$ ceph mds stat

# 创建cephFS
$ ceph osd pool create cephfs_data 128

# 挂载cephFS
$ sudo mount -t ceph 10.10.13.21:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret
$ df -h

接下来,将开始后续的Harbor部署已经相关数据库的迁移等。

三、数据库迁移

根据总体技术架构,单独设置一台服务器作为Mysql数据库进行独立提供数据库服务。由于Harbor本身提供数据库服务,尤其采用高可用的话,多实例Harbor之间无法实现数据共享,因此需要独立部署一个数据库服务器,让所有Harbor实例都统一指定访问这一个数据库系统,维护同一套数据,从而保证了数据的一致性。

1、Mariadb数据库部署

$ sudo yum -y install mariadb-server
$ sudo systemctl start mariadb

2、迁移db数据
经过启动单节点Harbor服务时,已经有一部分数据存储到harbor-db数据里面去了,而且Harbor启动时也会创建好所需要的数据库、表和数据等。这里我们只需要进入Harbor-db容器中,将registry数据库dump一份,然后Copy到当前节点机器上。

# 进入harbor-db容器
$ docker exec -it <harbor-db容器ID> bash

# 备份数据到默认目录/tmp/registry.dump
$ mysqldump -u -root -p registry > registry.dump
Enter password: XXXXX
$ exit


# 退出容器,copy备份数据到当前节点机器
$ docker cp <harbor-db容器ID>:/tmp/registry.dump /home/cephd/harbor/


#登陆数据库并创建用户
$ mysql -h 10.10.13.31 -P 3306 -u root -p <db_password>
mysql> CREATE USER 'harbor'@'%' IDENTIFIED BY 'XXXXXX';
mysql> GRANT ALL ON *.* TO 'harbor'@'%';
mysql> FLUSH PRIVILEGES;

#导入数据
$ mysql -h 10.10.13.31 -P 3306 -u harbor -pXXXXX
mysql> CREATE DATABASE IF NOT EXISTS registry default charset utf8 COLLATE utf8_general_ci;
mysql> USE registry;
Database changed
mysql> source /home/cephd/harbor/registry.dump;

经过上述指令执行,就已经成功将外部数据库搞定了。剩下的工作就是对Harbor组件进行配置,从而使得Harbor在访问数据库时自动连接外部数据库。

3、修改配置使用外部db
首先,既然我们已经有外部数据库了,那么就不需要Harbor再启动harbor-db服务了,只需要配置连接外部数据即可。因此就需要删除docker-compose.yml中mysql相关配置。如下图所示:

# 删除以下mysql配置
mysql:
    image: vmware/harbor-db:v1.5.3
    container_name: harbor-db
    restart: always
    volumes:
      - /data/database:/var/lib/mysql:z
    networks:
      - harbor
    env_file:
      - ./common/config/db/env
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "mysql"

# 删除depends_on中mysql部分
depends_on:
      # - mysql # 此处删除
      - registry
      - ui
      - log

在这里插入图片描述
在这里插入图片描述
其次,还需要修改./common/config/adminserver/env配置,这里面主要存放的是一些配置信息,里面就有配置Mysql的连接信息。因为该文件是执行install.sh的时候根据./common/templates/adminserver/env配置生成的,所以即使我们修改了,也是一次性的,重新install又会覆盖掉,所以可以直接修改./common/templates/adminserver/env该文件就一劳永逸了。

# 修改 ./common/templates/adminserver/env文件
……
MYSQL_HOST=10.10.13.31
MYSQL_PORT=3306
MYSQL_USR=harbor
MYSQL_PWD=XXXXXX
MYSQL_DATABASE=registry
……
RESET=true

注意:这里一定要设置RESET=true因为只有设置了该开关,Harbor才会在启动时覆盖默认配置,启用我们配置的信息。
再次启动Harbor服务,看一下能否启动成功,能否正常连接配置的外部数据库。

# 重启 Harbor 服务
$ ./install.sh

查看 Harbor 各组件容器启动状态,harbor-db服务已经删除
在这里插入图片描述

查看UI和jobservice日志,是否连接上Mysql

# 查看UI和jobservice日志,是否连接上Mysql
$ cat /mnt/cephfs/harbor/log/ui.log | grep database

通过日志发现,Harbor已经成功启动了,并且harbor-db服务组件按照设计也没有启动,日志显示连接外部数据库也没有问题,通过浏览http://10.10.13.21(harbor部署节点)看一下之前操作的数据是否能够正常显示出来。http://10.10.13.21(harbor部署节点)看一下之前操作的数据是否能够正常显示出来。
在这里插入图片描述
发现之前创建的帐号和导入的镜像数据都可以访问。说明原先在harbor-db服务中创建的数据库和相关账户信息等内容都已经成功迁移到外部数据库中,并且启动的Harbor服务能够正常访问外部数据库。那么多节点的Harbor集群都是按照此方法创建harbor服务,并且将Harbor服务连接和访问统一的外部数据库从而维持一套统一的数据库操作,在此不再赘述。剩下的工作就是针对多节点的Harbor服务如何实现通过以的IP地址访问,在此通过Nginx方式来实现负载均衡访问。

四、Nginx负载均衡

为了保持原有的Rancher容器集群在访问原有的单节点Harbor配置不用改变,我们将原先的Harbor单节点服务器10.10.13.1作为Nginx服务器,这样通过Nginx进行访问分发到之前创建的3台Harbor服务器上,这样原有的Rancher容器集群访问地址就不需要进行修改了。

为了快速安装Nginx,采用Docker方式启动Nginx服务。首先创建配置文件,当Nginx服务启动时,就可以根据配置文件进行负载均衡。

# 创建 default.conf 配置文件
$ mkdir /root/nginx
$ vim default.conf
upstream service_harbor {
    server 10.10.13.21;
    server 10.10.13.22;
    server 10.10.13.30;
    ip_hash;
}

server {
    listen                 80;
    server_name     10.10.13.1;
    index    index.html    index.htm;
    #access_log    /var/log/nginx/host.acces.log   main;

    location  /  {
       add_header   Access-Control-Allow-Orgin  *;
       proxy_next_upstream  http_502   http_504   error timeout invalid_header;
       proxy_set_header   Host   $host;
       proxy_set_header   X-Real-IP   $remote_addr;
       proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
       proxy_pass http://10.10.13.1;
       client_max_body_size     1024m   #设置接口客户端body最大长度为1024M
     } 
     access_log /var/log/harbor.access.log;
     error_log /var/harbor.error.log;
     error_page     404         /404.html;
     error_page      500   502   503    504     /50x.html;

     location = /50x.html {
             root      /usr/share/nginx/html;
     }
}


# Docker 启动 Nginx服务, 挂载上边配置文件覆盖默认配置,并开放80端口
$ docker run --name nginx-harbor -p 80:80 -v /root/nginx/default.conf:ro -d nginx

通过浏览器访问Nginx地址 http://10.10.13.1 能否能够访问Harbor UI。
在这里插入图片描述
至此,已经创建完成了基于Ceph的高可用Harbor部署。目前的基础资源可以使用一段时间了。不过还需要有几点还需要继续改进的地方。

Mysql数据库可以通过分部署方式提供服务。比如可以通过基于容器平台的Mysql主从、PXE等方式部署Mysql分布式集群,由底层容器平台提供数据库服务;
HA高可用部署还可以参数调优的方式,可以进一步提高负载均衡性能;
底层CephFS文件系统还可以持续进行HA高可用。从现有的Ceph进行承载发现在数据访问等方便确实比原先的单节点Harbor要慢一些。

扩展:

【1】基于Harbor和Cephfs搭建高可用Docker镜像仓库集群:
https://blog.csdn.net/aixiaoyang168/article/details/78909038
【2】Ceph介绍及原理架构分享:
https://www.jianshu.com/p/cc3ece850433
【3】初试Centos7上Ceph存储集群搭建:
https://blog.csdn.net/aixiaoyang168/article/details/78788703
【4】原文链接:
https://mp.weixin.qq.com/s/2EkFip32FWpp18CQY4RMzg

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37886429/article/details/89084549

智能推荐

计算机科学技术发展史的缩影 _旺达威尔克斯-程序员宅基地

从1966年颁发图灵奖至今,已有近40个年头,共计有40多名科学家获此殊荣,其中美国学者最多,此外还有英国、瑞士、荷兰、以色列、挪威等国少数学者,也包含一名美籍华人。图灵奖颁发的历史,实际上是计算机科学技术发展史的缩影,而且从图灵奖获得者身上,我们会受到很多有益的启迪。 一。.图灵和图灵奖:1. 图灵是计算机科学技术的奠基人 阿伦 ·图灵(Alan Mathison Turing) 是英国人_旺达威尔克斯

java entryset循环_Java之Map遍历方式性能分析:ketSet 与 entrySet-程序员宅基地

keySet():将Map中所有的键存入到Set集合中。因为set具备迭代器,所以可以以迭代方式取出所有的键,再根据get方法获取每一个键对应的值,其仅能通过get()取key。entrySet(): 返回此映射中包含的映射关系的 Set 视图,格式为Set>, Map.Entry表示映射关系,迭代后可以e.getKey()、e.getValue()取key和value,返回的是Entry接..._map循环 entryset()性能

Abaqus子程序开发之旅_abaqus子程序cd-程序员宅基地

渗碳淬火变形模拟-Abaqus欢迎使用Markdown编辑器代码功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使..._abaqus子程序cd

计算机开机界面图片怎么修改,电脑开关机画面怎么更改-程序员宅基地

1、准备 要替换启动画面。系统对这个图片有比较特殊的要求,提片尺寸应为640*480像素,使用16色,文 件名为Boot.bmp,然后将准备好的Boot.bmp文件拷贝到Winxp安装的分区的的Windows目录下 (即WinXP的安装目录).如c:\\windows\\ 2、替换 把准备好的图片替换为系统的启动界面.只须修改系统的Boot.ini文件,在xp对应的启动目录后面添加参 数" /bo..._电脑启动画面修改

【MFC笔记】点击列表控件List Control标题进行排序的实现。_可排序的 list control-程序员宅基地

1、在列表窗口右键,类向导。选择IDC_LIST1(我的列表控件的ID),消息选择LVN_COLUMNCLICK。2、消息映射出现如下ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, &amp;CMyMFCDlg::OnLvnItemchangedList1)出现以下函数void CMyMFCDlg::OnColumnclickList1(NMHD..._可排序的 list control

linux漏洞利用实践笔记-程序员宅基地

遗留问题:bin/sh/下面能执行什么?????? fread 函数原型 size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ; 参 数 buffer 用于接收数据的内存地址 size 要读的每个数据项的字节数,单位是字节 cou...

随便推点

Kali 2020.1 虚拟机安装及基本配置(详细)_kali chinese setting-程序员宅基地

前言捣鼓了半天,终于安装好了kali2020.1,也做了个kali启动U盘。2020.1版本是kali开启本十年的首发,新版本有如下几个特点:默认用户不再是root,即非根kali的安装镜像减少简化,仅有Installer,Live,NetHunter,ARMNetHunter变为Rootless主题和undercover(高仿win10)的改进更多新的工具此外,不再支持pyth..._kali chinese setting

MB/s与Mbit/s的区别!!!_48mbit/s-程序员宅基地

数据传输率的单位一般采用MB/s或Mbit/s,尤其在内部数据传输率上官方数据中更多的采用Mbit/s为单位。此处有必要讲解一下两个单位二者之间的差异: MB/s的含义是兆字节每秒,Mbit/s的含义是兆比特每秒,前者是指每秒传输的字节数量,后者是指每秒传输的比特位数。MB/s中的B字母是Byte的含义,虽然与Mbit/s中的bit翻译一样,都是比特,也都是数据量度单位,但二者是完全不同的。Byte是字节数,bit是位数,在计算机中每八位为一字节,也就是1By_48mbit/s

shell获取日期(昨天,明天,上月,下月)-程序员宅基地

今天sh-4.1$ echo `date +%Y-%m-%d`2016-08-17昨天sh-4.1$ echo `date -d "last day" +%Y-%m-%d`2016-08-16明天sh-4.1$ echo `date -d "next day" +%Y-%m-%d`2016-08-18本月sh-4.1$ echo `date ...

关于时间格式 GMT,UTC,CST,ISO_gmt时间格式_githubcurry的博客-程序员宅基地

GMT:格林尼治所在地的标准时间UTC:协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。中国大陆采用ISO 8601-1988的《数据元和交换格式信息交换日期和时间表示法》(GB/T 7408-1994)称之为国际协调时间,代替原来的GB/T 7408-1994;中国台湾采用CNS 7648的《资料元及交换格式–资讯交换–日期及时间的表示法》,称._gmt时间格式

bzoj1084: [SCOI2005]最大子矩阵(dp)-程序员宅基地

1084: [SCOI2005]最大子矩阵Time Limit:10 SecMemory Limit:162 MBSubmit:2865Solved:1428[Submit][Status][Discuss]Description  这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。I...

Android 通过AudioRecord实时录音并转AAC-程序员宅基地

public class AudioEncoder { private MediaCodec mediaCodec; private BufferedOutputStream outputStream; private String mediaType = "OMX.google.