Kubernetes是一个可轻便的,可拓展的开源平台,为管理容器与服务提供便利的配置以及自动化.现已有着很庞大以及快速增长的生态系统.
Kubernetes还有一个重要的思想就是一切皆容器.
k8s是kubernetes的简称,8代指是ubernete.

关键概念

node

一个节点可以是VM虚拟机或者物理机,部署service运行pod.由Master组件管理.

pod

在K8s当中能够被创建以及调度的最小单元,并不是单个容器,一个Pod是由若干个容器组成.Pod容器内共享Network space.

  • IP等网络资源分配的单位的基本单位.
  • 共享Volume
  • 同一个pod内的容器可以功能性IPC(消息队列等),共享主机名.

service

service其实就是一组pods的集合抽象定义.
service可以由Label Selector选出pods.

pod的IP地址会随着pod生命周期消亡而变更,但service的IP不会产生变更,这样可以很好的标识一个服务.

其实通过概念可以看出Service其实不是真正提供服务的因此,他需要将TCP/UDP的流量转发到实际的Endpoints(实际是由Service的selector选择出的Pod).
还有一点是Service可以直接通过设置ExternalIP(公网IP)访问到内部应用服务.

网络

Docker Mode

Docker中同一主机内容器通过虚拟桥接进行通信,默认情况下这个网络是host-private(私有网络).因此Docker容器在各个节点互不相同.
如果需要进行跨节点进行通信,需要在每台主机上开启端口,Docker代理并转发这个端口的流量到容器中,从而实现跨节点通信.

Kubernetes实现

Kubernetes网络实现概念:

1.所有的容器可以不基于NAT互相通信
2.所有的节点可以和容器进行不基于NAT通信
3.IP地址对容器内外都是一致

NAT:网络地址转换.

pod当中的容器位于同一个NetworkNamespace,因此它们是共享IP的,同一个pod可以通过localhost进行访问.这个是通过Docker的--net=--net=container:<id>实现.

KubeProxy

用于流量转发每个节点都会存在KubeProxy.为每个服务生成一个虚拟的IP,并由三种(IPVS,iptables,usersapce)方式转发到Pods中.

IPVS还是beta版,这里先只介绍一下两种方式:

  • iptables:默认模式,kubeproxy不参与真正的流量转发,实时监听endpoints与service的变化控制iptables的转发规则.实际流量的转发是由iptables进行.因此相比与userspace模式速度更快,流量的转发只是在内核.
  • userspace:将实际service中cluster的IP通过iptables转发到kube-proxy代理的端口中然后kube-proxy在转到对应的pod当中.

MASTER组件

MASTER组件可以运行到任集群的何节点,也可以实现高可用.运行这些组件的节点成为主节点.
这些组件为集群提供控制层.这些主要组件做一些主要的决策例如调度,发现和响应集群事件.

  • kube-apiserver
    位于MASTER节点,暴露K8s的接口
  • etcd
    提供一致性和高可用的持久化的键值存储服务.
  • kube-scheduler
    观察是否有新的pod创建,如果有新的pod创建并且没有分配节点,为pod分配节点并运行.
  • kube-controller-manager
    • Node Controller:当节点停止时发送通知和进行响应.
    • Replication Controller:维护pod在节点设置的正确运行的副本数量.可以用于灰度发布,滚动更新,多版本追踪等
    • Endpoints Controller:用于维护Services与endpoint的关系.
    • Service Account & Token Controllers:为新的命名空间创建下默认的账户与API的access token.

Node Component

Node Component运行在每一个节点之上,维护运行的pods,以及k8s的环境.

  • Kubelet
    集群当中每个节点的代理,确保在一个pod中的容器处于运行状态.
  • kube-proxy
    能够让k8s通过维护在主机的网络规则以及连接代理进行服务抽象.
  • Container Runtime
    是承担容器运行的软件

Addons

附加组件都属于kube-system命名空间,不是必须组件,但是这里只介绍一个DNS组件.

DNS

Cluster DNS是一个集群的DNS服务.容器启动时在DNS查询之时会使用DNS服务.

Namespaces

使用不同的命名空间是为了分割资源,使用标签来区分资源在同一命名空间下.
可以在多个命名空间存在相同的名字,但是在单个命名空间下只能存在一个.

Label 与 Selector

Label使用键值存储,关键做用是用于区分不同的对象.可以用来选择区分不同的对象.

命名规则

Label的key分为前缀以及名字.

Key 规则如下:

1.名字必须不超过63个字符,且以字母开头,可由[\.-_a-zA-Z0-9]构成.
2.前缀必须是域名加/,不超过253个字符.
3.如果前缀不存在那么k8s会假设这个Key是这个用户私有.

Value规则:

不超过63个字符且以字母开头可由[\.-_a-zA-Z0-9]构成.

进行选择

目前只支持基于集合和基于相等,并列条件可以在每个选择条件之间加入,表示逻辑&&.

基于集合

支持的字符:in not in exists not exists

exists的语法是直接写Key的名称,下述例子是查找env为qa,dev,prod,且包含partition的key,且不包含notincluded的key.

env in (qa, dev, prod),partition,!notincluded

基于相等

支持的字符:= != == .
===是等价的都表示相等条件.

使用示例:
选出pods当中label中的key为env,value为prod

kubectl get pods -l 'env=prod,partition in (1)'

deployment

主要为了操作部署replicaset与pod.
功能:可以进行横向扩展,蓝绿发布,金丝雀发布,灰度发布,多版本发布等.
除此之外可已根据对应的发布版本的历史记录进行回滚.

当然我们也可以设置自己的策略,当我们部署的pods或者需要更新pods没有正常执行而异常退出,deployment controller会根据设置的策略对部署的pods进行重新部署.

配置示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  #指定副本数量
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  #pod的模板信息   
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

replicaset

主要作用:确保当前运行数量的pods.

官方不推荐直接使用replicaset进行操作,而推荐使用deployment.
其与replication controller最主要的区别是replicaset中selector支持集合操作.

Jobs

一个Job创建一个或者多个pods确保明确的运行数量成功运行.

主要存在下述三种类型:

1.非平行工作:通常启动一个pod,当pod成功退出,任务就被完成.
2.固定执行任务数的平行工作:指定了.spec.completions非0正数值,当运行成功的pod满足了.spec.completions的值时,那么任务就会被完成
3.平行工作:每个pod都在运行job,只要有任一一个job中的工作完成,那么其他的pod也会终止job.

CronJob

CronJob是类似于Crond服务的计划工作模式.

配置要求:
1.Kubernetes版本大于1.8
2.对于小于1.8版本的需要在启动时增加--runtime-config=batch/v2alpha1=true配置项

简单的配置要求

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

Volume

k8s支持很多种类型的Volume.这里简单介绍几种Volume.
Volume声明是在pod当中,因此pod的内的容器共享Volume.

pod中进程看到容器的内的文件系统由两部分组成:
1.Docker镜像文件系统
2.若干个Volume

ConfigMap

ConfigMap可以用于存储一些配置数据,变量等.不适合存储大型文件.

示例:

apiVersion: v1
data:
  allowed: '"true"'
  enemies: aliens
  lives: "3"
kind: ConfigMap
metadata:
  creationTimestamp: 2017-12-27T18:36:28Z
  name: game-config-env-file
  namespace: default
  resourceVersion: "809965"
  selfLink: /api/v1/namespaces/default/configmaps/game-config-env-file
  uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8

secret

secret 可用于存储一些加密的信息以文件的形式传给pod.

persistentVolume

持久化volume,独立于pod的生命周期.指定资源类型,大小,存储类型等等.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

persistentVolumeClaim

对于PersistentVolume的资源请求(分配),被用于挂载persistentVolume到pod上,不需要关心底层的存储环境无论是GCE或者是ISCSI.
通过多个pod使用供用的PVC我们可以实现,不同的之间共享数据.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

pod使用emptDir类型Volume使用示例

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

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

更多推荐