glance 镜像导入

基于rbd存储, 上传glance镜像

1
2
3
4
5
6
7
8
openstack image create "CentOS 7.6 64bit" \
--disk-format raw --container-format bare \
--public --min-disk 50 \
--property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi \
--property hw_video_model=qxl --property vm_mode=hvm \
--property os_distro=centos \
--property os_type=linux \
--property hw_qemu_guest_agent=yes

#rbd -p sata_pool1 import –image-format 2 CentOS76.raw

#rbd -p sata_pool1 snap create –image CentOS76.raw –snap snap

#rbd -p sata_pool1 snap protect –image CentOS76.raw –snap snap

#glance location-add –url rbd://$ceph_fsid/sata_pool1/CentOS76.raw/snap $image_uuid

go goproxy代理

In Linux or macOS, you can execute the below commands.

1
2
3
4
# Enable the go modules feature
export GO111MODULE=on
# Set the GOPROXY environment variable
export GOPROXY=https://goproxy.io

Or, write it into the .bashrc or .bash_profile file.

In Windows, you can execute the below commands.

PowerShell Copy

1
2
3
4
# Enable the go modules feature
$env:GO111MODULE="on"
# Set the GOPROXY environment variable
$env:GOPROXY="https://goproxy.io"

Now, when you build and run your applications, go will fetch dependencies via goproxy.io. See more information in the goproxy repository.

If your Go version >= 1.13, the GOPRIVATE environment variable controls which modules the go command considers to be private (not available publicly) and should therefore not use the proxy or checksum database. For example:

Go version >= 1.13 Copy

1
2
3
go env -w GOPROXY=https://goproxy.io,direct
# Set environment variable allow bypassing the proxy for selected modules
go env -w GOPRIVATE=*.corp.example.com

Linux 使用阿里云yum源

1
2
3
4
5
6
7
8
9
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XBYBL322DY"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());

gtag('config', 'G-XBYBL322DY');
</script>

基于CentOS 7 x86_64

1
2
3
#wget -O /etc/yum.repos.d/aliyun-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 

#wget -O /etc/yum.repos.d/aliyun-epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

Linux vim 报错 E437

E437: terminal capability “cm” required

这个错误一般是环境变量TERM没有配置或者配置错误所致。

解决办法:

执行export TERM=xterm;

或者将export TERM=xterm 添加至/etc/profile文件中即可。

或者

方法1:要是偷懒,那直接执行命令 export TERM=linux 或者 export TERM=xterm

方法2:要下一劳永逸,将上述命令写入 /etc/bashrc 文件确保永久生效,切记保存后顺手执行 source /etc/bashrc

docker 安装MySQL 8.0

使用docker安装MySQL 8.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#wget https://download.docker.com/linux/centos/docker-ce.repo
#yum -y install docker-ce
#systemctl restart docker
#docker pull mysql:8.0
#mkdir /data/mysql/{conf,data,log}
#docker run -p 3306:3306 --name mysql8 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0
#docker cp mysql8:/etc/mysql /data/mysql/conf
#docker rm -f mysql8
#docker run \
-p 13306:3306 \
--name mysql8 \
--privileged=true \
--restart unless-stopped \
-v /data/mysql/log:/var/log/mysql \
-v /data/mysql/data:/var/lib/mysql \
-v /etc/localtime:/etc/localtime \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:8.0
#docker restart mysql8
1
2
3
4
5
6
7
8
9
#docker exec -it mysql8 bash
#mysql -uroot -p

>CREATE USER 'stack'@'%' identified by '123456';
>grant all on *.* to'stack'@'%';

更改root密码
>alter user 'root'@'localhost' identified by '123456';
>flush privileges;
1
>set global max_connections=1000;

git 常用命令

代码回退

默认参数 -soft,所有commit的修改都会退回到git缓冲区

参数–hard,所有commit的修改直接丢弃

$ git reset –hard HEAD^ 回退到上个版本 $ git reset –hard commit_id 退到/进到 指定commit_id

推送到远程

$ git push origin HEAD –force

新增tag

1
2
3
4
$git tag -a v1.0.0 -m "stable version 1.0.0"
$git push origin v1.0.0
(推送所有)
$git push origin --tags

push代码

1
2
强制push
$git push origin master -f
fork 上游
1
2
3
4
5
6
7
8
9
10
$git remote add upstream git@****:g-virt-dev/devops/hieradata.git

$git remote -v

$git fetch upstream

$git checkout master

$git merge upstream/master
剩下的开始提交就行
clone代码
1
2
指定tag/分支 clone代码
#git clone --branch [tags标签] [git地址] 或者 git clone --b [tags标签] [git地址]
仓库镜像
1
2
$ cd old-repository.git
$ git push --mirror https://github.com/exampleuser/new-repository.git

kubernetes calico 网络分析

Calico架构

Calico主要由Felix、etcd、BGP client、BGP Route Reflector组成。

  • Etcd:负责存储网络信息
  • BGP client:负责将Felix配置的路由信息分发到其他节点
  • Felix:Calico Agent,每个节点都需要运行,主要负责配置路由、配置ACLs、报告状态
  • BGP Route Reflector:大规模部署时需要用到,作为BGP client的中心连接点,可以避免每个节点互联

kubernetes flannel 网络分析

Flannel是kubernetes的CNI网络插件之一,实质上是一种主机 overlay网络 。flannel支持多种网络转发模式,常用的是vxlan、hostgw等,我们这里以常用的 VXLAN协议讲解。

**Flannel 特点 : **

  1. 使集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址。

  2. 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。

  3. 创建一个新的虚拟网卡flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。

  4. etcd保证了所有node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化。

各个组件的解释:

Cni0 :网桥设备,每创建一个pod都会创建一对 veth pair。其中一端是pod中的eth0,另一端是Cni0网桥中的端口(网卡)。Pod中从网卡eth0发出的流量都会发送到Cni0网桥设备的端口(网卡)上。

Cni0 设备获得的ip地址是该节点分配到的网段的第一个地址。

Flannel.1 : overlay网络的设备,用来进行 vxlan 报文的处理(封包和解包)。不同node之间的pod数据流量都从overlay设备以隧道的形式发送到对端。

Flanneld :flannel在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。同时Flanneld监听K8s集群数据库,为flannel.1设备提供封装数据时必要的mac,ip等网络数据信息。

不同node上的pod的通信流程:

  1. pod中产生数据,根据pod的路由信息,将数据发送到Cni0

  2. Cni0 根据节点的路由表,将数据发送到隧道设备flannel.1

  3. Flannel.1查看数据包的目的ip,从flanneld获得对端隧道设备的必要信息,封装数据包。

  4. Flannel.1将数据包发送到对端设备。对端节点的网卡接收到数据包,发现数据包为overlay数据包,解开外层封装,并发送内层封装到flannel.1设备。

  5. Flannel.1设备查看数据包,根据路由表匹配,将数据发送给Cni0设备。

  6. Cni0匹配路由表,发送数据给网桥上对应的端口。

测试集群 k8s定义的flannel网络(POD CIDR) 为172.20.0.0/16。

下面用用案例解释网络内不同POD间通信的一个网络实现吧

1
2
3
4
5
6
7
10.19.114.100 - pod1 路由
#kubectl -n stack exec -it api-0 -- bash
#ip route show

default via 172.20.0.1 dev eth0
172.20.0.0/24 dev eth0 proto kernel scope link src 172.20.0.73
172.20.0.0/16 via 172.20.0.1 dev eth0

image-20201016183244304

1
2
3
4
5
6
7
10.19.114.101 - pod2 路由
#kubectl -n stack exec -it redis-64c6c549ff-5plcq -- bash
#ip route show

default via 172.20.1.1 dev eth0
172.20.0.0/16 via 172.20.1.1 dev eth0
172.20.1.0/24 dev eth0 proto kernel scope link src 172.20.1.11

image-20201016183228551

由此可看出,默认POD 网卡网关走 .1 网关,而网关即为cni0 的IP,下一步分析流量到了宿主机之后的走向~~

1
2
3
4
5
6
7
8
9
10.19.114.100 宿主机路由
#ip route -n
default via 10.19.114.1 dev eth0
10.19.114.0/24 dev eth0 proto kernel scope link src 10.19.114.100
10.250.250.0/24 dev eth1 proto kernel scope link src 10.250.250.100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.20.0.0/24 dev cni0 proto kernel scope link src 172.20.0.1
172.20.1.0/24 via 172.20.1.0 dev flannel.1 onlink
172.20.2.0/24 via 172.20.2.0 dev flannel.1 onlink
1
2
3
4
5
6
7
8
9
10.19.114.101 宿主机路由
#ip route -n
default via 10.19.114.1 dev eth0
10.19.114.0/24 dev eth0 proto kernel scope link src 10.19.114.101
10.250.250.0/24 dev eth1 proto kernel scope link src 10.250.250.101
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.20.0.0/24 via 172.20.0.0 dev flannel.1 onlink
172.20.1.0/24 dev cni0 proto kernel scope link src 172.20.1.1
172.20.2.0/24 via 172.20.2.0 dev flannel.1 onlink

由如上路由可知,据最小匹配原则,匹配到上面的一条路由表项。从10.19.114.100 上去往172.20.1.0/24 网段的包,发送172.20.1.0 网关,网关设备是flannel.1

flannel.1为vxlan设备,当数据包来到flannel.1时,需要将数据包封装起来。此时的dst ip 为172.20.1.11,src ip为172.20.0.73。数据包继续封装需要知道172.20.1.11 ip地址对应的mac地址。此时,flannel.1不会发送arp请求去获得172.20.1.11 的mac地址,而是由Linux kernel将一个“L3 Miss”事件请求发送的用户空间的flanned程序。Flanned程序收到内核的请求事件之后,从etcd查找能够匹配该地址的子网的flannel.1设备的mac地址,即发往的pod所在host中flannel.1设备的mac地址。Flannel在为Node节点分配ip网段时记录了所有的网段和mac等信息,所以能够知道。

1
2
3
#ip neigh |grep 172
172.20.2.0 dev flannel.1 lladdr 82:c4:0e:f2:00:6f PERMANENT
172.20.1.0 dev flannel.1 lladdr 42:6e:8b:9b:e2:73 PERMANENT

到这里,vxlan的内层数据包就完成了封装。格式是这样的:

VXLAN的转发过程主要依赖于FDB(Forwarding Database)实现, VXLAN设备根据MAC地址来查找相应的VTEP IP地址,继而将二层数据帧封装发送至相应VTEP。

1
2
3
4
5
6

#/sbin/bridge fdb show dev flannel.1
42:6e:8b:9b:e2:73 dst 10.19.114.101 self permanent
ba:8b:ce:f3:b8:51 dst 10.19.114.101 self permanent
42:6f:c7:06:3e:a0 dst 10.19.114.102 self permanent
82:c4:0e:f2:00:6f dst 10.19.114.102 self permanent

kernel需要查看node上的fdb(forwarding database)以获得内层封包中目的vtep设备所在的node地址。因为已经从arp table中查到目的设备mac地址为42:6e:8b:9b:e2:73,同时在fdb中存在该mac地址对应的node节点的IP地址。如果fdb中没有这个信息,那么kernel会向用户空间的flanned程序发起”L2 MISS”事件。flanneld收到该事件后,会查询etcd,获取该vtep设备对应的node的”Public IP“,并将信息注册到fdb中。

当内核查看fdb获得了发往机器的ip地址后,arp得到mac地址,之后就能完成vxlan的外层封装。

具体可以通过wireshark抓包分析

10.19.114.101节点的eth0网卡接收到vxlan设备包,kernal将识别出这是一个vxlan包,将包拆开之后转给节点上的flannel.1设备。这样数据包就从发送节点到达目的节点,flannel.1设备将接收到一个如下的数据包

目的地址为172.20.1.11,到达10.19.114.101 flannel.1后查找自己的路由表,根据路由表完成转发,由下图可知,flannel.1将去往172.20.1.0/24的流量转发到cni0上去。。

image-20201020121011465

查看cni0网桥信息, cni0 网络通过绑定pod 的网卡和宿主机网卡,通过veth实现通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#brctl show
bridge name bridge id STP enabled interfaces
cni0 8000.a656432b14cf no veth1f7db117
veth3ee31d24
veth521bc030
veth5a59ced4
veth649412bd
veth65bbf59f
veth6ed62916
veth7e8e7733
veth9787b6ba
veth98c762b8
vethaf05d94b
vethc07c69cd
vethdf62bded
vethe2cf7392
vethf4995a29
docker0 8000.024216a031b6 no

由下图可知 172.20.1.11 的POD 网卡 对应 link-netnsid 0

image-20201020121943429

由下图可知 172.20.1.11 的POD 网卡 在宿主机上的veth 为 vethf4995a29

image-20201020121907024

所以在cni0网桥上挂载的pod的veth pair为vethf4995a29 , eth0@if21和vethf4995a29@if3组成的一对veth,pair。从而将流量注入到pod的eth0网卡上