第一章 Kubernetes入门

第一章 Kubernetes入门

kubernetes是基于容器技术的分布式架构领先方案,是一个完备的分布式系统支撑平台。

kubernetes带来的好处:1)全面拥抱微服务;2)统可以随时随地整体“搬迁”到公有云上;3)Kubernetes系统架构具备了超强的横向扩容能力。

基本概念和术语

在Kubernetes中,Node、Pod、Replication Controller、Service等概念都可以看作一种资源对象,通过Kubernetes提供的Kubectl工具或者API调用进行操作,并保存在etcd中。

master

master上运行etcd server,API server,controller Manager,scheduler等进程,每个kubernetes集群需要有一个master节点来负责整个集群的管理和控制。

 node

node作为工作负载节点,运行以下一组关键进程。

kubelet:负责pod对应的容器创建,启停等任务,同时与master节点密切协作,实现集群管理的基本功能。

kube-proxy:实现kubernetes Service的通信与负载均衡机制的重要组件。

Docker Engine:Docker引擎,负责本机的容器创建和管理工作。

查看集群中多少个node:kubectl get nodes

查看某个Node的详细信息:kubectl describe node <node_name>

pod

Pod是Kubernetes的最基本操作单元,包含一个活多个紧密相关的容器,类似于豌豆荚的概念。一个Pod可以被一个容器化的环境看作应用层的“逻辑宿主机”(Logical Host)。一个Pod中的多个容器应用通常是紧耦合的。Pod在Node上被创建、启动或者销毁。

apiVersion: v1
kind: Pod
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
containers:
    - name: slave
      image: kubeguide/guestbook-redis-slave
      env:
      - name: GET_HOSTS_FROM
        value: env
      ports:
      - containerPort: 6379
      resources:
        requests:    该资源的最小申请量,系统必须满足要求
           memory:"64Mi"
           cpu:"250m"
         limits:       资源最大允许使用量,超过将重启
           memory:"128Mi"
           cpu:"500m"
View Code

 

Label

Label以key/value键值对的形式附加到各种对象上,如Pod、Service、RC、Node等。Label定义了这些对象的可识别属性,用来对它们进行管理和选择。Label可以在创建时附加到对象上,也可以在对象创建后通过API进行管理。

基于等式的Label Selector使用等式类的表达式来进行选择:

  1. name = redis-slave: 选择所有包含Label中key="name"且value="redis-slave"的对象;
  2. env != production: 选择所有包括Label中的key="env"且value不等于"production"的对象。

基于集合的Label Selector使用集合操作的表达式来进行选择:

  1. name in (redis-master, redis-slave): 选择所有包含Label中的key="name"且value="redis-master"或"redis-slave"的对象;
  2. name not in (php-frontend): 选择所有包含Label中的key="name"且value不等于"php-frontend"的对象。

将多个Label Selector进行组合

  name=redis-slave,env!=production
  name not in (php-frontend),env!=production

总结:使用label可以给对象创建多组标签,Lable和label Selector共同构成了Kubernetes系统中最核心的应用模型,使得被管理对象能够被精细的分组管理,同时实现了整个集群的高可用性。

RC

RC定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包括如下几个部分:

1)pod期待的副本数

2)用于刷选目标Pod的label Selector

3)当pod的副本数量小于预期数量的时候,用于创建新pod的pod模板。

apiVersion: v1
kind: ReplicationController
metadata:
name: redis-slave
labels: redis-slave
name: redis-slave
spec:
replicas: 2
selector:
name: redis-slave      标签name=redis-slave的pod存在2个副本
template:
metadata:
labels:
name: redis-slave
spec:
container:

        - name: slave
          image: kubeguide/guestbook-redis-slave
          env:
          - name: GET_HOSTS_FROM
            value: env
          ports:
          - containerPort: 6379
View Code

Deployment

deployment在内部使用Replica Set来实现目的,无论从Deployment的作用与目的,它的YAM定义,还是从它的具体命令行操作来看,我们都可以把它看做RC的一次升级。

HPA(pod横向自动扩容)

通过追踪分析RC控制的所有目标pod的负载变化情况,来确定是否需要针对性的调整目标pod的副本数,这是HPA的实现原理。

下面是HPA定义的案例:

apiVersion:autoscaling/v1
kind:HorizontalPodAutoscaler
metadata:
    name:php-apache
    namespace:default
spec:
    maxReplicas:10
    minReplicas:1
    scaleTargetRef:
        kind:Deployment
        name:php-apache
    targetCPUUtilizationPercentage:90

#根据上面的定义,我们知道这个HPA控制的目标对象为Deployment里一个名叫php-apache的Pod副本,这个副本的CPUUtilizationPercentage值超过90%就会触发自动扩容行为,伸缩的副本数介于1-10之间。

#通过kubectl create创建HPA资源对象 或者
 kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10
View Code

service

 

一个Service可以看作一组提供相同服务的Pod的对外访问接口。Service作用于哪些Pod是通过Label Selector来定义的。

Pod的IP地址和Service的Cluster IP地址

Pod的IP地址是Docker Daemon根据docker0网桥的IP地址段进行分配的,但Service的Cluster IP地址是Kubernetes系统中的虚拟IP地址,由系统动态分配。Service的Cluster IP地址相对于Pod的IP地址来说相对稳定,Service被创建时即被分配一个IP地址,在销毁该Service之前,这个IP地址都不会再变化了。而Pod在Kubernetes集群中生命周期较短,可能被ReplicationContrller销毁、再次创建,新创建的Pod将会分配一个新的IP地址。

部署一个负载均衡器,为这组pod开启一个对外服务端口如8000端口,并且将pod的endpoint列表加入8000端口的转发列表中,客户端就可以通过负载均衡器的对外IP地址+服务端口来访问此服务,而客户端的请求最后会被转发到哪个pod,则由负载均衡器算法决定。

外部访问service

Node IP:Node节点的IP地址       Pod IP:Pod的IP地址   Cluster IP:Service的IP地址

Kubernetes支持两种对外提供服务的Service的type定义:NodePort和LoadBalancer。

NodePort

apiVersion: v1
kind: Service
metadata:
    name: frontend
    labels:
        name: frontend
spec:
    type: NodePort       *
ports:
- port: 80
  nodePort: 30001       *
selector:
    name: frontend   

 LoadBalancer

如果云服务商支持外接负载均衡器,则可以通过spec.type=LoadBalaner定义Service,同时需要制定负载均衡器的IP地址。使用这种类型需要指定Service的nodePort和clusterIP。例如:

apiVersion: v1
kind: Service
metadata: {
"kind" "Service",
"apiVersion": "v1",
"metadata": {
"name": "my-service"
},
"spec": {
"type": "LoadBalaner",
"clusterIP": "10.0.171.239",
"selector": {
"app": "MyApp"
},
"ports": [
{
"protocol": "TCP",
"port": 80,
"targetPort": 9376,
"nodePort": 30061
}
],
},
"status": {
"loadBalancer": {
"ingress": [
{
"ip": "146.148.47.155"
}
]
}
}
}
View Code

volume(存储卷)

Volume是Pod中能够被多个容器访问的共享目录。当容器终止或者重启时,Volume中的数据也不会丢失。另外,Kubernetes支持多种类型的Volume,并且一个Pod可以同时使用任意多个Volume。Kubernetes提供了非常丰富的Volume类型,下面逐一进行说明。

#举例来说,我们要给之前的tomcat pod增加一个名字为dataVol的volume,并且Mount到容器的/mydata-data目录,则只要对pod的定义文件做如下修改:
template:
 metadata:
       labels:
          app:app-demo
          tier:frontend
spec:
 volumes:
 -name:datavol
  emptyDir:{}
 containers:
 -name:tomcat-demo
 image:tomcat
volumeMount:
  - mountPath:/mydata-data
    name:datavol
  1. EmptyDir:一个EmptyDir Volume是在Pod分配到Node时创建的。从它的名称就可以看出,它的初始内容为空。在同一个Pod中所有容器可以读和写EmptyDir中的相同文件。当Pod从Node上移除时,EmptyDir中的数据也会永久删除。
  2. hostPath:在Pod上挂载宿主机上的文件或目录。
    使用宿主主机的/data目录定义hostPath类型的volume:
    volumes:
    -name:"persistent-storage"
     hostPah:
        path:"/data"
  3. gcePersistentDisk:使用这种类型的Volume表示使用谷歌计算引擎(Google Compute Engine,GCE)上永久磁盘(Persistent Disk,PD)上的文件。与EmptyDir不同,PD上的内容会永久保存,当Pod被删除时,PD只是被卸载(Unmount),但不会被删除。需要注意的是,你需要先创建一个永久磁盘(PD)才能使用gcePersistentDisk。
  4. awsElasticBlockStore:与GCE类似,该类型的Volume使用Amazon提供的Amazon Web Service(AWS)的EBS Volume,并可以挂在到Pod中去。需要注意到是,需要首先创建一个EBS Volume才能使用awsElasticBlockStore。
  5. nfs:使用NFS(网络文件系统)提供的共享目录挂载到Pod中。在系统中需要一个运行中的NFS系统。
  6. iscsi:使用iSCSI存储设备上的目录挂载到Pod中。
  7. glusterfs:使用开源GlusterFS网络文件系统的目录挂载到Pod中。
  8. rbd:使用Linux块设备共享存储(Rados Block Device)挂载到Pod中。
  9. gitRepo:通过挂载一个空目录,并从GIT库clone一个git respository以供Pod使用。
  10. secret:一个secret volume用于为Pod提供加密的信息,你可以将定义在Kubernetes中的secret直接挂载为文件让Pod访问。secret volume是通过tmfs(内存文件系统)实现的,所以这种类型的volume总是不会持久化的。
  11. persistentVolumeClaim:从PV(PersistentVolume)中申请所需的空间,PV通常是一种网络存储,不属于任何node,例如GCEPersistentDisk、AWSElasticBlockStore、NFS、iSCSI等。

namespace

Namespace(命名空间)是Kubernetes系统中的另一个非常重要的概念,通过将系统内部的对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。
Kubernetes集群在启动后,会创建一个名为“default”的Namespace,通过Kubectl可以查看到。
使用Namespace来组织Kubernetes的各种对象,可以实现对用户的分组,即“多租户”管理。对不同的租户还可以进行单独的资源配额设置和管理,使得整个集群的资源配置非常灵活、方便。

kubectl get namespaces    --查看命名空间

在yaml中定义名为development的namespace:
apiVersion:v1
kind:Namespace
metadata:
  name:development

将一个名为busybox的pod放入到development命名空间中:
apiVersion:v1
kind:Pod
metadata:
  name:busybox
  namespace:development
spec:
  containers:
  ..............
............

在对应的命名空间中查找pod:
kubectl get pods --namespace=development

Annotation

Annotation与Label类似,也使用key/value键值对的形式进行定义。Label具有严格的命名规则,它定义的是Kubernetes对象的元数据(Metadata),并且用于Label Selector。Annotation则是用户任意定义的“附加”信息,以便于外部工具进行查找。
用Annotation来记录的信息包括:

    1. build信息、release信息、Docker镜像信息等,例如时间戳、release id号、PR号、镜像hash值、docker registry地址等;
    2. 日志库、监控库、分析库等资源库的地址信息;
    3. 程序调试工具信息,例如工具名称、版本号等;
    4. 团队的联系信息,例如电话号码、负责人名称、网址等。

总结

Kubernetes集群由两类节点组成:Master和Node。在Master上运行etcd、API Server、Controller Manager和Scheduler四个组件,其中后三个组件构成了Kubernetes的总控中心,负责对集群中所有资源进行管理和调度。在每个Node上运行Kubelet、Proxy和Docker Daemon三个组件,负责对本节点上的Pod的生命周期进行管理,以及实现服务代理的功能。另外在所有节点上都可以运行Kubectl命令行工具,它提供了Kubernetes的集群管理工具集。

参考: http://www.jianshu.com/p/63ffc2214788

posted @ 2017-09-20 17:20  gaojy  阅读(207)  评论(0编辑  收藏  举报