zoukankan      html  css  js  c++  java
  • pod

    pod定义详解

    下面是一个完整的yaml格式定义的文件,注意格式,子集包含关系,不要有tab,要用空格。不是所有的元素都要写,按照实际应用场景配置即可。

    定义一个简单pod(最好把docker源改成国内的)

    apiVersion: v1
    kind: Pod
    metadata:
       name: hello-world
       namespace: default
    spec: 
      restartPolicy: OnFailure
      containers:             
      - name: hello 
        image: "ubuntu:14.04"  
        command: ["/bin/echo","hello","world"]

    pod文件解释:
    apiVersion: v1//k8s版本
    kind: pod//声明API对象类型这里是pod
    metadata:
            name:hello-word //pod名字必须在namespace中是唯一
    spec://配置pod具体配置
            restartPolicy: OnFailure // pod重启策略 [Always默认策略,当容器退出时总是重启容器|Never当容器退出时,从不重启|OnFailure容器正常退出不会再重新启动,退出码非0时才重启容器]
    containers: //pod中的容器列表,可以有多个容器
           - name: hello //容器名字,在一个pod中唯一
           image: "ubuntu:14.04" //镜像名字
           command: ["/bin/echo","hello","word"]//设置容器的启动命令

    创建pod

    [root@kubernetes-master pods]# kubectl create -f helloworld.yml
    pod "hello-word" created

    查看pod状态,状态不是runing而是完成,说明容器运行完成已经退出了

    查看容器log输出

    [root@kubernetes-master pods]# kubectl logs hello-world
    hello world

    这里要说一下command和args2个参数:

    pod中定义env

    容器获取pod信息

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4    name: print-pod-info
     5    namespace: default
     6 spec: 
     7   containers:             
     8   - name: my-pod
     9     image: busybox
    10     resources:   
    11         requests:
    12           memory: "32Mi"  
    13           cpu: "125m"     
    14         limits:
    15           memory: "64Mi"
    16           cpu: "250m"
    17     env:
    18     - name: MY_POD
    19       valueFrom:
    20         fieldRef:
    21            fieldPath: metadata.name
    22     - name: MY_POD_NAMESPACE
    23       valueFrom:
    24         fieldRef:
    25            fieldPath: metadata.namespace
    26     - name: MY_POD_IP
    27       valueFrom:
    28         fieldRef:
    29            fieldPath: status.podIP  
    30     - name: MY_POD_SERVICE_ACCOUNT
    31       valueFrom:
    32         fieldRef:
    33            fieldPath: spec.serviceAccountName
    34     - name: MY_CPU_REQUEST
    35       valueFrom:
    36         resourceFieldRef:
    37            containerName: my-pod
    38            resource: requests.cpu
    39     - name: MY_CPU_LIMIT
    40       valueFrom:
    41         resourceFieldRef:
    42            containerName: my-pod
    43            resource: limits.cpu
    44     - name: MY_MEM_REQUEST
    45       valueFrom:
    46         resourceFieldRef:
    47            containerName: my-pod
    48            resource: requests.memory
    49     - name: MY_MEM_LIMIT
    50       valueFrom:
    51         resourceFieldRef:
    52            containerName: my-pod
    53            resource: limits.memory
    54     command: ["/bin/sh","-c","while true;do sleep 5;done"]
    my_api.yaml

     解释:

    env:
        - name: MY_POD   定义的变量名字最好是大写
          valueFrom:     获取pod中的信息这个是固定的
            fieldRef:    获取pod中的信息这个是固定的
               fieldPath: metadata.name   获取pod中的信息这个是固定的

    定义普通变量:

    env:
        - name: MY_POD   定义的变量名字最好是大写
    value: "massage......" 变量的值

    端口:

    配置nginx

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4   name: my-nginx
     5   namespace: default
     6 spec:
     7   containers:
     8   - image: nginx
     9     imagePullPolicy: IfNotPresent
    10     name: nginx
    11     ports:  
    12     - name: web
    13       containerPort: 80   //容器内部端口
    14       protocol: TCP          //协议可选
    15       hostIP: 0.0.0.0      //worknodeIP可选,0.0.0.0就是任意选择
    16       hostPort: 8000     //worknode(宿主机)上的端口
    View Code

    提示:

    ports.name  这个值在pod中也是唯一的,当配置一个端口的时候是可选的,多个端口是必选。

    如果同时2个pod的的宿主机端口都是80那么k8s会将容器分别调度到没有占用80端口机器上启动

    数据持久化和共享

     1 piVersion: v1
     2 kind: Pod
     3 metadata:
     4    name: newhello
     5    namespace: default
     6 spec: 
     7   restartPolicy: Never
     8   containers:             
     9   - name: write
    10     image: "ubuntu:14.04"
    11     command: ["/bin/sh","-c","echo "hello word" >> /data/hello"]
    12     volumeMounts:
    13       - name: data             挂在下面定义卷data
    14         mountPath: /data    挂载到容器中的目录
    15   - name: read
    16     image: "ubuntu:14.04"
    17     command: ["bash","-c","sleep 10; cat /data/hello"]
    18     volumeMounts:
    19       - name: data
    20         mountPath: /data   
    21   volumes:         定义卷
    22   - name: data    卷名字
    23     hostPath:       宿主机
    24        path: /tmp    宿主机路径
    View Code

    查看结果

    [root@kubernetes-master pods]# kubectl logs newhello read
    hello word

    pod生命周期:

    1、 Pending:kubernetes已经开始创建Pod,但是Pod中的一个或多个容器还没有被启动。比如Pod正处在应该被分配到哪个节点上这个调度过程中,或者kubernetes还在从镜像仓库中下载Pod中容器镜像这个下载过程中。

    2、 Running:kubernetes已经将Pod分配到节点上,并且Pod中的所有容器都启动了。还包括Pod中至少有一个容器仍然在运行状态,或者正在重新启动状态。

    3、 Succeeded:Pod中的所有容器都处在终止状态,并且这些容器是自主正常退出到终止状态的,也就是退出代码为0,而且kubernetes也没有重启任何容器。

    4、 Failed:Pod中的所有容器都处在终止状态,并且至少有一个容器不是正常终止的,也就是退出代码不为0,或者是由于系统强行终止的。

    5、 Unknown:由于一些特殊情况无法获取Pod状态,比如由于网络原因无法同Pod所在的主机通讯。

    变量Phase的取值还取决于结构体PodSpec中的RestartPolicy变量,这个RestartPolicy变量是用来设置Pod中容器重启策略的,包括三个可选值,分别是Always、OnFailure和Never。

    这三个值得含义分别是:

    1、Always:表示对容器一直执行重启策略。如果不设置RestartPolicy,那么Always是默认值。

    2、OnFailure:表示在容器失败的时候重启容器。

    3、 Never:表示在对容器不执行重启策略。

     总结一下pod重启策略和容器退出后。pod状态

    pod生命周期回调

    主要作用就是在容器开始的时候做一个动作,容器停止的时候做一个动作

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4   name: javaweb2
     5   namespace: default
     6 spec:
     7   containers:
     8   - image:ubuntu:14.04
     9     name: war
    10     lifecycle:
    11        postStart:
    12             exec:
    13              command:
    14                 - "cp"
    15                 - "/sample.war"
    16                 - "/app"
    17        preStop:
    18            httpGet:
    19             host: monitor.com
    20             path: /warning
    21             port: 8080
    22             scheme: HTTP
    View Code

    PostStart:容器创建成功后回调

    PreStop :容器终止前回调

    自定义pod检查

    在很多实际场景下,仅仅使用进程级健康检查还远远不够。有时,从Docker的角度来看,容器进程依旧在运行;但是如果从应用程序的角度来看,代码处于死锁状态,即容器永远都无法正常响应用户的业务

      为了解决以上问题,Kubernetes引人了一个在容器内执行的活性探针(Liveness Probe)和(Readiness Probe)的概念,以支持用户自己实现应用业务级的健康检查。这些检查项由Kubelet代为执行,以确保用户的应用程序正确运转,至于什么样的状态才算“正确”,则由用户自己定义。

         1Liveness Probe 容器自定义检查,检查失败容器被杀死,然后根据pod重启策略来做

         2Readiness Probe 检查失败直接从代理后端移除,既不会分发请求给改pod。

    Kubernetes支持3种类型的应用健康检查动作,分别为HTTP Get、Container Exec和TCP Socket。个人感觉exec的方式还是最通用的,因为不是每个服务都有http服务,但每个服务都可以在自己内部定义健康检查的job,定期执行,然后将检查结果保存到一个特定的文件中,外部探针就不断的查看这个健康文件就OK了。

    HTTPget:

    path URL路径

    port 端口

    host 请求IP

    scheme:求情协议默认HTTP

    Kubelet将调用容器内Web应用的web hook,如果返回的HTTP状态码在200和399之间,则认为容器运转正常,否则认为容器运转不正常。每进行一次HTTP健康检查都会访问一次指定的URL。给出httpGet的简单示例如下:

     1 [root@k8s-master livenessProbe]# cat test-livenessprobe.yaml
     2 apiVersion: v1
     3 kind: Pod
     4 metadata:
     5   labels:
     6     name: test-livenessprobe
     7   name: test-livenessprobe
     8 spec:
     9   containers:
    10     - name: test-livenessprobe
    11       image: registry:5000/back_demon:1.0
    12       livenessProbe:
    13         httpGet:
    14           path: /starott_cloud_client/test/overview-frontend
    15           port: 8080
    16         initialDelaySeconds: 15
    17         periodSeconds: 5
    18         timeoutSeconds: 1
    19       command:
    20       - /run.sh
    HTTPGET

    TCP Socket:

    tcpSocket:

      port:8080

    检查tcp端口8080是否正常

    Exec:

    exec:

      command:

    这里拿exec做例子演示Liveness Probe和Readiness Probe区别:

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4   name: livemess-probe
     5   labels:
     6      test: liveness
     7 spec:
     8   containers:
     9   - name: libeness
    10     image: "ubuntu:14.04"
    11     command:
    12     - /bin/sh
    13     - -c 
    14     - echo ok > /tmp/health; sleep 30;rm -rf /tmp/health;sleep 600
    15     livenessProbe:
    16         exec:
    17           command:
    18           - cat
    19           - /tmp/health
    20         initialDelaySeconds: 15
    21         timeoutSeconds: 1
    livenessProbe

    注意看restarts数值

    30秒后容器重启了

    查看错误日志

    kubectl describe pod livemess-probe |grep Unhealthy

    Readiness Probe实验

    容器状态还是running但是k8s不会往这个pod上转发数据

    日志查询:

    一个pod中2个容器,一个正常退出一个异常退出。重启策略O:nFailure,异常退出时在重启容器

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4    name: logs-pod
     5    namespace: default
     6 spec: 
     7   restartPolicy: OnFailure
     8   containers:             
     9   - name: cont1
    10     image: "ubuntu:14.04"
    11     command: ["bash","-c","echo "cont1:`date --rfc-3339 ns`";exit 0"]
    12   - name: cont2
    13     image: "ubuntu:14.04"
    14     command: ["bash","-c","echo "cont2:`date --rfc-3339 ns`";exit 1"]
    logs-pod.yml

    查看容器1和容器2日志

    [root@kubernetes-master pods]# kubectl logs logs-pod cont1
    cont1:2017-07-11 13:15:41.122936441+00:00
    [root@kubernetes-master pods]# kubectl logs logs-pod cont2
    cont2:2017-07-11 13:21:40.452165906+00:00

    查看日志历史,有的时候会出现查询不到当前日志,我们就 可意查询上一次容器打的日志。加上这个--previous

    [root@kubernetes-master pods]# kubectl logs logs-pod cont2 --previous
    cont2:2017-07-11 13:21:40.452165906+00:00

    定义持久化日志

     1 apiVersion: v1
     2 kind: Pod
     3 metadata:
     4    name: logs-pod
     5    namespace: default
     6 spec: 
     7   restartPolicy: OnFailure
     8   containers:             
     9   - name: cont1
    10     terminationMessagePath: /dev/termination-log
    11     image: "ubuntu:14.04"
    12     command: ["bash","-c","echo "cont1:`date --rfc-3339 ns`" >> /dev/termination-log;"]
    View Code

    用到的参数terminationMessagePath:

    [root@kubernetes-master pods]# kubectl get pod logs-pod --template="{{range .status.containerStatuses}}{{.state.terminated.message}}{{end}}" --show-all
    cont1:2017-07-11 13:28:03.421374195+00:00

    远程连接容器

    1、exec(功能强大)

    2、attach(这个比较麻烦)

    远程执行命令并返回

    [root@kubernetes-master pods]# kubectl exec mysql -- date
    Tue Jul 11 13:42:44 UTC 2017

    进入pod容器

    [root@kubernetes-master pods]# kubectl exec -ti mysql  /bin/bash 

  • 相关阅读:
    java 实现前面带零的数字进行加减运算(保留前面的0)
    java 判断字符串是否是整数(纯数字:正整数、负整数、0)、至少包含一位小数、数字(可以是整数或小数)
    java 抽象类使用@Autowrited注入对象,子类直接使用父类的该属性
    java、springboot使用proguard混淆代码
    idea 使用阿里云仓库下载的jar包出现证书校验问题(PKIX:unable to find valid certification path to requested target)
    windows10安装zookeeper-3.6.2并生成zookeeper服务
    zookeeper-3.4.8 集群搭建
    zookeeper安装和使用 windows环境
    Dubbo入门---搭建一个最简单的Demo框架
    服务端高并发分布式架构演进之路
  • 原文地址:https://www.cnblogs.com/menkeyi/p/7134444.html
Copyright © 2011-2022 走看看