旅游网站制作视频百度云,建设网站多少钱 2017,做视频赚钱的国外网站,如何寻找一批做网站的公司文章目录容器镜像镜像名称镜像拉取策略私有仓库的拉取策略容器的环境变量和启动命令容器的环境变量容器的启动命令容器的生命周期钩子postStartpreStop容器的探针startupProbelivenessProbereadinessProbek8s 集群中最小的管理单元就是一个Pod#xff0c;而Pod里面才是容器而Pod里面才是容器但是容器里面到底应该怎么写yaml呢这个就是我今天学习的目标 一个最简单的Pod资源清单类似于以下这种
##pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-demoimage: nginx我们通过kubectl explain pod.spec.containers解释了容器到底里面能写什么忒多了
[rootk8s-01 k8s-yaml]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1RESOURCE: containers []ObjectDESCRIPTION:List of containers belonging to the pod. Containers cannot currently beadded or removed. There must be at least one container in a Pod. Cannot beupdated.A single application container that you want to run within a pod.FIELDS:args []stringArguments to the entrypoint. The docker images CMD is used if this is notprovided. Variable references $(VAR_NAME) are expanded using thecontainers environment. If a variable cannot be resolved, the reference inthe input string will be unchanged. The $(VAR_NAME) syntax can be escapedwith a double $$, ie: $$(VAR_NAME). Escaped references will never beexpanded, regardless of whether the variable exists or not. Cannot beupdated. More info:https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
...容器镜像
镜像名称
kubectl explain pod.spec.containers中的【image 】解释了有关镜像名称的含义和写法 Docker image 的镜像名称string 数据类型
##所以在写yaml文件的时候就应该以这种形式来确认你这个容器启动用的镜像
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-demoimage: nginx#image: nginx:1.21-alpine#image: tomcat:latest镜像拉取策略
kubectl explain pod.spec.containers中的【imagePullPolicy】解释的就是镜像拉取策略
kubectl explain pod.spec.containers.imagePullPolicy拉取策略 Always每当 kubelet 启动一个容器时kubelet 会查询容器的镜像仓库 将名称解析为一个镜像摘要。 如果 kubelet 有一个容器镜像并且对应的摘要已在本地缓存kubelet 就会使用其缓存的镜像 否则kubelet 就会使用解析后的摘要拉取镜像并使用该镜像来启动容器。这也是默认拉取策略NeverKubelet 不会尝试获取镜像。如果镜像已经以某种方式存在本地 kubelet 会尝试启动容器否则会启动失败。IfNotPresent只有当镜像在本地不存在时才会拉取。
##所以在写yaml文件的时候就应该以这种形式来确认要启动容器的镜像的来源
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-demoimage: nginximagePullPolicy: Always ## 默认拉取策略总是去下载举个栗子
我有下面这个pod文件我尝试启动一下试试
#####pod-test1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-demoimage: wordpressimagePullPolicy: Never私有仓库的拉取策略
如果我们需要从自己的阿里云私人镜像仓库拉取镜像又应该如何操作呢看一下官方帮助文档kubectl explain pod.spec中的【imagePullSecrets []Object】 官方地址 https://kubernetes.io/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod 官方是这样说的 要创建一个Secret 然后在 Pod 中引用 ImagePullSecrets
举个栗子
我要拉取我自己阿里云镜像仓库的镜像
我需要先创建一个Secret这个怎么创建呢官方是这样说的
kubectl create secret docker-registry name \--docker-serverDOCKER_REGISTRY_SERVER \--docker-usernameDOCKER_USER \--docker-passwordDOCKER_PASSWORD \--docker-emailDOCKER_EMAIL我就创建一个试试
kubectl create secret docker-registry test \--docker-serverregistry.cn-hangzhou.aliyuncs.com \--docker-usernametb330504_33 \--docker-passwordxxxxxxxx \--docker-email565616251qq.com我在准备一个Pod文件
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:imagePullSecrets:- name: testcontainers:- name: pod-demoimage: registry.cn-hangzhou.aliyuncs.com/publiclibrary/tomcat:8.5-jdk11-temurin-focalimagePullPolicy: IfNotPresent运行一下看是否能拉取后正常运行
正在拉取镜像 拉取成功运行成功 容器的环境变量和启动命令
容器的环境变量
kubectl explain pod.spec.containers.env 按照官方描述有关容器的环境变量就应该这样写了
####以mysql镜像为例
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-mysql-demoimage: mysqlimagePullPolicy: Alwaysenv:- name: MYSQL_DATABASEvalue: my-test- name: MYSQL_ROOT_PASSWORDvalue: admin123尝试并验证一下OK 容器的启动命令
kubectl explain pod.spec.containers.command https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell 尝试一下覆盖容器默认的启动命令
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels:app: MYAPP
spec:containers:- name: pod-demoimage: nginxcommand:- /bin/sh- -c- echo hello world;sleep 3600;可以看到如果设置了command字段信息就会覆盖默认的容器启动命令对于这个官方有明确的说明 如果在配置文件中设置了容器启动时要执行的命令及其参数那么容器镜像中自带的命令与参数将会被覆盖而不再执行。如果配置文件中只是设置了参数却没有设置其对应的命令那么容器镜像中自带的命令会使用该新参数作为其执行时的参数。 从最新的文档发现有些内容有所出入
容器的生命周期钩子 https://kubernetes.io/zh-cn/docs/concepts/containers/container-lifecycle-hooks/#container-hooks kubectl explain pod.spec.containers.lifecycle kubectl explain pod.spec.containers.lifecycle.postStart kubectl explain pod.spec.containers.lifecycle.preStop k8s 中提供了二个关于容器的生命周期钩子 postStart 在容器创建后将立刻执行。但是并不能保证该钩子函数在容器的 ENTRYPOINT 之前 执行。该钩子函数没有输入参数。 preStop 在容器被 terminate终止之前执行 postStart
k8s 在容器启动后立刻发送postStart事件但是并不能确保postStart事件处理程序在容器的EntryPoint之前执行意思就是容器启动了就会触发不管容器执行是否成功在 k8s 管理容器的时候将一直等待 postStart事件处理程序结束后才会将容器的状态标记为Running
exec容器创建以后钩子函数执行一个命令httpGet容器创建以后钩子函数发送一个http的get请求tcpSocket容器创建以后钩子函数连上一个TCP端口
我们以httpGet为例
我们先启动一个 nginx pod
##pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-demolabels: app: MYAPP
spec:containers:- name: pod-demoimage: nginx我们在准备一个示例yaml
##lifecycle-demo.yaml
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demolabels: app: MYAPP
spec:containers:- name: lifecycle-demoimage: nginxlifecycle:postStart:httpGet:host: 192.168.0.190path: /lifecycle-testport: 80scheme: HTTP ####注意这个地方是大写启动一下 查看一下钩子的设置是否生效
是有相关请求证明是生效的 preStop
钩子函数在容器被terminate之前执行执行是同步的执行完才删除容器写法也是和postStart一样
##lifecycle-demo.yaml
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demolabels: app: MYAPP
spec:containers:- name: lifecycle-demoimage: nginxlifecycle:preStop:httpGet:host: 192.168.0.190path: /lifecycle-testport: 80scheme: HTTP ####注意这个地方是大写我们先启动一个这样的 pod 我将这个pod杀死
kubectl delete -f lifecycle-demo.yaml看下是否生效 容器的探针
健康检查机制 probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断kubelet 既可以在容器内执行代码也可以发出一个网络请求。 startupProbe启动探针 指示容器中的应用是否已经启动。如果提供了启动探针则所有其他探针都会被禁用直到此探针成功为止。如果启动探测失败kubelet 将杀死容器 而容器依其重启策略进行重启。 如果容器没有提供启动探测则默认状态为 Success。 livenessProbe存活探针 指示容器是否正在运行。如果存活态探测失败则 kubelet 会杀死容器 并且容器将根据其重启策略决定未来。如果容器不提供存活探针 则默认状态为 Success。 readinessProbe就绪探针 指示容器是否准备好为请求提供服务。如果就绪态探测失败 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针则默认状态为 Success。 写法是一致的 kubectl explain pod.spec.containers.startupProbe initialDelaySeconds容器启动后要等待多少秒后才启动启动、存活和就绪探针 默认是 0 秒最小值是 0。 periodSeconds执行探测的时间间隔单位是秒。默认是 10 秒。最小值是 1。 timeoutSeconds探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。 successThreshold探针在失败后被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。 failureThreshold探针连续失败了 failureThreshold 次之后 Kubernetes 认为总体上检查已失败容器状态未就绪、不健康、不活跃。 对于启动探针或存活探针而言如果至少有 failureThreshold 个探针已失败 Kubernetes 会将容器视为不健康并为这个特定的容器触发重启操作。 kubelet 会考虑该容器的 terminationGracePeriodSeconds 设置。 对于失败的就绪探针kubelet 继续运行检查失败的容器并继续运行更多探针 因为检查失败kubelet 将 Pod 的 Ready 状况设置为 false。 terminationGracePeriodSeconds为 kubelet 配置从为失败的容器触发终止操作到强制容器运行时停止该容器之前等待的宽限时长。 默认值是继承 Pod 级别的 terminationGracePeriodSeconds 值如果不设置则为 30 秒最小值为 1。 检查机制 exec 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功 httpGet 对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400则诊断被认为是成功的 tcpSocket 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开则诊断被认为是成功的。 如果远程系统容器在打开连接后立即将其关闭这算作是健康的 探测结果 Success成功 容器通过了诊断。Failure失败 容器未通过诊断。Unknown未知 诊断失败因此不会采取任何行动。
startupProbe
我先启动了一个 pod-demo 的容器 我现在准备一个另一个 pod
apiVersion: v1
kind: Pod
metadata:name: probe-demolabels: app: MYAPP
spec:containers:- name: probe-demoimage: nginxstartupProbe:httpGet:host: 192.168.0.190path: /index2.htmlport: 80scheme: HTTP ####注意这个地方是大写initialDelaySeconds: 60failureThreshold: 3periodSeconds: 10我们启动验证一下
最开始肯定是失败的因为探针设置的路径不存在的所以pod的状态也是未就绪的 我们对pod-demo中的文件进行一个操作让测试pod可以探针成功 livenessProbe
我们还是以上面的为例准备一个测试 yaml
###每个1秒就去检查特定服务器的服务是否正常访问
apiVersion: v1
kind: Pod
metadata:name: probe-demolabels: app: MYAPP
spec:containers:- name: probe-demoimage: nginxlivenessProbe:httpGet:host: 192.168.0.190path: /index.htmlport: 80scheme: HTTP ####注意这个地方是大写initialDelaySeconds: 60failureThreshold: 3periodSeconds: 1查看一下各状态 我们删除探针里面需要用到的pod再看下状态 看下探针的事件检查失败就会一直重启 但是我不知道为啥pod还是处于READY的状态
readinessProbe
就绪探针理论是和上面一样的 有时候应用会暂时性地无法为请求提供服务。 例如应用在启动时可能需要加载大量的数据或配置文件或是启动后要依赖等待外部服务。 在这种情况下既不想杀死应用也不想给它发送请求。 Kubernetes 提供了就绪探针来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息并且不接受通过 Kubernetes Service 的流量。 后续实际应用中我再来探一下更多的用法场景