大家好,我是Linux运维工程师 Linke 。技术过硬,从不挖坑~

k8s启动容器,一定要理解 namespace 、deployment 、 pod 、container 、service 、labels 之间的关系,大体关系是这样的。

namespace 就好比是一个大的分组,一个k8s集群内可以创建多个namespace ,在它之下才能创建deployment ,然后在 deployment 之下可以启动多个名字一样的 pod(名字一样,id不同,pod全名是pod名加id组成的) ,在一个pod内可以启动多个 container ,一般情况下,一个pod内只跑一个容器,有些特殊的场景才会在pod内启动多个容器;创建了 service 可以将 pod 对 k8s 集群内进行dns解析,并且提供负载均衡能力,同一个namespace下的service可以直接使用 service名字进行解析,不同namespace执行的 service 需要加上 servicename.namespace 才能解析,并且,要解析service的话,只能在pod的容器内进行,容器之外无法解析。

最危险的操作是删除namespace,删除了这个的话,它下面的所有东西全部将被删除,所以namespace 、service 、pod 的yaml文件一定要分类放好,三者各自放在自己的目录中。

k8s各namespace之下的 pod 的 ip 在集群内可以直接通信。


进入正题

以下是namespace的 yaml 文件
kind 指定文件类型为 Namespace
metadata 下定义 Namespace 名字为 product ,给这个 Namespace 定义一个 labels 为 name=product

cat >> product_namespaces.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:
   name: product
   labels: 
     name: product
EOF

启动Namespace并查看

kubectl create -f product_namespaces.yaml
kubectl get namespaces

以下是我在生产环境的 pod 的yaml 文件,差不多已经很完善了。经过了一年多的不断完善。


创建 Deployment / pod 的 yaml 配置文件

cat >> app_aas.yaml << EOF
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: aas
  namespace: product
  labels:
    app: aas
spec:
  selector:
    matchLabels:
      app: aas
  revisionHistoryLimit: 5
  replicas: 2
  minReadySeconds: 60
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: aas 
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - aas
            topologyKey: kubernetes.io/hostname
      terminationGracePeriodSeconds: 60
      imagePullSecrets:
      - name: resecret-product
      nodeSelector:
        apptype: memnode
      containers:
      - name: aas 
        readinessProbe:
          httpGet:
            path: /aas/
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 80
          timeoutSeconds: 20
        livenessProbe:
          httpGet:
            path: /aas/
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 80
          timeoutSeconds: 20
        env:
        - name: JAVA_OPTS
          value: "-Xms1024M -Xmx1024M -server -Duser.timezone=GMT+08"
        image: registry.test.com/appimage/aas:AAS.01.00.001.release
        resources:
          limits:
            cpu: "600m"
            memory: 2048Mi
          requests:
            cpu: "300m"
            memory: 1280Mi
        volumeMounts:
        - mountPath: /etc/localtime
          readOnly: false
          name: localtime
        - mountPath: /home/gooagoo/config
          readOnly: false
          name: appconfig
        - mountPath: /home/gooagoo/resource
          readOnly: false
          name: appresource
        - mountPath: /home/gooagoo/log
          readOnly: false
          name: log
        - mountPath: /opt/tomcat/logs
          readOnly: false
          name: tomcatlog
        - mountPath: /mnt/mfs
          readOnly: false
          name: mnt
        
      volumes:
      - name: "localtime"
        hostPath:
          path: "/etc/localtime"
          type: File
      - name: "tomcatlog"
        hostPath:
          path: "/home/app/log/aas/tomcatlogs"
      - name: "log"
        hostPath:
          path: "/home/app/log/aas"
      - name: "appconfig"
        hostPath:
            path: "/home/app/config"
      - name: "appresource"
        hostPath:
            path: "/home/app/resource"
      - name: "mnt"
        flexVolume:
          driver: "alicloud/nas"
          options:
            server: "15123496df-bee90.cn-beijing.nas.aliyuncs.com"
            path: "/"
            vers: "4.0"
EOF

创建deployment 和 pod
查看deploy
查看pod

kubectl create -f app_aas.yaml
kubectl get deploy -n product
kubectl get pod -n product

详解:

api版本

apiVersion: extensions/v1beta1

类型为Deployment文件

kind: Deployment

定义Deployment名称、所属namespace、Deployment 的 labels名称

metadata:
  name: aas
  namespace: product
  labels:
    app: aas

最外层的spec下的内容定义了pod启动、更新的规则
定义 pod 启动在 labels 为 aas 的 Deployment 内

spec:
  selector:
    matchLabels:
      app: aas

指定可以列出pod的历史版本个数为 5 个、pod副本为2个、滚动更新间隔为60s 、每次最多更新1个

  revisionHistoryLimit: 5
  replicas: 2
  minReadySeconds: 60
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

定义pod的 labels 名称为 aas

  template:
    metadata:
      labels:
        app: aas 

第二层spec内定义pod的详细启动参数
防止带有相同 labels 的pod 不能启动到一个节点,避免相同应用启动到同一个节点,节点挂掉后,应用不能提供服务,生成环境建议必须要加这个。terminationGracePeriodSeconds官方解释为优雅的关闭pod,我的理解是就好比是 kill 命令不带 -9 ,最大限时为 60s ,超过时间后则强制杀掉 pod。

    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - aas
            topologyKey: kubernetes.io/hostname
      terminationGracePeriodSeconds: 60

启动pod所使用的镜像时私有docker仓库的话,使用自建的 Secrets 名称为 resecret-product 的授权拉取站点镜像,如何创建 secrets ,请参考文档: k8s创建secret,拉取私有仓库的镜像;并且pod只能分配到 labels 的键值为 apptype=memnode 的节点上,如何创建节点的 labels ,请参考文档:kubernetes调度pod到指定节点

      imagePullSecrets:
      - name: resecret-product
      nodeSelector:
        apptype: memnode

指定容器的基础名称为 aas(启动pod后,容器的名称会在指定的 aas 后拼接上随机字符串做为pod实现名称)
readinessProbe:pod创建后,第一次执行探测是需要等待80s,探测超时时间为20s,如果80s后探测健康接口超时时间超过20s,那么pod内的容器应用程序将重启。以下定义的探测接口是 http 请求,整体接口是这样的: http://容器ip:8080/aas/ ,如果在 20s内返回 200 状态码,认为pod启动成功。
livenessProbe: 每隔 80s 探测一次容器内的这个 http 健康接口,如果在 20s内返回 200 状态码,认为pod可以正常工作,否则pod内的容器程序将重启。

      containers:
      - name: aas 
        readinessProbe:
          httpGet:
            path: /aas/
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 80
          timeoutSeconds: 20
        livenessProbe:
          httpGet:
            path: /aas/
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 80
          timeoutSeconds: 20

env:启动容器时,向容器内传入环境变量名称为JAVA_OPTS,变量值为-Xms1024M -Xmx1024M -server -Duser.timezone=GMT+08 ,如果你打镜像时就定义了环境变量,那么这个会覆盖掉原来的环境变量
image:使用镜像 registry.test.com/appimage/aas:AAS.01.00.001.release 启动

        env:
        - name: JAVA_OPTS
          value: "-Xms1024M -Xmx1024M -server -Duser.timezone=GMT+08"
        image: registry.test.com/appimage/aas:AAS.01.00.001.release

requests:pod启动时,直接给容器中的系统分配 300m 的cpu (容器内使用的cpu是宿主机的逻辑核数,每核cpu使用一点cpu,加起来一共只能使用300m,1000m为1核),1024m的内存。
limits: pod启动后,最多可以消耗300m的cpu,最多可以消耗宿主机1280m内存。

        resources:
          limits:
            cpu: "300m"
            memory: 1280Mi
          requests:
            cpu: "300m"
            memory: 1024Mi

volumeMounts:指定将要挂载到容器内的文件或者目录的路径,readOnly为true时,挂载到容器内的文件或目录为只读权限
volumes:挂载到容器内的路径在宿主机对应的路径
flexVolume : 挂载阿里云 nas 的方式,挂载nas,需要在宿主机安装 nfs 客户端才行。

        volumeMounts:
        - mountPath: /etc/localtime
          readOnly: false
          name: localtime
        - mountPath: /home/gooagoo/config
          readOnly: false
          name: appconfig
        - mountPath: /home/gooagoo/resource
          readOnly: false
          name: appresource
        - mountPath: /home/gooagoo/log
          readOnly: false
          name: log
        - mountPath: /opt/tomcat/logs
          readOnly: false
          name: tomcatlog
        - mountPath: /mnt/mfs
          readOnly: false
          name: mnt
      volumes:
      - name: "localtime"
        hostPath:
          path: "/etc/localtime"
          type: File
      - name: "tomcatlog"
        hostPath:
          path: "/home/gooagoo/log/aas/tomcatlogs"
      - name: "log"
        hostPath:
          path: "/home/gooagoo/log/aas"
      - name: "appconfig"
        hostPath:
            path: "/home/gooagoo/config"
      - name: "appresource"
        hostPath:
            path: "/home/gooagoo/resource"
      - name: "mnt"
        flexVolume:
          driver: "alicloud/nas"
          options:
            server: "23fd346df-fds10.cn-beijing.nas.aliyuncs.com"
            path: "/"
            vers: "4.0"

以下是启动service使用的配置文件
文件详解:
kind 指定文件为 Service
metadata指定service名字为 aas ,在 product 的 namespace 中创建
spec下的内容为开放 service 的 8080 端口(pod内容器对外的什么端口,这里就用什么端口,它将直接映射在pod中),并且代理labels是 app=aas 的 pod
如上所说,要使用service名字 aas 找到 pod ,只能在 启动 pod 的容器中才能解析出来。

cat >> aas_service.yaml  << EOF
apiVersion: v1
kind: Service
metadata:
  name: aas
  namespace: product
spec:
  ports:
  - port: 8080
  selector:
    app: aas
EOF

创建service 和查看 servic

kubectl create -f  aas_service.yaml
kubectl get svc -n product

如果pod或者service已经创建,修改了yaml文件后,需要重读 yaml 文件的话,可以用下面的命令

kubectl apply -f app_aas.yaml
kubectl apply -f aas_service.yaml

使用 app_aas.yaml 文件删除 deploy 和 pod(删除service、namespace同理,但是删除namespace的话,下面的所有东西都会被删除,所以namespace创建后,一般就不会再动了)

kubectl delete -f app_aas.yaml

如果删除了yaml文件的话,要删除pod的话,有两种方式,直接删除pod会自动再创建,需要删除deploy后,pod 才不会自动再创建
删除pod,自动创建,可以把这个功能当做重新分配pod到k8s工作节点(一定要指定命名空间,即namespace)

kubectl delete po aas-6a5s2gf43dg34 -n product

不使用 yaml 文件永久删除的话,请直接删除deploy

kubectl delete deploy aas -n product

不使用 yaml 文件永久删除service

kubectl delete -f svc aas -n product
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐