1

1. 名词概念

  1. cluster:Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用。
  2. master:Master是Cluster的大脑,它的主要职责是调度,即决定将应用放在哪里运行。为了实现高可用,可以运行多个Master。
  3. node:Node的职责是运行容器应用。Node由Master管理,Node负责监控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。
  4. pod:Pod是Kubernetes的最小工作单元。每个Pod包含一个或多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。
  5. controller:Kubernetes通常不会直接创建Pod,而是通过Controller来管理Pod的。Controller中定义了Pod的部署特性,比如有几个副本、在什么样的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种Controller,包括Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等。
  6. service:Kubernetes Service定义了外界访问一组特定Pod的方式。Service有自己的IP和端口,Service为Pod提供了负载均衡。Deployment可以部署多个副本,每个Pod都有自己的IP,Service为外界访问这些副本提供了解决方式。
  7. namespace:Namespace可以将一个物理的Cluster逻辑上划分成多个虚拟Cluster,每个Cluster就是一个Namespace。不同Namespace里的资源是完全隔离的。Kubernetes默认创建了两个Namespace:(1)default:创建资源时如果不指定,将被放到这个Namespace中。(2)kubesystem:Kubernetes自己创建的系统资源将放到这个Namespace中。
  8. kubectl:kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。
  9. kubelet:kubelet 是运行在每个节点上的主要的“节点代理”,每个节点都会启动 kubelet进程,用来处理 Master 节点下发到本节点的任务,按照 PodSpec 描述来管理Pod 和其中的容器。kubelet的主要功能有:(1)pod管理,定期从所监听的数据源获取节点上 pod/container的期望状态并管理执行。(2)容器健康检查,查看容器是否正常运行,如果容器运行出错按照重启策略处理。(3)资源监控,监控所在节点的资源使用情况,并定时向 master 报告,知道整个集群所有节点的资源情况,对于 pod 的调度和正常运行至关重要。

2. 架构

k8s集群Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用。

image

2.1. master结构

Master是KubernetesCluster的大脑,运行着的Daemon服务包括kubeapiserver、kubescheduler、kubecontrollermanager、etcd和Pod网络。

2.1.1. api server

k8s api server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等http rest接口,是整个系统的数据总线和数据中心。像平时执行kubectl,实际是会将对资源的请求命令传递给api server。包括市场上有很多底层基于k8s的容器管理产品,都对api server的rest接口进行一定封装,从而对k8s进行操作。

kubernetes api server的功能:

  • 提供了集群管理的REST API接口(包括认证授权、数据校验以及集群状态变更);
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 api server查询或修改数据,只有 api server才直接操作etcd);
  • 是资源配额控制的入口;
  • 拥有完备的集群安全机制。

2.1.2. scheduler

Scheduler负责决定将Pod放在哪个Node上运行。Scheduler在调度时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。

2.1.3. controller manager

ControllerManager负责管理Cluster各种资源,保证资源处于预期的状态。

ControllerManager由多种controller组成,包括replicationcontroller、endpointscontroller、namespacecontroller、serviceaccountscontroller等。不同的controller管理不同的资源。例如,replicationcontroller管理Deployment、StatefulSet、DaemonSet的生命周期,namespacecontroller管理Namespace资源。

2.1.4. etcd

etcd负责保存KubernetesCluster的配置信息和各种资源的状态信息。当数据发生变化时,etcd会快速地通知Kubernetes相关组件。

2.2. node结构

Node是Pod运行的地方,Kubernetes支持Docker、rkt等容器Runtime。Node上运行的Kubernetes组件有kubelet、kubeproxy和Pod网络。

2.2.1. kubelet

kubelet是Node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet根据这些信息创建和运行容器,并向Master报告运行状态。

2.2.2. kube-proxy

service在逻辑上代表了后端的多个Pod,外界通过service访问Pod。service接收到的请求是如何转发到Pod的呢?这就是kubeproxy要完成的工作。

每个Node都会运行kubeproxy服务,它负责将访问service的TCP/UPD数据流转发到后端的容器。如果有多个副本,kubeproxy会实现负载均衡。

3. 部署服务

k8s上的资源编排命令,都通过kubectl来执行,kubectl的命令有很多,这里侧重于讲解两种部署方式。一种方式,通过kubectl的命令行来部署(kebectl run --optional);另一种方式,则通过启用完整的yaml文件来部署和编排服务。

第一种方式更快速便捷,但第二种方式更正式规范,下面都会做简单介绍。

3.1. kubectl命令

kubectl 创建对象
$ kubectl create -f ./my-manifest.yaml     #创建资源
$ kubectl create -f ./my1.yaml -f ./my2.yaml    #使用多个文件创建资源
$ kubectl create -f ./dir    #使用目录下的所有清单文件(yaml)来创建资源
$ kubectl create -f https://git.io/vPieo    #使用url创建资源
$ kubectl run nginx --image=nginx    #启动一个nginx实例
$ kubectl explain pods    #获取pod和svc的文档
kubectl 显示和查找资源
$ kubectl get pods --all-namespaces    #列出所有namespace中的pod,也可以是services、deployment等

$ kubectl get pods -o wide    #列出pod并显示详细信息

$ kubectl get deployment my-dep    #列出指定daployment

$ kubectl get pods --include-uninitialized    #列出该namespace中的所有pod,包括未初始化的
使用详细输出来描述命令
$ kubectl describe nodes <my-node IP or name>    #查看node节点信息

$ kubectl describe pods <my-pod>    #查看pod详细信息

$ kubectl get services --sort-by=.metadata.name --all-namespaces    #l列出所有service并按名称排序
kubectl编辑资源
$ kubectl -n codeus edit svc/c #编辑codeus命名空间下名称为c的service
kubectl Scale 资源
$ kubectl scale --replicas=3 rs/foo #扩展名称为foo的资源到3个,是否使用rs取决于yaml中的编写
kubectl 删除资源
$ kubectl delete deployment <name>     #删除指定deployment,此方法还可以删除service等

$ kubectl delete -f xxx.yaml    #通过创建此pod的yaml文件删除pod
kubectl 与运行中的pod交互
$ kubectl -n <namespaces> logs my-podname    #查看pod日志, -f 持续查看
$ kubectl port-forward my-podname 5000:6000    #转发pod中的6000端口到本地的5000端口
$ kubectl exec my-podname -- ls /    #在已存在的容器中执行命令

3.2. run部署

基础部署的命令是 kubectl run:

kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]

例如,部署一个nginx容器,启动5个副本:

kubectl run nginx --image=nginx --replicas=5

可以看到,主要决定容器部署的编排环境的,取决于 --后面的参数,具体的参数对照表如下:

参数名称默认值描述
attachfalseIf true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called. Default false, unless '-i/--stdin' is set, in which case the default is true. With '--restart=Never' the exit code of the container process is returned.
commandfalseIf true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.
dry-runfalseIf true, only print the object that would be sent, without sending it.
env[]Environment variables to set in the container
exposefalseIf true, a public, external service is created for the container(s) which are run
hostport-1The host port mapping for the container port. To demonstrate a single-machine container.
image The image for the container to run.
image-pull-policy The image pull policy for the container. If left empty, this value will not be specified by the client and defaulted by the server
include-extended-apistrueIf true, include definitions of new APIs via calls to the API server. [default true]
labels Labels to apply to the pod(s).
leave-stdin-openfalseIf the pod is started in interactive mode or with stdin, leave stdin open after the first attach completes. By default, stdin will be closed after the first attach completes.
limits The resource requirement limits for this container. For example, 'cpu=200m,memory=512Mi'. Note that server side components may assign limits depending on the server configuration, such as limit ranges.
no-headersfalseWhen using the default or custom-column output format, don't print headers (default print headers).
pod-running-timeout1m0sThe length of time (like 5s, 2m, or 3h, higher than zero) to wait until at least one pod is running
port The port that this container exposes. If --expose is true, this is also the port used by the service that is created.
replicas1Number of replicas to create for this container. Default is 1.
requests The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.
restartAlwaysThe restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created, if set to 'OnFailure' a job is created, if set to 'Never', a regular pod is created. For the latter two --replicas must be 1. Default 'Always', for CronJobs Never.
rmfalseIf true, delete resources created in this command for attached containers.
save-configfalseIf true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
schedule A schedule in the Cron format the job should be run with.
show-allfalseWhen printing, show all resources (default hide terminated pods.)
show-labelsfalseWhen printing, show all labels as the last column (default hide labels column)
sort-by If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.
stdinfalseKeep stdin open on the container(s) in the pod, even if nothing is attached.
template Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/te...].

3.3. yaml部署

可以将构建容器的所有配置信息写在yaml文件上,然后通过yaml文件来创建。原则上来说有createapply两种方式,不过如下面的对比,建议都用apply

  • kubectl create -f xxx.yaml (不建议使用,无法更新,必须先delete)
  • kubectl apply -f xxx.yaml (创建+更新,可以重复使用)

下面重点关注 yaml文件的编写,一个基础的yaml部署文件主要包含DeploymentService两部分。

前面说过了,k8s通过各种Controller来管理pod的生命周期,Controller有很多种,其中就包括Deployment。而针对多副本的pod,就需要Service来提供外界统一的访问方式。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: demo-space
spec:
  replicas: 2
  selector:
    matchLabels:
      app: k8s-demo-nginx
  template:
    metadata:
      labels:
        app: k8s-demo-nginx
    spec:
      containers:
      - name: nginx
        image: docker.io/nginx
        resources:
          limits:
            cpu: "0.3"
            memory: "300Mi"
          requests:
            cpu: "0.2"
            memory: "200Mi"
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: k8s-nginx
  namespace: demo-space
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80 
    nodePort: 10280
    protocol: TCP
  selector:
   app: k8s-demo-nginx

名词解释:

  • apiVersion:当前配置格式的版本。
  • kind:定义了要创建的资源类型,这里有Deployment和Service。
  • metadate:是该资源的元数据,其中name是必需的元数据项;namespace指明资源创建所处的命名空间,如果不填,默认创建中default命名空间下。
  • spec:定义该资源的规格说明。
  • replicas:副本数量,默认为1。
  • template:定义了pod的创建模版。
  • template.metadate:定义了pod的元数据,至少要定义一个label,label的key和value可以任意指定。
  • selector.matchLabels:和pod元数据中的label对应,挑选匹配的pod做统一管理。
  • template.spec.resources:做pod的资源限制。requests定义了容器运行时最少需要的资源,limits定义了容器运行时最多能分配的资源。

3.4. 各种Port对比

前面示例的yaml配置中,定义了很多端口(containerPort、targetPort、port、nodePort),下面解释一下它们的不同作用:

1、containerPort

定义Pod的端口,在Deployment yaml中,申明Pod容器需要暴露的端口。

2、targetPort

也是定义Pod的端口,在Service yaml中,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。

3、port

定义Service的端口,:port 是提供给集群内部客户访问service的入口。集群内部访问该地址,是会经过kube-proxy再流入pod。

4、nodePort

定义Service的端口,:nodePort 是提供给集群外部客户访问service的入口。集群外部访问该地址,是会经过kube-proxy再流入pod。



启用nodePort外部端口映射,需要先配置spec.type=nodePort,如果不指定nodePort的端口后,服务器会自动分配一个端口。

3.5. 各种IP对比

Kubernetes集群里有三种IP地址,分别如下:

1、Node IP

Node节点的IP地址,即物理网卡的IP地址。当我们使用nodePort 端口映射时,任意Node接口的IP地址加上映射的nodePort,都能暴露服务对外地址。

但是有单点风险,如果服务对外的地址是用某个Node节点的IP,当这个Node节点挂了之后,该服务就无法访问。除非在外部再做一层负载均衡。

2、Pod IP

Pod的IP地址,即docker容器的IP地址,此为虚拟IP地址。

3、Cluster IP

Service的IP地址,此为虚拟IP地址。


KerryWu
641 声望159 粉丝

保持饥饿


« 上一篇
类加载机制
下一篇 »
gitflow工作流