kubernetes:概念与架构;创建资源(Deployment、ReplicaSet、DaemonSet、Job、CronJob);Service功能(ClusterIP、NodePort、LoadBalancer);健康检查

 kubernetes概念与架构

复制代码
kubernetes概念说明(Cluster、Master、Node、Pod、Controller、Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job、Service)
============================================================================================================================
Cluster 
    Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。

Master 
    Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行 Linux 操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。
    
Node 
    Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。

Pod 
    Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。
    Pod 是容器的集合,通常会将紧密相关的一组容器放到一个 Pod 中,同一个 Pod 中的所有容器共享 IP 地址和 Port 空间,也就是说它们在一个 network namespace 中。
    Pod 是 Kubernetes 调度的最小单位,同一 Pod 中的容器始终被一起调度。


Kubernetes 引入 Pod 主要基于下面两个目的:
    1.可管理性。
    2.通信和资源共享。

Pods 有两种使用方式:
    1.运行单一容器。one-container-per-Pod 是 Kubernetes 最常见的模型
    2.运行多个容器。
        这些容器联系必须 非常紧密,而且需要 直接共享资源。


Controller 
    1.Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。
    2.Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。
    Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等

每种Controller对应不同的使用场景:
    Deployment 
        最常用的 Controller,比如前面在线教程中就是通过创建 Deployment 来部署应用的。Deployment 可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。
    ReplicaSet 
        实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。
    DaemonSet 
        用于每个 Node 最多只运行一个 Pod 副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon。

    StatefuleSet 
        能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。
    Job 
        用于运行结束就删除的应用。而其他 Controller 中的 Pod 通常是长期持续运行。



Service 
    Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。

Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。


Namespace
    Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。
    多个用户或项目组使用同一个 Kubernetes Cluster,就是用namespace来进行资源隔离的。
    Kubernetes 默认创建了两个 Namespace
kubernetes概念说明(Cluster、Master、Node、Pod、Controller、Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job、Service)
复制代码

 

复制代码
Kubernetes 架构;Master 节点、Node 节点;Kubernetes部署应用的过程
==============================================================================================
Master 节点
    Master 是 Kubernetes Cluster 的大脑,运行着如下 Daemon 服务:kube-apiserver、kube-scheduler、kube-controller-manager、etcd 和 Pod 网络(例如 flannel)

    API Server(kube-apiserver)
        API Server 提供 HTTP/HTTPS RESTful API,即 Kubernetes API。API Server 是 Kubernetes Cluster 的前端接口,各种客户端工具(CLI 或 UI)以及 Kubernetes 其他组件可以通过它管理 Cluster 的各种资源。

    Scheduler(kube-scheduler)
        Scheduler 负责决定将 Pod 放在哪个 Node 上运行。
        Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。

    Controller Manager(kube-controller-manager)
        Controller Manager 负责管理 Cluster 各种资源,保证资源处于预期的状态。Controller Manager 由多种 controller 组成,包括 replication controller、endpoints controller、namespace controller、serviceaccounts controller 等。
        不同的 controller 管理不同的资源。例如 replication controller 管理 Deployment、StatefulSet、DaemonSet 的生命周期,namespace controller 管理 Namespace 资源。

    etcd
        etcd 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。

    Pod 网络
        Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。

---------------------------------------------------------------------------------------------------------------------
Node 节点
    Node 是 Pod 运行的地方,Kubernetes 支持 Docker、rkt 等容器 Runtime。 Node上运行的 Kubernetes 组件有 kubelet、kube-proxy 和 Pod 网络(例如 flannel)。

    kubelet
        kubelet 是 Node 的 agent,当 Scheduler 确定在某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image、volume 等)发送给该节点的 kubelet,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。

    kube-proxy
        service 在逻辑上代表了后端的多个 Pod,外界通过 service 访问 Pod。service 接收到的请求是如何转发到 Pod 的呢?这就是 kube-proxy 要完成的工作。
        每个 Node 都会运行 kube-proxy 服务,它负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。
        如果有多个副本,kube-proxy 会实现负载均衡。

    Pod 网络
        Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。
-------------------------------------------------------------------------------------------------------------------
Kubernetes部署应用的过程:
    1. kubectl 发送部署请求到 API Server。
    2. API Server 通知 Controller Manager 创建一个 deployment 资源。
    3. Scheduler 执行调度任务,将两个副本 Pod 分发到 k8s-node1 和 k8s-node2。
    4. k8s-node1 和 k8s-node2 上的 kubectl 在各自的节点上创建并运行 Pod。

    应用的配置和当前状态信息保存在 etcd 中,执行 kubectl get pod 时 API Server 会从 etcd 中读取这些数据。
Kubernetes 架构;Master 节点、Node 节点;Kubernetes部署应用的过程
复制代码

 Kubernetes 创建资源

复制代码
Deployment 运行应用的过程(了解即可);Kubernetes 创建资源的多种方式:(kubectl run;kubectl apply;kubectl create、kubectl replace、kubectl edit、 kubectl patch)
==================================================================================================
Deployment 运行应用的过程:
    1.用户通过 kubectl 创建 Deployment。
    2.Deployment 创建 ReplicaSet。
    3.ReplicaSet 创建 Pod。
    
    对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。
    nginx-deployment------------------------------Deployment
    nginx-deployment-3954615459-------------------ReplicaSet
    nginx-deployment-3954615459-1gbdv-------------Pod
    nginx-deployment-3954615459-xw6xn-------------Pod

    [root@k8s-master ~]# kubectl get deployment
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   2         2         2            2           23h
    [root@k8s-master ~]# kubectl get replicaset
    NAME                          DESIRED   CURRENT   READY     AGE
    nginx-deployment-3954615459   2         2         2         23h
    [root@k8s-master ~]# kubectl get pod
    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-3954615459-1gbdv   1/1       Running   0          11h
    nginx-deployment-3954615459-xw6xn   1/1       Running   0          23h


-----------------------------------------------------------------------------------------------
Kubernetes 创建资源的多种方式:(kubectl run;kubectl apply;kubectl create、kubectl replace、kubectl edit、 kubectl patch)

    1.用 kubectl 命令直接创建,比如:
        kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
        在命令行中通过参数指定资源的属性。

    2. kubectl apply 不但能够创建 Kubernetes 资源,也能对资源进行更新,非常方便。
        通过配置文件和 kubectl apply 创建,要完成前面同样的工作,可执行命令:
        kubectl apply -f nginx.yml  #这种才是常用的方式

        [root@k8s-master dir_yml]# cat nginx.yml
        apiVersion: extensions/v1beta1          #apiVersion 是当前配置格式的版本
        kind: Deployment                        #kind 是要创建的资源类型,这里是 Deployment。
        metadata:                               #资源的元数据
          name: nginx-deployment                  #name 是必需的元数据项
        spec:                                   #Deployment 的规格说明
          replicas: 2                             #replicas 指明副本数量,默认为 1
          template:                               #template 定义 Pod 的模板,这是配置文件的重要部分
            metadata:                               #定义 Pod 的元数据,
              labels:                                 #至少要定义一个 label。label 的 key 和 value 可以任意指定。
                app: web_server
            spec:                                    #描述 Pod 的规格,此部分定义 Pod 中每一个容器的属性,name 和 image 是必需的。
              containers:
              - name: nginx                            #name 和 image 是必需的
                image: nginx:1.7.9                     #name 和 image 是必需的

    2.其他命令:kubectl create、kubectl replace、kubectl edit 和 kubectl patch。
Deployment 运行应用的过程(了解即可);Kubernetes 创建资源的多种方式:(kubectl run;kubectl apply;kubectl create、kubectl replace、kubectl edit、 kubectl patch)
复制代码

 

复制代码
机制说明:伸缩(Scale Up/Down)、Failover机制、用 label 控制 Pod 的位置
====================================================================================================
伸缩(Scale Up/Down)
    在线增加或减少 Pod 的副本数。
    修改yaml文件的replicas数量,并重新执行kubectl apply;kubernetes会在线增加或减少 Pod 的副本数。

------------------------------------------------------------------------------
Failover机制
    通过拔网线模拟k8s-node2故障
    等待一段时间,Kubernetes 会检查到 k8s-node2 不可用,将 k8s-node2 上的 Pod 标记为 Unknown 状态,并在k8s-node1创建新的pod,维持pod总可用副本数不变
        #node状态切换NotReady很快,但是pod状态切换时间有点长。。。。
        
------------------------------------------------------------------------------
Deployment实验2:用 label 控制 Pod 的位置
kubectl label node k8s-node-2 disktype=ssd_label        #为node节点设置标签
kubectl label node k8s-node-2 disktype-                 #删除node节点的指定标签
kubectl get node --show-labels                          #查看node节点的标签

[root@k8s-master ~]# cat nginx.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 8
  template:
    metadata:
      labels:
        app: web_server
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
      nodeSelector:                 #在pod模板里通过nodeSelector将pod部署到指定node上
        disktype: ssd_label

#执行kubectl apply -f nginx.yml,可以看到8个pod被调度到node2
#删除node节点的标签后,重新apply(即node2无指定标签,但是yml文件内的nodeSelector仍存在),pod分布无变化
#删除yml文件内的nodeSelector后,重新apply,pod分布发生了变化
[root@k8s-master ~]# kubectl get pod -o wide        #这是调度的中间状态;等到稳定状态下,pod总副本数为8
NAME                                READY     STATUS              RESTARTS   AGE       IP          NODE
nginx-deployment-2472058307-118lt   0/1       ContainerCreating   0          2s        <none>      k8s-node-2
nginx-deployment-2472058307-2phqg   1/1       Running             0          6s        10.0.46.2   k8s-node-1
nginx-deployment-2472058307-79xn5   1/1       Running             0          4s        10.0.46.5   k8s-node-1
nginx-deployment-2472058307-7hphw   1/1       Running             0          6s        10.0.46.3   k8s-node-1
nginx-deployment-2472058307-7pplw   1/1       Running             0          5s        10.0.46.4   k8s-node-1
nginx-deployment-2472058307-dqbl3   0/1       ContainerCreating   0          3s        <none>      k8s-node-2
nginx-deployment-2472058307-s5tv3   1/1       Running             0          5s        10.0.35.3   k8s-node-2
nginx-deployment-2658706764-0jxwj   1/1       Terminating         0          7m        10.0.35.6   k8s-node-2
nginx-deployment-2658706764-ddqdp   1/1       Running             0          7m        10.0.35.2   k8s-node-2
nginx-deployment-2658706764-p67mq   1/1       Terminating         0          7m        10.0.35.7   k8s-node-2
nginx-deployment-2658706764-tvgrp   1/1       Running             0          7m        10.0.35.5   k8s-node-2
机制说明:伸缩(Scale Up/Down)、Failover机制、用 label 控制 Pod 的位置
复制代码
复制代码
机制说明:滚动更新Rolling Update、回滚
====================================================================================================
滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新。
    滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。


每次替换的 Pod 数量是可以定制的。
    Kubernetes 提供了两个参数 maxSurge 和 maxUnavailable 来精细控制 Pod 的替换数量



[root@centos7 k8s_yml]# cat httpd.2.2.31.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 5
  template:
    metadata:
      labels:
        run: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2.2.31
        port:
        - containerPort: 80

[root@centos7 k8s_yml]# kubectl apply -f httpd.2.2.31.yml --validate=false
deployment "httpd" created
[root@centos7 k8s_yml]# kubectl get deployment -o wide httpd
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
httpd     5         5         5            5           3m
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   5         5         5         2m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd

#修改版本并重新apply之后
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   0         0         0         4m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd
httpd-985570287   5         5         5         30s       httpd          httpd:2.2.32   pod-template-hash=985570287,run=httpd

[root@centos7 k8s_yml]# kubectl describe deployment httpd
Name:                   httpd
Namespace:              default
CreationTimestamp:      Tue, 18 Jan 2022 17:44:54 +0800
Labels:                 run=httpd
Selector:               run=httpd
Replicas:               5 updated | 5 total | 5 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Conditions:
  Type          Status  Reason
  ----          ------  ------
  Available     True    MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet:  httpd-985570287 (5/5 replicas created)
Events:
  FirstSeen     LastSeen        Count   From                            SubObjectPath   Type            Reason                  Message
  ---------     --------        -----   ----                            -------------   --------        ------                  -------
  5m            5m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled up replica set httpd-910662638 to 5
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled up replica set httpd-985570287 to 1
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled down replica set httpd-910662638 to 4
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled up replica set httpd-985570287 to 2
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled down replica set httpd-910662638 to 3
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled up replica set httpd-985570287 to 3
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled down replica set httpd-910662638 to 2
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled up replica set httpd-985570287 to 4
  1m            1m              1       {deployment-controller }                        Normal          ScalingReplicaSet       Scaled down replica set httpd-910662638 to 1
  1m            1m              2       {deployment-controller }                        Normal          ScalingReplicaSet       (events with common reason combined)

###滚动更新现象,


===========================================================================================================================
回滚
    默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit 属性增加 revision 数量。
    --record 的作用是将当前命令记录到 revision 记录中

[root@centos7 k8s_yml]# kubectl apply -f httpd.2.2.31.yml --record --validate=false
deployment "httpd" created
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   5         5         5         1m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd

[root@centos7 k8s_yml]# kubectl apply -f httpd.2.2.32.yml --record --validate=false
deployment "httpd" configured
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   0         0         0         2m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd
httpd-985570287   5         5         4         7s        httpd          httpd:2.2.32   pod-template-hash=985570287,run=httpd


[root@centos7 k8s_yml]# kubectl rollout history deployment httpd
deployments "httpd"
REVISION        CHANGE-CAUSE
1               kubectl apply -f httpd.2.2.31.yml --record --validate=false
2               kubectl apply -f httpd.2.2.32.yml --record --validate=false



#滚来滚去,版本记录也发生了变化
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   0         0         0         5m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd
httpd-985570287   5         5         5         2m        httpd          httpd:2.2.32   pod-template-hash=985570287,run=httpd
[root@centos7 k8s_yml]# kubectl rollout undo deployment httpd --to-revision=1
deployment "httpd" rolled back
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   5         5         5         5m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd
httpd-985570287   0         0         0         2m        httpd          httpd:2.2.32   pod-template-hash=985570287,run=httpd

[root@centos7 k8s_yml]# kubectl rollout history deployment httpd
deployments "httpd"
REVISION        CHANGE-CAUSE
2               kubectl apply -f httpd.2.2.32.yml --record --validate=false
3               kubectl apply -f httpd.2.2.31.yml --record --validate=false


[root@centos7 k8s_yml]# kubectl rollout undo deployment httpd --to-revision=2
deployment "httpd" rolled back
[root@centos7 k8s_yml]# kubectl get replicaset -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
httpd-910662638   0         0         0         5m        httpd          httpd:2.2.31   pod-template-hash=910662638,run=httpd
httpd-985570287   5         5         4         3m        httpd          httpd:2.2.32   pod-template-hash=985570287,run=httpd
机制说明:滚动更新Rolling Update、回滚
复制代码

 

复制代码
DaemonSet :每个 Node 上最多只能运行一个副本;DaemonSet实验;docker run命令与k8s yml文件对比
===========================================================================================
DaemonSet :每个 Node 上最多只能运行一个副本。

DaemonSet 的典型应用场景有:
    1.在集群的每个节点上运行存储 Daemon,比如 glusterd 或 ceph。
    2.在每个节点上运行日志收集 Daemon,比如 flunentd 或 logstash。
    3.在每个节点上运行监控 Daemon,比如 Prometheus Node Exporter 或 collectd。

教程的kube-flannel-ds、kube-proxy是通过kubernetes部署的,所以通过分析这2个案例来学习DaemonSet
curl https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml > kube-flannel.yml

-----------------------------------------------------------------------
DaemonSet实验:运行自己的 DaemonSet
以 Prometheus Node Exporter 为例演示如何运行自己的 DaemonSet。
直接在 Docker 中运行 Node Exporter 容器,命令为:
docker run -d \
    -v "/proc:/host/proc" \
    -v "/sys:/host/sys" \  
    -v "/:/rootfs" \
    --net=host \  
    prom/node-exporter \  
    --path.procfs /host/proc \  
    --path.sysfs /host/sys \  
    --collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"

将其转换为 DaemonSet 的 YAML 配置文件 node_exporter.yml:
[root@k8s-master ~]# cat node_exporter.yml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: node-exporter-daemonset
  namespace: kube-system                                #指定namespace,此处只是为了展示这个metadata的功能,DaemonSet一般是不会运行在非root namespace的。
spec:
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      hostNetwork: true                                 #使用 Host 的网络
      containers:
      - name: node-exporter
        image: prom/node-exporter
        imagePullPolicy: IfNotPresent
        command:                                        #设置容器启动命令
        - /bin/node_exporter
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --collector.filesystem.ignored-mount-points
        - ^/(sys|proc|dev|host|etc)($|/)
        volumeMounts:
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: root
          mountPath: /rootfs
      volumes:                                          #通过 Volume 将 Host 路径 /proc、/sys 和 / 映射到容器中。
        - name: proc
          hostPath:
            path: /proc
        - name: sys
          hostPath:
            path: /sys
        - name: root
          hostPath:
            path: /

创建成功
[root@k8s-master ~]# kubectl apply -f node_exporter.yml
daemonset "node-exporter-daemonset" created
[root@k8s-master ~]# kubectl get pod  -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-deployment-2472058307-639j0   1/1       Running   0          58m       10.0.46.2      k8s-node-1
nginx-deployment-2472058307-ph65d   1/1       Running   0          58m       10.0.35.3      k8s-node-2
nginx-deployment-2472058307-wbps0   1/1       Running   0          58m       10.0.35.2      k8s-node-2
node-exporter-daemonset-32jjd       1/1       Running   0          7s        192.168.1.82   k8s-node-1
node-exporter-daemonset-k50p2       1/1       Running   0          7s        192.168.1.83   k8s-node-2

===============================================================================
一些错误的测试:
[root@k8s-master ~]# kubectl apply -f node_exporter.yml
Error from server (NotFound): error when creating "node_exporter.yml": namespaces "kube-system111" not found

#指定了不同的namespace,那么k8s就会认为是2个配置yml了?并不会回滚之前的daemonset,而是直接设置新的daemonset
#所以现在在host上存在了一共4个pod,只不过有2个pod是在namespace kube-system中;并且会运行起来,应该是因为冲突吧?最终2个pod的状态为error
[root@k8s-master ~]#  kubectl get pod  -o wide --all-namespaces
NAMESPACE     NAME                                READY     STATUS    RESTARTS   AGE       IP             NODE
default       nginx-deployment-2472058307-639j0   1/1       Running   0          48m       10.0.46.2      k8s-node-1
default       nginx-deployment-2472058307-ph65d   1/1       Running   0          48m       10.0.35.3      k8s-node-2
default       nginx-deployment-2472058307-wbps0   1/1       Running   0          48m       10.0.35.2      k8s-node-2
default       node-exporter-daemonset-90dl5       1/1       Running   0          7m        192.168.1.82   k8s-node-1
default       node-exporter-daemonset-gzb97       1/1       Running   0          7m        192.168.1.83   k8s-node-2
kube-system   node-exporter-daemonset-x18xq       1/1       Running   3          44s       192.168.1.82   k8s-node-1
kube-system   node-exporter-daemonset-xvdzq       0/1       Error     3          44s       192.168.1.83   k8s-node-2


#在daemonset模板中增加了replicas参数,果然会报错,但是增加--validate=false参数,仍然可以执行,但是1个node仍然只运行了1个pod
DaemonSet :每个 Node 上最多只能运行一个副本;DaemonSet实验;docker run命令与k8s yml文件对比
复制代码
复制代码
Job 一次性任务;Job实验;Job实验(测试失败的任务);Job实验:并行执行 Job
=====================================================================================================================
一次性任务job
容器按照持续运行的时间可分为两类:服务类容器和工作类容器。
    1.服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等。
        Deployment、ReplicaSet 和 DaemonSet 都用于管理服务类容器
    2.工作类容器则是一次性任务,比如批处理程序,完成后容器就退出。
        Job 用于管理工作类容器

---------------------------------------------------------------------------
[root@centos7 k8s_yml]# cat myjob.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo","hello k8s job!"]
      restartPolicy: Never


[root@centos7 k8s_yml]# kubectl apply -f myjob.yml
job "my-job" created
[root@centos7 k8s_yml]# kubectl get job
NAME      DESIRED   SUCCESSFUL   AGE
my-job    1         1            47s
[root@centos7 k8s_yml]# kubectl logs my-job-23dxr            #job运行成功
hello k8s job!

---------------------------------------------------------------------------
#执行一次失败的job任务会怎么样?模拟故障,这里在yml文件里传入了一个不存在的yml文件
实验1:command错误 + restartPolicy: Never
#可以看到实验现象:pod运行失败,然后kubernetes不断地启动新pod(因为restartPolicy: Never,所以失败容器不会被重启)
#原因是:当第一个 Pod 启动时,容器失败退出,根据 restartPolicy: Never,此失败容器不会被重启,但 Job DESIRED 的 Pod 是 1,目前 SUCCESSFUL 为 0,不满足,所以 Job controller 会启动新的 Pod,直到 SUCCESSFUL 为 1。
[root@k8s-master dir_yml]# kubectl apply -f myjob_error.yml
job "my-job" created
[root@k8s-master dir_yml]# kubectl get pod --show-all -o wide
NAME           READY     STATUS               RESTARTS   AGE       IP          NODE
my-job-4mvz8   0/1       ContainerCannotRun   0          9s        10.0.35.2   k8s-node-2
my-job-5236c   0/1       ContainerCannotRun   0          5s        10.0.46.2   k8s-node-1
my-job-5m68d   0/1       ContainerCreating    0          0s        <none>      k8s-node-2
my-job-7mbq6   0/1       ContainerCannotRun   0          14s       10.0.46.2   k8s-node-1
my-job-qvl1s   0/1       ContainerCannotRun   0          18s       10.0.35.2   k8s-node-2

---------------------------------------------------------------------------
实验2:command错误 + restartPolicy: OnFailure

#实现现象:容器运行失败后,kubernetes会重启失败的容器

[root@k8s-master dir_yml]# kubectl get pod --show-all -o wide
NAME           READY     STATUS             RESTARTS   AGE       IP          NODE
my-job-gr60j   0/1       CrashLoopBackOff   3          1m        10.0.35.2   k8s-node-2


===================================================================================================================

并行执行 Job
 Job 的并行特性,实际用途不大。

[root@centos7 k8s_yml]# cat myjob2.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
spec:
  completions: 6        #completions参数设置job成功完成 Pod 的总数;默认值为1
  parallelism: 2        #parallelism参数设置并行执行pod的数量;默认值为1
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo","hello k8s job!"]
      restartPolicy: Never


[root@k8s-master dir_yml]# kubectl get pod --show-all
NAME           READY     STATUS      RESTARTS   AGE
my-job-6q59m   0/1       Completed   0          18s
my-job-fss1w   0/1       Completed   0          28s
my-job-pdl3h   0/1       Completed   0          18s
my-job-qh717   0/1       Completed   0          28s
my-job-qwxgn   0/1       Completed   0          13s
my-job-rdk0k   0/1       Completed   0          13s

####Job 一共启动了6个 Pod,而且两两 AGE 相同,可见是并行运行的。
Job 一次性任务;Job实验;Job实验(测试失败的任务);Job实验:并行执行 Job
复制代码

 

复制代码
CronJob:定时执行 Job
---------------------------------------------------------
CronJob 定时执行 Job

 Kubernetes 默认没有 enable CronJob 功能,需要在 kube-apiserver 中加入这个功能。方法很简单,修改 kube-apiserver 的配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml:


[root@centos7 k8s_yml]# cat my_cron_job.yml
apiVersion: batch/v2alpha1                #当前 CronJob 的 apiVersion
kind: CronJob                            #当前资源的类型为 CronJob
metadata:
  name: my-cron-job
spec:
  schedule: "*/1 * * * *"                #每一分钟启动一次
  jobTemplate:                            #定义 Job 的模板,格式与前面 Job 一致
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            command: ["echo","hello k8s job!"]
          restartPolicy: OnFailure

#####定时任务失败了,待验证!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

https://mp.weixin.qq.com/s?__biz=MzIwMTM5MjUwMg==&mid=2653588395&idx=1&sn=6ef803f381616f8d91c214757bf4dd7f&chksm=8d3083b2ba470aa49254ccb8fa4fb0e51cf48e00d0ea8925b03f5e8a18aff0c96b5e2feba722&scene=21#wechat_redirect
CronJob:定时执行 Job
复制代码

 Service功能

复制代码
Kubernetes Service功能;service的多种类型(ClusterIP、NodePort、LoadBalancer);Service IP 原理;实验1:配置service cluster IP、观察iptables;实验2:service NodePort 实验
=======================================================================================================
Kubernetes Service

#个人理解:Kubernetes会根据lable动态维护Service 与 Pod 的映射关系

Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。
Service 有自己 IP,而且这个 IP 是不变的。
客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。
无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。

-------------------------------------------------------------------------------
service有多种类型,默认是ClusterIP

ClusterIP 
    Service 通过 Cluster 内部的 IP 对外提供服务,只有 Cluster 内的节点和 Pod 可访问,这是默认的 Service 类型。

NodePort 
    Service 通过 Cluster 节点的静态端口对外提供服务。
    Cluster 外部可以通过 <NodeIP>:<NodePort> 访问 Service。

LoadBalancer 
    Service 利用 cloud provider 特有的 load balancer 对外提供服务,cloud provider 负责将 load balancer 的流量导向 Service。目前支持的 cloud provider 有 GCP、AWS、Azur 等。
-------------------------------------------------------------------------------
Service IP 原理

Pod 的 IP 是在容器中配置的;service的Cluster IP其实是不存在的,通过iptables来实现

Service Cluster IP 是一个虚拟 IP,是由 Kubernetes 节点上的 iptables 规则管理的。
iptables 将访问 Service 的流量转发到后端 Pod,而且使用类似轮询的负载均衡策略。

Cluster 的每一个节点都配置了相同的 iptables 规则,这样就确保了整个 Cluster 都能够通过 Service 的 Cluster IP 访问 Service。


[root@centos7 k8s_yml]# ip r s m 10.254.182.36        #追踪service clusterIP,直接定位到默认路由。。。
default via 172.17.63.253 dev eth0

-------------------------------------------------------------------------------
kubeadm 部署时会默认安装 kube-dns 组件。
kube-dns 是一个 DNS 服务器。每当有新的 Service 被创建,kube-dns 会添加该 Service 的 DNS 记录。Cluster 中的 Pod 可以通过 <SERVICE_NAME>.<NAMESPACE_NAME> 访问 Service。

kubectl run busybox --rm -it --image=busybox /bin/sh    #这种方式也能创建应用,并进入容器
进入容器后,就可以通过域名来访问service IP,
curl httpd-svc.default:8080
    如果pod和serviceIP在相同的namespace,那么可以省略namespace

####此实验跳过了,因为没有安装kube-dns

===============================================================================================
实验1:配置service cluster IP、观察iptables
#Service Cluster IP 是一个虚拟 IP,是由 Kubernetes 节点上的 iptables 规则管理的。

[root@centos7 k8s_yml]# cat nginx.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: web_server                #设置Deployment应用的标签“app: web_server”
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9

[root@centos7 k8s_yml]# cat service.yml
apiVersion: v1
kind: Service
metadata:
  name: httpd-service
spec:
  selector:
    app: web_server                    #根据标签“app: web_server”筛选pod作为service的后端
  ports:
  - protocol: TCP                    #映射service 8080端口到pod 80端口,使用tcp协议
    port: 8080
    targetPort: 80


[root@centos7 k8s_yml]# kubectl get service
NAME            CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
httpd-service   10.254.182.36   <none>        8080/TCP   40s
kubernetes      10.254.0.1      <none>        443/TCP    16h

[root@centos7 k8s_yml]# curl 10.254.182.36:8080        #访问service IP

[root@centos7 k8s_yml]# kubectl describe service    #查看service与pod的对应关系
Name:                   httpd-service
Namespace:              default
Labels:                 <none>
Selector:               app=web_server
Type:                   ClusterIP
IP:                     10.254.182.36
Port:                   <unset> 8080/TCP
Endpoints:              10.0.32.3:80,10.0.32.4:80
Session Affinity:       None
No events.


    #删除了多余的策略,仅留下了serviceIP相关的策略
    #可以看到策略KUBE-SERVICES应用在了PREROUTING和OUTPUT,这样确保了本机接收、本机转发、本机发出的报文都会经过策略KUBE-SERVICES

    [root@centos7 k8s_yml]# iptables-save |grep -P "KUBE-SERVICES|10.254.182.36|KUBE-SVC-X2P42VLQEZCHLPKZ|10.0.32.3|10.0.32.4"
    :KUBE-SERVICES - [0:0]
    :KUBE-SVC-X2P42VLQEZCHLPKZ - [0:0]
    -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
    -A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES

    -A KUBE-SERVICES -d 10.254.182.36/32 -p tcp -m comment --comment "default/httpd-service: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-X2P42VLQEZCHLPKZ

    -A KUBE-SVC-X2P42VLQEZCHLPKZ -m comment --comment "default/httpd-service:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-V3J6SC7YPE7EHKKB
    -A KUBE-SVC-X2P42VLQEZCHLPKZ -m comment --comment "default/httpd-service:" -j KUBE-SEP-2QG6JRQA3LIDSRC6

    -A KUBE-SEP-2QG6JRQA3LIDSRC6 -s 10.0.32.4/32 -m comment --comment "default/httpd-service:" -j KUBE-MARK-MASQ
    -A KUBE-SEP-2QG6JRQA3LIDSRC6 -p tcp -m comment --comment "default/httpd-service:" -m tcp -j DNAT --to-destination 10.0.32.4:80
    -A KUBE-SEP-V3J6SC7YPE7EHKKB -s 10.0.32.3/32 -m comment --comment "default/httpd-service:" -j KUBE-MARK-MASQ
    -A KUBE-SEP-V3J6SC7YPE7EHKKB -p tcp -m comment --comment "default/httpd-service:" -m tcp -j DNAT --to-destination 10.0.32.3:80

    ----------------------------------------------------------------------------------------------------

    #删除了多余的策略,仅留下了serviceIP相关的策略
    #可以看到策略KUBE-SERVICES应用在了PREROUTING和OUTPUT,这样确保了本机接收、本机转发、本机发出的报文都会经过策略KUBE-SERVICES
    [root@centos7 k8s_yml]# iptables -t nat -nL
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination
    KUBE-SERVICES  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */        #确保了本机接收、本机转发、本机发出的报文都会经过策略KUBE-SERVICES

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    KUBE-SERVICES  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */        #确保了本机接收、本机转发、本机发出的报文都会经过策略KUBE-SERVICES


    Chain KUBE-SERVICES (2 references)
    target     prot opt source               destination
    KUBE-SVC-X2P42VLQEZCHLPKZ  tcp  --  0.0.0.0/0            10.254.182.36        /* default/httpd-service: cluster IP */ tcp dpt:8080    

    Chain KUBE-SVC-X2P42VLQEZCHLPKZ (1 references)
    target     prot opt source               destination
    KUBE-SEP-V3J6SC7YPE7EHKKB  all  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service: */ statistic mode random probability 0.50000000000
    KUBE-SEP-2QG6JRQA3LIDSRC6  all  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service: */


    Chain KUBE-SEP-V3J6SC7YPE7EHKKB (1 references)
    target     prot opt source               destination
    KUBE-MARK-MASQ  all  --  10.0.32.3            0.0.0.0/0            /* default/httpd-service: */                #这一条应该是无关的
    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service: */ tcp to:10.0.32.3:80        #此处进行了DNAT,真正生效的是这一条
    Chain KUBE-SEP-2QG6JRQA3LIDSRC6 (1 references)
    target     prot opt source               destination
    KUBE-MARK-MASQ  all  --  10.0.32.4            0.0.0.0/0            /* default/httpd-service: */
    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service: */ tcp to:10.0.32.4:80






























=====================================================================================================================================
实验2:service NodePort 实验
    由iptables实现功能。
[root@centos7 k8s_yml]# cat service_nodeport.yml
apiVersion: v1
kind: Service
metadata:
  name: httpd-service-nodeport
spec:
  type: NodePort                #NodePort类型的service
  selector:
    app: web_server
  ports:
  - protocol: TCP
    nodePort: 30000                #指定node节点port;默认Kubernetes 会从 30000-32767 中分配一个可用的端口,每个节点都会监听此端口并将请求转发给 Service
    port: 8080                    #ClusterIP 上监听的端口
    targetPort: 80                #Pod 监听的端口


[root@centos7 k8s_yml]# kubectl get service
NAME                     CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
httpd-service            10.254.182.36   <none>        8080/TCP         2h
httpd-service-nodeport   10.254.19.20    <nodes>       8080:31019/TCP   4s        
    #依然分配了clusterIP,同时有2个监听端口
    #8080是clusterIP监听端口
    #31019是node监听端口;
    
[root@centos7 k8s_yml]# netstat -nltp |grep 31019
tcp6       0      0 :::31019                :::*                    LISTEN      19775/kube-proxy

curl 10.254.19.20:8080
curl 127.1:31019



[root@centos7 k8s_yml]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
KUBE-SERVICES  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
KUBE-SERVICES  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */

Chain KUBE-SERVICES (2 references)
target     prot opt source               destination
KUBE-NODEPORTS  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL


Chain KUBE-NODEPORTS (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */ tcp dpt:31019                #看起来此链追踪到末端,作用就是打一个标记?
KUBE-SVC-MXEPW2VD44WIV6HB  tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */ tcp dpt:31019    #看起来此链追踪到末端,作用是进行DNAT

Chain KUBE-MARK-MASQ (6 references)
target     prot opt source               destination
MARK       all  --  0.0.0.0/0            0.0.0.0/0            MARK or 0x4000
Chain KUBE-SVC-MXEPW2VD44WIV6HB (2 references)
target     prot opt source               destination
KUBE-SEP-3534CP4NEW5BHPNH  all  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */ statistic mode random probability 0.50000000000
KUBE-SEP-2ZXVUOXWULLKWDRS  all  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */


Chain KUBE-SEP-2ZXVUOXWULLKWDRS (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  10.0.32.4            0.0.0.0/0            /* default/httpd-service-nodeport: */
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */ tcp to:10.0.32.4:80                #DNAT
Chain KUBE-SEP-3534CP4NEW5BHPNH (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  10.0.32.3            0.0.0.0/0            /* default/httpd-service-nodeport: */
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            /* default/httpd-service-nodeport: */ tcp to:10.0.32.3:80                #DNAT
Kubernetes Service功能;service的多种类型(ClusterIP、NodePort、LoadBalancer);Service IP 原理;实验1:配置service cluster IP、观察iptables;实验2:service NodePort 实验
复制代码

使用命令kubectl get node查找master节点机器
然后ssh到任意一台master节点机器,使用以下命令查看k8s services 网段
grep service-cluster-ip-range /etc/kubernetes/manifests/kube-apiserver.yaml

健康检查

复制代码
Health Check 机制(默认探测、Liveness探测、Readiness探测);探测方法(exec、httpGet);Health Check应用场景举例(Scale Up、Rolling Update);实验1:Liveness 探测;实验2:Readiness 探测
==========================================================================================================================
Health Check
kubernetes探测机制有3种:
    1.默认探测
    2.Liveness探测
    3.Readiness探测

Kubernetes 默认的健康检查机制:
    每个容器启动时都会执行一个进程,此进程由 Dockerfile 的 CMD 或 ENTRYPOINT 指定。如果进程退出时返回码非零,则认为容器发生故障,Kubernetes 就会根据 restartPolicy 重启容器。
    Pod 的 restartPolicy 设置为 OnFailure,默认为 Always。
    sleep 10; exit 1 模拟容器启动 10 秒后发生故障。

--------------------------------------------------------
自愈的默认实现方式是自动重启发生故障的容器。
用户还可以利用 Liveness 和 Readiness 探测机制设置更精细的健康检查,进而实现如下需求:
    1.零停机部署。
    2.避免部署无效的镜像。
    3.更加安全的滚动升级。

Liveness 探测
    Liveness 探测让用户可以自定义判断容器是否健康的条件。如果探测失败,Kubernetes 就会重启容器。
    livenessProbe 部分定义 Liveness 探测规则,Kubernetes 根据Liveness 探测的返回码来判断是否正常。

Readiness 探测
    Readiness 探测则是告诉 Kubernetes 什么时候可以将容器加入到 Service 负载均衡池中,对外提供服务。


Liveness 探测和 Readiness 探测比较:
    1.Liveness 探测和 Readiness 探测是两种 Health Check 机制,如果不特意配置,Kubernetes 将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零来判断探测是否成功。
    2.两种探测的配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。
    3.Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用 Liveness 探测判断容器是否需要重启以实现自愈;用 Readiness 探测判断容器是否已经准备好对外提供服务。

----------------------------------------------------------------------------------------------------------
探测方法:
    exec:
    httpGet:Kubernetes 对于该方法探测成功的判断条件是 http 请求的返回代码在 200-400 之间

===========================================================================================================
Health Check应用场景举例:
场景1.多副本应用的Scale Up(规模增长,部署新pod)
    对于多副本应用,当执行 Scale Up 操作时,新副本会作为 backend 被添加到 Service 的负责均衡中,与已有副本一起处理客户的请求。
        考虑到应用启动通常都需要一个准备阶段,比如加载缓存数据,连接数据库等,从容器启动到正真能够提供服务是需要一段时间的。我们可以通过 Readiness 探测判断容器是否就绪,避免将请求发送到还没有 ready 的 backend。
        在 Scale Up 中使用 Health Check - 每天5分钟玩转 Docker 容器技术(145)

场景2:多副本应用的 Rolling Update

在Rolling Update场景下:
    如果没有配置 Health Check因为新副本本身没有异常退出,默认的 Health Check 机制会认为容器已经就绪,进而会逐步用新副本替换现有副本,其结果就是:当所有旧副本都被替换后,整个应用将无法处理请求,无法对外提供服务。
    如果正确配置了 Health Check,新副本只有通过了 Readiness 探测,才会被添加到 Service;如果没有通过探测,现有副本不会被全部替换,业务仍然正常进行。

    案例期望的是10个正常副本
    但是在滚动更新中,出现了一共13个副本,其中8个正常,5个异常
        这是因为 滚动更新通过参数 maxSurge 和 maxUnavailable 来控制副本替换的数量。

    maxSurge
        此参数控制滚动更新过程中副本总数的超过 DESIRED 的上限。
        maxSurge 可以是具体的整数(比如 3),也可以是百分百,向上取整。maxSurge 默认值为 25%。

    maxUnavailable
        此参数控制滚动更新过程中,不可用的副本相占 DESIRED 的最大比例。 
        maxUnavailable 可以是具体的整数(比如 3),也可以是百分百,向下取整。maxUnavailable 默认值为 25%。

    maxSurge 值越大,初始创建的新副本数量就越多;maxUnavailable 值越大,初始销毁的旧副本数量就越多。
===========================================================================================================
实验1:Liveness 探测
[root@centos7 k8s_yml]# cat liveness.yml
apiVersion: v1
kind: Pod
metadata:
  name: liveness
  labels:
    test: liveness
spec:
  restartPolicy: OnFailure
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy;sleep 30;rm -rf /tmp/healthy;sleep 600
    livenessProbe:                    #定义了Liveness 探测规则
      exec:
        command:                    #Liveness 探测命令
        - cat
        - /tmp/healthy
      initialDelaySeconds: 10        #容器启动 10 之后开始执行 Liveness 探测;需要根据应用启动的准备时间来设置。比如某个应用正常启动要花 30 秒,那么 initialDelaySeconds 的值就应该大于 30。
      periodSeconds: 5                #每 5 秒执行一次 Liveness 探测;Kubernetes 如果连续执行 3 次 Liveness 探测均失败,则会杀掉并重启容器。


[root@centos7 k8s_yml]# kubectl get pod --show-all
NAME       READY     STATUS    RESTARTS   AGE
liveness   1/1       Running   2          3m

#可以额看到pod日志,当liveness探测失败时,将会杀死容器,创建一个新容器"container "liveness" is unhealthy, it will be killed and re-created."
[root@centos7 k8s_yml]# kubectl describe pod
…………………………
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath                   Type            Reason          Message
  ---------     --------        -----   ----                    -------------                   --------        ------          -------
  3m            3m              1       {default-scheduler }                                    Normal          Scheduled       Successfully assigned liveness to centos7
  3m            3m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Started         Started container with docker id 4720412b9dfb
  3m            3m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Created         Created container with docker id 4720412b9dfb; Security:[seccomp=unconfined]
  2m            2m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Killing         Killing container with docker id 4720412b9dfb: pod "liveness_default(5ebf48a3-78cf-11ec-927e-00163e1bae12)" container "liveness" is unhealthy, it will be killed and re-created.
  2m            2m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Started         Started container with docker id 925ccecc40f6
  2m            2m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Created         Created container with docker id 925ccecc40f6; Security:[seccomp=unconfined]
  1m            1m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Killing         Killing container with docker id 925ccecc40f6: pod "liveness_default(5ebf48a3-78cf-11ec-927e-00163e1bae12)" container "liveness" is unhealthy, it will be killed and re-created.
  1m            1m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Started         Started container with docker id 9ed738f1f187
  1m            1m              1       {kubelet centos7}       spec.containers{liveness}       Normal          Created         Created container with docker id 9ed738f1f187; Security:[seccomp=unconfined]
  3m            1m              5       {kubelet centos7}       spec.containers{liveness}       Warning         Unhealthy       Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory

  30s   30s     1       {kubelet centos7}       spec.containers{liveness}       Normal  Killing                 Killing container with docker id 9ed738f1f187: pod "liveness_default(5ebf48a3-78cf-11ec-927e-00163e1bae12)" container "liveness" is unhealthy, it will be killed and re-created.
  3m    30s     4       {kubelet centos7}       spec.containers{liveness}       Normal  Pulling                 pulling image "busybox"
  3m    26s     5       {kubelet centos7}                                       Warning MissingClusterDNS       kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
  3m    26s     4       {kubelet centos7}       spec.containers{liveness}       Normal  Pulled                  Successfully pulled image "busybox"
  26s   26s     1       {kubelet centos7}       spec.containers{liveness}       Normal  Created                 Created container with docker id 71702f49083d; Security:[seccomp=unconfined]
  26s   26s     1       {kubelet centos7}       spec.containers{liveness}       Normal  Started                 Started container with docker id 71702f49083d

-------------------------------------------------------------------------------------------------------------
实验2:Readiness 探测
[root@centos7 k8s_yml]# cat readiness.yml
apiVersion: v1
kind: Pod
metadata:
  name: readiness
  labels:
    test: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy;sleep 30;rm -rf /tmp/healthy;sleep 600
    readinessProbe:                        #仅仅只是把livenessProbe改为readinessProbe
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 30
      periodSeconds: 5

#Readiness 探测的配置语法与 Liveness 探测完全一样
#此处Readiness设置的“restartPolicy: OnFailure”,但是实测pod并不会重启容器;



[root@centos7 k8s_yml]# kubectl get pod
NAME        READY     STATUS    RESTARTS   AGE
readiness   0/1       Running   0          5m


[root@centos7 k8s_yml]# kubectl describe pod

Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath                   Type            Reason                  Message
  ---------     --------        -----   ----                    -------------                   --------        ------                  -------
  5m            5m              1       {default-scheduler }                                    Normal          Scheduled               Successfully assigned readiness to centos7
  5m            5m              1       {kubelet centos7}       spec.containers{readiness}      Normal          Pulling                 pulling image "busybox"
  5m            5m              2       {kubelet centos7}                                       Warning         MissingClusterDNS       kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
  5m            5m              1       {kubelet centos7}       spec.containers{readiness}      Normal          Pulled                  Successfully pulled image "busybox"
  5m            5m              1       {kubelet centos7}       spec.containers{readiness}      Normal          Created                 Created container with docker id 039c6a96394d; Security:[seccomp=unconfined]
  5m            5m              1       {kubelet centos7}       spec.containers{readiness}      Normal          Started                 Started container with docker id 039c6a96394d
  5m            4s              62      {kubelet centos7}       spec.containers{readiness}      Warning         Unhealthy               Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Health Check 机制(默认探测、Liveness探测、Readiness探测);探测方法(exec、httpGet);Health Check应用场景举例(Scale Up、Rolling Update);实验1:Liveness 探测;实验2:Readiness 探测
复制代码

 

Ingress概念

ingress是k8s集群的请求入口,可以理解为对多个service的再次抽象
通常说的ingress一般包括ingress资源对象及ingress-controller两部分组成
ingress-controller有多种实现,社区原生的是ingress-nginx,根据具体需求选择
ingress自身的暴露有多种方式,需要根据基础环境及业务类型选择合适的方式

https://cloud.tencent.com/developer/article/1562688

posted @   雲淡風輕333  阅读(275)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示