树莓派用作透明代理

海外的谷歌什么简直是美好,但是无奈每台机器都要配备特殊工具也是很累.研究了一段时间,发现用Pi做透明代理其实超级简单,也不用一大堆东西,就一个脚本完事.

保存这个脚本,设置到开机启动,替换服务器信息,比如我惯例丢/etc/rc.local,然后就可以用了.

当然,如果梯子超快,全部走海外,那就随你喜欢了.

最后,开启IPv4的转发协议.

CoreOS + VirtualBox

网上安装有很多,但是我要介绍一种全官方方法.需要一台Linux物理机(或者基于KVM架构的虚拟机,也就是可以VirtualBox内只做这个.)

这就是我们需要的 coreos 的镜像,coreos 有稳定版,冒死也要体验Alpha版和差不多就行Beta三个版本,我们想要哪个版本就可以把上面的第三行命令后面加上 -V stable/alpha/beta,来获取所需要的版本.

我这里冒死尝试Alpha版.制作过程最好扶墙,制作系统配置不需要高,并没什么太多复杂运算.最后在当前目录生成了coreos_production_1814.0.0.vdi

然后第二步生成配置驱动,这里只需说明一下第三行命令,第三行是执行脚本生成驱动文件并且把公钥添加到主机系统里.(如果系统未曾拥有公钥,先生成一个.否则报错empty file.).

到这一步,得到coreos_configdrive.iso,Linux使命就完成了~

把VDI和ISO拉出去~ 还有两个钥匙(至少要私钥)

把VDI改成20G大小.

新建虚拟机.

使用刚才做好的VDI硬盘.

创建后加载光盘.

然后把网络改成桥接(或者端口转发)

启动虚拟机.(也可以继续关闭声音啊什么各类没用东西.)

上面给出了IP,使用XSHELL登陆,OK了~

分析下性能,发现真的很快.(这还是在机械硬盘上首次启动.),而且因为我的用户配置里面有Fail,所以拖了不少时间.看了一下是etcd2服务改名了,这个生成脚本还没改,介意的话,还是用stable版本,省事.

用户空间程序还是挺多的.

CoreOS就是Docker时代产物,主要用途,当然是Docker了.

iptables 配合科学上网三件套

服务器:

对应的防火墙规则.

客户端:

对应的防火墙规则.

为什么UDP2RAW要DROP掉呢,据说是因为数据包不是真TCP包,要是全收了,会让内核发出错误的信息,更麻烦.

持久化iptables需要iptables-persistent软件包,可以直接apt安装.

Vultr 2.5 美金添加 IPv4 教程

我先新建了一个IPv4和一个IPv6 Only Debian系统.

然后新建了一个IP,然后绑定在主机.

默认挂载上去也是没法用IPv4资源,因为路由表优先走了运营商级NAT.而这个NAT无公网转发能力.

先按照提示修改文件.(不会修改文件,没救了.)

然后,使用控制面板的重启.

接着,重新连接(这时候其实已经可以用IPv4了,外网可以ping进来了,但是不要使用IPv4连接,修改路由表过程会断IPv4.)

查看了一下默认路由.

果然走的还是运营商NAT,删掉他,并添加默认路由,下面是我公网IP和我的网卡.

具体如下:

正常使用了~

下载IPv4资源测试.(git走IPv4模式下时…)

从 Typecho 迁移到 WordPress

早就听说WordPress多么牛逼,也由于WordPress默认采用MySQL,而我以前用Typecho都是SQLite的,这有很大区别.后来又听说WordPress已经支持SQLite了,于是搬过来,因为我也不是那种几千上万并发的大网站,所以还是很划算的,特别是我的服务器配置特别的低.也由于服务器有其他用途,所以,也就一直用着.

因为Typecho 不能直接过渡到 WordPress,主要还是数据格式不对,于是先转XML是很重要的,幸好,他们都提供了工具,这一点没什么毛病,另外WordPress的Lighttpd重写规则参考如下.(PS:其中我的Tater Web Engine 就是改自 Lighttpd , 性能提升.)

CA证书绑定root_bundle,pem证书是私钥和自己网站crt合并的.另外还有很多安全性配置,最好能关闭TLS 1.0(然后发现有些设备不支持),还有严格处理后,很多主题也不能用,以前Typecho因为功能简单,都是我自己做二次开发不觉得,现在感觉WP强大后,有点难控制啊.

最后,喜欢Lighttpd的原因是因为,服务器只有256MB RAM,如果开SWAP当然可以更好,但是,我觉得会影响实际性能.

Docker 学习之路 – Docker 运行时资源限制

Docker 基于 Linux 内核提供的 cgroups 功能,可以限制容器在运行时使用到的资源,比如内存、CPU、块 I/O、网络等。

内存限制

概述

Docker 提供的内存限制功能有以下几点:

  • 容器能使用的内存和交换分区大小。
  • 容器的核心内存大小。
  • 容器虚拟内存的交换行为。
  • 容器内存的软性限制。
  • 是否杀死占用过多内存的容器。
  • 容器被杀死的优先级

一般情况下,达到内存限制的容器过段时间后就会被系统杀死。

内存限制相关的参数

执行docker run命令时能使用的和内存限制相关的所有选项如下。

选项 描述
-m,--memory 内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
--memory-swap 内存+交换分区大小总限制。格式同上。必须必-m设置的大
--memory-reservation 内存的软性限制。格式同上
--oom-kill-disable 是否阻止 OOM killer 杀死容器,默认没设置
--oom-score-adj 容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0
--memory-swappiness 用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数
--kernel-memory 核心内存限制。格式同上,最小为 4M

用户内存限制

用户内存限制就是对容器能使用的内存和交换分区的大小作出限制。使用时要遵循两条直观的规则:-m,--memory选项的参数最小为 4 M。--memory-swap不是交换分区,而是内存加交换分区的总大小,所以--memory-swap必须比-m,--memory大。在这两条规则下,一般有四种设置方式。

你可能在进行内存限制的实验时发现docker run命令报错:WARNING: Your kernel does not support swap limit capabilities, memory limited without swap.
这是因为宿主机内核的相关功能没有打开。按照下面的设置就行。
step 1:编辑/etc/default/grub文件,将GRUB_CMDLINE_LINUX一行改为GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
step 2:更新 GRUB,即执行$ sudo update-grub
step 3: 重启系统。

1. 不设置

如果不设置-m,--memory--memory-swap,容器默认可以用完宿舍机的所有内存和 swap 分区。不过注意,如果容器占用宿主机的所有内存和 swap 分区超过一段时间后,会被宿主机系统杀死(如果没有设置--00m-kill-disable=true的话)。

2. 设置-m,--memory,不设置--memory-swap

-m--memory设置一个不小于 4M 的值,假设为 a,不设置--memory-swap,或将--memory-swap设置为 0。这种情况下,容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因为 Docker 默认容器交换分区的大小和内存相同。
如果在容器中运行一个一直不停申请内存的程序,你会观察到该程序最终能占用的内存大小为 2a。
比如$ docker run -m 1G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小也为 1G。容器内的进程能申请到的总内存大小为 2G。

3. 设置-m,--memory=a--memory-swap=b,且b > a

-m设置一个参数 a,给--memory-swap设置一个参数 b。a 时容器能使用的内存大小,b是容器能使用的 内存大小 + swap 分区大小。所以 b 必须大于 a。b -a 即为容器能使用的 swap 分区大小。
比如$ docker run -m 1G --memory-swap 3G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小为 2G。容器内的进程能申请到的总内存大小为 3G。

4. 设置-m,--memory=a--memory-swap=-1

-m参数设置一个正常值,而给--memory-swap设置成 -1。这种情况表示限制容器能使用的内存大小为 a,而不限制容器能使用的 swap 分区大小。
这时候,容器内进程能申请到的内存大小为 a + 宿主机的 swap 大小。

Memory reservation

这种 memory reservation 机制不知道怎么翻译比较形象。Memory reservation 是一种软性限制,用于节制容器内存使用。给--memory-reservation设置一个比-m小的值后,虽然容器最多可以使用-m使用的内存大小,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占用回到--memory-reservation设置的值大小。
没有设置时(默认情况下)--memory-reservation的值和-m的限定的值相同。将它设置为 0 会设置的比-m的参数大 等同于没有设置。
Memory reservation 是一种软性机制,它不保证任何时刻容器使用的内存不会超过--memory-reservation限定的值,它只是确保容器不会长时间占用超过--memory-reservation限制的内存大小。
例如:

如果容器使用了大于 200M 但小于 500M 内存时,下次系统的内存回收会尝试将容器的内存锁紧到 200M 以下。
例如:

容器可以使用尽可能多的内存。--memory-reservation确保容器不会长时间占用太多内存。

OOM killer

默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。这个杀死进程来节省内存的进程,我们姑且叫它 OOM killer。我们可以通过设置--oom-kill-disable选项来禁止 OOM killer 杀死容器内进程。但请确保只有在使用了-m/--memory选项时才使用--oom-kill-disable禁用 OOM killer。如果没有设置-m选项,却禁用了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。
下面的例子限制了容器的内存为 100M 并禁止了 OOM killer:

是正确的使用方法。
而下面这个容器没设置内存限制,却禁用了 OOM killer 是非常危险的:

容器没用内存限制,可能或导致系统无内存可用,并尝试时杀死系统进程来获取更多可用内存。
一般一个容器只有一个进程,这个唯一进程被杀死,容器也就被杀死了。我们可以通过--oom-score-adj选项来设置在系统内存不够时,容器被杀死的优先级。负值更教不可能被杀死,而正值更有可能被杀死。

核心内存

核心内存和用户内存不同的地方在于核心内存不能被交换出。不能交换出去的特性使得容器可以通过消耗太多内存来堵塞一些系统服务。核心内存包括:

  • stack pages(栈页面)
  • slab pages
  • socket memory pressure
  • tcp memory pressure

可以通过设置核心内存限制来约束这些内存。例如,每个进程都要消耗一些栈页面,通过限制核心内存,可以在核心内存使用过多时阻止新进程被创建。
核心内存和用户内存并不是独立的,必须在用户内存限制的上下文中限制核心内存。
假设用户内存的限制值为 U,核心内存的限制值为 K。有三种可能地限制核心内存的方式:

  1. U != 0,不限制核心内存。这是默认的标准设置方式
  2. K < U,核心内存时用户内存的子集。这种设置在部署时,每个 cgroup 的内存总量被过度使用。过度使用核心内存限制是绝不推荐的,因为系统还是会用完不能回收的内存。在这种情况下,你可以设置 K,这样 groups 的总数就不会超过总内存了。然后,根据系统服务的质量自有地设置 U。
  3. K > U,因为核心内存的变化也会导致用户计数器的变化,容器核心内存和用户内存都会触发回收行为。这种配置可以让管理员以一种统一的视图看待内存。对想跟踪核心内存使用情况的用户也是有用的。

例如:

容器中的进程最多能使用 500M 内存,在这 500M 中,最多只有 50M 核心内存。

没用设置用户内存限制,所以容器中的进程可以使用尽可能多的内存,但是最多能使用 50M 核心内存。

Swappiness

默认情况下,容器的内核可以交换出一定比例的匿名页。--memory-swappiness就是用来设置这个比例的。--memory-swappiness可以设置为从 0 到 100。0 表示关闭匿名页面交换。100 表示所有的匿名页都可以交换。默认情况下,如果不适用--memory-swappiness,则该值从父进程继承而来。
例如:

 
--memory-swappiness设置为 0 可以保持容器的工作集,避免交换代理的性能损失。

CPU 限制

概述

Docker 的资源限制和隔离完全基于 Linux cgroups。对 CPU 资源的限制方式也和 cgroups 相同。Docker 提供的 CPU 资源限制选项可以在多核系统上限制容器能利用哪些 vCPU。而对容器最多能使用的 CPU 时间有两种限制方式:一是有多个 CPU 密集型的容器竞争 CPU 时,设置各个容器能使用的 CPU 时间相对比例。二是以绝对的方式设置容器在每个调度周期内最多能使用的 CPU 时间。

CPU 限制相关参数

docker run命令和 CPU 限制相关的所有选项如下:

选项 描述
--cpuset-cpus="" 允许使用的 CPU 集,值可以为 0-3,0,1
-c,--cpu-shares=0 CPU 共享权值(相对权重)
cpu-period=0 限制 CPU CFS 的周期,范围从 100ms~1s,即[1000, 1000000]
--cpu-quota=0 限制 CPU CFS 配额,必须不小于1ms,即 >= 1000
--cpuset-mems="" 允许在上执行的内存节点(MEMs),只对 NUMA 系统有效

其中--cpuset-cpus用于设置容器可以使用的 vCPU 核。-c,--cpu-shares用于设置多个容器竞争 CPU 时,各个容器相对能分配到的 CPU 时间比例。--cpu-period--cpu-quata用于绝对设置容器能使用 CPU 时间。
--cpuset-mems暂用不上,这里不谈。

CPU 集

我们可以设置容器可以在哪些 CPU 核上运行。
例如:

表示容器中的进程可以在 cpu 1 和 cpu 3 上执行。

表示容器中的进程可以在 cpu 0、cpu 1 及 cpu 3 上执行。
在 NUMA 系统上,我们可以设置容器可以使用的内存节点。
例如:

表示容器中的进程只能使用内存节点 1 和 3 上的内存。

表示容器中的进程只能使用内存节点 0、1、2 上的内存。

CPU 资源的相对限制

默认情况下,所有的容器得到同等比例的 CPU 周期。在有多个容器竞争 CPU 时我们可以设置每个容器能使用的 CPU 时间比例。这个比例叫作共享权值,通过-c--cpu-shares设置。Docker 默认每个容器的权值为 1024。不设置或将其设置为 0,都将使用这个默认值。系统会根据每个容器的共享权值和所有容器共享权值和比例来给容器分配 CPU 时间。
假设有三个正在运行的容器,这三个容器中的任务都是 CPU 密集型的。第一个容器的 cpu 共享权值是 1024,其它两个容器的 cpu 共享权值是 512。第一个容器将得到 50% 的 CPU 时间,而其它两个容器就只能各得到 25% 的 CPU 时间了。如果再添加第四个 cpu 共享值为 1024 的容器,每个容器得到的 CPU 时间将重新计算。第一个容器的CPU 时间变为 33%,其它容器分得的 CPU 时间分别为 16.5%、16.5%、33%。
必须注意的是,这个比例只有在 CPU 密集型的任务执行时才有用。在四核的系统上,假设有四个单进程的容器,它们都能各自使用一个核的 100% CPU 时间,不管它们的 cpu 共享权值是多少。
在多核系统上,CPU 时间权值是在所有 CPU 核上计算的。即使某个容器的 CPU 时间限制少于 100%,它也能使用各个 CPU 核的 100% 时间。
例如,假设有一个不止三核的系统。用-c=512的选项启动容器{C0},并且该容器只有一个进程,用-c=1024的启动选项为启动容器C2,并且该容器有两个进程。CPU 权值的分布可能是这样的:

CPU 资源的绝对限制

Linux 通过 CFS(Completely Fair Scheduler,完全公平调度器)来调度各个进程对 CPU 的使用。CFS 默认的调度周期是 100ms。

关于 CFS 的更多信息,参考CFS documentation on bandwidth limiting

我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少 CPU 时间。使用--cpu-period即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的 CPU 时间。两者一般配合使用。
例如:

将 CFS 调度的周期设为 50000,将容器在每个周期内的 CPU 配额设置为 25000,表示该容器每 50ms 可以得到 50% 的 CPU 运行时间。

将容器的 CPU 配额设置为 CFS 周期的两倍,CPU 使用时间怎么会比周期大呢?其实很好解释,给容器分配两个 vCPU 就可以了。该配置表示容器可以在每个周期内使用两个 vCPU 的 100% 时间。
CFS 周期的有效范围是 1ms~1s,对应的--cpu-period的数值范围是 1000~1000000。而容器的 CPU 配额必须不小于 1ms,即--cpu-quota的值必须 >= 1000。可以看出这两个选项的单位都是 us。

正确的理解“绝对”

注意前面我们用--cpu-quota设置容器在一个调度周期内能使用的 CPU 时间时实际上设置的是一个上限。并不是说容器一定会使用这么长的 CPU 时间。比如,我们先启动一个容器,将其绑定到 cpu 1 上执行。给其--cpu-quota--cpu-period都设置为 50000。

调度周期为 50000,容器在每个周期内最多能使用 50000 cpu 时间。
再用docker stats test01可以观察到该容器对 CPU 的使用率在100%左右。然后,我们再以同样的参数启动另一个容器。

再用docker stats test01 test02可以观察到这两个容器,每个容器对 cpu 的使用率在 50% 左右。说明容器并没有在每个周期内使用 50000 的 cpu 时间。
使用docker stop test02命令结束第二个容器,再加一个参数-c 2048启动它:

再用docker stats test01命令可以观察到第一个容器的 CPU 使用率在 33% 左右,第二个容器的 CPU 使用率在 66% 左右。因为第二个容器的共享值是 2048,第一个容器的默认共享值是 1024,所以第二个容器在每个周期内能使用的 CPU 时间是第一个容器的两倍。

61.8元 极光KVM测试

相比于Neq3Host,极光KVM有另一个缺点,最明显的就是偷偷跑流量,经过我多天观察,也不知道去哪里反映,只能说自己来吧,发现了一个问题.都是UDP攻击.

原来默认开了这么多端口.(Debian 9 系统)

难怪不安全,rpcbind是局域网用于一些发现的,我们也不用啊.

还有exim4,给大家发垃圾邮件的可乘之机?我自己不发邮件,可以丢掉.增加安全性.

atop是个好工具,但是为什么要监听外部端口呢,而且平时我也不同他啊.htop更顺手,省点资源吧.

再看看系统上有什么进程.有个fail2ban,理论上,他就是保护系统安全的,但是同时,也是消耗系统资源的.我已经把SSH端口改掉了,也从来没人来猜.我的autodeny.sh更省资源.丢掉.

然后重启看看效果.清净多了~

最后整理下,装Debian 9的同学,直接执行这三句,搞定.

剩下SSH,最好改个端口,换SSH KEY登陆.

具体就是编辑sshd_config.

 

Virmach 正确打开方式

Virmach 很便宜,限制也很多,不是老司机随便翻车.
限制条款如下:

  1. High CPU: Customer’s Service cannot burst to 95-100% usage for more than five (5) minutes and cannot average higher than 50% usage within any two (2) hour period. Packages advertised to include dedicated CPU, Services with the high CPU option, and any customized Service plans that include high CPU option may burst to 100% at all times.
    高CPU占用: 客户的VPS不能占用95%~100%超过5分钟或者两小时内平均超过50%.
  2. High Load: Customer’s Service cannot have a 15-minute load average higher than the number of full logical cores assigned and cannot have a 1-day load average higher than 70% of the number of full logical cores assigned.
    高负载: 客户的VPS不能高于所分配核心数15分钟,或者一天内不能高于平均70%.
  3. High Mail Volume: VirMach reserves the right to block port 25 on Customer’s Service. Customer cannot send more than 100 maximum e-mails per hour, and must maintain a similar average volume of mail on a week-to-week basis—no bursting permitted. VirMach reserves the right to waive this requirement for the purpose of a customized Service plan.
    高邮件发送: Virmach保留屏蔽25端口的权利.客户不能发送高于100封邮件/小时,或者是每周不能超过16800封,没有突发值.
  4. High I/O: Customer’s Service cannot average more than 80 IOPS within any two (2) hour period, cannot burst above 300MB/s disk write average for more than ten (10) minutes, cannot average more than 300 write operations per second for more than 1 hour, and cannot be above 20% average utilization within any six (6) hour period.
    高I/O占用: 客户的机型在2小时内不能超过平均80IOPS,10分钟突发值不能超过300MB/s,平均值超过300次/秒持续时间不能超过1个小时,6小时内不能高于20%平均利用率.
  5. High Network Usage: Customer’s Service cannot have more than 50,000 conntrack sessions at any given time, and cannot use more than the allocated bandwidth. Customer understands that the network is shared and utilizing maximum network speed will not always be possible.
    高网络占用:客户机型在任何时间内不能超过50000链接, 不能超过分配的带宽; 客户同意所标注网络值为共享值,在实际使用中并非总能达到最大速率.

apt-get install cgroup-bin cgroup-tools cgroupfs-mount libcgroup1 cpulimit
针对第一个,对CPU进行限制.在cron添加cpulimit限制,把高占用限死.我保守一点,就让他一直只有40%的CPU.加入Cron,每分钟跑一次,把所有程序拉到里面.

针对第二个,是Load Avg,如果CPU一旦限制,再加上这么便宜的,基本单线程,没办法提上去,所以也解决了.
针对第三个,是你自己发邮件,这个控制不了
针对第四个,使用cgroup管理一下IO,2小时不得超过80,这简直是超级机械钻石盘.不过实际上,不要长时间占用,一般没人管.
 
.

Docker 学习之路 – 仓库用户管理

现在谁都有权限去操作仓库,而且如果人多了,每个人都改改配置也好麻烦.
那可以签名证书,不过,你先有个指向域名…

没多久,域名就生效了.
创建SSL证书也是个麻烦事情.
第一步.创建 CA 私钥(我就敷衍了事,全部回车.)

第二步,(新建)配置根证书文件root-ca.cnf

第三步,签发.

第四步,生成站点私钥.(不要抄我域名了~)


第五步,生成私钥请求文件.(继续敷衍了事)

第六步,配置证书.新建site.cnf文件.

第七步:部署

第八步:把得到的两个文件放ssl文件夹.(我推荐挪到/etc/docker/registry/ssl/)

容器里面的/etc/docker/registry/config.yml是配置文件,但是,我们不能操作他.在容器外做一个config.yml,然后用文件挂载方式挂进去.(根据你实际情况作出改变)

再做一个auth的文件夹.(记得替换用户名密码)

创建docker-compose.yml(这个我也不太理解,先做着.)

想启动,发现缺组件.

现在目录结构.

之前登录过DockerHub,现docker logout,然后docker login docker.lijingquan.net,然后悲剧了,自签证书的毛病.

还能怎样,信任他.然后重启容器服务,再重启仓库容器.就可以登录.

其他操作就没差别了… (还是开放docker好啊.)
好像还遇到nginx 403问题,说是文件过大…