源码地址:https://github.com/nangongchengfeng/Kubernetes/tree/main/wordpress-example
Kubernetes实战模拟二,已经优化架构,已经采取分离,可以实现高可用,并优化软策略,防止单点故障
接下来,慢慢实现健康检查和服务质量
版本3
思路:分别对2个pod的进行端口检查,判断pod是否正常和流量提供,测试性能,设置资源限制
健康检查:主要检查pod提供正常服务
资源限制:后期可以根据这个设置HPA。防止宿主资源不足,被驱逐
1、Pod的健康检查,也叫做探针,探针的种类有两种。
1)、livenessProbe,健康状态检查,周期性检查服务是否存活,检查结果失败,将重启容器。
2)、readinessProbe,可用性检查,周期性检查服务是否可用,不可用将从service的endpoints中移除。
livenessProbe (存活检查) # 如果检查失败,将杀死容器,根据Pod的restartPolicy来操作
readinessProbe(就绪检查) # 如果检查失败,kubernetes会把Pod从service endpoints中剔除
 
2、探针的检测方法。
1)、exec,执行一段命令。
2)、httpGet,检测某个http请求的返回状态码。
3)、tcpSocket,测试某个端口是否能够连接。
 
3、startupProbe检测
判断容器内的应用程序是否已启动。如果提供了启动探测,则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet将杀死容器,容器将服从其重启策略。如果容器没有提供启动探测,则默认状态为成功。
注意:不要将startupProbe和readinessProbe混淆。
 
 
 
配置Probe
Probe中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:
- 
initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
 
- 
periodSeconds:执行探测的频率。默认是10秒,最小1秒。
 
- 
timeoutSeconds:探测超时时间。默认1秒,最小1秒。
 
- 
successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
 
- 
failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
 
HTTP probe中可以给 httpGet设置其他配置项:
- 
host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。
 
- 
scheme:连接使用的schema,默认HTTP。
 
- 
path: 访问的HTTP server的path。
 
- 
httpHeaders:自定义请求的header。HTTP运行重复的header。
 
- 
port:访问的容器的端口名字或者端口号。端口号必须介于1和65525之间。
 
 
命名空间:(namespace.yaml)
| 1
2
3
4
 | apiVersion: v1
kind: Namespace
metadata:
  name: kube-example
 | 
 
mysql资源清单
mysql.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
 | apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  namespace: kube-example
  labels:
    app: wordpress
spec:
  selector:
    app: wordpress
    tier: mysql
  ports:
    - port: 3306
      targetPort: dbport
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  namespace: kube-example
  labels:
    app: wordpress
    tier: mysql
spec:
  replicas: 1
  template:
    metadata:
      name: wordpress-mysql
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          args:
          - --default_authentication_plugin=mysql_native_password
          - --character-set-server=utf8mb4
          - --collation-server=utf8mb4_unicode_ci
          ports:
            - containerPort: 3306
              name: dbport
          env:
          - name: MYSQL_ROOT_PASSWORD
            value: rootPassW0rd
          - name: MYSQL_DATABASE
            value: wordpress
          - name: MYSQL_USER
            value: wordpress
          - name: MYSQL_PASSWORD
            value: wordpress
          imagePullPolicy: IfNotPresent
          startupProbe:  #首次启动探测(如果没有成功,不会运行下面livenessProbe)
            tcpSocket:
              port: 3306
            failureThreshold: 2    #探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
            initialDelaySeconds: 20  # 容器启动后第一次执行探测是需要等待多少秒
            timeoutSeconds: 10  # 探测超时时间。默认1秒,最小1秒。
            periodSeconds: 10   # 执行探测的频率。默认是10秒,最小1秒。
         
      restartPolicy: Always
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
 | 
 
因为这个是模拟环境,现在数据没有持续化,如果加上下面的检测,如果pod的有问题,直接重启,数据都会丢失,这个后期数据持久化,我们可以加上面
| 1
2
3
4
5
6
7
8
 |  livenessProbe:
            tcpSocket:
              port: 3306  # 访问的容器的端口名字或者端口号
            initialDelaySeconds: 10
            timeoutSeconds: 5
            failureThreshold: 5
            periodSeconds: 5
            successThreshold: 3  #探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
 | 
 
Wordpress 清单
wordpress.yaml
我们的应用现在还有一个非常重要的功能没有提供,那就是健康检查,我们知道健康检查是提高应用健壮性非常重要的手段,当我们检测到应用不健康的时候我们希望可以自动重启容器,当应用还没有准备好的时候我们也希望暂时不要对外提供服务,所以我们需要添加我们前面经常提到的 liveness probe 和 rediness probe 两个健康检测探针,检查探针的方式有很多,我们这里当然可以认为如果容器的 80 端口可以成功访问那么就是健康的,对于一般的应用提供一个健康检查的 URL 会更好,这里我们添加一个如下所示的可读性探针,为什么不添加存活性探针呢?这里其实是考虑到线上错误排查的一个问题,如果当我们的应用出现了问题,然后就自动重启去掩盖错误的话,可能这个错误就会被永远忽略掉了,所以其实这是一个折衷的做法,不使用存活性探针,而是结合监控报警,保留错误现场,方便错误排查,但是可读写探针是一定需要添加的:
|  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
74
75
76
77
78
79
80
81
 | apiVersion: v1
kind: Service
metadata:
  name: wordpress
  namespace: kube-example
spec:
  selector:
    app: wordpress
    tier: frontend
  ports:
    - port: 80
      name: web
      targetPort: wdport
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  namespace: kube-example
  labels:
    app: wordpress
    tier: frontend
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  replicas: 4 #多副本+pod的反亲合力可以实现pod的高可用
  template:
    metadata:
      name: wordpress
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
        - name: wordpress
          image: wordpress:5.3.2-apache
          ports:
            - containerPort: 80
              name: wdport
          env:
          - name: WORDPRESS_DB_HOST
            value: wordpress-mysql:3306
          - name: WORDPRESS_DB_USER
            value: wordpress
          - name: WORDPRESS_DB_PASSWORD
            value: wordpress
          imagePullPolicy: IfNotPresent
          startupProbe:  #首次启动探测(如果没有成功,不会运行下面livenessProbe)
            httpGet:
              port: 80
            failureThreshold: 2    #探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
            initialDelaySeconds: 10  # 容器启动后第一次执行探测是需要等待多少秒
            timeoutSeconds: 10 #  探测超时时间。默认1秒,最小1秒。
            periodSeconds: 5  # 执行探测的频率。默认是10秒,最小1秒。
          readinessProbe:  # (就绪检查) # 如果检查失败,kubernetes会把Pod从service endpoints中剔除
            httpGet:
              port: 80
            initialDelaySeconds: 10
            timeoutSeconds: 5
            failureThreshold: 5
            periodSeconds: 5
            successThreshold: 3
      affinity:
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              podAffinityTerm:
                topologyKey: kubernetes.io/hostname
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - wordpress
      restartPolicy: Always
 | 
 
上面为什么不用livenessProbe检测,首先如果livenessProbe检测失败,会直接重启pod的,会毁坏错误的信息,不方便我们排查问题。我们有多个副本,如果一个出问题,其余会正常工作
| 1
2
3
4
5
6
7
 |           livenessProbe:  #(存活检查) # 如果检查失败,将杀死容器,根据Pod的restartPolicy来操作
            httpGet:
              port: 80
            initialDelaySeconds: 15
            timeoutSeconds: 5
            periodSeconds: 5
            failureThreshold: 5
 | 
 
PDB策略
pdb.yaml
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 | apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: wordpress-pdb
  namespace: kube-example
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
 | 
 
 
服务质量 QoS
QoS 是 Quality of Service 的缩写,即服务质量。为了实现资源被有效调度和分配的同时提高资源利用率,Kubernetes 针对不同服务质量的预期,通过 QoS 来对 Pod 进行服务质量管理。对于一个 Pod 来说,服务质量体现在两个具体的指标:CPU 和内存。当节点上内存资源紧张时,Kubernetes 会根据预先设置的不同 QoS 类别进行相应处理。
QoS 主要分为 Guaranteed、Burstable 和 Best-Effort三类,优先级从高到低。我们先分别来介绍下这三种服务类型的定义。
Guaranteed(有保证的)
属于该级别的 Pod 有以下两种:
- Pod 中的所有容器都且仅设置了 CPU 和内存的 limits
- Pod 中的所有容器都设置了 CPU 和内存的 requests 和 limits ,且单个容器内的requests==limits(requests不等于0)
Burstable(不稳定的)
Pod 中只要有一个容器的 requests 和 limits 的设置不相同,那么该 Pod 的 QoS 即为 Burstable。
Best-Effort(尽最大努力)
如果 Pod 中所有容器的 resources 均未设置 requests 与 limits,该 Pod 的 QoS 即为 Best-Effort。
fortio 部署
| 1
2
3
4
 | wget https://github.com/fortio/fortio/releases/download/v1.4.4/fortio-1.4.4-1.x86_64.rpm
rpm -ivh fortio-1.4.4-1.x86_64.rpm
nohup fortio server &
tail -f nohup.out
 | 
 
开始测压
命令行
fortio load -c 5 -n 20 -qps 0 http://www.baidu.com
#命令解释如下:
-c 表示并发数
-n 一共多少请求
-qps 每秒查询数,0 表示不限制
Web控制台
   web 控制台方式就是提供给习惯使用 web 界面操作的同学一个途径来使用 Fortio。因为是基于 web  方式,所以就需要首先启动一个 web server,这样客户端浏览器才可以访问到 web server 提供的操作界面进行负载压测。默认情况 fortio server 会启动 8080 端口,如下图所示:
   打开浏览器,输入 http://IP:8080/fortio,访问 Fortio server:
根据实现生成环境访问人数和次数模拟

测试前

测试后


资源限制
采用Guaranteed(有保证的),防止宿主机资源不够被优先驱逐
wordpress
| 1
2
3
4
5
6
7
 |           resources:
            limits:
              cpu: 800m
              memory: 150Mi
            requests:
              cpu: 800m
              memory: 150Mi
 | 
 
mysql
| 1
2
3
4
5
6
7
 |           resources:
            limits:
              cpu: 1000m
              memory: 400Mi
            requests:
              cpu: 1000m
              memory: 400Mi
 | 
 
此版本实现健康检查和服务质量QoS
问题
(1)自动扩缩容
(2)滚动更新策略
(3)数据持久化
(4)mysql账号密码注入等
这些一些列问题,都会在后面的版本架构中优化