K8s 提供的功能
-
服务发现和负载均衡: K8s 可以通过 DNS 或者 IP 来暴露一个容器。如果对一个容器的请求过高,K8s 可以通过负载均衡来分配流量
-
存储管理: K8s 允许使用本地或者第三方存储来保存持久化文件
-
自动部署回滚: K8s 允许指定部署容器的状态,控制状态切换的时间
-
自动装箱: 可以理解为通过指定需要的 CPU,内存,K8s 会为容器自动分配所在的 node
-
自动愈合: K8s 可以自动重启失败的容器,并删除健康检查失败的容器
-
密钥和配置管理: K8s 可以单独存储密码,SSH Key 等关键信息,这样更新这些密码信息时并不需要重新生成镜像
K8s 的组件
一个 K8s 集群由 Node 和 Control plane 两大组件构成
- Node:一个 node 对应一个服务器,可以是物理机,可以是 VM,也可以是云上的服务器(比如 EC2)。node 上会运行 pod(可以简单理解为容器),pod 是应用的具体载体,所以 node 是为应用 pod 提供计算服务的设备。
- Control plane:是用来管理 Node 的组件,Control Plane 可以由一个或多个服务器组成。
提示:Node 和 Control plane 可以理解为一个软件的两个组成部分,它们可以安装在一台机器上也可以分开安装在不同的机器上
K8s 集群结构如下图
图 2
说明:
在 AWS 中,当我们创建 EKS 集群的时候,创建的就是图中 Control Plane 这部分。AWS 会帮我们维护 Control Plane,并且不收费。
node 部分对应的就是 AWS 的 EC2,我们选定 EC2 的型号,数量之后,AWS 会启动 EC2 并在其上安装 K8s 相应的软件。
当我们自己做实验时,可以在本机安装一套 K8s,完整包括了 Node 和 Control Plane 两个组件。
下面我们简单说明一下 Control Plane 和 Nodes 各自拥有的主要组件。
这一部分内容主要涉及到 K8s 的管理,对于单纯使用 K8s 而言,这些内容了解即可。
Control Plane
Control Plane 的组件理论上可以运行在集群中的任意服务器上,但一般会默认装在同一台机器上。
对于 AWS 这样的云环境,Control Plane 完全由 AWS 托管,不需要我们进行维护。
Control Plane 主要由以下部分构成
-
kube-apiserver: 用来暴露 K8s API。比如当我们用 kubectl 命令行部署 pod 的时候,Kubectl 命令行就是与 kube-apiserver 进行通信
-
etcd: 键值数据库,用来存放 K8s 自身运行时需要的信息
-
kube-scheduler: 为新建的,没有指定 node 的 pod,根据资源要求、policy 设定等安排工作 node
-
kube-controller-manager:有各种 controller 控制不同的功能
- Node controller: 负责通知及响应 node 宕机
- Job controller: 负责运行一次性任务
- Endpoints controller: 产生 Endpoints 对象(Joins service 和 pods)
- Service Account & Token controllers: 创建默认帐号及 API access tokens
-
cloud-controller-manager: 为各个云平台提供支持的服务,与云平台相关,在本地服务器运行 K8s 时没有此组件
Nodes
- kubelet:在每个 node 运行的代理程序,管理 Pod 中运行的容器,不负责非 Pod 中运行的容器(比如,我 node 上用 docker 命令单独启动的容器不在 kubelet 管辖范围内)
- kube-proxy: 在 node 上运行的网络代理,维护 K8s 的网络规则,这些规则控制集群内外访问 Pods 的通信
- Container runtime:容器的运行环境,比如说 Docker,这是需要单独安装的
- Addons: 插件利用 K8s 资源去实现集群的一些特性
- DNS: K8s DNS 是一个 DNS 服务器,它与环境中的其它 DNS 服务器一起负责 K8s 服务的 DNS 解析工作。K8s 启动容器时,DNS 会自动加入容器的 DNS 搜索列表中
- Web UI(Dashboard): 提供图像界面管理 K8s
- Container Resource Monitoring: 记录各种 metric,但 K8s 只提供了 API 接口,无法直接使用
- Cluster-level Logging: 容器中默认日志输出到标准输出,会随着容器的消灭而灭亡,所以日志需要输出到外挂持久存储或者输出到第三方日志存储应用
K8s 对象
“在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态”
这是官网上 K8s 对象的定义,非常抽象。简单理解就是,在 K8s 中跑的一个 Pod 就是一个对象,在 K8s 中建的 Namespace,Service 等也是对象。
我们用 K8s 时,创建的所有内容都是 K8s 对象。以后在实际使用中,我们也是主要和 K8s 对象打交道。
对象的 Spec 和 Status
对象用 Spec 来描述其定义,用 Status 指定其运行时所在的状态。
K8s 会根据对象的 Spec 创建对象,根据 Status 来维护对象的运行情况(比如,pod failed 的时候 K8s 会自动帮你重启对象)。
描述对象
K8s 利用 yaml 文件来描述对象的 Spec 和 Status。
我们在 Yaml 文件中定义好需要的对象,然后利用 K8s API(kubectl 命令)把 Yaml 文件中的对象创建到 K8s 中。
下面是官网的一个 Yaml 文件“deployment.yaml”的例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
说明:
我们在这个 Yaml 文件中指定对象的类型为“Deployment”,运行容器的镜像为“nginx:1.14.2”并打开 80 端口
这个文件写好之后,我们可以用下列命令创建 Deployment
kubectl apply -f deployment.yaml --record