k8s

本文详细介绍了Kubernetes中的Pod及其初始化容器、容器探针、Pod相位,接着讲解了资源控制器如ReplicaSet、Deployment、DaemonSet、Job、CronJob的用法和特点。此外,还探讨了Service的各种类型、Ingress-Nginx的部署及配置,以及ConfigMap和Secret在存储敏感数据方面的作用。最后,文章提到了存储相关的Volume类型和持久化卷(PV)、持久化卷声明(PVC)以及StatefulSet的有序特性及其应用场景。

文章目录

pod

  • 资源清单
    • 明称空间级别
      • pod
    • 集群级别
      • role、namespace、node、role、clusterRole、roleBinding、ClusterRoleBinding
    • 元数据
      • HPA

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L33TYpAW-1576315971384)(E:\OneDrive\笔记\markdown\picture\image-20191118220148390.png)]

容器初始化

  • pod能有多个容器,应用运行在容器里面,但是他也有可能有一个或多个先于容器启动的Init容器。

  • init容器与普通容器非常像,除了以下两点:

    • 1.inti容器总是运行到成功完成为止
    • 2.每个init容器都必须在下一个init容器启动之前成功完成

如果pod的init容器启动失败,kubernetes会不断重启该pod,直到init容器成功为止。然而,如果pod对应的restartPolicy为Never,他不会重新启动

InitC

Pod能够具有多个容器,应用运行在容器里面,但是他也有一个或多个先于应用容器启动的Init容器。

Init容器与普通容器非常像,除了以下两点:

  • Init容器总是运行到成功完成为止
  • 每个Init容器都必须在下一个Init容器启动之前成功完成

如果Pod的Init容器容器失败,Kubernetes会不断重启该Pod,直到Init容器启动成功为止。然而,如果Pod对应的restartPolicy为Never,他不会重新启动。

Init容器的作用:

因为Init容器具有与应用程序容器分离的单独镜像,所以他们的启动相关代码具有如下优势:

  • 他们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用容器镜像中包含这些实用工具的
  • 他们可以包含实用工具或定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要FROM另一个镜像,只需要在安装过程中实用类似sed、awk、python、dig这样的工具
  • 应用程序镜像可以分离出创建和部署的角色,而没有必要联合他们构件一个单独的镜像
  • Init容器使用Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因此,他们能够具有访问Secrit的权限,而应用程序容器则不能。
  • 他们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动的方法,知道满足了一组先决条件。

特殊说明:

  • Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。这会在验证过程中强制执行
  • 在Pod中的每个app和Init容器的名称必须唯一;与任何其他容器共享同一个名称,会在验证时抛出错误。

init模板:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh','-c','echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox
    command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
apiVersion: v1
kind: Service
metadata:
 name: myservice
spec:
 ports:
   - protocol: TCP
     port: 80
     targetPort: 1111
---
apiVersion: v1
kind: Service
metadata:
 name: mydb
spec:
 ports:
   - protocol: TCP
     port: 80
     targetPort: 1112

容器探针

探针是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。

有三种类型的处理程序:

  1. ExecAction:在容器内执行指定命令。如果命令退出时返回码为0,则认为诊断成功。

  2. TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的

  3. HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果(200<=状态码<400),则诊断被认为是成功的

    HTTP probe中可以给httpGet设置以下配置项:

    • host: 连接的主机名,默认连接到pod的ip
    • scheme: 支持的协议,http、https,默认http
    • path:访问的HTTP server的path
    • httpHeaders:自定义请求的header
    • port:访问的容器的端口名字或者端口号,端口号必须介于1和65525之间

每次探测都将获得以下三种结果之一:

  • 成功:容器通过了诊断
  • 失败:容器未通过诊断
  • 未知:诊断失败,因此不会采取任何行动

???Probe中的精切配置,可以更精确的配置liveness和readiness检测:

  • periodSeconds: 3每3秒执行一次探测。执行探测的频率,默认是10秒,最小1秒
  • initialDelaySeconds: 3容器初始化完成后延迟3秒执行探测
  • timeoutSeconds:探测超时时间,默认1秒,最小1秒
  • successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认1,最小值是1。对于liveness必须是1
  • failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3,最小值是1

探测方式

  • 以下就绪检测和存活检测可以同时设置
  • 就绪检测和存货检测均支持以上三种检测方式
  • livenessProbe存活探针:指示容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器会受其重启策略的影响。如果容器不提供存活探针,则默认状态为Success
  • readinessProbe就绪探针:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success
检测探针-就绪检测

readinessProbe-httpget

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: tomcat:v1 #镜像名称
    imagePullPolicy: Never #镜像拉去策略,IfNotPresent:本地docker没有时从仓库拉取
    readinessProbe:
      httpGet: #httpget方式的探针诊断类型
        port: 8080 #访问的端口
        path: /docs/index.html #httpget请求的路径
      initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
      periodSeconds: 3 #每3秒检测一次
检测探针-存活检测

如果不符合存活条件就销毁pod再创建新的pod,与上面的就绪检测有一定差别

livenessProbe-exec

说明:以下容器启动时会先创建一个live文件,然后过60秒再删除这个文件。存活检测每三秒检测一次这个文件是否存在,如果不存在会直接销毁容器,重新创建。最后的现象就是pod会隔段时间不断重启

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox #不写镜像tag默认是latest
    imagePullPolicy: IfNotPresent #镜像拉去策略,IfNotPresent:本地docker没有时从仓库拉取
    command: ["bin/sh","-c","touch /tmp/live;sleep 60;rm -rf /tmp/live;sleep 60"] #容器创建完后先创建一个live文件,睡60秒,删除文件再睡60秒
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"] #测试文件是否存在,不存在就重启
      initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
      periodSeconds: 3 #每3秒检测一次

livenessProbe-httpget

说明:启动是正常的,进到容器内删除tomcat中的webapps/docs/index.html后,就会探活失败,pod会重启。

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: tomcat
    imagePullPolicy: IfNotPresent
    ports:
    - name: haha
      containerPort: 8080 #pod暴露的端口,此端口仅是额外的信息,对端口是否被暴露没有影响,不太理解
    livenessProbe:
      httpGet:
        port: haha #试探时发现要与上面的ports中的haha相对应才行,否则要直接写一个具体的端口号。
        path: /docs/index.html #访问的HTTP server的path
      initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
      periodSeconds: 3 #每3秒检测一次
      timeoutSeconds: 10 #超时时间

livenessProbe-tcp

说明:tcp探活探测端口9090是否有监听,本处是没有的,探测9090端口时没返回,而且超时时间设置为1秒,直接超时导致认为pod是挂的,会不断重启pod

apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcp-pod
  namespace: default
spec:
  containers:
  - name: liveness-tcp-container
    image: tomcat
    imagePullPolicy: IfNotPresent
    livenessProbe:
      initialDelaySeconds: 5 #容器初始化完成后延时几秒再探测
      periodSeconds: 3 #每3秒检测一次
      timeoutSeconds: 1 #超时时间
      tcpSocket: #tcp探测端口是否开启,如果没有监听则认为容器是挂的,就会重启pod
        port: 9090

启动退出动作

也即当容器启动时要做的事情,与容器停止时要做的事情。

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-pod #pod名称
  namespace: default
spec:
  containers:
  - name: lifecycle-demo-container #容器名称
    image: tomcat
    lifecycle:
      postStart: #启动容器后的操作
        exec:
          command: ["/bin/sh","-c","echo Hello postStart handler > /home/msg.txt"]
      preStop: #停止容器前的操作
        exec:
          command: ["/bin/sh","-c","echo bye~  postStop handler > /home/msg.txt"]

pod phase(相位):状态

  • 挂起(pending):Pod已被Kubernetes系统接受,但有一个或多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间
  • 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已经被创建。至少有一个容器在运行,或者正在 处于启动或停止的状态
  • 成功(Succeeded):Pod中所有的容器都被成功终止,并且不会再重启
  • 失败(Failed):Pod中所有的容器都已经终止,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
  • 未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败

资源控制器

Pod控制器

什么是控制器

Kubernetes 中内建了很多 controller(控制器),这些相当于一个状态机,用来控制 Pod 的具体状态和行为

控制器类型

  • ReplicationController 和 ReplicaSet
  • Deployment
  • DaemonSet
  • StateFulSet
  • Job/CronJob
  • Horizontal Pod Autoscaling

ReplicationController 和 ReplicaSet

ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收;

在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController 。ReplicaSet 跟ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector;RC已经被逐渐废弃!

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括;

  • 定义 Deployment 来创建 Pod 和 ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续 Deployment

DaemonSet

DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod

使用 DaemonSet 的一些典型用法:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterdceph
  • 在每个 Node 上运行日志收集 daemon,例如fluentdlogstash
  • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd 、Datadog 代理、[[New Relic 代理,或 Ganglia gmond
  • New Relic 代理,或 Ganglia gmond

Job

Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束

CronJob

Cron Job 管理基于时间的 Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行

使用前提条件:

当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)。对于先前版本的集群,版本 <1.8,启动 API Server时,通过传递选项--runtime-config=batch/v2alpha1=true可以开启 batch/v2alpha1API

典型的用法如下所示:

  • 在给定的时间点调度 Job 运行
  • 创建周期性运行的 Job,例如:数据库备份、发送邮件

StatefulSet

StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序

StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)

Horizontal Pod Autoscaling

应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放

Deployment控制器

RS 与 RC 与 Deployment 关联

RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收

Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有本质的不同,只是名字不一样,并且 RS 支持集合式的 selector

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: replicaset-demo #注意名字不能有大写字母
spec:
  replicas: 3
  selector:
    matchLabels: #标签选择器
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: my-tomcat
        image: tomcat
        env:
        - name: yc #环境变量key
          value: yangche #环境变量value
        ports:
        - containerPort: 80 #容器暴露的端口

RS 与 Deployment 的关联

image-20191124193014656

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

Ⅰ、部署一个简单的 Nginx 应用

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
    labels:
      app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record
## --record参数可以记录命令,我们可以很方便的查看每次 revision 的变化

Ⅱ、扩容


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值