Kubernetes容器上下文環境


目錄貼: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-volume
  labels:
    name: test-downwardaoi-volume
    zone: us-east
    cluster: test-cluster1
  annotations:
    build: two
    builder: zhenyuyaodidiao
spec:
  containers:
    - name: test-hostpath
      image: registry:5000/back_demon:1.0
      volumeMounts:
       - name: podinfo
         mountPath: /home/laizy/podinfo
         readOnly: false
      command:
      - /run.sh
  volumes:
  - name: podinfo
    downwardAPI:
      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-hostpath
    role: master
  name: test-lifecycle-hostpath
spec:
  containers:
    - name: test-lifecycle-hostpath
      image: registry:5000/back_demon:1.0
      lifecycle:
        postStart:
          exec:
            command:
              - "touch"
              - "/home/laizy/test/hostpath/post-start"
        preStop:
          exec:
            command:
              - "touch"
              - "/home/laizy/test/hostpath/pre-stop"
      volumeMounts:
       - name: testhost
         mountPath: /home/laizy/test/hostpath
         readOnly: false
      command:
      - /run.sh
  volumes:
  - name: testhost
    hostPath:
     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: lifecycle
    image: busybox
    lifecycle:
      postStart:
        exec:
          command:
            - "touch"
            - "/var/log/lifecycle/post-start"
      preStop:
        httpGet:
          path: "/abort"
          port: 8080

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM