1.什么是 Kubernetes?

  Kubernetes(通常写成“k8s”)是最开始由google设计开发最后贡献给Cloud Native Computing Foundation的开源容器集群管理项目。它的设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群。

  Kubernetes是近年来最具颠覆性的开源项目,作为一款强大的容器管理工具,在kubernetes的周围一间构建起了一个完整的开源生态链,值得所有人去钻研学习,Kubernetes具有如下几个特点:

  ①自动化容器的部署以及控制。

  ②容器规模的动态扩展伸缩(能够根据宿主机自身情况变化,如CPU占用率等)。

  ③将容器组织成组,构建出一组容器集群,能够提供服务的负载均衡。

  ④能够对容器进行动态升级,回滚到原版本。

  ⑤自带控制台,能够提供Web界面对容器集群进行管理。

 

  2.核心概念

  Kubernetes采用主从架构的方式进行管理,由Master上的各个组件将所部署的服务,Pod调度到Slave上面,并对其进行管理,监控其健康状态。资源的抽象主要包括:

  ①容器组(Pod):由位于统一节点的一个或多个容器组成。由Master进行资源分配,是Kubernetes资源调度的最小单位。

  ②服务(Service):能够通过yaml的方式对所构建的Pod,提供负载均衡,不随Pod的改变而变化,带有唯一的访问标示,如端口,IP,域名。

  ③复制控制器(Replication Controller):负责启动Pod并维护其健康状态,当一个Pod“优雅的”挂掉后,会根据复制控制器重新创建一个相同的Pod,保证Pod的数量。

  ④部署(Deployment):创建Pod,提供了一种更加简单的更新RC和Pod的机制,K8S版本1.2实现的。通过在Deployment中描述所期望的集群状态,Deployment Controller会将现在的集群状态在一个可控的速度下逐步更新成所期望的集群状态。Deployment主要职责同样是为了保证pod的数量和健康,90%的功能与RC完全一样,可以看做新一代的RC。

 

  Mster节点组成:

  Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd。      

  ①APIServer:APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。

  ②kubectl:Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用,是直接和APIServer交互的。      

  ③schedule:scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。      

  ④controller manager:如果说APIServer做的是“前台”的工作的话,那controller manager就是负责“后台”的。每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的。比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。      

  ⑤etcd:etcd是一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。

 

  Slave节点组成:    

  每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。      

  ①runtime:runtime指的是容器运行环境,目前Kubernetes支持docker和rkt两种容器。      

  ②kube-proxy:该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理方面:kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。另外kube-proxy还支持session affinity。          

  ③kubelet:Kubelet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是如果容器不是通过Kubernetes创建的,它并不会管理。本质上,它负责使Pod得运行状态与期望的状态一致。

  3.Kubernetes安装

  需要安装的镜像,kube安装包

  链接:https://pan.baidu.com/s/1hE4TTDOXv2Bll6OlfWMDog 密码:wujl

  三台主机,一台master两台node主机

  192.168.175.142 k8s1

  192.168.175.143 k8s2

  192.168.175.144 k8s3

  1.编辑/etc/hosts,保证各个节点能够正确解析

  图片.png

 

  2.保证本机DNS解析能够解析到自己的IP,这是个坑,在kubeadm初始化的时候,要是DNS解析不到本地的话,就会一直超时等待。

  以下两个IP解析的不是本地的DNS,而是vmware的网关,所以需要让虚拟机能够解析到自己

  图片.png

  修改nameserver,指定DNS为本机

  图片.png

  安装dnsmasq

  图片.png

  修改/etc/dnsmasq.conf文件

  图片.png

  重启dnsmasq服务

  重试一次,已经能够解析到自身的地址

  图片.png

 

  3.同步系统时间,关闭selinux,iptables,swap,设置内核参数

  图片.png

  #systemctl stop firewalld //关闭防火墙

  #swapoff on  //关闭swap,因为kubeadm初始化,不支持交换分区开启

  设置内核参数

  图片.png

  sysctl --system //加载内核参数

 

  4.安装docker

  # yum install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm  -y

  # yum install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm  -y

  # systemctl start docker && systemctl enable docker

  # systemctl start docker && systemctl enable docker

  导入kubernetes镜像       # 镜像包在网盘中下载  

  图片.png

  5.安装kube软件              # 软件包在网盘中下载    

  # tar -xvf kube-packages-1.10.1.tar
  # cd kube-packages-1.10.1
  # yum -y install local *.rpm
  # systemctl start kubelet && systemctl enable kubelet

  6.统一k8s与docker的驱动

  修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf

  修改cgroupfs

  图片.png

  7.kubeadm初始化master节点

  # kubeadm init --kubernetes-version=v1.10.1 --pod-network-cidr=10.244.0.0/16

  注意:版本必须要与安装的kube安装包一致

  初始化正确输出,下面的是用于将node添加到master的命令,需要记住!!要不然只能重新初始化。

  重新初始化,执行以下命令即可

  # kubeadm reset

  图片.png

 

  这个时候直接在node上面执行上述命令就能够将其添加入kubernetes集群当中

  如果以后再root管理kubernetes就直接在root下执行以下命令,不然就切换用户执行

  mkdir -p $HOME/.kube

  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

  查看各个节点的状态

  #kubectl get node -o wide

  图片.png

  8.部署网络flannel

  只需要在master上执行

    wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

    #版本信息:quay.io/coreos/flannel:v0.9.1-amd64
   

    #kubectl create -f  kube-flannel.yml

    网络部署完成,可以查看到每一个节点下都有flannel

    #ip a

    图片.png

  至此kubernetes集群配置完成

 

  4.dashboard配置

  # kubectl apply -f kubernetes-dashboard-http.yaml

  # kubectl apply -f admin-role.yaml
  # kubectl apply -f kubernetes-dashboard-admin.rbac.yaml

  yaml脚本在百度云盘中有

  查看运行情况

  # kubectl get pods --namespace=kube-system

   图片.png

  # kubectl describe svc kubernetes-dashboard --namespace=kebe-system 查看服务状态

  图片.png

  由上图可知dashboard的NodePort为31000,NodePort为对外在虚拟机显示的端口,可以通过该端口访问到dashboard的服务

  效果图如下:

  图片.png

 

  5.kubernetes基本应用

  1.配置单个pod

   配置一个pod,可以通过dashboard上书写yaml文件进行部署,也可以在命令行使用kubectl create创建

   下图为创建nginx Pod的一个简单部署,为了让其能够通过外部直接访问到,所以给他设置了Service负载

均衡,对外显示的NodePort端口为30088,NodePort指定的端口需要在30000-32767之间,这是外部通过

Service方位Pod的一种方式,还有就是Loadbalance。Service是根据Pod的Label标签来判断,那些Pod是

在该服务中,通过Pod的Label与Service的Selector选择器,来选定该服务中的容器组。

  selector:基于资源对象上绑定的标签信息,选择器可以通过指定标签键值对来过滤出一组特定的资源对象。

   图片.png

  Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组。因为Service是抽象的,所以在图表里通常看不到它们的存在,这也就让这一概念更难以理解。

  现在,假定有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)完成。这里有更多技术细节。

  2.部署Nginx应用(Deployment)

  Deployment需要区别apiVersion以及kind,Deployment部署正如前面所说的是能够成为新一代的Replication Controller而存在的

能够配置Pod集群,保证Pod高可用,并能够进行健康监测,在dashboard上能够较为清晰地了解到。

  replicas: 3 表示开启三个Pod容器组分布在两个Node节点上,当有一个Pod关闭,就会自动创建相同的Pod,保证Pod的数量在3。

还可以根据cpu负载数来调控Pod的数量。

  Label: app 设置标签,标签是一组键值对,用来标记所绑定对象,典型的就是Pod,进而可以分类。

  Deployment部署Nginx的Pod后,再通过Service的NodePort暴露出Pod容器组内服务的80端口在kubernetes对外的访问端口30089

的映射,便于客户端进行访问。

  图片.png

  根据上图yaml文件进行部署如下图,Pod容器组还在创建中,需要一点时间,若创建失败,则可以用

  # kubectl describe svc|pods nginx-service | nginx-deployment 查看详细信息

  图片.png

  部署成功,显示了各个Pod在哪一台node主机上,状态如何,Pod IP是多少

  图片.png

  通过30089端口正常访问:

  图片.png

 

 

  手动down掉一台Pod,马上就会创建一台相同配置的Pod保证高可用

  图片.png

 Deployment动态扩展

  扩展Pod数为4个

  # kubectl scale deployment nginx-deployment --replicas=4

  缩减Pod数为1个
  # kubectl scale deployment nginx-deployment --replicas=1

  最关键的功能就是可以弹性扩容根据CPU的占用率(需要结合资源限制一同使用),后面会进行实际演示,cpu使用率80%

  # kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=80