【云原生】Kubernetes - hippowc/hippowc.github.io GitHub Wiki
基础
Kubernetes (通常称为K8s,K8s是将8个字母“ubernete”替换为“8”的缩写) 是用于自动部署、扩展和管理容器化(containerized)应用程序的开源系统。
Kubernetes (希腊语"舵手" 或 "飞行员") 由Joe Beda,Brendan Burns和Craig McLuckie创立,并由其他谷歌工程师,包括Brian Grant和Tim Hockin进行加盟创作,并由谷歌在2014年首次对外宣布 。它的开发和设计都深受谷歌的Borg系统的影响,它的许多顶级贡献者之前也是Borg系统的开发者。在谷歌内部,Kubernetes的原始代号曾经是Seven,即星际迷航中友好的Borg(博格人)角色。Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。
基本概念
特点
- 可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
- 可扩展: 模块化, 插件化, 可挂载, 可组合
- 自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
- 快速部署应用,快速扩展应用
- 无缝对接新的应用功能
- 节省资源,优化硬件资源的使用
Kubernetes定义了一组构建块,它们可以共同提供部署、维护和扩展应用程序的机制。使用Kubernetes只需一个部署文件,使用一条命令就可以部署多层容器(前端,后台等)的完整集群, kubectl是和Kubernetes API交互的命令行程序。:
kubectl create -f single-config-file.yaml
集群
集群是一组节点,这些节点可以是物理服务器或者虚拟机,之上安装了Kubernetes平台。
Pod
Kubernetes的基本调度单元称为“pod”。它可以把更高级别的抽象内容增加到容器化组件。一个pod一般包含一个或多个容器,这样可以保证它们一直位于主机上,并且可以共享资源。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。Pod是短暂的,不是持续性实体。
Pod可以定义一个卷,例如本地磁盘目录或网络磁盘,并将其暴露在pod中的一个容器之中。pod可以通过Kubernetes API手动管理,也可以委托给控制器来管理。
Lable
一些Pod有Label。一个Label是attach到Pod的一对键/值对,用来传递用户定义的属性。比如,你可能创建了一个"tier"和“app”标签,通过Label(tier=frontend, app=myapp)来标记前端Pod容器,使用Label(tier=backend, app=myapp)标记后台Pod。然后可以使用Selectors选择带有特定Label的Pod,并且将Service或者Replication Controller应用到上面。
Replication Controller
Replication Controller确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了Replication Controller并且指定3个副本,它会创建3个Pod,并且持续监控它们。
Service
如果Pods是短暂的,那么重启时IP地址可能会改变,怎么才能从前端容器正确可靠地指向后台容器呢?Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组。假定有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
节点是物理或者虚拟机器,作为Kubernetes worker,通常称为Minion。每个节点都运行如下Kubernetes关键组件:
- Kubelet:是主节点代理。
- Kube-proxy:Service使用其将链接路由到Pod
- Docker或Rocket:Kubernetes使用的容器技术来创建容器
Kubernetes Master
集群拥有一个Kubernetes Master。Kubernetes Master提供集群的独特视角,并且拥有一系列组件,比如Kubernetes API Server。API Server提供可以用来和集群交互的REST端点。master节点包括用来创建和复制Pod的Replication Controller。
Kubernetes核心组件
Kubernetes遵循master-slave architecture。Kubernetes的组件可以分为管理单个的 node 组件和控制平面的一部分的组件。
etcd:分布式键值对(k,v)存储服务,存储整个集群的状态信息
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:提供集群日志采集、存储与查询
K3S 轻量级的 K8S
为了解决K8S占用资源过多,配置过于复杂的问题,Rancher推出了轻量级的K8S版本,k3s 本身包含了 k8s 的源码,所以本质上和 k8s 没有区别。但为了降低资源占用,k3s 和 k8s 还是有一些区别的,主要是:
- 使用了相比 Docker 更轻量的 containerd 作为容器运行时(Docker 并不是唯一的容器选择)
- 去掉了 k8s 的 Legacy, alpha, non-default features
- 用 sqlite3 作为默认的存储,而不是 etcd
- 其他的一些优化,最终 k3s 只是一个 binary 文件,非常易于部署
K3S的安装
https://get.k3s.io 这是 k3s 的安装脚本。我们直接运行这个脚本就可以安装 k3s。因为我们需要在 k3s 运行之前做一些事情,所以运行脚本的时候我们选择只安装,不启动 k3s
/ 下载脚本
curl -sfL https://get.k3s.io > install.sh
// 运行脚本
INSTALL_K3S_SKIP_START=true ./install.sh
镜像获取 && 启动 k3s
安装完之后要把之后 k3s 要用到的一些镜像下载到本地。因为 k3s 用的 pause 镜像地址是 gcr.io 的,国内是访问不了的。k3s 提供了 air-gap support 这个特性来支持镜像的本地预加载。这个特性本身是为了无法访问外网的环境准备的。国内的环境其实也是等于是没法访问外网,所以刚好可以用这个特性解决问题。
去 k3s 的 release 里面获取 k3s-airgap-images-$ARCH.tar $ARCH 是我们服务器的 CPU 架构。想办法把这个文件传到服务器上。然后运行:
sudo mkdir -p /var/lib/rancher/k3s/agent/images/
sudo cp ./k3s-airgap-images-$ARCH.tar /var/lib/rancher/k3s/agent/images/
最后运行:
systemctl start k3s
可以运行 kubectl 和 netstat -nplt 查看 k3s 是否正常启动。值得注意的是要看看 ipconfig 里是否出现了 flannel 的网络设备。之后的操作就和 k8s 一样了,用 kubectl 命令进行操作。
这个时候我们启动的是一个 k3s server(master节点),当然这个节点本身也是一个 worker Node。我们如果需要更多的节点,就需要手动加入更多。
加入节点
和 master 节点安装一样,首先获取安装脚本,然后运行
K3S_TOKEN=xxx K3S_URL=https://server-url:6443 INSTALL_K3S_SKIP_START=true ./install.sh
token 是从 master 节点的 /var/lib/rancher/k3s/server/node-token 文件里获取的。
复制镜像到本地目录,最后启动节点:
systemctl start k3s-agent
K8s部署
部署很复杂,先不关注