zoukankan      html  css  js  c++  java
  • 第五章 Kubernetes进阶之Pod

      Pod

    • 最小部署单元
    • 一组容器的组合
    • 一个Pod中容器共享网络命名空间
    • Pod是短暂的

      Pod容器分类

      Infrastructure Container 基础容器

        维护整个Pod网络空间

      InitContainers 初始化容器

        先于业务容器运行

      Container 业务容器

        并行启动

      镜像拉取策略

    • IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
    • Alway:每次创建Pod都会拉取一次镜像
    • Never:Pod永远不会拉取这个镜像

      查看默认镜像拉取参数是否是IfNotPresent

    kubectl get deploy/nginx-deployment -o yaml
    

     

       没有认证的公共镜像仓库可以直接拉取,搭建私有镜像仓库Habor

      本次搭建的主机为192.168.1.61,之前使用改主机搭建了nginx+keepalived为了不冲突需要关闭该主机的nginx即使用192.168.1.62来产生VIP192.168.1.60

      搭建参考

      https://www.cnblogs.com/minseo/p/8905736.html

      登录Harbor创建一个私有项目project

      默认用户名:admin 密码:Habor123456

     

       私有仓库需要登录才能下载,Harbor不是http提供访问,需要在node 192.168.1.65 192.168.1.66配置可信任

    # cat /etc/docker/daemon.json 
    {
              "registry-mirrors": ["https://7sl94zzz.mirror.aliyuncs.com"],
              "insecure-registries": ["192.168.1.61"]
    }
    

       node上面登录,输入用户名和密码

    docker login 192.168.1.61
    

     

       查看该node已有的镜像

    docker images
    

       下载一个tomcat镜像用于推送测试

    docker pull tomcat
    

       下载完毕打tag

    docker tag tomcat 192.168.1.61/project/tomcat
    

       查看

       推送至harbor私有仓库

    docker push 192.168.1.61/project/tomcat
    

     

       推送成功在harbor上可以看到

       排错,推送是出现提示,查看haabor该项目是否创建

    requested access to the resource is denied
    

       在另外一台node上拉取该镜像

    docker pull 192.168.1.61/project/tomcat
    

       PS:需要在该node节点至少登录过一次才能下载,否则会出现如下提示

     docker pull 192.168.1.61/project/tomcat
    Using default tag: latest
    Error response from daemon: pull access denied for 192.168.1.61/project/tomcat, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
    

       推送至harbor的镜像是私有的,如果是通过k8s部署则是拉取公网的镜像无法拉取到私有的镜像,需要通过配置imagePullSecrets参数才能从私有仓库拉取镜像

      示例

    # cat tomcat-deployment.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: tomcat
      name: tomcat
    spec:
      replicas: 3
      selector:
        matchLabels:
          run: tomcat
      template:
        metadata:
          labels:
            run: tomcat
        spec:
          containers:
          - image: tomcat
            name: tomcat
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        run: tomcat
      name: tomcat-service
    spec:
      ports:
      - port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        run: tomcat
      type: NodePort
    

       该yaml配置文件可以通过以下命令生成

    #生成deployment配置文件
     kubectl run tomcat --replicas=3 --image=tomcat --port=8080 --dry-run -o yaml>>tomcat-deployment2.yaml 
    #间隔符 多个配置需要间隔,否则创建时候部分不生效
    echo "---" >>tomcat-deployment2.yaml
    #生成service配置文件
    #生成该配置文件需要指定的deployment已经在运行中即要允许了命令 kubectl run tomcat --replicas=3 --image=tomcat --port=8080
    #可以先运行再删除该deployment
    kubectl expose deployment tomcat --port=8080 --type=NodePort --target-port=8080 --name=nginx-service --dry-run -o yaml >> tomcat-deployment.yaml 
    

       使用配置文件创建deployment和service

    # kubectl create -f tomcat-deployment.yaml 
    deployment.apps/tomcat created
    service/tomcat-service created
    

       查看

    # kubectl get pod,svc
    NAME                         READY   STATUS    RESTARTS   AGE
    pod/tomcat-5d6455cc4-lpwht   1/1     Running   0          36s
    pod/tomcat-5d6455cc4-wnfsh   1/1     Running   0          36s
    pod/tomcat-5d6455cc4-zgvbp   1/1     Running   0          36s
    
    NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    service/kubernetes       ClusterIP   10.10.10.1     <none>        443/TCP          6d2h
    service/tomcat-service   NodePort    10.10.10.105   <none>        8080:37426/TCP   36s
    

       通过node ip加NodePort端口即可访问tomcat默认页面

      配置文件指定镜像是从docker hub拉取的,现在改成私有镜像的地址,因为默认的策略是优先拉取本机已有镜像所以拉取镜像策略改成Always

      修改yaml配置文件,修改以下两处

       应用更新

    # kubectl apply -f tomcat-deployment.yaml 
    deployment.apps/tomcat configured
    service/tomcat-service unchanged
    

     

       查看pod事件

    kubectl describe pod tomcat-78876547c6-jn7c4
    

     

       需要配置凭据才能拉取

      在已经docker login过的node上面获取

    cat /root/.docker/config.json | base64 -w0
    

     

       复制这串字符编辑配置文件

    #cat registry-pull-secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: registry-pull-secret
    data:
      .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuNjEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuNiAobGludXgpIgoJfQp9
    type: kubernetes.io/dockerconfigjson
    

       应用

    # kubectl create -f registry-pull-secret.yaml 
    secret/registry-pull-secret created
    

       查看已经生成secret

    # kubectl get secret
    NAME                   TYPE                                  DATA   AGE
    default-token-pw8st    kubernetes.io/service-account-token   3      6d2h
    registry-pull-secret   kubernetes.io/dockerconfigjson        1      22s
    

       修改tomcat-deployment.yaml增加认证

       修改后完整的yaml文件如下

    # cat tomcat-deployment.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: tomcat
      name: tomcat
    spec:
      replicas: 3
      selector:
        matchLabels:
          run: tomcat
      template:
        metadata:
          labels:
            run: tomcat
        spec:
          imagePullSecrets: 
          - name: registry-pull-secret
          containers:
          - image: 192.168.1.61/project/tomcat
            imagePullPolicy: Always
            name: tomcat
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        run: tomcat
      name: tomcat-service
    spec:
      ports:
      - port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        run: tomcat
      type: NodePort
    

       应用更改

    kubectl apply -f tomcat-deployment.yaml
    

       查看

    # kubectl get pod,svc
    NAME                          READY   STATUS    RESTARTS   AGE
    pod/tomcat-68c76b858d-5lq22   1/1     Running   0          4m41s
    pod/tomcat-68c76b858d-ckrqr   1/1     Running   0          4m45s
    pod/tomcat-68c76b858d-dctgt   1/1     Running   0          4m43s
    
    NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    service/kubernetes       ClusterIP   10.10.10.1     <none>        443/TCP          6d3h
    service/tomcat-service   NodePort    10.10.10.105   <none>        8080:37426/TCP   29m
    

       因为镜像拉取策略是Always所以从pod的运行时间即可看出是否拉取了私有仓库的镜像

      登录Harbor查看也可以看到本次拉取镜像是从私有仓库拉取

     

       拍错:访问tomcat出现404错误提示,原因是tomcat镜像根目录没有文件,解决办法

    #分别进入容器
    kubectl exec -it tomcat-68c76b858d-5lq22 -c tomcat bash
    kubectl exec -it tomcat-68c76b858d-ckrqr -c tomcat bash
    kubectl exec -it tomcat-68c76b858d-dctgt -c tomcat bash
    #复制根目录文件,默认webapps为空
    cd /usr/local/tomcat
    rm -rf webapps
    mv webapps.dist/ webapps
    

      资源限制

      为了防止某个Pod占用资源过多影响宿主机需要对Pod进行资源限制

      Pod中的每个容器都可以指定一下一个或者多个值

    spec.containers[].resources.limits.cpu
    spec.containers[].resources.limits.memory
    spec.containers[].resources.requests.cpu
    spec.containers[].resources.requests.memory
    

       示例,该示例可以在官方复制https://kubernetes.io/zh/docs/concepts/configuration/manage-compute-resources-container/

      以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。

    # cat pod2.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend
    spec:
      containers:
      - name: db
        image: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
      - name: wp
        image: wordpress
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
    

       查看该pod分配到那一台node

    kubectl describe pod frontend
    

     

       查看资源限制是否生效

    kubectl describe nodes 192.168.1.66
    

     

       Pod重启策略

      restartPolicy

    • Always:当容器终止退出后,总是重启容器,默认策略
    • OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
    • Never:当容器终止退出,从不重启容器

      查看

    kubectl edit pods nginx-7cdbd8cdc9-ngpgr
    

     

       示例

    # cat pod3.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: foo
    spec:
      containers:
      - name: busybox
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 30 ; exit 3
    

       该yaml执行进入容器后等待30秒退出

      应用

    kubectl apply -f pod3.yaml
    

       查看pod会从running状态,到退出会提示错误状态,因为策略是Always所以又重启一次 

     

       修改

    apiVersion: v1
    kind: Pod
    metadata:
      name: foo
    spec:
      containers:
      - name: busybox
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 10
      restartPolicy: Never
    

       删除再应用

    kubectl delete -f pod3.yaml
    kubectl apply -f pod3.yaml 
    

       查看状态,容器运行10秒以后正常退出了,策略为Never所以不再新启动一个pod 状态显示完成状态

       健康检查

      Probe有以下两种类型

      livenessProbe

      如果检查失败,将杀死容器,根据Pod的restartPolicy来操作

      readinessProbe 

      如果检查失败,Kubernetes会把Pod从service endpoint中剔除

      查看endpoint使用命令

    # kubectl get ep
    NAME             ENDPOINTS                                            AGE
    kubernetes       192.168.1.63:6443,192.168.1.64:6443                  6d4h
    tomcat-service   172.17.41.4:8080,172.17.55.2:8080,172.17.55.5:8080   131m
    

       Probe支持以下三种检查方法

      HttpGet

      发送HTTP请求,返回200-400范围状态码为成功

      exec

      执行shell命令返回状态码是0为成功

      tcpSocket

      发起TCP Socket建立成功

      官方示例 下载地址https://kubernetes.io/zh/docs/concepts/configuration/manage-compute-resources-container/

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: liveness-exec
    spec:
      containers:
      - name: liveness
        image: busybox
        args:
        - /bin/sh
        - -c
        - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          #启动延时5秒以后开始健康检查
          initialDelaySeconds: 5
          #健康检查周期是5秒
          periodSeconds: 5
    

       应用

    kubectl apply -f pod4.yaml
    

       启动后创建了健康检查文件,等待30秒以后,删除了健康检查文件,健康检查没有发现该文件就重启容器了

       查看pod的描述日志

       企业生产环境中需要配置健康检查

      Pod调度约束

      可以让Pod放在指定节点上,例如A部门创建的Pod放在一台node,B部门创建的Pod放在另一台node

      用户创建Pod过程

       nodeName用于将Pod调度到指定的Node名称上

      nodeSelector用于将Pod调度到匹配Label的Node上

    #cat pod5.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-example
      labels:
        app: nginx
    spec:
      nodeName: 192.168.1.65
      containers:
      - name: nginx
        image: nginx
    

     

       设置标签

    #设置标签
    kubectl label nodes 192.168.1.65 team=a
    kubectl label nodes 192.168.1.66 team=b
    #查看标签
    kubectl get nodes --show-labels
    

      删除标签

    #在标签后加-号即可删除标签
    kubectl label nodes 192.168.1.65 team-
    kubectl label nodes 192.168.1.66 team-
    

     

       在yaml文件里面设置标签

    # cat pod6.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-example
      labels:
        app: nginx
    spec:
      nodeSelector:
        team: b
      containers:
      - name: nginx
        image: nginx
    

       应用

    kubectl apply -f pod6.yaml
    

       查看

       PS:如果调度约束配置不正确Pod会出现Pending状态查看描述会出现以下错误提示

    Warning  FailedScheduling  27s (x2 over 27s)  default-scheduler  0/2 nodes are available: 2 node(s) didn't match node selector.
    

       故障排查

    值  描述
    Pending Pod创建已经提交k8s,但是因为,某种原因不能顺利创建。例如下载镜像慢,调度不成功
    Running Pod已经绑定到一个节点,并且已经创建了所有容器。至少有一个容器在运行,或正在启动或重启
    Suceeded Pod中所有容器都已成功终止,不会重新启动
    Failed Pod中所有容器已终止,且至少有一个容器已在故障中终止,也就是说,容器要么已非零状态退出,要么被系统终止
    Unknown 由于某种原因apiserver无法获取Pod的状态,通常是由于master与pod所在主机kubelet通信时出错

      故障排查命令

    #查看pod事件
    kubectl describe TYPE/NAME
    #查看pod日志
    kubectl logs TYPE/NAME 
    #登录容器查看
    kubectl exec POD [-c CONTAINER] -- COMMAND [args...]
    

      

      

  • 相关阅读:
    网站宣传【免费】
    gridview行链接
    提前预告
    C#中var、int、object性能比较
    20部软件测试视频教程整合
    PO、VO、DTO、POJO
    云计算、虚拟化、容器
    Linux打包和压缩的区别
    Linux之Shell定时备份数据库
    luogu P1997 faebdc的烦恼 | 莫队
  • 原文地址:https://www.cnblogs.com/minseo/p/12411241.html
Copyright © 2011-2022 走看看