OCP使用CLI创建和构建应用

文章目录

  • 环境
  • 登录
  • 创建project
  • 赋予查看权限
  • 部署第一个image
    • 创建route
    • 检查pod
    • 扩展应用
  • 部署一个Python应用
  • 连接数据库
    • 创建secret
    • 加载数据并显示国家公园地图
  • 清理
  • 参考

环境

  • RHEL 9.3
  • Red Hat OpenShift Local 2.32

登录

通过 crc console --credentials 可以查看登录信息:

$ crc console --credentials
To login as a regular user, run 'oc login -u developer -p developer https://api.crc.testing:6443'.
To login as an admin, run 'oc login -u kubeadmin -p 9cdKu-ihELt-PYiiN-aazX2 https://api.crc.testing:6443'

登录:

$ oc login -u kubeadmin -p 9cdKu-ihELt-PYiiN-aazX2 https://api.crc.testing:6443
Login successful.You have access to 66 projects, the list has been suppressed. You can list all projects with 'oc projects'Using project "default".

注: https://api.crc.testing:6443 是可选的,缺省就是登录本机。

查看当前身份:

$ oc whoami
kubeadmin

登录时,可以加上 --web 选项,启动web console,通过web console登录:

$ oc login --web
Opening login URL in the default browser: https://oauth-openshift.apps-crc.testing/oauth/authorize?client_id=openshift-cli-client&code_challenge=FXeS7NXkkgk-c8T2IBC62OerE5idgtetRqackO6n15E&code_challenge_method=S256&redirect_uri=http%3A%2F%2F127.0.0.1%3A35445%2Fcallback&response_type=code

在这里插入图片描述

创建project

Project使得用户社区可以在隔离中组织和管理其内容。Project是OCP对Kubernetes namespace的扩展。Project具有额外的功能,使得用户能够自我provision(self-provisioning)。

用户需要从管理员处接收project的访问权限。集群管理员可以允许开发人员创建自己的project。多数情况下,用户会自动获得其自己的project的访问权限。

每个project都有自己的一系列对象、策略、约束和service帐户。

创建project user-getting-started

$ oc new-project user-getting-started --display-name="Getting Started with OpenShift"
Now using project "user-getting-started" on server "https://api.crc.testing:6443".You can add applications to this project with the 'new-app' command. For example, try:oc new-app rails-postgresql-exampleto build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.43 -- /agnhost serve-hostname

创建project后,会自动切换到该project。

赋予查看权限

OCP会在每个project中自动创建一些特殊的service帐户。默认服务帐户会负责运行pod。OCP使用并将此service帐户注入到所启动的每个pod中。

本例为默认的 ServiceAccount 对象创建一个 RoleBinding 对象。Service帐户与 OCP API通信,以了解project中的 pod、service和资源。

将查看(view)角色添加到 user-get-started project中的默认service帐户:

$ oc adm policy add-role-to-user view -z default -n user-getting-started
clusterrole.rbac.authorization.k8s.io/view added: "default"

部署第一个image

在OCP中部署应用的最简单方法是运行已有的容器image。本例部署一个应用的前端组件,名为 national-parks-app 。该web应用显示一个交互式的地图,显示全球主要国家公园的位置。

$ oc new-app quay.io/openshiftroadshow/parksmap:latest --name=parksmap -l 'app=national-parks-app,component=parksmap,role=frontend,app.kubernetes.io/part-of=national-parks-app'
--> Found container image 0c2f55f (3 years old) from quay.io for "quay.io/openshiftroadshow/parksmap:latest"* An image stream tag will be created as "parksmap:latest" that will track this image--> Creating resources with label app=national-parks-app,app.kubernetes.io/part-of=national-parks-app,component=parksmap,role=frontend ...imagestream.image.openshift.io "parksmap" createddeployment.apps "parksmap" createdservice "parksmap" created
--> SuccessApplication is not exposed. You can expose services to the outside world by executing one or more of the commands below:'oc expose service/parksmap' Run 'oc status' to view your app.

创建route

外部客户端可以通过路由层访问OCP里运行的应用,该路由层后端的数据对象被称为route。默认的OCP路由器(HAProxy)使用传入请求的HTTP header来确定代理连接的位置。

也可以为route定义安全性,比如TLS。

查看service:

$ oc get service
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
parksmap   ClusterIP   10.217.4.38   <none>        8080/TCP   6m11s

注:我使用的是Red Hat OpenShift Local,所以没有 EXTERNAL-IP

创建route:

$ oc create route edge parksmap --service=parksmap
route.route.openshift.io/parksmap created

查看route:

$ oc get route
NAME       HOST/PORT                                        PATH   SERVICES   PORT       TERMINATION   WILDCARD
parksmap   parksmap-user-getting-started.apps-crc.testing          parksmap   8080-tcp   edge          None

检查pod

OCP使用Kubernetes的pod概念,它是部署在同一主机上的一个或多个容器,也是可被定义、部署和管理的最小计算单元。对于容器来说,pod大致相当于机器实例(物理的或虚拟的)。

可以查看集群中的pod,并确定这些pod以及整个集群的健康状态。

$ oc get pod
NAME                       READY   STATUS    RESTARTS   AGE
parksmap-69b46d5f7-glwd2   1/1     Running   0          14m

查看pod详细信息:

$ oc describe pod
Name:             parksmap-69b46d5f7-glwd2
Namespace:        user-getting-started
Priority:         0
Service Account:  default
Node:             crc-ksq4m-master-0/192.168.126.11
Start Time:       Fri, 09 Feb 2024 08:09:58 +0800
Labels:           app=national-parks-appapp.kubernetes.io/part-of=national-parks-appcomponent=parksmapdeployment=parksmappod-template-hash=69b46d5f7role=frontend
Annotations:      k8s.v1.cni.cncf.io/network-status:[{"name": "openshift-sdn","interface": "eth0","ips": ["10.217.0.65"],"default": true,"dns": {}}]openshift.io/generated-by: OpenShiftNewAppopenshift.io/scc: restricted-v2seccomp.security.alpha.kubernetes.io/pod: runtime/default
Status:           Running
SeccompProfile:   RuntimeDefault
IP:               10.217.0.65
IPs:IP:           10.217.0.65
Controlled By:  ReplicaSet/parksmap-69b46d5f7
Containers:parksmap:Container ID:   cri-o://36d858cc571f219418f2d5fefcd4ebd606611c51a57f779c26fa6d3f86559f03Image:          quay.io/openshiftroadshow/parksmap@sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173bImage ID:       quay.io/openshiftroadshow/parksmap@sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173bPort:           8080/TCPHost Port:      0/TCPState:          RunningStarted:      Fri, 09 Feb 2024 08:10:34 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-92x92 (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:kube-api-access-92x92:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             trueConfigMapName:           openshift-service-ca.crtConfigMapOptional:       <nil>
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason          Age   From               Message----    ------          ----  ----               -------Normal  Scheduled       15m   default-scheduler  Successfully assigned user-getting-started/parksmap-69b46d5f7-glwd2 to crc-ksq4m-master-0Normal  AddedInterface  15m   multus             Add eth0 [10.217.0.65/23] from openshift-sdnNormal  Pulling         15m   kubelet            Pulling image "quay.io/openshiftroadshow/parksmap@sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b"Normal  Pulled          14m   kubelet            Successfully pulled image "quay.io/openshiftroadshow/parksmap@sha256:89d1e324846cb431df9039e1a7fd0ed2ba0c51aafbae73f2abd70a83d5fa173b" in 34.192111778s (34.19212265s including waiting)Normal  Created         14m   kubelet            Created container parksmapNormal  Started         14m   kubelet            Started container parksmap

注:也可以 oc describe pod xxx 查看某个pod的详细信息。本例中在当前project里只有一个pod,所以二者效果都一样。

扩展应用

在Kubernetes中, Deployment 对象定义了如何部署应用。多数情况下,用户会把pod、service、ReplicaSets、deployment资源一起使用。在大多数情况下,OCP会创建这些资源。

在部署 national-parks-app image时,会创建一个deployment资源。本例只部署了一个pod。

把应用从一个pod实例扩展到两个pod实例:

$ oc scale --current-replicas=1 --replicas=2 deployment/parksmap
deployment.apps/parksmap scaled

查看pod:

$ oc get pods
NAME                       READY   STATUS    RESTARTS   AGE
parksmap-69b46d5f7-btk54   1/1     Running   0          33s
parksmap-69b46d5f7-glwd2   1/1     Running   0          22m

把应用缩减回一个pod实例:

$ oc scale --current-replicas=2 --replicas=1 deployment/parksmap
deployment.apps/parksmap scaled

查看pod:

$ oc get pods
NAME                       READY   STATUS    RESTARTS   AGE
parksmap-69b46d5f7-glwd2   1/1     Running   0          24m

部署一个Python应用

本例为 parksmap 应用部署后端service。Python应用在MongoDB数据库执行2D地理空间( geo-spatial)查询,以定位和返回世界上所有国家公园的地图坐标。

部署的后端service是 nationalparks

创建Python应用:

$ oc new-app python~https://github.com/openshift-roadshow/nationalparks-py.git --name nationalparks -l 'app=national-parks-app,component=nationalparks,role=backend,app.kubernetes.io/part-of=national-parks-app,app.kubernetes.io/name=python' --allow-missing-images=true
warning: Cannot check if git requires authentication.
--> Found image 3c5d265 (5 weeks old) in image stream "openshift/python" under tag "3.9-ubi8" for "python"Python 3.9 ---------- Python 3.9 available as container is a base platform for building and running various Python 3.9 applications and frameworks. Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python's elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.Tags: builder, python, python39, python-39, rh-python39* A source build using source code from https://github.com/openshift-roadshow/nationalparks-py.git will be created* The resulting image will be pushed to image stream tag "nationalparks:latest"* Use 'oc start-build' to trigger a new build--> Creating resources with label app=national-parks-app,app.kubernetes.io/name=python,app.kubernetes.io/part-of=national-parks-app,component=nationalparks,role=backend ...imagestream.image.openshift.io "nationalparks" createdbuildconfig.build.openshift.io "nationalparks" createddeployment.apps "nationalparks" createdservice "nationalparks" created
--> SuccessBuild scheduled, use 'oc logs -f buildconfig/nationalparks' to track its progress.Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:'oc expose service/nationalparks' Run 'oc status' to view your app.

创建route来暴露 nationalparks 应用:

$ oc create route edge nationalparks --service=nationalparks
route.route.openshift.io/nationalparks created

查看route:

$ oc get route
NAME            HOST/PORT                                             PATH   SERVICES        PORT       TERMINATION   WILDCARD
nationalparks   nationalparks-user-getting-started.apps-crc.testing          nationalparks   8080-tcp   edge          None
parksmap        parksmap-user-getting-started.apps-crc.testing               parksmap        8080-tcp   edge          None

连接数据库

接下来,部署并连接一个MongoDB数据库, national -parks-app 应用将会存储位置信息于该数据库。一旦把 national-parks-app 应用标记为地图可视化工具的后端, parksmap deployment会使用OCP发现机制来自动显示地图。

连接数据库:

$ oc new-app quay.io/centos7/mongodb-36-centos7 --name mongodb-nationalparks -e MONGODB_USER=mongodb -e MONGODB_PASSWORD=mongodb -e MONGODB_DATABASE=mongodb -e MONGODB_ADMIN_PASSWORD=mongodb -l 'app.kubernetes.io/part-of=national-parks-app,app.kubernetes.io/name=mongodb'
--> Found container image dc18f52 (2 years old) from quay.io for "quay.io/centos7/mongodb-36-centos7"MongoDB 3.6 ----------- MongoDB (from humongous) is a free and open-source cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with schemas. This container image contains programs to run mongod server.Tags: database, mongodb, rh-mongodb36* An image stream tag will be created as "mongodb-nationalparks:latest" that will track this image--> Creating resources with label app.kubernetes.io/name=mongodb,app.kubernetes.io/part-of=national-parks-app ...imagestream.image.openshift.io "mongodb-nationalparks" createddeployment.apps "mongodb-nationalparks" createdservice "mongodb-nationalparks" created
--> SuccessApplication is not exposed. You can expose services to the outside world by executing one or more of the commands below:'oc expose service/mongodb-nationalparks' Run 'oc status' to view your app.

创建secret

Secret 对象提供了一种机制来保存敏感信息,如密码、OCP客户端配置文件、私有源仓库凭证等。Secret把敏感内容与pod解耦。可以通过volume插件把secret mount到容器中,系统也可以为pod而使用secret执行操作。本例添加secret nationalparks-mongodb-parameters ,并将它mount到 nationalparks 工作负载中。

创建secret:

$ oc create secret generic nationalparks-mongodb-parameters --from-literal=DATABASE_SERVICE_NAME=mongodb-nationalparks --from-literal=MONGODB_USER=mongodb --from-literal=MONGODB_PASSWORD=mongodb --from-literal=MONGODB_DATABASE=mongodb --from-literal=MONGODB_ADMIN_PASSWORD=mongodb
secret/nationalparks-mongodb-parameters created

更新环境变量,把mongodb secret 附加到 nationalpartks 工作负载:

$ oc set env --from=secret/nationalparks-mongodb-parameters deploy/nationalparks
deployment.apps/nationalparks updated

显示 nationalpartks deployment的状态:

$ oc rollout status deployment nationalparks
deployment "nationalparks" successfully rolled out

显示 mongodb-nationalparks deployment的状态:

$ oc rollout status deployment mongodb-nationalparks
deployment "mongodb-nationalparks" successfully rolled out

直接看当前project里所有deployment的更新状态:

$ oc rollout status deployment
deployment "mongodb-nationalparks" successfully rolled out
deployment "nationalparks" successfully rolled out
deployment "parksmap" successfully rolled out

加载数据并显示国家公园地图

目前已经部署了 parksmapNationalparks 应用,然后部署了 mongodb-nationalparks 数据库。但是,还没有把数据加载到数据库中。

加载国家公园数据:

$ oc exec $(oc get pods -l component=nationalparks | tail -n 1 | awk '{print $1;}') -- curl -s http://localhost:8080/ws/data/load
"Items inserted in database: 2893"

验证:

$ oc exec $(oc get pods -l component=nationalparks | tail -n 1 | awk '{print $1;}') -- curl -s http://localhost:8080/ws/data/all | jq .
[{"id": "Arikok National Park","latitude": "12.489967","longitude": "-69.9273915","name": "Arikok National Park"},{"id": "Wakhan National Park","latitude": "36.845432","longitude": "72.28375","name": "Wakhan National Park"},
......
......{"id": "Great Zimbabwe","latitude": "-20.2674635","longitude": "30.9337986","name": "Great Zimbabwe"}
]

为route添加label:

$ oc label route nationalparks type=parksmap-backend
route.route.openshift.io/nationalparks labeled

查看route:

$ oc get routes
NAME            HOST/PORT                                             PATH   SERVICES        PORT       TERMINATION   WILDCARD
nationalparks   nationalparks-user-getting-started.apps-crc.testing          nationalparks   8080-tcp   edge          None
parksmap        parksmap-user-getting-started.apps-crc.testing               parksmap        8080-tcp   edge          None

打开浏览器,访问 https://parksmap-user-getting-started.apps-crc.testing ,如下:

在这里插入图片描述

清理

crc delete -f

参考

  • https://access.redhat.com/documentation/en-us/openshift_container_platform/4.14/html-single/getting_started/index#openshift-cli

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

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

相关文章

CS50x 2024 - Lecture 2 - Arrays

00:00:00 - Introduction 00:01:01 - Story Time 00:06:03 - Compiling make本身并不是编译器&#xff0c;实际上是一个自动运行编译器的程序&#xff0c;如c语言的clang clang -o hello hello.csrc/ $ clang -o hello hello_world.c /usr/bin/ld: /tmp/hello_world-67f51…

【VTKExamples::PolyData】第二十四期 InterpolateTerrain

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例InterpolateTerrain,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. InterpolateTerrain 输出: Interp…

FX110网:如何判断行情是真突破还是假突破?

众所周知&#xff0c;在交易过程中&#xff0c;趋向线的突破对买入、卖出时机等选择具有重要的分析意义。因此&#xff0c;搞清趋势线何时突破&#xff0c;是有效的突破还是非有效的突破&#xff0c;于投资者而言是至关重要的。 本文将提供一些对于趋向线突破的判断方法和市场原…

软考 系统分析师系列知识点之信息系统战略规划方法(4)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之信息系统战略规划方法&#xff08;3&#xff09; 所属章节&#xff1a; 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.2 关键成功因素法 关键成功因素&#xff08;Critical Success Factors&#xff0c…

PySpark(四)PySpark SQL、Catalyst优化器、Spark SQL的执行流程、Spark新特性

目录 PySpark SQL 基础 SparkSession对象 DataFrame入门 DataFrame构建 DataFrame代码风格 DSL SQL SparkSQL Shuffle 分区数目 DataFrame数据写出 Spark UDF Catalyst优化器 Spark SQL的执行流程 Spark新特性 自适应查询(SparkSQL) 动态合并 动态调整Join策略 …

Redis篇之持久化

一、为什么要进行持久化 Redis是一个基于内存的键值存储系统&#xff0c;但为了保证数据在服务器重启、故障等情况下不丢失。 二、应该怎么持久化 1.RDB持久化 &#xff08;1&#xff09;RDB是什么 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff…

Android性能调优 - 应用安全问题

Android应用安全 1.组件暴露&#xff1a; 像比如ContentProvider,BroadcastReceiver&#xff0c;Activity等组件有android:exported属性&#xff1b; 如果是私有组件 android:exported “false”&#xff1b; 如果是公有组件 android:exported “true” 且进行权限控制&…

[BeginCTF]真龙之力

安装程序 双击安装 出现了安装失败的标签&#xff0c;开发者不允许测试。 查看Mainfest入口文件 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android" android:versionCo…

【Spring源码解读!底层原理高级进阶】【上】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

Electron基本介绍

Electron基本介绍 Electron 官方网站&#xff1a;https://www.electronjs.org/zh/ Electron安装方法&#xff1a;npm install electron -g 全局安装 Electron简介&#xff1a;Electron提供了丰富的本地&#xff08;操作系统&#xff09;API&#xff0c;使你能够使用纯JavaScr…

springboot项目热部署实现(Spring Boot DevTools方式)

文章目录 Spring Boot DevTools简介Spring Boot DevTools原理spring Boot Devtools优缺点Spring Boot DevTools集成步骤第一步&#xff1a;添加maven依赖第二步&#xff1a;IDEA热部署配置 Spring Boot DevTools简介 Spring Boot DevTools是Spring Boot提供的一个开发工具&…

UE4运用C++和框架开发坦克大战教程笔记(十九)(第58~60集)完结

UE4运用C和框架开发坦克大战教程笔记&#xff08;十九&#xff09;&#xff08;第58~60集&#xff09;完结 58. 弹窗显示与隐藏59. UI 面板销毁60. 框架完成与总结 58. 弹窗显示与隐藏 这节课我们先来补全 TransferMask() 里对于 Overlay 布局类型面板的遮罩转移逻辑&#xff…

K8S之运用亲和性设置Pod的调度约束

亲和性 Node节点亲和性硬亲和实践软亲和性实践 Pod节点亲和性和反亲和性pod亲和性硬亲和实践 pod反亲和性 Pod 的yaml文件里 spec 字段中包含一个 affinity 字段&#xff0c;使用一组亲和性调度规则&#xff0c;指定pod的调度约束。 kubectl explain pods.spec.affinity 配置…

MySQL优化器

优化器 MySQL存储引擎中存在了一个可插拔的优化器OPTIMIZER_TRACE&#xff0c;可以看到内部查询计划的TRACE信息&#xff0c;从而可以知道MySQL内部执行过程 查询优化器状态 show variables like optimizer_trace;Variable_name Valueoptimizer_trace enabledoff,one_lineoff…

[C++] opencv + qt 创建带滚动条的图像显示窗口代替imshow

在OpenCV中&#xff0c;imshow函数默认情况下是不支持滚动条的。如果想要显示滚动条&#xff0c;可以考虑使用其他库或方法来进行实现。 一种方法是使用Qt库&#xff0c;使用该库可以创建一个带有滚动条的窗口&#xff0c;并在其中显示图像。具体步骤如下&#xff1a; 1&…

【翻译】Processing安卓模式的安装使用及打包发布(内含中文版截图)

原文链接在下面的每一章的最前面。 原文有三篇&#xff0c;译者不知道贴哪篇了&#xff0c;这篇干脆标了原创。。 译者声明&#xff1a;本文原文来自于GNU协议支持下的项目&#xff0c;具备开源二改授权&#xff0c;可翻译后公开。 文章目录 Install&#xff08;安装&#xff0…

路由引入路由过滤排错

目录 排错网络拓扑图 排错需求 故障排错 故障一 故障二 故障三 排错网络拓扑图 排错需求 按照图示配置 IP 地址&#xff0c;总部和分支 A、分支 B 各自使用 loopback 口模拟业务网段公司业务流分为 A 流和 B 流&#xff0c;网段如图所示总部内部配置 OSPF 互通&#xff0…

Frostmourne (霜之哀伤)日志告警系统部署安装

简介 Frostmourne(霜之哀伤)是汽车之家经销商技术部监控系统的开源版本&#xff0c;用于帮助监控几乎所有数据库数据(包括Elasticsearch, Prometheus, SkyWalking, MySql 等等)。如果你已经建立起了日志系统&#xff0c; 指标体系&#xff0c;却苦恼于没有一个配套监控系统&am…

【芯片设计- RTL 数字逻辑设计入门 15 -- 函数实现数据大小端转换】

文章目录 函数实现数据大小端转换函数语法函数使用的规则Verilog and Testbench综合图VCS 仿真波形 函数实现数据大小端转换 在数字芯片设计中&#xff0c;经常把实现特定功能的模块编写成函数&#xff0c;在需要的时候再在主模块中调用&#xff0c;以提高代码的复用性和提高设…

「递归算法」:二叉树剪枝

一、题目 给你二叉树的根结点 root &#xff0c;此外树的每个结点的值要么是 0 &#xff0c;要么是 1 。 返回移除了所有不包含 1 的子树的原二叉树。 节点 node 的子树为 node 本身加上所有 node 的后代。 示例 1&#xff1a; 输入&#xff1a;root [1,null,0,0,1] 输出&…