kubernetes快速入门之K3S
kubernetes简介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 等大型云计算厂商以及一些开源公司共同牵头成立了Cloud Native Computing Foundation(云原生计算基金会)。
云原生计算基金会(CNCF)致力于培养和维护一个厂商中立的开源生态体系,来推广云原生技术。
云原生的概念从此广泛传播。
云原生定义
Kubernetes 是 CNCF 托管的第一个开源项目。因此现在提到云原生,往往我们都把它与kubernetes接洽起来。
[*]普通解释
使用Java、Go、PHP、Python等语言开发的应用我们称之为原生应用,在计划和开发这些应用时,使他们能够运行在云基础设施(或kubernetes)上,从而使应用具备可弹性扩展的本领,我们称之为云原生应用。我们可以将云原生明白为以容器技术为载体、基于微服务架构思想的一套技术体系和方法论。
[*]官方定义
云原生技术有利于各构造在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合体系。结合可靠的主动化手段,云原生技术使工程师能够轻松地对体系作出频繁和可猜测的庞大变动。
[*]微服务
在Kubernetes之前,Pivotal(开源 Java 开发框架Spring的母公司,后被 VMware 收购)是云原生应用的提出者,并推出了Pivotal Cloud Foundry 云原生应用平台和Spring Cloud开发框架,成为云原生应用架构中先驱者和探路者。Spring Cloud通过微服务架构,使程序具备可拓展性和在分布式环境运行的本领。Spring Cloud和Kubernetes有许多功能是重合的,例如:
[*]服务注册和发现
[*]API网关
[*]负载均衡
[*]设置管理
但是Spring Cloud只能用于Java应用开发,而kubernetes是语言无关的,可以用于各种语言开发的应用。
kubernetes架构
kubernetes架构
一个Kubernetes集群至少包含一个控制平面(control plane),以及一个或多个工作节点(worker node)。
**控制平面(Control Plane) : **控制平面负责管理工作节点和维护集群状态。所有使命分配都来自于控制平面。
**工作节点(Worker Node) : **工作节点负责执行由控制平面分配的请求使命,运行实际的应用和工作负载。
控制平面
控制平面组件会为集群做出全局决策,比如资源的调度、检测和相应集群变乱。
https://cdn.nlark.com/yuque/0/2022/png/28915315/1665199931155-09836d6e-2a2a-4060-a469-9016efda8039.png#averageHue=%23e6e9ee&clientId=u41fc8447-ff3f-4&errorMessage=unknown%20error&from=paste&height=323&id=MciyU&originHeight=646&originWidth=504&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20657&status=error&style=none&taskId=ubdfd9d4b-94d1-40e8-887a-a8b78ccad05&title=&width=252
kube-apiserver
如果需要与Kubernetes 集群进行交互,就要通过 API。
apiserver是 Kubernetes 控制平面的前端,用于处理内部和外部请求。
kube-scheduler
集群状况是否良好?如果需要创建新的容器,要将它们放在哪里?这些是调度程序需要关注的问题。
scheduler调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点。
etcd
etcd是一个键值对数据库,用于存储设置数据和集群状态信息。
kube-controller-manager
控制器负责实际运行集群,controller-manager控制器管理器则是将多个控制器功能合而为一,降低了程序的复杂性。
controller-manager包含了这些控制器:
[*]节点控制器(Node Controller):负责在节点出现故障时进行通知和相应
[*]使命控制器(Job Controller):监测代表一次性使命的 Job 对象,然后创建 Pods 来运行这些使命直至完成
[*]端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即参加 Service 与 Pod)
[*]服务帐户和令牌控制器(Service Account & Token Controllers):为新的定名空间创建默认帐户和 API 访问令牌
Node 组件
节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。
https://cdn.nlark.com/yuque/0/2022/png/28915315/1665200584349-0e11b6d2-b3f3-49cf-9a7e-5effff7371d1.png#averageHue=%23e5e9ef&clientId=u41fc8447-ff3f-4&errorMessage=unknown%20error&from=paste&height=404&id=YOKFb&originHeight=808&originWidth=566&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20222&status=error&style=none&taskId=uf2c2169f-3928-421d-8cd2-e9cf7d7c1c8&title=&width=283
kubelet
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
当控制平面需要在节点中执行某个操作时,kubelet 就会执行该操作。
kube-proxy
kube-proxy 是集群中每个节点(node)上运行的网络代理,是实现 Kubernetes 服务(Service) 概念的一部门。
kube-proxy 维护节点网络规则和转发流量,实现从集群内部或外部的网络与 Pod 进行网络通信。
容器运行时(Container Runtime)
容器运行环境是负责运行容器的软件。
Kubernetes 支持许多容器运行环境,例如 containerd、docker大概其他实现了 Kubernetes CRI (容器运行环境接口)的容器。
组件关系
https://cdn.nlark.com/yuque/0/2022/png/28915315/1663728057486-c85b9364-71ce-46a6-9b4e-eb51ede304db.png#averageHue=%23dddcdc&clientId=u5d151d87-377a-4&errorMessage=unknown%20error&from=paste&height=487&id=mZfpN&originHeight=974&originWidth=2034&originalType=binary&ratio=1&rotation=0&showTitle=false&size=272505&status=error&style=none&taskId=uc88c0742-abe7-4065-96cd-eec3c12ecb4&title=&width=1017
cloud-controller-manager
控制平面还包含一个可选组件cloud-controller-manager。
云控制器管理器(Cloud Controller Manager)答应你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分脱离来。
如果在自己的环境中运行 Kubernetes,大概在当地计算机中运行学习环境, 所摆设的集群不需要有云控制器管理器。
使用K3s快速搭建集群
提示:
1.基于kubernetes V1.25版本。
2.从V1.24开始,kubernetes默认容器运行时使用containerd,不再使用docker。
为什么使用K3s
K3s 是一个轻量级的、完全兼容的 Kubernetes 发行版本。非常适合初学者。
K3s将所有 Kubernetes 控制平面组件都封装在单个二进制文件和进程中,文件大小 alpine.tar#kubernetes使用的镜像都在k8s.io定名空间中ctr -n k8s.io images import alpine.tar
[*]从containerd导出、导入镜像
systemctl disable firewalld --nowDeployment(摆设)与ReplicaSet(副本集)
Deployment是对ReplicaSet和Pod更高级的抽象。
它使Pod拥有多副本,自愈,扩缩容、滚动升级等本领。
ReplicaSet(副本集)是一个Pod的集合。
它可以设置运行Pod的数量,确保任何时间都有指定数量的 Pod 副本在运行。
通常我们不直接使用ReplicaSet,而是在Deployment中声明。
yum install -y container-selinux selinux-policy-base
yum install -y https://rpm.rancher.io/k3s/latest/common/centos/7/noarch/k3s-selinux-0.2-1.el7_8.noarch.rpm缩放
[*]手动缩放
mv k3s /usr/local/bin
chmod +x /usr/local/bin/k3s
[*]主动缩放
主动缩放通过增加和淘汰副本的数量,以保持所有 Pod 的匀称 CPU 利用率不超过 75%。
主动伸缩需要声明Pod的资源限制,同时使用 Metrics Server 服务(K3s默认已安装)。
本例仅用来说明kubectl autoscale下令的使用,完整示例参考:HPA演示
mkdir -p /var/lib/rancher/k3s/agent/images/
cp ./k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images/滚动更新
#修改权限
chmod +x install.sh
#离线安装
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
#安装完成后,查看节点状态
kubectl get node
#查看token
cat /var/lib/rancher/k3s/server/node-token
#K10c4b79481685b50e4bca2513078f4e83b62d1d0b5f133a8a668b65c8f9249c53e::server:bf7b63be7f3471838cbafa12c1a1964d版本回滚
INSTALL_K3S_SKIP_DOWNLOAD=true \
K3S_URL=https://192.168.56.109:6443 \
K3S_TOKEN=K1012bdc3ffe7a5d89ecb125e56c38f9fe84a9f9aed6db605f7698fa744f2f2f12f::server:fdf33f4921dd607cadf2ae3c8eaf6ad9 \
./install.shService(服务)
Service将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
Service为一组 Pod 提供相同的 DNS 名,并且在它们之间进行负载均衡。
Kubernetes 为 Pod 提供分配了IP 地址,但IP地址可能会发生变化。
集群内的容器可以通过service名称访问服务,而不需要担心Pod的IP发生变化。
Kubernetes Service 定义了这样一种抽象:
逻辑上的一组可以互相更换的 Pod,通常称为微服务。
Service 对应的 Pod 集合通常是通过选择算符来确定的。
举个例子,在一个Service中运行了3个nginx的副本。这些副本是可互换的,我们不需要关心它们调用了哪个nginx,也不需要关注 Pod的运行状态,只需要调用这个服务就可以了。
创建Service对象
ServiceType 取值
[*]ClusterIP:将服务公开在集群内部。kubernetes会给服务分配一个集群内部的 IP,集群内的所有主机都可以通过这个Cluster-IP访问服务。集群内部的Pod可以通过service名称访问服务。
[*]NodePort:通过每个节点的主机IP 和静态端口(NodePort)暴露服务。 集群的外部主机可以使用节点IP和NodePort访问服务。
[*]ExternalName:将集群外部的网络引入集群内部。
[*]LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。
kubectl run mynginx --image=nginx
# 查看Pod
kubectl get pod
# 描述
kubectl describe pod mynginx
# 查看Pod的运行日志
kubectl logs mynginx
# 显示pod的IP和运行节点信息
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口
curl 10.42.1.3
#在容器中执行
kubectl exec mynginx -it -- /bin/bash
kubectl get po --watch
# -it 交互模式
# --rm 退出后删除容器,多用于执行一次性任务或使用客户端
kubectl run mynginx --image=nginx -it --rm -- /bin/bash
# 删除
kubectl delete pod mynginx
# 强制删除
kubectl delete pod mynginx --forcemirrors:
docker.io:
endpoint:
- "https://fsp2sfpr.mirror.aliyuncs.com/"https://cdn.nlark.com/yuque/0/2022/png/28915315/1663833870854-8b427a13-7038-4ef9-a761-631902bb998e.png#averageHue=%23111010&clientId=u6f98c5ab-0bc7-4&errorMessage=unknown%20error&from=paste&height=92&id=FdjhO&originHeight=162&originWidth=1314&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33444&status=error&style=none&taskId=u0e4ff564-f6b4-4cf4-b28a-171ab9b40a4&title=&width=747
访问Service
外部主机访问:192.168.56.109:32296。
1.NodePort端口是随机的,范围为:30000-32767。
2.集群中每一个主机节点的NodePort端口都可以访问。
3.如果需要指定端口,不想随机产生,需要使用设置文件来声明。
https://cdn.nlark.com/yuque/0/2022/png/28915315/1664261419003-e9a5a68a-f988-48da-a51d-b8756bce8f24.png#averageHue=%23f7f6f5&clientId=uc9de1ce8-ac6e-4&errorMessage=unknown%20error&from=paste&height=467&id=iQm2T&originHeight=762&originWidth=1306&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46949&status=error&style=none&taskId=u8cf1e62a-5bff-4185-a1de-f33c6f02619&title=&width=800
# master节点执行
systemctl restart k3s
# node节点执行
systemctl restart k3s-agentNamespace(定名空间)
定名空间(Namespace)是一种资源隔离机制,将同一集群中的资源分别为相互隔离的组。
定名空间可以在多个用户之间分别集群资源(通过资源配额)。
[*]例如我们可以设置开发、测试、生产等多个定名空间。
同一定名空间内的资源名称要唯一,但跨定名空间时没有这个要求。
定名空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等。
这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。
Kubernetes 会创建四个初始定名空间:
[*]**default** 默认的定名空间,不可删除,未指定定名空间的对象都会被分配到default中。
[*]**kube-system** Kubernetes 体系对象(控制平面和Node组件)所使用的定名空间。
[*]**kube-public**** **主动创建的公共定名空间,所有用户(包括未经过身份验证的用户)都可以读取它。通常我们约定,将整个集群中公用的可见和可读的资源放在这个空间中。
[*]**kube-node-lease**** ** 租约(Lease)对象使用的定名空间。每个节点都有一个关联的 lease 对象,lease 是一种轻量级资源。lease对象通过发送心跳,检测集群中的每个节点是否发生故障。
使用kubectl get lease -A查看lease对象
使用多个定名空间
[*]定名空间是在多个用户之间分别集群资源的一种方法(通过资源配额)。
[*]例如我们可以设置开发、测试、生产等多个定名空间。
[*]不必使用多个定名空间来分隔轻微不同的资源。
[*]例如同一软件的不同版本: 应该使用标签 来区分同一定名空间中的不同资源。
[*]定名空间适用于跨多个团队或项目标场景。
[*]对于只有几到几十个用户的集群,可以不用创建定名空间。
[*]定名空间不能相互嵌套,每个 Kubernetes 资源只能在一个定名空间中。
管理定名空间
cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml切换当前定名空间
crictl pull mysql:5.7-debian
crictl images声明式对象设置
管理对象
[*]下令行指令
例如,使用kubectl下令来创建和管理 Kubernetes 对象。
下令行就好比口头转达,简单、快速、高效。
但它功能有限,不适合复杂场景,操作不容易追溯,多用于开发和调试。
[*]声明式设置
kubernetes使用yaml文件来描述 Kubernetes 对象。
声明式设置就好比申请表,学习难度大且设置麻烦。
利益是操作留痕,适合操作复杂的对象,多用于生产。
常用下令缩写
名称缩写KindnamespacesnsNamespacenodesnoNodepodspoPodservicessvcServicedeploymentsdeployDeploymentreplicasetsrsReplicaSetstatefulsetsstsStatefulSetdocker pull alpine:3.16
docker save alpine:3.16 > alpine.tar
#kubernetes使用的镜像都在k8s.io命名空间中
ctr -n k8s.io images import alpine.tarYAML规范
[*]缩进代表上下级关系
[*]缩进时不答应使用Tab键,只答应使用空格,通常缩进2个空格
[*]**:** 键值对,后面必须有空格
[*]**-**列表,后面必须有空格
[*]**[ ]**数组
[*]**#**注释
[*]**|** 多行文本块
[*]**---**表示文档的开始,多用于分割多个资源对象
#导出镜像
ctr -n k8s.io images export mysql.tar docker.io/library/mysql:5.7-debian --platform linux/amd64
#导入镜像
ctr -n k8s.io images import mysql.tar设置对象
在创建的 Kubernetes 对象所对应的 yaml文件中,需要设置的字段如下:
[*]**apiVersion** -Kubernetes API 的版本
[*]**kind** - 对象类别,例如Pod、Deployment、Service、ReplicaSet等
[*]**metadata** - 描述对象的元数据,包括一个 name 字符串、UID 和可选的 namespace
[*]**spec** - 对象的设置
使用yaml定义一个Pod
Pod设置模版
#创建deployment,部署3个运行nginx的Pod
kubectl create deployment nginx-deployment --image=nginx:1.22 --replicas=3
#查看deployment
kubectl get deploy
#查看replicaSet
kubectl get rs
#删除deployment
kubectl delete deploy nginx-deployment使用yaml文件管理对象
#将副本数量调整为5
kubectl scale deployment/nginx-deployment --replicas=5
kubectl get deploy标签
标签(Labels) 是附加到对象(比如 Pod)上的键值对,用于补充对象的描述信息。
标签使用户能够以松散的方式管理对象映射,而无需客户端存储这些映射。
由于一个集群中可能管理成千上万个容器,我们可以使用标签高效的进行选择和操作容器集合。
[*]键的格式:
[*]前缀(可选)/名称(必须)。
[*]有用名称和值:
[*]必须为 63 个字符或更少(可以为空)
[*]如果不为空,必须以字母数字字符()开头和结尾
[*]包含破折号**-**、下划线**_**、点**.**和字母或数字
label设置模版
#自动缩放
kubectl autoscale deployment/nginx-auto --min=3 --max=10 --cpu-percent=75
#查看自动缩放
kubectl get hpa
#删除自动缩放
kubectl delete hpa nginx-deployment#查看版本和Pod
kubectl get deployment/nginx-deployment -owide
kubectl get pods
#更新容器镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.23
#滚动更新
kubectl rollout status deployment/nginx-deployment
#查看过程
kubectl get rs --watch选择器
标签选择器 可以辨认一组对象。标签不支持唯一性。
标签选择器最常见的用法是为Service选择一组Pod作为后端。
Service设置模版
#查看历史版本
kubectl rollout history deployment/nginx-deployment
#查看指定版本的信息
kubectl rollout history deployment/nginx-deployment --revision=2
#回滚到历史版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2现在支持两种范例的选择运算:基于等值的和基于集合的。
多个选择条件使用逗号分隔,相当于And(&&)运算。
[*]等值选择
# port是service访问端口,target-port是Pod端口
# 二者通常是一样的
kubectl expose deployment/nginx-deployment \
--name=nginx-service --type=ClusterIP --port=80 --target-port=80
[*]集合选择
# 随机产生主机端口
kubectl expose deployment/nginx-deployment \
--name=nginx-service2 --type=NodePort --port=8080 --target-port=80
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]