Kubernetes零基础快速入门!初学者必看!

Kubernetes零基础快速入门!初学者必看!

起源

Kubernetes 源自于 google 内部的服务编排系统 - borg,诞生于2014年。它汲取了google 十五年生产环境的经验积累,并融合了社区优秀的idea和实践经验。

名字

Kubernetes 这个名字,起源于古希腊,是舵手的意思,所以它的 logo 即像一张渔网又像一个罗盘,谷歌选择这个名字还有一个深意:既然docker把自己比作一只鲸鱼,驮着集装箱,在大海上遨游,google 就要用Kubernetes去掌握大航海时代的话语权,去捕获和指引着这条鲸鱼按照主人设定的路线去巡游。

核心

得益于 docker 的特性,服务的创建和销毁变得非常快速、简单。Kubernetes 正是以此为基础,实现了集群规模的管理、编排方案,使应用的发布、重启、扩缩容能够自动化。

Kubernetes - 认知

集群设计

Kubernetes 可以管理大规模的集群,使集群中的每一个节点彼此连接,能够像控制一台单一的计算机一样控制整个集群。

集群有两种角色,一种是 master ,一种是 Node(也叫worker)。

  • master 是集群的"大脑",负责管理整个集群:像应用的调度、更新、扩缩容等。
  • Node 就是具体"干活"的,一个Node一般是一个虚拟机或物理机,它上面事先运行着 docker 服务和 kubelet 服务( Kubernetes 的一个组件),当接收到 master 下发的"任务"后,Node 就要去完成任务(用 docker 运行一个指定的应用)

 

Deployment - 应用管理者

当我们拥有一个 Kubernetes 集群后,就可以在上面跑我们的应用了,前提是我们的应用必须支持在 docker 中运行,也就是我们要事先准备好docker镜像。

有了镜像之后,一般我们会通过Kubernetes的 Deployment 的配置文件去描述应用,比如应用叫什么名字、使用的镜像名字、要运行几个实例、需要多少的内存资源、cpu 资源等等。

有了配置文件就可以通过Kubernetes提供的命令行客户端 - kubectl 去管理这个应用了。kubectl 会跟 Kubernetes 的 master 通过RestAPI通信,最终完成应用的管理。
比如我们刚才配置好的 Deployment 配置文件叫 app.yaml,我们就可以通过
"kubectl create -f app.yaml" 来创建这个应用啦,之后就由 Kubernetes 来保证我们的应用处于运行状态,当某个实例运行失败了或者运行着应用的 Node 突然宕机了,Kubernetes 会自动发现并在新的 Node 上调度一个新的实例,保证我们的应用始终达到我们预期的结果。

 

Pod - Kubernetes最小调度单位

其实在上一步创建完 Deployment 之后,Kubernetes 的 Node 做的事情并不是简单的docker run 一个容器。出于像易用性、灵活性、稳定性等的考虑,Kubernetes 提出了一个叫做 Pod 的东西,作为 Kubernetes 的最小调度单位。所以我们的应用在每个 Node 上运行的其实是一个 Pod。Pod 也只能运行在 Node 上。如下图:

那么什么是 Pod 呢?Pod 是一组容器(当然也可以只有一个)。容器本身就是一个小盒子了,Pod 相当于在容器上又包了一层小盒子。这个盒子里面的容器有什么特点呢?

  • 可以直接通过 volume 共享存储。
  • 有相同的网络空间,通俗点说就是有一样的ip地址,有一样的网卡和网络设置。
  • 多个容器之间可以“了解”对方,比如知道其他人的镜像,知道别人定义的端口等。

至于这样设计的好处呢,还是要大家深入学习后慢慢体会啦~

Service - 服务发现 - 找到每个Pod

上面的 Deployment 创建了,Pod 也运行起来了。如何才能访问到我们的应用呢?

最直接想到的方法就是直接通过 Pod-ip+port 去访问,但如果实例数很多呢?好,拿到所有的 Pod-ip 列表,配置到负载均衡器中,轮询访问。但上面我们说过,Pod 可能会死掉,甚至 Pod 所在的 Node 也可能宕机,Kubernetes 会自动帮我们重新创建新的Pod。再者每次更新服务的时候也会重建 Pod。而每个 Pod 都有自己的 ip。所以 Pod 的ip 是不稳定的,会经常变化的。

面对这种变化我们就要借助另一个概念:Service。它就是来专门解决这个问题的。不管Deployment的Pod有多少个,不管它是更新、销毁还是重建,Service总是能发现并维护好它的ip列表。Service对外也提供了多种入口:

  1. ClusterIP:Service 在集群内的唯一 ip 地址,我们可以通过这个 ip,均衡的访问到后端的 Pod,而无须关心具体的 Pod。
  2. NodePort:Service 会在集群的每个 Node 上都启动一个端口,我们可以通过任意Node 的这个端口来访问到 Pod。
  3. LoadBalancer:在 NodePort 的基础上,借助公有云环境创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort。
  4. ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。

好,看似服务访问的问题解决了。但大家有没有想过,Service是如何知道它负责哪些 Pod 呢?是如何跟踪这些 Pod 变化的?

最容易想到的方法是使用 Deployment 的名字。一个 Service 对应一个 Deployment 。当然这样确实可以实现。但k ubernetes 使用了一个更加灵活、通用的设计 - Label 标签,通过给 Pod 打标签,Service 可以只负责一个 Deployment 的 Pod 也可以负责多个 Deployment 的 Pod 了。Deployment 和 Service 就可以通过 Label 解耦了。

RollingUpdate - 滚动升级

滚动升级是Kubernetes中最典型的服务升级方案,主要思路是一边增加新版本应用的实例数,一边减少旧版本应用的实例数,直到新版本的实例数达到预期,旧版本的实例数减少为0,滚动升级结束。在整个升级过程中,服务一直处于可用状态。并且可以在任意时刻回滚到旧版本。

 

Kubernetes - 入门实践

Deployment 实践

首先配置好 Deployment 的配置文件(这里用的是 tomcat 镜像)

[ app.yaml ]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 2
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
        ports:
        - containerPort: 8080
通过 kubectl 命令创建服务
# 创建应用
$ kubectl create -f app.yaml
Deployment.apps/web created

# 等待一会后,查看 Pod 调度、运行情况。
# 我看可以看到 Pod 的名字、运行状态、Pod 的 ip、还有所在Node的名字等信息
$ kubectl get Pods -o wide
NAME                       READY     STATUS    RESTARTS   AGE   IP       NODE
web-c486dd5c4-86fxm        1/1       Running   0          1m        172.24.3.13     node-01
web-c486dd5c4-zxdbb        1/1       Running   0          1m        172.24.0.149    node-02

Service 实践

通过上面创建的 Deployment 我们还没法合理的访问到应用,下面我们就创建一个 service 作为我们访问应用的入口。

首先创建service配置

[ service.yaml ]

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  ports:
  - port: 80 # 服务端口
    protocol: TCP
    targetPort: 8080 # 容器端口
  selector:
    app: web # 标签选择器,这里的app=web正是我们刚才建立app
创建服务
# 创建
$ kubectl create -f service.yaml
service/web created

# 查看
$ kubectl get service
NAME     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
web      ClusterIP   10.95.189.143   <none>        80/TCP    9s
访问服务

接下来就可以在任意节点通过ClusterIP负载均衡的访问后端应用了

# 在任意 Node 上访问tomcat服务
$ curl -I 10.95.189.143
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked

One More Thing

好啦~ 以上就是Kubernetes入门的全部内容,看懂这篇文章,你就整体上大概了解了Kubernetes。


转载于:https://www.imooc.com/article/285913?block_id=tuijian_wz#comment

Kubernetes是什么?有什么核心组件?

1.1 Kubernetes 是什么?
先看官方介绍:
Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications. 用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。
翻译成大白话就是:“Kubernetes 是负责自动化运维管理多个 Docker 程序的集群”。那么问题来了:Docker 运行可方便了,为什么要用Kubernetes,它有什么优势?

Kubernetes 是用于自动部署、扩展和管理容器化(containerized)应用程序的开源系统。

它旨在提供“跨主机集群的自动部署、扩展以及运行应用程序容器的平台”。它支持一系列容器工具, 包括Docker等。CNCF于2017年宣布首批Kubernetes认证服务提供商(KCSPs),包含IBM、MIRANTIS、华为、inwinSTACK迎栈科技等服务商。
插一句题外话:
为什么 Kubernetes 要叫 Kubernetes 呢?维基百科已经交代了(老美对星际是真的痴迷):
Kubernetes(在希腊语意为“舵手”或“驾驶员”)由 Joe Beda、Brendan Burns 和 Craig McLuckie 创立,并由其他谷歌工程师,包括 Brian Grant 和 Tim Hockin 等进行加盟创作,并由谷歌在 2014 年首次对外宣布 。该系统的开发和设计都深受谷歌的 Borg 系统的影响,其许多顶级贡献者之前也是 Borg 系统的开发者。在谷歌内部,Kubernetes 的原始代号曾经是 Seven,即星际迷航中的 Borg(博格人)。Kubernetes 标识中舵轮有七个轮辐就是对该项目代号的致意。
为什么 Kubernetes 的缩写是 K8S 呢?我个人赞同 Why Kubernetes is Abbreviated k8s[1] 中说的观点“嘛,写全称也太累了吧,不如整个缩写”。其实只保留首位字符,用具体数字来替代省略的字符个数的做法,还是比较常见的。
1.2 为什么是 Kubernetes?
试想下传统的后端部署办法:把程序包(包括可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。
有问题吗?显然有!最大的一个问题在于:如果服务的请求量上来,已部署的服务响应不过来怎么办?传统的做法往往是,如果请求量、内存、CPU 超过阈值做了告警,运维马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。
问题出现了:从监控告警到部署服务,中间需要人力介入!那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢?
这,就是 Kubernetes 要做的事情:自动化运维管理 Docker(容器化)程序。
1.3 Kubernetes 怎么做?
我们已经知道了 Kubernetes 的核心功能:自动化运维管理多个容器化程序。那么 Kubernetes 怎么做到的呢?这里,我们从宏观架构上来学习 Kubernetes 的设计思想。首先看下图,图片来自文章 Components of Kubernetes Architecture[2]:

Kubernetes 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责核心的调度、管理和运维,Slave 节点则在执行用户的程序。但是在 Kubernetes 中,主节点一般被称为 Master Node 或者 Head Node(本文采用 Master Node 称呼方式),而从节点则被称为Worker Node 或者 Node(本文采用 Worker Node 称呼方式)。
要注意一点:Master Node 和 Worker Node 是分别安装了 Kubernetes 的 Master 和 Woker 组件的实体服务器,每个 Node 都对应了一台实体服务器(虽然 Master Node 可以和其中一个 Worker Node 安装在同一台服务器,但是建议 Master Node 单独部署),所有 Master Node 和 Worker Node 组成了 Kubernetes 集群,同一个集群可能存在多个 Master Node 和 Worker Node。

首先来看Master Node都有哪些组件:

  • API Server,Kubernetes 的请求入口服务。API Server 负责接收 Kubernetes 所有请求(来自 UI 界面或者 CLI 命令行工具),然后,API Server 根据用户的具体请求,去通知其他组件干活。
  • Scheduler,Kubernetes 所有 Worker Node 的调度器。当用户要部署服务时,Scheduler 会选择最合适的 Worker Node(服务器)来部署。
  • Controller Manager,Kubernetes 所有 Worker Node 的监控器。Controller Manager 有很多具体的 Controller,在文章 Components of Kubernetes Architecture[2] 中提到的有 Node Controller、Service Controller、Volume Controller 等。Controller 负责监控和调整在 Worker Node 上部署的服务的状态,比如用户要求 A 服务部署 2 个副本,那么当其中一个服务挂了的时候,Controller 会马上调整,让 Scheduler 再选择一个 Worker Node 重新部署服务。
  • etcd,Kubernetes 的存储服务。etcd 存储了 Kubernetes 的关键配置和用户配置,Kubernetes 中仅 API Server 才具备读写权限,其他组件必须通过 API Server 的接口才能读写数据(见 Kubernetes Works Like an Operating System[3])。

接着来看Worker Node的组件,笔者更赞同 HOW DO APPLICATIONS RUN ON KUBERNETES[4] 文章中提到的组件介绍:

  • Kubelet,Worker Node 的监视器,以及与 Master Node 的通讯器。Kubelet 是 Master Node 安插在 Worker Node 上的“眼线”,它会定期向 Master Node 汇报自己 Node 上运行的服务的状态,并接受来自 Master Node 的指示采取调整措施。
  • Kube-Proxy,Kubernetes 的网络代理。私以为称呼为 Network-Proxy 可能更适合?Kube-Proxy 负责 Node 在 Kubernetes 的网络通讯、以及对外部网络流量的负载均衡。
  • Container Runtime,Worker Node 的运行环境。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如 Docker Engine。大白话就是帮忙装好了 Docker 运行环境。
  • Logging Layer,Kubernetes 的监控状态收集器。私以为称呼为 Monitor 可能更合适?Logging Layer 负责采集 Node 上所有服务的 CPU、内存、磁盘、网络等监控项信息。
  • Add-Ons,Kubernetes 管理运维 Worker Node 的插件组件。有些文章认为 Worker Node 只有三大组件,不包含 Add-On,但笔者认为 Kubernetes 系统提供了 Add-On 机制,让用户可以扩展更多定制化功能,是很不错的亮点。

Kubernetes 特点

1、可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)

2、可扩展: 模块化, 插件化, 可挂载, 可组合

3、自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展

4、快速部署应用,快速扩展应用

5、无缝对接新的应用功能

6、节省资源,优化硬件资源的使用

Kubernetes主要由以下几个核心组件组成:

组件名称

说明

etcd

保存了k8s所有数据的存储及操作记录,对于K8s集群来说,etcd是相当重要的,一旦故障,可能导致整个集群的瘫痪或者数据丢失;

apiserver

提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

controller manager

负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

scheduler

负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

kubelet

负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;

Container runtime

负责镜像管理以及Pod和容器的真正运行(CRI);

kube-proxy

负责为Service提供cluster内部的服务发现和负载均衡;

 

除了核心组件,还有一些推荐的Add-ons:

组件名称

说明

kube-dns

负责为整个集群提供DNS服务

Ingress Controller

为服务提供外网入口

Heapster

提供资源监控

Dashboard

提供GUI

Federation

提供跨可用区的集群

Fluentd-elasticsearch

提供集群日志采集、存储与查询

 

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示:

分层说明:

分层结构

说明

核心层

Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境

应用层

部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)

管理层

系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)

接口层

kubectl命令行工具、客户端SDK以及集群联邦

生态系统

在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴

Kubernetes外部

日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等

Kubernetes内部

CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

 

总结来看,Kubernetes 的 Master Node 具备:请求入口管理(API Server),Worker Node 调度(Scheduler),监控和自动调节(Controller Manager),以及存储功能(etcd);而 Kubernetes 的 Worker Node 具备:状态和监控收集(Kubelet),网络和负载均衡(Kube-Proxy)、保障容器化运行环境(Container Runtime)、以及定制化功能(Add-Ons)。

posted @ 2020-12-31 16:36  西瓜君~  阅读(799)  评论(0编辑  收藏  举报