docker+k8s基礎篇三


Docker+K8s基礎篇(三)


  •  kubernetes上的資源

    • A:k8s上的常用資源
  • Pod的配置清單

    • A:Pod上的清單定義
    • B:Pod創建資源的方法
    • C:spec下其它字段的介紹
  • Pod的生命周期

    • A:Pod的生命周期階段
    • B:容器的兩種探測(探針)
    • C:容器啟動后和終止前鈎子

♣一:kubernetes的資源

A:k8s上的常用資源:

1:workload(工作負載型對象):
pod,Replicaset,Deployment,statefulSet,DaemonSet,Job,Cronjob,.....(以及各種各樣的pod控制器)deployment
2:服務發現和負載均衡:
Service,Ingress,....
3:配置和存儲:
Volume,CSI(K8S上的容器存儲接口,用來擴展各種第三方的存儲卷)
配置相關:
ConfigMap(配置中心類型的存儲對象),Secret(主要功能和ConfigMap相似,但是用於存儲敏感數據),.....
外部信息輸出給容器:
DownwardAPI,......
4:集群級的資源:(之前的pod資源默認都是在default名稱空間里面的),但是有些資源需要在集群級內部進行定義。
Namespace,Node,Role(角色),ClusterRole(集群角色),RoleBinding(角色綁定),ClusteRoleBinding(集群角色綁定)
5:元數據型資源:
HPA,PodTemplate(用於控制器創建pod的模板),LimitRange(定義資源限制)

♣二:Pod的配置清單

A:Pod上的清單定義:

我們前面都使用命令來創建pods,但是這種形式創建pods資源的時候不能人為的定義其內部的配置。

[root@www .kube]# kubectl get pod myapp-5bc569c47d-jh6qk -o yaml  (我們可以通過查看pods資源信息的時候加上-o yaml來查看pods資源的詳細信息,而這些詳細信息的展示方式也是我們接下來要使用的配置清單來創建pods資源的形式。
apiVersion: v1  api群組的名稱和版本
在實際定義中我們會使用group(組名)/version(版本)來定義的,如果沒有定義組名,默認是cron(核心組)
kind: Pod   資源類別
metadata:    元數據
  creationTimestamp: "2019-06-23T03:39:45Z"
  generateName: myapp-5bc569c47d-
  labels:
    pod-template-hash: 5bc569c47d
    run: myapp
  name: myapp-5bc569c47d-jh6qk
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: myapp-5bc569c47d
    uid: 8b17b969-9568-11e9-9101-000c291028e5
  resourceVersion: "8087"
  selfLink: /api/v1/namespaces/default/pods/myapp-5bc569c47d-jh6qk
  uid: 8b1c0e97-9568-11e9-9101-000c291028e5
spec:    規格,定義我們要創建的資源需要滿足什么規范和特性(這個字段下的內容從定義之初就已經決定了pods資源啟動之后的特性)
  containers:  
  - image: ikubernetes/myapp:v1   
    imagePullPolicy: IfNotPresent
    name: myapp
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-7bd8r
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:  容忍度(污點)
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-7bd8r
    secret:
      defaultMode: 420
      secretName: default-token-7bd8r
status:   這個字段定義了pods資源在當前的狀態,上面的spec定義初始狀態,status則定義當前狀態(只讀),如果我們定義的spec狀態和后面運行的status當前狀態不統一,k8s會自動把當前狀態向目標狀態轉移或靠攏,直到滿足用戶期望的狀態。
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2019-06-23T03:39:45Z"
    message: '0/3 nodes are available: 3 node(s) had taints that the pod didn''t tolerate.'
    reason: Unschedulable
    status: "False"
    type: PodScheduled
  phase: Pending
  qosClass: BestEffort
[root@www .kube]#
kubectl get pod myapp-5bc569c47d-jh6qk -o yaml

B:Pod創建資源的方法:

不是所有的資源都能接受yaml格式定義的資源,例如apiservice就只能接受JSON格式的資源定義,但是JSON格式在定義起來不如yaml格式的方便,如果使用yaml格式來提供配置清單,apiservice能無損切自動的江yaml格式的清單轉換成JSON格式,然后提交直到運行。

配置清單的字段組成:

1:apiVersion(用來定義當前屬於哪個組和那個版本,這個直接關系到最終提供使用的是那個版本)
通過命令kubectl api-versions可以查看到當前所有api的版本。

[root@www .kube]# kubectl api-versions
    k8s將api的版本都以組的形式來划分,這樣我們后面如果是對版本升級,只需要對組內的版本升級即可,避免全部版本都受到影響。而且分組之后還能在一個組里面定義多個版本,來實現多版本並存。
    admissionregistration.k8s.io/v1beta1
    apiextensions.k8s.io/v1beta1
    apiregistration.k8s.io/v1
    apiregistration.k8s.io/v1beta1
    apps/v1
    apps/v1beta1
    apps/v1beta2
    authentication.k8s.io/v1
    authentication.k8s.io/v1beta1
    authorization.k8s.io/v1
    authorization.k8s.io/v1beta1
    autoscaling/v1
    autoscaling/v2beta1
    autoscaling/v2beta2
    在各組的版本之間還分為了穩定版本(v1),穩定版表示定義好的接口在后續不會再進行變化,萬一有變化也是在已有的接口上來增加新的接口。
    非穩定版本(beta),表示定義的接口還會進行變化。
    batch/v1
    batch/v1beta1
    certificates.k8s.io/v1beta1
    coordination.k8s.io/v1
    coordination.k8s.io/v1beta1
    events.k8s.io/v1beta1
    extensions/v1beta1
    networking.k8s.io/v1
    networking.k8s.io/v1beta1
    node.k8s.io/v1beta1
    policy/v1beta1
    rbac.authorization.k8s.io/v1
    rbac.authorization.k8s.io/v1beta1
    scheduling.k8s.io/v1
    scheduling.k8s.io/v1beta1
    storage.k8s.io/v1
    storage.k8s.io/v1beta1
    v1
    [root@www .kube]#
kubectl api-versions

2:kind(資源類別)用來定義創建的對象是屬於什么類別,是pod,service,還是deployment等對象,可以按照其固定的語法格式來自定義。

3:metadata(元數據):
提供以下幾個字段:
  creationTimestamp: "2019-06-24T12:18:48Z"
  generateName: myweb-5b59c8b9d-
  labels: (對象標簽)
    pod-template-hash: 5b59c8b9d
    run: myweb
  name: myweb-5b59c8b9d-gwzz5 (pods對象的名稱,同一個類別當中的pod對象名稱是唯一的,不能重復)
  namespace: default (對象所屬的名稱空間,同一名稱空間內可以重復,這個名稱空間也是k8s級別的名稱空間,不和容器的名稱空間混淆)
  ownerReferences:
    - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: myweb-5b59c8b9d
    uid: 37f38f64-967a-11e9-8b4b-000c291028e5
  resourceVersion: "943"
  selfLink: /api/v1/namespaces/default/pods/myweb-5b59c8b9d-gwzz5
  uid: 37f653a6-967a-11e9-8b4b-000c291028e5
  annotations(資源注解,這個需要提前定義,默認是沒有的)
通過這些標識定義了每個資源引用的path:即/api/group/version/namespaces/名稱空間/資源類別/對象名稱

4:spec (這個字段最重要,因為spec是用來定義目標狀態的‘disired state’,而且資源不通導致spec所嵌套的字段也各不相同,也就因為spec重要且字段不相同,k8s在內部自建了一個spec的說明用於查詢)

5:status:(當前狀態,’current state‘,這個字段有kubernetes集群來生成和維護,不能自定義,屬於一個只讀字段)
spec字段的定義說明:

[root@www kubeadm]# kubectl explain pods(通過explain參數加上資源類別就能看到該資源應該怎么定義)
    KIND:     Pod
    VERSION:  v1

    DESCRIPTION:
         Pod is a collection of containers that can run on a host. This resource is
         created by clients and scheduled onto hosts.

    FIELDS:
       apiVersion   <string>
         APIVersion defines the versioned schema of this representation of an
         object. Servers should convert recognized schemas to the latest internal
         value, and may reject unrecognized values. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

       kind <string>
         Kind is a string value representing the REST resource this object
         represents. Servers may infer this from the endpoint the client submits
         requests to. Cannot be updated. In CamelCase. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

       metadata     <Object>  在相應的字段下面只要看到Object就可以知道該字段下面是要嵌套很多二級字段的,但是二級字段我們還是不知道怎么去定義。
         Standard object's metadata. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

       spec <Object>
         Specification of the desired behavior of the pod. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

       status       <Object>
         Most recently observed status of the pod. This data may not be up to date.
         Populated by the system. Read-only. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

    [root@www kubeadm]# kubectl explain pods.metadata 通過資源類別加上帶有Object標記的字段,我們就可以看到一級字段下二級字段的內容有那些怎么去定義等
    KIND:     Pod
    VERSION:  v1

    RESOURCE: metadata <Object>

    DESCRIPTION:
         Standard object's metadata. More info:
         https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

         ObjectMeta is metadata that all persisted resources must have, which
         includes all objects users must create.

    FIELDS:
       annotations  <map[string]string>  二級字段加上map標記代表是映射字段,其字段是有k=v數據組成的json數組
         Annotations is an unstructured key value map stored with a resource that
         may be set by external tools to store and retrieve arbitrary metadata. They
         are not queryable and should be preserved when modifying objects. More
         info: http://kubernetes.io/docs/user-guide/annotations

       clusterName  <string>
         The name of the cluster which the object belongs to. This is used to
         distinguish resources with same name and namespace in different clusters.
         This field is not set anywhere right now and apiserver is going to ignore
         it if set in create or update request.

       creationTimestamp    <string>
         .........
        ownerReferences      <[]Object>  二級字段下面還可以嵌套三級字段,和上面方法一樣[root@www kubeadm]# kubectl explain pods.metadata.ownerReferences,通過加上不同級別的字段名稱來看下字段下的內容,而且前面的[]號代表對象列表

    (如果字段后面加上了-required-就代表這個字段是必選字段)
    ........
kubectl explain pods

自定義yaml文件:

我們在創建yaml文件的時候可以先把上面5個一級字段寫下來,然后慢慢填空來完成:
apiVersion: v1
kind: Pod
metadata:
  name: pod-number 而且這個位置的名字好像不支持大寫字母
  namespace: default
  labels: #這個位置可以使用{key:value,key:value.....}kv之間逗號隔開
    app: myweb 注意這個位置的名字和下面創建image的時候的名字一致
    tier: Not outside
spec:
  containers:
  - name: myweb
  image: ikubernetes/myapp:v1
  - name: busybox #如果有多個容器,還可以多定義幾個
  image: busybox:latest 因為busybox默認是啟動的sh命令,我們可以給shell命令傳遞些參數。
  command: (["/bin/sh","-c","sleep 20"] 傳遞的參數可以使用[]來寫,也可以用下面的形式來定義)
  - "/bin/sh"
  - "-c"
  - "echo $(date) >> /usr/share/nginx/html/index.html; sleep 5"

[root@www TestYaml]# kubectl create -f pod-test.yaml 然后使用create參數-f去指定加載的yaml文件名
pod/pod-number created
[root@www TestYaml]# kubectl get pods
NAME         READY   STATUS             RESTARTS   AGE
pod-kk       1/1     Running            0          88s
pod-number   1/2     CrashLoopBackOff   4          5m59s可以看到pod-number已經被創建
kubectl create -f pod-test.yaml(從文件加載創建pods)

我們定義了兩個容器,正在運行的有一個,我們可以通過命令來查看通過yaml創建的文件的詳細信息

[root@www TestYaml]# kubectl describe pods pod-number  通過describe參數來查看pods的詳細信息
Name:               pod-number
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               www.kubernetes.node1.com/192.168.181.140  運行在哪個節點上
Start Time:         Wed, 26 Jun 2019 21:05:36 +0800
Labels:             app=myweb
                    tier=Not-outside
Annotations:        <none>
Status:             Running  可以看到名稱叫myweb狀態是運行中
IP:                 10.244.1.19
Containers:
  myweb:
    Container ID:   docker://4b213ff75852bf943adc4a4f35dfb41dd881ac10b051bd545ca00f8bdbcb9ab1
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 26 Jun 2019 21:05:41 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-n5fjx (ro)
  busybox:
    Container ID:  docker://e2b6b439439202e1887b3182b3155bb7e6798460be48c42edafda046ef907e8f
    Image:         busybox:latest
    Image ID:      docker-pullable://busybox@sha256:7a4d4ed96e15d6a3fe8bfedb88e95b153b93e230a96906910d57fc4a13210160
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      echo $(date) >> /usr/share/nginx/html/index.html; sleep 5
    State:          Waiting   因為我們第二個容器創建之后運行的命令是有問題的,所有狀態也是顯示不正常的
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Wed, 26 Jun 2019 21:27:15 +0800
      Finished:     Wed, 26 Jun 2019 21:27:20 +0800
    Ready:          False
    Restart Count:  8
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-n5fjx (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-n5fjx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-n5fjx
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:  在這個字段信息下,我們可以看到整個yaml格式創建pods的過程
  Type     Reason     Age                 From                               Message
  ----     ------     ----                ----                               -------
  Normal   Scheduled  26m                 default-scheduler                  Successfully assigned default/pod-number to www.kubernetes.node1.com
  Normal   Created    25m                 kubelet, www.kubernetes.node1.com  Created container myweb
  Normal   Pulled     25m                 kubelet, www.kubernetes.node1.com  Container image "ikubernetes/myapp:v1" already present on machine
  Normal   Started    25m                 kubelet, www.kubernetes.node1.com  Started container myweb
  Warning  Failed     25m                 kubelet, www.kubernetes.node1.com  Failed to pull image "busybox:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/library/busybox/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Alibrary%2Fbusybox%3Apull&service=registry.docker.io: net/http: TLS handshake timeout
  Warning  Failed     25m (x2 over 25m)   kubelet, www.kubernetes.node1.com  Error: ErrImagePull
  Warning  Failed     25m                 kubelet, www.kubernetes.node1.com  Failed to pull image "busybox:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
  Warning  Failed     24m (x2 over 25m)   kubelet, www.kubernetes.node1.com  Error: ImagePullBackOff
  Normal   BackOff    24m (x2 over 25m)   kubelet, www.kubernetes.node1.com  Back-off pulling image "busybox:latest" 
  Normal   Started    24m (x2 over 24m)   kubelet, www.kubernetes.node1.com  Started container busybox
  Normal   Pulling    23m (x5 over 25m)   kubelet, www.kubernetes.node1.com  Pulling image "busybox:latest"
  Normal   Created    23m (x3 over 24m)   kubelet, www.kubernetes.node1.com  Created container busybox
  Normal   Pulled     15m (x7 over 24m)   kubelet, www.kubernetes.node1.com  Successfully pulled image "busybox:latest"
  Warning  BackOff    54s (x89 over 23m)  kubelet, www.kubernetes.node1.com  Back-off restarting failed container
kubectl describe pods pod-number

查看pods日志:

因為我們創建busybox的是狀態是有問題的,我們就可以通過命令來查看。

[root@www TestYaml]# kubectl logs pod-number busybox  我們通過logs參數指定查看pods里面容器的日志
/bin/sh: can't create /usr/share/nginx/html/index.html: nonexistent directory  可以看到報錯內容,方便我們去查詢容器的錯誤
[root@www TestYaml]# curl 10.244.1.19  因為我們創建的myweb是正常運行,但是沒有訪問請求,我們自己訪問下myweb制造訪問請求
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@www TestYaml]# kubectl logs pod-number myweb
10.244.0.0 - - [26/Jun/2019:13:41:35 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"   可以看到來自master在什么時間對myweb進行了訪問
kubectl logs pod-number busybox

創建好的容器我們也可以和docker一樣通過命令到容器里面去操作。

[root@www TestYaml]# kubectl exec --help  可以使用exec命令來操作
命令行格式
Usage:
  kubectl exec POD [-c CONTAINER] -- COMMAND [args...] [options]
  注意command前面的--是固定格式
[root@www TestYaml]# kubectl exec -it pod-number -c myweb -- /bin/sh 
/ #
[root@www TestYaml]# kubectl get pods
NAME         READY   STATUS         RESTARTS   AGE
pod-kk       1/1     Running        0          45m
pod-number   1/2     ErrImagePull   12         49m
exec

基於yaml文件刪除pods。

[root@www TestYaml]# kubectl delete -f pod-test.yaml  我們在刪除pods資源的時候可以基於yaml文件定義的pods資源來刪除,這樣我們即使刪除了pods,但是yaml文件還存在,想創建隨時可以create下就能出來,無需每次都run,避免人為命令行run的時候導致的問題
pod "pod-kk" deleted
[root@www TestYaml]# kubectl get pods    而且在基於yaml文件刪除的時候發現刪除的pods不在會被自動創建了,也就是說pods不在受控制器管理了,想刪除隨時可以刪除和創建
NAME         READY   STATUS    RESTARTS   AGE
pod-number   1/2     Running   13         50m
kubectl delete -f pod-test.yaml

我們上面只是寫了一個最簡單yaml,其實yaml能更好的按照我們的期許或者更加可控的形式來創建pods,yaml形式大大的彌補了pods自定義這個概念,使得最大限度上pods是按照約束和規范來創建的。
kubectl管理資源有三種方式:
1:命令管理法;
2:配置清單管理法(聲明式);
  配置清單式好處是不言而喻的,可以隨時修改和創建,極大的規避了錯誤的產生。
3:通過其它命令的配置清單管理法。
我們上面創建的pods是沒有持久存儲功能的,要想完成持久存儲,必須脫離k8s集群節點之外的網絡存儲節點,這種存儲節點都是具有持久存儲的節點。

C:spec下其它字段的介紹:

我們可以通過explain一層層的從一級字段(例如spec)往下看。

[root@www TestYaml]# kubectl explain pods.spec.containers.imagePullPolicy
KIND:     Pod
VERSION:  v1

FIELD:    imagePullPolicy <string>

DESCRIPTION:
     Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
     if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
     More info:
     https://kubernetes.io/docs/concepts/containers/images#updating-images
imagePullPolicy字段定義了三種鏡像獲取的方式,而且當對象一旦被創建之后,改字段是不被允許的。
Always:總是去倉庫里面拖鏡像,而且如果鏡像標簽是latest,就默認從倉庫獲取鏡像;
Never:總是以使用本地鏡像,本地沒有也不會去倉庫里面拖鏡像;
IfNotPresent:當本地沒有才去倉庫拖鏡像,除了latest之外,其它的都遵循IfNotPresent模式。
imagePullPolicy(鏡像獲取方式))
[root@www TestYaml]# kubectl explain pods.spec.containers.ports
如果是創建的對象后面需要暴露端號出去,可以一次暴露多個端口,而且每個暴露出去的端口還可以自定義名字,最后還指明暴露的端口是什么協議
當然我們還注意的是例如對象是nginx,默認是80端口,及時在此不指定暴露的端口,默認也是暴露服務默認的端口。
KIND:     Pod
VERSION:  v1

RESOURCE: ports <[]Object>

DESCRIPTION:
     List of ports to expose from the container. Exposing a port here gives the
     system additional information about the network connections a container
     uses, but is primarily informational. Not specifying a port here DOES NOT
     prevent that port from being exposed. Any port which is listening on the
     default "0.0.0.0" address inside a container will be accessible from the
     network. Cannot be updated.

     ContainerPort represents a network port in a single container.
那從實際的角度來說指定容器端口即可containerPort
FIELDS:
   containerPort        <integer> -required-
     Number of port to expose on the pod's IP address. This must be a valid port
     number, 0 < x < 65536.

   hostIP       <string>
     What host IP to bind the external port to.

   hostPort     <integer>
     Number of port to expose on the host. If specified, this must be a valid
     port number, 0 < x < 65536. If HostNetwork is specified, this must match
     ContainerPort. Most containers do not need this.

   name <string>
     If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
     named port in a pod must have a unique name. Name for the port that can be
     referred to by services.

   protocol     <string>
     Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".  
     沒有指定協議,默認是tcp的協議
 案例:
 spec:
   containers:
   - name: myweb1
     image: ikubernetes/myapp:v2
     ports:
     - name: http
       containerPort: 80   可以一次暴露多個端口
     - name: https
       containerPort: 443
ports(pods端口暴露)
[root@www TestYaml]# kubectl explain pods.spec.containers.args  
args指默認向command(命令)傳遞參數 
KIND:     Pod
VERSION:  v1

FIELD:    args <[]string>

DESCRIPTION:
     Arguments to the entrypoint. The docker image's CMD is used if this is not
     provided. Variable references $(VAR_NAME) are expanded using the
     container's environment. If a variable cannot be resolved, the reference in
     the input string will be unchanged. The $(VAR_NAME) syntax can be escaped
     with a double $$, ie: $$(VAR_NAME). Escaped references will never be
     expanded, regardless of whether the variable exists or not. Cannot be
     updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
[root@www TestYaml]# kubectl explain pods.spec.containers.command
command指向要運行的對象給與默認執行的命令或者程序
KIND:     Pod
VERSION:  v1

FIELD:    command <[]string>

DESCRIPTION:
     Entrypoint array. Not executed within a shell(默認給出的命令是不會運行在shell里面的,如果想運行在sehll里面需要自己指定  ). The docker image's
     ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME)
     are expanded using the container's environment. If a variable cannot be
     resolved, the reference in the input string will be unchanged. The
     $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME).
     Escaped references will never be expanded, regardless of whether the
     variable exists or not. Cannot be updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
args和command

在args和command和dockerfile里面的entypoint和cmd是存在一定關系的:
  當沒有提供args和command的時候就運行鏡像里面的entypoint和cmd;
  如果只提供了command,沒有提供args,那鏡像里面的entypoint和cmd都被忽略;
  當只定義了args,默認會將args當參數傳遞給entypoint,這個時候鏡像里面的cmd將不再生效;
  當提供了args和command兩種,鏡像里面的entypoint和cmd就將失效了。

標簽:
標簽是k8s上一個重要的對象聲明,標簽具有以下特征:
  一個對象可以有多個標簽,一個標簽也可以貼在多個對象上;
  標簽即可以在被創建的時候定義,也可以在創建之后來增加,修改和刪除;
  以便於對象被創建之后,方便調度器做匹配度檢查,從而達到目標對象。
標簽在定義的時候應該考慮到以下幾個部分:
  1:對象的版本(穩定版,開發版,公測版,內存版)
  2:環境標簽(測試版,開發版本)
  3:對象提供的功能(web服務,代理服務,數據庫服務等等)
  4:分區標簽(用戶a,用戶b等等)
  5:品控標簽(月級定時追蹤,周級定時追蹤等等)
標簽的定義需要遵循:
  key:字母,數字,_,-,. 字符,且不能超過63個字符;
  value;其它和key相同,但是可以為空。

[root@www TestYaml]# kubectl get pods --show-labels  通過參數--show-labels來查看對象標簽
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-yy   1/1     Running   0          61m   app=myweb1,tier=Not-outside
[root@www TestYaml]# kubectl get pods -L app   加-L參數值過濾查詢對象標簽的值
NAME     READY   STATUS    RESTARTS   AGE     APP
pod-kk   1/1     Running   1          2m57s   mypod01
pod-yy   1/1     Running   0          66m     myweb1
[root@www TestYaml]# kubectl get pods -l app --show-labels  -l過濾查看指包含app這個標簽一類的對象
NAME     READY   STATUS    RESTARTS   AGE    LABELS
pod-kk   1/1     Running   1          5m6s   app=mypod01,tier=Not-outside
pod-yy   1/1     Running   0          68m    app=myweb1,tier=Not-outside
kubectl get pods --show-labels(查看標簽))
Usage:
  kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
[options]
[root@www TestYaml]# kubectl label pods pod-kk edition=beta_version
pod/pod-kk labeled
[root@www TestYaml]# kubectl get pods pod-kk --show-labels 可以看到新的標簽已經標記完成
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-kk   1/1     Running   1          11m   app=mypod01,edition=beta_version,tier=Not-outside
給已經創建的對象打標簽
k8s的標簽選擇器支持兩種方式來進行選擇性查詢:
等值關系的標簽選擇器:
支持:=,==,!=
[root@www TestYaml]# kubectl get pods -l app=mypod01 --show-labels 等於
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-kk   1/1     Running   1          20m   app=mypod01,edition=beta_version,tier=Not-outside
[root@www TestYaml]# kubectl get pods -l app!=mypod01 --show-labels  不等於
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-yy   1/1     Running   0          83m   app=myweb1,tier=Not-outside
[root@www TestYaml]# kubectl get pods -l app=mypod01,edition=beta_version --show-labels  同時滿足多個條件的
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-kk   1/1     Running   1          22m   app=mypod01,edition=beta_version,tier=Not-outside
集合關系的標簽選擇器:
key in (value1,value2)
key notin (value1,value2)
key和!key
[root@www TestYaml]# kubectl get pods -l "edition in (beta_version)" --show-labels
NAME     READY   STATUS    RESTARTS   AGE   LABELS
pod-kk   1/1     Running   1          37m   app=mypod01,edition=beta_version,tier=Not-outside
[root@www TestYaml]#
k8s標簽選擇器的查詢方式

在k8s上我們很多資源都需要通過標簽和標簽選擇器來關聯其它的資源,例如pod控制器和service,針對這種資源我們通常會使用兩個字段來嵌套關聯其它資源
1:matchLabesl;直接給定鍵值
2:matchExpressions;基於給定的表達式來定義使用的選擇器
  {key:“KEY",operator:"OPERATOR",values:[value1,value2....]}
  表示定義的key的values值基於operator來做比較,能滿足即表示滿足我們的需求,否則就不能滿足我們的需求
  operator表示操操作符,常用的有:In,Notin,Exists(存在),NotExists(不存在)
                  使用In,Notin后面的values必須是一個非空列表
                  Exists,NotExists的valuel必須是一個空列表
k8s上很多資源都可以打標簽,例如nodes等。

[root@www TestYaml]# kubectl get nodes --show-labels
NAME                        STATUS   ROLES    AGE    VERSION   LABELS
                                                               beta.kubernetes.io是前綴,這個前綴是dns域名
www.kubernetes.master.com   Ready    master   142m   v1.14.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=www.kubernetes.master.com,kubernetes.io/os=linux,node-role.kubernetes.io/master=
www.kubernetes.node1.com    Ready    <none>   140m   v1.14.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=www.kubernetes.node1.com,kubernetes.io/os=linux
www.kubernetes.node2.com    Ready    <none>   140m   v1.14.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=www.kubernetes.node2.com,kubernetes.io/os=linux
[root@www TestYaml]#
kubectl get nodes --show-labels
nodeSelector節點選擇器,可以選擇pod在哪個節點上運行,這樣我們可以指定該pod在哪個或者哪類節點上運行,因為我們幾點資源不都是一樣的,有的可能是虛擬機和雲機,有的是ibm或者dell的實體機等,針對這種我們做監控也得有針對性的運行pods
[root@www TestYaml]# kubectl explain pods.spec.nodeSelector
KIND:     Pod
VERSION:  v1

FIELD:    nodeSelector <map[string]string> 注意字段的類型

DESCRIPTION:
     NodeSelector is a selector which must be true for the pod to fit on a node.
     Selector which must match a node's labels for the pod to be scheduled on
     that node. More info:
     https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
spec:
   containers:
   - name: mypod01
     image: ikubernetes/myapp:v2
     ports:
     - name: http
       containerPort: 80
     - name: https
       containerPort: 443
   nodeSelector:   例如我們定義改pods只能運行在帶有IBM標簽的機器上,當然得事先定義帶IMB的標簽
       lable: IBM
如果不想這么麻煩,我就想直接指定節點,也可以,字段是nodeName
[root@www TestYaml]# kubectl explain pods.spec.nodeName
KIND:     Pod
VERSION:  v1

FIELD:    nodeName <string>

DESCRIPTION:
     NodeName is a request to schedule this pod onto a specific node. If it is
     non-empty, the scheduler simply schedules this pod onto that node, assuming
     that it fits resource requirements.
nodeSelector節點選擇器
annotations:資源注解,這個label不同的是,不能作為標簽選擇器的挑選機制所存在,只能為對象提供元數據,而且資源描述是沒有字符限制的。當創建的大型且重要對象的適合,資源描述尤為重要。
[root@www TestYaml]# cat pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
   name: pod-kk
   namespace: default
   labels:
     app: mypod01
     tier: Not-outside
   annotations:  我們定義了三個資源的描述
     creator: "Tommy"
     create_time: "2019-06-30"
     Contact_information: "baidu@163.com"
spec:
   containers:
   - name: mypod01
     image: ikubernetes/myapp:v2
     ports:
     - name: http
       containerPort: 80
     - name: https
       containerPort: 443
   nodeSelector:
       lable: IBM
[root@www TestYaml]# kubectl create -f pod-test.yaml
pod/pod-kk created
[root@www TestYaml]# kubectl describe pods pod-kk
Name:               pod-kk
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               <none>
Labels:             app=mypod01
                    tier=Not-outside
Annotations:        Contact_information: baidu@163.com  可以看到Annotations的信息,但是不是安裝我們定義的順序來的,但是無關緊要。
                    create_time: 2019-06-30
                    creator: Tommy
Status:             Pending
IP:
Containers:
  mypod01:
    Image:        ikubernetes/myapp:v2
    Ports:        80/TCP, 443/TCP
    Host Ports:   0/TCP, 0/TCP
    Environment:  <none>
..........
annotations:資源注解

♣三:Pod的生命周期

A:Pod的生命周期階段:

一個pods的生命周期需要經歷一下幾個階段:
  1:pod被創建到運行為一個階段;
  2:pods在被創建之后到運行為容器之前有一段的空閑時間,這個時間有可能需要給容器做一些環境的初始化。
  3:當pods被運維為容器的最開始,容器本身需要最環境的初始化,例如容器如果是nginx,nginx需要對html路徑下的文件按照順序加載等等,當然容器有開始就有結束,結束的時候對容器產生的數     據進行處理;
  4:容器在運行的過程中我們需要對容器做監控,存活性狀態檢測。
pod的生命周期按照狀態來划分可以分為一下幾個部分:
  1:Pending(掛起),pods為什么會掛起,pods運行的時候是按照yaml文件來運行的,當節點環境不能滿足pods運行就會處於掛起,也代表調度尚未完成;
  2:Running(運行)
  3:Failed(失敗)
  4:Succeeded(成功)
  5:Unknown(未知狀態)
  等等狀態
pods創建的過程:
當用戶創建pods的時候,這個請求會傳遞給apiservice,apisevice接收到請求之后會保存在etcd當中,接下來apiservice會請求scheduler來進行調度,如果調度成功了會將調度的結果保存在etcd的poids資源狀態信息當中,
被調度的節點上的kubelet會得到這個保存的狀態知道有一個新任務給到自己了,kubelet拿到清單之后並啟動運行這個pods,pods創建的狀態對由kubelet發送給apiservice保存在etcd當中。
pod生命周期中的重要行為,初始化容器,容器探測。
pod的重啟:

[root@www TestYaml]# kubectl explain pods.spec.restartPolicy 
restartPolicy用來給重啟容器,當探測到容器掛了,restartPolicy會提供三種選項給用戶,Always(總是重啟),OnFailure(只有正常終止的才重啟),Never(從不重啟)
KIND:     Pod
VERSION:  v1

FIELD:    restartPolicy <string>

DESCRIPTION:
     Restart policy for all containers within the pod. One of Always, OnFailure,
     Never. Default to Always. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
restartPolicy

pods的重啟不是我們常規理解的一旦服務退出就立馬重啟,周而復始的重啟,因為每一次重啟都會消耗我們的硬件資源的,如果不能合理處理這種情況,可能我們機器硬件資源就用完了,影響到其他的程序,所以pods的重啟是第一次掛了立馬重啟,
當第二次掛了是延時重啟,每一次重啟就要在上一次時間上翻倍,直到最大時長300秒,到300秒一會代表pods每一次重啟都需要300秒。當pods節點沒有掛或者pods沒有被刪除,就一直會在此節點上重啟。
pod的終止:
pod的終止需要遵循平滑終止的策略,主要是為了保證我們的數據不會丟失,當用戶或者外在因素終止了pods,pods首先會想其內部的容器發起終止信號,讓pods中的容器自然終止,這個終止是有時間限制的,例如10秒,10秒沒有終止,就會發起kill信號。
這個寬限的時間默認是30秒,也可以自行定義。

B:容器的兩種探測(探針)

liveness probe(存活性探測)和readiness probe(就緒性探測)
容器的探測和我們生活常見的探測一樣,在容器里面安裝一些傳感器或者探針等,來獲取一些數據來作為容器是否存活或者就緒的標准,目前k8s上對兩種狀態的探測方式是一樣的。
三種探測(探針)類型:
1:ExecAction
2:TCPSocketAction(tcp套接字探測)
3:HTTPGetAction(如果對象是http服務,我們直接發送http的請求即可達到探測目的)
上述三種針對兩種不同的狀態又分為了存活性探針或者就緒性探針,還有這個探測是用來探測容器的,不是pods。

[root@www home]# kubectl explain pod.spec.containers.livenessProbe
KIND:     Pod
VERSION:  v1

RESOURCE: livenessProbe <Object>

DESCRIPTION:
     Periodic probe of container liveness. Container will be restarted if the
     probe fails. Cannot be updated. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

     Probe describes a health check to be performed against a container to
     determine whether it is alive or ready to receive traffic.

FIELDS:
   exec <Object>  第一種
     One and only one of the following should be specified. Exec specifies the
     action to take.

   failureThreshold     <integer>  指定探測的多少次都是失敗的,才認為是失敗的
     Minimum consecutive failures for the probe to be considered failed after
     having succeeded. Defaults to 3(默認是3此). Minimum value is 1.(最少是一次)

   httpGet      <Object> 第二種
     HTTPGet specifies the http request to perform.

   initialDelaySeconds  <integer>  在docker容器在啟動的時候立即做探測,這個時候可能主程序還沒有啟動完成,這個時候探測結果有可能是失敗造成誤傷,在多長時間之后進行探測
     Number of seconds after the container has started before liveness probes  默認是容器一旦啟動就立馬探測
     are initiated. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

   periodSeconds        <integer>  指定探測次數之后間隔多長時間來進行探測
     How often (in seconds) to perform the probe. Default to 10 (默認是10秒探測一次)seconds. Minimum
     value is 1.

   successThreshold     <integer>
     Minimum consecutive successes for the probe to be considered successful
     after having failed. Defaults to 1. Must be 1 for liveness. Minimum value
     is 1.

   tcpSocket    <Object>第三種
     TCPSocket specifies an action involving a TCP port. TCP hooks not yet
     supported

   timeoutSeconds       <integer>  指定探測間隔時間之后超時多長時間
     Number of seconds after which the probe times out. Defaults to 1(默認是1秒) second.
     Minimum value is 1. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
     上面三種探針,我們一次創建指需要定義一個足以
livenessProbe(存活性探針)
[root@www home]# kubectl explain pod.spec.containers.readinessProbe
KIND:     Pod
VERSION:  v1

RESOURCE: readinessProbe <Object>  探測方式和livenessProbe一樣的,但是需要分清楚兩者之間的屬性,程序存活不代表程序就是就緒的

DESCRIPTION:
     Periodic probe of container service readiness. Container will be removed
     from service endpoints if the probe fails. Cannot be updated. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

     Probe describes a health check to be performed against a container to
     determine whether it is alive or ready to receive traffic.

FIELDS:
   exec <Object>
     One and only one of the following should be specified. Exec specifies the
     action to take.

   failureThreshold     <integer>
     Minimum consecutive failures for the probe to be considered failed after
     having succeeded. Defaults to 3. Minimum value is 1.

   httpGet      <Object>
     HTTPGet specifies the http request to perform.

   initialDelaySeconds  <integer>
     Number of seconds after the container has started before liveness probes
     are initiated. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes

   periodSeconds        <integer>
     How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
     value is 1.

   successThreshold     <integer>
     Minimum consecutive successes for the probe to be considered successful
     after having failed. Defaults to 1. Must be 1 for liveness. Minimum value
     is 1.

   tcpSocket    <Object>
     TCPSocket specifies an action involving a TCP port. TCP hooks not yet
     supported

   timeoutSeconds       <integer>
     Number of seconds after which the probe times out. Defaults to 1 second.
     Minimum value is 1. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
readinessProbe(就緒性探針)

除了上述兩種,k8s還提供了生命周期的探測。

[root@www home]# kubectl explain pod.spec.containers.lifecycle
這個什么周期是用來定義容器啟動前和終止后的鈎子參數的
KIND:     Pod
VERSION:  v1

RESOURCE: lifecycle <Object>

DESCRIPTION:
     Actions that the management system should take in response to container
     lifecycle events. Cannot be updated.

     Lifecycle describes actions that the management system should take in
     response to container lifecycle events. For the PostStart and PreStop
     lifecycle handlers, management of the container blocks until the action is
     complete, unless the container process fails, in which case the handler is
     aborted.

FIELDS:
   postStart    <Object>
     PostStart is called immediately after a container is created. If the
     handler fails, the container is terminated and restarted according to its
     restart policy. Other management of the container blocks until the hook
     completes. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

   preStop      <Object>
     PreStop is called immediately before a container is terminated due to an
     API request or management event such as liveness probe failure, preemption,
     resource contention, etc. The handler is not called if the container
     crashes or exits. The reason for termination is passed to the handler. The
     Pod's termination grace period countdown begins before the PreStop hooked
     is executed. Regardless of the outcome of the handler, the container will
     eventually terminate within the Pod's termination grace period. Other
     management of the container blocks until the hook completes or until the
     termination grace period is reached. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
exec說明:
lifecycle(生命周期探測)
[root@www TestYaml]# kubectl explain pod.spec.containers.livenessProbe.exec
KIND:     Pod
VERSION:  v1

RESOURCE: exec <Object>

DESCRIPTION:
     One and only one of the following should be specified. Exec specifies the
     action to take.

     ExecAction describes a "run in container" action.

FIELDS:要想使用exec命令必須是容器里面程序擁有並且能執行的命令才可以
   command      <[]string>  
     Command is the command line to execute inside the container, the working
     directory for the command is root ('/') in the container's filesystem. The
     command is simply exec'd, it is not run inside a shell, so traditional
     shell instructions ('|', etc) won't work. To use a shell, you need to
     explicitly call out to that shell. Exit status of 0 is treated as
     live/healthy and non-zero is unhealthy.
livenessProbe.exec
[root@www TestYaml]# cat pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
   name: busybox-test
   namespace: default
spec:
   containers:
   - name: busybox-test-pod
     image: busybox:latest
     command: ["bin/sh","-c","touch /home/busybox; sleep 20; mv /home/busybox /tmp/; sleep 1200"] 我們給定命令讓對象啟動為容器之后執行的命令
     livenessProbe:
       exec:  使用exec加上命令對這個容器運行之后創建的文件進行命令的探測
         command: ["test","-e","/home/busybox"]  
       initialDelaySeconds: 3  在容器啟動后3秒才開始探測
       periodSeconds: 4 每隔4秒探測一次
[root@www TestYaml]# kubectl create -f pod-test.yaml
pod/busybox-test created
[root@www TestYaml]# kubectl get pods -w
NAME           READY   STATUS    RESTARTS   AGE
busybox-test   1/1     Running   0          46s  可以看到pods開始是running的
pod-kk         0/1     Pending   0          19m
[root@www TestYaml]# kubectl describe pods busybox-test
Name:               busybox-test
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               www.kubernetes.node1.com/192.168.181.140
Start Time:         Mon, 01 Jul 2019 21:01:03 +0800
Labels:             <none>
Annotations:        <none>
Status:             Running   容器狀態是running和實際的狀態相符
IP:                 10.244.1.22
Containers:
  busybox-test-pod:
    Container ID:  docker://dce312cf24767a597ee177cf65d83686d1cf0a12a638708eb2810e78a18ab0de
    Image:         busybox:latest
    Image ID:      docker-pullable://busybox@sha256:7a4d4ed96e15d6a3fe8bfedb88e95b153b93e230a96906910d57fc4a13210160
    Port:          <none>
    Host Port:     <none>
    Command:
      bin/sh
      -c
      touch /home/busybox; sleep 20; mv /home/busybox /tmp/; sleep 1200
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated  但是看到最近一次的狀態是結束的
      Reason:       Error   原因是錯誤
      Exit Code:    137    退出的代碼是137
      Started:      Mon, 01 Jul 2019 21:19:55 +0800   啟動的時間 
      Finished:     Mon, 01 Jul 2019 21:20:57 +0800   完成的時間
    Ready:          False
    Restart Count:  9  已經幫忙重啟了9次
    Liveness:       exec [test -e /home/busybox] delay=3s timeout=1s period=4s #success=1 #failure=3  可以看到詳細的探測過程
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-npzp7 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-npzp7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-npzp7
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                  From                               Message
  ----     ------     ----                 ----                               -------
  Normal   Scheduled  20m                  default-scheduler                  Successfully assigned default/busybox-test to www.kubernetes.node1.com
  Normal   Pulled     17m (x3 over 20m)    kubelet, www.kubernetes.node1.com  Successfully pulled image "busybox:latest"
  Normal   Created    17m (x3 over 20m)    kubelet, www.kubernetes.node1.com  Created container busybox-test-pod
  Normal   Started    17m (x3 over 20m)    kubelet, www.kubernetes.node1.com  Started container busybox-test-pod
  Warning  Unhealthy  17m (x9 over 19m)    kubelet, www.kubernetes.node1.com  Liveness probe failed:
  Normal   Killing    17m (x3 over 19m)    kubelet, www.kubernetes.node1.com  Container busybox-test-pod failed liveness probe, will be restarted
  Normal   Pulling    9m57s (x8 over 20m)  kubelet, www.kubernetes.node1.com  Pulling image "busybox:latest"
  Warning  BackOff    21s (x36 over 12m)   kubelet, www.kubernetes.node1.com  Back-off restarting failed container
[root@www TestYaml]# kubectl get pods -w
NAME           READY   STATUS         RESTARTS   AGE
busybox-test   0/1     ErrImagePull   9          26m
pod-kk         0/1     Pending        0          44m
busybox-test   1/1     Running        10         26m
可以看到RESTARTS的數字在變化,說明一直在幫忙重啟,標記的重啟次數。
[root@www TestYaml]# kubectl get pods -w
NAME           READY   STATUS         RESTARTS   AGE
busybox-test   0/1     ErrImagePull   9          26m
pod-kk         0/1     Pending        0          44m
busybox-test   1/1     Running        10         26m
busybox-test   0/1     ErrImagePull   10         27m
busybox-test   0/1     CrashLoopBackOff   10         27m
重啟10次之后直接顯示容器掛了
livenessProbe.exec(案例)
[root@www TestYaml]# kubectl explain pod.spec.containers.livenessProbe.tcpSocket
KIND:     Pod
VERSION:  v1

RESOURCE: tcpSocket <Object>

DESCRIPTION:
     TCPSocket specifies an action involving a TCP port. TCP hooks not yet
     supported

     TCPSocketAction describes an action based on opening a socket

FIELDS:
   host <string>  必須要指定主機地址
     Optional: Host name to connect to, defaults to the pod IP.

   port <string> -required-  必須指定從服務的那個端口來進行探測
     Number or name of the port to access on the container. Number must be in
     the range 1 to 65535. Name must be an IANA_SVC_NAME.
tcpSocket探測
httpGet探測
[root@www TestYaml]# kubectl explain pod.spec.containers.livenessProbe.httpGet  如果對象是一個http服務,你們可以直接使用httpGet來探測
KIND:     Pod
VERSION:  v1

RESOURCE: httpGet <Object>

DESCRIPTION:
     HTTPGet specifies the http request to perform.

     HTTPGetAction describes an action based on HTTP Get requests.

FIELDS:
   host <string>
     Host name to connect to, defaults to the pod IP. You probably want to set
     "Host" in httpHeaders instead.

   httpHeaders  <[]Object>
     Custom headers to set in the request. HTTP allows repeated headers.

   path <string>   直接像執行地址和端口的url發起請求,如果返回碼是200,301,302都是代表正常,其它代表錯誤
     Path to access on the HTTP server.

   port <string> -required-   
     Name or number of the port to access on the container. Number must be in
     the range 1 to 65535. Name must be an IANA_SVC_NAME.如果定義暴露的端口有指定名稱,可以通過命令來訪問也行

   scheme       <string>
     Scheme to use for connecting to the host. Defaults to HTTP.
httpGet探測
[root@www TestYaml]# cat http-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
   name: http-test
   namespace: default
spec:
   containers:
   - name: http-test-pod
     image: ikubernetes/myapp:v1
     ports:
     - name: myhttp
       containerPort: 80
     livenessProbe:
       httpGet:
         port: myhttp
         path: /index.html
       initialDelaySeconds: 3
       periodSeconds: 4
[root@www TestYaml]# kubectl get pods
NAME           READY   STATUS             RESTARTS   AGE
busybox-test   0/1     CrashLoopBackOff   13         43m
http-test      1/1     Running            0          12s
pod-kk         0/1     Pending            0          61m
[root@www TestYaml]# kubectl describe pods http-test
Name:               http-test
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               www.kubernetes.node2.com/192.168.181.146
Start Time:         Mon, 01 Jul 2019 21:44:04 +0800
Labels:             <none>
Annotations:        <none>
Status:             Running 
IP:                 10.244.2.6
Containers:
  http-test-pod:
    Container ID:   docker://67693dafae6c8b5f84bd344df045dbab0d5600fac67f42bfe00d06f1bfbc8b63
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 01 Jul 2019 21:44:09 +0800
    Ready:          True
    Restart Count:  0
    Liveness:       http-get http://:myhttp/index.html delay=3s timeout=1s period=4s #success=1 #failure=3  可以看到整個探測的方式和詳細的參數和參數值
                    是通過httpget的形式不斷去的訪問index.html這個url
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-npzp7 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-npzp7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-npzp7
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                               Message
  ----    ------     ----  ----                               -------
  Normal  Scheduled  81s   default-scheduler                  Successfully assigned default/http-test to www.kubernetes.node2.com
  Normal  Pulled     77s   kubelet, www.kubernetes.node2.com  Container image "ikubernetes/myapp:v1" already present on machine
  Normal  Created    77s   kubelet, www.kubernetes.node2.com  Created container http-test-pod
  Normal  Started    76s   kubelet, www.kubernetes.node2.com  Started container http-test-pod
我們手動進入容器把index.html文件改名字然后在查看
[root@www TestYaml]# kubectl exec -it http-test -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # mv index.html index.html.bak
/usr/share/nginx/html # ls
50x.html        index.html.bak
/usr/share/nginx/html #
[root@www TestYaml]# kubectl describe pods http-test
Name:               http-test
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               www.kubernetes.node2.com/192.168.181.146
Start Time:         Mon, 01 Jul 2019 21:44:04 +0800
Labels:             <none>
Annotations:        <none>
Status:             Running
IP:                 10.244.2.6
Containers:
  http-test-pod:
    Container ID:   docker://850776a64342adae194fa117c6d53ca8baf1a672b33346169de8d687a16fd729
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 01 Jul 2019 21:49:41 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Mon, 01 Jul 2019 21:44:09 +0800
      Finished:     Mon, 01 Jul 2019 21:49:40 +0800
    Ready:          True
    Restart Count:  1  可以看到已經在幫忙重啟了一次
    Liveness:       http-get http://:myhttp/index.html delay=3s timeout=1s period=4s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-npzp7 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-npzp7:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-npzp7
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                  From                               Message
  ----     ------     ----                 ----                               -------
  Normal   Scheduled  6m3s                 default-scheduler                  Successfully assigned default/http-test to www.kubernetes.node2.com
  Warning  Unhealthy  27s (x3 over 35s)    kubelet, www.kubernetes.node2.com  Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    27s                  kubelet, www.kubernetes.node2.com  Container http-test-pod failed liveness probe, will be restarted
  Normal   Pulled     26s (x2 over 5m59s)  kubelet, www.kubernetes.node2.com  Container image "ikubernetes/myapp:v1" already present on machine
  Normal   Created    26s (x2 over 5m59s)  kubelet, www.kubernetes.node2.com  Created container http-test-pod
  Normal   Started    26s (x2 over 5m58s)  kubelet, www.kubernetes.node2.com  Started container http-test-pod
[root@www TestYaml]# kubectl exec -it http-test -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html #
因為我們創建的容器在重啟整個環境會被重置,重置之后index.html文件又因為環境的重置恢復了
[root@www TestYaml]# kubectl exec -it http-test -- /bin/sh
........
 Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Mon, 01 Jul 2019 21:44:09 +0800
      Finished:     Mon, 01 Jul 2019 21:49:40 +0800
    Ready:          True
    Restart Count:  1
    Liveness:       http-get http://:myhttp/index.html delay=3s timeout=1s period=4s #success=1 #failure=3
    Environment:    <none>
[root@www TestYaml]# kubectl get pods
NAME           READY   STATUS             RESTARTS   AGE
busybox-test   0/1     CrashLoopBackOff   15         53m
http-test      1/1     Running            1          10m  可以看到重啟的次數為1次
pod-kk         0/1     Pending            0          71m
[root@www TestYaml]# kubectl logs http-test http-test-pod
10.244.2.1 - - [01/Jul/2019:13:49:44 +0000] "GET /index.html HTTP/1.1" 200 65 "-" "kube-probe/1.14" "-"
10.244.2.1 - - [01/Jul/2019:13:49:48 +0000] "GET /index.html HTTP/1.1" 200 65 "-" "kube-probe/1.14" "-"
10.244.2.1 - - [01/Jul/2019:13:49:52 +0000] "GET /index.html HTTP/1.1" 200 65 "-" "kube-probe/1.14" "-"
......
[root@www TestYaml]# kubectl logs http-test http-test-pod | wc -l
110  已經探測了110次了
[root@www TestYaml]# kubectl logs http-test http-test-pod  我們再刪除一次index.html,可以看到日志也提示了index.html文件不存在
2019/07/01 13:58:24 [error] 6#6: *131 open() "/usr/share/nginx/html/index.html" failed (2: No such file or directory), client: 10.244.2.1, server: localhost, request: "GET /index.html HTTP/1.1", host: "10.244.2.6:80"
10.244.2.1 - - [01/Jul/2019:13:58:24 +0000] "GET /index.html HTTP/1.1" 404 169 "-" "kube-probe/1.14" "-"
.....
重啟之后又立馬恢復正常
httpGet探測(案例)

就緒性探測邏輯和存活性探測類似,其實我們在get pods的時候也能看到容器的大致情況
[root@www TestYaml]# kubectl get pods
NAME    READY    STATUS    RESTARTS   AGE
busybox-test  0/1    CrashLoopBackOff   17       61m
http-test    1/1       Running               2      18m
pod-kk           0/1        Pending                0      80m
在READY下面展示的0/1,其中前面的代表幾個容器已經就緒的,后面代表這個pods里面有幾個容器。但是這個前面的1是容器一啟動就代表就緒,但是實際上大多數情況下不代表實際的情況,所以需要去調整這個探測的時間。

                                                                

如上圖所示,當service在調度的時候只要滿足名稱為web-pod條件的pod就會被自由調度,這個時候正好起了一個web-pod-003的pods,里面跑的容器和001和002一樣,如果我們設置的yaml文件是容器啟動就代表就緒,那此時有新用戶的請求進來被service
調度到003上,但是因為003上的容器內部的nginx和java都需要做啟動前環境檢測,nginx加載java文件等操作,這個操作也是會消耗時間,假如消耗時長為5秒,那這5秒之內將會有很多用戶的請求將得不到內容,此種也算作生產事故。由此可見我們設定
探測時間也變得尤為重要。

[root@www TestYaml]# cat readiness.http-get.yaml
apiVersion: v1
kind: Pod
metadata:
   name: readiness-http-test
   namespace: default
spec:
   containers:
   - name: readiness-http-test-pod
     image: ikubernetes/myapp:v1
     ports:
     - name: http
       containerPort: 80
     readinessProbe:
       httpGet:
         port: http
         path: /index.html
       initialDelaySeconds: 3
       periodSeconds: 4[root@www TestYaml]# kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
readiness-http-test   1/1     Running   0          12s
[root@www TestYaml]# kubectl exec -it readiness-http-test -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # rm -rf index.html  刪掉主頁文件
/usr/share/nginx/html # ls
50x.html
/usr/share/nginx/html #
[root@www ~]# kubectl get pods -w
NAME                  READY   STATUS    RESTARTS   AGE
readiness-http-test   1/1     Running   0          119s
readiness-http-test   0/1     Running   0          2m38s  可以看到顯示未就緒狀態了

/usr/share/nginx/html # netstat -anptu | grep 80 而此時我們的nginx還是運行的狀態
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro
tcp        0      0 10.244.1.23:80          10.244.1.1:37590        TIME_WAIT   -
tcp        0      0 10.244.1.23:80          10.244.1.1:37586        TIME_WAIT   -
/usr/share/nginx/html # touch index.html  我們手動touch一個index文件
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html #

[root@www ~]# kubectl get pods -w
NAME                  READY   STATUS    RESTARTS   AGE
readiness-http-test   1/1     Running   0          119s
readiness-http-test   0/1     Running   0          2m38s
readiness-http-test   1/1     Running   0          6m2s   可以看到又變成就緒的狀態了
readinessProbe(就緒性探針案例)

C:容器啟動后和終止前鈎子

postStart啟動后鈎子

preStop終止前鈎子

[root@www TestYaml]# kubectl explain pods.spec.containers.lifecycle
KIND:     Pod
VERSION:  v1

RESOURCE: lifecycle <Object>

DESCRIPTION:
     Actions that the management system should take in response to container
     lifecycle events. Cannot be updated.

     Lifecycle describes actions that the management system should take in
     response to container lifecycle events. For the PostStart and PreStop
     lifecycle handlers, management of the container blocks until the action is
     complete, unless the container process fails, in which case the handler is
     aborted.

FIELDS:
   postStart    <Object>  支持啟動后
     PostStart is called immediately after a container is created. If the
     handler fails, the container is terminated and restarted according to its
     restart policy. Other management of the container blocks until the hook
     completes. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

   preStop      <Object>終止前
     PreStop is called immediately before a container is terminated due to an
     API request or management event such as liveness probe failure, preemption,
     resource contention, etc. The handler is not called if the container
     crashes or exits. The reason for termination is passed to the handler. The
     Pod's termination grace period countdown begins before the PreStop hooked
     is executed. Regardless of the outcome of the handler, the container will
     eventually terminate within the Pod's termination grace period. Other
     management of the container blocks until the hook completes or until the
     termination grace period is reached. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
[root@www TestYaml]# kubectl explain pods.spec.containers.lifecycle.postStart
KIND:     Pod
VERSION:  v1

RESOURCE: postStart <Object>

DESCRIPTION:
     PostStart is called immediately after a container is created. If the
     handler fails, the container is terminated and restarted according to its
     restart policy. Other management of the container blocks until the hook
     completes. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

     Handler defines a specific action that should be taken

FIELDS:
   exec <Object>
     One and only one of the following should be specified. Exec specifies the
     action to take.

   httpGet      <Object>
     HTTPGet specifies the http request to perform.

   tcpSocket    <Object>
     TCPSocket specifies an action involving a TCP port. TCP hooks not yet
     supported

[root@www TestYaml]#

[root@www TestYaml]# kubectl explain pods.spec.containers.lifecycle.preStop
KIND:     Pod
VERSION:  v1

RESOURCE: preStop <Object>  終止前

DESCRIPTION:
     PreStop is called immediately before a container is terminated due to an
     API request or management event such as liveness probe failure, preemption,
     resource contention, etc. The handler is not called if the container
     crashes or exits. The reason for termination is passed to the handler. The
     Pod's termination grace period countdown begins before the PreStop hooked
     is executed. Regardless of the outcome of the handler, the container will
     eventually terminate within the Pod's termination grace period. Other
     management of the container blocks until the hook completes or until the
     termination grace period is reached. More info:
     https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

     Handler defines a specific action that should be taken

FIELDS:
   exec <Object>  可以看到三種方式和上面的探針一樣,其功能也類似
     One and only one of the following should be specified. Exec specifies the
     action to take.

   httpGet      <Object>
     HTTPGet specifies the http request to perform.

   tcpSocket    <Object>
     TCPSocket specifies an action involving a TCP port. TCP hooks not yet
     supported
lifecycle

兩者都是容器的兩個極端點運行之前需要執行一些命令或者操作之后才能運行和終止容器,如果這些命令和操作執行失敗了,容器會終止並重啟,這個重啟就取決於重啟策略。


免責聲明!

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



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