利用Git的Rebase功能合并一系列commits

工作中如果使用Git作为版本管理工具的话,应该经常会遇到因为各种原因一下提交了很多个commit的情况,比如添加一个功能,测试出问题继续commit修改,最后git log看提交历史就会变成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# git log
commit 9995aafb7a597d9a7fcf9a341a731324813c5aad (HEAD -> master)
...
Commit 4

commit 54062e7317fa19a228d8f4f63236467317c17672
...
Commit 3

commit 1571ee6b861315ec46875fbececd46c9daaa5d04
...
Commit 2

commit ae95aac116af934742e1dd2eca435a0d6e70b77f
...
Commit 1

commit 3f0373c3afb9e9ffd6174b8244ec3e936d3583e0
...
init

这样看起来不那么美观,也会一定程度上污染主分支,如果遇到问题,需要看diff的时候,也会不那么方便,所以介绍一个利用git rebase命令合并一系列commit的方法。

阅读全文

Istio的流量劫持和Linux下透明代理实现

一般情况下,如果一个程序需要使用代理服务器,那么需要在运行的时候设置一下参数,或者,在Linux下,大部分的程序支持http_proxy这个环境变量,设置这个环境变量,意味着程序将使用设置值作为代理。
这样的问题在于,设置代理这个操作是不透明的,也就是说,客户端必须要知道代理的存在,需要手动设置将流量导入到代理,如果程序本身不支持代理,或者我们不希望执行所有程序的时候都手动设置代理,那么就需要一个相对“透明”的代理办法了。

阅读全文

Calico网络中的ProxyARP

如果K8s使用Calico作为网络方案的话,应该都会知道Calico是个纯3层的方案,也是就说,所有的数据包,都是通过路由的形式找到对应机器和容器的,然后通过BGP协议来将所有的路由同步到所有的机器或者数据中心,来完成整个网络的互联。
简单的来说,Calico针对一个容器,在主机上创建了一堆veth pair,其中一端在主机,一端在容器的网络空间里,然后在主机和容器中分别设置几条路由,来完成网络的互联,我们可以看一个例子:

阅读全文

如何在一秒之内丢弃1000万个网络数据包?

偶然看到一篇cloudflare的博客How to drop 10 million packets per second,如何实现单核情况下一秒钟丢弃1000万个数据包,原文循序渐进,从最简单的用户态丢弃到使用非常新的技术XDP,逐步将单核丢包性能提升到10mpps,很有意思,网上也没有看到原文的中文版本,所以这里顺便翻译一下,看看cloudflare是如何处理类似的情况的。

阅读全文

删除K8s Namespace时卡在Terminating状态

想要删除K8s里的一个Namespace,结果删除了所有该Namespace资源之后使用kubectl delete namespace test发现删除不掉,一直卡在Terminating状态,使用--force参数依然无法删除,报错:
Error from server (Conflict): Operation cannot be fulfilled on namespaces "test": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system.
找了一圈,发现这个Issue,里面有条评论

kubectl get namespace annoying-namespace-to-delete -o json > tmp.json
then edit tmp.json and remove”kubernetes”

curl -k -H “Content-Type: application/json” -X PUT –data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/annoying-namespace-to-delete/finalize

and it should delete your namespace,

跟着试了一下,很管用,直接就删除了:
先运行kubectl get namespace test -o json > tmp.json,拿到当前namespace描述,然后打开tmp.json,删除其中的spec字段。因为这边的K8s集群是带认证的,所以又新开了窗口运行kubectl proxy跑一个API代理在本地的8081端口。最后运行curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/test/finalize

搞定!

阅读全文

kubelet判断机器是否重启逻辑

如果K8s中某个Node节点重启,在Event信息中会有一条消息,大致内容如Node xxxxx has been rebooted, boot id: xxx,而如果是重启kubelet,则不会有这条消息,所以kubelet是怎么判断是自己重启了还是机器重启了呢?

阅读全文

CentOS系统Bonding+VLAN+Bridge配置

由于业务的需要,需要在我们的一台虚拟化机器上,实现如下的配置:

首先,需要将两块网卡设置Bonding并配置交换机对应端口trunk模式;在此基础上,添加宿主机的IP地址,并添加相应的VLAN,最后,还需要添加一个Bridge,用于桥接创建的虚拟机。

由于本身这台机器就是Openstack的宿主机,所以当前的状况是除了所需要的一个Bridge,其他都已经配置完成了,并且由于Openstack的原因,已经有个Bridge virbr0被绑定到bond0上了。
但是呢,这个Bridge是给ovs用的,也就是说,桥接在virbr0上的网络需要自己带上VLAN的tag才能正常工作,而我们希望的是再有一个Bridge br0,桥接在br0上不需要管理VLAN,保持和宿主机相同就可以。

阅读全文

Kubernetes Pod dnsPolicy 配置

在Kubernetes中,可以针对每个Pod设置DNS的策略,通过PodSpec下的dnsPolicy字段可以指定相应的策略,目前支持的策略如下:

  • Default“: Pod继承所在宿主机的设置,也就是直接将宿主机的/etc/resolv.conf内容挂载到容器中。
  • ClusterFirst“: 默认的配置,所有请求会优先在集群所在域查询,如果没有才会转发到上游DNS。
  • ClusterFirstWithHostNet“: 和ClusterFirst一样,不过是Pod运行在hostNetwork:true的情况下强制指定的。
  • None“: 1.9版本引入的一个新值,这个配置忽略所有配置,以Pod的dnsConfig字段为准。

阅读全文

一行Python生成随机字符串

一行Python代码生成随机字符串:

1
import random, string; print(''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15)))

阅读全文

/etc/resolv.conf search和ndots配置

先说说背景,为什么会要了解一下/etc/resolv.conf配置,起因是一个跑在k8s集群的一个业务出现问题,仔细排查后,发现其中一个Pod的域名解析有问题,域名login.example.com被解析到了一个IP,而这个IP地址是另一个范域名*.ichenfu.com的解析,经过一番调查,最终发现是同事在配置一台机器上的kubelet时填错了clusterDomain的配置,将原本需要配置为c2.ichenfu.com的配置写成了c1.ichenfu.com,那么问题来了,为什么这么配置会导致DNS解析到一个错误的,而且是完全不相干的地址的呢?下面就慢慢分析一下。

首先还原一下场景,默认情况下,kubelet启动Pod的时候,会将DNS配置注入到Pod中,出问题的Pod里/etc/resove.conf内容如下:

1
2
3
nameserver 10.254.0.2
search default.svc.c1.ichenfu.com svc.c1.ichenfu.com c1.ichenfu.com localdomain
options ndots:5

阅读全文