手把手带你玩转k8s-常用对象详解

2,227 阅读7分钟

前言

经过前面几篇文章的实战案例,相信我们对k8s是如何部署应用也有了一定的了解。虽然部署的模板并不一定是最优的,但是基本上能解决大多数应用的部署问题。本文会着重讲解一下前几篇文章用到的Kubernetes 对象。

常用对象详解

当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl),API 请求必须在请求体中包含 JSON 格式的信息。 大多数情况下,需要在 .yaml 文件中为 kubectl 提供这些信息kubectl 在发起 API 请求时,将这些信息转换成 JSON 格式。

必需字段

在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类型
    • ConfigMap
    • PersistentVolume
    • PersistentVolumeClaim
    • Deployment
    • Service
    • Ingress
    • StorageClass(存储类,本文新增)
  • metadata - 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-cm
  namespace: mldong-test
data:
  a.conf: |-
    server {
      listen       80;
      server_name  a.mldong.com;
      location / {
        root   /usr/share/nginx/html/a;
        index  index.html index.htm;
      }
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
        root   /usr/share/nginx/html;
      }
    }
  b.conf: |-
    server {
      listen       80;
      server_name  b.mldong.com;
      location / {
        root   /usr/share/nginx/html/b;
        index  index.html index.htm;
      }
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
        root   /usr/share/nginx/html;
      }
    }
    

在该例中:

  • 将在命名空间mldong-test,由.metadata.namespace字段指示。
  • 创建名为 nginx-cmConfigMap ,由 .metadata.name字段指示。
  • 创建了两个配置文件a.confb.conf,由.data字段指示,key-value的方式,key对应的是文件名,value对应的是文件内容
  • 定义好的ConfigMap可由Deployment.template.spec.volumes[].name指定

PersistentVolume

PersistentVolume(PV)用于为用户和管理员提供如何提供和消费存储的API,PV由管理员在集群中提供的存储。它就像Node一样是集群中的一种资源。PersistentVolume 也是和存储卷一样的一种插件,但其有着自己独立的生命周期。PersistentVolumeClaim (PVC)是用户对存储的请求,类似于Pod消费Node资源,PVC消费PV资源。Pod能够请求特定的资源(CPU和内存),声明请求特定的存储大小和访问模式。PV是一个系统的资源,因此没有所属的命名空间。

生命周期

  • 供应(Provisioning):即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建
  • 绑定(Binding):将PV分配给PVC
  • 使用(Using):Pod通过PVC使用该Volume
  • 释放(Releasing):Pod释放Volume并删除PVC
  • 回收(Reclaiming):回收PV,可以保留PV以便下次使用,也可以直接从云存储中删除
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
  labels:
    alicloud-pvname: nginx-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  csi:
    driver: nasplugin.csi.alibabacloud.com
    volumeHandle: nginx-pv
    volumeAttributes:
      server: "9fdd94bf87-wfq66.cn-zhangjiakou.nas.aliyuncs.com"
      path: "/"
      vers: "3"
  storageClassName: nas

在该例中:

  • 创建名为 nginx-pvPersistentVolume ,由 .metadata.name字段指示。
  • 创建一个大小为5G的卷,由.spec.capacity.storage字段指示。
  • 该卷可进行读写,由``.spec.accessModes`字段指示
    • ReadWriteOnce:可以被一个node读写。缩写为RWO。
    • ReadOnlyMany:可以被多个node读取。缩写为ROX。
    • ReadWriteMany:可以摆多个node读写。缩写为RWX。
  • 使用的存储类为nas,csi插件由阿里提供,可参考阿里官方文档。

PersistentVolumeClaim

先略吧--后续存储卷开个单章来讲。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: 'yes'
    pv.kubernetes.io/bound-by-controller: 'yes'
  finalizers:
    - kubernetes.io/pvc-protection
  name: nginx-pvc
  namespace: mldong-test
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      alicloud-pvname: nginx-pv
  storageClassName: nas
  volumeMode: Filesystem
  volumeName: nginx-pv

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: mldong-test
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/nginx:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              name: port
              protocol: TCP
          volumeMounts:
            - name: nginx-pvc
              mountPath: "/usr/share/nginx/html"
            - name: nginx-cm
              mountPath: "/etc/nginx/conf.d"
      volumes:
        - name: nginx-pvc
          persistentVolumeClaim: 
            claimName: nginx-pvc
        - name: nginx-cm
          configMap:
            name: nginx-cm

在该例中:

  • 将在命名空间mldong-test,由.metadata.namespace字段指示。
  • 创建名为 nginxDeployment ,由 .metadata.name字段指示。
  • Deployment 创建3个复制的 Pods,由 replicas 字段指示。
  • selector 字段定义 Deployment 如何查找要管理的 Pods。 在这种情况下,只需选择在 Pod 模板(app: nginx)中定义的标签。但是,更复杂的选择规则是可能的,只要 Pod 模板本身满足规则。
  • template 字段包含以下子字段:
  • Pod 标记为app: nginx,使用labels字段。
  • Pod 模板规范或 .template.spec 字段指示 Pods 运行一个容器, nginx,运行 nginx 私有镜像仓库版本latest的镜像 。
  • 创建一个容器并使用name字段将其命名为 nginx
  • 镜像拉取策略为IfNotPresent,由字段.template.spec.containers.imagePullPolicy指示
    • IfNotPresent:如果不存在则拉取
    • Always:总是拉取pull
    • Never:只使用本地镜像,从不摘取
  • 创建容器对外暴露的端口为80,由字段``.template.spec.containers.ports[].containerPort`指示
  • 创建容器挂载了两个目录/usr/share/nginx/html/etc/nginx/conf.d,由.template.spec.containers.volumeMounts[]指示,其中name对应的是.template.spec.volumes中的name,而volumes的定义会有多种方式,如configMappersistentVolumeClaim等。

当前,除了上述定义,可能还会用到其他的,比如

  • 环境变量.template.spec.containers.env
  • 启动命令.template.spec.containers.command
  • 服务存活监测.template.spec.containers.livenessProbe
  • 资源定义限制.template.spec.containers.resources
  • 等等

Service

服务访问方式

ClusterIP方式

用于为集群内Pod访问时,提供的固定访问地址,默认是自动分配地址,可使用ClusterIP关键字指定固定IP.

  • 将在命名空间mldong-test,由.metadata.namespace字段指示。
  • 创建名为nginxService,由.metadata.name字段指示
  • 类型为ClusterIP的服务,由.spec.type字段指示
  • 对应着容器的端口为80,由.spec.ports[].targetPort字段指示
  • 指定标签选择器选择的标签范围为app:nginx,由.spec.selector指示,对应的Deployment.template.metadata.labels
  • 使用该方式指定的服务,可以用过http://nodeIP:nodePort的方式访问
  • 其中
    • 可通过命令获取nodeport kubectl get svc -n mldong-test
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: mldong-test
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

NodePort方式

用于为集群外部访问Service后面Pod提供访问接入端口

这种类型的service工作流程为:       Client----->NodeIP:NodePort----->ClusterIP:ServicePort----->PodIP:ContainerPort

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
  namespace: mldong-test
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    # nodePort: 32180 # 这里不指定就会随机(30000-32767)
  selector:
    app: nginx

在该例中:

  • 将在命名空间mldong-test,由.metadata.namespace字段指示。
  • 创建名为nginx-nodeportService,由.metadata.name字段指示
  • 类型为NodePort的服务,由.spec.type字段指示
  • 对应着容器的端口为80,由.spec.ports[].targetPort字段指示
  • 指定标签选择器选择的标签范围为app:nginx,由.spec.selector指示,对应的Deployment.template.metadata.labels
  • 使用该方式指定的服务,可以用过http://nodeIP:nodePort的方式访问
  • 其中
    • 可通过命令获取节点ip kubectl get nodes
    • 可通过命令获取nodeport kubectl get svc -n mldong-test

Ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管

 internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
  name: nginx-ingress
  namespace: mldong-test
spec:
  rules:
    - host: a.mldong.com
      http:
        paths:
          - backend:
              serviceName: nginx
              servicePort: 80
            path: /
    - host: b.mldong.com
      http:
        paths:
          - backend:
              serviceName: nginx
              servicePort: 80
            path: /

在该例中:

  • 将在命名空间mldong-test,由.metadata.namespace字段指示。
  • 创建名为nginx-ingressIngress,由.metadata.name字段指示

每个 HTTP 规则都包含以下信息:

  • 可选主机。在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。如果提供了主机(例如 a.mldong.com和b.mldong.com),则规则适用于该主机。
  • 路径列表(例如,/),每个路径都有一个由 serviceNameservicePort 定义的关联后端。在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
    • serviceName对应的.Service.metadata.name
    • servicePort对应的.Service.spec.ports[].port

查看命令

kubectl get ingress -n mldong-test

结果中的ADDRESS即为域名解析的IP(阿里云这个值是空的,其为负载均衡器绑定的ip),如果在内网内,可以通过配置/etc/hosts,添加如下记录

IP a.mldong.com
IP b.mldong.com

即可通过如下方式访问服务

curl a.mldong.com
curl b.mldong.com

小结

唉,纯写文,我果然不是很擅长,后面再慢慢练吧。

相关文章

手把手带你玩转k8s-集群创建和Hello World

手把手带你玩转k8s-ConfigMap与持久化存储

手把手带你玩转k8s-完整的发布一个可对外访问的服务

手把手带你玩转k8s-docker进阶Dockerfile与docker-compose

手把手带你玩转k8s-一键部署springboot项目

手把手带你玩转k8s-一键部署vue项目