花木兰

  • 首页

  • 归档

Ubuntu NFS使用

发表于 2017-06-05 | 更新于 2019-06-20 | 分类于 经验

在Ubuntu16.04下测试通过

NFS安装

CentOS下查看NFS是否已经安装:

1
rpm -qa | grep "nfs"

Ubuntu下安装NFS服务器:

1
sudo apt install nfs-kernel-server

Ubuntu下安装NFS客户端:

1
sudo apt install nfs-common

在NFS服务器上指定共享目录

指定共享目录有2种方式,分别有不同的目的:一种适用于通用的文件存储;另一种则适用于带权限管理的文件存储。

root用户可以在系统的任何位置做任何事情。然而,NFS挂载的目录不是这个系统的一部分,所以默认情况下,NFS服务器会拒绝执行需要超级用户权限的操作。这个默认的限制意味着,客户端系统的root用户无法在NFS挂载目录下,以root角色写文件,重新指定文件拥有者,或者执行其它超级用户操作。

这里先介绍默认方式的共享目录配置方法,它适用于大多数场景,比如作为内容管理系统存储上传的文件,或者为用户开辟空间共享项目文件。

首先,创建一个待共享的目录:

1
mkdir -p /home/mine/nfs

由于是默认的共享方式,NFS会将客户机上的所有root操作都映射为nobody:nogroup身份,因此,我们需要修改该目录的拥有权,以便匿名身份可以读写该目录:

1
sudo chown nobody:nogroup /home/mine/nfs

在下文的/etc/exports配置中,我们可以使用all_squash选项,将客户机上的所有用户都映射为匿名用户,这样就保证了所有人都能够存取该目录。

接下来,配置NFS导出:

使用root权限打开/etc/exports文件:

1
sudo vim /etc/exports

这个文件有一段注释内容,展示了每一个配置行的基本结构,语法大致是这样的:

1
directory_to_share client(share_option1,...,share_optionN)

对于每一个要共享的目录都要配置一行:

1
/home/mine/nfs 192.168.100.180(rw,sync,all_squash,insecure)

这意味着将/home/mine/nfs目录共享给192.168.100.180机器使用,如果想共享给所有主机,也可以换成*:

1
2
/home/mine/nfs *(rw,sync,all_squash,insecure) 
/*option list之间不能有空格,否则会报错:bad option list*/

共享设置一览:

  • rw: 允许客户端对卷有读写权限
  • sync: 强制NFS在回复之前将改变写入磁盘。因为回复反映了远程卷的实际状态,所以这样可以产生更加稳定一致的环境。然而,它也降低了文件操作的速度。
  • all_squash:客户机上的任何用户读写该共享目录时,都映射成匿名用户,这样就便于所有用户对文件的存取。
  • insecure:允许客户机从大于等于1024的端口来访问NFS,如果不写明此选项,有时候客户机mount时会报错access denied。

Ubuntu下操作NFS服务器:

1
sudo systemctl start/stop/restart/status nfs-kernel-server.service

在客户端创建挂载点

为了在客户端机器上使用远程共享目录,我们需要将该目录挂载到本地一个空目录上。

如果待挂载目录下已经有文件或文件夹,那么一旦你挂载了NFS共享目录,原有的文件就会被隐藏掉。所以要确保你的挂载目录若已存在,那么它得是一个空目录。

创建挂载目录:

1
mkdir -p /home/client/nfs

挂载NFS共享目录:

1
sudo mount 192.168.1.100:/home/mine/nfs /home/client/nfs //192.168.1.100是NFS服务器IP

检查挂载情况:

1
df -h

卸载共享目录的挂载:

1
sudo umount /home/client/nfs

okay,现在无论在NFS服务器,还是客户机上,任何人都能对nfs共享目录进行读写操作了。

参考文章

  • NFS
  • How To Set Up an NFS Mount on Ubuntu 16.04
  • exports(5) - Linux man page

Mac常用命令积累

发表于 2017-06-01 | 更新于 2019-06-20 | 分类于 经验
  • Mac自带的terminal,新建标签页快捷键:command + T

  • Mac自带的terminal,关闭标签页快捷键:command + W

  • Mac自带的terminal,显示上一个标签页快捷键:control + shift + tab

  • Mac自带的terminal,显示下一个标签页快捷键:control + tab

  • Mac剪切粘贴文件,Mac Finder剪切快捷键默认被禁用,需要采用如下2步骤才能实现剪贴:

    1. command + C 复制源文件
    2. command + option + V 在目的地剪贴

Kubernetes 缩放应用规模

发表于 2017-05-19 | 更新于 2019-06-20 | 分类于 Kubernetes

英文原文:https://kubernetes.io/docs/tutorials/kubernetes-basics/scale-intro/

缩放一个应用规模


之前我们创建了一个部署,然后通过一个服务将它暴露到公网。部署操作只创建了一个Pod来运行我们的应用。当流量增大时,我们将需要扩展应用,以跟上用户的需求。

通过更改部署中副本的数量可以实现缩放

缩放概述


扩展一个部署将会保证创建新的Pods,并能调度到可用的节点上。而缩减一个部署则会减少Pods的数量,以到达一个新的期望状态。Kubernetes也支持Pods的自动缩放,但这超出了本文的范围。将Pods数量缩减为0也是可以的,这就会将该部署中的所有Pods都终结掉。

运行一个应用的多个实例,就需要一种方式将流量分散到它们上面。服务有一个集成的负载均衡,它可以将暴露到集群外的部署所接收到的流量,分散到所有的Pods上去。服务将会使用路径[endpoints]持续监控运行的Pods,以保证流量只会发送到可用的Pods中。

一旦你的应用拥有多个运行实例,你就可以无需停机来进行滚动更新。后面我们会介绍应用更新。

Kubernetes Service 简介

发表于 2017-05-17 | 更新于 2019-06-20 | 分类于 Kubernetes

英文原文:https://kubernetes.io/docs/tutorials/kubernetes-basics/expose-intro/

Kubernetes服务概述


Kubernetes Pods不是永恒的,实际上它有一个生命周期。当一个工作节点挂掉的时候,运行在上面的Pods也会消失。一个复制操控程序将会通过创建新的Pods使你的应用保持运行,来动态地驱动集群恢复到期望的状态。再举一个例子,考虑一个拥有3个副本的镜像处理后台。这些副本是可以互相替代的;前端系统不需要关注后端的副本,甚至也不需要关注一个Pod是消失还是被重建。即便如此,每一个Kubernetes集群中的Pod都有一个唯一的IP地址,即使在同一个节点上的多个Pods也是这样,所以需要有一种方法能够使Pods中的变化自动保持一致,以保证你的应用持续正常运行。这就要提到服务了。在Kubernetes中,一个服务也是一个抽象概念,它定义了一个逻辑意义上的Pods集合,以及一个控制谁能访问它们的协议[policy]。服务可以使Pods之间的依赖很松散的耦合。一个服务使用YAML(优先)或者JSON来定义,就像所有的Kubernetes对象一样。一个服务标定的Pods集合通常由一个LabelSelector来决定(关于为什么在属性集中你也许不想让服务包含selector,可以看下面的内容)。

即使Pods每个都有一个唯一的IP地址,但是没有服务,这些IP就不会暴露在集群外面。服务允许你的应用接收通讯。服务可以在ServiceSpec中指定一个type来以不同的方式向外部暴露:

  • ClusterIP(默认的) – 在集群中将服务暴露在一个内部IP上。这种类型使得服务只能在集群内部访问。

  • NodePort – 使用NAT,对于集群中每一个选中的节点,将服务暴露在同一个端口上。这样可以使用:来从集群外部访问服务。NodePort是ClusterIP的超集。

  • LoadBalancer – 在当前云环境中创建一个外部的负载均衡器(如果支持的话),并且为服务指定一个固定的外部IP。LoadBalancer是NodePort的超集。

  • ExternalName – 使用一个任意的名字,通过返回一个包含该名字的CNAME记录来暴露服务(在属性集中通过externalName指定名字)。不使用任何协议。这个类型需要kube-dns版本为v1.7及以上。

关于服务的不同类型更多信息,可以参看Using Source IP教程。也可以参看Connecting Applications with Services。

另外,要注意在一些场景下,服务的属性集中并没有定义selector。一个没有selector的服务也不会创建对应的路径[Endpoints]对象。这样可以允许用户手动将一个服务映射到指定的路径上。另一个不含selector的原因可能是你严格使用了type: ExternalName。

一个Kubernetes服务是一个抽象层,定义了一个逻辑上的Pods集合,并且对这些Pods启用外部通讯暴露,负载均衡和服务发现

服务和标签[Services and Labels]


一个服务在一组Pods中路由流量。服务是一个抽象的概念,它允许pods在Kubernetes中消亡和复制而不影响应用运行。依赖Pods的发现和路由(比如一个应用的前端和后端组件)也是经由服务来处理。

服务使用labels和selectors来匹配一组Pods,这是一个分组元素,可以在Kubernetes中对多个对象进行逻辑操作。Labels是附加到对象上的键值对,可以以多种方式使用,比如:

  • 指明该对象是用于开发,测试,还是生产环境

  • 嵌入版本标签

  • 使用标签对一个对象进行分类

Labels可以在对象创建时附加到对象上,也可以以后再添加。并且你可以随时修改它们。

hexo next自定义样式

发表于 2017-05-17 | 更新于 2019-06-20 | 分类于 经验

在使用hexo next主题时,可以对网站的样式进行自定义,比如整个网站的背景色,正文字体等等。

主要是因为默认的背景色白的发亮,字体又略小,看久了感觉眼累,所以去折腾了一番,在这里留下经验

修改的地方涉及到CSS样式,主要在${blog_dir}/themes/next/source/css目录下。

修改网站背景色,在${blog_dir}/themes/next/source/css/_variables/base.styl文件中:

1
2
// Background color for <body>
$body-bg-color = #123456 //white

修改正文字体大小,在${blog_dir}/themes/next/source/css/_variables/base.styl文件中:

1
2
// Font size
$font-size-base = 1em //14px

Kubernetes Pod 简介

发表于 2017-05-17 | 更新于 2019-06-20 | 分类于 Kubernetes

Pods


英文原文: https://kubernetes.io/docs/tutorials/kubernetes-basics/explore-intro/

当你创建了一个应用部署后,Kubernetes就会产生一个Pod来托管你的应用实例。一个Pod是Kubernetes的一个抽象概念,代表了一组容器(比如Docker或者rkt)和这些容器的一些共享资源,容器里面包含了一个或多个应用程序,共享资源包括:

  • 共享存储,比如卷。

  • 网络,比如一个唯一的集群IP地址。

  • 关于如何运行每个容器的信息,比如容器镜像版本,或者指定的可用端口。

一个Pod建立了一个特定应用的“逻辑主机”模型,它可以包含多个不同的,但相对来说紧密相关的应用容器。比如,一个Pod可能同时包含你的Node.js应用容器,以及另一个为Node.js服务器提供数据的容器。在一个Pod中的容器共享一个IP地址和端口空间,总是共同被定位以及共同被调度,并运行在同一个节点的共享上下文中。

Pod是Kubernetes平台上的原子单元。当我们在Kubernetes中创建一个应用部署时,部署操作会创建出内含了容器的Pods(而不是直接创建这些容器)。每一个Pod都和它被安排的节点绑定,并一直留在那里直到销毁(根据重启协议)或者删除。假如节点宕机,完全相同的Pods将会被安排在集群的其它可用节点上。

在一个Pod中的多个容器,如果它们紧密相关并且需要共享资源,比如磁盘,那么这些容器必须只能共同调度。

Pods图例


Alt text

节点[Nodes]


一个Pod总是运行在一个节点上。一个节点是在Kubernetes中的一台工作机器,可能是一台虚拟机,也可能是一台物理机,这依赖于集群环境。每一个节点都是由主节点[Master]管理。一个节点可以有多个pod,并且Kubernetes主节点会在整个集群中自动处理pods在节点中的调度问题。主节点的自动化调度会考虑到每一个节点的可用资源。

每一个Kubernetes节点上,至少运行:

  • Kubelet,一个进程,负责Kubernetes主节点和节点之间的通讯;它还管理着运行在这台机器上的Pods和容器。

  • 一个容器运行时(比如Docker,rkt),负责从一个登记仓库中拉取容器镜像,解压容器,并运行应用。

节点图例


Alt text

Linux常用命令积累

发表于 2017-05-10 | 更新于 2019-06-20 | 分类于 经验

kill进程和其所有子进程

父进程和其子进程都有同样的PGID[进程组ID],这个PGID即为父进程的PID。

而kill时,如果传入的PID为负值,则信号就会传给PID进程,以及所有的PGID为这个值的进程,这正好是子进程。

故

1
$ ps -ef | grep "test" | grep -v grep | awk '{print $2}' | xargs -I pid kill -9 -pid

这里面用到了xargs的赋值变量,其实就是替换字符串,即xargs -I pid。这里的pid即为替换字符串,将管道前的输出临时存储到pid中,后面所有出现的pid地方,都替换为管道的输出

查看Linux系统版本

1
2
3
$ uname -a
$ lsb_release -a
$ cat /proc/version
阅读全文 »

Git常用命令积累

发表于 2017-05-06 | 更新于 2019-06-20 | 分类于 git

常用命令

  • git pull <远程主机名> <远程分支名>:<本地分支名>

git pull的作用是:取回远程主机某个分支的更新,再与本地指定分支合并。

如果远程分支是与当前分支合并,则<本地分支名>可以省略,即常见的

1
$ git pull origin master
阅读全文 »

Vanilla JS和D3中获取元素宽高像素值的方法

发表于 2017-05-02 | 更新于 2019-06-20 | 分类于 前端

所谓Vanilla JS,其实就是原生的JavaScript,不依赖于任何库。好吧,这只是个黑话。

在布局处理中,常常需要获取元素的宽高像素值,通常这些元素的宽高是自适应的,或是使用百分比指定,在这种情况下,需要获取其像素宽高,通常在D3应用中,这种情况尤其常见。

假设有元素<div id="container">,需要获取其宽高像素值。

Vanilla JS:

1
2
3
let c = document.getElementById("container"); //获取Element对象
let width = c.getBoundingClientRect().width; //获取像素宽度
let height = c.getBoundingClientRect().height; //获取像素高度

而在D3中,可以使用select达到同样效果:

1
2
3
let svg = d3.select("#container");
let width = svg.node().getBoundingClientRect().width;
let height = svg.node().getBoundingClientRect().height;

网页顶部和侧边栏固定的方法

发表于 2017-04-22 | 更新于 2019-06-20 | 分类于 前端

在常见的网站布局中,通常是如下布局结构:顶部横幅header,紧接着有左侧边栏sider,然后是右边content主体,有的还尾随着底部footer。

Alt text

这里涉及到header的横向铺满视窗,sider的纵向铺满视窗剩余部分,并且多数都会固定header和sider。

阅读全文 »

1…456

runningbar

分享即收获
51 日志
16 分类
© 2020 runningbar
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Muse v7.1.2