关注公众号 风色年代(itfantasycc) 300G微服务资料等你拿!

Kubernetes容器上下文环境

  下面我们将主要介绍运行在Kubernetes集群中的容器所能够感知到的上下文环境,以及容器是如何获知这些信息的。

  首先,Kubernetes提供了一个能够让容器感知到集群中正在发生的事情的方法:环境变量。作为容器环境组成的一部分,这些集群信息对于容器构建“集群环境感知”起着非常重要的作用。其次,Kubernetes容器环境还包括一系列与容器生命周期相关的容器钩子,其对应的回调函数hook handler可以作为单个容器可选定义项的一部分。这个容器钩子与操作系统传统进程模型的通知回调机制有些类似。其实,还有一个与容器环境相关的重要部分是容器可用的文件系统。通过前面的讨论可知,在Kubernetes中,容器的文件系统由一个容器镜像和若干个Volume组成。

  下面我们将着重讨论暴露给容器的集群信息和用于向容器发布对其生命周期管理信息的容器钩子这两种同容器上下文环境协作的方法。

1、集群环境感知

  运行在Kubernetes集群中的一个容器在容器内部能够感知两种类型的环境变量信息,一种是与容器自身相关的信息,另一种是集群的信息。

1.1容器自身信息

  容器能够感知到的与容器自身相关的信息包括运行该容器的pod的名字、pod所在的namespace、在pod资源配置文件中env字段定义的键/值对,等等。其中,pod的名字被设置成容器的的主机名,而且可以在容器内通过所有访问主机名的方式获得,例如,hostname命令或JAVA中InetAddress.getLocalHost()函数调用。pod的名字和namespace还可以通过downwardAPI进行访问。对容器而言,用户在pod资源配置文件中自定义的环境变量的可访问性与在Docker镜像中指定的环境变量是一样的。downwardAPI示例如下:

[root@k8s-master downwardapi]# cat test-downwardapi.yaml
apiVersion: v1
kind: Pod
metadata:name: test-downwardaoi-volumelabels:name: test-downwardaoi-volumezone: us-eastcluster: test-cluster1annotations:build: twobuilder: zhenyuyaodidiao
spec:containers:- name: test-hostpathimage: registry:5000/back_demon:1.0volumeMounts:- name: podinfomountPath: /home/laizy/podinforeadOnly: falsecommand:- /run.shvolumes:- name: podinfodownwardAPI:items:- path: "pod_name"fieldRef:fieldPath: metadata.name- path: "pod_namespace"fieldRef:fieldPath: metadata.namespace- path: "pod_labels"fieldRef:fieldPath: metadata.labels- path: "pod_annotations"fieldRef:fieldPath: metadata.annotations[root@k8s-master downwardapi]# kubectl create -f test-downwardapi.yaml
pod "test-downwardaoi-volume" created[root@k8s-master downwardapi]# kubectl exec -ti test-downwardaoi-volume /bin/bash
[root@test-downwardaoi-volume /]# cd /home/laizy/podinfo/
[root@test-downwardaoi-volume podinfo]# ls
pod_annotations  pod_labels  pod_name  pod_namespace
[root@test-downwardaoi-volume podinfo]# cat pod_annotations
build="two"
builder="zhenyuyaodidiao"
kubernetes.io/config.seen="2017-03-22T09:42:11.832955302+08:00"
kubernetes.io/config.source="api"
[root@test-downwardaoi-volume podinfo]# cat pod_labels
cluster="test-cluster1"
name="test-downwardaoi-volume"
zone="us-east"
[root@test-downwardaoi-volume podinfo]# cat pod_name
test-downwardaoi-volume
[root@test-downwardaoi-volume podinfo]# cat pod_name
test-downwardaoi-volume
[root@test-downwardaoi-volume podinfo]# cat pod_namespace
default
[root@test-downwardaoi-volume podinfo]# exit
exit

1.2集群信息

  我们在前面已经讨论过Kubernetes服务发现的两种机制:DNS和环境变量。service环境变量属于集群信息,在容器创建时由Kubemetes集群API注人,在容器内以环境变量或域名的方式被访问。

2.容器钩子

  容器钩子是Kubemetes针对容器生命周期管理引入的事件处理机制,它负责监听Kubemetes对容器生命周期的管理信息,并将这些信息以广播的形式通知给容器。然后执行相应的回调函数。

2.1容器钩子类型

  Kubemetes支持两种类型的容器钩子,分别为PostStart和PreStop。

  PostStart。该钩子在容器被创建后立刻触发,通知容器它已经被创建。该钩子不需要向其所对应的hook handler传人任何参数。如果该钩子对应的hook handler执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器。

  PreStop。该钩子在容器被删除前触发,其所对应的hook handler必须在删除该容器的请求发送给Docker daemon之前完成。在该钩子对应的hook handler完成后不论执行的结果如何,Docker daemon会发送一个SGTERN信号量给Docker daemon来删除该容器。同样地。该钩子也不需要传人任何参数

2.2hook handler执行

  当一个容器管理hook发生时,管理系统将会在容器中调用注册的hook handler。其中hook handler通过在包含该容器的pod资源配置文件的Lifecycle字段中定义来完成注册。注意,当hook handler在执行时,其他对该容器所在pod的管理动作将被阻塞除非该容器异常退出。而如果你自定义的hook handler阻塞时,其他对pod的管理操作包括容器健康检查将不会发生,直到hook handler继续执行完毕。因此,一般建议用户自定义的hook handler代码尽可能地轻量化,尽管确实有一些场景的hook handler需要长时间运行(例如在容器时退出保存运行状态等)。

2.3hook handler的执行方式

  hook handler是hook在容器内执行的回调函数,也即hook暴露给容器的方式。Kubemetes支持两种不同的hook handler类型,分别是Exec和HTTPGet。

    Exec。在容器的cgroup和namespace内启动一个新进程来执行指定的命令,由该命令消耗的资源全部要计人容器的消耗。正如在之前容器健康检查中提到的,如果Exec执行的命令最后在标准输出stdout的结果为0k,就代表handler执行成功,否则就被认为执行异常,并且Kuberlet将强制重新启动该容器。

    HTTPGet。向容器的指定接口发起一个HTTP请求作为handler的具体执行内容,并通过返回的HTTP状态码来判断该请求执行是否成功。

  综上,hook机制为用户提供了一种能够根据容器生命周期及其上下文的变化来触发不同操作的协作方法。这对于很多需要精细控制容器的场景是非常有用的,比如在容器结束前执行一些清理工作来保证其“优雅”退出。以下给出hook执行exec的示例:

[root@k8s-master hook]# cat test-lifecycle-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:labels:name: test-lifecycle-hostpathrole: mastername: test-lifecycle-hostpath
spec:containers:- name: test-lifecycle-hostpathimage: registry:5000/back_demon:1.0lifecycle:postStart:exec:command:- "touch"- "/home/laizy/test/hostpath/post-start"preStop:exec:command:- "touch"- "/home/laizy/test/hostpath/pre-stop"volumeMounts:- name: testhostmountPath: /home/laizy/test/hostpathreadOnly: falsecommand:- /run.shvolumes:- name: testhosthostPath:path: /home/testhost
[root@k8s-master hook]# date
2017年 03月 22日 星期三 10:21:58 CST
[root@k8s-master hook]# kubectl create -f test-lifecycle-hostpath.yaml
pod "test-lifecycle-hostpath" created
[root@k8s-master hook]# kubectl get pod -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP          NODE
test-lifecycle-hostpath             1/1       Running   0          13s       10.0.9.3    k8s-node-3
[root@k8s-master hook]# date
2017年 03月 22日 星期三 10:22:52 CST
[root@k8s-master hook]# kubectl delete pod test-lifecycle-hostpath
pod "test-lifecycle-hostpath" deleted

在node3上查看外挂出来的路径上,生成了两个文件,post-start文件是在pod创建之后生成的;pre-stop文件是在pod删除之前生成的。

[root@k8s-node-3 ~]# ll /home/testhost/
总用量 0
-rw-r--r--. 1 root root 0 3月  22 10:22 post-start
-rw-r--r--. 1 root root 0 3月  22 10:23 pre-stop
[root@k8s-node-3 ~]#

对应的httpGet示例简单示意如下:

containers:- name: lifecycleimage: busyboxlifecycle:postStart:exec:command:- "touch"- "/var/log/lifecycle/post-start"preStop:httpGet:path: "/abort"port: 8080

kubernetes 容器内获取Pod信息(包括:宿主主机IP)

kubernetes 容器内获取Pod信息(包括:宿主主机IP)_kozazyh的专栏-CSDN博客_k8s获取pod信息

kubernetes 自从1.7开始,可以在pod 的container 内获取pod的spec,metadata 等信息。

具体方法可以通过env获取:

      env:- name: MY_NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName- name: MY_POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: MY_POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: MY_POD_SERVICE_ACCOUNTvalueFrom:fieldRef:fieldPath: spec.serviceAccountName

spec.nodeName : pod所在节点的IP、宿主主机IP

status.podIP :pod IP

metadata.namespace : pod 所在的namespace

更多参数:https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/

https://github.com/kubernetes/kubernetes/issues/24657

kubernetes 通过环境变量暴露POD的信息给容器

kubernetes 通过环境变量暴露POD的信息给容器_纵横四海的博客-CSDN博客

有时候,容器需要获取pod的信息时,就可以通过设置环境保护来实现 
例子 
1.使用POD 的字段的值作为环境变量的值

apiVersion: v1
kind: Pod
metadata:name: dapi-envars-fieldref
spec:containers:- name: test-containerimage: k8s.gcr.io/busyboxcommand: [ "sh", "-c"]args:- while true; doecho -en '\n';printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;//对应下面的环境变量的值printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;sleep 10;done;env:- name: MY_NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName- name: MY_POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: MY_POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: MY_POD_SERVICE_ACCOUNTvalueFrom:fieldRef:fieldPath: spec.serviceAccountNamerestartPolicy: Never

2.使用容器的字段的值作为环境变量的值 
例子

apiVersion: v1
kind: Pod
metadata:name: dapi-envars-resourcefieldref
spec:containers:- name: test-containerimage: k8s.gcr.io/busybox:1.24command: [ "sh", "-c"]args:- while true; doecho -en '\n';printenv MY_CPU_REQUEST MY_CPU_LIMIT;printenv MY_MEM_REQUEST MY_MEM_LIMIT;sleep 10;done;resources:requests:memory: "32Mi"cpu: "125m"limits:memory: "64Mi"cpu: "250m"env:- name: MY_CPU_REQUESTvalueFrom:resourceFieldRef:containerName: test-containerresource: requests.cpu- name: MY_CPU_LIMITvalueFrom:resourceFieldRef:containerName: test-containerresource: limits.cpu- name: MY_MEM_REQUESTvalueFrom:resourceFieldRef:containerName: test-containerresource: requests.memory- name: MY_MEM_LIMITvalueFrom:resourceFieldRef:containerName: test-containerresource: limits.memoryrestartPolicy: Never

参考: 
environment-variable-expose-pod-information

Kubernetes 配置Pod和容器(十五) 通过环境变量公开Pod信息到容器

Kubernetes 配置Pod和容器(十五) 通过环境变量公开Pod信息到容器 - 简书

这个章节展示了如何使用环境变量公开pod的信息到它自己运行的容器里面。环境变量可以公开Pod字段和容器字段。

有两种方式用来公开Pod和容器字段给运行的容器:环境变量和DownwardAPIVolumeFiles。

使用Pod字段作为环境变量的值

在本次实验,创建包含一个容器的Pod。下面是这个Pod的配置文件:

apiVersion: v1
kind: Pod
metadata:name: dapi-envars-fieldref
spec:containers:- name: test-containerimage: gcr.io/google_containers/busyboxcommand: [ "sh", "-c"]args:- while true; doecho -en '\n';printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;sleep 10;done;env:- name: MY_NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName- name: MY_POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: MY_POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: MY_POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: MY_POD_SERVICE_ACCOUNTvalueFrom:fieldRef:fieldPath: spec.serviceAccountNamerestartPolicy: Never

在这个配置文件,可以看到五个环境变量。env字段是个数组。数组里面的第一个元素指定了MY_NODE_NAME环境变量,它的值是从Pod的spec.nodeName里面获取的。类似的其他的环境变量获取pod的字段名称。

注意:这些例子里面的字段是pod的字段。不是运行在pod里面的容器的字段。

创建pod:

kubectl create -f test.yaml

验证运行在pod里面的容器:

kubectl get pods

查看容器的日志:

kubectl logs dapi-envars-fieldref

输出展示了选择的环境变量的值:

minikube
dapi-envars-fieldref
default
172.17.0.4
default

为何在日志里面是这些值,可以看配置文件的command和args。当容器启动的时候,把这个五个环境变量的值写入的标准输出里面。每十秒钟重复一次。

下一步,通过shell进入Pod运行的容器里面:

kubectl exec -it dapi-envars-fieldref -- sh

在shell里面,查看环境变量:

/# printenv

输出展示了确定已经把pod字段的值分配给环境变量:

MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref

使用容器字段作为环境变量的值

在上面的实验,使用pod字段作为环境变量的值。在下一个实验,可以使用容器字段作为环境变量的值。下面是Pod的配置文件:

apiVersion: v1
kind: Pod
metadata:name: dapi-envars-resourcefieldref
spec:containers:- name: test-containerimage: gcr.io/google_containers/busybox:1.24command: [ "sh", "-c"]args:- while true; doecho -en '\n';printenv MY_CPU_REQUEST MY_CPU_LIMIT;printenv MY_MEM_REQUEST MY_MEM_LIMIT;sleep 10;done;resources:requests:memory: "32Mi"cpu: "125m"limits:memory: "64Mi"cpu: "250m"env:- name: MY_CPU_REQUESTvalueFrom:resourceFieldRef:containerName: test-containerresource: requests.cpu- name: MY_CPU_LIMITvalueFrom:resourceFieldRef:containerName: test-containerresource: limits.cpu- name: MY_MEM_REQUESTvalueFrom:resourceFieldRef:containerName: test-containerresource: requests.memory- name: MY_MEM_LIMITvalueFrom:resourceFieldRef:containerName: test-containerresource: limits.memoryrestartPolicy: Never

在配置文件里面,可以看到四个环境变量。env字段是一个数组。数组的第一个元素指定了MY_CPU_REQUEST环境变量的值通过名字为test-container容器的request.cpu字段获取。类似的其他的环境变量通过他们对应的容器字段获取相应的值。

创建Pod:

kubectl create -f test.yaml

验证Pod里面的容器已经运行:

kubectl get pods

查看容器日志:

kubectl logs dapi-envars-resourcefieldref

输出展示了选择的环境变量的值:

关注公众号 风色年代(itfantasycc) 300G微服务资料等你拿!

1
1
33554432
67108864

获取Kubernetes容器上下文环境相关推荐

  1. Kubernetes容器上下文环境

    目录贴:Kubernetes学习系列 下面我们将主要介绍运行在Kubernetes集群中的容器所能够感知到的上下文环境,以及容器是如何获知这些信息的. 首先,Kubernetes提供了一个能够让容器感 ...

  2. 解决在非spring上下文的环境中无法获取Spring容器的bean【nullpointer:connot invoke because xxx is null问题】

    文章目录 1.背景: 2.原代码: 非spring环境中获取bean 1.背景: 项目在nio监听端口的事件中需要在接收到客户端数据以后把数据封装然后调用service层间接访问数据库插入数据,调试了 ...

  3. 轻量级Kubernetes之k3s:2:使用docker作为容器运行环境

    缺省安装的k3s使用的是containerd作为容器运行环境,如果希望使用Docker作为容器运行环境,只需要在安装时通过环境变量INSTALL_K3S_EXEC指定--docker即可.这篇文章具体 ...

  4. Spring Boot中普通类获取Spring容器中的Bean

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,自己动手n ...

  5. Spring Cloud Kubernetes容器化实践

    随着公司业务量和产品线的增加,项目越来越多,普通运维系统架构对整个软件研发生命周期的管理越来越难,效率低下,难以统一管理.近年来Docker统一了容器标准,对于软件开发流程产生了深远的影响,Docke ...

  6. 开课吧课堂:Kubernetes集群环境常见问题解决

    本文主要分享了k8s集群环境下,镜像不能自动拉取.容器执行错误.镜像导入导出.集群崩溃常见问题解决. 1.Kubernetes集群环境下各个node镜像不能自动拉取 一般情况下遇到这种情况下,比较笨的 ...

  7. Kubeadm介绍与使用Kubeadm搭建kubernetes集群环境

    文章目录 1.Kubeadm介绍 2.使用Kubeamd搭建kubernetes集群环境 2.1.首先准备一个三台的centos机器 2.2.yum -y update [在三台机器上执行更新包] 2 ...

  8. kubernetes集群环境搭建(kubeadm方式)

    1. kubernetes简介 kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本,于2014年9月发布第一个版本,2 ...

  9. SpringUtil获取Spring容器对象

    **自己公司使用的简单的SpringUtil,可以使用直接从Spring容器中获取对象.比较方便. 主要就是实现ApplicationContextAware ,学过Spring的都知道,Spring ...

最新文章

  1. 深度学习(4)基础4 -- 神经网络架构激活函数过拟合处理
  2. iOS 查询数组中的对象
  3. 慢动作输出Linux命令结果并用彩色显示
  4. WPF之命名空间和资源
  5. 挖矿病毒解决实例(隐藏进程,文章较好)(入侵)
  6. 关于CSS预处理器(less,sass)
  7. 1199: [HNOI2005]汤姆的游戏 - BZOJ
  8. 2010年“最具全球竞争力中国公司20强”榜单:
  9. 揭秘!女程序员为啥更赚钱?这4个大招,用Python做副业躺赚
  10. php excel 高度,PHPExcel,自动调整行高
  11. JavaScript操作canvas制作前端H5小游戏——Flappy Bird
  12. 多多成稿作品网www.no1paper.cn测评
  13. 如何设置本电脑中的mysql让别人的电脑连接
  14. Golang蓝湖一面
  15. 西湖大学自然语言处理(七)—— 解决OOV问题的两种平滑技术
  16. 如何发布一个本地网站
  17. Java加密与解密笔记(四) 高级应用
  18. window正版验证的秘密
  19. 《激励-理论篇》课程笔记
  20. zotero 设置 双击打开pdf 外边

热门文章

  1. SpringBoot:Mybatis + Druid 数据访问
  2. 797. 差分(有图解)
  3. Angular使用ng build打包报错 Property 'setControl' does not exist on type 'AbstractControl'.解决方法
  4. Ubuntu之安装摄像头软件GTK_UVC_Viewer
  5. matlab 创建批量文件夹_学会这12个批量操作,从此告别加班!
  6. 循环队列 - 顺序存储结构
  7. BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划
  8. PHP中COOKIE即时生效,php实现cookie即时生效
  9. java 1.5 代替for循环_J2EE 1.5 提供的另一种形式的for循环
  10. java set 接口_java笔记四:Set接口