0%

前言

整个k8s诸多组件几乎都是无状态的,所有的数据保存在etcd里,可以说etcd是整个k8s集群的数据库。

具体方案

etcd-backup

https://github.com/giantswarm/etcd-backup

将etcdctl 修改为线上实际的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM alpine:3.8

RUN apk add --no-cache curl

# Get etcdctl
ENV ETCD_VER=v3.2.24
RUN \
cd /tmp && \
curl -L https://storage.googleapis.com/etcd/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz | \
tar xz -C /usr/local/bin --strip-components=1

COPY ./etcd-backup /
ENTRYPOINT ["/etcd-backup"]
CMD ["-h"]

k8s

选择k8s中的cronjob比较合适,备份策略是每三小时备份一次。

cronjob.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: etcd-backup
namespace: kube-system
spec:
schedule: "0 */4 * * *"
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
jobTemplate:
spec:
# Job timeout
activeDeadlineSeconds: 300
template:
spec:
tolerations:
# Tolerate master taint
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
# Container creates etcd backups.
# Run container in host network mode on G8s masters
# to be able to use 127.0.0.1 as etcd address.
# For etcd v2 backups container should have access
# to etcd data directory. To achive that,
# mount /var/lib/etcd3 as a volume.
nodeSelector:
node-role.kubernetes.io/master: ""
containers:
- name: etcd-backup
image: iyacontrol/etcd-backup:0.1
args:
# backup guest clusters only on production instalations
# testing installation can have many broken guest clusters
- -prefix=k8s-prod-1
- -etcd-v2-datadir=/var/lib/etcd
- -etcd-v3-endpoints=https://172.xx.xx.221:2379,https://172.xx.xx.83:2379,https://172.xx.xx.246:2379
- -etcd-v3-cacert=/certs/ca.crt
- -etcd-v3-cert=/certs/server.crt
- -etcd-v3-key=/certs/server.key
- -aws-s3-bucket=mybucket
- -aws-s3-region=us-east-1
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-datadir
- mountPath: /certs
name: etcd-certs
env:
- name: ETCDBACKUP_AWS_ACCESS_KEY
valueFrom:
secretKeyRef:
name: etcd-backup
key: ETCDBACKUP_AWS_ACCESS_KEY
- name: ETCDBACKUP_AWS_SECRET_KEY
valueFrom:
secretKeyRef:
name: etcd-backup
key: ETCDBACKUP_AWS_SECRET_KEY
- name: ETCDBACKUP_PASSPHRASE
valueFrom:
secretKeyRef:
name: etcd-backup
key: ETCDBACKUP_PASSPHRASE
volumes:
- name: etcd-datadir
hostPath:
path: /var/lib/etcd
- name: etcd-certs
hostPath:
path: /etc/kubernetes/pki/etcd/
# Do not restart pod, job takes care on restarting failed pod.
restartPolicy: Never
hostNetwork: true

注意:容忍 和 nodeselector配合,让pod调度到master节点上。

secret.yaml

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Secret
metadata:
name: etcd-backup
namespace: kube-system
type: Opaque
data:
ETCDBACKUP_AWS_ACCESS_KEY: QUtJTI0TktCT0xQRlEK
ETCDBACKUP_AWS_SECRET_KEY: aXJ6eThjQnM2MVRaSkdGMGxDeHhoeFZNUDU4ZGRNbgo=
ETCDBACKUP_PASSPHRASE: ""

VXLAN协议

VXLAN是Virtual eXtensible Local Area Network的缩写,虚拟可扩展的局域网,RFC 7348的标题“A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks”,说明了VXLAN是一个在传统Layer 3网络上架设出来的Layer 2 overlay网络。RFC Abstract如下:

阅读全文 »

RBD介绍

RBD即RADOS Block Device的简称,RBD块存储是最稳定且最常用的存储类型。RBD块设备类似磁盘可以被挂载。 RBD块设备具有快照、多副本、克隆和一致性等特性,数据以条带化的方式存储在Ceph集群的多个OSD中。如下是对Ceph RBD的理解。

阅读全文 »

java.lang.OutOfMemoryError

1
2
3
4
5
6
7
8
9
10
11
12
13
这个服务有一个线程池,在代码里面设置的最小是8,最大限制是2147483647 ,用完的线程要1分钟之后才能回收。这就存在两个问题:
一、业务在持续不断的发送请求,这个服务就会一直创建线程,而因为给定的线程最大值过大,相当于可以无限制的创建线程了,会一直消耗资源;
二、用完的线程1分钟之后才会回收,时间过长。
在这两点的影响下,程序跑一段时间,就会出现创建大量的线程,过度的消耗内存资源.

由于docker容器在最初的时候没有做容器的内存限制,所以默认情况下容器使用的资源是不受限制的。
也就是可以使用主机内核调度器所允许的最大资源,因此当主机发现内存不够用的时候,也会抛出内存溢出的错误。而且会开始杀死一些进程用于释放内存空间。可怕的是任何进程都可能成为内核猎杀的对象,包括 docker daemon 和宿主机上的其它一些重要的程序。更危险的是如果某个支持系统运行的重要进程被kill掉了,整个系统也就宕掉了。

1、开发优化代码,包括限制线程池的最大线程数量和线程回收的时间,重新发布代码打补丁,后面观察到目前,没有再出现类这个问题了;
2、限制docker内存。重新优化了docker容器,限制了docker内存的使用量,减少docker容器过度占用宿主机资源的风险;
3、加强对docker容器的监控与告警;


Linux系统的开机启动顺序

1
加载BIOS–>读取MBR–>Boot Loader–>加载内核–>用户层init用inittab文件来设定系统运行的等级(一般3或者5,3是多用户命令行,5是界面)–>init进程执行rc.syninit–>启动内核模块–>执行不同级别运行的脚本程序–>执行/etc/rc.d/rc.local(本地运行服务)–>执行/bin/login,就可以登录了。

FTP的主动模式和被动模式

1
2
3
4
5
6
7
FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。

PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端在命令链路上用 PORT 命令告诉服务器:“我打开了XX端口,你过来连接我”。于是服务器从20端口向客户端的 XX 端口发送连接请求,建立一条数据链路来传送数据。

PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器在命令链路上用PASV 命令告诉客户端:“我打开了XX端口,你过来连接我”。于是客户端向服务器的 XX 端口发送连接请求,建立一条数据链路来传送数据。

从上面可以看出,两种方式的命令链路连接方法是一样的,而数据链路的建立方法就完 全不同。

系统中出现大量不可中断进程和僵尸进程怎么办

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
进程常见的五种状态:
(1)R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。

(2)D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。

注意:进程长时间处于不可中断状态,通常表示系统有 I/O 性能问题。

(3)Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。

(4)S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。

(5)I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高,I 状态的进程却不会。

进程不常见的两种状态:
1)T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。

向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。

而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行。

(2)X,也就是 Dead 的缩写,表示进程已经消亡,所以你不会在top 或者 ps 命令中看到它。

注意:Ss+:S表示可中断睡眠状态,s表示这个进程是一个会话的领导进程,而+表示前台进程组。


安装dstat
(1)CentOS:yum install -y dstat

(2)Ubuntu:apt install dstat
dstat是一个新的性能工具,它吸收了vmstat、iostat、ifstat等几种工具的优点,可以同时观察系统的CPU、磁盘I/O、网络以及内存使用情况。


(1)dstat 1 10 (间隔1秒输出10组数据)

(2)pidstat -d -p 4344 1 3 (-d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据)

(3)strace -p 6082 (-p指定进程号)Strace最常用的跟踪进程系统调用的工具。

(4)perf record -g(终端运行十五分钟左右,再ctrl+c)

(5)perf report

僵尸进程的处理
要解决僵尸进程,就要找到它的根儿,也就是找出父进程,然后在父进程里解决。

(1)pstree -aps 3084(-a表示输出命令行选项,p表示PID,s表示指定进程的父进程)

(2)接着查看 app 应用程序的代码,看看子进程结束的处理是否正确,比如有没有调用wait() 或 waitpid() ,抑或是,有没有注册 SIGCHLD 信号的处理函数。