Kubernetes学习-相关概念

Kubernetes架构图php

上图能够看到以下组件,使用特别的图标表示Service和Label:html

    • Pod
    • Container(容器)
    • Label(label)(标签)
    • Replication Controller(复制控制器)
    • Service(enter image description here)(服务)
    • Node(节点)
    • Kubernetes Master(Kubernetes主节点)

Pod

  Pod 是Kubernetes的基本操做单元,也是应用运行的载体。整个Kubernetes系统都是围绕着Pod展开的,好比如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。另外,Pod是一个或多个机关容器的集合,提供了一种容器的组合的模型。前端

 Pod(上图绿色方框)安排在节点上,包含一组容器和卷。同一个Pod里的容器共享同一个网络命名空间,可使用localhost互相通讯。Pod是短暂的,不是持续性实体。node

    • Pod是短暂的,pod重建的时候数据会丢失对于须要持久化的数据,由于Kubernetes支持的概念,故可使用持久化的卷类型。这样就能持久化容器数据使其可以跨重启而存在。
    • 建立Pod时能够手动建立单个Pod,也可使用Replication Controller使用Pod模板建立出多份拷贝。
    • Pod是短暂的,那么重启时IP地址可能会改变,那么怎么才能从前端容器正确可靠地指向后台容器呢?这时可使用Service。

   Pods提供两种共享资源:网络和存储。
网络:
  每一个Pod被分配一个独立的IP地址,Pod中的每一个容器共享网络命名空间,包括IP地址和网络端口。
  Pod内的容器可使用localhost相互通讯。
  当Pod中的容器与Pod 外部通讯时,他们必须协调如何使用共享网络资源(如端口)。
存储:
  Pod能够指定一组共享存储volumes。
  Pod中的全部容器均可以访问共享volumes,容许这些容器共享数据。
  volumes 还用于Pod中的数据持久化,以防其中一个容器须要从新启动而丢失数据。mysql

 

  • 基本操做

  建立  kubectl create -f xxx.yamlnginx

  查询  kubectl get pod yourPodName  kubectl describe pod yourPodNamegit

  删除  kubectl delete pod yourPodNamegithub

  更新  kubectl replace /path/to/yourNewYaml.yamlweb

  •  Pod与容器

  在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod能够认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又是共享的(包括PID、Network、IPC、UTS)。除此以外,Pod中的容器能够访问共同的数据卷来实现文件系统的共享。redis

  • Pod与Controller

  Controller能够建立和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。若是一个Node故障,Controller就能自动将该节点上的Pod调度到其余健康的Node上。

  • 镜像

  在kubernetes中,镜像的下载策略为:

    Always:每次都下载最新的镜像

    Never:只使用本地镜像,从不下载

    IfNotPresent:只有当本地没有的时候才下载镜像

  Pod被分配到Node以后会根据镜像下载策略进行镜像下载,能够根据自身集群的特色来决定采用何种下载策略。不管何种策略,都要确保Node上有正确的镜像可用。

  •  其余

  经过yaml文件,能够在Pod中设置:

    启动命令,如:spec-->containers-->command;

    环境变量,如:spec-->containers-->env-->name/value;

    端口桥接,如:spec-->containers-->ports-->containerPort/protocol/hostIP/hostPort(使用hostPort时须要注意端口冲突的问题,不过Kubernetes在调度Pod的时候会检查宿主机端口是否冲突,好比当两个Pod均要求绑定宿主机的80端口,Kubernetes将会将这两个Pod分别调度到不一样的机器上);

    Host网络,一些特殊场景下,容器必需要以host方式进行网络设置(如接收物理机网络才可以接收到的组播流),在Pod中也支持host网络的设置,如:spec-->hostNetwork=true;

    数据持久化,如:spec-->containers-->volumeMounts-->mountPath;

    重启策略,当Pod中的容器终止退出后,重启容器的策略。这里的所谓Pod的重启,实际上的作法是容器的重建,以前容器中的数据将会丢失,若是须要持久化数据,那么须要使用数据卷进行持久化设置。Pod支持三种重启策略:Always(默认策略,当容器终止退出后,老是重启容器)、OnFailure(当容器终止且异常退出时,重启)、Never(从不重启);

  •  Pod生命周期

  Pod被分配到一个Node上以后,就不会离开这个Node,直到被删除。当某个Pod失败,首先会被Kubernetes清理掉,以后ReplicationController将会在其它机器上(或本机)重建Pod,重建以后Pod的ID发生了变化,那将会是一个新的Pod。因此,Kubernetes中Pod的迁移,实际指的是在新Node上重建Pod。

 

Replication Controller

  Replication Controller确保任意时间都有指定数量的Pod“副本”在运行。若是为某个Pod建立了Replication Controller而且指定3个副本,它会建立3个Pod,而且持续监控它们。若是某个Pod不响应,那么Replication Controller会替换它。

  当建立Replication Controller时,须要指定两个东西:

    1. Pod模板:用来建立Pod副本的模板
    2. Label:Replication Controller须要监控的Pod的标签。RC与Pod的关联是经过Label来实现的。

  使用过程:

  1.   rc.yaml文件

 

apiVersion: v1
kind: ReplicationController
metadata:      #设置rc的元数据
  name: frontend
  labels:
    name: frontend
spec:
  replicas: 3    #设置Pod的具体数量
  selector:    #经过selector来匹配相应的Pod的label
    name: frontend
  template:    #设置Pod的模板
    metadata:
     labels:
       name: frontend
    spec:
     containers:
     - name: frontend
       image: kubeguide/guestbook-php-frontend:latest
    imagePullPolicy: IfNotPresent     #镜像拉取策略,分为Always,Never,IfNotPresent,默认是Always env : - name : GET_HOSTS_FROM value : env ports: - containerPort: 80

yaml字段的含义: 
spec.replicas:副本数量3 
spec.selector:RC经过spec.selector来筛选要控制的Pod 
spec.template:这里写Pod的定义(但不须要apiVersion和kind) 
spec.template.metadata.labels:Pod的label,能够看到这个label与spec.selector相同

这个文件的意思: 
定义一个RC对象,它的名字是frontend(metadata.name:frontend),保证有3个Pod运行(spec.replicas:3),Pod的镜像是kubeguide/guestbook-php-frontend:latest(spec.template.spec.containers.image:kubeguide/guestbook-php-frontend:latest)

  1. 关键在于spec.selector与spec.template.metadata.labels,这两个字段必须相同,不然下一步建立RC会失败。(也能够不写spec.selector,这样默认与spec.template.metadata.labels相同)

RC的经常使用操做命令:

    经过kubectl建立RC

    # kubectl create -f rc.yaml

    查看RC具体信息

    # kubectl describe rc frontend

    经过RC修改Pod副本数量(须要修改yaml文件的spec.replicas字段到目标值,而后替换旧的yaml文件)

    # kubectl replace -f rc.yaml     或     # kubect edit replicationcontroller frontend

    对RC使用滚动升级,来发布新功能或修复BUG

    # kubectl rolling-update frontend --image=kubeguide/guestbook-php-frontend:latest

    当Pod中只有一个容器时,经过–image参数指定新的Tag完成滚动升级,但若是有多个容器或其余字段修改时,须要指定yaml文件

     # kubectl rolling-update frontend -f FILE.yaml

    若是在升级过程当中出现问题(如发现配置错误、长时间无响应),可使用CTRL+C退出,再进行回滚

     # kubectl rolling-update frontend --image=kubeguide/guestbook-php-frontend:latest --rollback

     但若是升级完成后出现问题(好比新版本程序出core),此命令就无能为力了。咱们须要使用一样方法,利用原来的镜像,“升级”为旧版本。

 

Deployment

  更加方便的管理Pod和Replica Set

  k8s是一个高速发展的项目,在新的版本中,官方推荐使用Replica Set和Deployment来代替RC。那么它们优点在哪里,咱们来看一看:

  • RC只支持基于等式的selector(env=dev或environment!=qa),但Replica Set还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)),这对复杂的运维管理很方便。

  • 使用Deployment升级Pod,只须要定义Pod的最终状态,k8s会为你执行必要的操做,虽然可以使用命令# kubectl rolling-update完成升级,但它是在客户端与服务端屡次交互控制RC完成的,因此REST API中并无rolling-update的接口,这为定制本身的管理系统带来了一些麻烦。

  • Deployment拥有更加灵活强大的升级、回滚功能。

目前,Replica Set与RC的区别只是支持的selector不一样,后续确定会加入更多功能。Deployment使用了Replica Set,它是更高一层的概念。除非用户须要自定义升级功能或根本不须要升级Pod,在通常状况下,咱们推荐使用Deployment而不直接使用Replica Set。

  Deployment的一些基础命令。

$ kubectl describe deployments  #查询详细信息,获取升级进度
$ kubectl rollout pause deployment/nginx-deployment2  #暂停升级
$ kubectl rollout resume deployment/nginx-deployment2  #继续升级
$ kubectl rollout undo deployment/nginx-deployment2  #升级回滚
$ kubectl scale deployment nginx-deployment --replicas 10  #弹性伸缩Pod数量
 

  使用子命令create,建立Deployment

  # kubectl create -f deployment.yaml --record

  注意–record参数,使用此参数将记录后续建立对象的操做,方便管理与问题追溯

  使用子命令edit,编辑spec.replicas/spec.template.spec.container.image字段,完成deployment的扩缩容与滚动升级(这要比子命令rolling-update速度快不少)

  # kubectl edit deployment hello-deployment

  使用rollout history命令,查看Deployment的历史信息

  # kubectl rollout history deployment hello-deployment

  上面提到RC在rolling-update升级成功后不能直接回滚,而使用Deployment却能够回滚到上一版本,但要加上–revision参数,指定版本号

  # kubectl rollout history deployment hello-deployment --revision=2

  使用rollout undo回滚到上一版本

  # kubectl rollout undo deployment hello-deployment 

  使用–to-revision能够回滚到指定版本

  # kubectl rollout undo deployment hello-deployment --to-revision=2

 

Volume

    在Docker中,容器中的数据是临时的,当容器被销毁时,其中的数据将会丢失。若是须要持久化数据,须要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。Docker中有docker Volume的概念,Docker的Volume只是磁盘中的一个目录,生命周期不受管理。固然Docker如今也提供Volume将数据持久化存储,但支持功能比较少(例如,对于Docker 1.7,每一个容器只容许挂载一个Volume,而且不能将参数传递给Volume)。
    在Kubernetes中,当Pod重建的时候,数据也会丢失,Kubernetes也是经过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是Pod级别的,能够用来实现Pod中容器的文件共享。Kubernetes Volume具备明确的生命周期 - 与pod相同。所以,Volume的生命周期比Pod中运行的任何容器要持久,在容器从新启动时能够保留数据,固然,当Pod被删除不存在时,Volume也将消失。注意,Kubernetes支持许多类型的Volume,Pod能够同时使用任意类型/数量的Volume。
    要使用Volume,pod须要指定Volume的类型和内容(spec.volumes字段),和映射到容器的位置(spec.containers.volumeMounts字段)。
    容器中的进程能够看到Docker image和volumes组成的文件系统。Docker image处于文件系统架构的root,任何volume都映射在镜像的特定路径上。Volume不能映射到其余volume上,或者硬连接到其余volume。容器中的每一个容器必须堵路地指定他们要映射的volume。

  Kubernetes支持Volume类型有:

  • emptyDir
  • hostPath
  • gcePersistentDisk
  • awsElasticBlockStore
  • nfs
  • iscsi
  • fc (fibre channel)
  • flocker
  • glusterfs
  • rbd
  • cephfs
  • gitRepo
  • secret
  • persistentVolumeClaim
  • downwardAPI
  • projected
  • azureFileVolume
  • azureDisk
  • vsphereVolume
  • Quobyte
  • PortworxVolume
  • ScaleIO
  • StorageOS
  • local

  emptyDir

  使用emptyDir,当Pod分配到Node上时,将会建立emptyDir,而且只要Node上的Pod一直运行,Volume就会一直存。当Pod(无论任何缘由)从Node上被删除时,emptyDir也同时会删除,存储的数据也将永久删除。注:删除容器不影响emptyDir。

  从名称就能够看出,它的初始内容为空。同一个pod中全部容器能够读和写emptyDir中的相同文件。

emptyDir的用途:

  • 临时空间,例如用于某些应用程序运行时所需的临时目录,且无需永久保存;
  • 长时间任务的中间过程CheckPoint临时保存目录;
  • 一个容器须要从另外一个容器中获取数据的目录(多容器共享目录)

示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

  hostPath

  hostPath容许挂载Node上的文件系统到Pod里面去。若是Pod须要使用Node上的文件,可使用hostPath。

hostPath一般应用于:

  • 容器应用程序生成的日志文件须要永久保存,可使用宿主机的高速文件系统进行存储;
  • 须要访问宿主机上Docker引擎内部数据结构的容器应用,能够经过定义hostpath为宿主机/var/lib/docker目录,使得容器内部应用能够直接访问Docker的文件系统。

使用此类型的Volume时需注意:

  在不一样Node上具备相同配置的Pod可能会由于宿主机上的目录和文件不用而致使对Volume上目录和文件的访问结果不一致

示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd  #容器路径
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data      #宿主机路径

  gcePersistentDisk

  gcePersistentDisk能够挂载GCE上的永久磁盘到容器,须要Kubernetes运行在GCE的VM中。与emptyDir不一样,Pod删除时,gcePersistentDisk被删除,但Persistent Disk 的内容任然存在。这就意味着gcePersistentDisk可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

提示:使用gcePersistentDisk,必须用gcloud或使用GCE API或UI 建立PD

建立PD

使用GCE PD与pod以前,须要建立它

gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk

示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    # This GCE PD must already exist.
    gcePersistentDisk:
      pdName: my-data-disk
      fsType: ext4

  awsElasticBlockStore

  awsElasticBlockStore能够挂载AWS上的EBS盘到容器,须要Kubernetes运行在AWS的EC2上。与emptyDir Pod被删除状况不一样,Volume仅被卸载,内容将被保留。这就意味着awsElasticBlockStore可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

提示:必须使用aws ec2 create-volumeAWS API 建立EBS Volume,而后才能使用。

建立EBS Volume

在使用EBS Volume与pod以前,须要建立它。

aws ec2 create-volume --availability-zone eu-west-1a --size 10 --volume-type gp2

AWS EBS配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-ebs
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-ebs
      name: test-volume
  volumes:
  - name: test-volume
    # This AWS EBS volume must already exist.
    awsElasticBlockStore:
      volumeID: <volume-id>
      fsType: ext4

  NFS

  NFS 是Network File System的缩写,即网络文件系统。Kubernetes中经过简单地配置就能够挂载NFS到Pod中,而NFS中的数据是能够永久保存的,同时NFS支持同时写操做。Pod被删除时,Volume被卸载,内容被保留。这就意味着NFS可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间相互传递。

  iSCSI

  iscsi容许将现有的iscsi磁盘挂载到咱们的pod中,和emptyDir不一样的是,删除Pod时会被删除,但Volume只是被卸载,内容被保留,这就意味着iscsi可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

  flocker

  Flocker是一个开源的容器集群数据卷管理器。它提供各类存储后端支持的数据卷的管理和编排。

  glusterfs

  glusterfs,容许将Glusterfs(一个开源网络文件系统)Volume安装到pod中。不一样于emptyDir,Pod被删除时,Volume只是被卸载,内容被保留。味着glusterfs可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

  RBD

  RBD容许Rados Block Device格式的磁盘挂载到Pod中,一样的,当pod被删除的时候,rbd也仅仅是被卸载,内容保留,rbd可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

  cephfs

  cephfs Volume能够将已经存在的CephFS Volume挂载到pod中,与emptyDir特色不一样,pod被删除的时,cephfs仅被被卸载,内容保留。cephfs可以容许咱们提早对数据进行处理,并且这些数据能够在Pod之间“切换”。

提示:可使用本身的Ceph服务器运行导出,而后在使用cephfs。

  gitRepo

  gitRepo volume将git代码下拉到指定的容器路径中。

示例:

apiVersion: v1
kind: Pod
metadata:
  name: server
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /mypath
      name: git-volume
  volumes:
  - name: git-volume
    gitRepo:
      repository: "git@somewhere:me/my-git-repository.git"
      revision: "22f1d8406d464b0c0874075539c1f2e96c253775"

  secret

  secret volume用于将敏感信息(如密码)传递给pod。能够将secrets存储在Kubernetes API中,使用的时候以文件的形式挂载到pod中,而不用链接api。 secret volume由tmpfs(RAM支持的文件系统)支持。      

  persistentVolumeClaim

  persistentVolumeClaim用来挂载持久化磁盘的。PersistentVolumes是用户在不知道特定云环境的细节的状况下,实现持久化存储(如GCE PersistentDisk或iSCSI卷)的一种方式。

  downwardAPI

  经过环境变量的方式告诉容器Pod的信息

  projected

  Projected volume将多个Volume源映射到同一个目录

目前,能够支持如下类型的卷源:

  • secret
  • downwardAPI
  • configMap

全部卷源都要求与pod在同一命名空间中。

示例

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - downwardAPI:
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "cpu_limit"
              resourceFieldRef:
                containerName: container-test
                resource: limits.cpu
      - configMap:
          name: myconfigmap
          items:
            - key: config
              path: my-group/my-config

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - secret:
          name: mysecret2
          items:
            - key: password
              path: my-group/my-password
              mode: 511

  FlexVolume

  alpha功能

  AzureFileVolume

  AzureFileVolume用于将Microsoft Azure文件卷(SMB 2.1和3.0)挂载到Pod中。

  AzureDiskVolume

  Azure是微软提供的公有云服务,若是使用Azure上面的虚拟机来做为Kubernetes集群使用时,那么能够经过AzureDisk这种类型的卷插件来挂载Azure提供的数据磁盘。

  vsphereVolume

  须要条件:配置了vSphere Cloud Provider的Kubernetes。

  vsphereVolume用于将vSphere VMDK Volume挂载到Pod中。卸载卷后,内容将被保留。它同时支持VMFS和VSAN数据存储。

  重要提示:使用POD以前,必须使用如下方法建立VMDK。

  建立一个VMDK卷

  • 使用vmkfstools建立。先将ssh接入ESX,而后使用如下命令建立vmdk
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
  • 使用vmware-vdiskmanager建立
shell vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk

示例

apiVersion: v1
kind: Pod
metadata:
  name: test-vmdk
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-vmdk
      name: test-volume
  volumes:
  - name: test-volume
    # This VMDK volume must already exist.
    vsphereVolume:
      volumePath: "[DatastoreName] volumes/myDisk"
      fsType: ext4

  Quobyte

  在kubernetes中使用Quobyte存储,须要提早部署Quobyte软件,要求必须是1.3以及更高版本,而且在kubernetes管理的节点上面部署Quobyte客户端。

  PortworxVolume

  Portworx能把你的服务器容量进行蓄积(pool),将你的服务器或者云实例变成一个聚合的高可用的计算和存储节点。

  PortworxVolume能够经过Kubernetes动态建立,也能够在Kubernetes pod中预先配置和引用。示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-portworx-volume-pod
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /mnt
      name: pxvol
  volumes:
  - name: pxvol
    # This Portworx volume must already exist.
    portworxVolume:
      volumeID: "pxvol"
      fsType: "<fs-type>"

  ScaleIO

  ScaleIO是一种基于软件的存储平台(虚拟SAN),可使用现有硬件来建立可扩展共享块网络存储的集群。ScaleIO卷插件容许部署的pod访问现有的ScaleIO卷(或者能够为持久卷声明动态配置新卷,请参阅 Scaleio Persistent Volumes)。

示例:

apiVersion: v1
kind: Pod
metadata:
  name: pod-0
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: pod-0
    volumeMounts:
    - mountPath: /test-pd
      name: vol-0
  volumes:
  - name: vol-0
    scaleIO:
      gateway: https://localhost:443/api
      system: scaleio
      volumeName: vol-0
      secretRef:
        name: sio-secret
      fsType: xfs

  StorageOS

  StorageOS是一家英国的初创公司,给无状态容器提供简单的自动块存储、状态来运行数据库和其余须要企业级存储功能,但避免随之而来的复杂性、刚性以及成本。

核心:是StorageOS向容器提供块存储,可经过文件系统访问。

StorageOS容器须要64位Linux,没有额外的依赖关系,提供免费开发许可证。

安装说明,请参阅StorageOS文档

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: redis
    role: master
  name: test-storageos-redis
spec:
  containers:
    - name: master
      image: kubernetes/redis:v1
      env:
        - name: MASTER
          value: "true"
      ports:
        - containerPort: 6379
      volumeMounts:
        - mountPath: /redis-master-data
          name: redis-data
  volumes:
    - name: redis-data
      storageos:
        # The `redis-vol01` volume must already exist within StorageOS in the `default` namespace.
        volumeName: redis-vol01
        fsType: ext4

有关动态配置和持久卷声明的更多信息,请参阅StorageOS示例

  Local

  目前处于 Kubernetes 1.7中的 alpha 级别。

Local 是Kubernetes集群中每一个节点的本地存储(如磁盘,分区或目录),在Kubernetes1.7中kubelet能够支持对kube-reserved和system-reserved指定本地存储资源。

经过上面的这个新特性能够看出来,Local Storage同HostPath的区别在于对Pod的调度上,使用Local Storage能够由Kubernetes自动的对Pod进行调度,而是用HostPath只能人工手动调度Pod,由于Kubernetes已经知道了每一个节点上kube-reserved和system-reserved设置的本地存储限制。

示例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
  annotations:
        "volume.alpha.kubernetes.io/node-affinity": '{
            "requiredDuringSchedulingIgnoredDuringExecution": {
                "nodeSelectorTerms": [
                    { "matchExpressions": [
                        { "key": "kubernetes.io/hostname",
                          "operator": "In",
                          "values": ["example-node"]
                        }
                    ]}
                 ]}
              }'
spec:
    capacity:
      storage: 100Gi
    accessModes:
    - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    storageClassName: local-storage
    local:
      path: /mnt/disks/ssd1

请注意,本地PersistentVolume须要手动清理和删除。

有关local卷类型的详细信息,请参阅 Local Persistent Storage user guide

  Using subPath

  有时,能够在一个pod中,将同一个卷共享,使其有多个用处。volumeMounts.subPath特性能够用来指定卷中的一个子目录,而不是直接使用卷的根目录。

如下是使用单个共享卷的LAMP堆栈(Linux Apache Mysql PHP)的pod的示例。HTML内容映射到其html文件夹,数据库将存储在mysql文件夹中:

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

  Resources

  emptyDir Volume的存储介质(Disk,SSD等)取决于kubelet根目录(如/var/lib/kubelet)所处文件系统的存储介质。不限制emptyDir或hostPath Volume使用的空间大小,不对容器或Pod的资源隔离。

 

Service

  Service是定义一系列Pod以及访问这些Pod的策略的一层抽象由于Service是抽象的,因此在图表里一般看不到它们的存在。

  Service经过Label找到Pod组。当你在Service的yaml文件中定义了该Service的selector中的label为app:my-web,那么这个Service会将Pod-->metadata-->labeks中label为app:my-web的Pod做为分发请求的后端。当Pod发生变化时(增长、减小、重建等),Service会及时更新。这样一来,Service就能够做为Pod的访问入口,起到代理服务器的做用,而对于访问者来讲,经过Service进行访问,无需直接感知Pod。

   Service的目标是提供一种桥梁, 它会为访问者提供一个固定访问地址,用于在访问时重定向到相应的后端,这使得非 Kubernetes原生应用程序,在无须为Kubemces编写特定代码的前提下,轻松访问后端。

  须要注意的是,Kubernetes分配给Service的固定IP是一个虚拟IP,并非一个真实的IP,在外部是没法寻址的。真实的系统实现上,Kubernetes是经过Kube-proxy组件来实现的虚拟IP路由及转发。因此在以前集群部署的环节上,咱们在每一个Node上均部署了Proxy这个组件,从而实现了Kubernetes层级的虚拟转发网络。有一个特别类型的Kubernetes Service,称为'LoadBalancer',做为外部负载均衡器使用,在必定数量的Pod之间均衡流量。好比,对于负载均衡Web流量颇有用。


  如今,假定有2个后台Pod,而且定义后台Service的名称为‘backend-service’,lable选择器为(tier=backend, app=myapp)。backend-service 的Service会完成以下两件重要的事情:

    • 会为Service建立一个本地集群的DNS入口,所以前端Pod只须要DNS查找主机名为 ‘backend-service’,就可以解析出前端应用程序可用的IP地址。
    • 如今前端已经获得了后台服务的IP地址,可是它应该访问2个后台Pod的哪个呢?Service在这2个后台Pod之间提供透明的负载均衡,会将请求分发给其中的任意一个。经过每一个Node上运行的代理(kube-proxy)完成。

 

  Service代理外部服务

    Service不只能够代理Pod,还能够代理任意其余后端,好比运行在Kubernetes外部Mysql、Oracle等。这是经过定义两个同名的service和endPoints来实现的。示例以下:

redis-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  ports:
  - port: 6379
    targetPort: 6379
    protocol: TCP

redis-endpoints.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: redis-service
subsets:
  - addresses:
    - ip: 10.0.251.145
    ports:
    - port: 6379
      protocol: TCP

基于文件建立完Service和Endpoints以后,在Kubernetes的Service中便可查询到自定义的Endpoints。

[root@k8s-master demon]# kubectl describe service redis-service
Name:            redis-service
Namespace:        default
Labels:            <none>
Selector:        <none>
Type:            ClusterIP
IP:            10.254.52.88
Port:            <unset>    6379/TCP
Endpoints:        10.0.251.145:6379
Session Affinity:    None
No events.
[root@k8s-master demon]# etcdctl get /skydns/sky/default/redis-service
{"host":"10.254.52.88","priority":10,"weight":10,"ttl":30,"targetstrip":0}

 

  Service内部负载均衡

    当Service的Endpoints包含多个IP的时候,及服务代理存在多个后端,将进行请求的负载均衡。默认的负载均衡策略是轮训或者随机(有kube-proxy的模式决定)。同时,Service上经过设置Service-->spec-->sessionAffinity=ClientIP,来实现基于源IP地址的会话保持。

  发布Service

    Service的虚拟IP是由Kubernetes虚拟出来的内部网络,外部是没法寻址到的。可是有些服务又须要被外部访问到,例如web前段。这时候就须要加一层网络转发,即外网到内网的转发。Kubernetes提供了NodePort、LoadBalancer、Ingress三种方式。

  • NodePort,在以前的Guestbook示例中,已经延时了NodePort的用法。NodePort的原理是,Kubernetes会在每个Node上暴露出一个端口:nodePort,外部网络能够经过(任一Node)[NodeIP]:[NodePort]访问到后端的Service。
  • LoadBalancer,在NodePort基础上,Kubernetes能够请求底层云平台建立一个负载均衡器,将每一个Node做为后端,进行服务分发。该模式须要底层云平台(例如GCE)支持。
  • Ingress,是一种HTTP方式的路由转发机制,由Ingress Controller和HTTP代理服务器组合而成。Ingress Controller实时监控Kubernetes API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等开源方案。

   servicede 自发性机制

    Kubernetes中有一个很重要的服务自发现特性。一旦一个service被建立,该service的service IP和service port等信息均可以被注入到pod中供它们使用。Kubernetes主要支持两种service发现 机制:环境变量和DNS。

   环境变量方式

    Kubernetes建立Pod时会自动添加全部可用的service环境变量到该Pod中,若有须要.这些环境变量就被注入Pod内的容器里。须要注意的是,环境变量的注入只发送在Pod建立时,且不会被自动更新。这个特色暗含了service和访问该service的Pod的建立时间的前后顺序,即任何想要访问service的pod都须要在service已经存在后建立,不然与service相关的环境变量就没法注入该Pod的容器中,这样先建立的容器就没法发现后建立的service。

   DNS方式

    Kubernetes集群如今支持增长一个可选的组件——DNS服务器。这个DNS服务器使用Kubernetes的watchAPI,不间断的监测新的service的建立并为每一个service新建一个DNS记录。若是DNS在整个集群范围内均可用,那么全部的Pod都可以自动解析service的域名。

  多个service如何避免地址和端口冲突

    此处设计思想是,Kubernetes经过为每一个service分配一个惟一的ClusterIP,因此当使用ClusterIP:port的组合访问一个service的时候,无论port是什么,这个组合是必定不会发生重复的。另外一方面,kube-proxy为每一个service真正打开的是一个绝对不会重复的随机端口,用户在service描述文件中指定的访问端口会被映射到这个随机端口上。这就是为何用户能够在建立service时随意指定访问端口。

  service目前存在的不足

    Kubernetes使用iptables和kube-proxy解析service的人口地址,在中小规模的集群中运行良好,可是当service的数量超过必定规模时,仍然有一些小问题。首当其冲的即是service环境变量泛滥,以及service与使用service的pod二者建立时间前后的制约关系。目前来看,不少使用者在使用Kubernetes时每每会开发一套本身的Router组件来替代service,以便更好地掌控和定制这部分功能。

相关文章
相关标签/搜索