2-k8s基本单元-Pod

16 篇文章 0 订阅
6 篇文章 0 订阅

1、k8s项目部署(项目上线)

1、项目上线流程

在这里插入图片描述

2、k8s中部署nginx和tomcat

部署Nginx:

# 创建一个Deployment控制器管理Pod
kubectl create deployment nginx --image=nginx
# 对外暴露服务
kubectl expose deployment nginx --port=80 --type=NodePort --name nginx
kubectl get pod,svc

访问地址:http://NodeIP:Port

部署Tomcat:

# 托管Pod到Deployment
kubectl create deployment tomcat --image=tomcat
# 对外暴露服务
kubectl expose deployment tomcat --port=8080 --type=NodePort --name tomcat

访问地址:http://NodeIP:Port

1、k8s资源-Pod

1、Pod概述

image.png

  • Pod是k8s系统中可以创建和管理的最小单元

  • 其他资源都是用来支撑和扩展Pod对象功能的

  • Pod是由一个或多个container组成的

  • 每个Pod都有一个特殊的容器Pause(根容器)

  • 除了Pause容器,还包含一个或多个紧密相连的业务容器

  • 每个Pod都是一个应用实例,有专用的IP

  • 同一个 Pod 中的容器总会被调度到相同 Node 节点,不同节点间 Pod 的通信基于虚拟二层网 络技术实现

  • Pod可以分为普通Pod和静态Pod(特定由kubelet管理)

2、Pod特性

  1. 资源共享

    多个容器间共享存储和网络

  2. 生命周期短暂

    发生故障被重新调度后,将是一个全新的Pod

  3. 平坦的网络

    K8s 集群中的所有 Pod 都在同一个共享网络地址空间中,也就是说每个 Pod 都可以通过其 他 Pod 的 IP 地址来实现访问

3、Pod分类

Pod的两种类型:

  1. 普通Pod

    普通 Pod 一旦被创建,就会被放入到 etcd 中存储,随后会被 Kubernetes Master 调度到某 个具体的 Node 上并进行绑定,随后该 Pod 对应的 Node 上的 kubelet 进程实例化成一组相 关的 Docker 容器并启动起来。在默认情 况下,当 Pod 里某个容器停止时,Kubernetes 会 自动检测到这个问题并且重新启动这个 Pod 里某所有容器, 如果 Pod 所在的 Node 宕机, 则会将这个 Node 上的所有 Pod 重新调度到其它节点上

  2. 静态Pod

    静态 Pod 是由 kubelet 进行管理的仅存在于特定 Node 上的 Pod,它们不能通过 API Server 进行管理,无法与 ReplicationController、Deployment 或 DaemonSet 进行关联,并且 kubelet 也无法对它们进行健康检查

4、Pod管理命令

# 创建Pod:
kubectl apply -f <file.yaml>
kubectl create -f <file.yaml>

# 或者使用命令:kubectl run <Pod_name> --image=<IMAGE> 

# 查看Pod:
kubectl get pods [命名空间]
kubectl describe pod <Pod名称>

# 查看日志:
kubectl logs <Pod名称>  [-c CONTAINER]
kubectl logs <Pod名称>  [-c CONTAINER] -f

# 进入容器终端:
kubectl exec <Pod名称> [-c CONTAINER] -- bash

# 删除Pod:
kubectl delete pod <Pod名称>

5、在k8s上运行第一个应用

kubectl run web --image=nginx --port=80 
  • web:Pod的名称
  • –image:指定镜像
  • –port:指定监听端口

查看创建的Pod:

kubectl get pod --namespace default [-o wide|yaml]

删除Pod

kubectl delete pod <pod_name>/all [-n namespace]

获取pod的yaml资源清单文件

kubectl get pod web -o yaml

6、Pod创建的工作流程

在这里插入图片描述

  1. kubectl 向api server 发起一个create pod 请求

  2. api server接收到pod创建请求后,不会去直接创建pod,而是生成一个包含创建信息并写入到etcd

  3. scheduler 查看 k8s api ,类似于通知机制。

  4. 判断pod.spec.Node == null?若为null,表示这个Pod请求是新来的,需要创建;因此先进行调度计算,找到最“闲”的node,并“报告”给apiserver。

  5. 写入etcd数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点)

  6. 对应节点的kubelet 通过”监视“发现api server 中有了个新的Node。

  7. 通过节点上的运行时去创建Pod。

  8. kubelet将结果“报告”给 apiserver。

  9. 将结果写入etcd。

7、访问web应用

kubectl expose pod web --type=NodePort --port=80 --target-port=80

8、Pod生命周期和重启策略

Pod整个生命周期被定义为各种状态,熟悉Pod的各种状态有助于理解Pod调度和重启策略,以及问题的排查

Pod的各种状态也被称为phase(阶段),定义在Pod的PodStatus对象的phase 字段中。

1. Pod状态

主要的有如下几种:

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

在这里插入图片描述

Pod 有一个 PodStatus 对象,其中包含一个 PodCondition 数组。 PodCondition包含以下以下字段:

  • lastProbeTime:Pod condition最后一次被探测到的时间戳。
  • lastTransitionTime:Pod最后一次状态转变的时间戳。
  • message:状态转化的信息,一般为报错信息,例如:containers with unready status: [c-1]。
  • reason:最后一次状态形成的原因,一般为报错原因,例如:ContainersNotReady。
  • status:包含的值有 True、False 和 Unknown。
  • type:Pod状态的几种类型。

其中type字段包含以下几个值:

  • PodScheduled:Pod已经被调度到运行节点。
  • Ready:Pod已经可以接收请求提供服务。
  • Initialized:所有的init container已经成功启动。
  • Unschedulable:无法调度该Pod,例如节点资源不够。
  • ContainersReady:Pod中的所有容器已准备就绪。

除了以上Pod的几种阶段性状态之外,我们在创建应用并观察时,也会经常看到Pod会有一下几种常见的状态信息:

CrashLoopBackOff: 容器退出,kubelet正在将它重启
InvalidImageName: 无法解析镜像名称
ErrImageNeverPull: 策略禁止拉取镜像
ImagePullBackOff: 正在重试拉取
RegistryUnavailable: 连接不到镜像中心
ErrImagePull: 通用的拉取镜像出错
ContainerCreating:容器创建中
PodInitializing:pod 初始化中

2. 重启策略(restartPolicy)

Pod通过restartPolicy字段指定重启策略,重启策略类型为:Always(默认)、OnFailure 和 Never。

注意:restartPolicy 仅指通过同一节点上的 kubelet 重新启动容器。(重新调度和重启的区别)

策略说明
Always当容器失效时,由kubelet自动重启该容器
OnFailure当容器退出码不为0时,由kubelet自动重启该容器
Neverkubelet永远不会重启该容器

说明

可以管理Pod的控制器有ReplicationController(rc),ReplicaSet(rs),Job,DaemonSet,及kubelet(静态Pod)。

  1. RC、RS和DaemonSet:必须设置为Always,需要保证应用的持续稳定运行;
  2. Job:OnFailure或Never,确保容器执行完后不再重启;
  3. kubelet:根据重启策略重启时,不论RestartPolicy设置为什么值,并且不会对Pod进行健康检查。

3. 健康检查

Pod健康检查分为两种:

  • 存活检查(livenessProbe)

    liveness:检查容器内应用的存活的情况,如果检查失败会杀掉容器进程,是否重启容器则取决于Pod的重启策略

  • 就绪检查(readinessProbe)

    检查容器内的应用是否能够正常对外提供服务,如果探测失败,则Endpoint Controller会将这个Pod的IP从endpoints服务中删除。(用于:容器启动缓慢,需要加载大量数据和配置文件或依赖等待外部服务,而这段时间不能对外提供服务时)

注意:livenessProbereadinessProbe配置参数一样

支持的三种检查方式:

  • httpGet:发送HTTP请求,返回200-400范围状态码为成功。

  • exec:执行Shell命令返回状态码是0为成功。

  • tcpSocket:发起TCP Socket建立成功。

1)exec检查

https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
  • initialDelaySeconds:容器启动后多久进行健康检查(单位:s)

  • periodSeconds:健康检查周期,多长时间进行一次检查(单位:s)

2)httpGet检查
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: liveness # 修改镜像
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
  • initialDelaySeconds:指定了 kubelet 每隔 3 秒执行一次存活探测
  • periodSeconds:告诉 kubelet 在执行第一次探测前应该等待 3 秒

如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。

3)TCP检查
apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: geray/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

TCP 检测的配置和 HTTP 检测非常相似。 下面这个例子同时使用就绪和存活探测器。kubelet 会在容器启动 5 秒后发送第一个就绪探测。 这会尝试连接 goproxy 容器的 8080 端口。 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。

除了就绪探测,这个配置包括了一个存活探测。 kubelet 会在容器启动 15 秒后进行第一次存活探测。 与就绪探测类似,会尝试连接 goproxy 容器的 8080 端口。 如果存活探测失败,这个容器会被重新启动。

4、Pod容器设置环境变量

在我创建Pod的时候,容器内应用程序想要获取Pod信息或者想要获取某些特定的参数变量,我们可以给容器设置相关的环境变量;

环境变量的几种定义方式:

  • 自定义变量
  • 从Pod属性获取
  • 变量值从Secret、ConfigMap获取(参考后续控制器)
1)自定义环境变量
apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
spec:
  containers:
  - name: envar-demo-container
spec:
  containers:
    - name: dependent-envars-demo
      command: ["sh", "-c", "sleep 12h"]
      image: busybox
      env:
        - name: SERVICE_PORT
          value: "80"
        - name: SERVICE_IP
          value: "172.17.0.1"
        - name: UNCHANGED_REFERENCE
          value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
        - name: PROTOCOL
          value: "https"
        - name: SERVICE_ADDRESS
          value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
        - name: ESCAPED_REFERENCE
          value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
# 通过printenv命令测试
kubectl exec envar-demo -- printenv 
2)获取Pod属性
apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sh", "-c"]
      args:
      - sleep 12h
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName

5、初始化容器(init容器)

特点:

  • 应用程序容器之前运行的专用容器
  • 可以包含应用程序映像中不存在的实用程序或设置脚本
  • 一个Pod可以包含一个或多个init容器
  • 使用initContainers字段设置

与普通应用容器的区别:

  • init容器总是运行到完成,先与业务容器启动
  • 每个 init 容器必须在下一个启动之前成功完成;业务容器是并行启动
  • init 容器不支持lifecycle(生命周期), livenessProbe, readinessProbe, 或 startupProbe(启动探测器)(Pod 准备好之前运行完成)
1)init容器的使用
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28.4
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
  • until :和while工作相反,当返回状态码不为0,循环;否则退出循环
  • nslookup:查询DNS记录和域名解析是否正常

创建两个对应的service后Pod正常启动

---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

6、静态Pod

kubelet管理的Pod,例如kubeadm 部署后的etcdAPIServer

kubelet管理静态Pod的资源清单路径:

vi /var/lib/kubelet/config.yaml
...
staticPodPath: /etc/kubernetes/manifests # 静态Pod的存放路径
...

静态Pod特点:

  • Pod由特定节点上的kubelet管理

  • 不能使用控制器

  • Pod名称标识当前节点名称

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值