参考

1.pod容器

1.一个Pod中运行一个容器。"每个pod中一个容器"的模式是最常见的用法

2.在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位。
pod容器的好处:
Pod做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。
Pod中的容器共享相同的数据和网络地址空间,Pod之间也进行了统一的资源管理与分配

生命周期图
intc容器写在资源清单的init-Container,探针(liveness,readness)写在LivenessProbe,ReadnessProbe,stop&start写在资源清单的lifecycle
main容器包括下面的pause容器和应用程序容器

2.pause容器

k8s解决同一个pod的所有容器共享资源问题

一个Pod下的容器必须运行于同一节点上。现代容器技术建议一个容器只运行一个进程,该进程在容器中PID命令空间中的进程号为1,可直接接收并处理信号,进程终止时容器生命周期也就结束了。若想在容器内运行多个进程,需要有一个类似Linux操作系统init进程的管控类进程,以树状结构完成多进程的生命周期管理。运行于各自容器内的进程无法直接完成网络通信,这是由于容器间的隔离机制导致,k8s中的Pod资源抽象正是解决此类问题,Pod对象是一组容器的集合,这些容器共享Network、UTS及IPC命令空间,因此具有相同的域名、主机名和网络接口,并可通过IPC直接通信。

Pod资源中针对各容器提供网络命令空间等共享机制的是底层基础容器pause,基础容器(也可称为父容器) pause就是为了管理Pod容器间的共享操作,这个父容器需要能够准确地知道如何去创建共享运行环境的容器,还能管理这些容器的生命周期。为了实现这个父容器的构想,kubernetes中,用pause容器来作为一个Pod中所有容器的父容器。

这个pause容器有两个核心的功能
一是它提供整个Pod的Linux命名空间的基础。
二来启用PID命名空间,它在每个Pod中都作为PID为1进程(init进程),并回收僵尸进程

2.1:网络
每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。
Pod中的容器与外界通信时,必须分配共享网络资源例如使用宿主机的端口映射)。
2.2存储
Pod可以指定多个共享的volume。Pod中的所有容器都可以访问共享的volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。

pause功能:
①  PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
② 网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
③ IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
④ UTS命名空间:Pod中的多个容器共享一个主机名;Volumes(共享存储卷):
⑤ Pod中的各个容器可以访问在Pod级别定义的Volumes。

3.pod的三个探针

livenessProbe(存活探针)、readinessProbe(就绪探针)startupProbe(启动探针)三个探针,也是写在pod的资源清单里面的,写好了他的探测机制以及命令,写资源清单的时候没写过
实践参考
初始化容器实践

apiVersion: v1  #指定k8s的官方接口版本,目前就只有v1,这个是这个yaml文档使用服务接口
kind: Pod #指定这个yaml文件是一个Pod数据类型
metadata:
  name: lqh-initpod1   #这个pod的名字
  labels: #给这个pod贴标签
    app: pod01-label
    version: v2 #给这个pod定义一个版本
  namespace: space02   #声明一个新的命名空间

spec: #详细定义这个yaml资源的内容specific具体的单词缩写
  initContainers: #容器执行完就退出了
    - name: redis011 #容器名
      image: redis  #镜像名字
      imagePullPolicy: IfNotPresent # 指定拉取镜像的策略,默认是Always,每次尝试拉去新的, IfNotPresent表示每本的的再去拉
      command: ["echo", "Hello第一个初始化容器redis01!"]
    - name: nginx011  #容器名
      image: nginx  #镜像名字
      imagePullPolicy: IfNotPresent # 指定拉取镜像的策略,默认是Always,每次尝试拉去新的, IfNotPresent表示每本的的再去拉
      command: ["echo", "Hello 第二个初始化容器Nginx01!"]

  containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
    - name: redis01 #容器名
      image: redis  #镜像名字
      imagePullPolicy: IfNotPresent # 指定拉取镜像的策略,默认是Always,每次尝试拉去新的, IfNotPresent表示每本的的再去拉
      ports:
        - containerPort: 6379
          hostPort: 6355
        - containerPort: 8080
          hostPort: 8089
    - name: nginx01  #容器名
      image: nginx  #镜像名字
      imagePullPolicy: IfNotPresent # 指定拉取镜像的策略,默认是Always,每次尝试拉去新的, IfNotPresent表示每本的的再去拉```
     

在这里插入图片描述

在这里插入图片描述

4.pod的的start和stop

pod的启动和退出需要做哪一些操作写在1资源清单的lifecycle的postStart和preStop字段里,这就是start和stop.
参考

5.pod的相位

pod的状态就是相位,说的高大上而已。在这里插入图片描述

由pod的分类知道什么是控制器

Pod 的分类
自主式 Pod:Pod 退出了,此类型的 Pod 不会被创建

控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目

1.replicaController:能保证pod的一定的副本数,pod异常退出会自动创建新的来代替
2.replicaSet:在replicaController基础上支持集合式的selector;可以使用打标签的方式进行指定集合
3.deployment(部署):这个控制器是通过创建replicaSet来进行管理,支持回滚,升级pod(灰度上线)
4.daemonset(守护set):确保k8s集群的每一个node都有这个控制器下pod的副本,当有一个Node加入了就增加一个pod的副本,删除了一个node就相对得去掉一个pod副本

5.statefulSet**:状态控制器**,相对replicaSet和deployment是没状态设计的控制器,例如部署存储的pod.

6.job:一次性执行任务,其中cron job 管理基于时间的定时job

apply 和create的区别

1.kubectl create命令可创建新资源。 因此,如果再次运行该命令,则会抛出错误,因为资源名称在名称空间中应该是唯一的。
2.apply 重复创建一个pod不报错,报pod/lqhpod1 unchanged;资源清单不在在kubectl apply命令中,我们指定系统的目标状态,并且不指定特定操作,因此声明性 。 我们让系统决定采取什么行动。 如果资源不在那里,它将创建它,如果资源在那里,那么它将配置应用于现有资源。

实践ReplicaSet

k8s的污点:
什么是污点容忍度:
taints:污点,定义在节点上,是键值数据
tolerations:容忍度,定义在pod上,可以定义能容忍哪些污点
使节点能够排斥一类特定的 pod。Taint 和 toleration 相互配合,可以用来避免pod 被分配到不合适的节点上。
apply生成rs报错:1 node(s) had taints that the pod didn’t tolerate
解决办法:删除node的污点
污点参考
在这里插入图片描述
replicaset的资源清单(新建一个名称为lqhrs2的rs)

apiVersion: extensions/v1beta1  #指定k8s的官方接口版本,目前就只有v1,这个是这个yaml文档使用服务接口
kind: ReplicaSet
metadata:
  name: lqhrs2
  namespace: space01  #声明一个新的命名空间

spec:
  replicas: 3
  selector:
    matchLabels:
      tier: lqhlabel1
  template: # pod薪资嵌套在这个控制器的template里面
    metadata:
      labels:
        tier: lqhlabel1 #绑定selector的label
    spec:
      nodeName: k8s-master01  #指定了node那么他所有的pod都在这个节点运行
      containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
      - name: redis01 #容器名
        image: redis  #镜像名字
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          hostPort: 6355
        - containerPort: 8080
          hostPort: 8089
      - name: nginx01  #容器名
        image: nginx  #镜像名字
        imagePullPolicy: IfNotPresent



遇到上面bug后看新建结果
在这里插入图片描述

实践rs拉起被删除的pod(控制器自动新建一个来代替
在这里插入图片描述

控制器rs是通过label来控制pod的(注意pod的label是通过键值对来标识的,资源清单的tie也是开发者随意起的名字)

lqhrs2的pod(lqhrs2-vpdvs)更改label之前
在这里插入图片描述
更改之后lqhlabel2
在这里插入图片描述
lqhrs2会新建一个pod维持自己的副本3,lqhrs2-vpdvs这个pod不受lqhrs2这个控制器管了
在这里插入图片描述


## 实践deployment
deployment资源清单(新建一个lqhdm1的deployment)
```yaml
apiVersion: extensions/v1beta1  
kind: Deployment
metadata:
  name: lqhdm1
  namespace: space01  #声明一个新的命名空间

spec:
  replicas: 3
  selector:
    matchLabels:
      dmlab: lqhdmlab
  template: # pod薪资嵌套在这个控制器的template里面
    metadata:
      labels:
        dmlab: lqhdmlab #绑定selector的label
    spec:
      containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
      - name: redis01 #容器名
        image: redis  #镜像名字
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          # hostPort: 6355
        - containerPort: 8080
          # hostPort: 8089
      - name: nginx01  #容器名
        image: nginx  #镜像名字
        imagePullPolicy: IfNotPresent

在这里插入图片描述

scale扩容新建pod是一个逐渐的过程
在这里插入图片描述
更新deployment下的容器的镜像

外部docker制作另外一个nginx镜像nginxv2
在这里插入图片描述
更新镜像不成功应该是不是使用本地的nginxv2 新建起来的,新建的rs(lqhdm1-6c64c5d7dd)下的pod没起来,还是使用原来的rs(lqhdm1-5ddc7f777b)
在这里插入图片描述

查找pod更新镜像失败没起来原因:其他两个node本地没有nginxv2这个镜像,在其他两个节点重复上面操作制作镜像nginxv2之后成功了,dmlqh1这个deployment的下的rs变成了lqhdm1-6c64c5d7dd
在这里插入图片描述
回滚版本
在这里插入图片描述
deployment的其他指令:

kubectl set image deployment/nginx-deployment nginx=nginx:1.91
kubectl rollout status deployments nginx-deployment //查看回滚状态
kubectl get pods
kubectl rollout history deployment/nginx-deployment //查看回滚历史版本
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2 ## 可以使用 --revision参数指定
某个历史版本
kubectl rollout pause deployment/nginx-deployment ## 暂停 deployment 的更新

daemonSet实践

daemon资源清单里面指定replicas会报错 ValidationError(DaemonSet.spec): unknown field “replicas”
原因: daemonSet控制器会保证每一node有一个副本,不用指定
资源清单

apiVersion: apps/v1 #和rs,deployment又不一样
kind: DaemonSet
metadata:
  name: lqhds1
  namespace: space01  #声明一个新的命名空间

spec:
  # replicas: 2 #daemonset是没有这个字段的
  selector:
    matchLabels:
      dslab: lqhdslab
  template: # pod薪资嵌套在这个控制器的template里面
    metadata:
      labels:
        dslab: lqhdslab #绑定selector的label
    spec:
      containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
      - name: redis01 #容器名
        image: redis  #镜像名字
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          # hostPort: 6355
        - containerPort: 8080
          #hostPort: 8089
      - name: nginx01  #容器名
        image: nginx  #镜像名字
        imagePullPolicy: IfNotPresent

看效果,daemonset不会像deployment新建一个rs来实现
在这里插入图片描述
删除一个master上的一个pod,为了维持每一个node上有一个pod副本会立即生成一个新的pod
在这里插入图片描述

job实践
资源和其他控制器有区别不用selector

apiVersion: batch/v1 #和rs,deployment又不一样
kind: Job
metadata:
  name: lqhjob1
  namespace: space01  #声明一个新的命名空间

spec:
  template: # pod薪资嵌套在这个控制器的template里面
    metadata:
    spec:
      containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
      - name: redis01 #容器名
        image: redis  #镜像名字
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
        - containerPort: 8080
        command: ["echo", "Hello 作业帮牛的!"]
      - name: nginx01  #容器名
        image: nginx  #镜像名字
        imagePullPolicy: IfNotPresent
        command: ["echo", "Hello 作业帮牛的!"]
      restartPolicy: Never #容器永不重启

看效果
在这里插入图片描述

cronJob实践

资源清单,job的模板是嵌套在jobTemplate下面的,k8s变量名不能大写
起两个容器的每一分钟的第一秒执行的定时任务

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: lqhCronJob1
  namespace: space01  #声明一个新的命名空间

spec:
  schedule: "*/1 * * * *"  #必写字段,仅支持5位,第一位表示每一分钟的第一秒执行,
  jobTemplate: #job模板,必填,和job的格式一样
    spec:
      template: #是嵌套在jobTemplate下面的
        metadata:
        spec:
          containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
          - name: redis01 #容器名
            image: redis  #镜像名字
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 6379
            - containerPort: 8080
            command: ["echo", "这是一个定时任务哦"]
          - name: nginx01  #容器名
            image: nginx  #镜像名字
            imagePullPolicy: IfNotPresent
            command: ["echo", "这是一个定时任务哦!"]
          restartPolicy: OnFailure #容器异常重启


.spec.concurrencyPolicy:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:

Allow(默认):允许并发运行 Job
Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
Replace:取消当前正在运行的 Job,用一个新的来替换

看效果
在这里插入图片描述
在这里插入图片描述
这个定时任务不删除,会每一分钟新建一个pod,但查询只保留了三个,会定期删除complete的pod

在这里插入图片描述

statefulSet实践

statefulSet有状态服务,之前一直理解错了并不是因为他是能存储数据,其实deployment也可以通过pvc,volume技术挂载的,但deployment是解决不了pod之间主从关系、主备关系等,pod之间是完全对等的关系。statefulset能有稳定的网络标识(通过没有headless service实现),pod之前的启动删除扩展是有顺序的,这个才是为什么他叫有状态服务的原因。
statefulset的资源清单必须有serviceName这个字段的
headless无头服务资源清单

apiVersion: v1
kind: Service
metadata:
  name: lqh-statefulset-svc
  namespace: space02

spec:
  type: ClusterIP
  selector:
    svc-lab: svc-lab-Value #绑定ClusterIp的label
  clusterIP: None  #没有ip的服务svc
  ports:
    - name: redis01p1
      port: 6378 #访问svc暴露的port
      targetPort: 6379 #svc访问pod使用port
    - name: redis01p2
      port: 8090
      targetPort: 8080
    - name: nginx01
      port: 81
      targetPort: 80

statefulset资源清单:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: lqh-svc-statefulset
  namespace: space02  #声明一个新的命名空间

spec:
  serviceName: lqh-statefulset-svc
  replicas: 3
  selector:
    matchLabels:
      stateful-lab: stateful-lab-value
  template: # pod薪资嵌套在这个控制器的template里面
    metadata:
      labels:
        svc-lab: svc-lab-Value
        stateful-lab: stateful-lab-value #
    spec:
      containers: #指定这个pod的容器 下面的中横杠是表示yaml格式的数组
        - name: redis01 #容器名
          image: redis  #镜像名字
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 6379
            - containerPort: 8080
        - name: nginx01  #容器名
          image: nginx  #镜像名字
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

看效果
在这里插入图片描述

statefulset下的pod的名字不会变的。
1.StatefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为: ( p o d n a m e ) . ( h e a d l e s s s e r v e r n a m e ) ,也就意味着 ∗ ∗ 服务间是通过 P o d 域名来通信而非 P o d I P ∗ ∗ ( n o d e 节点通过这个 p o d 名字是行不通的),因为当 P o d 所在 N o d e 发生故障时, P o d 会被飘移到其它 N o d e 上, P o d I P 会发生变化,但是 P o d 域名不会有变化 2. S t a t e f u l S e t 使用 H e a d l e s s 服务来控制 P o d 的域名,这个域名的 F Q D N 为: (podname).(headless server name),也就意味着**服务间是通过Pod域名来通信而非 Pod IP**(node节点通过这个pod名字是行不通的),因为当Pod所在Node发生故障时, Pod 会 被飘移到其它 Node 上,Pod IP 会发生变化,但是 Pod 域名不会有变化 2.StatefulSet 使用 Headless 服务来控制 Pod 的域名,这个域名的 FQDN 为: (podname).(headlessservername),也就意味着服务间是通过Pod域名来通信而非PodIP(node节点通过这个pod名字是行不通的),因为当Pod所在Node发生故障时,Pod会被飘移到其它Node上,PodIP会发生变化,但是Pod域名不会有变化2.StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为:(servicename).$(namespace).svc.cluster.local,其中,“cluster.local” 指的是集群的域名
在这里插入图片描述

进入statefulset的容器里面根据pod名可以访问另外一个pod,这里由无头服务的DNS完成
在这里插入图片描述

k8s是给无头服务(没指定的虚拟ip的clusterIp类型的svc)提供了域名解析服务,可以借助dig指令来解析一下(servicename).$(namespace).svc.cluster.local这个空间下服务的ip映射。k8s域名服务器是在kube-system空间下dnspod。dig指令使用教程
看效果:
在这里插入图片描述
进入到无头服务以外的pod容器内ping无头服务的svc域名lqh-statefulset-svc.space02.svc.cluster.local(或lqh-statefulset-svc.space02),每次打到的ip不一样,一般是轮询,这相当于集群内部服务之间的调用,例如sch调用schui,
注意:在本节点node去ping这个SVC域名是通不了的,因为域名服务只提供给内部服务pod用

在这里插入图片描述
进入到无头服务以外的pod容器内ping无头服务的某一台pod域名也可以不svc.cluster.local
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐