Quantcast
Channel: Kunpeng Fan's Blog
Viewing all 57 articles
Browse latest View live

Install OpenStack by Kolla Ansible and Get LoadBalancer IP

$
0
0

安装

指导文档:https://docs.openstack.org/kolla-ansible/latest/user/quickstart.html

CentOS 7.3 多节点Kolla安装 http://www.chenshake.com/kolla-centos-over-more-than-7-3-node-installation/

  • fatal: [localhost]: FAILED! => {“changed”: false, “failed”: true, “msg”: “Unknown error message: Tag 4.0.1 not found in repository docker.io/kolla/ubuntu-binary-kolla-toolbox”}. → 修改里面的openstack-version,从auto改为4.0.0。这是因为4.0.1没有push到docker hubs上面?
  • deploy后,打开dashboard可以,但是static file都返回404。→ cleanup-containers & cleanup-host in /usr/local/share/kolla-ansible/tools. 这是清空重新部署的常用命令。
  • fatal: [localhost]: FAILED! => {"failed": true, "msg": "The conditional check ''' not in ''' failed. The error was: Invalid conditional detected: EOL while scanning string literal (<unknown>, line 1)\n\nThe error appears to have been in '/usr/local/share/kolla-ansible/ansible/roles/rabbitmq/tasks/precheck.yml': line 54, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- fail: msg=\"Hostname has to resolve to IP address of api_interface\"\n ^ here\n"}→ 我看安装程序已经设置hostname的ip为api_interface的ip。
  • Docker will not be able to stop the nova_libvirt container with those running. → 自己create的nova instance默认是用libvirt(因为我的host机器不是vm),shutdown后就可以运行cleanup-containers了。
  • Cannot uninstall ‘PyYAML’. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall. → pip install pip==8.1.2
  • /usr/share/kolla-ansible/init-runonce 文件里面 EXT_NET_CIDR这个是设置浮动IP的范围,必须设置好,这样运行 init-runonce 后,绑定 floating ip可以直接assign外网ip了,否则又得重新部署。http://www.chenshake.com/kolla-installation/ 这个里面有谈到。里面说 这个其实是从 neutron_external_interface 网卡访问的,如何确认?因为在 OpenWrt 是看不到的。arp -an里面返回对应 IP 地址是 fa:16:3e:62:fb:ed,私营 mac,看了下也不是 vm nic mac,ui 里面看了下,是 network:router_gateway public1 的 Mac 地址。 这次忘了设置,修改再次运行时,报错 This tool should only be run once per deployment. 不想重新运行,按照这里 https://www.howtoing.com/openstack-networking-guide 在界面上创建网络。But notebook can’t ping floating ip & vm can’t ping 192.168.51.1. yum install openswitch then run ovs-vsctl show, otherwise command not found. No idea. Re-deploy. tools/cleanup-containers & tools/cleanup-host as https://docs.openstack.org/kolla-ansible/latest/user/operating-kolla.html. cmd is in /usr/share/kolla-ansible/tools.

VM ssh 免密码登录必须要在 root 用户下才能进,密钥在root用户下?是的,安装用的是 root 账户。 部署好后,默认的就可以访问 horizon,在 network_interface 上面,admin password is in /etc/kolla/passwords.yml:keystone_admin_password.

安装好后,很多服务比如 swift 没有安装。这个我得自己弄么?Just edit /etc/kolla/globals.yml and enable serivce like cinder. Then kolla-ansible deploy -i all-in-one again. Then OK. 今天又重新装了遍,安装好后,发现horizon没有装(现在默认不装了?),修改global.yaml,enable后重新deploy,居然也没有错,然后可以访问horizon。 可以额外添加的服务 https://github.com/openstack/kolla-ansible/blob/master/README.rst#openstack-services 注释里面的值就是默认值。比如默认打开了 horizon, heat。但是我看没有 heat 这个命令,仿照 openstackclient 安装方法 pip install python-heatclient,但是运行时报警:WARNING (shell) “heat stack-list” is deprecated, please use “openstack stack list” instead。

init-runonce 会创建很多初始化的资源,比如网络路由、cirros 磁盘镜像、虚机类型,但是只能运行一次。

Magnum

既然已经有了:enable_horizon_magnum & enable_magnum,启用,然后 kolla-ansible deploy,是很方便,就是似乎每次添加一个组件都挺耗时。 刷新后界面上已经有了新的菜单项 container Infra,但是会出错误消息:Error: Unable to retrieve the cluster templates. Error: Unable to retrieve the stats. 客户端用命令行安装 pip install -U python-magnumclient,这个是想当然猜出来的(现在已经用 openstack coe来代替 magnum 命令了。)。magnum cluster-list报错:

ERROR: 'NoneType' object has no attribute 'replace' (HTTP 500) (Request-ID: req-6c01fbcf-f883-41e3-a7f9-cecf92c7cf34)

这里同样问题,说是 GitHub 已经 fix 了。但是我看 /etc/kolla/magnum-conductor 下面还是用的 www_authenticate_uri,什么情况。直接跑到 /usr/share/kolla-ansible/ansible/roles/magnum/templates 下修改 magnum.conf.j2,将 www_authenticate_uri 改为 auth_uri,原来上面的 /etc/kolla 都是根据这个来产生的。这个是已知 bug https://bugs.launchpad.net/ubuntu/+source/magnum/+bug/1793813

重新 deploy 后可以看到/etc/kolla 下面被修改了,但是 docker ps 显示对应镜像还是 半小时前的,所以错误还是一样,如何重新生成呢?清空重新部署。现在magnum ui & cli 都可以运行不出错。这个重新部署很要命,有时可以,有时要清空然后重新部署,有地方说重启全部容器就可以。

然后在界面创建 cluster template,这比命令行方便。但是出现错误(错误都只在 http response 里面才能看到):Cluster type (vm, None, kubernetes) not supported (HTTP 400)这个错误在命令行下可以看到,所以 UI 做的不行还不如命令行。这种 hello world 一定要能测试通过,否则就失去了 UI 快速上手的意义。 上面错误在这里解释很清楚,原因在于我的 os image 必须带一个属性 os_distro标明其 linux 发行名,属性可以在 ui 里面的 image meta 加(rocky 只能命令行,UI 会报错)。现在只支持 fedora-atomic, coreos,看来 magnum 知道 k8s 配置对操作系统很敏感。

openstack image set --property os_distro=fedora-atomic foo

集群创建中一直报错:

Service cinder is not available for resource type Magnum::Optional::Cinder::Volume, reason: cinder volumev3 endpoint is not in service catalog.

这个 Cinder 是必须的么?开启 enable_cinder,重新 deploy,这个不需要任何 backend?先这样再说。 创建集群还是出错,这次用 cli 查看,因为 ui 又连不上。

magnum cluster-show fantest
Resource CREATE failed: resources[0]: resources.kube_masters.Property error: resources.docker_volume.properties.volume_type: Error validating value '': The VolumeType () could not be found.

修改模板 magnum cluster-template-update fedora add volume_driver=cinder,还是一样。我在界面创建卷的时候也看到 No Volume type。openstack volume type list也为空。 好吧,enable_ceph,重新 deploy,没看到啥变化,只是多了两个 ceph 容器。手工创建一个 volume type,然后创建一个该 type 的 volume,失败。看来部署 Cehp 没有那么简单。

下面 Ceph 配置好后,回到这里。现在可以在界面成功创建一个 volume,但是创建 k8s 集群时依然同样错误。这里说缺少一个default_docker_volume_type字段,docker exec -it magnum_conductor进去后直接修改,然后 restart container,后来发现 restart 后值丢失,原来要修改 /etc/kolla/magnum-*下面的对应文件,我猜容器是用 mount /etc 目录的方式来访问配置,这种操作如果放在 k8s 下面做就简单方便很多。这个值原始定义在 /usr/share/kolla-ansible/ansible/roles/magnum/defaults/main.yml中。这个 volume type 没有绑定特定的 volume backend,可能被当做为默认类型。

现在开始漫长的创建 k8s 集群了。然后居然就可以了,一个 master,两个 minion,没有出现任何错误。看来已经颇为稳定了。

尝试创建一个带 load balance 功能的 k8s 集群,失败报错:

ERROR: ResourceTypeUnavailable: : resources.api_lb<file:///var/lib/kolla/venv/lib/python2.7/site-packages/magnum/drivers/common/templates/lb.yaml>: : HEAT-E99001 Service neutron is not available for resource type Magnum::Optional::Neutron::LBaaS::LoadBalancer, reason: Required extension lbaasv2 in neutron service is not available.

好吧,在 kolla 中打开 enable_neutron_lbaas,重新部署。这每次修改 /etc/kolla/globals.yml都没有记录,到最后也不知道自己做了哪些修改。

这次重新部署 UI 还是出现浏览器 Angular JavaScript 错误:

Error: [$injector:nomod] Module 'horizon.app' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

这个问题太常见,每次都在添加一个新的 horizon 模块/plugin之后发生,清空再重新部署好了。按理说 kolla/centos-source-horizon:queens是 binary 的,不会重新构建啊。主 JS 为 http://192.168.51.147/static/dashboard/js/3bf910c7ae4c.js,记下看看这个是否会变。bash 到 horizon 容器中,发现几个 js 文件都是刚刚才产生出来的。暂时不知道办法,清除后重新部署,漫长等待后终于成功。

后来发现创建集群模板那里的 Master LB(–master-lb-enabled) 其实是多 master 的 load balance,和 k8s 里面的 Service LoadBalance 不同。进入 master 节点,查看 /etc/kubernetes 各个配置,都没有--cloud-provider=openstackcloud_provider_enabled这个默认不是为 true 么?但是似乎是 Rocky 才有的新功能。我在 magnum-conductor 容器里面查看 configure-kubernetes-master.sh 文件,里面没有考虑到新的标志位。

if [ -n "$TRUST_ID" ]; then
    KUBE_API_ARGS="$KUBE_API_ARGS --cloud-config=/etc/kubernetes/kube_openstack__
config --cloud-provider=openstack"
fi

这个 shell 脚本其实是由 magnum 传给 heat,在 fedora atomic 上面运行。从 magnum 源代码看,这个 trust_id 贯穿整个流程,为空为什么在创建集群的时候就报错?troubleshooting这里有讲到 Trustee for cluster 的问题,折腾几次,发现要修改 /etc/kolla/magnum-*/magnum.conf 里面的 cluster_user_trust为 True。不知道这个为什么要默认设置为 false。为了固化配置,修改 /etc/kolla/globals.yml,加上 enable_cluster_user_trust: "yes"

然后把集群里面已经装好的 dashboard service 改为 LoadBalancer 类型的,稍等片刻就能拿到 external IP 了。也试了下 Cinder StorageClass,简单的声明,没有 IP 配置之类,测试成功。有了 cloud provider 获取外部资源确实方便。

OpenStack 到此一游。

openstack-k8s-network-topology

这个网络拓扑可以看到集群时由 1 个 master、2 个 minion 节点组成,属于 private 子网,然后通过一个 router 连接外网。private 子网的端口(Ports)除了 3 个节点,还有 DHCP,和 load balancer。

在 horizon 里面,外网或者内网网络是一个 IP 地址池(子网络),通过路由来连接两个网络,图中路由通过两个接口来连接两个网络。而浮动 ip 是外网子网里面的一个 ip,其和内网子网的某个 ip 做了绑定,这样就能通过浮动 ip 直接访问内网虚拟机。

queens 创建出来 k8s 默认版本是 1.9.3,rocky 的是 1.11.1。暂时没有找到配置 k8s 版本的地方。

k8s 集群删除失败的问题

一直在删除中,重启服务器后 DELETE_FAILED。进入容器查看 /var/log/kolla/magnum/magnum-condductor.log:

ERROR magnum.drivers.heat.driver [req-b693] Cluster error, stack status: DELETE_FAILED, stack_id: c8789bac-6957-48f1-8dd7-94124073c996, reason: Resource DELETE failed: Conflict: resources.network.resources.extrouter_inside: Router interface for subnet 50b433da-d225-413f-89b8-56d94acd7bb0 on router fd2120d9-4599-4a0a-acb0-c237d5bbc126 cannot be deleted, as it is required by one or more floating IPs.

查看 floating IP,只有一个 Dashboard load balance 的还没有删除。浮动 IP 手工释放,但是 load balance 挺难删除,相互依赖,摸索后发现最后删除次序为:pool's healthmonitor —> pool —> listener -> LB -> k8s network

Magnum 是如何知道这个浮动 ip 资源是属于 k8s 集群(这里叫stack)的呢?并没有 db 保存这些数据啊?还是 heat 做的?为什么创建集群时创建的 etcd & api LB 都可以删除,dashboard 的却不能?资源都属于一个完整的 stack 范围,这个 stack 和 AWS 的是一样的。

openstack stack list
openstack stack resource list foo

全部都在这里,magnum 只是一个支持多集群的工具而已。更多命令看 heat 文档。创建好集群后,各资源为:

resource_namephysical_resource_idresource_typeresource_statusupdated_time
etcd_lb0fe47743-fa07-488d-ad2a-4975b2f18825file:///usr/lib/python2.7/site-packages/magnum/drivers/common/templates/lb.yamlCREATE_COMPLETE2018-12-10T03:38:08Z
kube_masters51ff11de-11f8-47c2-aa99-9c01a223e36fOS::Heat::ResourceGroupCREATE_COMPLETE2018-12-10T03:38:07Z
network0d8ebd19-fad5-4be6-bcf8-121a81a73f31file:///usr/lib/python2.7/site-packages/magnum/drivers/common/templates/network.yamlCREATE_COMPLETE2018-12-10T03:38:08Z
api_lbce7a4d96-0f13-4fa2-8b5f-5f204aa5330ffile:///usr/lib/python2.7/site-packages/magnum/drivers/common/templates/lb.yamlCREATE_COMPLETE2018-12-10T03:38:08Z
secgroup_kube_minion97c19df9-c9dc-4466-9c01-463aa3c19932OS::Neutron::SecurityGroupCREATE_COMPLETE2018-12-10T03:38:07Z
nodes_server_group73e54288-535d-4564-b46c-ceb2adc18e7dOS::Nova::ServerGroupCREATE_COMPLETE2018-12-10T03:38:08Z
secgroup_kube_mastercf148deb-ffd2-474e-aecf-6f913f7f0802OS::Neutron::SecurityGroupCREATE_COMPLETE2018-12-10T03:38:07Z
kube_minions8eb65593-bb46-40dc-b98a-90b07878035fOS::Heat::ResourceGroupCREATE_COMPLETE2018-12-10T03:38:07Z
api_address_floating_switch06644da0-8e50-4512-9e97-458263924be9Magnum::FloatingIPAddressSwitcherCREATE_COMPLETE2018-12-10T03:38:07Z
api_address_lb_switcha941f98d-a2fe-4077-a375-5fdde66982f8Magnum::ApiGatewaySwitcherCREATE_COMPLETE2018-12-10T03:38:07Z
etcd_address_lb_switchf544d40b-6f4a-46be-a29d-6f63e35aac7fMagnum::ApiGatewaySwitcherCREATE_COMPLETE2018-12-10T03:38:07Z

可以看到有 api 和 etcd 的 LB。手工设置 Dashboard Service Type 为 LoadBalancer 后,上面列表并没有改变,问题可能出现在这里,看上去只有纳入 heat 管理的资源才会被正确的删除。magnum 创建了 subnet,所有的 Ports (node & LB)都属于这个子网,删除这个网络必须先移除所有的 Ports,k8s 创建 LB (直接调用 OpenStack API)的 magnum 觉得不属于自己管理,所以就不会主动删除,这导致整个网络也无法删除。上面表格里面有个资源类型,比如 LB 的/usr/lib/python2.7/site-packages/magnum/drivers/common/templates/lb.yaml,可能 magnum(或者 heat)严格按照这个来进行创建和删除,这有点像 k8s。

删除上面集群,openstack stack resource list foo变为:

resource_namephysical_resource_idresource_typeresource_statusupdated_time
network0d8ebd19-fad5-4be6-bcf8-121a81a73f31file:///usr/lib/python2.7/site-packages/magnum/drivers/common/templates/network.yamlDELETE_FAILED2018-12-10T03:38:08Z

其他的都已经删除。heat event-list mystack也可以查看删除失败原因,其实上面所有信息在 Horizon Orchestration 界面上看得更清楚,😄

openstack-heat-stack-graph

这个可视化编排工具和 AWS 的就非常像了,到底能起多大作用就不得而知了。

疑问:块设备(cinder)是属于哪个资源类型?也会存在同样问题。一种解决办法当 k8s 通过 cloud provider 在 OpenStack 中创建资源时,填入一个新的字段:k8s cluster id,删除时根据 id 找到 lb 和 volume,全部删除。具体查看 openstack_loadbalancer.go , openstack_volumes.gomagnum/api/controllers/v1/cluster.pydelete 方法。更完美的方法应该是 Cloud Provider 调用 heat 来创建资源(失去了通用性),也就是对 stack 进行操作。不然为什么自动创建的 etcd & api LB 可以删除呢?但是 heat 是根据 template 来创建 stack,所以修改可能没那么容易。

所以这里就要看 heat 的设计理念了。heat 创建 stack 时候,需要传入 template-file 和 environment-file,后者其实就是 template 里面定义的各种参数(这种结构和 Helm 很类似)。template 描述了各种预定义资源,那么当 stack 运行起来后,其自生(应用内部)创建的资源是否属于 stack 管理范围呢?这是个很有意思的取舍。创建集群后,如果使用 magnum 动态扩容 - 添加一个新节点,这个节点在 heat 管理范围内么?AWS 是如何处理的?

使用命令 magnum cluster-update foo replace node_count=3添加一个节点后,openstack stack resource show foo kube_minions可以在 links属性下面看到有 3 个节点,horizon UI 也可以查看。我猜想删除集群时这个新的节点也可以被删除。

这里添加节点有个小问题:heat 已经显示 Update Complete,k8s 运行正常,但是 magnum 还是 UPDATE_IN_PROGRESS。

Ceph

感觉相关依赖没有做好,后面加 Ceph,前面创建好的 Cinder 容器没有重建,容器里面的配置都没有修改,这怎么能行呢?清除后重建集群。登录到后发现 cinder-api 下面还是没有 /etc/ceph/ceph.conf 文件,cinder-volume 有,ceph status 无法登录。ceph-mgr 容器运行 ceph osd pool ls返回四个已经创建好的 pool:images, volumes, backups, vms。ceph -s返回 0 kB used, 0 kB / 0 kB avail。日。

https://docs.openstack.org/kolla-ansible/latest/reference/storage/ceph-guide.html 这里有详细配置,原来这个需要给硬盘加标签,然后 kolla 才会把这个硬盘分配给 Ceph。我只运行:

parted /dev/sdb -s -- mklabel gpt mkpart KOLLA_CEPH_OSD_BOOTSTRAP 1 -1

还是不行,cinder service-list显示 cinder-volume ms1@rbd-1 是 down 的状态。但是我看 kolla/centos-source-cinder-volume:rocky 这个容器已经起来。现在问题是几种方法都没有在 docker ps 中看到 ceph-osd/ceph-rbd 容器。再次细看文档:all-in-one 情况下,需要设置 osd pool default size = 1,但是没有 /etc/kolla/config/ceph.conf 这个文件,修改 /usr/share/kolla-ansible/ansible/roles/ceph/templates/ceph.conf.j2,重新 deploy 后已经能看到 /etc/kolla/ceph-osd/ceph.conf 里面有我加的配置。但是还是不行,容量还是为 0 ,/dev/sdb 根本没有考虑进去。 换成 Queens 版本,因为这个没有 Bluestore,也不知道是不是这个原因。再不行得看 ansible 代码了。 http://docs.ceph.com/docs/master/start/quick-ceph-deploy/ 这里创建 rbd 都是直接命令行,没有放到配置里面。 不行,/usr/share/kolla-ansible/ansible/roles/ceph/tasks/start_osds.yml 创建 osd 的脚本,但是如何知道运行结果呢?kolla-ansible 运行只输出到屏幕,没有地方看全部日志,可能我没找到。启用 verbose,使用命令

kolla-ansible ...  -v | tee log

果然发现:

TASK [ceph : Looking up disks to bootstrap for Ceph OSDs]  *********
ok: [localhost] => {"changed": false, "cmd": ["docker", "exec", "-t", "kolla_toolbox", "sudo", "-E", "ansible", "localhost", "-m", "find_disks", "-a", "partition_name=KOLLA_CEPH_OSD_BOOTSTRAP_BS match_mode='prefix' use_udev=True"], "delta": "0:00:01.454122", "end": "2018-11-27 21:46:51.368490", "failed_when_result": false, "rc": 0, "start": "2018-11-27 21:46:49.914368", "stderr": "", "stderr_lines": [], "stdout": "localhost | SUCCESS => {\r\n    \"changed\": false, \r\n    \"disks\": \"[]\"\r\n}", "stdout_lines": ["localhost | SUCCESS => {", "    \"changed\": false, ", "    \"disks\": \"[]\"", "}"]}

返回空数组,这是没有找到合适的磁盘了?KOLLA_CEPH_OSD_BOOTSTRAP_BS为什么是这个?这个是 bluestore,应该是 KOLLA_CEPH_OSD_BOOTSTRAP。这个分区名字是在 /usr/share/kolla-ansible/ansible/roles/ceph/defaults/main.yml 中决定的,接着由 ceph_osd_store_type 决定,在 /usr/share/kolla-ansible/ansible/group_vars/all.yml 这个默认是 bluestore。好的,我在 /etc/kolla/globals.yml 加上 ceph_osd_store_type: “filestore”。重新发布,现在会停在出错的地方,错误很隐晦,手工在 kolla-toolbox container 里面运行:

ansible localhost -m find_disks -a "partition_name=KOLLA_CEPH_OSD_BOOTSTRAP match_mode='prefix' use_udev=True”

重现错误:

localhost | FAILED! => {
    "changed": false, 
    "failed": true, 
    "msg": "UnicodeDecodeError('ascii', '\\xe6\\x96\\xb0\\xe5\\x8a\\xa0\\xe5\\x8d\\xb7', 0, 1, 'ordinal not in range(128)')"
}

有对应磁盘反而报错,似乎是字符集的问题,问题是这个看不懂。下载源码 find_disk.py,稍作修改,本地运行,发现磁盘有个 LABEL 新加卷,导致出错。parted /dev/sdb这个命令默认就会产生这个 label。折腾各种命令来修改 label,最后发现这个『新加卷』是原来的 Windows 磁盘,用的 parted 命令并不会删除旧有分区。mkfs.ext4 格式化之 或者使用 parted 交互式方式删除分区。

另外一个问题:

TASK [ceph : Bootstrapping Ceph OSDs] failed: [localhost] (item=[0, {u'fs_uuid': u'', u'journal_device': u'/dev/sdb', u'journal': u'/dev/sdb2', u'partition': u'/dev/sdb1', u'partition_num': u'1', u'journal_num': 2, u'fs_label': u'', u'device': u'/dev/sdb', u'partition_label': u'KOLLA_CEPH_OSD_BOOTSTRAP', u'external_journal': False}]) => {"changed": true, "item": [0, {"device": "/dev/sdb", "external_journal": false, "fs_label": "", "fs_uuid": "", "journal": "/dev/sdb2", "journal_device": "/dev/sdb", "journal_num": 2, "partition": "/dev/sdb1", "partition_label": "KOLLA_CEPH_OSD_BOOTSTRAP", "partition_num": "1"}], "msg": "Container exited with non-zero return code 1"}

这个 bootstrap 容器运行后退出,docker ps --all才能看到。docker logs bootstrap_osd_0日志里面有:

GPT data structures destroyed! You may now partition the disk using fdisk orother utilities.
Warning: The kernel is still using the old partition table.The new table will be used at the next reboot.
mkfs.xfs: cannot open /dev/sdb1: Device or resource busy

所以每次清空部署后,最好重启服务器。

现在 OK 了!检查最后成功状态:

[root@ms1 fan]# lsblk /dev/sdb
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   0 238.5G  0 disk 
├─sdb1   8:17   0 233.5G  0 part /var/lib/ceph/osd/6fce7aad-0b42-4a0e-bdca-8bb7c9ed7135
└─sdb2   8:18   0     5G  0 part 

sdb1 下面都是散放的文件,这个就是 filestore 的意思?现在可以看到有个 kolla/centos-source-ceph-osd:queens 容器在运行。

安装好后,磁盘 label KOLLA_CEPH_OSD_BOOTSTRAP 会被去掉,所以每次清空再次部署时需要自己加上。

Kolla集成外接ceph存储集成到我原来创建好的 Rook Ceph 上去?滑稽。

启用 ceph 后,kolla 也会安装 ceph dashboard,也就是 ceph-mgr docker image,一个 web 的监控 UI。容器映射端口是多少呢?奇怪的是用 docker port返回空,netstat -tlnp才找到端口为 7000。

默认 OpenStack 会创建的 ceph pool 有 images, volumes, backups, vms。images 保持 glance 里面的 Linux Cloud Image,和 glance image-list返回一样,raw 或者 qcow2 格式。vms 放 vm 节点的启动磁盘(这个不知道如何用命令查看)。volumes 则是 vm 节点的扩展磁盘,和 openstack volume list返回一样。

Log

Central Logging原来已经有这个东西。kolla ansible 的部署日志没法记录吧,那时候日志服务还没好。

Kibana 没法起来:/usr/local/bin/kolla_start: line 18: /usr/share/kibana/bin/kibana: No such file or directory这什么鬼,好吧,binary 镜像没法自己改吧。自己下载 Kibana 本地运行个,毕竟只是个 UI 端,还好 Elasticsearch 能工作。修改配置让其后端连接 kolla 创建好的 Elasticsearch。启动出现错误:Status changed from yellow to red - This version of Kibana requires Elasticsearch v6.5.1 on all nodes. I found the following incompatible nodes in your cluster: v2.4.6 @ 192.168.51.147:9200 (192.168.51.147)版本不兼容啊,查看其兼容性 matrix, 下载对应 4.6.4 版本。

现在 Kibana 里面是可以看到一堆 log 了,但是对于 magnum,只有 magnum-api,没有 magnum-conductor。后来发现要在 magum.conf 里面设置 debug=True。

虚拟机一直是 scheduling 状态

https://docs.openstack.org/kolla-ansible/latest/user/troubleshooting.html 这里有调试方法,用 docker exec -it 进入 shell,cat /var/log/kolla/nova/nova-scheduler.log,

AMQP server on 192.168.51.247:5672 is unreachable: [Errno 111] ECONNREFUSED. Trying again in 6 seconds. Client port: None: error: [Errno 111] ECONNREFUSED

界面显示服务 nova-scheduler down 状态。nova service-list 也显示为 down。 https://ask.openstack.org/en/question/54526/amqp-server-on-1000115672-is-unreachable/ 同样问题 docker ps 返回里面有 kolla/centos-binary-rabbitmq:queens 这个 docker 运作中,shell 进去,rabbitmqctl status,lsof -i :5672 看到已经有很多连接了。不对,上面unreachable日志是昨天的。docker ps -a 返回所有 docker,发现 kolla/centos-binary-nova-scheduler:queens 已经退出了。

    b63907bcea6e        kolla/centos-binary-nova-scheduler:queens              "kolla_start"       16 hours ago        Exited (0) 13 hours ago                       nova_scheduler

为什么是 13 小时前,几天上午我开机的时候没有尝试重启这个 docker?我自己运行 docker start nova_scheduler (不能 start id),可以起来,然后就一切好了。(我有尝试关掉防火墙和 selinux,应该没有关系),有的说这个和 NTP 和启动依赖有关系,这个依赖 mq。

Docker ps 有返回 kolla/centos-binary-horizon:queens,这里才知道安装的是 queens 版本。命令行用 —version 返回的都是数字。

ps aux里面有返回 qemu-kvm 进程,为什么公司机器的就没有呢?难到是因为我用的 qcow2 格式,可以该换 raw 格式,可能性不大。

还有虚机运行的磁盘文件是直接放在宿主机上面:-drive file=/var/lib/nova/instances/78687529-9333-429f-a184-9a13c725fcca/disk,format=qcow2,如果使用了 ceph,会放到 ceph 上面?

部署到 Neutron 时候控制台挂起

一次成功部署后,重启机器,主端口连接不上。清空重新部署,运行到 Running Neutron bootstrap container,控制台 ssh 网络断开,TTY console 登录查看最后日志为:

TASK [neutron : Running Neutron bootstrap container] ******************************************************************************************************
changed: [localhost -> localhost] => {"changed": true, "result": false}

TASK [neutron : Running Neutron lbaas bootstrap container] ************************************************************************************************
fatal: [localhost -> localhost]: FAILED! => {"changed": true, "msg": "'Traceback (most recent call last):\\n  File \"/tmp/ansible_kolla_docker_payload_e0UJ1B/__main__.py\", line 874, in main\\n    result = bool(getattr(dw, module.params.get(\\'action\\'))())\\n  File \"/tmp/ansible_kolla_docker_payload_e0UJ1B/__main__.py\", line 666, in start_container\\n    self.pull_image()\\n  File \"/tmp/ansible_kolla_docker_payload_e0UJ1B/__main__.py\", line 507, in pull_image\\n    repository=image, tag=tag, stream=True\\n  File \"/usr/lib/python2.7/site-packages/docker/api/image.py\", line 400, in pull\\n    self._raise_for_status(response)\\n  File \"/usr/lib/python2.7/site-packages/docker/api/client.py\", line 248, in _raise_for_status\\n    raise create_api_error_from_http_exception(e)\\n  File \"/usr/lib/python2.7/site-packages/docker/errors.py\", line 31, in create_api_error_from_http_exception\\n    raise cls(e, response=response, explanation=explanation)\\nAPIError: 500 Server Error: Internal Server Error (\"Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)\")\\n'"}

NO MORE HOSTS LEFT ****************************************************************************************************************************************
	to retry, use: --limit @/usr/share/kolla-ansible/ansible/site.retry

PLAY RECAP ************************************************************************************************************************************************
localhost                  : ok=311  changed=175  unreachable=0    failed=1 

禁用掉 lbaas 也没用。因为是在部署 neutron,所以应该是网络配置出现问题导致后面没法拉镜像。尴尬。为什么不先下载所有镜像然后开始部署?干净 centos 部署没有问题,几次之后就会出现这个问题。有 iptables 之类的残留?这里这里都有讨论这个问题,似乎 kolla 会创建一个 br-ex 网桥来做外部通信。后来尝试在宿主机中禁用 neutron_external_interface,也就是关掉 DHCP 获取 IP,问题消失,😂

每次清除集群后最好重启下服务器,因为有些 network interface like qbr, qvo, qvb 没有清理干净。

Rocky 创建 k8s 集群失败

CREATE aborted (Task create from SoftwareDeployment "enable_cert_manager_api_deployment" Stack "cai-7fzsht5k5dzv-kube_masters-zmbdkz4oxa5s-0-4zytyo6ftz4h" [3bb2ae99-ee48-41e7-b4d7-a38c93a2da41] Timed out)在 master 节点上面运行 journalctl | grep runc

novalocal runc[2745]: E1211 03:57:42.946464       1 reflector.go:205] k8s.io/kubernetes/cmd/kube-scheduler/app/server.go:176: Failed to list *v1.Pod: Get http://127.0.0.1:8080/api/v1/pods?fieldSelector=status.phase%21%3DFailed%2Cstatus.phase%21%3DSucceeded&limit=500&resourceVersion=0: dial tcp 127.0.0.1:8080: connect: connection refused
novalocal runc[2849]: W1211 03:57:43.388424       1 proxier.go:469] Failed to load kernel module ip_vs with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules
novalocal runc[2468]: Source [heat] Unavailable.
novalocal runc[2406]: /var/lib/os-collect-config/local-data not found. Skipping
novalocal runc[2468]: publicURL endpoint for orchestration service in null region not found

如此之多错误?运行 runc list可以看到 atomic 上面 heat 是作为一个容器运行在 master node 上面,查看 log 用 journalctl --no-pager -u heat-container-agent。对于 publicURL endpoint for orchestration service in null region not found 的问题,这里有解释,我本地试了下,openstack endpoint list包含 heat,Service Type:orchestration,openstack service list里面也包含 heat,难道是因为 RegionOne 没有传给 heat agent?(/etc/kolla/magnum-conductor/magnum.conf 里面已经定义了 RegionOne)可能因为 heat 依赖 keystone 来找到所有的注册信息。在 master node 上面 cat /var/run/heat-config/heat-config,返回为 [],空数组,正常是一大堆 JSON。从 null regin看,多半还是配置问题。费劲转为开发模式后还是一样问题😂

Heat 创建一个虚拟机,参数如何传递?cloud-init 还是 ssh?

heat-container-agent 容器会向 heat 报告信息。具体看 https://github.com/openstack/magnum/blob/master/magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml,里面有 start_container_agent。注意里面的 write_heat_params,传入大量参数,写入到 /etc/sysconfig/heat-params,里面包含 REGION_NAME="RegionOne",按我理解 heat 拿到 keystone 地址后调用 api,找到 orchestration service 地址,现在看来数据都在。heat-config是如何产生出来的呢?

heat-engine log,里面可以看到一个个 task 的运行日志:

Task create from ResourceGroup "kube_masters" Stack "tong-wvfftolmtniv" [3d0dae3d-5cce-4e47-976b-400633f92d94] timed out
Task create from SoftwareDeployment "enable_cert_manager_api_deployment" Stack "tong-wvfftolmtniv-kube_masters-4pu45beuteve-0-vsoxums4xz6k" [9f7f80df-9fbd-4624-a029-55b58391dc50] timed out

后面一个 task 属于前面一个。 https://github.com/openstack/magnum/blob/master/magnum/drivers/common/image/heat-container-agent/scripts/heat-config-notify里面有获取 orchestration endpoint 的代码:

ks = ksclient.Client(
    auth_url=iv['deploy_auth_url'],
    user_id=iv['deploy_user_id'],
    password=iv['deploy_password'],
    project_id=iv['deploy_project_id'])
endpoint = ks.service_catalog.url_for(
    service_type='messaging', endpoint_type='publicURL',
    region_name=iv.get('deploy_region_name'))

这个方法由 55-heat-config调用,输入为两个文件,上面的大量参数比如 deploy_auth_url都由 heat-config 传递,其格式为:

[{"inputs":[{"type":"String","name":"deploy_server_id","value":"3fb12f6a-cc17-4478-8a2f-ce4cca0bfb8b","description":"ID of the server being deployed to"}],"group":"script","name":"kong-ob42euoeumne-kube_masters-hfnvgsn727tt-0-k8s_keystone_service-nzkdrrgtemm5","outputs":[],"creation_time":"2018-12-10T08:11:27","options":{},"config":"#!/bin/sh\n\n. /etc/sysconfig/heat-params\nexport PATH=$PATH:/var...."}]

master node 上面的 heat agent 容器收到这个请求后执行任务。不是,agent 只是回报 heat 部署进展。因为即使部署失败,我看到 enable_services 还是被触发了。

根据这里的提示,查看 /etc/os-collect-config.conf,果然发现其中 region_name = null,老版本没有这个值。这个文件是如何产生的呢?这个是 nova 配置主机方式,template 定义 在 write-os-apply-config-templates.sh,数据在 /var/lib/os-collect-config/os_config_files.json,其包含 /var/lib/os-collect-config/heat_local.json,里面 region_name: null,其他都有。这里看,这个为 heat local metadata,应该是 heat 创建 vm 时传入。os-collect-config heat_local.py负责写入 heat_local,数据从 /var/lib/heat-cfntools/cfn-init-data,里面数据等同于 /var/lib/cloud/data/cfn-init-data。Heat Walk-through里面会做这一步,如此看来,这是 heat bug?因为都是自动化部署出来的,没办法来个途中硬编码确认。

region_name 是 stack 运行的一个参数,dashboard 显示这个值已经传入。

打开 debug 后会输出更多内容,如何打开?

write-os-apply-config-templates.sh 这文件会写入 /var/run/heat-config/heat-config,

echo ""> $oac_templates/var/run/heat-config/heat-config

deployments 变量是容器的输入变量。

关于 heat, Heat metadata service is provided via the CFN API, its primary use is for heat-cfntools to talk to Heat via that API.

Heat Troubleshooting描述了获取 user data 方法:

    curl -s http://169.254.169.254/2009-04-04/user-data

试了下,果然可以(为什么是 2009-04-04 😂),这是 multipart 数据格式。这个是 vm 内置的 metadata server。最后两段为:

--===============2826715925626734437==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
...

systemctl enable wc-notify
systemctl start --no-block wc-notify

--===============2826715925626734437==
Content-Type: text/x-cfninitdata; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cfn-init-data"

{"os-collect-config": {"heat": {"password": "x#g*ilkG&E*rNp%9u3z#KQO89bC4FK0!", "user_id": "0a3afbf8af2246bf86c2a480afa766ff", "region_name": null, "stack_id": "tong-wvfftolmtniv-kube_masters-4pu45beuteve-0-vsoxums4xz6k/9f7f80df-9fbd-4624-a029-55b58391dc50", "resource_name": "kube-master", "auth_url": "http://192.168.51.253:5000/v3/", "project_id": "4d70c955bbef4a8a94dfa9c7370042cb"}, "collectors": ["ec2", "heat", "local"]}, "deployments": []}

可以看到里面 region_name 也为空。而这段对应 magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml

kube_master_init:type:OS::Heat::MultipartMimeproperties:parts:-config:{get_resource:install_openstack_ca}-config:{get_resource:disable_selinux}-config:{get_resource:write_heat_params}-config:{get_resource:configure_etcd}-config:{get_resource:write_kube_os_config}-config:{get_resource:configure_docker_storage}-config:{get_resource:configure_kubernetes}-config:{get_resource:make_cert}-config:{get_resource:add_proxy}-config:{get_resource:start_container_agent}-config:{get_resource:enable_services}-config:{get_resource:write_flannel_config}-config:{get_resource:flannel_config_service}-config:{get_resource:flannel_service}-config:{get_resource:kube_apiserver_to_kubelet_role}-config:{get_resource:master_wc_notify}

可以看出 master_wc_notify 能找到定义,但是 cfn-init-data 没有,可能为 Heat 默认附上。

直接查看 Heat 源代码,nova.py build_userdata 方法会写这块 multipart:

ifmetadata:attachments.append((jsonutils.dumps(metadata),'cfn-init-data','x-cfninitdata'))

调用者 heat/heat/engine/resources/openstack/nova/server.py:

metadata=self.metadata_get(True)or{}userdata=self.client_plugin().build_userdata(metadata,ud_content,instance_user=None,user_data_format=user_data_format)

metadata 数据会写入 userdata。metadata_get 定义在 heat/engine/resource.py(VS Code 安装扩展后可以方便的查看方法定义)

defmetadata_get(self,refresh=False):ifrefresh:self._rsrc_metadata=Noneifself.idisNoneorself.action==self.INIT:returnself.t.metadata()ifself._rsrc_metadataisnotNone:returnself._rsrc_metadatars=resource_objects.Resource.get_obj(self.stack.context,self.id,refresh=True,fields=('rsrc_metadata',))self._rsrc_metadata=rs.rsrc_metadatareturnrs.rsrc_metadata

转为开发模式暨步骤总结

Check Kolla source code. It has branches like stable/rocky. It is very clear. But if you just pip install, you will get master version and can’t get the exact one by OpenStack version. As above shows, master use www_authenticate_uri which was wrong(valid in future). Rocky should use auth_uri. So we should use git branch rather than latest pip package.

  1. cd /etc/kolla,use old/tested global.yaml & passwords.yml. Just keep these 2 files and clear others.
  2. git checkout stable/rocky
  3. edit ./kolla-ansible/ansible/roles/magnum/defaults/main.yml, set default_docker_volume_type: "ssdvolume"
  4. edit ./kolla-ansible/ansible/roles/ceph/templates/ceph.conf.j2, set osd pool default size = 1& osd pool default min size = 1 since server has only one disk
  5. parted /dev/sdb -s -- mklabel gpt mkpart KOLLA_CEPH_OSD_BOOTSTRAP 1 -1; parted /dev/sdb print
  6. deploy ./kolla-ansible/tools/kolla-ansible -i ./kolla-ansible/ansible/inventory/all-in-one deploy -v | tee log
  7. edit kolla-ansible/tools/init-runonce(IP range) and run it
  8. glance image-create --name atomic27 --visibility public --disk-format raw --container-format bare < Fedora-Atomic-27-1.6.x86_64.raw
  9. openstack image set --property os_distro=fedora-atomic atomic27
  10. openstack volume type create "ssdvolume"

Think

  • Ansible 是幂等的,也就是说反复部署不会对功能造成影响,这个是理想情况。
  • Docker 对宿主机的网络和设备全面接管,和独立运行的程序没啥差别。用容器部署比直接程序更简便么?可能隔离性更好,不需要安装包,对宿主机操作系统影响不大。另外:其配置(/etc/kolla/)和运行时(容器)是隔离开的,符合 12 法则应用理论。
  • Docker 用的不错。那用了 Docker 还用 OpenStack vm 干啥呢?技术变化太快,总的来说:OpenStack plays the role of the overall data center management. KVM as the multi-tenant compute resource management, and Docker containers as the application deployment package. 容器另外一个问题是强隔离还不够好,vm 能弥补这个缺点。
  • 直接用 Docker,出了错只能直接操作 Docker 调试,显然用 k8s 更好些,但牵涉到网络、存储这个问题就更复杂了。
  • 漫长的部署居然没有写日志的地方,我只找到使用管道 tee的方法。
  • kolla 部署了大量镜像,这些镜像有缓存么?docker images ls没有看到任何镜像。
  • kolla 用 Docker 方法部署 OpenStack,目的是为了简化,但是坑也比较多,还要注意各种参数。
  • Python 动态语言虽然开发遍历,但如何保证类型安全,这里感觉 Go 更为合适
  • Heat 设计因为模仿了 AWS CloudFormation,和原来 OpenStack 并不十分吻合,很多地方有拼凑之感,颇为恶心
  • Heat 编排大量依赖 cloud-init/userdata,隔着 vm 在 Linux 上面各种操作,颇有 hack 之感,k8s 则没有 vm 这个屏障,初始化过程看得清清楚楚

RISC-V

$
0
0

荔枝糖

荔枝糖

wiki内容不多,如何连接 ft2232d 也没有说,这里可能有些讨论,需要焊接排线。

手把手教你设计CPU——RISC-V处理器篇

riscv-book

手把手教你设计CPU——RISC-V处理器篇,语言是生动了,但是内容却很空洞:上手地方太少。介绍用 Arty Artix-7 开发版模拟,这个淘宝价格1000¥,还是入门级的,搞个其他的不行?上面这个国产荔枝糖也是极好的呀。

如何评价嘉楠耘智的勘智K210芯片?,里面描述缺点在于没有用PCIE接口,内置8MB内存在算法加载模型时带宽太小。

https://cnrv.io/为推广RISC-V尽些薄力

https://www.cnx-software.com/2018/10/19/kendryte-kd233-risc-v-board-k210-soc-machinve-vision/

如何看待开源指令集RISC-V ? https://www.zhihu.com/question/28368960/answer/157247133

测试下 Rook

$
0
0

CNCF首个云原生存储项目——ROOK,基于成熟的 Ceph。

https://rook.io/docs/rook/v0.8/ceph-quickstart.html

Design Doc https://github.com/rook/rook/tree/master/design

Ref https://rook.io/docs/rook/v0.8/

怎么保证磁盘的访问性能呢?不过 Ceph 部署比较复杂,这样统一管理似乎也有优势,更重要的是可以监控起来,也可以更容易的伸缩。总的来说,如果是个分布式系统,则迁移到 k8s 上是有优势的。 这里看 volume plugin 会直接分区和 Mount 磁盘?如果这样就和自己安装 Ceph 性能差别不大了。 这里连接磁盘方式就有多种了。上面是直接 mount 节点上面的磁盘,但是一般架构存储和计算是分开的,存储一般需要较多的磁盘,机架格局和计算不同。如此需要部署一个单独的 k8s 存储集群了?

原来它用的是 FlexVolume 这种扩展,https://rook.io/docs/rook/v0.8/flexvolume.htmlFlexvolume似乎只是一种让 kubelet 直接运行的二进制文件,放在 /usr/libexec/kubernetes/kubelet-plugins/volume/exec/下面,这些不是容器镜像。使用这些文件可以直接对节点上的磁盘操作,比如分区和挂载,似乎和每个节点上安装 ceph-common 一样,但是这个是由 k8s 来管理安装和更新,不用手工干预。为什么不放 pod 里面?pod 无法访问磁盘?不对啊,osd server 是直接访问的。问题是 osd server 能直接访问节点的磁盘比如/dev/vdb 么?

[centos@k8s-4 ~]$ sudo ls /var/lib/rook/osd0 -lh总用量 44K
lrwxrwxrwx 1 root root   58 9月  27 07:07 block -> /dev/disk/by-partuuid/8f0c90b3-e76f-47f7-940f-79165b5f54c1
lrwxrwxrwx 1 root root   58 9月  27 07:07 block.db -> /dev/disk/by-partuuid/9c5ad55d-764e-4425-a688-7d16171629d1
lrwxrwxrwx 1 root root   58 9月  27 07:07 block.wal -> /dev/disk/by-partuuid/d1dc01e5-e5eb-45c6-a50e-0b11d05a3a99
[centos@k8s-4 ~]$ lsblk --output NAME,PARTLABEL,PARTUUID
NAME   PARTLABEL       PARTUUID
vda                    
└─vda1                 
vdb                    
├─vdb1 ROOK-OSD0-WAL   d1dc01e5-e5eb-45c6-a50e-0b11d05a3a99
├─vdb2 ROOK-OSD0-DB    9c5ad55d-764e-4425-a688-7d16171629d1
└─vdb3 ROOK-OSD0-BLOCK 8f0c90b3-e76f-47f7-940f-79165b5f54c1

这样就很清楚了,容器还是以文件的形式来访问宿主机,而上面的符号连接应该是由 rook flexvolume 来完成的。UNIX 任何皆文件的哲学果然强大。这样就能理解为什么重建 ceph cluster 时为什么要删除/var/lib/rook 目录了。

其 quickstart 默认用的是主机磁盘文件系统:If you are using dataDirHostPath to persist rook data on kubernetes hosts, make sure your host has at least 5GB of space available on the specified path. 为什么不提供直接 mount 主机上面的磁盘 /dev/sdb 这种方式?https://rook.io/docs/rook/v0.8/ceph-cluster-crd.html#storage-selection-settings deviceFilter * sdb: Only selects the sdb device if found,直接这样就可以?这个是节点上面的磁盘吧,容器能直接访问磁盘?如果某个节点没有磁盘,那这个上面也不会安装 Ceph?Operator 这么智能?我可以搞一个有多个磁盘的裸机然后加入已有集群。

按照 https://rook.io/docs/rook/v0.8/ceph-quickstart.html安装之。默认磁盘时安装在 host 机器上的 /var/lib/rook,我 3 个节点,会有 3 个 osd pod,一个 mgr pod,3 个 monitor pod,每个节点都有一个。整个速度挺快的,比自己整 ceph 集群快多了。mgr pod 就是自带的 Dashboard web ui。ceph version 12.2.7 luminous (stable),operator,果然比我 Ceph 门外汉更专业。Dashboard 可实时刷新数据,用的是轮训,感觉监控起来比命令行要方便。不过看不到 pool 下面的对应 pvc 的卷。

现在添加磁盘,先给 k8s-4 节点分配一个新硬盘,然后设置 cluster.yaml useAllDevices: true,这会对节点上所有的非操作系统的磁盘分区。kubectl apply 没变化,只能全删除后重建。但是这次一个 osd server 也没有。osd-prepare-k8s-4 上有日志:

2018-09-13 09:15:57.545604 I | exec: Running command: lsblk /dev/vdb --bytes --pairs --output NAME,SIZE,TYPE,PKNAME 
2018-09-13 09:15:57.548315 I | exec: Running command: udevadm info --query=property /dev/vdb1 
2018-09-13 09:15:57.550359 I | sys: non-rook partition: 
2018-09-13 09:15:57.550378 I | exec: Running command: udevadm info --query=property /dev/vdb 
2018-09-13 09:15:57.552510 I | cephosd: skipping device vdb that is in use (not by rook). fs: , ownPartitions: false 
2018-09-13 09:15:57.562849 I | cephosd: configuring osd devices: {"Entries":{}} 

不能自己分区?可能是为了保护数据。好吧,我删除 /dev/vdb1 分区,然后重建集群。为什么每次都要重建?现在有一个 osd server 了!好耶!有了这个 operator,重建 ceph 集群真是好方便!进入到 k8s-4,/dev/vdb 被分成了 3 个区,但是没有看到那个容器挂载了这些分区。对于曾经加入 ceph 过的磁盘,再次加入集群时可以不用删除已有分区。

kubectl apply -f storageclass.yaml创建 StorageClass:

apiVersion:ceph.rook.io/v1beta1kind:Poolmetadata:name:replicapoolnamespace:rook-cephspec:replicated:​    size:1---apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:rook-ceph-blockprovisioner:ceph.rook.io/blockparameters:pool:replicapool# Specify the namespace of the rook cluster from which to create volumes.# If not specified, it will use `rook` as the default namespace of the cluster.# This is also the namespace where the cluster will beclusterNamespace:rook-ceph# Specify the filesystem type of the volume. If not specified, it will use `ext4`.fstype:xfs

相当简单,不用配置 IP 之类的,和 Openstack 环境下 cinder 挂载类似。然后就可以 helm chart postgresql创建 了。在 postgresql pod 所在的节点上面可以看到 dmesg 里面有:

libceph: mon1 10.100.238.135:6790 session established 
rbd: rbd0: capacity 8589934592 features 0x1 
[centos@k8s-2-new ~]$ lsblk 
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT 
sda      8:0    0  366K  0 disk 
vda    252:0    0   20G  0 disk 
└─vda1 252:1    0   20G  0 part / 
rbd0   251:0    0    8G  0 disk /var/lib/kubelet/pods/13be1c5a-b73b-11e8-86d6-aa90b3cbae01/volumes/ceph.rook.io~rook-ceph-system/pvc-139b6b86-b73b-11e8-86d6-aa90b3cbae01 

用的和我自己搭建 Ceph 差不多的工具库,不知道这次会不会出现 libceph socket closed 导致节点高负载的问题。ceph 版本不同,provisioner 也不同,希望不会出现吧。(想不到困扰一时的问题这么解决?😂)

上面的 10.100.238.135 是建立在 k8s-4上面 service 的 ClusterIP,这个配置没有写在 StorageClass 里面,我猜是 provisioner 做的自动配置。

怎么通过 ceph-common 命令查看上面的集群呢?https://rook.io/docs/rook/v0.8/toolbox.html考虑到了,不错。kubectl create -f toolbox.yaml一行代码就搞定(examples/kubernetes/ceph 这个样例代码做的不错)。文档有问题,连接 pod 的名字不对。这样就可以验证删除 pv 后 Ceph 里面 pool/pv 是否也删除:确实删除了!

验证下稳定性:重启唯一的 osd 节点 k8s-4,结果挂了:qcow2: Image is corrupt; cannot be opened read/write。难道 ceph 把系统盘给修改了?也修复不好,没办法,只能重建。重建后因为我 hostname 没有改,k8s-4 上面自动运行了一个 osd server,但是有错误:

bluestore(/var/lib/rook/osd0/block) _read_bdev_label failed to open /var/lib/rook/osd0/block: (2) No such file or directory 

可能 operator 已经记录了 k8s-4 上面有一个磁盘,并且已经 prepare 过,所以认为这个目录下应该对应的配置文件。我觉得重新 repare 下应该可以,现在不知道方法,手工删除 rook 目录,重启 k8s-4。得重建集群了。

[centos@k8s-1 ceph]$ kubectl delete -f cluster.yaml
namespace "rook-ceph" deleted
serviceaccount "rook-ceph-cluster" deleted
role.rbac.authorization.k8s.io "rook-ceph-cluster" deleted
rolebinding.rbac.authorization.k8s.io "rook-ceph-cluster-mgmt" deleted
rolebinding.rbac.authorization.k8s.io "rook-ceph-cluster" deleted
cluster.ceph.rook.io "rook-ceph” deleted

删除卡在最后一步,强制删除后重新安装会显示 cluster.ceph.rook.io “rook-ceph” unchanged,这会导致后面 pod 都不会创建出来。

[centos@k8s-1 ceph]$ kubectl get clusters.ceph.rook.io  -n rook-ceph
NAME        AGE
rook-ceph   18h
[centos@k8s-1 ceph]$ kubectl delete clusters.ceph.rook.io rook-ceph -n rook-ceph
cluster.ceph.rook.io "rook-ceph" deleted

也是卡在这一步。似乎 CRD 删除容易出现这种问题,ceph-teardown已经记录了,要删除 CRD 的 finalizer。

然后问题依旧。只能 kubectl delete -f operator.yaml再重建。

既然在 k8s 中管理 Ceph,一个问题就是动态管理。比如如何添加一个新的磁盘后把这个磁盘加入到 ceph 集群中,这些都能通过操作 CRD 而不用了解 ceph 知识么?添加新磁盘后,pod 的 ceph monitor 会同步更新么?这里描述说:如果 useAllNodes 设置为 false,Nodes can be added and removed over time by updating the Cluster CRD

创建一个新节点,并把其加入到 k8s 中。检测系统,发现 rook-ceph-system 下已经有 rook-ceph-agent & rook-discover pod 运行了(都是守护进程集),rook-ceph namespace 下面并没有新的 ceph-monitor pod。新节点已经 load libceph rbd kernel module,是 rook 加的?新节点上还没有安装 ceph-common 包。然后新节点关机加入新磁盘,启动。rook-discover 日志已经能发现新磁盘 /dev/vdb,但是没有创建对应的 osd pod。我集群 useAllNodes 为 true,应该为自动添加啊。这时候我发现新节点里面 rook-agent 里面有好多错误:

github.com/rook/rook/vendor/github.com/rook/operator-kit/watcher.go:76: Failed to list *v1beta1.Cluster: Get https://10.96.0.1:443/apis/ceph.rook.io/v1beta1/clusters?resourceVersion=0: dial tcp 10.96.0.1:443: i/o timeout 

关闭新节点(fedora)上面的防火墙,还是老样子。命令行下 curl -k url 有错误,其他老节点都没问题。dmesg 下面有如下错误:

overlayfs: unrecognized mount option "context="system_u:object_r:container_file_t:s0:c514" or missing value 

换成 centos,没有上面错误,但是还是没有 osd pod。这个 Q&A OSD pods are not created on my devices写了些原因,不过都和我的不一样,不过还是安装起解决办法删除 rook-ceph-operator pod,这样会有一个新的 osd-prepare,但是其运行错误:

2018-09-18 06:28:51.356903 I | partition vda: Could not create partition 2 from 1181696 to 43124735 
2018-09-18 06:28:51.356947 I | partition vda: Unable to set partition 2's name to 'ROOK-OSD13-DB'! 
2018-09-18 06:28:51.356953 I | partition vda: Error encountered; not saving changes. 
failed to configure devices. failed to config osd 13. failed format/partition of osd 13. failed to partion device vda. failed to partition /dev/vda. Failed to complete 'partition vda': exit status 4. 

找了下,原来 ceph 需要磁盘至少 30GB,这个错误提示也太隐晦了吧!ceph 果然是古老的东西。这些错误是 ceph 报出来的,这个新节点上面没有安装 ceph-common 客户端。提高磁盘容量之后 osd pod 就创建了。就是这个必须要删除 operator 才能生效有点蹩脚。如果我一早就预备 30gb 就没这个问题?不可能吧,因为不重建 operator pod,连 prepare pod 都不会出来。这个新节点上面 monitor 并没有,可能觉得 3 个就够了。

然后 poweroff 这个节点,节点上的 osd pod 没有迁移到其他节点,状态为『此容器正在等待中』,这是合理的,因为磁盘已经不在了。Ceph Dashboard 中仍显示为 HEALTH_OK。

然后 kubectl delete node,这个时候 pod 为 『此容器组已经出错』0/5 nodes are available: 1 node(s) were not ready, 1 node(s) were out of disk space, 4 node(s) didn’t match node selector. OSD 副本集上有很多选择器:app: rook-ceph-osd;ceph-osd-id: 15;pod-template-hash: 1499787393;rook_cluster: rook-ceph,但是我看各个节点上面都没有这些标签,不知道是怎么匹配的。Ceph Dashboard 没有任何变化。

重建 operator pod,没啥用,k8s 资源都要手工删除。Ceph Dashboard 还是显示已经删除的 OSD Server。

Fedora 重新试一下,使用系统 docker-ce,猜测 rook-agent 网络不通应该是 ipvs 问题(要升级 kube-proxy),现在 agent 没有 timeout 的问题了。再这个节点上测试上面功能,一样问题。提了个 issue

第二天来发现 mon pod 已经迁移到新节点上,自动迁移已靠近 osd pod?总数还是 3 个。但是有错误:rook error: unknown flag: –config-dir,其他 mon pod 都好好的啊,奇怪。到 hub.docker.com 检查后把镜像版本从 master 改为 v0.8.2 就可以了,这帮人开发瞎搞。

我 30GB 硬盘,ceph 自动分区后为:

#         Start          End    Size  Type            Name
1         2048      1181695    576M  Linux filesyste ROOK-OSD0-WAL
2      1181696     43124735     20G  Linux filesyste ROOK-OSD0-DB
3     43124736     62914526    9.4G  Linux filesyste ROOK-OSD0-BLOCK

为什么block只有 10Gb,哪里配置?databaseSizeMB & journalSizeMB,去掉这些我修改的参数,重新部署(不需删除已有分区),现在 DB 分区只有 1G。

单独添加某个磁盘还不支持,currently in Rook v0.7, there is only official support for adding and removing entire nodes (with all their disks and directories).

一个节点上如有磁盘要加入 Ceph,则起一个 pod 即可。感觉有点不踏实:如果这个 pod killed 了呢?当然 k8s liveness 会帮忙起一个 pod,新建 pod 也需要其加入已有的 Ceph cluster,这个过程如果很完美则比自己维护一个 ceph 集群可靠性更好。这个是 failed over 么?节点上如果起多个 pod 来提供 HA 可以么?有状态的没法这么干吧。

运行一段时间后,节点还是失去反应,libceph socket closed (con state connecting),好的一点在于日志吐出并不块,CPU 占用率也不高,但是系统还是失去响应,得强制重启。可能原因在于我已经删除了 ceph cluster,它为了保证数据完整,内核不让重启。现在似乎不少节点无法命令行重启。

没有自动创建的 issue无人解答,自己探索。

<== pkg/operator/ceph/cluster/osd/spec.go makeJob 会创建 prepare Job 
<== pkg/operator/ceph/cluster/osd/osd.go startProvisioning,这个方法会遍历 cluster.Storage.Nodes 所有节点,没看到有条件的创建 job 
<== pkg/operator/ceph/cluster/osd/osd.go Start 
<== pkg/operator/ceph/cluster/cluster.go createInstance 
<== pkg/operator/ceph/cluster/controller.go onAdd & handleUpdate ( handleUpdate 实为 onUpdate) 

这些 on 方法都是 watch “kind: rook.Cluster” 资源了吧。只监听 Cluster 资源当然不会在添加新节点的时候触发以上过程了!怪不得有地方建议直接删除 Operator pod,这种有点粗鲁。可以 edit cluster,useAllNodes:false,然后加上新节点的 ip,这样可以吧。不知道这样是否会对已有的节点会造成影响。

修改 useAllNodes: false,然后在 nodes 下面定义的一个节点 k8s-4 。部署集群后,一切正常,现在只有一个 OSD server。修改 cluster.yaml(kubectl edit 里面没有节点部分),在加入一个新的节点 k8s-new-node,OSD server 都能顺利创建出来。Operator 有如下日志:

2018-09-27 07:12:00.214724 I | op-cluster: update event for cluster rook-ceph 
2018-09-27 07:12:00.214800 I | op-cluster: The list of nodes has changed 
2018-09-27 07:12:00.214811 I | op-cluster: update event for cluster rook-ceph is supported, orchestrating update now 
2018-09-27 07:12:00.260502 I | op-mon: start running mons 
2018-09-27 07:12:00.265528 I | cephmon: parsing mon endpoints: a=10.110.87.214:6790,b=10.110.186.133:6790,c=10.97.189.6:6790 
2018-09-27 07:12:00.265684 I | op-mon: loaded: maxMonID=2, mons=map[b:0xc4209c76c0 c:0xc4209c7740 a:0xc4209c7640], mapping=&{Node:map[c:0xc420318840 a:0xc4203187e0 b:0xc420318810] Port:map[]} 
2018-09-27 07:12:00.276099 I | op-mon: saved mon endpoints to config map map[data:a=10.110.87.214:6790,b=10.110.186.133:6790,c=10.97.189.6:6790 maxMonId:2 mapping:{"node":{"a":{"Name":"k8s-2-new","Hostname":"k8s-2-new","Address":"192.168.51.12"},"b":{"Name":"k8s-3-new","Hostname":"k8s-3-new","Address":"192.168.51.13"},"c":{"Name":"k8s-4","Hostname":"k8s-4","Address":"192.168.51.14"}},"port":{}}] 
2018-09-27 07:12:00.276785 I | cephconfig: writing config file /var/lib/rook/rook-ceph/rook-ceph.config 
2018-09-27 07:12:00.277239 I | cephconfig: copying config to /etc/ceph/ceph.conf 
2018-09-27 07:12:00.277466 I | cephconfig: generated admin config in /var/lib/rook/rook-ceph 
2018-09-27 07:12:00.289078 I | op-mon: Found 1 running nodes without mons 
2018-09-27 07:12:00.289120 I | op-mon: ensuring mon rook-ceph-mon-a (a) is started 
2018-09-27 07:12:00.394787 I | op-mon: mon a running at 10.110.87.214:6790 
2018-09-27 07:12:00.466938 I | op-mon: mon b running at 10.110.186.133:6790 
2018-09-27 07:12:09.280754 I | op-osd: 2 of the 2 storage nodes are valid 
2018-09-27 07:12:09.280775 I | op-osd: checking if orchestration is still in progress 
2018-09-27 07:12:09.283427 I | op-osd: start provisioning the osds on nodes, if needed 
2018-09-27 07:12:09.310899 I | op-osd: avail devices for node k8s-4: [{Name:vdb FullPath: Config:map[]}] 
2018-09-27 07:12:09.315175 I | op-osd: Removing previous provision job for node k8s-4 to start a new one 
2018-09-27 07:12:09.335221 I | op-osd: batch job rook-ceph-osd-prepare-k8s-4 still exists 
2018-09-27 07:12:11.341452 I | op-osd: batch job rook-ceph-osd-prepare-k8s-4 deleted 
2018-09-27 07:12:11.351147 I | op-osd: osd provision job started for node k8s-4 
2018-09-27 07:12:11.455374 I | op-osd: avail devices for node k8s-new-node: [{Name:vdb FullPath: Config:map[]} {Name:sda FullPath: Config:map[]} {Name:vda FullPath: Config:map[]}] 
2018-09-27 07:12:11.466879 I | op-osd: osd provision job started for node k8s-new-node 
2018-09-27 07:12:11.466905 I | op-osd: start osds after provisioning is completed, if needed 
2018-09-27 07:12:11.475870 I | op-osd: osd orchestration status for node k8s-4 is starting 
2018-09-27 07:12:11.475917 I | op-osd: osd orchestration status for node k8s-new-node is starting 
2018-09-27 07:12:11.475927 I | op-osd: 0/2 node(s) completed osd provisioning 
2018-09-27 07:12:12.519123 I | op-osd: osd orchestration status for node k8s-4 is computingDiff 
2018-09-27 07:12:12.652414 I | op-osd: osd orchestration status for node k8s-4 is orchestrating 
2018-09-27 07:12:12.665979 I | op-osd: osd orchestration status for node k8s-4 is completed 
2018-09-27 07:12:12.666037 I | op-osd: starting 1 osd daemons on node k8s-4 
2018-09-27 07:12:12.684588 I | op-osd: deployment for osd 0 already exists. updating if needed 
2018-09-27 07:12:12.688043 I | op-k8sutil: updating deployment rook-ceph-osd-0 
2018-09-27 07:12:14.713141 I | op-k8sutil: finished waiting for updated deployment rook-ceph-osd-0 
2018-09-27 07:12:14.713224 I | op-osd: started deployment for osd 0 (dir=false, type=) 
2018-09-27 07:12:14.897416 I | op-osd: osd orchestration status for node k8s-new-node is computingDiff 
2018-09-27 07:12:15.126273 I | op-osd: osd orchestration status for node k8s-new-node is orchestrating 
2018-09-27 07:12:30.533344 I | op-osd: osd orchestration status for node k8s-new-node is completed 
2018-09-27 07:12:30.533379 I | op-osd: starting 1 osd daemons on node k8s-new-node 
2018-09-27 07:12:30.564077 I | op-osd: started deployment for osd 1 (dir=false, type=) 
2018-09-27 07:12:30.596881 I | op-osd: 2/2 node(s) completed osd provisioning 
2018-09-27 07:12:30.596940 I | op-osd: checking if any nodes were removed 
2018-09-27 07:12:30.645332 I | op-osd: processing 0 removed nodes 
2018-09-27 07:12:30.645360 I | op-osd: done processing removed nodes 
2018-09-27 07:12:30.645369 I | op-osd: completed running osds in namespace rook-ceph 
2018-09-27 07:12:30.645518 I | exec: Running command: ceph osd unset noscrub --cluster=rook-ceph --conf=/var/lib/rook/rook-ceph/rook-ceph.config --keyring=/var/lib/rook/rook-ceph/client.admin.keyring --format json --out-file /tmp/956465413 
2018-09-27 07:12:31.559860 I | exec: noscrub is unset 
2018-09-27 07:12:31.560148 I | exec: Running command: ceph osd unset nodeep-scrub --cluster=rook-ceph --conf=/var/lib/rook/rook-ceph/rook-ceph.config --keyring=/var/lib/rook/rook-ceph/client.admin.keyring --format json --out-file /tmp/041764000 
2018-09-27 07:12:32.695130 I | exec: nodeep-scrub is unset 
2018-09-27 07:12:32.695290 I | op-cluster: Done creating rook instance in namespace rook-ceph 
2018-09-27 07:12:32.707479 I | op-cluster: succeeded updating cluster in namespace rook-ceph 
2018-09-27 07:12:32.707735 I | op-cluster: update event for cluster rook-ceph 
2018-09-27 07:12:32.707772 I | op-cluster: update event for cluster rook-ceph is not supported 
2018-09-27 07:12:32.710587 I | op-cluster: update event for cluster rook-ceph 
2018-09-27 07:12:32.710663 I | op-cluster: update event for cluster rook-ceph is not supported 

修改 cluster.yaml,删除 name: “k8s-new-node”,osd pod 等会就会被删除,不错。

按设计来说,operator 确实只需监听 CRD 资源的定义就可以,毕竟这个描述定义所有的内容。但是如何处理 useAllNodes:true?在代码里面监听节点变化当然可以,但如此一来,监听的东西就多的去了,能否用声明式的方法写在 CRD 描述里面?这样监听的订阅和取消都由外部处理。

“kind: Cluster” 指的是 ceph cluster,所以字面上确实和 k8s cluster 不同,这点要注意。

加入新节点没有监听还可以解释,已加入的节点挂起是否监听呢?如果没有这个可用性大打折扣啊。

只监听 CRD 就足够的话,还要 discover & agent pod 做什么呢?其实这两个守护进程可以做到 『watch k8s cluster』同样效果。。。

这个现在在 0.9 milestone 中 https://github.com/rook/rook/milestone/10

Cluster 删除难的问题反复出现,ceph-teardown写了要删除 CRD 的 finalizer。今天查了下根源,删除时 operator 有日志:

2018-09-27 06:17:08.606342 I | op-cluster: cluster rook-ceph has a deletion timestamp 
2018-09-27 06:17:08.616067 I | op-cluster: waiting for volume attachments in cluster rook-ceph to be cleaned up. Retrying in 2s. 
2018-09-27 06:17:36.696588 W | op-cluster: exceeded retry count while waiting for volume attachments for cluster rook-ceph to be cleaned up. vols: [{TypeMeta:{Kind:Volume APIVersion:rook.io/v1alpha2} ObjectMeta:{Name:pvc-8cb3ff34-bc95-11e8-86d6-aa90b3cbae01 GenerateName: Namespace:rook-ceph-system SelfLink:/apis/rook.io/v1alpha2/namespaces/rook-ceph-system/volumes/pvc-8cb3ff34-bc95-11e8-86d6-aa90b3cbae01 UID:8ebfb7f1-bc95-11e8-86d6-aa90b3cbae01 ResourceVersion:10884495 Generation:1 CreationTimestamp:2018-09-20 05:25:16 +0000 UTC DeletionTimestamp:<nil> DeletionGracePeriodSeconds:<nil> Labels:map[] Annotations:map[] OwnerReferences:[] Initializers:nil Finalizers:[] ClusterName:} Attachments:[{Node:k8s-3-new PodNamespace:default PodName:toned-waterbuffalo-redis-master-0 ClusterName:rook-ceph MountDir:/var/lib/kubelet/pods/8cb71bfa-bc95-11e8-86d6-aa90b3cbae01/volumes/ceph.rook.io~rook-ceph-system/pvc-8cb3ff34-bc95-11e8-86d6-aa90b3cbae01 ReadOnly:false}]}] 
2018-09-27 06:17:36.700940 E | op-cluster: failed to remove finalizer cluster.ceph.rook.io from cluster rook-ceph. Operation cannot be fulfilled on clusters.ceph.rook.io "rook-ceph": the object has been modified; please apply your changes to the latest version and try again 

这个目录确实存在,但是 Redis 已经不在了。可能是我上次强制删除时留下的痕迹。这个 operator 有记录每次创建的 pv?但是不是只有 Cluster 这个 resource 么?

[centos@k8s-1 ceph]$ kubectl get volumes.rook.io --all-namespaces
NAMESPACE          NAME                                       AGE
rook-ceph-system   pvc-8cb3ff34-bc95-11e8-86d6-aa90b3cbae01   7d

果然还有另外一个 CRD。上面目录可以直接删除,然后删除 volume crd。删除 cluster.ceph.rook.io 依然有错误:

op-cluster: failed to remove finalizer cluster.ceph.rook.io from cluster rook-ceph. Operation cannot be fulfilled on clusters.ceph.rook.io "rook-ceph": the object has been modified; please apply your changes to the latest version and try again 

一般存储是单独部署的,有自己的控制网络和数据网络。这种让 Ceph 运行在计算集群内的方式是否稳定呢?生产环境如何处理?查了下,可以用 nodeSelector 让 pod 运行在特定的节点上,但是没有找到方法让节点只运行 Ceph 相关 pod 而进行隔离。使用 admission controller准入控制器 PodNodeSelector 可以定制控制。还是算了,即便约束了我猜这种混合部署的方式稳定性也没提高多少。单独的部署一个新的集群?那计算集群里面的 StorageClass 就得使用标准的 Ceph brd 连接(配置一堆 monitor)?

rook-ceph namespace 已经暴露出了 rook-ceph-mon-[a,b,c] 三个 service,ClusterIP。这个网络是 weave 网络,不知道性能如何。有个配置 hostNetwork,uses network of the hosts instead of using the SDN below the containers. https://github.com/rook/rook/issues/561 hostnetwork support

考虑到容器网络的复杂和各种 policy 控制,Ceph 这种大数据量的似乎不适合容器化,适合的地方在于监控和恢复。 如果应用和 Ceph 在同一集群,则网络问题似乎并不大。

其他存储

这个 Rook 现在已经支持很多存储:Ceph, CockroachDB, Minio, Cassandra, EdgeFS

这个如果支持 Gluster 似乎是很好的,既然都有对磁盘有支持。 暂时不支持,说是 heketi 的存储模型只能让一个进程打开。 虽然 Gluster 已经够简单,但是我看了下其 Samba 方案挺复杂,真不想配置,我只是想试试而已,自己配置肯定有很多坑。在深入了解一个东西前并准备真正去用前,为什么要趟这些坑呢?而且这些坑会让人知难而退。而这些也是开源虽然火热也有其痛点,云服务厂商的 PaaS 的开箱即用优势便在这里。如果说 IaaS 只是方便了运维,PaaS 面向的则是开发者。

EdgeFS https://rook.io/docs/rook/v0.9/edgefs-storage.htmlhttp://edgefs.io/https://itnext.io/edgefs-cluster-with-rook-in-google-cloud-885227625b9b Geo-transparent,我理解是多云环境的不同的数据中心的 db 合起来为一个统一的 db。这不和 CockroachDB 一样了么。

从最早对 Rook 的怀疑,到现在 Rook 的蓬勃发展,真是有趣的事情。 https://github.com/rook/rook/releases看看每个 release 的 feature 也是一件有趣的事情。

单独升级ceph, What version of Ceph would you like with that?Decoupling the Ceph version

Kong as an API Gateway

$
0
0

安装

helm install stable/kong

会创建两个 service:一个 admin,一个 proxy。

https://192.168.51.11:30291/这个不能用 k8s-1 hostname,为什么?页面啥没有,只返回一个 json。

https://docs.konghq.com/0.14.x/getting-started/configuring-a-service/这里创建一个 hello world 的接口:

curl -i -X POST --url <https://k8s-1:30291/services/> --data 'name=example-service' --data 'url=[http://mockbin.org](http://mockbin.org/)' -k 
curl -i -X POST --url <https://k8s-1:30291/services/example-service/routes> --data 'hosts[]=[example.com](http://example.com/)' -k 

第一条命令创建 service,这里用一个已经存在的 mockbin 作为测试服务,第二条创建路由。

curl -i -X GET --url https://k8s-1:31831 --header 'Host: [example.com](http://example.com/)' -k 

然后访问。前面用的都是 admin 端口,这里要用 proxy 端口。返回是网站 HTML,这里修改 mockbin REST 地址,返回一个更有意义的。不过现在 mockbin 已经不能创建新的条目了,说是 Redis 满了 https://github.com/Kong/mockbin/issues/78原来这个网站是开源的,和 Kong 同一作者。

curl -i -X POST --url https://k8s-1:30291/services/ --data 'name=example-service' --data 'url=http://mockbin.com/request?foo=bar' -k 

返回 HTTP Header 里面加了 Via: kong/0.14.0

http://mockbin.com/request这个可以网站打开 web ui,显示请求的 Web HTTP Header,代码访问设置 Accept Header 返回 json,不错的设计。

这一条条命令太麻烦,有 web ui:https://github.com/pantsel/kongahttps://github.com/PGBI/kong-dashboard

试了下 https://github.com/PGBI/kong-dashboard,这个没有 helm,使用 k8s dashboard 安装,需要设置:

参数: start --kong-url [https://kilted-llama-kong-admin.kong:8444](https://kilted-llama-kong-admin.kong:8444/) 

Error: self signed certificate,已知 issue,暂时没办法,只能修改 helm chart。 helm inspect stable/kong 查看参数后,

helm install stable/kong --namespace kong --set admin.useTLS=false --set proxy.useTLS=false 

然后 k8s dashboard 这个部署显示错误:

Readiness probe failed: Get https://10.36.0.223:8444/status: http: server gave HTTP response to HTTPS client 

修改部署 yaml 里面 livenessProbe 和 readinessProbe,”scheme”: “HTTP”改成这个。但是其服务内部端口还是 8444,虽然没啥关系,但是怪怪的。这个 chart bug 挺多。

kong-ui

有了这个界面,创建 service, router 就容易多了啊!这个应该是内置的。Istio 也必须有这个,否则乱七八糟太复杂。

按照 get started - enable plugin

curl -i -X POST --url <http://k8s-1:32103/services/foobar/plugins/> --data 'name=key-auth’ 

可以成功。界面上可以方便的 disable。

kong-ui-plugins

一切一换,访问结果立马不同(能访问和需要认证),有点神奇。对于这种经常需要切换的就需要有这样的操作界面。

从上图可以看到 plugin 能关联 kong 里面所有其他的资源:service/route, consumer。

认证 Plugin

https://github.com/nokia/kong-oidc这个 plugin 不是内置的,进入 pod 命令行,运行 luarocks install kong-oidc,这个命令 pod 已经包含。但是调用 admin api 创建时报错:”config”: “plugin ‘oidc’ not enabled; add it to the ‘plugins’ configuration property”。说明我上面安装的 plugin 没有生效?在 pod console 下 /etc/kong/kong.conf.default,加入一条 plugins = bundled, oidc,运行 kong reload,然后 api 就可以调用成功。

上访问 router,这时会跳到登录 keycloak 登录页面。感觉差不多成功了。然后修改 client_id && client_secret,值都可以在 keycloak 管理页面找到。这时 keycloak 页面会报错:无效的参数 : redirect_uri。原来遇到过,还是 keycloak console 创建一个新的 client 吧,设置其 Valid Redirect URIs http://k8s-1:32402/* ,这里用了 url wildcard。然后访问http://k8s-1:32402/aaa,需要输入用户名密码。然后就可以访问后面的 API (http://mockbin.com/request )了,刷新页面也不用重新登录,这是因为浏览器带了 cookie 了。http://mockbin.com/request 界面可以看到所有的请求参数,用来做调试用,里面确实带了一个编码后的 X-Userinfo 值。也有 session timeout 机制。

感觉这个可以取代 k8s dashboard keycloak proxy了,原理页差不多,都是 cookie。不对,dashboard proxy 只是 cookie->jwt token,本身不做认证,而是 proxy 下面的 api server 来做认证。下面这个图很清楚,这里 kong oidc plugin 在没有登录时会到 keycloak 做认证并且缓存授权信息,登录后自己只校验 cookie。后面 API 总是不做认证。

kong-auth

但是这个 cookie 方案只适合浏览器,对于代码怎么带 cooke 呢?只能从前端开始就带上了。

而且这个方案要自己保存 cookie,整个变成一个有状态服务了。

对于我们的需求:一个 dashboard+自己的 api,这个方案就没法适用了。而且我现在才发现:上面方案没有使用 JWT!

https://docs.konghq.com/hub/kong-inc/jwt/这个是官方的 plugin,直接用证书校验,所以还不能和 keycloak 关联。

感觉我需要的只是:使用 keycloak 证书认证 JWT,就如 k8s api server 所做的事情一样。

参照上面步骤,其实都可以在 kong dashboard 中完成。

kong-jwt

现在开始测试:不带任何 header,返回:

401 "message": “Unauthorized"

Postman 加上 Bearer token,随便填

401 "message": "Bad token; invalid JSON” 

好的,加上一个格式正确的:

"message": "No credentials found for given 'iss’” 

好的,创建一个有效的:

jwt

上面 iss 是 JWT credentials key,verify signature 里面要填入 JWT credentials secret。

整个串联流程是:创建 JWT Plugin,其挂上一个 Router,这样访问 Router 的时候都要先经过这些 plugin(像过滤器或者管道,切面,钩子)。JWT Plugin 校验 token 时会从 Consumers 里面找到对应的用户,如果找到用户并且签名正确(个人臆想),则请求可以从这个 plugin 可以顺利通过。

kong-consumers

Consumer 这里可以配置用户的方方面面,包含 group。这里演变成一个用户管理系统了?

为了避免每次访问 proxy 都用端口号,起一个新的 Ingress,host 匹配为:host: “*.proxy.kong.x.access.ly”。注意要用双引号才能 wildcard。这样 router 配置 host 为 aaa.proxy.kong.x.access.ly 就可以直接访问了并且也能和其他 router 很容易的区分开。

Router 和 Service 定义有重复,似乎是在模仿 k8s ingress 和 service 概念。kong service 有些自己特性:可以设定重试次数,默认为 5 次,还可以设定 timeout 时间。

总的来说,这个 Kong 挺轻量级,比 Istio 通过 yaml 来操作 CRD 简单多了。还有这个有个 UI,容易上手。虽然将来可能觉得 UI 不够强大灵活,但是对于新手 UI 帮助很大。入门后可以抛弃 UI 而用命令行来搞定,但并不意味着这个 UI 没有起到帮助。

架构基于 Nginx,为了更动态和灵活配置,使用了 OpenResty。 这里有谈到 Multi-datacenter with Cassandra,不知道是不是企业版专有。

kong-arch

这个 api gateway,就有点像 service mesh 了。

这里面的 Kong 提供很多功能,比如认证就功能很多,号称 api 网关,使用了数据库,不知道这里为什么要这么复杂,为什么不用 etcd? Kong 人气很旺,也是基于 OpenResty 开发,选择Kong作为你的API网关。其 https://github.com/Kong/kubernetes-ingress-controller基于 ingress nginx,版本才 0.1.1,这是专门搞企业版去了么?

虽然 nginx ingress 功能现在比较少,但是优势在于 nginx 非常成熟和经过考验,扩展多。

跨平台图形客户端 Discord,Telegram...

$
0
0

Discord

背后技术不大清楚, https://www.reddit.com/r/discordapp/comments/86logj/detailed_discord_tech_stack_explanation/ 这里也没说什么。

https://blog.discordapp.com/how-discord-resizes-150-million-images-every-day-with-go-and-c-c9e98731c65d https://blog.discordapp.com/tagged/engineering

桌面客户端安装体验很棒,直接安装,不用选择一些选项。 https://en.wikipedia.org/wiki/Discord_(software) 还是基于 Electron?我看其桌面和web页面很多元素和动画效果都是一样的。 但是我看其 Windows 安装目录有很多二进制库比如 libEGL.dll, libGLESv2.dll Mac 下简洁些,有:Mantle.framework, ReactiveCocoa.framework, Squirrel.framework. 可以打开 developer tool,确实是基于 Electron 无疑了。

上面游戏介绍都已经汉化,看来都知道大陆是游戏大市场啊!而且很多非游戏社区也用这个客户端。

tdesktop

https://github.com/telegramdesktop/tdesktop Qt 5.3.2 and 5.6.2, slightly patched https://news.ycombinator.com/item?id=14088147 Qt Mac 使用了本地的观感,所以看上去应用就是用本地的风格。 FONTCONFIG_FILE=/etc/fonts/ Telegram,否则linux上面启动要好几分钟。

Etcher

https://github.com/resin-io/etcher

React

react-desktop 是基于 Facebook ReactJS 的 JavaScript 库,为 OS X EI Capitan 和 Windows 10 提供 Web 原生桌面体验,支持 node-webkit 和 Electron.js,但可以在任意 JavaScript 驱动的项目使用。

https://github.com/chentsulin/electron-react-boilerplate React + Electron,试了下,开发窗口里面自带很多 react 开发插件,整体开发起来和一般 web 开发差不多。

  1. 如何创建 native 的菜单?
  2. 如何访问本地文件?node.js 访问?

Slack 桌面3.0迁移到BrowserView http://www.infoq.com/cn/news/2017/11/slack-browser-view-3 不大懂,这个直接用系统浏览器?

ATOM editor: 基于JavaScript, Node.js,运行在Chrome上面。神奇。这样能做负责的UI么?不过收益于Chrome的快速优化和web开发的快速发展带来的福利。 开发语言好像是coffescript,参考这里的自己写package http://flight-manual.atom.io/hacking-atom/sections/package-word-count/ 我的atom: https://atom-china.org/t/atom/1950

http://electron.atom.io/ ATOM背后的技术 C:\Users\fkpwo_000\AppData\Local\atom\app-1.10.2\resources\app\apm 包管理的位置,里面并没有react或者angular.js,可能因为性能考虑没有用这些库。

https://github.com/docker/kitematic/blob/master/CONTRIBUTING.md docker的图形管理工具也是基于electron开发的。

CEF - Chromium Embedded Framework

https://bitbucket.org/chromiumembedded/cef https://bbs.deepin.org/forum.php?mod=viewthread&tid=39743 网易云音乐用的这个

fan@jstone:/usr/lib/netease-cloud-music$ ls -lh
total 106M
-rw-r--r-- 1 root root 342K May 11 2016 cef_100_percent.pak
-rw-r--r-- 1 root root 450K May 11 2016 cef_200_percent.pak
-rw-r--r-- 1 root root 4.0M May 11 2016 cef_extensions.pak
-rw-r--r-- 1 root root 2.4M May 11 2016 cef.pak
-rwsr-sr-x 1 root root 15K Jun 28 2016 chrome-sandbox
-rw-r--r-- 1 root root 9.8M May 11 2016 icudtl.dat
-rw-r--r-- 1 root root 73M Jun 28 2016 libcef.so
drwxr-xr-x 2 root root 4.0K Nov 2 17:42 locales
-rw-r--r-- 1 root root 430K May 11 2016 natives_blob.bin
-rwxr-xr-x 1 root root 16M Jun 28 2016 netease-cloud-music
-rw-r--r-- 1 root root 642K May 11 2016 snapshot_blob.bin

官方 hello world 文档有点烂,看看这个 https://github.com/acristoffers/CEF3SimpleSample 这个好像是编译好的 chrome 库,有600MB。运行起来很快。Linux下一堆问题。后来发现还不如下载官方的,里面会带一个simple的例子,按照这里的文档https://bitbucket.org/chromiumembedded/cef-project。结果我卡在 fatal error: gtk/gtk.h: No such file or directory,libgtk-dev各个版本的我都安装了啊,什么鬼。后来换成 Ninja 编译就好了。然后用 cefsimple.exe –url=http://news.163.com可以打开网站,cool!但是这个为什么不在 binary 里面包含而要自己编译呢? 想找个borderless window的例子,一般都是Windows上面的 http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=13628

优点么,天然跨平台,容易布局, 这个和已有的 native web 比如 atom,有啥区别? https://github.com/zhaojunmeng/myblog/blob/master/posts/cef/hello-cef.md 这个有提到Off Screen Rendering(OSR,离屏渲染)

屌炸天的内核来袭,史上最小chromium内核miniblink!https://zhuanlan.zhihu.com/p/22611497 “cef:优点是由于集成的chromium内核,所以对H5支持的很全,同时因为使用的人也多,各种教程、示例,资源很多。但缺点很明显,太大了。最新的cef已经夸张到了100多M,还要带一堆的文件。同时新的cef已经不支持xp了(chromium对应版本是M49)。而且由于是多进程架构,对资源的消耗也很夸张。如果只是想做个小软件,一坨文件需要带上、超大的安装包,显然不能忍受。 nwjs,或者最近大火的electron:和cef内核类似,都是chromium内核。缺点和cef一模一样。优点是由于可以使用nodejs的资源,同时又自带了各种api的绑定,所以可以用的周边资源非常丰富;而基于js的开发方案,使得前端很容易上手。所以最近N多项目都是基于nwjs或electron来实现。例如vscode,atom等等。”

https://proton-native.js.org/#/ React Native 可以写桌面应用了,不必使用 Electron 了。有人写了一个渲染器,把 RN 渲染成桌面操作系统的 Native 应用。

Build Kubernetes HA Cluster by Kubic

$
0
0

总指导文章:https://kubernetes.io/docs/setup/independent/ha-topology/

简单测试

想试下 terraform + kvm 来搭建,感觉自己用 cloud-init 还是太慢。为什么不用 OpenStack?还是少生一事吧。

使用 https://github.com/dmacvicar/terraform-provider-libvirt terraform-provider-libvirt-Fedora-28,binary 现在区分 provider OS 下载。还是有点懒,https://github.com/kubic-project/automation/tree/master/kubic-kvm 这个有,为什么要自己创建呢?代码里面的地址有点老,改成 https://download.opensuse.org/repositories/devel:/kubic:/images/openSUSE_Tumbleweed/ 这个下面的。我用的是 openSUSE-Tumbleweed-Kubic.x86_64-15.0-kubeadm-cri-o-OpenStack-Cloud-Build4.5.qcow2。另外一个 https://github.com/kubic-project/automation/tree/master/caasp-kvm 可以创建多 master,但是要企业账号。运行完后会显示 3 个 vm 的地址:

ips = [
    [192.168.122.122], [192.168.122.174], [192.168.122.244]
]

不知道 terraform 有没有可以查询这个 ip 的命令,否则得先记下来(使用 terraform show命令即可)。我没有用 micro-os 的,用的是 kubic-kubeadm,这个 vm 起来后啥都没有,只是 vm image 预先包含了 kubeadm/kubelet 包,容器引擎用的是 cri-o,集群还要自己初始化:

kubeadm init --cri-socket="/var/run/crio/crio.sock"--pod-network-cidr=10.244.0.0/16
mkdir -p ~/.kube, then cp -i /etc/kubernetes/admin.conf ~/.kube/config

只需这个命令就可以,不需要 kubeadm 配置文档里面的七七八八的东西,还是比自己用 kubeadm 从头搭建方便些。CNI 我用的是推荐的 flannel。 .tf 文件使用了 template plugin,这样可以方便的创建多个 vm。创建后,我使用 pci-passthough sr-iov 网卡,这样能直接访问节点。暂时手工在 virt-manager里面修改,terraform-provider-libvirt 还没法控制 sr-iov 设备。

HA - External etcd topology

好,现在创建了 6 个节点,3 + 3,开始安装 HA https://kubernetes.io/docs/setup/independent/high-availability/使用External etcd nodes模式。这篇文章写的质量比较差,难以看懂。用到了ssh-agent 『它是linux 系统上的一个程序,这个程序可以控制和保存公钥身份验证所使用的私钥程序,当 ssh-add 把私钥交给 ssh-agent 来管理时,其他程序需要身份验证的时候都可以申请交给 ssh-agent 来完成整个认证过程.所以,到这里我们应该大体了解 ssh-agent : 它就是一个帮助我们验证身份的程序.』 和 ssh-copy-id 或者 ssh -i id_rsa 这种免密登录不一样么? 我的 external etcd cluster 使用的是用 etcd operator 已经创建的好的集群,和上面图有些不同,我画了一张。 用 external etcd mode,需要三个证书来访问 etcd,etcd operator 配置 https://github.com/coreos/etcd-operator/blob/master/doc/user/cluster_tls.md 有点麻烦,不好搞。准备转为 stack 模式前,看了下 example/tls/example-tls-cluster.yaml,居然有这个好东西,创建 CRD 前要先执行命令 kubectl create secret(无法放到 yaml 里面?)。访问的时候必须用这个 Host name。先设置 service 为 NodePort,这时候打开 https://192.168.51.11:30373/ NET::ERR_CERT_AUTHORITY_INVALID,合理。但是上面 link 说『To access the cluster, use the service example-client.default.svc, which matches the SAN of its certificates.』,我看证书生成过程中也指名了 host,这个是证书的必填项,不能为*(dashboard自己生成证书似乎可以匹配任何host),于是在 OpenWrt /etc/dnsmasq.conf 中添加:

address=/.example.default.svc/192.168.51.11address=/example-client.default.svc/192.168.51.11

etcdctl 测试通过。需要的三个文件为 etcd-client.crt,etcd-client.key,etcd-client-ca.crt。crt 和 key 为证书和私钥(为什么要两个?),因为是我们自己生成的证书,所以要有个假的 CA 来证明证书是合法的。最后使用下面命令测试下:

ETCDCTL_API=3 etcdctl --endpoints=https://example-client.default.svc:30373  --cert=etcd-client.crt --key=etcd-client.key --cacert=etcd-client-ca.crt member list -w table
ETCDCTL_API=3 etcdctl --endpoints=https://example-client.default.svc:30373  --cert=certs/etcd-client.crt --key=certs/etcd-client.key --cacert=certs/etcd-client-ca.crt get ''--prefix=true
ETCDCTL_API=3 etcdctl --endpoints=https://example-client.default.svc:30373 --cert=certs/etcd-client.crt --key=certs/etcd-client.key --cacert=certs/etcd-client-ca.crt del ''--prefix
etcdctl -w table endpoint status

配置 api server LB,使用 HAProxy

listenhttps_web192.168.51.230:6443modetcpbalanceroundrobin# Load Balancing algorithm
#kubic-0,1,2
serverserver1192.168.51.141:6443weight1maxconn512checkserverserver1192.168.51.120:6443weight1maxconn512checkserverserver1192.168.51.123:6443weight1maxconn512check

check 表示健康检查,这样就没有必要使用 Keepalived 了。然后再 OpenWrt 里面配置 k8s.api.server DNS IP 为上面的 192.168.51.230,因为要有证书访问。上面配置我可以使用 hostname,比如 kubic-1,重建后 Hostname 对应的 IP 会变,但是 HAProxy 照样能工作。可以的。这里通过 6443 端口能否访问来判断 api server 是否运行,并没有通过检查响应内容来判断服务是否正常。

有一次,kubic-0 上面的api-server pod停止运行,dashboard页面打不开,但是其错误现实似乎是个内部ip的地址。 Get https://10.96.0.1:443/apis/rbac.authorization.k8s.io/v1/roles: dial tcp 10.96.0.1:443: connect: connection refused 停掉api server pod: crictl stopp 1a84106e28fb3,pod 马上变为 running,原来这个 pod 也和普通一样会自动重启,看来要停掉kube-0才能测试了。先找到方法监控haproxy,本身就有带:

listenstatsbind:32700statsenablestatsuri/statshide-version

这样就可以看到详细的统计信息,不错啊。现在停掉kubic-0(我用的是 libvirt pause,并非关机),haproxy stats 马上就可以看到效果: 因为是master节点,所以并没有发生pod迁移。dashboard用kubic-1:nodeport可以继续访问。 继续 k8s HA 部署。kubeadm-config.yaml 为:

apiVersion:kubeadm.k8s.io/v1beta1kind:ClusterConfigurationkubernetesVersion:stableapiServer:certSANs:-"k8s.api.server"controlPlaneEndpoint:"k8s.api.server:6443"networking:podSubnet:10.244.0.0/16etcd:external:endpoints:-https://example-client.default.svc:30373caFile:/etc/kubernetes/pki/etcd/ca.crtcertFile:/etc/kubernetes/pki/apiserver-etcd-client.crtkeyFile:/etc/kubernetes/pki/apiserver-etcd-client.key

上面 api server 要设置 dns,etcd endports 我这里是 etcd in k8s cluster 的 server 地址,单个节点似乎没法在 k8s 外部单独访问。拷贝证书后,运行 kubeadm init –config kubeadm-config.yaml –cri-socket=”/var/run/crio/crio.sock”,错误: [ERROR ExternalEtcdVersion]: this version of kubeadm only supports external etcd version >= 3.2.18. Current version: 3.2.13 看来可以连接我的 etcd cluster within k8s 了,修改 etcd CRD 的版本,看看 operator 能否自动更新。可以,不错。但是创建出来的 pod 在 dashboard 显示为 58 分钟前,应该为刚刚创建才对。api server 有日志: [certs] apiserver serving cert is signed for DNS names [kubic-0 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local k8s.api.server k8s.api.server] and IPs [10.96.0.1 192.168.51.156] 这个是 kubeadm 自动创建 api server 的 load balance 证书。从上面看证书不仅可以绑定域名,也可以绑定 IP,当然还是 DNS 域名更灵活。 生成证书的比 dashboard 的更为严格。 然后出现错误:Unfortunately, an error has occurred: timed out waiting for the condition。journalctl -xeu kubelet里面有错误说无法访问 https://k8s.api.server:443。我 haproxy 里面配置的是 443 端口,改为6443,这个为 api server 的默认端口。重新部署,先要 crictl stop 2c8a3864d03a0 e628c4b5031ae(pod id) 删除老的 pod,否则报错说端口占用,这似乎为 kubeadm reset 的 bug:没有考虑到 cri-o。后来发现原来 reset 的时候也要加上参数 –cri-socket:kubeadm reset –cri-socket=”/var/run/crio/crio.sock”,这样就不用手工停止容器。 现在很快就可以看到 join 命令:

kubeadm join k8s.api.server:6443 --token ex0wd0.3ds30ke6hx2xal8k --discovery-token-ca-cert-hash sha256:12c505a79febe74a4a3255750b25b9c7a4e6556cb65bdb80f737d1092051b69c

For master node, should add additional parameters: --experimental-control-plane --cri-socket="/var/run/crio/crio.sock". For work node, just need --cri-socket. 然后把 kubic-1加入到 master 中,我把公钥拷贝到 kubic-0 上面,这样就能免密登录其他机器。可能这种和 ssh-agent 效果差不多。这个时候发现 kubic-0上面的 api server 反复重启。crictl logs 显示:

Unable to create storage backend: config (&{ /registry [https://example-client.default.svc:30373] /etc/kubernetes/pki/apiserver-etcd-client.key /etc/kubernetes/pki/apiserver-etcd-client.crt /etc/kubernetes/pki/etcd/ca.crt true 0xc0005ba1b0 <nil> 5m0s 1m0s}), err (dial tcp 192.168.51.11:30373: connect: no route to host)

一会又好了。

REATED             STATE               NAME                      ATTEMPT             POD ID
7349fd77f0edb       fe242e556a995a0ea9e3accec7c514ad01559900692308463b5166046337656d                                          6 minutes ago       Running             kube-apiserver            8

现在 attempt 8 次,后来反复创建都没有出现这个问题,这个可能是网络延迟。经过一段时间测试,虽然 kubectl 命令有些慢,这种 external etcd 的模式基本没有问题。考虑到这个 etcd 集群是由 etcd operator 创建出来的容器,性能会有些差,但还是可以用的。etcd operator 默认创建出来的容器的文件系统可能是普通文件镜像,没有保存到磁盘。文档中的:

scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt
scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key

我只有 ca.crt 文件,看看原来部署的集群,也是只有一个文件,只拷贝第一个,似乎也没问题。但是 api server boot error:

Unable to create storage backend: config (&{ /registry [https://example-client.default.svc:30373] /etc/kubernetes/pki/apiserver-etcd-client.key /etc/kubernetes/pki/apiserver-etcd-client.crt /etc/kubernetes/pki/etcd/ca.crt true 0xc00090a240 <nil> 5m0s 1m0s}), err (open /etc/kubernetes/pki/apiserver-etcd-client.crt: no such file or directory)

缺文件,于是拷贝 apiserver-etcd-client.crt & apiserver-etcd-client.key,下载问题好了,Node 也 ready,but now find coredns pod is still in ContainerCreating status, run kubectl describe on it: failed to find plugin “weave-net” in path [/usr/lib/cni /opt/weave-net/bin]. I have ever encountered this issue in KubeVirt / Kata Containers. Fix it by modify cri-o conf file. Then another error: failed to find plugin “loopback” in path [/opt/cni/bin /opt/loopback/bin]. OK. Copy weave plugin to /usr/lib/cni.

kubic-0:/usr/lib/cni # cp -r /opt/cni/bin/weave-plugin-2.5.1 ./
cp: cannot create regular file './weave-plugin-2.5.1': 只读文件系统

WTF. So the OpenSuse release should be like Fedora Atomic(Transactional Updates). It is too later to change weave to another CNI like flannel because I didn’t add CIDR parameter. The dir /usr/lib/cni has this cni. So the kubic image didn’t add other cni by default? No other way. Switch to flannel. But the pod can’t start:

Failed to create SubnetManager: error retrieving pod spec for 'kube-system/kube-flannel-ds-amd64-5nklv': Get https://10.96.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-amd64-5nklv: dial tcp 10.96.0.1:443: i/o timeout

Try serveal times and still get same error. Why? etcd or iptables or ipvs cache? Or my CIDR setting issue(controller manager log report this)? Switch back to weave, same issue:

FATA: 2019/02/11 12:36:47.243705 [kube-peers] Could not get peers: Get https://10.96.0.1:443/api/v1/nodes: dial tcp 10.96.0.1:443: i/o timeout

WTF. Destroy all nodes and re-create again. This time when just run kubeadm init and the weave pod is already there! I didn’t install weave yet. Indeed, kubeadm reset will not clean external etcd. To wipe, run etcdctl del "" --prefix. Be careful to run this command, this will make a running cluster broken immediately! This should be root cause. Try again and use flannel as cni. Works well. So make sure everything in first node works well and then add another node to control panel.

Then add work node. It is quite simple as deploy non HA cluster. Not need copy cert file.

Kubic

It is based on openSuse MicroOS. + kubeadm. Use btrfs file system. https://kubic.opensuse.org/blog/2019-01-22-certified/. Use Open Build Service to build so many different image. Use CRI-O container engine. MicroOS based on openSUSE Tumbleweed。 Tumbleweed 项目是一个“滚动升级”的 openSUSE 版本,俗称“风滚草”。滚动升级的版本不像 openSUSE 的常规版本(Leap) 那样受限于版本开发周期,可以始终使用最新稳定版本的全部软件。该项目适合想使用最新的、稳定的软件的 openSUSE 用户。 https://en.opensuse.org/Kubic:MicroOS Read-only root filesystem. But why can write file to /etc/kubernetes & /root directory? /etc/fstab:

LABEL=ROOT    /.snapshots             btrfs    defaults,subvol=@/.snapshots                0  0
LABEL=ROOT    /home                   btrfs    defaults,subvol=@/home                      0  0
LABEL=ROOT    /opt                    btrfs    defaults,subvol=@/opt                       0  0
LABEL=ROOT    /root                   btrfs    defaults,subvol=@/root                      0  0
LABEL=ROOT    /srv                    btrfs    defaults,subvol=@/srv                       0  0
LABEL=ROOT    /tmp                    btrfs    defaults,subvol=@/tmp                       0  0
LABEL=ROOT    /var                    btrfs    defaults,subvol=@/var,x-initrd.mount        0  0
LABEL=ROOT    /usr/local              btrfs    defaults,subvol=@/usr/local                 0  0
LABEL=ROOT    /boot/grub2/i386-pc     btrfs    defaults,subvol=@/boot/grub2/i386-pc        0  0
LABEL=ROOT    /boot/grub2/x86_64-efi  btrfs    defaults,subvol=@/boot/grub2/x86_64-efi     0  0
LABEL=ROOT    /                       btrfs    ro                                          0  0
LABEL=EFI     /boot/efi               vfat     defaults                                    0  0
LABEL=docker  /var/lib/docker         btrfs    defaults                                    0  0
overlay       /etc                    overlay  defaults,lowerdir=/sysroot/var/lib/overlay/3/etc:/sysroot/var/lib/overlay/2/etc:/sysroot/var/lib/overlay/etc:/sysroot/etc,upperdir=/sysroot/var/lib/overlay/4/etc,workdir=/sysroot/var/lib/overlay/work-etc,x-systemd.requires-mounts-for=/var,x-systemd.requires-mounts-for=/var/lib/overlay,x-systemd.requires-mounts-for=/sysroot/var,x-systemd.requires-mounts-for=/sysroot/var/lib/overlay,x-initrd.mount  0  0
/etc is an overlay file system. Is there way to rollback all of my modification?
`btrfs subvolume list /` will list lots of volumes.

Transactional Updates in Leap 15 & Tumbleweed,所以事务更新是 opensuse 的功能了。试着安装了一个包:transactional-update pkg in wget,安装后需要重启。然后现在如果要列出所以的snapshot点呢?transactional-update rollback last这个会恢复到上次的snapshot点。

So why not use Fedora Atomic? Because it not provided Terraform script to build k8s with KVM. http://www.projectatomic.io/docs/gettingstarted/ Here use virt-manager to deploy k8s with atomic. But It build vm manually.

https://github.com/kubernetes-sigs/kubespray look like all-in-one solution. Support lots of linux distribution and different component. Kubic just provide a container linux and still need extra works to build a HA cluster. Kubespray will install k8s cluster automatically, just like Magnum.

Terraform KVM provider SR-IOV support

Error creating libvirt domain: virError(Code=1, Domain=10, Message=’internal error: process exited while connecting to monitor: 2019-02-12T10:20:45.293085Z qemu-system-x86_64: -drive file=/home/fan/go/src/github.com/dmacvicar/terraform-provider-libvirt/libvirt/testdata/tcl.iso,format=raw,if=none,id=drive-ide0-0-0,readonly=on: Could not open ‘/home/fan/go/src/github.com/dmacvicar/terraform-provider-libvirt/libvirt/testdata/tcl.iso’: Permission denied’) —> lots of this issue. I just copy the file to /var/lib/libvirt/images.

Error clearing libvirt network: virError(Code=1, Domain=0, Message=’internal error: Network is already in use by interface virbr1’) —> sudo ip link set virbr1 down

Add passthrough = “enp6s0”, then get error “testing.go:538: Step 0 error: After applying this step, the plan was not empty” —> https://www.terraform.io/docs/extend/best-practices/testing.html#expecting-errors-or-non-empty-plans add ExpectNonEmptyPlan: true. But why? But this will result in that the code will not get passthrough attribute. The above link say “It is possible for scenarios to exist where a valid configuration (no errors during plan) would result in a non-empty plan”, so I changed tf script to add another interface without ‘network_name’:

network_interface = {
    network_name = "default"
}
network_interface {
    passthrough = "enp6s0"
}

Then work well. "hostdev = "${var.hostdev_list[count.index]}" It ref an array. If count > array length, an error “libvirt_domain.kubic-domain[5]: index 5 out of range for list var.hostdev_list (max 3) in” before run script. A static check. Good since until now no resource created so not need to rollback.

But then I found the interfac-hostdev is wrong. Shoud directly use hostdev as vendor/github.com/libvirt/libvirt-go-xml/domain_test.go DomainHostdevSubsysPCI does, since hostdev would any device beside network interface. If terraform encounter error like “could not access /sys/bus/pci/devices/0000:01:0a.0/config: No such file or directory” when do ‘terraform apply’, the vm will still be created. But looks vm state will not be saved and result in that the vm will not be deleted when do ‘terraform destroy’.

The code of master branch has issue: the created vm’s disk size is 0 and vm can’t boot. Change to v0.5.1. OK. But make testacc TEST_ARGS=”-run TestAccLibvirtDomain_Hostdev” will test all testcase. WTF.

Now pci passthrough works well. But old way to get ip will not work. Anyway I can use hostname to access vm.

terraform is good if we can finish task by existing task and I can accept the strange syntax and less flexibility. If I have to write my plugin by Golang, not good.

git push fan pci-passthough:pci-passthough. This command will: 1) submit to my remote branch; 2) create PR to original branch.

Ansible to bring up HA

tf 是声明式的,需要大量的plugin,似乎 https://github.com/kubernetes-sigs/kubespray 这种更简单,kubespray不创建节点,所以结合使用 terraform 更好。

Ok. Now turn above kubic image to common os image since kubic has too much package like kubelet which would be conflict with kubespray. Reuse kubic-kvm and just change os image, failed. Ubuntu can’t boot. Turn into Fedora-Cloud-Base-28-1.1.x86_64.qcow2 since Fedora will automatically bring up NIC even it is sr-iov. Boot ok and can get dhcp ip. But hostname not work. Same as Cenots-7. Use command ‘hostnamectl set-hostname ${hostname}’ as here in commoninit.cfg still not work. hostname changed in hostnamectl but DHCP name still localhost.

I try Centos. It can get IP by dhcp but no hostname. But if reboot, ip lost because nic MAC changed. This NIC 82576 SR-IOV will change mac randomly? But If I use kubic, everything works well and MAC didn’t changed. Really strange. I should give up kubespray and just use Ansible maybe.

Here is an Ansible hello world https://codingbee.net/tutorials/ansible/ansible-a-hello-world-playbook. Or Chinese here https://ansible-tran.readthedocs.io/en/latest/docs/intro_getting_started.html By default, it read /etc/ansible/hosts as hostname. Not good. I used a ‘–inventory file’ as parameter.

More details on HA k8s Ansible, check https://github.com/lingxiankong/kubernetes-study/tree/master/installation/ansible/version_4 https://lingxiankong.github.io/2018-06-22-multi-master-k8s.html

For a newbie like me, there is so many small try like “copy” and “retry” task. I have create a new test.yaml for this purpose. If I test in whole big task it will take long time since kubeadm init will take lots of time. https://stackoverflow.com/questions/23945201/how-to-run-only-one-task-in-ansible-playbook Another way.

- name: Wait for APIs to become available.
  command: kubectl get --raw /apis/autoscaling/v1
  register: autoscalingv1
  until: autoscalingv1.failed != True and (autoscalingv1.stdout | from_json).apiVersion == "v1"
  retries: 60
  delay: 5

The ‘until’ and ‘retries’ are really useful for common task. Terraform looks no this kind of feature? To clear etcd, I have installed etcd package by brew in Mac OS and run script locally. Terraform has etcd plugin and better support for CNCF.

Ansible error: “Failed to connect to the host via ssh: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!” It need to change local ssh config. So Ansible use local OS command like ssh. Not good.

k3s on Odroid HC1

$
0
0

Setup

『Lightweight Kubernetes. 5 less than k8s.』- 啊~五环,你比四环多一环~

既然是轻量级,当然得跑在 ARM 上才有存在感。Odroid HC1/XU4 虽然有点老,也不是 arm64 的,胜在软件稳定,CPU 性能也比一般的 A53x4 arm64 设备比如 rk3328 要强些,当然有更强的比如 rk3399 + eMMC,没银子置办,而且我的也可以接大容量磁盘,聊以慰藉。跑容器应用,一个镜像动辄 1GB,系统盘还是大点好,32GB 比较合适。

现在的 k3s 已经是 all-in-one 了,包含了 kubectl+containerd+runc+flannel,部署似乎比 kubeadm 还要方便很多。

Inside

除了做减法(去掉不必要组件),k3s 也做了些加法,比如 helm chart 的自动安装和内置 LoadBalancer 功能。

pkg/helm/controller.go watch CRD 然后创建klipper-helm pod,在pkg/server/server.go里面注册,hard code,里面还有个pkg/servicelb/controller.go,自动生成 load balance pod 的。其他的官方组件是在哪里注册并且运行的呢?官方组件不需要注册,pkg/daemons/control/server.go 会启动所有组件比如 api server, scheduler, controller,这个文件最后还是由 pkg/server/server.go 调用。

如果 service 为 LoadBalancer,会自动生成一个svclb开头的 pod,rancher/klipper-lb,这样 lb service 就可以获取 ip 了,在没有云环境情况下,这个解决了遗留已久的问题,比如我把 dashboard service 改为 lb马上就可以获取 IP 了,颇为神奇。https://github.com/rancher/klipper-lb不知道是否要对 k8s 核心进行修改。

Jenkins on Kubernetes

$
0
0

安装

[centos@k8s-1 ~]$ helm install stable/jenkins
NAME:   filled-eagle
LAST DEPLOYED: Thu Jun  6 13:26:38 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME                  AGE
filled-eagle-jenkins  0s
==> v1/Pod(related)
NAME                                   READY  STATUS   RESTARTS  AGE
filled-eagle-jenkins-7b89475bfd-nq7p7  0/1    Pending  0         0s
==> v1/ConfigMap
NAME                        AGE
filled-eagle-jenkins        0s
filled-eagle-jenkins-tests  0s
==> v1/ServiceAccount
filled-eagle-jenkins  0s
==> v1/Role
filled-eagle-jenkins-schedule-agents  0s
==> v1/RoleBinding
filled-eagle-jenkins-schedule-agents  0s
==> v1/Secret
filled-eagle-jenkins  0s
==> v1/PersistentVolumeClaim
filled-eagle-jenkins  0s
==> v1/Service
filled-eagle-jenkins-agent  0s
filled-eagle-jenkins        0s
NOTES:
1. Get your 'admin' user password by running:
  printf$(kubectl get secret --namespace default filled-eagle-jenkins -ojsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
2. Get the Jenkins URL to visit by running these commands in the same shell:
  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        You can watch the status of by running 'kubectl get svc --namespace default -w filled-eagle-jenkins'export SERVICE_IP=$(kubectl get svc --namespace default filled-eagle-jenkins --template"")echo http://$SERVICE_IP:8080/login
3. Login with the password from step 1 and the username: admin
For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine

上面挂载了一个磁盘卷,命名 “name”: “jenkins-home”, “mountPath”: “/var/jenkins_home”。 这个chart 有个缺点就是 jenkins 启动后,Some plugins could not be loaded due to unsatisfied dependencies. 安装报错,可能是因为我网络的问题。这些 plugin 安装后是放到 jenkins_home目录(也就是 PV)么?这样重启后这些 plugin 还在,是个不错的结果。helm install bitnami/jenkins这个倒没有依赖错误,但是没有内置 cloud build engine plugin。

Jenkins on Kubernetes 这个其实是一套方案,Cloud Build can be used from within your Jenkins jobs to build Docker images without needing to host your own Docker daemon. 也就是说是构建容器的方案。配置构建执行程序,还有点复杂。

测试构建

具体安装好plugin后,会看到每次运行 job 都会起一个 jenkins/jnlp-slave pod:

Still waiting to schedule task
Waiting for next available executor
Agent default-dmn7k is provisioned from template Kubernetes Pod Template
Agent specification [Kubernetes Pod Template] (filled-eagle-jenkins-slave ):
* [jnlp] jenkins/jnlp-slave:3.27-1(resourceRequestCpu: 200m, resourceRequestMemory: 256Mi, resourceLimitCpu: 200m, resourceLimitMemory: 256Mi)

运行完就会关闭。这个可以在pod里面构建容器?docker in docker?

这个样例代码里面很有意思,agent的定义其实可以在jenkins系统配置里面web ui进行定义,如果系统配置里面定义了,就要设置executor数字为0,然后agent为any,这样就能match倒系统配置里面的kubernetes。agent里面Kubernetes的容器列表最后其实是运行在Pod里面的多个容器,比如主的jenkins/jnlp-slave和发布的kubectl pod,在pipeline里面调用pod里面容器用container(‘kubectl’)方式,很炫酷啊,显示了容器的灵活之处。这块代码是在plugin java写的?

这里认证怎么办?一个是docker push的镜像仓库地址,一个是kubeconfig信息。尝试运行了kubectl get nodes,可以直接返回,这是哪里的默认权限?

Docker in Docker?其实太复杂,有兼容性问题,这里提供的方案是直接连Host上面的docker daemon。

Kaniko is another option for users looking to build containers inside their clusters. Kaniko does not require a Docker daemon to be present in order to build and push images to a remote registry.这个是google推荐的,这个是怎么实现的呢?The kaniko executor image is responsible for building an image from a Dockerfile and pushing it to a registry. Within the executor image, we extract the filesystem of the base image (the FROM image in the Dockerfile). We then execute the commands in the Dockerfile, snapshotting the filesystem in userspace after each one. After each command, we append a layer of changed files to the base image (if there are any) and update image metadata. 直接操作镜像,不知道这样是否有兼容性问题。

使用Kaniko进行构建 kaniko不依赖于Docker守护程序,并且在用户空间中完全执行Dockerfile中的每个命令。 在kubernetes上构建还有另外一种选择,就是docker in docker,将宿主机的/var/run/docker.dock挂载到pod,并使用宿主机Docker守护程序执行构建。但是docker in docker必须运行在特权模式下,这会产生安全风险。我不禁想:jenkins X是用的什么技术呢?原来是tektoncd,这个很强,可以用自己格式定义pipeline CRD,看了下,似乎build docker用的也是kaniko。看来我的方案最终要用的也是这个。jenkin x用这个,那自己的pipeline有啥用呢?感觉只是一个皮而已了。

取消 Jenkins job 的时候还在运行的 Pod 会被 kill 掉,这个不错。

创建一个 Pod 模板定义: https://github.com/GoogleContainerTools/kaniko#running-kaniko-in-a-kubernetes-cluster an example of using Kaniko in Jenkins

push 到哪里去呢?既然这个 kaniko 支持 –insecure –skip-tls-verify,直接自己搭建一个?但是这样后续k8s安装不是也得相应配置。

权限配置可以通过ConfigMap传入,但是我的一直报错:

MountVolume.SetUp failed for volume "volume-0" : configmap " docker-config" not found 

我用了个BusBox 测试,可以 mount,查看两者的yaml,并无不同。仔细查看,我上面” docker-config”多了个空格😂 还好错误信息这里用引号,否则是怎么也看不出来了(一个好的日志显示方式)。 这里很重要:根据yaml就能完全掌握一个Pod,而不是代码的细节有区别。yaml就是标准,这样不管pod是如何创建的(手工yaml或者程序yaml),这些都没有区别。yaml就是html,就是标准,运行结果就是渲染结果,一样的html,没有可能渲染结果不一样,不一样结果肯定是yaml不同。

push镜像出现问题:

error pushing image: failed to push to destination index.docker.io/fkpwolf/spring-boot-k8s-hpa:pp1: BLOB_UPLOAD_UNKNOWN: "blob upload unknown to registry"

这个Dockerfile里面有两阶段,这个是怎么push的呢?先搞个直接运行kaniko的例子吧:

apiVersion:v1kind:Podmetadata:name:kanikospec:containers:-name:kanikoimage:gcr.io/kaniko-project/executor:debug-539ddefcae3fd6b411a95982a830d987f4214251args:["--dockerfile=/demo/Dockerfile","--context=/demo","--insecure=true","--skip-tls-verify=true","--destination=fkpwolf/spring-boot-k8s-hpa:pp1"]volumeMounts:-name:docker-configmountPath:/kaniko/.docker/-name:project-volumemountPath:/demorestartPolicy:Nevervolumes:-name:docker-configconfigMap:name:docker-config-name:project-volumehostPath:path:/home/centos/flask-demonodeSelector:kubernetes.io/hostname:k8s-3-new

这里用到了hostPath作为直接读取的目录,这样不用git来下载,为了不用每个主机上面准备这个目录,用了nodeSelector来标明,这样我只用在这个节点上准备目录就可以。

还是一样的Push 失败。难道是我docker-config内容是错误的?删除这个卷,还是一样的错误,认证方式不对?好吧,我试试其他的 docker registry:

[centos@k8s-1 ~]$ helm install stable/docker-registry --namespace cicd --set persistence.enabled=true
NAME:   lumbering-starfish
LAST DEPLOYED: Sat Jun  8 13:05:07 2019
NAMESPACE: cicd
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME                                AGE
lumbering-starfish-docker-registry  0s
==> v1beta1/Deployment
lumbering-starfish-docker-registry  0s
==> v1/Pod(related)
NAME                                                 READY  STATUS   RESTARTS  AGE
lumbering-starfish-docker-registry-564bbc7457-rrmgl  0/1    Pending  0         0s
==> v1/Secret
NAME                                       AGE
lumbering-starfish-docker-registry-secret  0s
==> v1/ConfigMap
lumbering-starfish-docker-registry-config  0s
==> v1/PersistentVolumeClaim
lumbering-starfish-docker-registry  0s
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace cicd -l"app=docker-registry,release=lumbering-starfish"-ojsonpath="{.items[0].metadata.name}")echo"Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:5000

这个默认都不要用户名和密码,上面构建测试成功,看来还是 push 时认证的问题导致。

  • curl 192.168.51.11:30704/v2/_catalog可以看到remote repository列表
  • curl 192.168.51.11:30704/v2/spring-boot-k8s-hpa/tags/list列出所有tags

使用Kaniko进行构建这个是push到harbor上面,有配置证书。

最后的 pipeline 定义为:

#!groovypipeline{agentanystages{stage('build'){steps{git'https://github.com/learnk8s/spring-boot-k8s-hpa.git'container(name:'kaniko',shell:'/busybox/sh'){sh'''#!/busybox/sh
                    /kaniko/executor -f `pwd`/Dockerfile -c `pwd` --insecure --skip-tls-verify --cache=true --destination=192.168.51.11:30704/spring-boot-k8s-hpa:pp2
                    '''}}}stage('deploy to k8s'){steps{echo"start to deploy"container('kubectl'){sh("kubectl get nodes")}}}}}

下一步可以看看如果启用 docker registry 用户认证,pipeline 能否还能正常运行。

Inside

  • Jenkins Pod 常驻运行,Agent Pod 动态创建,对应一次构建
  • Agent Pod 包含多个容器,在 Kubernetes plugin 中配置或者定义在 pipeline 里面

这种运行模式对已有系统改变很小,Jenkins 也可以直接在操作系统上面运行。

插件

https://wiki.jenkins.io/display/JENKINS/Kubernetes+Plugin

https://github.com/jenkinsci/kubernetes-plugin

  • src/main/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplate.java 这个是对应 web ui form 的pojo
  • src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesLauncher.java 启动 pod
  • src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlave.java 调用 k8s,用的是io.fabric8.kubernetes.client.KubernetesClient
  • src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapter.java 连接 k8s,用的是fabric8的ConfigBuilder和DefaultKubernetesClient类,https://github.com/fabric8io/kubernetes-client This client provides access to the full Kubernetes & OpenShift 3 REST APIs via a fluent DSL,Java 的客户端,能和 go-client比较么?

fabric8是一个开源集成开发平台,为基于Kubernetes和Jenkins的微服务提供持续发布,也是一个蛮大的 java 微服务平台,似乎已经停止开发了。也是 RedHat 的项目,可惜了啊。


Ceph on K3OS - 一种快速部署 Ceph 的方法

$
0
0

目的

创建一个高性能的 Ceph 集群,来为另外一个 k8s 集群提供快存储服务。

使用 k3os 部署 Kubernetes

一个 master node + 三个 work node,每个 work node 连接一个 NVME 磁盘。

virt-install \--import--disk /var/lib/libvirt/images/test1.qcow2,bus=virtio \--name k3os \--ram 2000 \--vcpus 2 \--disk /var/lib/libvirt/images/k3os-amd64.iso,device=cdrom \--bootkernel=/var/lib/libvirt/images/k3os-vmlinuz-amd64,initrd=/var/lib/libvirt/images/k3os-initrd-amd64,kernel_args="console=tty1 console=ttyS0 k3os.fallback_mode=install \
k3os.install.silent=true k3os.install.tty=ttyS0 k3os.install.device=/dev/vda \
k3os.install.config_url=https://temp.blob.core.windows.net/file/config.yaml \
k3os.password=rancher"\--console=pty,target_type=serial \--os-type linux \--os-variant generic \--host-device=pci_0000_09_10_0 \--nonetworks\--graphics none

上面的 config.yaml 文件内容:

ssh_authorized_keys:-"ssh-rsaAAAAB3NzaC1y...fan@fans-iMac.lan"-"github:fkpwolf"k3os:k3s_args:-server-"--disable-agent"

该命令可以:

  1. 创建的虚机启动后会自动安装 k3os,不需要手工干预
  2. config.yaml 主要保存登录公钥
  3. host-device 用来做 pci 穿透,这里赋予了两个 pci 设备:网卡和 NVME 卡

使用这种命令行的方式比用图形化的 virt-manager 优势在于:

  1. 可以使用 tty 串口直接访问控制台,可能需要和上面一样传递内核参数
  2. 传递参数更为快捷

部署 Rook Ceph

配置hostNetwork: true,这样外部(另外一个 k8s 集群)就可以直接通过外部 IP 来访问 Ceph MON,否则默认是 k8s 内部 ClusterIP。设置好后,kubectl get pods -n rook-ceph -o wide会看到外部 IP 地址。

使用

Think

如果把 Ceph 集群和 k8s 集群合在一个大集群里面,资源利用率会比这种分离模式更高,这里只是测试的目的。在现在 k8s 弱多租户的情况下,分离也许是种常见场景。

驱动 Ultrafine 5K 显示器

$
0
0

各系统支持情况

Windows HiDPI 支持算是最好的:

  • 可以支持更多 scale 倍数
  • 不同屏幕可以用不同 DPI
  • 窗口拖动的时候可以跨屏显示,Mac 会截掉一半

Windows 下面 250% 的放大比例最为完美。Gnome 下面 200% 放大比在 4k 下表现好很多,4k 下 200% 放大会让窗口组件过大而显得不够精细, 而 Linux Fractional Scaling还不成熟。

主板

  • MEG Z590I UNIFY有两个 DP IN 接口,3K 太贵了,特别是只支持 11 代CPU,不支持 MacOS。但是两个 DP IN 算是最高规格了,BIOS里面也有雷电相关的详细配置。MEG Z590 ACE也有两个 DP IN。
  • ProArt B550-Creator, one DP-IN. BIOS里面雷电选项还挺丰富。”PCIe 3.0 x4 will be switched from Thunderbolt™ 4 to PCIEX16_3 if the slot is populated; by then Thunderbolt™ 4 will have no output” Z490也是这样,因为没有足够的PCI条数。
  • B550 VISION D-P all has one DP-IN. 2k. But not mATX board. Manual doesn’t show thunderbolt menu in detail - same as B550M AORUS. tonymacx86 details guide on this board.
  • ASRock X570 Phantom Gaming-ITX/TB3 amazon.cn 1700¥. BIOS Manual has no thunderbolt info. 似乎一个DP IN只能支持最高4K显示。
  • PRIME X299-DELUXE II, 技嘉 X299X AORUS Designare都有两个dp in,两个雷电口。就是板子太贵,平台有点老,cpu 似乎还可以,7940x/7960x/7980xe 价格都不贵。
  • Z490主板里面支持 2 DP in 的似乎只有华硕 PROART Z490-CREATOR 10G,而且 BIOS 里面的功能也很全。完整的OpenCore文件,似乎已经被研究的很透彻了。可惜规格这么高的z490大板只有少的可怜的pci通道&CPU太老,真实使用起来和我的 B460m 差不多吧。
  • 10代Intel cpu中 10850k 比较有性价比,10核心20线程,2400¥。
  • 超微X11SRA有雷电header,但是BIOS不支持,这么多PCI-E,真是可惜了。这里说可以在没有header的超微X11DPH-T上面实验成功,奇怪了,多半是默认开启,但是pre-boot肯定是没有了。
  • Pro WS W480-ACE,两DP IN,支持CPU有10代,11代和Xeon W,不过PCI条数似乎没啥亮点

雷电扩展卡

https://www.gigabyte.com/Motherboard/GC-TITAN-RIDGE-rev-20#kf https://www.gigabyte.com/Motherboard/GC-TITAN-RIDGE-rev-10#kf 居然连AMD B550也支持,B550M AORUS PRO感觉这个还可以,DP接口支持5K,如果配个APU就可以省下显卡钱了。 https://www.chiphell.com/thread-1955259-1-1.html TITAN RIDGE 不需要雷电header就可以,有时候需要短接。 Z490支持DP IN的,也就是支持5k输出的是Z490 VISION D。 https://cn.msi.com/Motherboard/Z490M-S1/Specification 这个主板规格比较完美,不过是微星的,技嘉的扩展卡不知道是否兼容。或者MAG B460M MORTAR 迫击炮感觉也行,有雷电口5pin JTBT1,这个OC支持的更多 https://heipg.cn/tutorial/b460m-install-big-sur.html。好玩是的从规格书上看是微星这个板子有两个thunderbolt接口: GC-TITAN-RIDGE-20的规格书也有这两个接口。Z490/B560M AORUS PRO AX技嘉的板子也有两个雷电header,B550M AORUS PRO则只有一个。问题是技嘉的扩展卡和主板都没有详细列出header的定义,所以不确定微星的主板是否和技嘉的扩展卡兼容。这个 RTD3 好像是“现代待机”(Modern Standby)的东西。

技嘉Titan ridge v1.0使用:固件要升级,否则无法视频输出。主板没有thunderbolt header,1//3要短接,USB 接口要连接,否则难以激活。 HP Elite 90W Thunderbolt 3 Dock,这个也要更新固件,否则接在Ultrafine上面的USB鼠标键盘容易卡顿,和固件没有关系。现在这个Dock的唯一问题是接在Ultrafine上面的usb键盘无法进入BIOS。我在thunderbolt 控制中心看到安全性级别是“用户身份验证(SL1)”,我的冥王峡谷能进是因为安全级别比这个低么?

确实,我修改NUC BIOS后为“无安全性(SL0)”,但是我也没法在技嘉主板BIOS里面修改啊。https://github.com/ameyrupji/thunderbolt-macpro-5-1/blob/master/GC-TitanRidge.md 这里有刷机的步骤。后来发现这个技嘉板子里面可以修改,修改后进入thunderbolt controller center也能看到security level改变了,我改为none。但是启动后发现雷电下面usb无法链接,重启也不行,只有热拔插雷电线可以,只能改回默认的 user auth。似乎这个如果bios里面修改了值,bios启动时会修改雷电扩展卡配置,但是不知道是因为和主板不兼容,还是我没有连接header,导致启动后OS虽然能看到修改后的安全级别,但是功能出现问题。这个是我的猜测。 B550M AORUS BIOS 没有pre-boot acl支持怎么办?可以试试去掉mortar的雷电header改为短接,如果pre-boot还是可以工作,那说明这个功能完全是由bios控制。 用AMIBCP看了b550m vision d板子的Bios,选项也很少。不是说技嘉的雷电支持是最好的么? 这个板子问题也挺多:

  1. 关机变成重启,我再BIOS里面关掉了ethernet weak on lan,可以关机,但是在windows日志里面还是有意外关机的错误
  2. “跟这台计算机连接的一个USB设备运行不正常“,导致ultrafine下级的usb无法工作。有的地方说”出现该问题只有两个原因:一是数据线问题,二是主机电压问题。“ 真是麻烦啊。
  3. 换回titan ridge v1.0后在user auth安全模式下似乎稳定了些。错觉
  4. 关掉windows的快速启动,在user auth模式下似乎很稳定了。no auth还是老问题。
  5. 使用”测试架PCB夹子治具夹具探针”接上thb 5pin口,问题依然,和短接没区别,只是可以正常关机了。看来要pre-boot 键盘支持的话必须bios支持
  6. user auth下,发现关机后无法连接,后来还是必须关掉windows的快速启动

MAG B460M MORTAR

v11 bios菜单里面有雷电,虽然问题多多(雷电设备能看到,但是USB和PCI网卡都看不到)。但是v14居然去掉了。v13 changelog 我看还有改进 Thunderbolt functional patch. 换成v13,问题解决。 security level我如果改成none,和上面技嘉B550m一样的问题:usb 无法连接。有时候第一次可以,但是重启后就不行了。改成user auth好很多,但这样和上面其实效果一样。所以关键还是在这个雷电扩展卡?这个板子bios里面雷电选项很多,比如从雷电启动。 这里设置pre-boot ACL就可以用接在雷电上面的鼠标键盘进入BIOS了,不管这个键盘是接在一级还是二级雷电设备下。微星的这个BIOS太强了,还是 intel 做的好?这里看MSI MEG Z590I Unify也是支持pre-boot ACL的了。 为什么冥王峡谷反而没有?这里说这个版本的驱动是支持的啊:

Added support for PRE-BOOT ACL feature (deprecating previous implementation from 17.1.64.250): Devices that can be used for boot or during pre-boot need to be pre-approved. Pre-Boot ACL solution enables device pre boot approval by maintaining an access control list in the FW as well

但是nuc bios里面没有看到对应的配置。看看其thunderbolt nvm version is just 33.0,但是 NUC 官网也没有新的版本。 我猜测进入windows系统后动态的启用和批准设备的pre boot,这样重启后启动就能在启动阶段使用键盘。 其实后来测试这个NUC对pre-boot支持的已经挺好了,虽然bios里面没有,默认似乎是已经开启了。

雷电 4

https://www.gigabyte.com/Motherboard/GC-MAPLE-RIDGE-rev-10#kf 这个表明支持5k,我看也是Display Port 1.4。这个也可以。https://www.msi.com/Motherboard/MAG-B560M-MORTAR/Specification 微星这个性价比的选择1x TBT connector (Supports RTD3) 。这个B560M AORUS PRO AX白雕也挺好看。 Asus Thunderbolt EX3-TR,新版本,居然不支持mATX的板子。14-1 pin Thunderbolt,这个只有asus板子才有这个规格吧。 Kensington Thunderbolt 4 有 4 个雷电口,看上去不错,¥2400。

显卡

https://superuser.com/questions/845302/what-specs-must-a-graphics-card-have-to-power-a-5k-monitor https://images.nvidia.com/aem-dam/en-zz/Solutions/design-visualization/quadro-product-literature/NV-DS-NVS-310-May12-US-NV.pdf https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/NVS_510_DS_Oct12_NVIDIA_LR.pdf 都支持MST,但是记得安装最新驱动。安装后直接显示一个5k显示器,否则会显示两个屏幕。

以前是ultrafine的声音设备只有先进入windows,然后重启进入macOS后,macos可以认识声音设备,但是刷bios后这个问题消失了。 似乎是pre-boot ACL问题,但是我这个应该要linux和macos自身的问题,也就是关机时设置雷电外设。 https://fedoramagazine.org/thunderbolt-how-to-use-keyboard-during-boot-time/

如果type-c或者雷电线支持视频,USB和声音传输,这就有点像KVM功能了。

发现一个WIN PC使用LG Ultrafine显示器的神器 https://www.chiphell.com/thread-2324414-1-1.html ,200¥,不知道是否支持5k

对于5k,此显示器同时支持MST和SST。用雷电卡,将双路DP1.2合并到USB-C形状的雷电,直接MST方式驱动即可;另外新款N卡,支持DP1.4输出即采用SST方式驱动,因WIN10同时支持MST和SST,所以两种方式很容易驱动。但是HACKINTOSH驱动5k只能采取MST方式,系统原生不支持SST驱动5k,所以只能采取win10的第一种方式,即利用雷电卡将两路DP1.2合并到USB-C形状的雷电,驱动显示器。 https://www.chiphell.com/forum.php?mod=redirect&goto=findpost&ptid=2327490&pid=47599622 贝尔金CV10 线(DP转 TYPEC) 据说可以直接搞定。不过不是雷电方案,要拖几根usb线,感觉违背了雷电初衷。

雷电扩展坞

OWC Thunderbolt 3 Pro 配有 10 Gb 以太网连接 startech.com thunderbolt 3 DOCK 感觉就这个便宜点 HP雷电扩展坞 HP Elite 65W Thunderbolt 3 Dock,如果接usb键盘鼠标,冷启动OpenCore中无法操作键盘鼠标,重启可以操作。 为什么 ultrafine 的usb键盘可以操作呢?usb 2.0 hub?ultrafine也不是所有情况都可以:只有windows关机和重启后才可以。如果是linux关机后开机,一样问题。 上面的ASM1042A要到HP官网上才能下载驱动,Windows 默认没有带驱动。真是辣鸡啊。(默认似乎有驱动,但是安装titan ridge后没法驱动了)

Belkin Thunderbolt 3 Express Dock HD, F4U095 https://www.belkin.com/th/support-article?articleNum=216428 没有windows驱动和固件更新下载 据说Windows下面没法PD输出电流,买的有点唐突

总结

总的看来,雷电的理念确实不错:一根线能传输电和数字信号,这对桌面的整洁至关重要,特别适合某些场景:

  1. 笔记本接显示器工作模式
  2. 多个台式机共享显示器。一般用 KVM 切换来解决这个问题,但是如果接高分辨率显示器, 可惜的是,因为是 Intel 的方案,存在不少兼容性问题。

直接在 KVM 上面使用 cloud-init image

$
0
0

Image list

https://cloud-images.ubuntu.com/releases/16.04/release/ .img是给QEUM和KVM用,.vhd是给Azure用,vmdk是给Vmware用。一般这些是在 OpenStack 这样的 IaaS 平台上面使用。这里描述如何在安装有 KVM 的普通 Linux 机器上面使用这些 Image。

https://cloud.fedoraproject.org/ Fedora cloud image,比 Ubuntu 兼容性好。

https://get.opensuse.org/leap/ Jeos is for cloud. Leap is normal version, Tumbleweed is rolling update. openSUSE MicroOS is a variant of openSUSE Tumbleweed and serves as a base of openSUSE Kubic, a Container as a Service platform. Guide of kubeadm’s installation container runtimes uses Tumbleweed. KVM and XEN version of JeOS image is cool: need interactive installation and it is fast. Doesn’t need extra disk for OS so boot image is enough. OpenStack-Cloud filesystem is xfs and 1G size. KVM and XEN filesystem is btrfs and 26G size. But Tumbleweed KVM version didn’t have igbvf driver. Crazy! Need zypper install kernel-default. It is 5.11.11. So what is stock or default kernel version?

https://download.rockylinux.org/pub/rocky/8.4/images/ Rocky Linux cloud image.

今天发现了个新的 Linux Amazon Linux 2 https://aws.amazon.com/cn/amazon-linux-2/faqs/ 亮点何在呢?主要特点就是安全?

Create VM

  • https://people.redhat.com/mskinner/rhug/q3.2014/cloud-init.pdf
  • cloud-init 工作原理 - 每天5分钟玩转 OpenStack IBM DW.
  • 手工要专门的办法做cloud-init http://ubuntu-smoser.blogspot.com/2013/02/usooing-ubuntu-cloud-images-without-cloud.html把用户信息注入到里面。
## Install a necessary packages $ sudo apt-get install kvm cloud-utils genisoimage 
## URL to most recent cloud image of 12.04 $ img_url="http://cloud-images.ubuntu.com/server/releases/12.04/release"$ img_url="${img_url}/ubuntu-12.04-server-cloudimg-amd64-disk1.img"## download the image $ wget $img_url-O disk.img.dist 
## Create a file with some user-data in it $ cat> my-user-data <<EOF 
#cloud-config 
password: passw0rd 
chpasswd: { expire: False } 
ssh_pwauth: True
ssh_authorized_keys: 
  - ssh-rsa AAAAB3NzaC1yc2EAAAADABUB... fan@fandeiMac.lan
EOF 
## Convert the compressed qcow file downloaded to a uncompressed qcow2 $ qemu-img convert -O qcow2 download-disk.img disk.qcow2 
## create the disk with NoCloud data on it. $ cloud-localds my-seed.img my-user-data 
If not the command, run: genisoimage  -output seed.iso -volid cidata -joliet-rock user-data meta-data 
## Create a delta disk to keep our .orig file pristine $ qemu-img create -f qcow2 -b disk.qcow2 disk-new.img 
## Boot a kvm $ kvm -net nic -net user -hda disk.img -hdb my-seed.img -m 512

密码似乎不能用123123这种简单的。完整的 user-data 可以参考 http://cloudinit.readthedocs.io/en/latest/topics/examples.html,更多操作指南参考 KVM / libvirt。

上面配置要是能设置 static IP 和 hostname 就好了,有点怀念 vagrant。

网络

详细配置看 http://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html https://gist.github.com/smoser/635897f845f7cb56c0a7ac3018a4f476 这个提供了样例和调试的方法。 其中match的方法对于我来说没啥用,因为mac地址是virtual function的,不固定。用match driver igbvf,发现: Kernel driver name, corresponding to the DRIVER udev property. Globs are supported. Matching on driver is only supported with networkd.

找了一圈,只有Fedora用的是systemd networkd,其他用的都是/etc/network/interface 这种老式的方式。 但是其cloud-init log里面有错误:AttributeError: ‘NoneType’ object has no attribute ‘iter_interfaces’ 嗯,centos呢?也是一样的错误。发现 centos7 (kernel v3.10) vm 启动很快,比 ubuntu 16.04 快多了。16.04 cloud image hangs at first boot,原来这个和 TTY有关系。但是我看 virt-manager 默认已经帮我生成好了啊。又尝试了下 Debian cloud image,也很快。 仔细查看上面 v2 文档,发现其需要 netplan,这样只有 Ubuntu 17.10 支持了?v1 我试过是可以的,但是其只能用 mac 地址匹配。

为什么每次启动 vm 后其virtual function mac地址会变呢?算了,最后我还是自己修改 os 配置为静态 ip 地址。对于 Centos,要删除 /etc/sysconfig/network-scripts/ifcfg-ens3 文件里面的 HWADDR=xxx 和 BOOTPROTO=dhcp 的配置。

Resize image

Ubuntu cloud image default size is 2GB, you can use ‘qemu-img info a.img’ to check details. To resize it:

  1. You need to convert the qcow2 image to raw qemu-img convert -O raw guest.img guest.raw
  2. Then resize the raw file qemu-img resize guest.raw 10G
  3. Then convert it back to qcow2(this will create 1G file, 1G = 10G * 0.10) qemu-img convert -O qcow2 -o compat=0.10 guest.raw guest.img.10g
  4. Then run the guest and resize your file system

Using this way, ubuntu need lots of time to boot. It hang on “ systemd:started journal service”. I thought it was because I used virtIO disk or a small virtual image as disk. But at last it turn out Centos use xfs filesystem, after reboot, disk was enlarged.

Check snapshot file details:

fan@ubuntu-gg:~$ qemu-img info vm2.img
image: vm2.img
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 196K
cluster_size: 65536
backing file: ubuntu-16.04-server-cloudimg-amd64-disk1.img.10g
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

It is small now but increase fast and soon it will be same size as original file.

Useful commands

virt-install --import --disk /var/lib/libvirt/images/focal-server-cloudimg-amd64-disk-kvm.img,bus=virtio --name vm1--ram 2000 --nographics

https://quantum-integration.org/posts/install-cloud-guest-with-virt-install-and-cloud-init-configuration.html –nographics option forces virt-install to redirect the console output to the terminal window. After successful boot you get to the vm promt:

For Debian, it will start an install dialog.

virt console vm to connect running vm. The default escape key - to exit: ^[ ( Ctrl + [ )

Installing a KVM Guest OS from the Command-line (virt-install) command reference

KVM Install from Console

virt-install -n nwtest --description Test -r 512 --vcpus 1 \ 
   --location http://ftp.ca.debian.org/debian/dists/squeeze/main/installer-amd64/ \ 
   --os-type=linux --os-variant=debiansqueeze\ 
   --disk /srv/virtual/nwtest,device=disk,bus=virtio,size=3 \ 
   --network bridge=br0,model=virtio \ 
   --autostart \ 
    --nographics \ 
   -x "console=tty0 console=ttyS0,115200n8" 
Directly install from scratch, step by step. the location parameter specific kernel and initrd address. It is net-install indeed.

virsh domxml-to-nativethis command can convert virt instance into a vm creation command.

各种 Database

$
0
0

企业上云系列之开源数据库的现状 http://www.infoq.com/cn/articles/situation-of-the-open-source-database 对于很多应用来说,其领域对象模型并不适合于转换成关系数据库形式来存储。这也是非关系型数据库(NoSQL)得以流行的原因。NoSQL 数据库的种类很多,包括键值对数据库、面向文档数据库和图形数据库等。

http://nosql-database.org/ 所有的 nosql 数据库

https://db-engines.com/en/ranking DB-Engines Ranking

https://use-the-index-luke.com/ Use The Index, Luke!

SQLite Is Serverless

  • https://www.sqlite.org/serverless.html
  • https://www.sqlite.org/whentouse.html

为什么数据库不应该使用外键 https://draveness.me/whys-the-design-database-foreign-key/ 为什么 MySQL 使用 B+ 树 https://draveness.me/whys-the-design-mysql-b-plus-tree/

国内的数据库博主

  • https://www.zhihu.com/people/fuyufjh/posts
  • https://www.zhihu.com/column/c_1037748468491689984
  • https://draveness.me

Leveldb 和 RocksDB

Leveldb 和 RocksDB 在大 value 场景下的一些问题 http://idning.github.io/leveldb-rocksdb-on-large-value.html 获得PCC性能大赛第一名方案背后的 RocksDB 引擎:5分钟全面了解其原理 http://weibo.com/ttarticle/p/show?id=2309404088129911940161 RocksDB 是基于levedb,借鉴了hbase思想。据说为 SSD 这种存储做了优化。

小米分布式 Key-Value 存储系统基于 RocksDB 对比了 HBase 的缺点

既生 Redis 何生 LevelDB ?

几款主流 NoSql 数据库的对比 http://www.cnblogs.com/vajoy/p/5471308.html leveldb 和 mongodb 很像,但是作为一个数据库后者功能更全面,前者性能是好,但只是一个库。 浅析 Bigtable 和 LevelDB 的实现 http://draveness.me/bigtable-leveldb.html 实现和hbase比较像,但是leveldb用了memtable作为磁盘table的中介和缓存,性能会提高,而hbase则偏向大数据情况下的处理。主要是 Leveldb 不支持分布式。

【Rocksdb实现及优化分析】 JoinBatchGroup http://kernelmaker.github.io/Rocksdb_Study_1 TiDB 底层也基于这个

badger https://github.com/dgraph-io/badger separating values from keys, significantly reducing the write amplification compared to a typical LSM tree. badger 一个高性能的LSM K/V store如何评价 Badger (fast key-value storage)?“基本思路是RocksDB基于LevelDB为SSD优化,但不是为SSD尤其是目前超高随机读写能力的NVME SSD设计.” badger 事务过程笔记

LeanStore

a high-performance OLTP storage engine optimized for many-core CPUs and NVMe SSDs. https://dbis1.github.io/leanstore.html Talk https://twitter.com/andy_pavlo/status/1389042478796492800

Cassandra

Netflix 用的比较多 分布式 Key-Value 存储系统:Cassandra 入门 https://www.ibm.com/developerworks/cn/opensource/os-cn-cassandra/ 关于Cassandra的错误观点 http://www.infoq.com/cn/articles/cassandra-mythology https://zh.wikipedia.org/wiki/Cassandra 宽列存储模型(Wide Column Stores) ScyllaDB Cassandra优化版本,DPDK,开源。对 Linux 网络,缓存做了很多改变,是一个传统软件优化的很好例子。 https://www.zhihu.com/question/35956679 https://www.scylladb.com/2018/03/29/scylla-kubernetes-overview/ https://github.com/scylladb/scylla-code-samples/blob/master/kubernetes-scylla/README.md 优化程度这么高,运行在 k8s 上面还有优势么?

RethinkDB

听说最近死而复生,而且号称实时 web 开发,”RethinkDB是第一个数据库使用了一种令人激动的新的数据库的访问模型,而不是轮询数据库更改,开发者可以命令RethinkDB实时的向应用连续推送更新查询结果。” http://www.infoq.com/cn/news/2017/02/RethinkDB-join-Linux 一个数据库怎么和 web 开发关系起来?试试看。 伯克利推出世界最快的KVS数据库Anna:秒杀Redis和Cassandra https://zhuanlan.zhihu.com/p/34603927 https://www.rethinkdb.com/docs/install/ubuntu/ 然后 https://www.rethinkdb.com/docs/quickstart/ rethinkdb –bind all,可以 bind 所有的端口而不仅仅 localhost。 启动后会在8080端口打开一个 ui,设计的还是相当专业。 运行了几个命令,还行。不过还是没有看到后段怎么推送查询结果。 https://www.rethinkdb.com/docs/guide/javascript/ node.js 作为客户端调用,我 mac 上运行 js 。 node 作为消息驱动的开发模式和这个类型的数据库很匹配啊。怎么和前端交互?websocket? 实时推送查询结果,似乎很牛。不过应用场景比较少,二则这种性能的问题容易被转移成其他问题。 https://github.com/rethinkdb/rethinkdb 这里面有提供他的使用场景,都是和实时紧密相关。

Riak

《Designing Data-Intensive Applications》提到较多 类 Dynamo 的分布式 Key-Value 系统,Erlang 编写,Bitcask为其存储引擎 支持 global secondary index by term HaloDB https://github.com/yahoo/HaloDB/blob/master/docs/WhyHaloDB.md,类似 Bitcask 解决 LSM 写放大的问题,Java 编写 “an index in memory which stores all the keys, and append-only log files on the persistent layer which stores all the data” 混合的技术

YugabyteDB

https://github.com/yugabyte/yugabyte-db YugabyteDB 介绍 partition https://docs.yugabyte.com/latest/architecture/docdb-sharding/ a new term ‘tablet’. master server: keep metadata & coordinate. TServer: query & storage. The arch is some like HBase.

FoundationDB

苹果公司开源FoundationDB的简单分析『和其他NoSQL不一样的是,FoundationDB的Key-Value Store实现了强一致性,而非最终一致性』大数据时代的Key-Value Store大体上分为两类:

  1. 以BigTable和HBase为代表的,分区键(Partition Key)全局排序,通常采用的是范围分区(Range Partition)
  2. 以AWS DynamoDB和Cassandra为代表,分区键(Partition Key)不排序,通常采用的是哈希分区(Hash Partition)

https://apple.github.io/foundationdb/getting-started-linux.html 安装挺容易,集群也不复杂,依赖很少,果然是苹果出的,用户体验不错。https://apple.github.io/foundationdb/class-scheduling.html 这个是实例一般的 CRUD 操作,非 sql 语法,虽然有点像 k-v 操作,但是是支持事务的。https://www.voltdb.com/blog/2015/04/01/foundationdbs-lesson-fast-key-value-store-not-enough/ Plans for SQL Layer? issue 也就是说 sql 现在还不能用,tidb 作者建议使用 tidb 的 sql layer,说是已经抽象,但是 foundationdb 已经支持 acid 了,并非一个简单的 k-v 数据库,而且 tidb 有个 pd,这个在 fdb 没有对应的吧?https://github.com/opentradesolutions/opentick 这个提供了初步的 sql layer 支持。 『在核心外, FoundationDB通过分层设计的方式,实现了对各种数据模型,比如文档数据库,图数据库,关系数据库的支持。』这个也是 https://www.foundationdb.org/ 上面说的首要特征:Multi-model data store,https://apple.github.io/foundationdb/layer-concept.html 这里解释一般选择数据库就选择了数据模型(关系、文档)和存储引擎以及访问方式(REST, SQL),而用分层的概念解耦了数据模型和存储引擎,FDB 的 k-v 存储引擎能用在各种数据模型上面,而这种灵活性(其他 k-v 数据库也有)不丢失 ACID。 其文档写的很全,不错。

非通用数据库

  • https://db-engines.com/en/system/LokiJS%3BLovefield%3BPouchDB System Properties Comparison LokiJS vs. Lovefield vs. PouchDB JavaScript 数据库,轻量级,可以在客户端(浏览器、手机)运行,然后同步整个db data to server side. Azurite is an open source Azure Storage API compatible server (emulator) 有用到。
  • https://www.arangodb.com/ 专门为图算法优化的数据库。
  • TSDB

国内数据库

  • TiDB
  • openGauss 华为开源的数据库 https://opengauss.org/zh/
  • ZNBase 浪潮的分布式数据库 http://www.znbase.com/
  • 淘宝 OceanBase融合了 mysql 的事务并且兼容 mysql,以及用了 leveldb 类似的内存写的技术,不过虽然开源但是 commit 特别少,现在已经成为阿里云上面的一个产品了。

比较传统数据库

CAP理论十二年回顾:”规则”变了 http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed 现在是三选二,舍弃部分性质。这里比较了各个k-v 支持 CAP 的程度。 查找慢写快适合一些场景比如log写入,要查找快就只能 map-reduce 了?或者 SSD。所以对于一般业务对读写没有特别要求还是 mysql 这种在线数据库安逸点,即便是 facebook 也用 mysql,号称世界最大,当然他还混合很多其他技术。对于facebook大多数业务特别是其图片,读操作是远大于写操作的,所以其用了大量的 cache 来提高性能。Scaling Memcache At Facebook 翻译这里也是用 k-v 技术,不过这个k-v 就是像 redis 了,基于内存的缓存系统。

Google Cloud Spanner https://cloud.google.com/spanner/?authuser=1&hl=zh-cn 第一种可横向扩展、高度一致的关系型数据库服务,只有商业数据库这么大而全,比如CosmosDB。 这种在大数据量的情况下如何保证网络带宽?还是整套方案都用它的?原来这些统一叫 NewSQL NewSQL究竟新在哪里?「企业上云」系列之开源数据库的现状,TiKV 作者,也比较了很多各种类型的数据库。 https://aws.amazon.com/cn/products/databases/ AWS 产品很多,类似的似乎是Aurora,关系数据库,还有 RDS。https://www.percona.com/blog/2018/07/17/when-should-i-use-amazon-aurora-and-when-should-i-use-rds-mysql/ 区别在于 RDS 对 MYSQL 引擎兼容性更好 阿里的RDB似乎也是newsql https://cn.aliyun.com/product/rds NoSQL没落了?NewSQL有机会挑大梁吗?解释了一堆其他的 newsql 数据库,从这些项目的实现架构来看,主要分为两种:

  • 原生实现:如CockroachDB、YugaByteDB
  • NoSQL+ACID+SQL:如TiDB、Trafodion

cockroachdb和 tidb 一样是基于 rocksdb 啊,为什么不同呢?这个参考是 tidb 老版本基于 hbase 的?刘奇:如何使用HBase构建NewSQL?老版本的 tidb 是基于 hbase 的吧,现在应该已经换了。HBase进化之从NoSQL到NewSQL,凤凰涅槃成就Phoenix用的还是官方项目phoenix。可惜 hbase 是 java 的并且运行在 hadoop 上面,依赖带笨重了。

一分钟搞懂列式与行式数据库行式更适合OLTP,比如传统的基于增删改查操作的应用。列式更适合OLAP,非常适合于在数据仓库领域发挥作用,比如数据分析、海量存储和商业智能;涉及不经常更新的数据。 Hbase 列式存储,传统的关系型数据库,如Oracle、DB2、MySQL、SQL SERVER等采用行式存储法,TiDB 典型的 OLTP 行存数据库

TiDB HTAP 深度解读“TP 和 AP 传统来说仰赖不同的存储格式:行存对应 OLTP,列存对应 OLAP。” “使用写优化方式存储变更数据,然后逐步将更新部分归并到读优化的主列存区” 如何看待王垠对数据库的理解?我们对比了5款数据库,告诉你NewSQL的独到之处 https://mariadb.com/kb/en/library/mariadb-columnstore/ 传统的数据库也在演变

OLTP和OLAP的区别

联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改。比如在银行的一笔交易记录,就是一个典型的事务。OLTP的特点一般有:

  1. 实时性要求高。我记得之前上大学的时候,银行异地汇款,要隔天才能到账,而现在是分分钟到账的节奏,说明现在银行的实时处理能力大大增强。
  2. 数据量不是很大,生产库上的数据量一般不会太大,而且会及时做相应的数据处理与转移。
  3. 交易一般是确定的,比如银行存取款的金额肯定是确定的,所以OLTP是对确定性的数据进行存取
  4. 高并发,并且要求满足ACID原则。比如两人同时操作一个银行卡账户,比如大型的购物网站秒杀活动时上万的QPS请求。 联机分析处理OLAP(On-Line Analytical Processing) 是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。典型的应用就是复杂的动态的报表系统。OLAP的特点一般有:
  5. 实时性要求不是很高,比如最常见的应用就是天级更新数据,然后出对应的数据报表。
  6. 数据量大,因为OLAP支持的是动态查询,所以用户也许要通过将很多数据的统计后才能得到想要知道的信息,例如时间序列分析等等,所以处理的数据量很大;
  7. OLAP系统的重点是通过数据提供决策支持,所以查询一般都是动态,自定义的。所以在OLAP中,维度的概念特别重要。一般会将用户所有关心的维度数据,存入对应数据平台。 总结: OLTP即联机事务处理,就是我们经常说的关系数据库,增删查改就是我们经常应用的东西,这是数据库的基础;TPCC(Transaction Processing Performance Council)属于此类。 OLAP即联机分析处理,是数据仓库的核心部心,所谓数据仓库是对于大量已经由OLTP形成的数据的一种分析型的数据库,用于处理商业智能、决策支持等重要的决策信息;数据仓库是在数据库应用到一定程序之后而对历史数据的加工与分析,读取较多,更新较少,TPCH属于此类。 随着大数据时代的到来,对于OLAP,列存储模式或者说nosql模式比传统意义的行存储模式可能更具优势。

Think

  • 对于私有云来说,每个微服务趋向自己创建数据库,或者自己维护的大的数据库。
  • 对于公有云来说,每个微服务会直接使用已有的多租户数据库。
  • 从技术上来说当然是公有云多租户数据库更好(技术、经济),但是国内环境下,自己维护的更多,这种情况下,NewSQL 对于升级换代吸引很大。

键盘

$
0
0

键帽

  • Cherry G80-3000 白色键盘的键帽是pbt,黑色的键盘帽是pom的
  • 关于键帽表面材质以及印刷工艺的详细介绍 https://www.wstx.com/p-20810-1
  • Filco 圣手87,虽然是ABS键帽,但是比PBT的那种磨砂感更为细腻。不过这在这种很少了。ABS 缺点是更容易打油,但是更容易做出不同色彩和配色的键帽。

轴体

  • TTC 快银轴,无段落,比较热门的轴体。
  • 佳达隆 G 黄轴,无段落,手感柔弱,但压到底后回弹有力,性价比高。
  • Box Navy 段落轴,挺硬的
  • Romer-G,罗技和欧姆龙合作出品,双触点,轴柱特殊导致很难换键帽

PCB

多模支持多种模式,比如有线、2.4G无线和蓝牙无线。大多数是一个单片机加上蓝牙模块来支持多模,这对蓝牙模块 MCU 其实是浪费。 对于热拔插键盘,PCB会包含热拔插轴座,否则需要手工直接焊接轴体到PCB上面。 不管PCB是否支持热拔插,用的轴体是通用的,只是要注意轴体有3针和5针两种规格。

组装

除了上面基本部件,还需定位板和外壳。 定位板是用来防止轴体晃动的部件。 外壳则是包含上面所有部件的外壳。常见的有GH60通用外壳,个人比较喜欢黑透款式,塑料材质,这样整块键盘可以轻松拿起,有樱桃原厂无钢板键盘的风格。

配列

所谓配列,就是键盘布局。包含数字小键盘的全尺寸的是104布局,这个最常见。去掉数字键盘但是包含F1-F12功能键的是87布局,这个算是成品键盘里面最常见了,其中IKBC是个不错的选择。 去掉F1-F12功能键和方向键就是60布局了,这个在客制化键盘里面最常见。去掉F1-F12功能键一般人还能适应,因为用的不多。但是去掉了方向键而改用组合键来实现上下左右,这个挺多人不适应。 所以就有了加上方向键的64布局。

开源键盘

软件

  • QMK https://qmk.fm/大多数有线键盘都基于这个方案
  • VIA https://caniusevia.com/修改键盘配列的一个图形界面软件。这个软件强的地方在于修改后立即生效,没有保存的动作。而且下次修改的时候会加载键盘里面的配置,所以是无缝连接。如果能让一款成品键盘,比如IKBC的支持VIA,那是极好的。不过为什么要改标准布局的键盘的布局呢?

DIY无线优联机械键盘

这种方式是拿罗技的主控板,加上定制PCB来实现键盘。因为罗技的无线技术还是很牛的:省电、稳定,这两点对于无线键盘来说都很重要。

小键盘 keypad

一般多媒体键盘都包含音量控制键,很方便控制音量大小。而且对于我来说,PC上有Windows+Linux,使用蓝牙键盘后,开机时无法连接而进入BIOS里选择启动操作系统。

按键延时

从算法上,并不是每个键都连了一个GPIO,而是每排和每列连接一个GPIO,键盘每排的按键是并连的,也就是说任何一个接通都会设置这个GPIO为接通,然后算法先遍历每排,然后遍历每列。这种叫矩阵扫描。

机械键盘矩阵扫描并不是延时的最大问题,而是去抖比较耗时。

如何全键无冲呢?感觉FPGA可以在一个指令里面检查所有GPIO状态吧,其他的客制化键盘都支持么?avr 的也不支持吧,还是遍历速度够快就可以了么?

延迟和回报率这两者是一回事么?

【外设科普1】键盘、机械键盘按键延迟原理 B站视频,讲的还比较全面。

“RealKey Technology是CHERRY于2015 年CES发布的技术,搭载于当时的 CHERRY MX-BOARD 6.0键盘上,后来因为一些原因导致RK技术不得不更换成现在的HS(High Speed)技术,但其可以做到键盘触发1毫秒响应以及真正意义上的全键盘无冲等得以保留。而且HS技术取代一般机械键盘的信号交叉触发技术,以一个控制器为单位,令每一个按键变成一个独立触发点,并连接高度敏感的模拟。让按键触发不再需要横竖信号交叉触发,可以直接单点触发并及时反馈,可以做到真正的无延时。”

社区

各种 Database

$
0
0

企业上云系列之开源数据库的现状对于很多应用来说,其领域对象模型并不适合于转换成关系数据库形式来存储。这也是非关系型数据库(NoSQL)得以流行的原因。NoSQL 数据库的种类很多,包括键值对数据库、面向文档数据库和图形数据库等。

http://nosql-database.org/所有的 nosql 数据库

https://db-engines.com/en/ranking DB-Engines Ranking

https://use-the-index-luke.com/ Use The Index, Luke!

SQLite Is Serverless

为什么数据库不应该使用外键 https://draveness.me/whys-the-design-database-foreign-key/ 为什么 MySQL 使用 B+ 树 https://draveness.me/whys-the-design-mysql-b-plus-tree/

国内的数据库博主

Leveldb 和 RocksDB

Leveldb 和 RocksDB 在大 value 场景下的一些问题

获得PCC性能大赛第一名方案背后的 RocksDB 引擎:5分钟全面了解其原理 RocksDB 是基于levedb,借鉴了hbase思想。据说为 SSD 专门做了优化。

小米分布式 Key-Value 存储系统基于 RocksDB 对比了 HBase 的缺点

既生 Redis 何生 LevelDB ?

几款主流 NoSql 数据库的对比 leveldb 和 mongodb 很像,但是作为一个数据库后者功能更全面,前者性能是好,但只是一个库。 浅析 Bigtable 和 LevelDB 的实现 http://draveness.me/bigtable-leveldb.html 实现和hbase比较像,但是leveldb用了memtable作为磁盘table的中介和缓存,性能会提高,而hbase则偏向大数据情况下的处理。主要是 Leveldb 不支持分布式。

【Rocksdb实现及优化分析】 JoinBatchGroup http://kernelmaker.github.io/Rocksdb_Study_1 TiDB 底层也基于这个

badger https://github.com/dgraph-io/badger separating values from keys, significantly reducing the write amplification compared to a typical LSM tree. badger 一个高性能的LSM K/V store如何评价 Badger (fast key-value storage)?“基本思路是RocksDB基于LevelDB为SSD优化,但不是为SSD尤其是目前超高随机读写能力的NVME SSD设计.” badger 事务过程笔记

MyRocks: MariaDB将MyRocks作为一个alpha阶段的存储引擎 https://mariadb.com/kb/en/about-myrocks-for-mariadb/

LeanStore

a high-performance OLTP storage engine optimized for many-core CPUs and NVMe SSDs. https://dbis1.github.io/leanstore.html Talk https://twitter.com/andy_pavlo/status/1389042478796492800

Cassandra

Netflix 用的比较多 分布式 Key-Value 存储系统:Cassandra 入门 https://www.ibm.com/developerworks/cn/opensource/os-cn-cassandra/ 关于Cassandra的错误观点 http://www.infoq.com/cn/articles/cassandra-mythology https://zh.wikipedia.org/wiki/Cassandra 宽列存储模型(Wide Column Stores) ScyllaDB Cassandra优化版本,DPDK,开源。对 Linux 网络,缓存做了很多改变,是一个传统软件优化的很好例子。 https://www.zhihu.com/question/35956679 https://www.scylladb.com/2018/03/29/scylla-kubernetes-overview/ https://github.com/scylladb/scylla-code-samples/blob/master/kubernetes-scylla/README.md 优化程度这么高,运行在 k8s 上面还有优势么?

RethinkDB

听说最近死而复生,而且号称实时 web 开发,”RethinkDB是第一个数据库使用了一种令人激动的新的数据库的访问模型,而不是轮询数据库更改,开发者可以命令RethinkDB实时的向应用连续推送更新查询结果。” http://www.infoq.com/cn/news/2017/02/RethinkDB-join-Linux 一个数据库怎么和 web 开发关系起来?试试看。 伯克利推出世界最快的KVS数据库Anna:秒杀Redis和Cassandra https://zhuanlan.zhihu.com/p/34603927 https://www.rethinkdb.com/docs/install/ubuntu/ 然后 https://www.rethinkdb.com/docs/quickstart/ rethinkdb –bind all,可以 bind 所有的端口而不仅仅 localhost。 启动后会在8080端口打开一个 ui,设计的还是相当专业。 运行了几个命令,还行。不过还是没有看到后段怎么推送查询结果。 https://www.rethinkdb.com/docs/guide/javascript/ node.js 作为客户端调用,我 mac 上运行 js 。 node 作为消息驱动的开发模式和这个类型的数据库很匹配啊。怎么和前端交互?websocket? 实时推送查询结果,似乎很牛。不过应用场景比较少,二则这种性能的问题容易被转移成其他问题。 https://github.com/rethinkdb/rethinkdb 这里面有提供他的使用场景,都是和实时紧密相关。

Riak

《Designing Data-Intensive Applications》提到较多 类 Dynamo 的分布式 Key-Value 系统,Erlang 编写,Bitcask为其存储引擎 支持 global secondary index by term HaloDB https://github.com/yahoo/HaloDB/blob/master/docs/WhyHaloDB.md,类似 Bitcask 解决 LSM 写放大的问题,Java 编写 “an index in memory which stores all the keys, and append-only log files on the persistent layer which stores all the data” 混合的技术

YugabyteDB

https://github.com/yugabyte/yugabyte-db YugabyteDB 介绍 partition https://docs.yugabyte.com/latest/architecture/docdb-sharding/ a new term ‘tablet’. master server: keep metadata & coordinate. TServer: query & storage. The arch is some like HBase.

FoundationDB

苹果公司开源FoundationDB的简单分析『和其他NoSQL不一样的是,FoundationDB的Key-Value Store实现了强一致性,而非最终一致性』大数据时代的Key-Value Store大体上分为两类:

  1. 以BigTable和HBase为代表的,分区键(Partition Key)全局排序,通常采用的是范围分区(Range Partition)
  2. 以AWS DynamoDB和Cassandra为代表,分区键(Partition Key)不排序,通常采用的是哈希分区(Hash Partition)

https://apple.github.io/foundationdb/getting-started-linux.html 安装挺容易,集群也不复杂,依赖很少,果然是苹果出的,用户体验不错。https://apple.github.io/foundationdb/class-scheduling.html 这个是实例一般的 CRUD 操作,非 sql 语法,虽然有点像 k-v 操作,但是是支持事务的。https://www.voltdb.com/blog/2015/04/01/foundationdbs-lesson-fast-key-value-store-not-enough/ Plans for SQL Layer? issue 也就是说 sql 现在还不能用,tidb 作者建议使用 tidb 的 sql layer,说是已经抽象,但是 foundationdb 已经支持 acid 了,并非一个简单的 k-v 数据库,而且 tidb 有个 pd,这个在 fdb 没有对应的吧?https://github.com/opentradesolutions/opentick 这个提供了初步的 sql layer 支持。 『在核心外, FoundationDB通过分层设计的方式,实现了对各种数据模型,比如文档数据库,图数据库,关系数据库的支持。』这个也是 https://www.foundationdb.org/ 上面说的首要特征:Multi-model data store,https://apple.github.io/foundationdb/layer-concept.html 这里解释一般选择数据库就选择了数据模型(关系、文档)和存储引擎以及访问方式(REST, SQL),而用分层的概念解耦了数据模型和存储引擎,FDB 的 k-v 存储引擎能用在各种数据模型上面,而这种灵活性(其他 k-v 数据库也有)不丢失 ACID。 其文档写的很全,不错。

非通用数据库

  • https://db-engines.com/en/system/LokiJS%3BLovefield%3BPouchDB System Properties Comparison LokiJS vs. Lovefield vs. PouchDB JavaScript 数据库,轻量级,可以在客户端(浏览器、手机)运行,然后同步整个db data to server side. Azurite is an open source Azure Storage API compatible server (emulator) 有用到。
  • https://www.arangodb.com/ 专门为图算法优化的数据库。
  • TSDB

国内数据库

  • TiDB
  • openGauss 华为开源的数据库 https://opengauss.org/zh/
  • ZNBase 浪潮的分布式数据库 http://www.znbase.com/
  • 淘宝 OceanBase融合了 mysql 的事务并且兼容 mysql,以及用了 leveldb 类似的内存写的技术,不过虽然开源但是 commit 特别少,现在已经成为阿里云上面的一个产品了。
  • 阿里云 PolarDB for PostgreSQL“数据库由传统的 Share-Nothing 架构,转变成了 Shared-Storage 架构。由原来的 N 份计算 + N 份存储,转变成了 N 份计算 + 1 份存储。”

比较传统数据库

CAP理论十二年回顾:”规则”变了 http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed 现在是三选二,舍弃部分性质。这里比较了各个k-v 支持 CAP 的程度。 查找慢写快适合一些场景比如log写入,要查找快就只能 map-reduce 了?或者 SSD。所以对于一般业务对读写没有特别要求还是 mysql 这种在线数据库安逸点,即便是 facebook 也用 mysql,号称世界最大,当然他还混合很多其他技术。对于facebook大多数业务特别是其图片,读操作是远大于写操作的,所以其用了大量的 cache 来提高性能。Scaling Memcache At Facebook 翻译这里也是用 k-v 技术,不过这个k-v 就是像 redis 了,基于内存的缓存系统。

Google Cloud Spanner https://cloud.google.com/spanner/?authuser=1&hl=zh-cn 第一种可横向扩展、高度一致的关系型数据库服务,只有商业数据库这么大而全,比如CosmosDB。 这种在大数据量的情况下如何保证网络带宽?还是整套方案都用它的?原来这些统一叫 NewSQL NewSQL究竟新在哪里?「企业上云」系列之开源数据库的现状,TiKV 作者,也比较了很多各种类型的数据库。 https://aws.amazon.com/cn/products/databases/ AWS 产品很多,类似的似乎是Aurora,关系数据库,还有 RDS。https://www.percona.com/blog/2018/07/17/when-should-i-use-amazon-aurora-and-when-should-i-use-rds-mysql/ 区别在于 RDS 对 MYSQL 引擎兼容性更好 阿里的RDB似乎也是newsql https://cn.aliyun.com/product/rds NoSQL没落了?NewSQL有机会挑大梁吗?解释了一堆其他的 newsql 数据库,从这些项目的实现架构来看,主要分为两种:

  • 原生实现:如CockroachDB、YugaByteDB
  • NoSQL+ACID+SQL:如TiDB、Trafodion

cockroachdb和 tidb 一样是基于 rocksdb,为什么不同呢?这个参考是 tidb 老版本基于 hbase 的?刘奇:如何使用HBase构建NewSQL?老版本的 tidb 是基于 hbase 的吧,现在应该已经换了。HBase进化之从NoSQL到NewSQL,凤凰涅槃成就Phoenix用的还是官方项目phoenix。可惜 hbase 是 java 的并且运行在 hadoop 上面,依赖太笨重。

一分钟搞懂列式与行式数据库行式更适合OLTP,比如传统的基于增删改查操作的应用。列式更适合OLAP,非常适合于在数据仓库领域发挥作用,比如数据分析、海量存储和商业智能;涉及不经常更新的数据。 Hbase 列式存储,传统的关系型数据库,如Oracle、DB2、MySQL、SQL SERVER等采用行式存储法,TiDB 典型的 OLTP 行存数据库

TiDB HTAP 深度解读“TP 和 AP 传统来说仰赖不同的存储格式:行存对应 OLTP,列存对应 OLAP。” “使用写优化方式存储变更数据,然后逐步将更新部分归并到读优化的主列存区” 如何看待王垠对数据库的理解?我们对比了5款数据库,告诉你NewSQL的独到之处 https://mariadb.com/kb/en/library/mariadb-columnstore/ 传统的数据库也在演变

OLTP和OLAP的区别

联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改。比如在银行的一笔交易记录,就是一个典型的事务。OLTP的特点一般有:

  1. 实时性要求高。我记得之前上大学的时候,银行异地汇款,要隔天才能到账,而现在是分分钟到账的节奏,说明现在银行的实时处理能力大大增强。
  2. 数据量不是很大,生产库上的数据量一般不会太大,而且会及时做相应的数据处理与转移。
  3. 交易一般是确定的,比如银行存取款的金额肯定是确定的,所以OLTP是对确定性的数据进行存取
  4. 高并发,并且要求满足ACID原则。比如两人同时操作一个银行卡账户,比如大型的购物网站秒杀活动时上万的QPS请求。 联机分析处理OLAP(On-Line Analytical Processing) 是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。典型的应用就是复杂的动态的报表系统。OLAP的特点一般有:
  5. 实时性要求不是很高,比如最常见的应用就是天级更新数据,然后出对应的数据报表。
  6. 数据量大,因为OLAP支持的是动态查询,所以用户也许要通过将很多数据的统计后才能得到想要知道的信息,例如时间序列分析等等,所以处理的数据量很大;
  7. OLAP系统的重点是通过数据提供决策支持,所以查询一般都是动态,自定义的。所以在OLAP中,维度的概念特别重要。一般会将用户所有关心的维度数据,存入对应数据平台。 总结: OLTP即联机事务处理,就是我们经常说的关系数据库,增删查改就是我们经常应用的东西,这是数据库的基础;TPCC(Transaction Processing Performance Council)属于此类。 OLAP即联机分析处理,是数据仓库的核心部心,所谓数据仓库是对于大量已经由OLTP形成的数据的一种分析型的数据库,用于处理商业智能、决策支持等重要的决策信息;数据仓库是在数据库应用到一定程序之后而对历史数据的加工与分析,读取较多,更新较少,TPCH属于此类。 随着大数据时代的到来,对于OLAP,列存储模式或者说nosql模式比传统意义的行存储模式可能更具优势。

Think

  • 对于私有云来说,每个微服务趋向自己创建数据库,或者自己维护的大的数据库。
  • 对于公有云来说,每个微服务会直接使用已有的多租户数据库。
  • 从技术上来说当然是公有云多租户数据库更好(技术、经济),但是国内环境下,自己维护的更多,这种情况下,NewSQL 对于升级换代吸引很大。

cat /proc/cpuinfo

$
0
0
system type : MediaTek MT7620A
machine : Baidu BR100 Board
processor : 0
cpu model : MIPS 24KEc V5.0
BogoMIPS : 385.84
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
ASEs implemented : mips16 dsp
shadow register sets : 1
kscratch registers : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
system type : Atheros AR9344 rev 2
machine : MerCury MW4530R
processor : 0
cpu model : MIPS 74Kc V4.12
BogoMIPS : 278.93
CPUClock : 560
FlashSize : 8
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0720, 0x0700, 0x0b98]
system type : Atheros AR9330 rev 1
machine : TP-LINK TL-WR703N v1
processor : 0
cpu model : MIPS 24Kc V7.4
BogoMIPS : 265.42
wait instruction : yes
microsecond timers : yes
tlb_entries : 16
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0f10, 0x0e10, 0x0a20]
system type : Atheros AR7240 rev 2

machine : Buffalo WHR-HP-G300N
processor : 0
cpu model : MIPS 24Kc V7.4
BogoMIPS : 265.42
Processor : ARMv7 Processor rev 2 (v7l)
processor : 0
BogoMIPS : 1785.85

processor : 1 2 3

Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 2
Hardware : ODROIDXU
Board Type : XU Lite
Processor : ARMv7 Processor rev 0 (v7l)

processor : 0
BogoMIPS : 1631.46
processor : 1
BogoMIPS : 1631.46
Features : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x3
CPU part : 0xc09
CPU revision : 0

Hardware : RK30board
processor : 0 - 7
vendor_id : AuthenticAMD
cpu family : 16
model : 8
model name : AMD Opteron(tm) Processor 4122
stepping : 0
cpu MHz : 798.039
cache size : 512 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 4
apicid : 8
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp
lm 3dnowext 3dnow constant_tsc rep_good nonstop_tsc extd_apicid pni monitor cx1
6 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowpr
efetch osvw ibs skinit wdt nodeid_msr
bogomips : 4389.19
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate
processor : 0 - 7
cpu : POWER7 (architected), altivec supported
clock : 4004.000000MHz
revision : 2.2 (pvr 003f 0202)
timebase : 512000000
platform : pSeries
model : IBM,9119-FHB
machine : CHRP IBM,9119-FHB
model name      : ARMv7 Processor rev 0 (v7l)
processor       : 0-1
BogoMIPS        : 1993.93
Features        : swp half thumb fastmult edsp tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0

Hardware        : Northstar Prototype(xiaomi miwif, bcm4709)
Revision        : 0000
Serial          : 0000000000000000
processor       : 3
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 57.60
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : BCM2709 (raspberry pi 2)
Revision        : a01041
Serial          : 00000000f3919f9b
Processor       : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS        : 697.95
Features        : swp half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xb76
CPU revision    : 7

Hardware        : BCM2708 (raspberry pi)
Revision        : 0003
Serial          : 00000000f90cbb6b
processor       : 0-3
model name      : ARMv7 Processor rev 10 (v7l)
BogoMIPS        : 790.52
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x2
CPU part        : 0xc09
CPU revision    : 10

Hardware        : Freescale i.MX6 Quad/DualLite (Device Tree)
Revision        : 0000
Serial          : 0000000000000000
Beaglebone Black
processor       : 0
model name      : ARMv7 Processor rev 2 (v7l)
Features        : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc08
CPU revision    : 2

Hardware        : Generic AM33XX (Flattened Device Tree)
Revision        : 0000
Serial          : 0000000000000000
root@OpenWrt:~# cat /proc/cpuinfo
processor    : 0 ~ 1
model name    : ARMv7 Processor rev 1 (v7l)
BogoMIPS    : 2655.84
Features    : half thumb fastmult vfp edsp vfpv3 tls vfpd32 
CPU implementer    : 0x41
CPU architecture: 7
CPU variant    : 0x4
CPU part    : 0xc09
CPU revision    : 1

Hardware    : Marvell Armada 380/385 (Device Tree)
Revision    : 0000
Serial        : 0000000000000000
processor    : 0 ~ 31
vendor_id    : GenuineIntel
cpu family    : 6
model        : 45
model name    : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
stepping    : 7
microcode    : 0x710
cpu MHz        : 1199.945
cache size    : 20480 KB
physical id    : 1
siblings    : 16
core id        : 7
cpu cores    : 8
apicid        : 47
initial apicid    : 47
fpu        : yes
fpu_exception    : yes
cpuid level    : 13
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid xsaveopt
bogomips    : 4418.03
clflush size    : 64
cache_alignment    : 64
address sizes    : 46 bits physical, 48 bits virtual
power management:
ubuntu@great-aigo:~$ cat /proc/cpuinfo
processor       : 0~5
vendor_id       : AuthenticAMD
cpu family      : 21
model           : 1
model name      : AMD Opteron(tm) Processor 4230 HE
stepping        : 2
microcode       : 0x600063d
cpu MHz         : 1400.000
cache size      : 2048 KB
physical id     : 0
siblings        : 6
core id         : 0
cpu cores       : 3
apicid          : 16
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs xop skinit wdt lwp fma4 nodeid_msr topoext perfctr_core perfctr_nb cpb hw_pstate vmmcall arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold
bugs            : fxsave_leak sysret_ss_attrs
bogomips        : 5800.38
TLB size        : 1536 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm 100mhzsteps hwpstate cpb
fan@bstone:~$ cat /proc/cpuinfo
processor       : 0~3
vendor_id       : GenuineIntel
cpu family      : 6
model           : 37
model name      : Intel(R) Xeon(R) CPU           L3406  @ 2.27GHz
stepping        : 5
microcode       : 0x2
cpu MHz         : 1200.000
cache size      : 4096 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 11
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 popcnt lahf_lm tpr_shadow vnmi flexpriority ept vpid dtherm ida arat
bugs            :
bogomips        : 4533.31
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
root@OpenWrt:/bin# cat /proc/cpuinfo 
processor     : 0
vendor_id     : GenuineIntel
cpu family     : 6
model          : 26
model name     : Intel Core i7 9xx (Nehalem Class Core i7)
stepping     : 3
microcode     : 0x1
cpu MHz          : 2266.660
cache size     : 4096 KB
physical id     : 0
siblings     : 1
core id          : 0
cpu cores     : 1
apicid          : 0
initial apicid     : 0
fpu          : yes
fpu_exception     : yes
cpuid level     : 4
wp          : yes
flags          : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc rep_good nopl pni vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt hypervisor lahf_lm tpr_shadow vnmi flexpriority ept vpid
bugs          :
bogomips     : 4533.32
clflush size     : 64
cache_alignment     : 64
address sizes     : 40 bits physical, 48 bits virtual
power management:

KVM on Intel(R) Xeon(R) CPU L3406
[root@eypc ~]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                48
On-line CPU(s) list:   0-47
Thread(s) per core:    2
Core(s) per socket:    24
Socket(s):             1
NUMA node(s):          4
Vendor ID:             AuthenticAMD
CPU family:            23
Model:                 1
Model name:            AMD EPYC 7401P 24-Core Processor
Stepping:              2
CPU MHz:               1996.203
BogoMIPS:              3992.40
Virtualization:        AMD-V
L1d cache:             32K
L1i cache:             64K
L2 cache:              512K
L3 cache:              8192K
NUMA node0 CPU(s):     0,4,8,12,16,20,24,28,32,36,40,44
NUMA node1 CPU(s):     1,5,9,13,17,21,25,29,33,37,41,45
NUMA node2 CPU(s):     2,6,10,14,18,22,26,30,34,38,42,46
NUMA node3 CPU(s):     3,7,11,15,19,23,27,31,35,39,43,47
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc art rep_good nopl nonstop_tsc extd_apicid amd_dcm aperfmperf eagerfpu pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_l2 cpb hw_pstate ibpb_support avic fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold overflow_recov succor smca

Linux Command Tips

$
0
0

System Info

Neofetch is a command-line system information tool written in bash 3.2+. Neofetch displays information about your operating system, software and hardware in an aesthetic and visually pleasing way.

Neofetch has lots of dependency. An alternative is screenfetch.

lsb_release -a show linux release version and codename

Find Out Ram Speed, Make, Form Factor, Type and Other Information : dmidecode --type memory.

Configurate System

set timezone sudo dpkg-reconfigure tzdata

To change locale, use sudo update-locale LANG=en_US.utf8. Then ssh can show Chinese characters. In Ubuntu Server, “locale -a” say zh_CN.utf8. It is unusual. In Putty, “Connection → Data → Environment variables”, add LANG/zh_CN.utf8 & LC_CTYPE/zh_CN.utf8. Than Putty can type and show Chinese. Mac always ok on Chinese.

Package management

dpkg --get-selections | grep java find which package provides java command

TTY Device

screen /dev/ttyUSB0 115200 screen -L /dev/tty.SLAB_USBtoUART 115200 — will generate a log file screenlog.0 in current directory. To activate screen logging function, just press “Ctrl-A” and “H“. (Please be careful, we use capital ‘H’ letter. Using non capital ‘h’, will only create a screenshot of screen in another file named hardcopy). Ctrl-A, d — will detach from current, but screen still run background. Mac will not release TTL device. If want to attach again, use “screen -r”. Ctrl-A, : — will enter command mode, run “quit” will exit completely.

picocom -b 115200 -f h /dev/ttyS0 To exit, C-a, C-x compared with screen, picocom can view output history.

no permission to access tty device: sudo usermod -a -G dialout $USER sudo reboot

SSH

http://stackoverflow.com/questions/12202587/automatically-enter-ssh-password-with-script sshpass -p “YOUR_PASSWORD” ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM http://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine ssh user@host «‘ENDSSH’ #commands to run on remote host ENDSSH

Example of .ssh/config

Host 192.168.51.3* f*
    User fedora 
    IdentityFile ~/.ssh/hp1_id_rsa 
Host f1 
    HostName 192.168.51.31
Host * 
    User fan

More details about the config, check https://deepzz.com/post/how-to-setup-ssh-config.html

“permissions are too open” error : chmod 400 ~/.ssh/id_rsa Sometimes ssh it very slow: Next authentication method: gssapi-with-mic Next authentication method: publickey 第一种认证方法浪费时间,可以在.ssh/config里面加上 PreferredAuthentications publickey。 或者GSSAPIAuthentication no

Connection closed by remote host due to inactivity

TCPKeepAlive yes 
ServerAliveInterval 10

Set it in client $HOME/.ssh/config file. Now all ssh connections will send a TCPKeepAlive every 10 seconds.

Unable to negotiate with host: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1 –> ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 user@host

File

show details when copy file: cp –verbose -rf /src/ /dsc/

rsync -avz –progress /path/of/source /path/of/target

A look at rsync performance https://lwn.net/Articles/400489/

https://stackoverflow.com/questions/13713101/rsync-exclude-according-to-gitignore-hgignore-svnignore-like-filter-c rsync -a -v –ignore-existing a/ b/ –filter=’:- .gitignore’ –exclude=’/.git’

mount loop image file https://www.linuxquestions.org/questions/linux-general-1/how-to-mount-img-file-882386/ only this work for me https://unix.stackexchange.com/questions/316401/how-to-mount-a-disk-image-from-the-command-line/316407#316407

exclude all “permission denied” messages from “find” find / -name javac 2>/dev/null

chmod 755, 644, 700 http://learn-web-hosting-domain-name.mygreatname.com/chmod-tutorial.html

who use this file : fuser file -v

Disk

https://askubuntu.com/questions/587247/how-to-create-a-ext4-partition-for-all-users

Check SATA speed smartctl -a /dev/sda nvme-cli package sudo nvme list sudo nvme smart-log /dev/nvme0n1

Samba sometimes need create user: smbpasswd -a linuxsir. ‘root’ user is not permitted. Sometimes need “chmod 777 /mnt/sda1” if only read & can’t write. New samba looks having better UX: just add/append below to /etc/samba/smb.conf. Then ok. Restart is not need.

Network

Ubuntu: netplan

Binary file

To list a binary dependency library: “ldd file”, or use “readelf -a file”.

run “readelf -a portal” and find line as below: [Requesting program interpreter: /lib/ld-linux-armhf.so.3] Then run “ln -s /lib/ld-linux.so.3 /lib/ld-linux-armhf.so.3”.

readelf -a /usr/arm-linux-gnueabihf/lib/libm.so.6grep FP

nm a.so

strings a.so #print printable string.

Bash

$ heketi-cli -s http://192.168.51.2:8080 volume list
Id:382bba388e29fbc9fdb3b53b96a203e0    Cluster:1f4e1ef2c5b292aec8cfe282222fa876    Name:vol_382bba388e29fbc9fdb3b53b96a203e0
Id:467863a2abe78ceb8b22dabf7d92c12f    Cluster:1f4e1ef2c5b292aec8cfe282222fa876    Name:vol_467863a2abe78ceb8b22dabf7d92c12f
heketi-cli -s http://192.168.51.2:8080 volume list|grep -oP "Id:\K\w*"| xargs -L 1 heketi-cli -s http://192.168.51.2:8080 volume delete

In line, “\K” means deleting the matching “id:” sting. “-L 1” means deleting every volume id. Otherwise, all lines will be executed only once. https://rook.io/docs/rook/v1.6/ceph-teardown.html another way to run command within foreach.

Image

Others

Vim modify _vimrc in home directory:

set guifont=Cascadia_Code:h9
set guioptions -=T

CNTRL+ALT & F1 through F6 you have 7 virtual consoles the seventh is reserved for X.

Edit this file /etc/dhcp/dhclient.conf and set timeout to a reasonable value, like timeout 15 The default value of 300 seconds is way too high. The suggested replacement value of 15 was tested and works fine.

echo -n “STRING” | base64 -n is to avoid a new line character on the end of the line.

linux nohup http://kumu-linux.github.io/blog/2013/08/06/tmux/

mutliply download: axel. It also can be used in OS X.

patch -p1 <~/patch1.diff

Most digital cameras and cell phone add EXIF metadata to the images. EXIF metadata includes camera specifications, settings, location (GPS coordinates) and more. exiftool -all= /.jpg -overwrite_original

STDERR (standard error) in UNIX and UNIX-like systems is redirected using 2> instead of a single chevron (>). gpc xxx.pas 2> error.txt

https://www.cyberciti.biz/faq/what-process-has-open-linux-port/

https://linux.cn/article-5608-1.html

零刻 GTR7 & mini 小主机

$
0
0

零刻 GTR7 & mini 小主机

链接

https://www.bee-link.com.cn/catalog/product/index?id=808 Product page.

https://www.bee-link.com.cn/cms/support/driverhardware Driver download.

https://www.wolai.com/meiss/76fqibfv2v7iN8wAnfWLZ4 BIOS upgrade guide.

https://weibo.com/u/7319305762官方微博

体验

背部接口没有标记,雷电接口也没有。

前面板非雷电TYPE-C 10GB,没有20GB的。后面雷电接口接雷电硬盘盒可以跑满速,但是接20gb硬盘盒只能跑10gb。

DDR5能到5600,非常不错。这个对于核显的发挥很重要。

上面板进风,Logo有遮挡。虽然有风格,但是散热是第一位的。HWiNFO 里面看不到风扇转速。

如果顶部完全封闭,那就可以放其他设备了,这样更适合放到桌面上。放到桌面上后USB接口就容易拔插。铭凡UM780 XTX(126x130x60),零刻SER8&SEi14(135x135x44.7),机械革命imini Pro820(154x152.2x37.8),蝰蛇峡谷(230x180x60)都是这种类型。这么说mac mini(197x197x35.8)之所以还是原来的老尺寸,容易堆叠是重要原因。

内部很精细,达到了NUC水平。

BIOS很老土,但是可以改进,问题也不大。不得非要图形化BIOS,功能可用即可。

CLR CMOS,这个按钮为什么放前面?

指纹不错,Windows Hello可以用。容易触碰,导致关机。Linux 下对这个指纹芯片还不支持。https://linux-hardware.org/?id=usb:1c7a-0577

外观色彩里面应该有个黑色。或者只有黑色。

体积还是大了点。

Windows 下面机器没法休眠,BIOS这个可以改进。my question https://tieba.baidu.com/p/8604777597。Linux可以。

AMD贴纸在机器反面,好评。

磁吸电源接口,拔插手感一般,没有苹果笔记本的顺畅。不过这个没带电池,拔掉就关机,平时也不像笔记本那样经常拔插,手感不好问题不大。但有这个创新意识就很好。贴吧认为联想拯救者C130和C140电源兼容性比较好,支持20Vx6A功率。雷电4电源,可以开机,但是过一会就自动关机了。客服说是开机峰值110W,PD最高只能100W。感觉这个峰值可以在BIOS里面微调,还是等待以后改进吧。其实这个使用场景更多是为笔记本服务的(反向充电),mini小主机并不会从中受益很多,主要是要占用一个雷电接口。总的来说,PD电源有不少兼容性问题,而这个对于主机电源来说是致命的。

贴吧很多(这里这里)反映重启问题,在双条内存下,播放视频会重启。似乎是和显卡驱动有关系。我内存是棘蛇JAZER 8GB DDR5 5600,CPU-Z显示为海力士颗粒。

雷电接口

雷电显示器开始没法显示开机BIOS画面,要等到进入windows后才会点亮屏幕。但是新款BIOS解决了部分问题:可以在type-c显示器上面操作。虽然开机时间边长了,但是这个改进的速度还是很让人点赞的。

最早的显卡驱动版本,工作正常。升级成官方新版本后无法驱动雷电显示器,只能回退。后来从成功升级到2023/5/30,原因可能是需要安装 chipshet 驱动,或者安装驱动时选择 minimal+reset config。最好接上 HDMI 再安装,否则中途会出错。

默认设置进入linux,之后如果要重启进入windows,可以使用 efibootmgr 命令。

Linux下面待机后恢复很快,但是待机后如果雷电hub接过其他设备然后再切换回来,恢复有点慢,但最后还是能成功。

teardown, looks no USB4.0 chip. Supported by 7840HS natively?

00:03.1PCIbridge:AdvancedMicroDevices,Inc.[AMD]Family19hUSB4/ThunderboltPCIetunnel00:04.1PCIbridge:AdvancedMicroDevices,Inc.[AMD]Family19hUSB4/ThunderboltPCIetunnelca:00.5USBcontroller:AdvancedMicroDevices,Inc.[AMD]PinkSardineUSB4/ThunderboltNHIcontroller#1ca:00.6USBcontroller:AdvancedMicroDevices,Inc.[AMD]PinkSardineUSB4/ThunderboltNHIcontroller#2

这个机器能驱动 LG Ultrafine 5K,是因为雷电有两条 DP OUT 么?如何在 Windows 下面查看?

Untitled

确实有两个 DP IN,如果接普通4K显示器,上面隧道DP IN为1。而 780M 显卡输出为4 Displays (max.), HDMI 2.1, DisplayPort 2.1 https://www.notebookcheck.net/AMD-Radeon-780M-GPU-Benchmarks-and-Specs.680539.0.html所以这是全接出了。

散热

Untitled

拆机视频。从面板的后部排风口看,涡轮风扇距离面板很近,所以并不能靠两侧的孔网进风。但是因为是涡轮风扇,感觉上面板盖住问题也不大,只要不是全封闭。

Change boot order

https://superuser.com/questions/1338643/how-do-i-change-the-uefi-boot-order-from-within-windows-10

https://superuser.com/questions/1016762/is-it-possible-to-select-which-system-to-boot-before-rebooting-on-a-multi-boot

Set Linux as default boot OS. In Linux, run command sudo efibootmgr -n 0000 to set EFI BootNext var which will boot to Windows only next time. The boot order is not changed.

铭凡和其他品牌

https://www.sohu.com/a/713846019_121649107

BD790i,7945HX,TYPE-C显示,无雷电。这个级别的CPU还是适合作为游戏笔记本,因为iGPU羸弱,加个独立显卡刚好。mini小主机加显卡就不能mini了,必须要有专门定制的机箱,类似NUC幽灵峡谷,否则和自己配ITX主板+显卡没啥优势。“银欣 ML12薄型ITX小机箱”这个还可以,因为这个mini主机散热只能用下压了。或者分形工艺 Ridge。这里看感觉小厂实力。这里装机展示用的机箱是酷冷至尊NR200,评论里面有用XPROTO-Mini这种全开放式机箱。

UM880PRO,2599¥,8845HS,双USB4,改进后的型号。

HX100G: 7840HS+RX6650M,双雷电口,这样可惜集成显卡了。HX200G:7945HX+7600M XT,这个配置很梦幻,但是雷电口就没有了,TYPE-C也没有标明是否有显示输出。原子侠 G7,7945HX+7600M XT。

AR900i(板载i9-13900HX),也没有雷电接口,但是有type-c显示输出。

玄派创世魔方,8845HS,原生oculink,双雷电,图形化BIOS。堪称ai pc前的辉煌了。B站上有不少评测。就是外观设计有点呆,底部进风也很小。

2024玲珑产品发布会——世界上首台可以折叠的键盘迷你主机我觉得还是很有想法的,就是略微尴尬,不知道用在哪里。屏幕演示里面主要是ipad,我没有这个习惯。用ipad是讨巧的场景,如果用便携屏幕就真不如笔记本了。

MS-01 和其他全闪NAS小主机

https://minisforum.hk/products/ms01https://www.chiphell.com/thread-2542008-1-1.html讨论贴,https://www.chiphell.com/thread-2571531-1-1.html评测,https://www.koolcenter.com/posts/465评测,i5-12600H 版本 2999¥,我认为只有这个最便宜的版本才有价值,因为这个板子主要是扩展性,CPU 太高反而散热着急。绿联DXP480T Plus,和这个很像,价格也类似。DXP6800 Pro也可以,如果有机械硬盘的需求,CHH讨论贴

这种NAS的雷电能作为非host接入USB4 hub么?如果可以,这个雷电倒是有了个很好的使用场景。

MoDT

畅网 7840HS NAS 软路由 https://www.changwang.com/product.html?id=49带一个雷电口。厂商介绍视频,下面都是批评的,我看只是因为价格贵。感觉国内的厂商也开始有创造力了。这个和铭凡MS-01很相像了,而畅网的优势在于这个是itx主板,24pin atx电源接口,折腾的空间会更大。价格3K,没有万兆,导致那么多2.5g有点尴尬。

尔英板载CPU套装13代,一个雷电口,DDR5,13600H 1400¥,三个m.2。CPU可能比7480差,但是7840现在主板很少。MS-01其实不错,但是不是ATX电源接口灵活性不够。

Intel Ultra

机械革命(MECHREVO)imini Pro游戏商务电脑台式迷你主机 Ultra 5 125H,只有一个雷电口。拆解另外一个型号是“Ultra 7 155h”

Asus NUC14 Pro+,双雷电口,这个型号更小,改进了进风,4299¥,贵了不少,拆解评测,散热很独特,涡轮风扇能两边出风。精致商用机。

Minisforum UH125 Pro 双USB4+OCulink+双5G网口,OCulink不会占用m.2。https://minisforum.hk/products/minisforum-uh125-pro

零刻 GTi14,内置PCIe X8插槽,感觉这样还不如像幽灵峡谷那样直接做成个nuc的主机,内置PCIe X8插槽。

Ryzen AI 300

这个短时间内上 mini pc 有点难。

功耗

https://www.cnx-software.com/2024/04/29/raspberry-pi-5-intel-n100-mini-pc-comparison-features-benchmarks-price/“N100 mini pc to 1.3-1.5W idle power consumption”, “enabling ASPM for all PCI-E root ports and setting maximum package C-state to C10”

thunderbolt 3 hub lost after suspend

xhci_hcd 0000:6a:00.0: xHCI host controller not responding, assume dead
6a:00.0 USB controller: Fresco Logic FL1100 USB 3.0 Host Controller (rev 10)

冷启动没有问题,但是suspend然后resume后就出现问题。像是这个设备的linux driver问题,同样雷电hub在b650m/b660m主机上面工作正常。感觉还是BIOS电源设置问题。这个USB HUB是pcie的,雷电hub上面的pcie网卡倒是正常工作。和BIOS里面的ASPM有关么?

on B650M

[    2.690958] xhci_hcd 0000:0c:00.0: xHCI Host Controller
[    2.690981] xhci_hcd 0000:0c:00.0: new USB bus registered, assigned bus number 1
[    2.692350] xhci_hcd 0000:0c:00.0: hcc params 0x200071e9 hci version 0x100 quirks 0x0000000000000410
[    2.692765] xhci_hcd 0000:0c:00.0: xHCI Host Controller
[    2.692788] xhci_hcd 0000:0c:00.0: new USB bus registered, assigned bus number 2
[    2.692789] xhci_hcd 0000:0c:00.0: Host supports USB 3.0 SuperSpeed

when resume, only [ 392.346717] xhci_hcd 0000:0c:00.0: xHC error in resume, USBSTS 0x411, Reinit.

Viewing all 57 articles
Browse latest View live