kubernetes简介及安装部署

news2024/12/28 2:55:04

目录

一、kubernetes简介

1、k8s的概念

2、k8s各个组件及用途

3、k8s各组件之间的调用关系

4、k8s常用名词概念

5、k8s的分层架构

二、kubernetes安装部署

1、k8s集群环境搭建

2、本地解析、swap禁用

3、安装docker

4、复制harbor仓库中的证书并启动docker

5、设定docker的资源管理模式为systemd

6、安装docker插件及其依赖性

7、安装K8S部署工具

8、设置kubectl命令补齐功能

9、在master节点拉取镜像

10、集群初始化

11、安装flannel网络插件

12、k8s集群环境检测


一、kubernetes简介

1、k8s的概念

Kubernetes(简称 k8s)是一个开源的容器编排引擎,它可以自动化部署、扩展和管理容器化应用。它提供了强大的功能,如自动调度、弹性伸缩、服务发现、负载均衡等,使得容器化应用的部署和管理更加高效、可靠和便捷。通过 k8s,你可以轻松地在不同的环境中运行和管理大规模的容器化应用,提高开发和运维效率。

  • 在Docker 作为高级容器引擎快速发展的同时,在Google内部,容器技术已经应用了很多年

  • Borg系统运行管理着成千上万的容器应用。

  • Kubernetes项目来源于Borg,可以说是集结了Borg设计思想的精华,并且吸收了Borg系统中的经验和教训。

  • Kubernetes对计算资源进行了更高层次的抽象,通过将容器进行细致的组合,将最终的应用服务交给用户。

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器

  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整

  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务

  • 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡

  • 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本

  • 存储编排:可以根据容器自身的需求自动创建存储卷

2、k8s各个组件及用途

一个kubernetes集群主要是由控制节点(master)工作节点(node)构成,每个节点上都会安装不同的组件。

1 、master:集群的控制平面,负责集群的决策

  • ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

  • Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

  • ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

  • Etcd :负责存储集群中各种资源对象的信息

2 、node:集群的数据平面,负责为容器提供运行环境

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

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

  • kube-proxy:负责为Service提供cluster内部的服务发现和负载均衡

3、k8s各组件之间的调用关系

当我们要运行一个web服务时:

  1. kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中

  2. web服务的安装请求会首先被发送到master节点的apiServer组件

  3. apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上

    在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer

  4. apiServer调用controller-manager去调度Node节点安装web服务

  5. kubelet接收到指令后,会通知docker,然后由docker来启动一个web服务的pod

  6. 如果需要访问web服务,就需要通过kube-proxy来对pod产生访问的代理

4、k8s常用名词概念

  • Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

  • Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的

  • Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

  • Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

  • Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

  • Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

  • NameSpace:命名空间,用来隔离pod的运行环境

5、k8s的分层架构

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

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

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

  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦

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

  • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等

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

二、kubernetes安装部署

基于红帽9系统的k8s集群环境搭建,前期准备:四台主机其中包含一台专门用来存放镜像的harbor仓库主机和一个主节点主机、两个工作节点主机。harbor仓库搭建可参考文章Docker仓库搭建-CSDN博客

1、k8s集群环境搭建

主机名ip角色
reg.leoma.org172.25.254.254harbor仓库
k8s-master.mlh.org172.25.254.100master,k8s集群控制节点
k8s-node1.mlh.org172.25.254.10worker,k8s集群工作节点
k8s-node2.mlh.org172.25.254.20worker,k8s集群工作节点
  • 所有节点禁用selinux和防火墙

  • 所有节点同步时间和解析

  • 所有节点安装docker-ce

  • 所有节点禁用swap,注意注释掉/etc/fstab文件中的定义

2、本地解析、swap禁用

所有主机:

[root@k8s-master ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100  k8s-master
172.25.254.10   k8s-node1
172.25.254.20   k8s-node2
172.25.254.111  reg.leoma.org
[root@k8s-master ~]# scp /etc/hosts root@172.25.254.10:/etc/host
[root@k8s-master ~]# scp /etc/hosts root@172.25.254.20:/etc/host
yum list httpd 	#测试yum源

systemctl mask dev-nvme0n1p3.swap
swapoff -a

[root@k8s-master ~]# vim /etc/fstab
#/dev/mapper/rhel-swap   none                    swap    defaults        0 0

systemctl status dev-nvme0n1p3.swap

K8s 集群搭建要禁用 swap 是因为开启 swap 可能会导致节点调度不准确和性能不稳定,影响容器的资源分配和调度决策。

3、安装docker

所有主机:

[root@k8s-master ~]# vim /etc/yum.repos.d/docker.repo
[docker]
name=docker
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable/
gpgcheck=0

yum install makecache

[root@k8s-master ~]# dnf install docker-ce -y
#还可以采用rpm包安装方式

4、复制harbor仓库中的证书并启动docker

mkdir /etc/docker/certs.d/reg.leoma.org/ -p

[root@reg ~]# scp /data/certs/leoma.org.crt root@172.25.254.100:/etc/docker/certs.d/reg.leoma.org/ca.crt

vim /etc/docker/daemon.json

{
    "registry-mirrors" : ["https://reg.leoma.org"]
}
systemctl daemon-reload
systemctl enable --now docker

docker login reg.leoma.org

5、设定docker的资源管理模式为systemd

#企业9中默认为systemd,企业7需要以下配置
[root@k8s-master ~]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://reg.westos.org"],
        "exec-opts": ["native.cgroupdriver=systemd"],
        "log-driver": "json-file",
        "log-opts": {
                "max-size": "100m"
        },
        "storage-driver": "overlay2"
}

docker info	
#“Cgroup Driver: systemd” 表示在使用容器技术(如 Docker)时,采用的是 Systemd 作为控制组(cgroup)的驱动。

6、安装docker插件及其依赖性

在 Kubernetes 集群中安装 Docker 插件及依赖性是为了确保在 Kubernetes 1.24 及更高版本移除 dockershim 后仍能使用 Docker 作为容器运行时。

所有节点安装:

dnf install cri-dockerd-0.3.14-3.el8.x86_64.rpm -y
dnf install libcgroup-0.41-19.el8.x86_64.rpm -y

systemctl enable --now cri-docker 

7、安装K8S部署工具

控制节点及两个工作节点:

#部署软件仓库,添加K8S源
[root@k8s-master ~]# vim /etc/yum.repos.d/k8s.repo
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm
gpgcheck=0

#安装软件
dnf install makecache
[root@k8s-master ~]# dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y

一、kubelet kubelet是在每个 Kubernetes 节点(包括主节点和工作节点)上运行的主要代理。

负责管理和维护所在节点上的 Pod 和容器: 确保容器按照指定的资源请求和限制运行。 监控容器的健康状态,在容器出现故障时进行重启或报告给控制平面。

与 Kubernetes 控制平面通信: 接收来自控制平面的指令,如创建、删除或更新 Pod。 向控制平面报告节点的状态信息,包括资源使用情况、容器状态等。

二、kubeadm kubeadm是一个用于快速部署 Kubernetes 集群的工具。

初始化集群: 可以使用 kubeadm init 命令轻松地初始化一个新的 Kubernetes 控制平面节点,包括设置必要的证书、配置网络插件等。

加入节点: 对于工作节点,可以使用 kubeadm join 命令将其加入到已有的 Kubernetes 集群中。

升级集群: kubeadm还可以用于升级 Kubernetes 集群到新版本,简化了升级过程中的复杂操作。

三、kubectl kubectl是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互。

管理资源对象: 可以使用 kubectl 命令创建、删除、更新和查看各种 Kubernetes 资源对象,如 Pod、Deployment、Service 等。

监控和调试: 查看集群的状态、节点信息、容器日志等,以便进行故障排除和监控。 可以执行一些调试操作,如进入容器内部进行检查。

扩展和定制: 通过编写自定义的 YAML 配置文件,可以使用 kubectl 来部署复杂的应用架构和进行集群的定制化配置。

8、设置kubectl命令补齐功能

控制主机:

[root@k8s-master ~]# dnf install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc	#kubectl命令提供 bash 自动补全功能
[root@k8s-master ~]# source  ~/.bashrc

9、在master节点拉取镜像

#拉取k8s集群所需要的镜像
[root@k8s-master ~]# kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
#指定容器运行时接口(Container Runtime Interface,CRI)的套接字地址为 “unix:///var/run/cri-dockerd.sock”。这告诉kubeadm使用特定的 CRI 实现来拉取和管理容器镜像,以便与 Kubernetes 协同工作。

#上传镜像到harbor仓库
[root@k8s-master ~]# docker images | awk '/google/{ print $1":"$2}' \
| awk -F "/" '{system("docker tag "$0" reg.leoma.org/k8s/"$3)}'

[root@k8s-master ~]# docker images  | awk '/k8s/{system("docker push "$1":"$2)}'

10、集群初始化

指定根容器,控制节点及工作节点
[root@k8s-master ~]# vim /lib/systemd/system/cri-docker.service
#指定网络插件名称及基础容器镜像
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.leoma.org/k8s/pause:3.9

[root@k8s-master ~]# scp /lib/systemd/system/cri-docker.service root@172.25.254.10:/lib/systemd/system/cri-docker.service
[root@k8s-master ~]# scp /lib/systemd/system/cri-docker.service root@172.25.254.20:/lib/systemd/system/cri-docker.service

systemctl daemon-reload
systemctl restart cri-docker

[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository reg.leoma.org/k8s --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock
#集群初始化

[root@k8s-master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
[root@k8s-master ~]# source ~/.bash_profile
#指定集群配置文件变量

11、安装flannel网络插件

#编辑kube-flannel.yml 修改镜像下载位置
[root@k8s-master ~]# vim kube-flannel.yml

#需要修改以下几行
[root@k8s-master ~]# grep -n image kube-flannel.yml
146:        image: flannel/flannel:v0.25.5
173:        image: flannel/flannel-cni-plugin:v1.5.1-flannel1
184:        image: flannel/flannel:v0.25.5

[root@k8s-master ~]# docker load -i flannel-0.25.5.tag.gz	#导入镜像包并加载本地镜像库

[root@k8s-master ~]# docker tag flannel/flannel:v0.25.5 reg.leoma.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker push reg.leoma.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 reg.leoma.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
[root@k8s-master ~]# docker push reg.leoma.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
#上传至harbor仓库方便后续拉取

#安装flannel网络插件
[root@k8s-master ~]# kubectl apply -f kube-flannel.yml

[root@k8s-master ~]# kubeadm token create --print-join-command	#可重新生成token

 kubeadm join 172.25.254.100:6443 --token asr9qc.yvqejrc68qa5dfeg \--discovery-token-ca-cert-hash sha256:b7203595313e91c854e88c4cee5e3e8413cb9aa894cdaee508fcde251d649d98 --cri-socket=unix:///var/run/cri-dockerd.sock
#集群初始化生成的token

12、k8s集群环境检测

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES           AGE    VERSION
k8s-master   Ready    control-plane   112m   v1.30.4
k8s-node1    Ready    <none>          110m   v1.30.0
k8s-node2    Ready    <none>          110m   v1.30.0

[root@k8s-master ~]# kubectl -n kube-flannel get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
kube-flannel-ds-4vt5l   1/1     Running   0          57m   172.25.254.100   k8s-master   <none>           <none>
kube-flannel-ds-tg25x   1/1     Running   0          57m   172.25.254.10    k8s-node1    <none>           <none>
kube-flannel-ds-vphr6   1/1     Running   0          57m   172.25.254.20    k8s-node2    <none>

[root@k8s-master ~]# kubectl run tset --image nginx
pod/tset created
[root@k8s-master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
tset   1/1     Running   0          16s

从上述命令输出可以看出,当前有一个名为 “k8s-master” 的主节点处于就绪状态且承担控制平面角色,还有 “k8s-node1” 和 “k8s-node2” 两个工作节点也都处于就绪状态。在 “kube-flannel” 命名空间下有三个 “kube-flannel-ds” 类型的 Pod 分别在三个节点上正常运行。随后通过命令创建了一个名为 “tset” 的 Pod,该 Pod 使用 Nginx 镜像且状态为运行中。这表明 Kubernetes 集群运行正常,能够成功调度和运行容器化应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2216290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Cesium.js的可视化大屏,效果绝对的震撼!

基于 Cesium.js 的可视化大屏确实能带来震撼的效果。Cesium.js 强大的三维渲染能力&#xff0c;能够逼真地呈现地理信息和各种数据模型。 在大屏上&#xff0c;广袤的地形地貌、精细的建筑模型以及动态的数据展示&#xff0c;仿佛将观众带入一个全新的虚拟世界。无论是用于地理…

网络分析仪——提升网络性能的关键工具

目录 什么是网络分析仪&#xff1f; 1. 实时流量监控 2. 历史数据回溯分析 3. 网络性能关键指标监测 4. 可视化界面与报告生成 总结 在当今的数字化世界&#xff0c;网络的稳定性和性能直接影响企业的运营效率。网络拥堵、延迟和丢包等问题会导致用户体验的下降&#xff…

“屏” 步青云:轻松开启录屏功能,Windows 实例教学

你知道 Windows 的录屏功能怎么打开吗&#xff1f;在当今数字化时代&#xff0c;录屏功能成为了许多人工作、学习和娱乐中的得力助手。无论是制作教学视频、记录游戏精彩瞬间&#xff0c;还是为线上会议留存资料&#xff0c;掌握录屏技能都至关重要。今天我们不仅会介绍 Window…

springboot智能网上问诊系统-计算机毕业设计源码99634

摘要 智能网上问诊系统作为医疗健康领域的重要应用之一&#xff0c;为患者提供了便捷的医疗服务途径。本研究旨在基于Springboot框架设计和实现一套智能网上问诊系统&#xff0c;结合医疗专业知识&#xff0c;实现患者与医生之间的在线咨询和诊疗服务。 通过对Springboot框架…

如何从模块内部运行 Pytest

在 Python 中&#xff0c;pytest 是一个强大的测试框架&#xff0c;用于编写和运行测试用例。通常我们会在命令行中运行 pytest&#xff0c;但是有时你可能希望从模块或脚本的内部运行 pytest&#xff0c;比如为了自动化测试或集成到某个工作流程中。 1、问题背景 当你从模块…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式&#xff0c;或者找一找开源的一些算法&am…

秋招突击——8/6——万得数据面试总结

文章目录 引言正文面经整理一1、讲一下java的多态&#xff0c;重载&#xff0c;重写的概念&#xff0c;区别2、说一下Java的数组&#xff0c;链表的结构&#xff0c;优缺点3、创建java线程的方式有哪些&#xff0c;具体说说4、创建线程池呢、每个参数的意义5、通过那几种方式保…

java基础(5)继承与多态

目录 ​编辑 1.前言 2.正文 2.1继承 2.1.1继承概念 2.1.2继承语法 2.1.3子类访问父类 2.1.4super关键字 2.2多态 2.2.1多态概念 2.2.2多态条件 2.2.3重写 2.2.4向上转型与向下转型 2.2.5为什么要使用多态 3.小结 1.前言 哈喽大家好啊&#xff0c;今天继续来为大…

汽车开发流程管理工具赋能安全与质量

随着数字化、人工智能、自动化系统及物联网技术的迅速发展&#xff0c;工程驱动型企业正面临重大转型挑战&#xff0c;亟需加速并深化其变革步伐。众多企业正试图通过采用基于模型的系统工程(MBSE)、产品线工程(PLE)、ASPICE、安全、网络安全、软件定义汽车、敏捷和精益开发实践…

微信小程序上传组件封装uploadHelper2.0使用整理

一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云&#xff0c;对象存储封装库 第一步&#xff0c;下载组件代码&#xff0c;放置到自己的小程序项目中 第二步、 创建上传对象&#xff0c;执行选择图片/视频 var _this th…

【java Web如何开发?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

讯飞与腾讯云:Android 实时语音识别服务对比选择

在 移动端 接入实时语音识别方面&#xff0c;讯飞和腾讯云都是优秀的选择&#xff0c;但各有其特点和优势。以下是对两者的详细比较&#xff1a; 一、讯飞语音识别 1.1 讯飞实时语音识别介绍 1.1.1 功能特点 1.支持多种语言识别&#xff0c;满足不同语种用户的需求。(普通话/…

Kafka之消费者组与消费者

消费者&#xff08;Consumer&#xff09;在Kafka的体系结构中是用来负责订阅Kafka中的主题&#xff08;Topic&#xff09;&#xff0c;并从订阅的主题中拉取消息后进行处理。 与其他消息中间件不同&#xff0c;Kafka引入一个逻辑概念——消费组&#xff08;Consumer Group&…

使用excel.js(layui-excel)进行layui多级表头导出,根据单元格内容设置背景颜色,并将导出函数添加到toolbar

本段是菜狗子的碎碎念&#xff0c;解决办法请直接从第二段开始看。layui多级表头的导出&#xff0c;弄了两天才搞定&#xff0c;中途一度想放弃&#xff0c;还好坚持下来了。一开始用的是layui的toolbar里自带的那个导出&#xff0c;但是多级表头没有正常导出&#xff0c;单元格…

FPGA学习(6)-基础语法参数化设计阻塞与非阻塞

目录 1.两种参数化不改变源文件&#xff0c;只改仿真文件的值 2.参数化设计实现模块的重用 2.1不用参数化方法 2.1.1源文件 2.1.2仿真文件 2.1.3仿真波形及实验 2.2 用参数方法 2.2.1调用之前写的led灯闪烁模块&#xff0c;在本源函数中&#xff0c;例化4次调用之前的模…

【pyspark学习从入门到精通7】DataFrames_2

目录 创建 DataFrames 生成我们自己的 JSON 数据 创建 DataFrame 创建临时表 简单的 DataFrame 查询 DataFrame API 查询 SQL 查询 创建 DataFrames 通常&#xff0c;您会通过使用 SparkSession&#xff08;或在 PySpark shell 中调用 spark&#xff09;导入数据来创建 …

SpinalHDL之错误集(一)

本文作为SpinalHDL学习笔记第七十六篇&#xff0c;作为错误集使用&#xff0c;类似高中生的错题集&#xff0c;记录使用SpinalHDL过程中遇到的问题&#xff0c;小到语法错误、版本兼容问题&#xff0c;大到SpinalHDL库函数错误等等&#xff0c;持续更新。 SpinalHDL学习笔记总…

记录 ruoyi-vue-plus在linux 部署遇到的问题

整理 linux 文件不要放在 /, 根目录下&#xff0c;要放在 home 文件夹下。docker 启动mysql 容器&#xff0c;映射的 my.cnf 文件不能设置太高权限&#xff0c;权限太高有安全问题&#xff0c;无法读取。 linux 使用注意事项 docker 文件夹 部署在home文件夹下 总结学习到的…

Asp.Net Core 发布 IIS、docker、Azure、文件夹、AAS、ASF、AWM等

发布 微软资料 微软资料 在 IIS 工作进程 (w3wp.exe) 内托管 ASP.NET Core 应用&#xff0c;称为进程内托管模型。 将 Web 请求转发到运行 Kestrel 服务器的后端 ASP.NET Core 应用&#xff0c;称为进程外托管模型。 发布到IIS 》》》Asp.net 之前 》》》 Asp.net Core …

JavaScript 网页设计案例:使用 Canvas 实现趣味打气球小游戏

JavaScript 网页设计案例&#xff1a;使用 Canvas 实现趣味打气球小游戏 在网页设计中&#xff0c;交互性和趣味性是吸引用户的重要因素。借助 JavaScript 和 HTML5 的 canvas 元素&#xff0c;我们可以轻松实现各种动画效果&#xff0c;今天将带你打造一个有趣的 打气球小游戏…