k8s的进阶--06

Posted 王佐的运维笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s的进阶--06相关的知识,希望对你有一定的参考价值。

今天我们说一下容器,说到容器首先说到容器镜像,在 Kubernetes 的 Pod 中使用容器镜像之前,您必须将其推送到一个镜像仓库(或者使用仓库中已经有的容器镜像)。在 Kubernetes 的 Pod 定义中定义容器时,必须指定容器所使用的镜像,容器中的 image 字段支持与 docker 命令一样的语法,包括私有镜像仓库和标签。上一篇我们说了企业级的私有镜像。

例如:my-registry.example.com:5000/example/web-example:v1.0.1由如下几个部分组成:

my-registry.example.com:5000/example/web-example:v1.0.1

  • 绿色部分:registry 端口

  • 紫色部分:repository 名字

  • 红色部分:image 名字

  • 棕色部分:image 标签


那我们如何进行跟新镜像呢?

Kubernetes中,默认的镜像抓取策略是 IfNotPresent,使用此策略,kubelet在发现本机有镜像的情况下,不会向镜像仓库抓取镜像。如果您期望每次启动 Pod 时,都强制从镜像仓库抓取镜像,可以尝试如下方式:

  • 设置 container 中的 imagePullPolicy 为 Always

  • 省略 imagePullPolicy 字段,并使用 :latest tag 的镜像

  • 省略 imagePullPolicy 字段和镜像的 tag

  • 激活 AlwaysPullImages管理控制器


imagePullPolicy 字段和 image tag的可能取值将影响到 kubelet 如何抓取镜像:

  • imagePullPolicy: IfNotPresent 仅在节点上没有该镜像时,从镜像仓库抓取

  • imagePullPolicy: Always 每次启动 Pod 时,从镜像仓库抓取

  • imagePullPolicy 未填写,镜像 tag 为 :latest 或者未填写,则同 Always 每次启动 Pod 时,从镜像仓库抓取

  • imagePullPolicy 未填写,镜像 tag 已填写但不是 :latest,则同 IfNotPresent 仅在节点上没有该镜像时,从镜像仓库抓取

  • imagePullPolicy: Never,Kubernetes 假设本地存在该镜像,并且不会尝试从镜像仓库抓取镜像

重要
在生产环境部署时,您应该避免使用 :latest tag,如果这样做,您将无法追踪当前正在使用的镜像版本,也无法正确地执行回滚动作如果要 100% 确保所有的容器都使用了同样的镜像版本,可以尝试使用镜像的 digest 例如 sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2。Digest 唯一地标识了容器镜像的版本,并且永远不会改变。容器引擎的镜像缓存机制使得 imagePullPolicy: Always 仍然是高效的。在 Docker 中,如果镜像已经存在,抓取尝试非常快速,先检查镜像所有的 layer 是否有更新,如果该镜像在镜像仓库中所有 layer 的 digest 与本地所有 layer 的 digest 相同,则不会再下载镜像。

使用私有仓库中的docker镜像

在之前我们已经搭建了私有仓库,主要参数如下:

参数名称 参数值 备注
registry地址 my-registry.example.com 推荐使用域名,也可以是 ip 地址
registry端口 5000 必须支持 HTTPS
registry用户名 myusername
registry密码 mypassowrd
repository名字 example
image名字 web-example
image标签 v1.0.1


并且,我们可以在 kubernetes 集群中的任意节点通过如下 docker 命令成功抓取该 docker 镜像

docker login my-registry.example.com:5000# username: 提示 username 时,输入:myusername# password: 提示 password 时,输入:mypassworddocker pull my-registry.example.com:5000/example/web-example:v1.0.1
TIP
您的私有 docker registry 必须支持 HTTPS如果搭建私有的 docker registry,我推荐 Harbor您也可以使用任何其他 docker registry,只要您能够在 kubernetes 集群的任意节点通过上面的 docker pull 命令成功抓取到该 docker registry 中的镜像

容器的环境变量:

Kubernetes为容器提供了一系列重要的资源:

  • 由镜像、一个或多个数据卷合并组成的文件系统

  • 容器自身的信息

  • 集群中其他重要对象的信息


容器的信息

在容器中执行 hostname 命令或者在libc 中执行 gethostname (opens new window)函调用,获得的是容器所在 Pod 的名字。

Pod 的名字,以及 Pod 所在名称空间可以通过 downward API (opens new window)注入到容器的环境变量里。

用户也可以为容器自定义环境变量,后边会说到使用ConfigMap配置应用程序。


集群的信息

在容器创建时,集群中所有的 Service 的连接信息将以环境变量的形式注入到容器中。例如,已创建了一个名为 Foo 的 Service,此时再创建任何容器时,该容器将包含如下环境变量:

FOO_SERVICE_HOST=<Service的ClusterIP>FOO_SERVICE_PORT=<Service的端口>

容器生命周期事件处理

Kubernetes 中支持容器的 postStart 和 preStop 事件,本文阐述了如何向容器添加生命周期事件处理程序(handler)。

  • postStart 容器启动时,Kubernetes 立刻发送 postStart 事件,但不确保对应的 handler 是否能在容器的 EntryPoint 之前执行

  • preStop 容器停止前,Kubernetes 发送 preStop 事件


定义postStart和preStop处理程序

下面的例子中,我们将创建一个包含单一容器的 Pod,并为该容器关联 postStart 和 preStop 处理程序(handler)。Pod 的yaml文件定义如下:

apiVersion: v1kind: Podmetadata: name: lifecycle-demospec: containers: - name: lifecycle-demo-container image: nginx lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] preStop: exec: command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]


创建pod:

kubectl apply -f lifecycle.yaml

验证pod是否正在运行:

kubectl get pod lifecycle-demo

进入容器的命令行终端:

kubectl exec -it lifecycle-demo -- /bin/bash

在命令行终端中,验证 postStart 处理程序创建的 message 文件:

root@lifecycle-demo:/# cat /usr/share/message

输出结果如下所示:

Hello from the postStart handler

总结

Kubernetes 在容器启动后立刻发送 postStart 事件,但是并不能确保 postStart 事件处理程序在容器的 EntryPoint 之前执行。postStart 事件处理程序相对于容器中的进程来说是异步的(同时执行),然而,Kubernetes 在管理容器时,将一直等到 postStart 事件处理程序结束之后,才会将容器的状态标记为 Running。

Kubernetes 在决定关闭容器时,立刻发送 preStop 事件,并且,将一直等到 preStop 事件处理程序结束或者 Pod 的 --grace-period 超时,才删除容器。







以上是关于k8s的进阶--06的主要内容,如果未能解决你的问题,请参考以下文章

Atom编辑器入门到精通 Atom使用进阶

Atom编辑器入门到精通 Atom使用进阶

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

Atom编辑器入门到精通 Atom使用进阶

第二篇:二进制部署K8s集群进阶使用

K8s进阶