k8s进阶5——AppArmor、Seccomp、ImagePolicyWebhook

文章目录

  • 一、AppArmor限制容器对资源访问
    • 1.1 实现步骤
      • 1.1.1 定义策略
      • 1.1.2 加载策略
      • 1.1.3 引用策略
    • 2.2 案例
  • 二、Seccomp 限制容器进程系统调用
    • 案例一:使用自定义策略
    • 案例二:使用容器运行时默认策略
  • 三、动态准入控制Webhook
    • 3.1 ImagePolicyWebhook控制器
      • 3.1.1 apiserver服务器准备操作
      • 3.1.2 部署webhook服务器
      • 3.1.3 测试验证

一、AppArmor限制容器对资源访问

概念:

  • AppArmor(Application Armor) 是一个 Linux 内核安全模块,用于限制主机操作系统上运行的进程。每个进程都可以拥有自己的安全配置文件,安全配置文件用来允许或禁止特定功能,例如网络访问、文件读/写/执行权限等。
  • 是Linux发行版的内置功能,比如Ubuntu、Debian、SUSE,而CentOS和redhat系统没有这个AppArmor,其功能相当于selinux,但selinux安全程度不高,也不方便使用,所以一般人不用。
  • Ubuntu系统携带了许多没有合并到上游 Linux 内核中的 AppArmor 补丁, 包括添加附加钩子和特性的补丁。Kubernetes 只在上游版本中测试过,不承诺支持其他特性。

工作模式:

  1. Enforcement(强制模式) :在这种模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条件的程序会进行日志记录,相当于selinux的enforcing模式。
  2. Complain(投诉模式):在这种模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行记录,一般用于调试,相当于selinux的permissive模式。

K8s使用AppArmor的先决条件:

  1. K8s版本v1.4+,检查是否支持:kubectl describe node |grep AppArmor。
  2. Linux内核已启用AppArmor,查看 cat /sys/module/apparmor/parameters/enabled。
  3. 容器运行时需要支持AppArmor,docker、CRI-O 、containerd都支持。
  4. 比如以下ubuntu系统核内核是支持的,但在centos系统是看不到apparmor进程的。
    在这里插入图片描述

工作流程图:在这里插入图片描述

1.1 实现步骤

****:

  1. 将自定义策略配置文件保存到默认目录/etc/apparmor.d/下。
  2. 加载配置文件到内核。
  3. 定义pod.yaml文件时,在注解参数下指定策略名。因为AppArmor目前还处于测试阶段,因此以注解形式设定,日后进入正式阶段就可以使用安全上下文格式来配置了。

1.1.1 定义策略

配置策略:

vim /etc/apparmor.d/k8s-deny-write      ##文件名称自定义。
#include <tunables/global>     ##默认格式,导入依赖,遵循C语言约定。
profile k8s-deny-write flags=(attach_disconnected) {    ##指定策略名,也就是命令能查到显示出来的策略名称。#include <abstractions/base>      ##定义策略。file,                             ##允许所有文件读写。deny /bin/** w,                   ##递归匹配,拒绝/bin目录下的所有目录和文件写权限。deny /data/www/** w,              ##递归匹配,拒绝/data/www目录下的所有目录和文件写权限。
}

1.1.2 加载策略

  • 使用以下命令将策略加载到内核。
常用命令释义
apparmor_status查看AppArmor配置文件的当前状态的。
apparmor_parser将AppArmor配置文件加载到内核中。
apparmor_parser < profile >加载到内核中。
apparmor_parser -r < profile >重新加载配置。
apparmor_parser -R < profile >删除配置。
aa-complain将AppArmor配置文件设置为投诉模式,需要安装apparmor-utils软件包。
aa-enforce将AppArmor配置文件设置为强制模式,需要安装apparmor-utils软件包。

1.1.3 引用策略

  • 定义pod.yaml时添加注解加以引用。
  • 注意,引用的策略文件必须是要pod所在的宿主机上,实际生产中是需要运维来维护的,可以写脚本把策略文件给K8s集群每个节点分配上去并加载到内核。
apiVersion: v1
kind: Pod
metadata:name: hello-apparmorannotations:container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_ref>......##< container_name >: Pod中容器名称。##< profile_ref >: Pod所在宿主机上策略名,默认目录/etc/apparmor.d。
访问文件权限模式字符描述
r
w
a追加
k文件锁定
l链接
x可执行
通配符描述示例
*在目录级别匹配零个或多个字符。/dir/* :匹配目录中的任何文件。
/dir/a* :匹配目录中以a开头的任意文件。
/dir/.png: 匹配目录中以.png结尾的任意文件。
/dir/a
/ :匹配/dir里面以a开头的目录。
/dir/*a/ :匹配/dir里面以a结尾的目录。
**在多个目录级别匹配零个或多个字符。/dir/** : 匹配/dir目录或者/dir目录下任何文件和目录。
/dir/**/ : 匹配/dir或者/dir下面任何目录。
[]
[^]
字符串,匹配其中任意字符。/dir/[^.]* :匹配/dir目录中以.之外的任何文件。
/dir/**[^/] :匹配/dir目录或者/dir下面的任何目录中的任何文件。
pod.yaml字段释义
<container_name>pod.yaml文件里所针对的容器名称。
<profile_def>Pod所在宿主机上策略名,引用刚刚定义的配置文件。
<profile_ref>可以是以下取值之一:
runtime/default:应用运行时的默认配置。
localhost/<profile_name>:应用在主机上加载的名为 <profile_name> 的配置文件。
unconfined:表示不加载配置文件。

2.2 案例

案例:容器文件系统访问限制。

1.先查看默认生效的策略名称,我们定义的策略生效后就会显示在该列表中。
在这里插入图片描述
2.查看策略文件所在目录。
在这里插入图片描述
3.在K8s每个节点的/etc/apparmor.d目录下生成策略文件。策略是禁止在/bin目录下写,然后将策略文件加载到内核,查看结果。因为在编写pod.yaml里指定策略地址时,是使用的localhost读取本地。
在这里插入图片描述
在这里插入图片描述
4.先测试下使用我们生成策略之前效果,进入测试容器,可以在/bin目录下正常创建文件。
在这里插入图片描述
5.创建一个pod,其yaml文件里指定策略名称。
在这里插入图片描述
在这里插入图片描述
6.进入该容器创建目录测试效果。
在这里插入图片描述
7.若要修改策略,则修改后需要重新加载,并且需要重建pod容器。

apparmor parser -r k8s-deny-write

二、Seccomp 限制容器进程系统调用

前提了解:

  • 在Linux上, 我们操作的所有跟资源相关的命令都是通过系统调用来完成的。
  • 系统调用实现技术层次上解耦,内核只关心系统调用API的实现,而不必关心谁调用的。

调用关系图:
在这里插入图片描述

基本概念:

  1. Seccomp(Secure computing mode) 是一个 Linux 内核安全模块,可用于应用进程允许使用的系统调用。容器实际上是在宿主机上运行的一个进程,共享宿主机内核,如果所有容器都具有任何系统调用的能力,那么容器如果被入侵,就很轻松绕过容器隔离更改宿主机系统权限或者进入宿主机。这就可以使用Seccomp机制限制容器系统调用,有效减少攻击面。
  2. Linux发行版内置:CentOS、Ubuntu。

Type类型:

  • pod.yaml中会定义Type字段,表示将应用哪种类型的seccomp配置文件,具有如下选项:
    • Localhost:应该使用在节点上的文件中定义的配置文件。
    • RuntimeDefault:应该使用容器运行时默认配置文件。
    • Unconfined:无限制,不使用策略。

注意事项:

  1. 引用的策略文件必须是要pod所在的宿主机上,实际生产中是需要运维来维护的,可以写脚本把策略文件给K8s集群每个节点分配上去并加载到内核。
  2. Seccomp在Kubernetes 1.3版本引入,在1.19版本成为GA版本,因此K8s中使用Seccomp可以通过以下两种方式:
    • 1.19版本之前使用注解:
    annotations:seccomp.security.alpha.kubernetes.io/pod: "localhost/<profile>"
    
    • 1.19版本+配置安全上下文:
    apiVersion: v1
    kind: Pod
    metadata:name: hello-seccomp
    spec:securityContext:seccompProfile:type: LocalhostlocalhostProfile: <profile> # Pod所在宿主机上策略文件名,默认目录:/var/lib/kubelet/seccompcontainers:
    ...
    

案例一:使用自定义策略

  • 需求:禁止容器使用chmod。

1.创建默认文件路径。

[root@k8s-master1 ~]# mkdir /var/lib/kubelet/seccomp

2.在默认路径下生成限制策略。

[root@k8s-master1 seccomp]# cat chmod.json 
{"defaultAction": "SCMP_ACT_ALLOW",       ##在syscalls部分未定义的任何系统调用默认动作为允许。"syscalls": [{"names": [                      ##系统调用名称,可以换行写多个。"chmod"],"action": "SCMP_ACT_ERRNO"      ## 阻止自定义的系统调用。}]  
}

3.创建pod时,引用该策略。

[root@k8s-master1 ResourceQuota]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: baimu
spec:nodeName: k8s-master1    ##需要执行该pod被分配的机器上是有限制策略的。securityContext:         ##添加此参数。seccompProfile:type: Localhost      ##指定类型,调用本地自定义策略文件。localhostProfile: chmod.json       ##使用相对路径,指定应用策略名称。containers:- image: busyboxname: testcommand:- sleep- 24h

4.进入普通容器测试可以修改权限。
在这里插入图片描述
5.进入指定限制策略的容器修改权限失败,限制成功。
在这里插入图片描述
6.此时需要再限制创建目录权限,就直接在chmod.json文件里加。
在这里插入图片描述
7.限制策略文件内容更改后,指定该策略的pod需要重新创建,先删除再创建容器,最后进入容器测试。
在这里插入图片描述

案例二:使用容器运行时默认策略

  • 大多数容器运行时都提供一组允许或不允许的默认系统调用。

  • 通过使用 runtime/default 注释 或将Pod 或容器的安全上下文中的 seccomp 类型设置为 RuntimeDefault,可以轻松地在 Kubernetes中应用默认值。

  • docker默认配置说明
    在这里插入图片描述

1.指定docker默认策略创建pod。

[root@k8s-master1 ResourceQuota]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: baimu
spec:nodeName: k8s-master1securityContext:seccompProfile:type: RuntimeDefault    ##修改类型,使用容器运行时默认策略。#  localhostProfile: chmod.json    ##注释掉。containers:- image: busyboxname: testcommand:- sleep- 24h

2.查看系统调用。查看操作命令用到哪些系统调用可以使用strace命令查看,一个命令通常会使用多个系统调用,若是在实际生产中使用需要挨个调试。

[root@k8s-master1 seccomp]# yum -y install strace

在这里插入图片描述

三、动态准入控制Webhook

基本概念:

  • 前面讲过的准入控制是通过添加K8s内置的准入插件来实现,当然也可以作为扩展独立开发,并以运行时所配置的 Webhook 的形式运行。
  • 准入控制器Webhook是准入控制插件的一种,是一种用于接收准入请求并对其进行处理的 HTTP 回调机制 ,常用于拦截所有向apiserver发送的请求,并且可以修改请求或拒绝请求。
  • Admission webhook为开发者提供了非常灵活的插件模式,在kubernetes资源持久化之前,管理员通过程序可以对指定资源做校验、修改等操作。例如为资源自动打标签、pod设置默认SA,自动注入sidecar容器等。

Webhook准入控制器分类:

  1. Mutating Admission Webhook:先调用,修改资源,理论上可以监听并修改任何经过ApiServer处理的请求。
  2. Validating Admission Webhook:后调用,验证资源。
  3. ImagePolicyWebhook:镜像策略,主要验证镜像字段是否满足条件,允许使用后端 Webhook 做出准入决策。

工作流程图:
在这里插入图片描述

3.1 ImagePolicyWebhook控制器

工作流程图:
在这里插入图片描述
玩法思路:

  1. 签发证书。镜像策略服务器是以https启用,需要给它自签证书,访问它时也要携带根证书或者客户端证书。
  2. 准备imgaepolicywebhook配置文件,指定镜像策略服务器配置文件存放目录。
  3. 准备镜像策略服务器配置文件,指定连接服务器IP地址、端口、API、根证书、客户端证书。
  4. 启用准入控制插件。

3.1.1 apiserver服务器准备操作

1.定义镜像策略控制器配置文件,指定配置文件存放路径。

##镜像策略控制器配置文件,指定连接镜像策略服务器配置文件地址,连接服务器通用策略。
[root@k8s-master1 imagepolicywebhook]# cat admission_configuration.yaml 
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhookconfiguration:imagePolicy:kubeConfigFile: /etc/kubernetes/image-policy/connect_webhook.yaml  # 指定镜像策略服务器配置文件。allowTTL: 50       # 控制批准请求的缓存时间,单位秒denyTTL: 50        # 控制批准请求的缓存时间,单位秒retryBackoff: 500    # 控制重试间隔,单位毫秒defaultAllow: true    # 确定webhook后端失效的行为

2.定义镜像策略服务器连接配置文件,指定它的根证书、连接它的客户端证书、连接地址、端口和API。

[root@k8s-master1 imagepolicywebhook]# cat connect_webhook.yaml 
apiVersion: v1
kind: Config
clusters:
- cluster:certificate-authority: /etc/kubernetes/image-policy/webhook.pem # 数字证书,用于验证远程服务server: https://192.168.130.146:8080/image_policy # 镜像策略服务器地址,必须是httpsname: webhook
contexts:
- context:cluster: webhookuser: apiservername: webhook
current-context: webhook 
preferences: {}
users:
- name: apiserveruser:client-certificate: /etc/kubernetes/image-policy/apiserver-client.pem # webhook准入控制器使用的证书client-key: /etc/kubernetes/image-policy/apiserver-client-key.pem # 对应私钥证书

3.统一两文件存放目录。

[root@k8s-master1 imagepolicywebhook]# mkdir -p /etc/kubernetes/image-policy  
[root@k8s-master1 imagepolicywebhook]# mv admission_configuration.yaml connect_webhook.yaml /etc/kubernetes/image-policy/

4.签发证书。

[root@k8s-master1 ssl]# cat image-policy-certs.sh 
cat > ca-config.json <<EOF    ##k8s根证书。
{"signing": {"default": {"expiry": "87600h"},"profiles": {"kubernetes": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOFcat > ca-csr.json <<EOF
{"CN": "kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","ST": "Beijing"}]
}
EOFcfssl gencert -initca ca-csr.json | cfssljson -bare ca -cat > webhook-csr.json <<EOF   ##镜像策略服务器根证书。
{"CN": "webhook","hosts": ["192.168.130.146"     ##镜像策略服务器地址。],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOFcfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes webhook-csr.json | cfssljson -bare webhookcat > apiserver-client-csr.json <<EOF            ##连接镜像策略服务器的客户端证书。
{"CN": "apiserver","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOFcfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-client-csr.json | cfssljson -bare apiserver-client

在这里插入图片描述

5.将证书放入前面两文件目录里,文件里有指定读取这两个证书。

[root@k8s-master1 ssl]# mv apiserver-client*.pem webhook.pem /etc/kubernetes/image-policy/

6.修改apiserver配置文件,开启ImagePolicyWebhook插件,指定imagepolicywebhook配置文件位置,并挂载到容器里面。

 - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook- --admission-control-config-file=/etc/kubernetes/image-policy/admission_configuration.yaml

在这里插入图片描述
在这里插入图片描述

3.1.2 部署webhook服务器

在这里插入图片描述

1.部署webhook站点服务器,我这里是写了一个python程序来实现对部署时的镜像没有指定标签(即latest)进行拒绝。

[root@k8s-master2 imagepolicywebhook]# cat main.py 
from flask import Flask,request
import jsonapp = Flask(__name__)@app.route('/image_policy',methods=["POST"])     ##处理发送过来的post请求。
def image_policy():post_data = request.get_data().decode()           ##接受发送过来的post请求。#print("POST数据: %s" %post_data)                  ##将post请求打印出来。data = json.loads(post_data)                      ##解析这个post请求。for c in data['spec']['containers']:                  ##过滤这个post请求中的spec.containers字段下的内容。if ":" not in c['image'] or ":latest" in c['image']:  ##如果镜像里不带冒号或者带:latest说明是镜像使用latest标签。allowed, reason = False, "检查镜像失败!镜像标签不允许使用latest!"breakelse:allowed, reason = True, "检查镜像通过."print("检查结果: %s" %reason)result = {"apiVersion": "imagepolicy.k8s.io/v1alpha1","kind": "ImageReview",     ##返回个apiserver的api,固定格式。"status": {"allowed": allowed,"reason": reason}}return json.dumps(result,ensure_ascii=False) if __name__ == "__main__":                               ##监听服务端口8999,需要把证书传到该服务器,后面会挂载到容器里。app.run(host="0.0.0.0",port=8080,ssl_context=('/data/www/webhook.pem','/data/www/webhook-key.pem'))

2.构建镜像。

[root@k8s-master2 imagepolicywebhook]# cat Dockerfile 
FROM python
RUN useradd python
RUN mkdir /data/www -p
COPY . /data/www
RUN chown -R python /data
RUN pip install flask -i https://mirrors.aliyun.com/pypi/simple/
WORKDIR /data/www
USER python
CMD python main.py [root@k8s-master2 imagepolicywebhook]# docker build -t qingjun:v1  .

3.准备好之前在apiserver服务器上创建的证书,并运行一个容器进入查看,容器日志会显示python程序检查apiserver发过来的请求结果。

docker run -d -u root --name=baimu1 \
-v $PWD/webhook.pem:/data/www/webhook.pem \
-v $PWD/webhook-key.pem:/data/www/webhook-key.pem \
-e PYTHONUNBUFFERED=1 -p 8080:8080 \
qingjun:v1

在这里插入图片描述

3.1.3 测试验证

1.创建pod容器时,使用不带标签的镜像,则返回false。
在这里插入图片描述
2.创建pod容器时,使用带latest标签的镜像,返回false。
在这里插入图片描述
3.创建pod容器时,使用带标签的镜像,返回true。
在这里插入图片描述

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

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

相关文章

数组如何转对象

最近做项目的时候需要把拿到的数组转为对象使用 let arr [{id:1,value:正式},{id:2,value:非正式}]//首先定义一个空对象let obj{}//循环遍历数组arr.forEach(item>{//把id作为对象的键 把value作为对象的值值obj[item.id]item.value})console.log(obj);运行结果如下 这样…

对象转为数组

对象转成数组 在开发中&#xff0c;前端处理数据&#xff0c;很多时候都会用到把对象转成数组&#xff0c;话不多说&#xff0c;咱们直接上代码 // 对象转数组&#xff0c;想要转成什么字段根据需求 function fmObjToArr (data) {let arr []for (let key in data) {arr.push…

js数组对象转对象

将数组对象的数据转换为普通对象键值对key:value的形式 let arr [{id:1,employeeNo:110,name:张三},{id:2,employeeNo:111,name:李四},{id:3,employeeNo:112,name:王五},{id:4,employeeNo:113,name:章雨},{id:5,employeeNo:114,name:小红}, ] let newObj {} arr.map(item >…

JS对象转数组

一、JS对象转数组方法如下(不考虑for相关遍历): 1.[...res] 2.Array.from(res) 3.Object.values(res) 4. Array.prototype.slice.call(res) let obj {name:李四, age:22, gender:男} //可枚举 let obj2 {0:李四, 1:22, 2:男, length:3} //可枚举 伪数组 let set new Set([…

3种JavaScript 对象转数组的方法

来源 | https://www.fly63.com 我们在项目开发的时候&#xff0c;有时需要将js对象转换为数组&#xff0c;下面小编给大家具体演示一下怎么转换&#xff0c;主要是介绍一些常用、简洁的转换方法。 比如JavaScript对象如下&#xff1a; let obj {name: 前端,url: https://www.w…

对象数据如何转化成数组

文章目录 前言一、后端给的数据二、如何转换三、最终结果 前言 项目中后端给的数据有时候不可能完全符合前端的数据要求&#xff0c;比如element-uivue项目组合中&#xff0c;下拉框数据是数组的形式。然而后端同事给的确是对象数据&#xff0c;当然你可以和后端协商改成你想要…

json对象转对象数组

对象的两种取值方式 let obj {name: wan}; console.log(obj.name); //wan这是最普通的一种方式&#xff0c;还有一种方式我们用的不太多&#xff0c;就是使用[]包住属性名取值 let obj {name: wan}; console.log(obj[name]); //wan将对象转化为数组 let obj {未完成:5, 已…

将数组转换为对象

本文翻译自&#xff1a;Convert Array to Object What is the best way to convert: 转换的最佳方式是什么&#xff1a; [a,b,c]to: 至&#xff1a; {0: a,1: b,2: c }#1楼 参考&#xff1a;https://stackoom.com/question/Hghl/将数组转换为对象 #2楼 Quick and dirty #2…

js把对象转换成数组

1.把类似数组的对象转换成数组 【1】什么是类似数组的对象 比如&#xff1a; let arrayLike {0:"z",1:"y",2:"k",length:3 }; 本质是有length属性&#xff0c;可以类似数组的获取元素的方式arrayLike[0]、arrayLike[1]去获取元素&#xff0…

js数组转对象

js数组转对象 1.js var list {}; var arr ["123","456","789"]; for (var key in arr) {list[key] arr[key]; } console.log(list); 效果&#xff1a;

JS 中的类数组对象如何转换为数组?

大家好&#xff0c;我是前端西瓜哥&#xff0c;今天说一下 JS 的类数组对象是什么&#xff0c;以及如何将类数组对象转为数组。 类数组对象是什么&#xff1f; 类数组对象&#xff0c;就是含有 length 属性的对象&#xff0c;但这个对象不是数组。 通常来说还会有 0 &#x…

js中对象转数组

今天睡前看到小组群里贴了这么一张图&#xff0c;印象中曾经面试的时候好像也是遇到过&#xff0c;对于大佬们来说这肯定是很基础的一道题&#xff0c;在此分享给正在学习前端和正在面试的小伙伴们。 这里我用fo……in……实现了两种取值方式的改变 let obj {json:0,production…

(十六)创建Lua脚本模板

Unity里能创建 c#脚本模板&#xff0c;但是如果我想创建Lua脚本模板怎么办呢&#xff1f;拓展一下编辑器吧。 设置一下Lua脚本的模板地址 &#xff1a; Assets/Editor/Lua/Template/lua.lua using UnityEngine; using UnityEditor; using System; using System.IO; using Sys…

Unity(二十):创建自定义脚本模板

编辑器内部自定义脚本存储位置展示 创建自己的自定义脚本 using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using UnityEditor; using UnityEditor.ProjectWindowCallback; using UnityEngine;internal class C…

修改Visual Studio中C#中的默认脚本模板方法

目录 一、修改后的效果 二、修改Visual Studio中C#的默认脚本步骤 三、验证修改模板是否成功 一、修改后的效果 二、修改Visual Studio中C#的默认脚本步骤 ①如果按照Visual Studio的默认安装路径安装该IDE,则路径为&#xff1a; C:\Program Files (x86)\Microsoft Visual …

Unity 添加,修改默认创建脚本模板

Unity 默认创建的脚本可以添加也可以修改&#xff0c;不需要修改Editor。 一、找到模板目录 \Editor\Data\Resources\ScriptTemplates 二、如果要修改模板&#xff0c;直接打开修改就可以了&#xff0c;每个模板都是可以修改的。 修改默认unity创建的脚本&#xff1a; 三、如…

Unity编辑器VS的脚本模板(Script Templates)设置

最近在用Unity做小游戏玩儿时&#xff0c;经常需要用到添加一些整体的说明或者相关系列脚本开发的功能&#xff0c;每一次都需要去手动的敲一下题头说明&#xff0c;虽然也只是从一个脚本copy题头过来修改&#xff0c;但是也是挺麻烦的&#xff0c;做的只是无用功重复&#xff…

unity修改脚本模板

文章目录 前言 前言 在unity有时候创建脚本的时候&#xff0c;会频繁加一些命名空间或者要继承基类并且重写方法&#xff0c;在这里记录一下&#xff0c;修改一下创建脚本时默认模板。 打开安装的unity&#xff0c; 将 81-C# Script-NewBehaviourScript.cs 移动到桌面 使用VS打…

Unity 自定义脚本模板

找到模板 C:\Program Files\Unity\Editor\Data\Resources\ScriptTemplates修改模板 将自己想要自定义模板的原版复制一个副本&#xff0c;并自定义名称 80&#xff1a;序号&#xff1b;Tmz Script&#xff1a;一级列表中的名称&#xff1b;NewTmzScript&#xff1a;新建出来…

pygame安装成功了但却无法导入求大神解

setting里面也设置成功使用了 就是无法导入 有懂得大神指导一下吗 2.8 后面发现是版本不兼容导致的