Kubernetes对象

目录

1 对象

Kubernetes 对象 是持久化的条目. Kubernetes 使用这些条目去表示整个集群的状态.

  • 1.1 分类

    类别名称
    资源对象Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
    存储对象Volume、PersistentVolume、Secret、ConfigMap
    策略对象SecurityContext、ResourceQuota、LimitRange
    身份对象ServiceAccount、Role、ClusterRole

2 Namespaces

Kubernetes可以使用Namespaces(命名空间)创建多个虚拟集群.

  • 2.1 何时使用多个Namespaces

    当团队或项目中具有许多用户时,可以考虑使用Namespace来区分. 提供特殊性质需求时,可以开始使用Namespace.

    Namespace为名称提供了一个范围. 资源的Names在Namespace中具有唯一性.

  • 2.2 使用 Namespaces

    • 2.2-1 创建

      (1) 命令行直接创建
      $ kubectl create namespace new-namespace
      
      (2) 通过文件创建
      $ cat my-namespace.yaml
      apiVersion: v1
      kind: Namespace
      metadata:
      	name: new-namespace
      
      $ kubectl create -f ./my-namespace.yaml
      
    • 2.2-2 删除

      kubectl delete namespaces new-namespace
      

      注意:

      • 删除一个namespace会自动删除所有属于该namespace的资源.
      • default和kube-system命名空间不可删除.
      • PersistentVolumes是不属于任何namespace的,但PersistentVolumeClaim是属于某个特定namespace的.
      • Events是否属于namespace取决于产生events的对象.
    • 2.2-3 查看 Namespaces

      使用以下命令列出群集中的当前的Namespace:

      $ kubectl get namespaces
      NAME          STATUS    AGE
      default       Active    1d
      kube-system   Active    1d
      
  • 2.3 所有对象都在Namespace中?

    大多数Kubernetes资源(例如pod、services、replication controllers或其他)都在某些Namespace中.

    Namespace资源本身并不在Namespace中. 低级别资源(如Node和persistentVolumes)不在任何Namespace中.

3 Labels 和 Selectors

Labels可以让用户将他们自己的有组织目的的结构以一种松耦合的方式应用到系统的对象上.

  • 3.1 Labels选择器

    • 3.1-1 Equality-based requirement 基于相等的要求

      基于相等的或者不相等的条件允许用标签的keys和values进行过滤. 有三种运算符是允许的,“=”,“==”和“!=”.

      例如:

      # 选择所有key等于 environment 值为 production 的资源
      environment = production
      # 选择所有key等于tier 值不等于 frontend 的资源,和那些没有key等于tier 的label的资源
      tier != frontend
      
    • 3.1-2 Set-based requirement 基于集合的要求

      Set-based 的标签条件允许用一组value来过滤key. 支持三种操作符: in , notin 和 exists(仅针对于key符号).

      # 选择所有key等于 environment ,且value等于 production 或者 qa 的资源
      environment in (production, qa)
      # 选择所有key等于 tier 且值是除了 frontend 和 backend 之外的资源,和那些没有标签的key是 tier 的资源
      tier notin (frontend, backend)
      # 选择所有有一个标签的key为partition的资源;value是什么不会被检查
      partition
      # 选择所有的没有lable的key名为 partition 的资源;value是什么不会被检查
      !partition
      
  • 3.2 API

    一些Kubernetes对象,例如services和replicationcontrollers,也使用标签选择器来指定其他资源的集合,如pod.

    • 3.2-1 API对象中引用

      • 3.2-1.1 Service和ReplicationController

        一个service针对的pods的集合是用标签选择器来定义的. 类似的,一个replicationcontroller管理的pods的群体也是用标签选择器来定义的.

        # 等同于component=redis或component in (redis)
        selector:
        	component: redis
        
      • 3.2-1.2 支持set-based要求的资源

        Job,Deployment,Replica Set,和Daemon Set,支持set-based要求.

        # matchLabels和matchExpressions取交集
        selector:
        	matchLabels:                           # matchLabels 是一个{key,value}的映射
        		component: redis
        	matchExpressions:                  # AND关系
        		- {key: tier, operator: In, values: [cache]}
        		- {key: environment, operator: NotIn, values: [dev]}
        
      • 3.2-1.3 Selecting sets of nodes

        根据节点的 label 进行Pod调度.

        首先给Node打上标签:

        $ kubectl label nodes 192.168.1.140 source=qikqiak
        node "192.168.1.140" labeled
        # 查看标签是否生效
        kubectl get nodes --show-labels
        

        编排文件:
        在这里插入图片描述

4 Volume

  • 4.1 Volume 类型

    • 4.1.1 emptyDir

      使用emptyDir,当Pod分配到Node上时,将会创建emptyDir,并且只要Node上的Pod一直运行,Volume就会一直存.
      当Pod(不管任何原因)从Node上被删除时,emptyDir也同时会删除,存储的数据也将永久删除. 注:删除容器不影响emptyDir.

      示例:

      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: {}
      
    • 4.1.2 hostPath

      hostPath允许挂载Node上的文件系统到Pod里面去. 如果Pod需要使用Node上的文件,可以使用hostPath.

      示例:

      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
      
    • 4.1.3 NFS

      NFS支持同时写操作. Pod被删除时,Volume被卸载,内容被保留. 这些数据可以在Pod之间相互传递

      示例:

    • 4.1.4 RBD

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

      示例:

    • 4.1.5 secret

      secret volume用于将敏感信息(如密码)传递给pod. 使用的时候以文件的形式挂载到pod中,而不用连接api. secret volume由tmpfs(RAM支持的文件系统)支持.

      示例:

    • 4.1.6 Local

      Local 是Kubernetes集群中每个节点的本地存储(如磁盘,分区或目录),Local Storage同HostPath的区别在于对Pod的调度上,使用Local Storage可以由Kubernetes自动的对Pod进行调度,而是用HostPath只能人工手动调度Pod.

      示例:

      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
      
  • 4.2 Using subPath

    • 4.2.1 共享同一存储卷

      subPath跟目录,相对路径即可

      # 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
      
    • 4.2.2 挂载文件到某个目录,不覆盖其他内容

      subPath后跟文件名称

      containers:
      - name: kafka
        #imagePullPolicy: Always
        image: fastop/kafka:2.2.0
        volumeMounts:
        	- name: storage
        	  mountPath: "/var/lib/kafka"
      	- name: kafka
        	  mountPath: "/opt/kafka/config/server.properties"
        	  subPath: server.properties                     # 此处挂载kafka配置文件到容器内部目录,不覆盖原始文件
      

5 Pod概述

  • 5.1 了解Pod

    Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程.

    一个Pod封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项.

    • 5.1.1 Pods如何管理多个容器

      Pods提供两种共享资源:网络和存储

      • 网络

        每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口.
        Pod内的容器可以使用localhost相互通信.
        当Pod中的容器与Pod 外部通信时,他们必须协调如何使用共享网络资源(如暴露端口).

      • 存储

        Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据.
        volumes 还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据.

  • 5.2 使用Pod

    Pod的生命周期是短暂的,用后即焚的实体.
    注意:重启Pod中的容器跟重启Pod不是一回事. Pod只提供容器的运行环境并保持容器的运行状态,重启容器不会造成Pod重启.

    • 5.2.1 Pod和Controller

      Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力.
      例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上.

      常见的控制器:

      • Deployment
      • StatefulSet
      • DaemonSet
  • 5.3 Pod模板

    Pod模板是包含了其他对象(如Replication Controllers,Jobs和 DaemonSets)中的pod定义 . Controllers控制器使用Pod模板来创建实际需要的pod.

6 Replica Sets

ReplicaSet(RS)是Replication Controller(RC)的升级版本.
ReplicaSet 和 Replication Controller之间的唯一区别是对选择器的支持. ReplicaSet支持lset-based选择器, 而Replication Controller仅支持equality-based的选择器.

  • 6.1 何时使用ReplicaSet

    ReplicaSet能确保运行指定数量的pod. 然而,Deployment 是一个更高层次的概念,它能管理ReplicaSets,并提供对pod的更新等功能.

7 Deployment

  • 7.1 创建 Deployment

    # 将kubectl的 --record 的 flag 设置为 true可以在 annotation 中记录当前命令创建或者升级了该资源
    $ kubectl create -f nginx-deployment.yaml --record
    deployment "nginx-deployment" created
    

    过几秒后再执行get命令,将获得如下输出:

    # 可用的(根据Deployment中的.spec.minReadySeconds声明,处于已就绪状态的pod的最少个数)
    $ kubectl get deployments
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3            3         3             3       18s
    
    • 7.1.1 Pod-template-hash label

      当 Deployment 创建或者接管 ReplicaSet 时,Deployment controller 会自动为 Pod 添加 pod-template-hash label. 这样做的目的是防止 Deployment 的子ReplicaSet 的 pod 名字重复.
      你可能注意到:ReplicaSet 的名字总是<Deployment的名字>-<pod template的hash值>,Pod的名字是 <Deployment的名字>-<pod template的hash值>-<随机值>.

      $ kubectl get pods --show-labels
      NAME                                READY     STATUS    RESTARTS   AGE       LABELS
      nginx-deployment-2035384211-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211
      nginx-deployment-2035384211-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211
      nginx-deployment-2035384211-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211
      
  • 7.2 更新Deployment

    注意: Deployment 的 rollout 当且仅当 Deployment 的 pod template(例如.spec.template)中的label更新或者镜像更改时被触发. 其他更新,例如扩容Deployment不会触发 rollout.

    滚动更新步骤:创建出来新的RS,生成新的Pod;新RS扩容更新,旧RS缩容.

    • 7.2.1 Rollover(多个rollout并行)

      假如您创建了一个有5个niginx:1.7.9 replica的 Deployment,但是当还只有3个nginx:1.7.9的 replica 创建出来的时候您就开始更新含有5个nginx:1.9.1 replica 的 Deployment. 在这种情况下,Deployment 会立即杀掉已创建的3个nginx:1.7.9的 Pod,并开始创建nginx:1.9.1的 Pod. 它不会等到所有的5个nginx:1.7.9的 Pod 都创建完成后才开始改变航道.

    • 7.2.2 Label selector 更新

      不鼓励更新 label selector,请一定要谨慎并确认您已经预料到所有可能因此导致的后果.

      • 增添 selector:导致所有旧版本的 ReplicaSet 都被丢弃,并创建新的 ReplicaSet.
      • 更新 selector:导致跟增添 selector 同样的后果.
      • 删除 selector:
  • 7.3 回退Deployment

    默认情况下,kubernetes 会在系统中保存前两次的 Deployment 的 rollout 历史记录,以便您可以随时回退(您可以修改revision history limit来更改保存的revision数).

    注意: 只要 Deployment 的 rollout 被触发就会创建一个 revision。也就是说当且仅当 Deployment 的 Pod template(如.spec.template)被更改,例如更新template 中的 label 和容器镜像时,就会创建出一个新的 revision.

    其他的更新,比如扩容 Deployment 不会创建 revision——因此我们可以很方便的手动或者自动扩容。这意味着当您回退到历史 revision 是,直有 Deployment 中的 Pod template 部分才会回退.

    • 7.3.1 检查 Deployment 升级的历史记录

      # 检查下 Deployment 的 revision
      kubectl rollout history deployment/nginx-deployment
      # 查看单个revision 的详细信息
      kubectl rollout history deployment/nginx-deployment --revision=2
      
    • 7.3.2 回退到历史版本

      # 回退上个版本
      kubectl rollout undo deployment/nginx-deployment
      # 使用 --revision参数指定某个历史版本
      kubectl rollout undo deployment/nginx-deployment --to-revision=2
      
    • 7.3.3 清理 Policy

      您可以通过设置.spec.revisonHistoryLimit项来指定 deployment 最多保留多少 revision 历史记录. 如果将该项设置为0,Deployment就不允许回退了.

  • 7.4 Deployment 扩容

    使用以下命令扩容 Deployment:

    kubectl scale deployment nginx-deployment --replicas 10
    
    • 7.4.1 比例扩容

      RollingUpdate Deployment 支持同时运行一个应用的多个版本,为了降低风险,Deployment controller 将会平衡已存在的活动中的 ReplicaSet和新加入的 replica. 这被称为比例扩容.

      例如,您正在运行中含有10个 replica 的 Deployment. maxSurge=3,maxUnavailable=2.

      $ kubectl get deploy
      NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
      nginx-deployment     10        10        10           10          50s
      

      您更新了一个镜像,而在集群内部无法解析:

      $ kubectl set image deploy/nginx-deployment nginx=nginx:sometag
      deployment "nginx-deployment" image updated
      

      第一次更新:镜像更新启动了一个包含ReplicaSet nginx-deployment-1989198191的新的rollout,但是它被阻塞了,因为我们上面提到的maxUnavailable:

      # 此处新启的nginx-deployment-1989198191 个数5 = maxSurge=3 + maxUnavailable=2
      $ kubectl get rs
      NAME                          DESIRED   CURRENT   READY     AGE
      nginx-deployment-1989198191   5         5         0         9s
      nginx-deployment-618515232    8         8         8         1m
      

      第二次更新:然后发起了一个新的Deployment扩容请求。autoscaler将Deployment的repllica数目增加到了15个. Deployment controller需要判断在哪里增加这5个新的replica.
      如果我们没有谁用比例扩容,所有的5个replica都会加到一个新的ReplicaSet中. 如果使用比例扩容,大的部分加入replica数最多的ReplicaSet中,小的部分加入到replica数少的ReplciaSet中.

      在我们上面的例子中,3个replica将添加到旧的ReplicaSet中,2个replica将添加到新的ReplicaSet中:

      $ kubectl get deploy
      NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
      nginx-deployment     15        18        7            8           7m
      $ kubectl get rs
      NAME                          DESIRED   CURRENT   READY     AGE
      nginx-deployment-1989198191   7         7         0         7m                    # +2个
      nginx-deployment-618515232    11        11        11        7m                   # +3个
      
  • 7.5 暂停和恢复Deployment

    您可以在发出一次或多次更新前暂停一个 Deployment,然后再恢复它. 这样您就能多次暂停和恢复 Deployment,在此期间进行一些修复工作,而不会发出不必要的 rollout.

    使用以下命令暂停 Deployment:

    $ kubectl rollout pause deployment/nginx-deployment
    deployment "nginx-deployment" paused
    

    然后更新 Deplyment中的镜像:

    $ kubectl set image deploy/nginx nginx=nginx:1.9.1
    deployment "nginx-deployment" image updated
    

    您可以进行任意多次更新,例如更新使用的资源:

    $ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
    deployment "nginx" resource requirements updated
    

    Deployment 暂停前的初始状态将继续它的功能,而不会对 Deployment 的更新产生任何影响,只要 Deployment是暂停的.

    最后,恢复这个 Deployment,观察完成更新的 ReplicaSet 已经创建出来了:

    $ kubectl rollout resume deploy nginx
    deployment "nginx" resumed
    
    $ KUBECTL get rs
    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   0         0         0         2m
    nginx-3926361531   3         3         3         28s
    

    注意: 在恢复 Deployment 之前您无法回退一个已经暂停的 Deployment.

  • 7.6 Deployment 状态

    使用kubectl rollout status命令监控 Deployment 的进度.

  • 7.7 滚动更新配置

    .spec.strategy.type=Recreate:创建出新的Pod之前会先杀掉所有已存在的Pod.
    .spec.strategy.type=RollingUpdate:Deployment使用rolling update 的方式更新Pod . 您可以指定.spec.strategy.rollingUpdate.maxUnavailable和.spec.strategy.rollingUpdate.maxSurge来控制 rolling update 进程.
    .spec.progressDeadlineSeconds:Deployment controller等待多少秒才能确定(通过Deployment status)Deployment进程是卡住的. 如果设置该参数,该值必须大于 .spec.minReadySeconds.
    .spec.minReadySeconds:Pod并被认为是可用状态的最小秒数,默认是0(Pod在ready后就会被认为是可用状态).
    .spec.revisionHistoryLimit:指定可以保留的旧的ReplicaSet数量.
    .spec.template.spec.restartPolicy:默认为Always.

8 StatefulSets

  • 8.1 使用StatefulSets

    在具有以下特点时使用StatefulSets:

    • 稳定性,唯一的网络标识符
    • 稳定性,持久化存储
    • 有序的部署和扩展
    • 有序的删除和终止
    • 有序的自动滚动更新

    Pod调度运行时,如果应用不需要任何稳定的标示、有序的部署、删除和扩展,则应该使用一组无状态副本的控制器来部署应用,例如 Deployment 或 ReplicaSet更适合无状态服务需求.

  • 8.2 限制

    • Pod的存储,必须基于请求storage class的PersistentVolume Provisioner或由管理员预先配置来提供
    • 基于数据安全性设计,删除或缩放StatefulSet将不会删除与StatefulSet关联的Volume
    • StatefulSets需要Headless Service负责Pods的网络的一致性(必须创建此服务)
  • 8.3 组件

  • 8.4 部署和扩展

    不要将StatefulSet的pod.Spec.TerminationGracePeriodSeconds(关闭pod缓冲时间,默认为30s)值设置为0

    • 对于具有N个副本的StatefulSet,当部署Pod时,将会顺序从{0…N-1}开始创建

    • Pods被删除时,会从{N-1…0}的相反顺序终止

    • 扩容、缩容操作应用于Pod之前,它的所有前辈必须运行和就绪

    • 8.4.1 Pod管理

      在Kubernetes 1.7及更高版本中,通过.spec.podManagementPolicy字段设置Pod管理策略

      • 8.4.1.1 OrderedReady Pod Management
        StatefulSets的默认行为,实现了上述 “部署/扩展” 行为. 按序部署.
      • 8.4.1.2 Parallel Pod Management
        告诉StatefulSet控制器同时启动或终止所有Pod,不建议使用.
  • 8.5 Update Strategies

    • 8.5.1 删除

      当spec.updateStrategy未指定时的默认策略,当StatefulSet .spec.updateStrategy.type设置为OnDelete,StatefulSet控制器将不会自动更新StatefulSet中的Pod,用户必须手动删除Pods以使控制器创建新的Pod.
    • 8.5.2 滚动更新

      当StatefulSet .spec.updateStrategy.type设置为RollingUpdate,StatefulSet控制器将删除并重新创建StatefulSet中的每个Pod.
      它将以与Pod终止相同的顺序进行(从最大的序数到最小的顺序)来更新每个Pod.
      • 8.5.2.1 Partitions
        通过指定 .spec.updateStrategy.rollingUpdate.partition来分割RollingUpdate更新策略. 更新具有大于或等于partition的序数的所有Pods .spec.template,小于partition的序数的所有Pod将不会被更新.
        在通常数情况下,不需要使用partition,但如果需要进行更新,推出金丝雀或执行分阶段推出,可以使用partition

9 Service

Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束.
Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务.

  • 9.1 定义 Service

    Kubernetes Service 能够支持 TCP 和 UDP 协议,默认 TCP 协议.

    kind: Service
    apiVersion: v1
    metadata:
    	name: my-service
    spec:
    	selector:
    		app: MyApp
    	ports:
    		- protocol: TCP
      		  port: 80
      		  targetPort: 9376
    
    • 9.1.1 没有 selector 的 Service

      在任何这些场景中,都能够定义没有 selector 的 Service :

      kind: Service
      apiVersion: v1
      metadata:
      	name: my-service
      spec:
      	ports:
      	- protocol: TCP
      	  port: 80
      	  targetPort: 9376
      

      由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:

      kind: Endpoints
      apiVersion: v1	
      metadata:
      	name: my-service
      subsets:
      	- addresses:
      		- ip: 1.2.3.4
      	  ports:
      	  - port: 9376
      

      注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24).

      ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

      kind: Service
      apiVersion: v1
      metadata:
      	name: my-service
      	namespace: prod
      spec:
      	type: ExternalName
      	externalName: my.database.example.com
      

      当查询主机 my-service.prod.svc.CLUSTER时,集群的 DNS 服务将返回一个值为 my.database.example.com 的 CNAME 记录.
      访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发.
      如果后续决定要将数据库迁移到 Kubernetes 集群中,可以启动对应的 Pod,增加合适的 Selector 或 Endpoint,修改 Service 的 type.

  • 9.2 VIP 和 Service 代理

    在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务

    在 Kubernetes 集群中的每一个节点都运行着一个 kube-proxy 进程,这个进程会负责监听 Kubernetes 主节点中 Service 的增加和删除事件并修改运行代理的配置,为节点内的客户端提供流量的转发和负载均衡等功能,但是当前 kube-proxy 的代理模式目前来看有三种:
    在这里插入图片描述

    • 9.2.1 userspace 代理模式

      作为运行在用户空间的代理,对于每一个 Service 都会在当前的节点上开启一个端口,所有连接到当前代理端口的请求都会被转发到 Service 背后的一组 Pod 上,它其实会在节点上添加 iptables 规则,通过 iptables 将流量转发给 kube-proxy 处理。
      在这里插入图片描述

    • 9.2.2 iptables 代理模式

      脱离了用户空间在内核空间中实现转发的方式能够极大地提高 proxy 的效率,增加 kube-proxy 的吞吐量。
      在这里插入图片描述

    • 9.2.3 IPVS

      ipvs 就是用于解决在大量 Service 时,iptables 规则同步变得不可用的性能问题。与 iptables 比较像的是,ipvs 的实现虽然也基于 netfilter 的钩子函数,但是它却使用哈希表作为底层的数据结构并且工作在内核态,这也就是说 ipvs 在重定向流量和同步代理规则有着更好的性能。
      在这里插入图片描述

  • 9.3 多端口 Service

    使用多个端口时,必须给出所有的端口的名称,这样 Endpoint 就不会产生歧义:

    kind: Service
    apiVersion: v1
    metadata:
    	name: my-service
    spec:
    	selector:
      		app: MyApp
    	ports:
        	- name: http
        	  protocol: TCP
        	  port: 80
        	  targetPort: 9376
      	  - name: https
        	protocol: TCP
       		port: 443
        	targetPort: 9377
    
  • 9.4 选择自己的 IP 地址

    在 Service 创建的请求中,可以通过设置 spec.clusterIP 字段来指定自己的集群 IP 地址.

  • 9.5 服务发现

    • 9.5.1 环境变量

      当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量.

      举个例子,一个名称为 “redis-master” 的 Service 暴露了 TCP 端口 6379,同时给它分配了 Cluster IP 地址 10.0.0.11,这个 Service 生成了如下环境变量:

      REDIS_MASTER_SERVICE_HOST=10.0.0.11
      REDIS_MASTER_SERVICE_PORT=6379
      REDIS_MASTER_PORT=tcp://10.0.0.11:6379
      REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
      REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
      REDIS_MASTER_PORT_6379_TCP_PORT=6379
      REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
      

      这意味着需要有顺序的要求 —— Pod 想要访问的任何 Service 必须在 Pod 自己之前被创建,否则这些环境变量就不会被赋值.

    • 9.5.2 DNS

      一个可选(尽管强烈推荐)集群插件 是 DNS 服务器. DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录.
      例如:一个Service叫"my-service",namespace是"ops",因此你可以在"ops"命名空间通过"my-service"查询到服务,要是不同的命名空间必须"my-service.ops"查找,最终查找到的都是ClusterIP.
      Kubernetes 也支持对端口名称的 DNS SRV(Service)记录. 如果名称为 “my-service.my-ns” 的 Service 有一个名为 “http” 的 TCP 端口,可以对 “_http._tcp.my-service.my-ns” 执行 DNS SRV 查询,得到 “http” 的端口号.
      Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式.
      更多DNS和Pod知识:https://k8smeetup.github.io/docs/concepts/services-networking/dns-pod-service/

  • 9.6 Headless Service

    对这类 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了 selector。

    • 9.6.1 配置 Selector

      定义了 selector 的 Headless Service,Endpoint 控制器在 API 中创建了 Endpoints 记录,并且修改 DNS 配置返回 A 记录(地址),通过这个地址直接到达 Service 的后端 Pod上。
    • 9.6.2 不配置 Selector

  • 9.7 发布服务 —— 服务类型

    • 9.7.1 NodePort 类型

    • 9.7.2 LoadBalancer 类型

      使用支持外部负载均衡器的云提供商的服务,设置 type 的值为 “LoadBalancer”,将为 Service 提供负载均衡器。
      在这里插入图片描述
    • 9.7.3 外部 IP

      通过外部 IP(作为目的 IP 地址)进入到集群,打到 Service 的端口上的流量,将会被路由到 Service 的 Endpoint 上。 externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。
      在这里插入图片描述

10 ingress

Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如

  • 对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在支持的cloud provider上面

Ingress就是为了解决这些限制而引入的新资源,主要用来将服务暴露到cluster外面,并且可以自定义服务的访问策略

https://www.kubernetes.org.cn/1885.html

11 特权模式

containers:
- name: prometheus
  image: prom/prometheus
  securityContext:
    runAsUser: 0
    privileged: true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值