Kubernetes(十七)深入理解Pod
- 理解pod
- 基础知识
- pod是kubernetes最基本的执行单元(最小、最简单的单元),pod表示在集群上运行的进程。
- pod封装了应用程序容器(某些情况下多个容器),存储资源、唯一网络IP、以及控制器该如何运行的选项。
- 运行单个容器的pod:一个pod运行一个容器是kubernetes最常见的。
- 运行多个容器的pod:pod可能封装多个紧密耦合且需要共享资源的共处容器组成的应用程序。
- 如果希望横向扩展应用程序,则应该使用多个pod,在kubernetes中,称为副本。
- pod是短暂的。
- 网络
- 每个pod分配一个唯一的IP地址,pod的每个容器共享网络命名空间。包括IP地址和端口。pod内的容器可以使用localhsot相互通信。
- 存储
- 一个pod可以指定一组共享存储卷。pod中所有的容器都可以访问共享卷,允许这些容器共享数据。卷数据可以持久化
- pod的分类
- Infrastructure Container 基础容器
- 在node节点:cat /opt/kubernetes/cfg/kubelet.kubeconfig 可以看到指定的容器,每创建一个pod都会创建一个,和pod一一对应。
- 在node节点:通过 docker ps 会看到name为*/pause-amd64:3.0的就是了。
- 负责维护pod的网络空间。
- 该容器对用户无感知,由后台自动完成。
- InitContainers 初始化容器
- 在pod启动时,在主容器启动前执行初始化工作。
- 参考简书 https://www.jianshu.com/p/2f3736deb16f
- 参考官网 https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/
- containers 业务容器
- 我们主要使用的容器
- Infrastructure Container 基础容器
- pod的意义
- 解决一个docker容器只运行一个程序的限制;pod是多进程模型,可以运行多个应用程序,每个程序由容器来管理。
- 某些亲密性应用场景是需要多个容器一起运行的;例如:频繁交互数据的两个应用,通过localhost相互访问可以提供性能,防止出现跨节点、跨网络的通信。
- pod实现机制
- 3
- 镜像拉取策略
- IfNotPresent 默认值,镜像在宿主机上不存在时才拉取
- Always 每次创建pod都拉取镜像
- Never pod永远不会主动拉取镜像
- 示例:使用Always方式拉取一个私有的镜像
- 官方链接 https://kubernetes.io/zh/docs/tasks/configure-pod-container/pull-image-private-registry/
- 生成secret有2种方式:
- 一、使用docker登录的凭证来生成
- 1.先登录镜像仓库 docker login -u *** -p *** https://registry.cn-shanghai.aliyuncs.com
- 2.查看docker登录的凭证 cat .docker/config.json
- 3.将凭证base64位编码 cat .docker/config.json |base64 -w 0
- 4.生成token成功,将token保存到yaml模板即可;
- 二、使用kubectl来生成(在集群中创建保存授权令牌的secret)
- 1.创建 kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
- 2. 查看 kubectl get secret regcred --output=yaml
- 创建一个使用secret的pod
我们取名叫
useridentity-deployment.yaml- 执行 kubectl create -f useridentity-deployment.yaml
- 如果镜像拉取失败,查看详细信息 kubectl describe pods useridentity
- 基本的创建pod和service的yaml示例
- pod资源限制
- 官方链接 https://kubernetes.io/zh/docs/concepts/configuration/manage-compute-resources-container/
- 当您定义pod的时候,可以选择未每个容器指定需要的CPU和内存大小。当为容器指定了资源请求后,调度器就能更好的判断将容器调度到哪个节点上。
- 资源类型
- cpu和内存都是资源类型,cpu单位是核心数,内存单位是字节
- pod和容器的资源请求和限制
- pod中的每个容器都可以指定以下一个或者多个值
- spec.containers[].resources.limits.cpu
- spec.containers[].resources.limits.memory
- spec.containers[].resource.requests.cpu
- spec.containers[].resource.requests.memory
- pod中的每个容器都可以指定以下一个或者多个值
- cpu的含义
- 0.1cpu=100m;0.1的cpu在双核,多核机器中的意义是一样的。
- 内存的含义
- 内存的限制和请求以字节为单位。常见单位 Ei,Pi,Ti,Gi,Mi,Ki。
- 具有资源请求的pod如何调度
- 当你创建一个pod时,kubernetes调度程序将为pod选择一个节点。每个节点具有每种资源类型的最大容量,调度程序确保对每种资源类型,调度的容器的资源请求综合人小于节点的容量。
- 具有资源限制的pod如何运行
- 当kubectl启动一个容器时,它会将cpu和内存限制传递到容器运行时 。
- spec.containers[].resource.request.cpu 作用于docker run 命令中的--cpu-shares
- spec.containers[].resource.limits.cpu 作用于docker run 命令中的--cpu-quota
- spec.containers[].resource.limits.memory 作用于 docker run 命令中的--memory
- 当kubectl启动一个容器时,它会将cpu和内存限制传递到容器运行时 。
- 监控计算资源的使用
- 如果为集群配置了可选监控,则可以从监控系统检索pod资源使用情况
- 疑难解答
- pod状态为pending,并且时间信息显示failedScheduling
- 如果调度器找不到任何可以匹配的节点,则该pod将保持不可调度状态,直到找到一个可以被调度的位置。
- pod事件查看 kubectl describe pod nginx | grep -A 3 Events
- 查看pod资源限制利用率 kubectl describe nodes k8s-node1
- 容器意外终止
- 容器终止了要查看是否是因为资源限制被杀死,要查看容器详情
- 查看详情 kubectl describe pod nginx
- 查看容器终止前后状态对比 kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' nginx-59d795d786-czfj4
- 含资源限制的yaml示例文件
- pod状态为pending,并且时间信息显示failedScheduling
- pod重启策略(restartPolicy)
- 官方链接 https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/#%e9%87%8d%e5%90%af%e7%ad%96%e7%95%a5
- 重启的三种策略
- Always 当容器终止退出后,总是重启(默认)
- OnFailure 当容器异常退出(退出状态码非0),才重启容器
- Never 当容器终止退出,从不重启容器
- spec.restartPolicy
- restartPolicy: Always
- 含重启策略yaml示例文件
pod健康检查(Probe)
- 官方链接 https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
- probe探测器类型
- kubectl使用存活探测器(livenessProbe)来知道要什么时候来重启容器。
- 如果检查失败,将容器杀死,使用restartPolicy策略来操作容器
- kubectl使用就绪探测器(readinessProbe)来知道容器什么时候准备好了可以接受流量请求。
- 如果检查失败,kubernetes会把pod从service 负载均衡器中移除
- kubectl使用启动探测器(
startupProbe
)就可以知道应用程序什么时候启动了。- 可以控制容器在启动成功后进行活性和就绪检查,确保存活和就绪探测器不会影响程序的启动。
- kubectl使用存活探测器(livenessProbe)来知道要什么时候来重启容器。
- probe探测器支持3种检测方法
- exec 执行shell命令,返回状态码0表示成功
- httpGet 发送http请求,返回200-400为成功
- tcpScoket 发送tcp Socket建立成功
- 探测器配置
- initialDelaySeconds:容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认0秒;
- periodSeconds:执行探测器的时间间隔,默认是10秒;
- timeoutSeconds:探测的超时后等待多少秒。默认值是1,最小值是1;
- sucsessThreshold:探测器失败后,被视为成功的最小连续成功数。默认值1.存活探测器必须是1.最小值是1;
- failureThreshold:当pod启动了并探测到失败,kubernetes重试次数,默认值3,最小值1;
- http探测器可以在httpGet上配置额外的字段
- host:链接使用的主机名,默认是pod的IP
- scheme:链接方式,http\https
- path:访问http的路径
- httpHeaders:请求证自定义的http头
- port:访问容器的端口号和端口名,必须在1-65535之间
pod调度约束
- 官方链接 https://kubernetes.io/zh/docs/concepts/configuration/assign-pod-node/
- 当我们集群里面运行多个项目时候,可能就会使用到node划分;虽然kunernetes默认的分配基本上满足需求了;
- NodeName 进行节点约束
-
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx nodeName: kube-01
-
- NodeSelector 通过lable进行节点约束
-
apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: disktype: ssd
-
pod故障排查
- pod状态
- pending :Pod创建已经提交到了kubernetes,但是因为某种原因不能顺利创建,例如镜像比较慢,调度节点不成功。
- running :Pod已经绑定到一个节点,并且已经创建了所有容器。至少有一个容器运行中 ,或正在启动或重新启动。
- succeded:pod中所有容器都已经终止,不会重新启动。
- failed:Pod的所有容器均已经终止,至少有一个容器在故障终止,也就是说要么容器以非0状态退出,要么被系统终止。
- Unkown:由于某种原因apiserver无法获得Pod状态,通过是由于master与pod所在主机kubelet通信时出错。
- 常用查看异常命令
- kubectl logs type/name #查看容器日志
- kuberctl describe type/name #查看容器详细描述
- kubectl exec -it name bash #进入容器内部查看