k8s
简介
Kubernetes 是一个开源的容器编排引擎和容器集群管理工具,用来对容器化应用进行自动化部署、扩缩和管理。
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。 k8s 这个缩写是因为 k 和 s之间有 8 个字符。 Google 在 2014 年开源了Kubernetes 项目。
Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上,结合了社区中最优秀的想法和实践。它之所以能够迅速流行起来,是因为它的许多功能高度契合互耳关网大厂的部署和运维需求。
Kubernetes 可以提供:
- 服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。如果进入容器的流量很大 Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。 - 存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。 - 自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为期望状态。例如,你可以自动化Kubernetes 来为你的部署创建新容器,删除现有容器并将它们的所有资源用于新容器。也可以是方便的实现金丝雀部署(canary deployment)。 - 自动完成装箱计算
你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。 - 自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。 - 密钥与配置管理Kubernetes 允许你存储和管理敏感信息,例如密码、 OAuth 令牌和 ssh 密钥。你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
云原生
2015 年由 Google 、Redhat 等大型云计算厂商以及一些开源公司共同牵头成立了 CloudNative Computing Foundation (云原生计算基金会)云原生计算基金会 (CNCF) 致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。云原生的概念从此广泛传播。
云原生定义
Kubernetes 是 CNCF 托管的第一个开源项目。因此现在提到云原生,往往我们都把它与kubernetes 联系起来。
- 通俗解释
使用 Java 、Go 、PHP 、Python 等语言开发的应用我们称之为原生应用,在设计和开发这些应用时,使他们能够运行在云基础设施(或 kubernetes )上,从而使应用具备可弹性扩展的能力,我们称之为云原生应用。我们可以将云原生理解为以容器技术为载体、基于微服务架构思想的一套技术体系和方法论。
kubernetes 架构
一个 Kubernetes 集群至少包含一个控制平面 (control plane), 以及一个或多个工作节点(worker node)
- 控制平面( Contro | Plane) :控制平面负责管理工作节点和维护集群状态。所有任务分配都来自于控制平面。
- 工作节点 (Worker Node) :工作节点负责执行由控制平面分配的请求任务,运行实际的应用和工作负载。
控制平面
控制平面组件会为集群做出全局决策,比如资源的调度、检测和响应集群事件。
kube—apiserver
如果需要与 Kubernetes 集群进行交互,就要通过 API。
apiserver
是 Kubernetes 控制平面的前端,用于处理内部和外部请求。
kube—scheduler
集群状况是否良好?如果需要创建新的容器,要将它们放在哪里?这些是调度程序需要关注的问题。
scheduler
调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点。
kube—controller—manager
控制器负责实际运行集群,controller-manager
控制器管理器则是将多个控制器功能合而为一,降低了程序的复杂性。
controller-manager
包含了这些控制器:
- 节点控制器 (Node Controller) :负责在节点出现故障时进行通知和响应
- 任务控制器 (Job Controller) :监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
- 端点控制器 (Endpoints Controller) :填充端点 (Endpoints) 对象(即加入Service 与 Pod)
- 服务帐户和令牌控制器 (Service Account & Token Controllers) :为新的命名空间创建默认帐户和 API 访问令牌
cloud—controller—manager
控制平面还包含一个可选组件 cloud-cont rotler-manager
云控制器管理器 (Cloud Controller Manager) 允许你将你的集群连接到云提供商的 API之上,并将与该云平台交互的组件同与你的集群交互的组件分离开来。
如果在自己的环境中运行 Kubernetes ,或者在本地计算机中运行学习环境,所部署的集群不需要有云控制器管理器。
etcd
etcd
是一个键值对数据库,用于存储配置数据和集群状态信息
Node组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境
kubelet
kubelet 会在集群中每个节点 (node) 上运行。它保证容器 (containers) 都运行在Pod 中。当控制平面需要在节点中执行某个操作时, kubelet 就会执行该操作。
kube—proxy
kube-proxy 是集群中每个节点 (node) 上运行的网络代理,是实现 Kubernetes 服务(Service) 概念的一部分。kube-proxy 维护节点网络规则和转发流量,实现从集群内部或外部的网络与 Pod 进行网络通信。
容器运行时 (Container Runtime)
容器运行环境是负责运行容器的软件。Kubernetes 支持许多容器运行环境,例如 containerd 、 docker 或者其他实现了Kubernetes CRI(容器运行环境接囗)的容器。
组件关系
Kubectl
kubectl 是一个kvbernetes 命令行工具。
kubectl 使用 Kubernetes API 与 Kubernetes 集群的控制面进行通信,可以使用kubectl 部署应用程序、检查和管理群集资源以及查看日士
K3s
为什么使用 K3sK3s 是一个轻量级的、完全兼容的 Kubernetes 发行版本。非常适合初学者。
K3s 将所有 Kubernetes 控制平面组件都封装在单个二进制文件和进程中,文件大小< 100M ,占用资源更小,且包含了 kubernetes 运行所需要的部分外部依赖和本地存储提供程序。
K3s 提供了离线安装包,安装起来非常方便,可以避免安装过程中遇到各种网络资源访问问题。
K3s 特别适用于边缘计算、物联网、嵌入式和 ARM 移动端场景。
提示:K3s 完全兼容 kubernetes ,二者的操作是一样的,使用 k3s 完全满足我们学习kubernetes 的要求,课程的最后,我们再使用 kubeadm 安装一个完整的集群。
安装
安装需要三台虚拟机(放在同一虚拟机下也可以),分别是k8s-master
,k8s-worker1
,k8s-worker2
在线安装
The install.sh
script provides a convenient way to download K3s and add a service to systemd or openrc.
To install k3s as a service, run:
1 | curl -sfL https://get.k3s.io | sh - |
国内镜像
1 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
A kubeconfig file is written to /etc/rancher/k3s/k3s.yaml
and the service is automatically started or restarted. The install script will install K3s and additional utilities, such as kubectl
, crictl
, k3s-killall.sh
, and k3s-uninstall.sh
, for example:
1 | sudo kubectl get nodes |
K3S_TOKEN
is created at /var/lib/rancher/k3s/server/node-token
on your server. To install on worker nodes, pass K3S_URL
along with K3S_TOKEN
environment variables, for example:
1 | curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=XXX sh - |
国内镜像
1 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://172.17.1.158:6443 K3S_TOKEN=K108f01130e73a8c3f971ec59b90c7af8a3e6f7bec22425cc2b658d822db791e24e::server:144a10db80a6d2b877d2cf6502598ac1 sh -
离线安装
下载安装包
- 下载安装脚本
install.sh
:https://get.k3s.io/ - 下载
k3s
二进制文件 - 下载必要的
image
这些文件都可以在github仓库中获取:https://github.com/k3s-io/k3s
- 下载安装脚本
执行安装脚本
将
k3s
二进制文件移动到/usr/local/bin
目录,并添加执行权限1
2mv k3s /usr/local/bin
chmod +x /usr/local/bin将镜像移动到
/var/lib/rancher/k3s/agent/images/
目录(无需解压)1
2mkdir -p /var/lib/rancher/k3s/agent/images/
mv k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/在
k8s-master
节点执行:1
2
3
4chmod +x install.sh
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
kubectl get node
cat /var/lib/rancher/k3s/server/node-token在
k8s-worker1
和k8s-worker2
节点执行1
2
3
4INSTALL_K3S_SKIP_DOWNLOAD=true \
K3S_URL=https://k8s-master:6443 \
K3S_TOKEN=XXX \
./install.sh注意使用的是https协议
镜像加速
由于 kubernetes 从 V1.24
版本开始默认使用 containerd
,需要修改 containerd
的配置文件,才能让 Pod 的镜像使用镜像加递器。配置文件路径一般为 /etc/containerd/config.toml
,详见阿里云镜像加速。
在 K3s 中配置镜像仓库
K3s 会自动生成 containerd 的配置文件 /var/lib/rancher/k3s/agent/etc/containerd/config.toml
, 不要直接修改这个文件, k3s 重启后修改会丢失。为了简化配置, K3s 通过 /etc/rancher/k3s/registries.yaml
文件来配置镜像仓库, K3s会在启动时检查这个文件是否存在。我们需要在每个节点上新建 /etc/rancher/k3s/registries.yaml
文件,配置内容如下:
1 | mirrors: |
镜像仓库从阿里云系统上登录注册账号获得,每个账号都是独立的镜像地址
网址:cr.console.aliyun.com
配置后重启k3s
1 | systemctl restart k3s |
Pod(容器集)
Pod 是包含一个或多个容器的容器组,是 Kubernetes 中创建和管理的最小对象。
Pod 有以下特点:
- Pod是kubernetes中最小的调度单位(原子单元),Kubernetes直接管理Pod而不是容器。
- 同一个Pod中的容器总是会被自动安排到集群中的同一节点(物理机或虚拟机)上,并且一起调度。
- Pod可以理解为运行特定应用的“逻辑主机”,这些容器共享存储、网络和配置声明(如资源限制)。
- 每个 Pod 有唯一的 IP 地址。 IP地址分配给Pod,在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,Pod 内的容器可以使用
localhost
互相通信。
例如,你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 “边车 (sidercar)” 容器负责从远端更新这些文件,如下图所示:
创建和管理Pod
1 | kubectl run mynginx --image=nginx |
Deployment(部署)与ReplicaSet(副本集)
Deployment是对ReplicaSet和Pod更高级的抽象。
它使Pod拥有多副本,自愈,扩缩容、滚动升级等能力。
ReplicaSet(副本集)是一个Pod的集合。
它可以设置运行Pod的数量,确保任何时间都有指定数量的 Pod 副本在运行。
通常我们不直接使用ReplicaSet,而是在Deployment中声明。
1 | 创建deployment,部署3个运行nginx的Pod |
缩放
手动缩放
1
2
3将副本数量调整为5
kubectl scale deployment nginx-deployment --replicas=5
kubectl get deploy自动缩放
自动缩放通过增加和减少副本的数量,以保持所有 Pod 的平均 CPU 利用率不超过 75%。
自动伸缩需要声明Pod的资源限制,同时使用 Metrics Server 服务(K3s默认已安装)。
1
2
3
4
5
6自动缩放
kubectl autoscale deployment/nginx-auto --min=3 --max=10 --cpu-percent=75
查看自动缩放
kubectl get hpa
删除自动缩放
kubectl delete hpa nginx-deployment
滚动更新
1 | 查看版本和Pod |
版本回滚
1 | 查看历史版本 |
Service(服务)
Service将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
Service为一组 Pod 提供相同的 DNS 名,并且在它们之间进行负载均衡。
Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化。
集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化。
Kubernetes Service 定义了这样一种抽象:
逻辑上的一组可以互相替换的 Pod,通常称为微服务。
Service 对应的 Pod 集合通常是通过 选择算符 来确定的。
举个例子,在一个Service中运行了3个nginx的副本。这些副本是可互换的,我们不需要关心它们调用了哪个nginx,也不需要关注 Pod的运行状态,只需要调用这个服务就可以了。
ServiceType 取值
● ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务。
● NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务。
● ExternalName:将集群外部的网络引入集群内部。
● LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。
1 | port是service访问端口,target-port是Pod端口 |
1 | 随机产生主机端口 |
访问Service
外部主机访问:
1.NodePort端口是随机的,范围为:30000-32767。
2.集群中每一个主机节点的NodePort端口都可以访问。
3.如果需要指定端口,不想随机产生,需要使用配置文件来声明。
创建Service对象
ServiceType取值
- ClusterlP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的IP,集群内的所有主机
都可以通过这个Cluster-lP访问服务。集群内部的Pod可以通过service:名称访问服务。 - NodePort:通过每个节点的主机lP和静态端口(NodePort)暴露服务。集群的外部主机可以使用节
点P和NodePorti访问服务。 - ExternalName:将集群外部的网络引入集群内部.
- LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。
1 | port是service访问端口,target-port是Pod端口 |
1 | 随机产生主机端口 |
访问Service
外部主机访问: 172.17.1.158:32296
- NodePort端口是随机的,范围为:30000-32767
- 集群中每一个主机节点的NodePort端口都可以访问
- 如果需要指定端口,不想随机产生,需要使用配置文件来声明
1 | 集群内访问 |
声明式对象配置
配置对象
在创建的 Kubernetes 对象所对应的 yaml
文件中,需要配置的字段如下:
apiVersion
- Kubernetes API 的版本kind
- 对象类别,例如Pod
、Deployment
、Service
、ReplicaSet
等metadata
- 描述对象的元数据,包括一个 name 字符串、UID 和可选的 namespacespec
- 对象的配置
Pod配置模板
1 | apiVersion: v1 |
使用yaml文件管理对象
1 | #创建对象 |