首页 > 其他分享 >Kubernetes 学习整理(三)

Kubernetes 学习整理(三)

时间:2024-01-24 15:22:19浏览次数:30  
标签:kubectl Kubernetes kubernetes -- app bootcamp 学习 整理 root

k8s

kubelet (Kubernetes node agent): 是运行在每个节点上的代理,负责管理该节点上的容器, 它从 Kubernetes Master 接收 Pod 的描述,并确保节点上运行的容器与描述一致。不能跨节点。
kubelet 的主要作用是保证节点上的容器按照期望的状态运行。它监控容器的健康状态,执行生命周期操作,并报告状态给 Kubernetes Master。

kubectl(kubernetes 集群维护检查): 部署应用程序、创建和管理 Kubernetes 资源,以及监控集群中的各种状态

kube-apiserver
拉取 kube-apiserver 镜像,如果没有显示,则启动一个 goroutine 来等待 etcd,然后在 /var/lib/rancher/rke2/agent/pod-manifests/ 中写入静态 pod 定义。

ll /var/lib/rancher/rke2/agent/pod-manifests/
total 32
-rw-r--r-- 1 root root 3282 Jan 17 22:52 etcd.yaml
# 是分布式键值存储系统,用于存储 Kubernetes 集群的配置信息、状态和元数据。它是集群的数据存储后端。
# 需要足够的权限以接受和处理来自 kube-apiserver 的写入和读取请求。存储和提供集群的配置信息,保持集群状态的一致性。
-rw-r--r-- 1 root root 9704 Jan 17 22:55 kube-apiserver.yaml
# 负责提供集群的 API 接口。它接收来自各种客户端(如 kubectl、Controller Manager、Scheduler 等)的请求,并将这些请求转换成对集群状态的操作。支持资源的创建、更新、删除等操作,同时执行身份验证和授权。
-rw-r--r-- 1 root root 5468 Jan 17 22:55 kube-controller-manager.yaml
# 包含多个控制器,每个控制器负责监控集群中的不同资源类型。控制器的任务包括确保实际状态与期望状态一致,处理故障恢复等。
-rw-r--r-- 1 root root 2444 Jan 17 22:55 kube-proxy.yaml
# 运行在每个节点上,其作用范围限定在单个节点上, 主要涉及网络规则的设置,通常需要足够的权限以配置节点上的网络规则。
-rw-r--r-- 1 root root 3895 Jan 17 23:16 kube-scheduler.yaml
# 负责将新创建的 Pod 调度到集群中的节点上。它考虑节点资源、亲和性、亲和性规则等因素来选择最合适的节点,并更新调度的相关状态。
drwxr-xr-x 1 root root  138 Jan 17 23:16 scheduler

ll /var/lib/rancher/rke2/agent/pod-manifests/scheduler/
total 20
-rw-r--r-- 1 root root  433 Jan 17 23:16 config-19.yaml
-rw-r--r-- 1 root root  433 Jan 17 23:16 config-23.yaml
-rw-r--r-- 1 root root  350 Jan 17 23:16 config.yaml
-rw-r--r-- 1 root root 2729 Jan 17 23:16 kube-scheduler.yaml
-rw-r--r-- 1 root root  266 Jan 17 23:16 policy.yaml

Etcd 和 Kubernetes Control Plane 组件在 kube-system 命名空间中作为静态 Pod 运行。
可以使用 kubectl 访问每个 Kubernetes Pod 的日志:

/var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml logs -n kube-system -l component=kube-apiserver

使用 kubectl 从外部访问集群
将 /etc/rancher/rke2/rke2.yaml 复制到位于集群外部的主机上的 ~/.kube/config。然后将 127.0.0.1 替换为 RKE2 server 的 IP 或主机名。现在,你可以使用 kubectl 来管理 RKE2 集群。

/var/lib/rancher/rke2 是 RKE2 的默认数据目录, 快照是默认启动的

# 手动执行快照: rke2 etcd-snapshot save --name pre-upgrade-snapshot
ll /var/lib/rancher/rke2/server/db/snapshots
total 222768
-rw------- 1 root root 38015008 Jan 19 12:00 etcd-snapshot-ali1-atlantic-host-1705694403
-rw------- 1 root root 38015008 Jan 20 00:00 etcd-snapshot-ali1-atlantic-host-1705737602
-rw------- 1 root root 38015008 Jan 20 12:00 etcd-snapshot-ali1-atlantic-host-1705780802
-rw------- 1 root root 38015008 Jan 21 00:00 etcd-snapshot-ali1-atlantic-host-1705824001
-rw------- 1 root root 38015008 Jan 21 12:00 etcd-snapshot-ali1-atlantic-host-1705867202
-rw------- 1 root root 38015008 Jan 21 19:21 pre-upgrade-snapshot-ali1-atlantic-host-1705893675

Helm 是 Kubernetes 的包管理工具。Helm Chart 为 Kubernetes YAML 清单文件提供了模板语法。通过 Helm,用户可以创建可配置的 deployment,而不仅仅只能使用静态文件。

日志:
journalctl -u rke2-server
journalctl -u rke2-agent
/var/log/syslog
/var/lib/rancher/rke2/agent/containerd/containerd.log
/var/lib/rancher/rke2/agent/logs/kubelet.log

每个容器的日志都写入 /var/log/pods,你也可以使用 crictl 访问:

export CONTAINER_RUNTIME_ENDPOINT=unix:///run/k3s/containerd/containerd.sock
# 列出运行的容器
/var/lib/rancher/rke2/bin/crictl ps
# 通过容器 ID 获取容器日志
/var/lib/rancher/rke2/bin/crictl logs <container_id>

rke2-server 主要运行 etcd(用于存储集群状态)、kube-apiserver(提供 Kubernetes API)、kube-controller-manager(运行控制器)、kube-scheduler(调度器)等控制平面组件。。

rke2-agent 运行 Pod 和容器,负责执行实际的应用程序工作负载, 将节点注册到 etcd 中,以及与 rke2-server 通信以保持集群状态一致。

  1. Create a Kubernetes cluster

  2. Deploy an app

  3. Explore your app
    kubectl get pods 命令检查您的应用程序的 Pod 是否已成功启
    kubectl logs 命令查看应用程序 Pod 的日志,以了解应用程序的运行状况和可能的错误。
    kubectl get services 命令检查服务的状态。

  4. Expose your app publicly:通过执行 "Expose your app publicly" 步骤,您可以确保应用程序可以从集群外部访问,提供给外部用户或其他系统使用。
    kubectl expose 命令或通过定义一个 Service YAML 文件来创建一个 Kubernetes Service
    进一步公开应用程序,使其可以通过集群节点的公共 IP 地址和一个公共端口访问。这通常使用 Service 类型为 LoadBalancer 或 NodePort 来完成。
    kubectl get services 命令检查新创建的 Service 的外部 IP 地址和端口。
    使用提供的 IP 地址和端口访问您的应用程序。这可以通过浏览器、curl 或其他工具来完成。

  5. Scale up your app 第3 4 步骤分别是做什么

Deploy an app

1. kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

2. kubectl get deployments

View the app

# open a second terminal window to run the proxy:
1. kubectl proxy

# query the version directly through the API using the curl command:
2. curl http://localhost:8001/version
{
  "major": "1",
  "minor": "27",
  "gitVersion": "v1.27.6+rke2r1",
  "gitCommit": "741c8db18a52787d734cbe4795f0b4ad860906d6",
  "gitTreeState": "clean",
  "buildDate": "2023-09-13T19:23:53Z",
  "goVersion": "go1.20.8 X:boringcrypto",
  "compiler": "gc",
  "platform": "linux/amd64"


# First we need to get the Pod name, and we'll store in the environment variable POD_NAME:

3. export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
4. echo Name of the Pod: $POD_NAME
5. curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/
6. curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME:8080/proxy/

# Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-855d5cc575-v22dh | v=1

Explore the APP

kubectl get - list resources
kubectl describe - show detailed information about a resource
kubectl logs - print the logs from a container in a pod
kubectl exec - execute a command on a container in a pod

kubectl logs "$POD_NAME"
kubectl exec "$POD_NAME" -- env

在container 内部执行

# 进入container内部的bash
kubectl exec -ti $POD_NAME -- bash
root@kubernetes-bootcamp-855d5cc575-v22dh:/#

# 在container内部执行cli
root@kubernetes-bootcamp-855d5cc575-v22dh:/# cat server.js
var http = require('http');
var requests=0;
var podname= process.env.HOSTNAME;
var startTime;
var host;

# 在container内部 访问8080
root@kubernetes-bootcamp-855d5cc575-v22dh:/# curl http://localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-855d5cc575-v22dh | v=1

exit

Expose the APP

Replica set

监控pods的运行状态,确保实际运行的和期望的一致。
observed state vs desired state

ReplicaSet:
Pod 副本管理: ReplicaSet 负责确保在集群中始终运行指定数量的 Pod 副本。它使用 Label Selector 来标识要监控和维护的 Pod。

Self-Healing: 如果实际运行的 Pod 数量和 ReplicaSet 期望的数量不一致,ReplicaSet 会采取措施来修复这个差异。例如,如果有更多的 Pod 实例运行,它可能会终止一些多余的实例。如果缺少实例,它可能会创建新的 Pod 来满足期望的数量。

Service:
服务访问与负载均衡: Service 负责提供一个稳定的入口点,使其他应用程序或服务能够访问一组 Pod。Service 通常与 Label Selector 结合使用,以将请求路由到属于特定组的 Pod。

Traffic Balancing: Service 提供负载均衡功能,以确保请求被分发到属于服务的多个 Pod 实例。这有助于实现高可用性和水平扩展。

关系:
协同工作: ReplicaSet 通常与 Deployment 一起使用,Deployment 提供了对 ReplicaSet 的声明性定义,允许轻松地进行滚动更新和版本控制。Deployment 控制 ReplicaSet 的创建和更新。

Traffic Balancing: Service 与 ReplicaSet 一起使用,Service 可以路由流量到由 ReplicaSet 管理的多个 Pod。这帮助实现服务的可扩展性和高可用性。

Lables (key/value pairs), selectors

  1. A Service is defined using YAML or JSON, which defines a logical set of Pods and a policy by which to access them.
  2. The set of Pods targeted by a Service is usually determined by a label selector.
  3. Services match a set of Pods using labels and selectors.
  4. Lable: 为对象添加的元数据; Selector: 是一种选择机制,根据指定label选择一组对象。

具体流程如下:

**Deployment: **创建一个 Deployment 对象,该对象定义了您要运行的应用程序(app)的副本数量、Pod 模板等信息。Deployment 会确保指定数量的 Pod 副本在集群中运行,并在需要时进行扩展或缩减。

示例 Deployment YAML:

Copy code
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app-image:latest

**Service: **为了使其他应用程序或服务能够访问您的应用程序,您创建一个 Service 对象。Service 为一组符合特定标签条件的 Pod 提供了一个虚拟 IP 地址(Cluster IP),并可以选择通过负载均衡提供公共 IP 地址和端口。

示例 Service YAML:

Copy code
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

通过这样的设置,其他应用程序或服务可以通过 my-app-service 访问您的应用程序,而无需直接关心底层 Pod 的标识。Service 将负责将流量分发到后端运行的多个 Pod,并提供负载均衡的功能,确保应用程序的高可用性和扩展性。

Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a type in the spec of the Service:

ClusterIP (default) - Exposes the Service on an internal IP in the cluster. This type makes the Service only reachable from within the cluster.

NodePort - Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a Service accessible from outside the cluster using <NodeIP>:<NodePort>. Superset of ClusterIP.

LoadBalancer - Creates an external load balancer in the current cloud (if supported) and assigns a fixed, external IP to the Service. Superset of NodePort.

ExternalName - Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up. This type requires v1.7 or higher of kube-dns, or CoreDNS version 0.0.8 or higher.

Create a service

step1: 查看现有pod 和现有service

 kubectl get pods
NAME                                   READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-855d5cc575-v22dh   1/1     Running   0          56m

kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   4d

step 2: expose service

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed

kubectl get services
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            ClusterIP   10.43.0.1       <none>        443/TCP          4d
kubernetes-bootcamp   NodePort    10.43.186.203   <none>        8080:31816/TCP   4s

step 3: 查看 service 详细信息

kubectl describe services/kubernetes-bootcamp
Name:                     kubernetes-bootcamp
Namespace:                default
Labels:                   app=kubernetes-bootcamp
Annotations:              <none>
Selector:                 app=kubernetes-bootcamp
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.43.186.203
IPs:                      10.43.186.203
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  31816/TCP
Endpoints:                10.42.0.22:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

step 4: 查看pod详细信息

 kubectl get pods kubernetes-bootcamp-855d5cc575-v22dh --show-labels
NAME                                   READY   STATUS    RESTARTS   AGE   LABELS
kubernetes-bootcamp-855d5cc575-v22dh   1/1     Running   0          60m   app=kubernetes-bootcamp,pod-template-hash=855d5cc575

kubectl describe pod kubernetes-bootcamp-855d5cc575-v22dh
Name:                 kubernetes-bootcamp-855d5cc575-v22dh
Namespace:            default
Priority:             500000
Priority Class Name:  cmo-medium-priority
Service Account:      default
Node:                 ali1-atlantic-node-3/10.224.35.209
Start Time:           Sun, 21 Jan 2024 22:27:58 -0800
Labels:               app=kubernetes-bootcamp

step 5: 拿到 service所在node的port

export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"

echo "NODE_PORT=$NODE_PORT"

# NODE_PORT=31816

step 6: 访问app, 要用它的node 和 port, 因为type是NodePort,意思是所有node上的这个port都可以访问

export NODE_IP="$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')"

echo $NODE_IP
# 10.224.35.217

curl http://"10.224.35.209:$NODE_PORT"
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-855d5cc575-v22dh | v=1

curl http://"10.224.35.210:$NODE_PORT"
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-855d5cc575-v22dh | v=1

Using labels

  1. 查看 deploy
# 查看 deploy
kubectl describe deployment

Name:                   kubernetes-bootcamp
Namespace:              default
CreationTimestamp:      Sun, 21 Jan 2024 22:27:58 -0800
Labels:                 app=kubernetes-bootcamp
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=kubernetes-bootcamp
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=kubernetes-bootcamp
  Containers:
   kubernetes-bootcamp:
    Image:        gcr.io/google-samples/kubernetes-bootcamp:v1
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   kubernetes-bootcamp-855d5cc575 (1/1 replicas created)
Events:          <none>

  1. 用label来查询相关的pod
# 用label来查询相关的po
kubectl get pods -l app=kubernetes-bootcamp

NAME                                   READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-855d5cc575-v22dh   1/1     Running   0          86m
  1. 用label 来查询相关的service
# 用label 来查询相关的service
kubectl get services -l app=kubernetes-bootcamp

NAME                  TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes-bootcamp   NodePort   10.43.186.203   <none>        8080:31816/TCP   30m
  1. 提取pod name
export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')"
echo "Name of the Pod: $POD_NAME"
# Name of the Pod: kubernetes-bootcamp-855d5cc575-v22dh
  1. 给pod 增加新label
kubectl label pods "$POD_NAME" version=v1
# pod/kubernetes-bootcamp-855d5cc575-v22dh labeled

  1. 查看已经有新label啦
kubectl describe pods "$POD_NAME"
Name:                 kubernetes-bootcamp-855d5cc575-v22dh
Namespace:            default
Priority:             500000
Priority Class Name:  cmo-medium-priority
Service Account:      default
Node:                 ali1-atlantic-node-3/10.224.35.209
Start Time:           Sun, 21 Jan 2024 22:27:58 -0800
Labels:               app=kubernetes-bootcamp
                      pod-template-hash=855d5cc575
                      version=v1
  1. 用新label 来查询相关的service
# 用新label 来查询相关的service
kubectl get pods -l version=v1
NAME                                   READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-855d5cc575-v22dh   1/1     Running   0          90m

# 另一个label也可以
kubectl get services -l app=kubernetes-bootcamp
NAME                  TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes-bootcamp   NodePort   10.43.186.203   <none>        8080:31816/TCP   33m

  1. 用label delete service
kubectl get service
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            ClusterIP   10.43.0.1       <none>        443/TCP          4d1h
kubernetes-bootcamp   NodePort    10.43.186.203   <none>        8080:31816/TCP   35m
kubectl delete service -l app=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted

kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   4d1h

This proves that the application is not reachable anymore from outside of the cluster. You can confirm that the app is still running with a curl from inside the pod:

  1. 再次访问这个service,已经访问不到了
echo $NODE_IP
10.224.35.217
echo $NODE_PORT
31816
curl http://"$NODE_IP:$NODE_PORT"
curl: (7) Failed to connect to 10.224.35.217 port 31816 after 0 ms: Couldn't connect to server
  1. 但是cluster内部还是能访问的:
kubectl exec -ti $POD_NAME -- curl http://localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-855d5cc575-v22dh | v=1

标签:kubectl,Kubernetes,kubernetes,--,app,bootcamp,学习,整理,root
From: https://www.cnblogs.com/vivivi/p/17984761

相关文章

  • Spring学习
    简单Spring代码1、BeanFactory和FactoryBean和BeanDefinitionBeanDefinition是Bean的定义。BeanFactory是Bean容器顶层接口。FactoryBean是用来创建Bean的,实现此接口的getBean方法可以通过此FactoryBean的名字获得Bean,如果想获得他本身则要转移&。2、容器 简单容器接......
  • kafka 学习贴
    为什么要使用Kafka消息队列?解耦、削峰:传统的方式上游发送数据下游需要实时接收,如果上游在某些业务场景:例如上午十点会流量激增至顶峰,那么下游资源可能会扛不住压力。但如果使用消息队列,就可以将消息暂存在消息管道中,下游可以按照自己的速度逐步处理;可扩展:通过横向扩展生产者......
  • SpringCloudAliBaBa Seata学习
    SpringCloudAliBaBa学习服务的注册与发现分布式事务使用场景同一个事务对两个数据库操作,事务肯定是会失效的因为一个事务就是一个数据库连接,不同的连接就是不同的事务Seata是什么?Seata是一款分布式事务解决方案,用AT模式是阿里推荐的事务模式:TCC、SAGA、XA常见分布式事......
  • 信息安全管理与评估整理-ipv6无状态地址自动配置
    无状态地址自动配置实验一1.接口下配置ipv6地址,关闭ra消息抑制,没有建立dhcp地址池只在接口下面将o位置一实验过程截图Wriershark抓包数据前缀信息A,O比特数据交换机配置Pc获取到的地址实验二2.接口下配置ipv6地址,关闭ra消息抑制,接口下未再进行其他配置Wireshark抓......
  • 信息安全管理与评估整理--ipv6有状态自动配置
    Ipv6地址池自动配置有状态以下是关闭ra消息抑制,配置前缀地址池方式,有状态自动配置l不自动获取网关,通过修改网卡—高级设置添加默认网关方式建立本地地址池调用l接口下调用通过wireshark抓包,需要将消息开启才能看到M,O为位比特前缀地址池信息A位与O位含义A比特位:f......
  • 寒假怎么制定学习计划高效?可以给自己制定学习计划的软件
    随着寒冬的降临,寒假也随之而至。对于中小学生和大学生们来说,这是一个放松身心、挖掘兴趣、提升学业的黄金时期。然而,众多学子纷纷表示,寒假在家中往往面临太多诱惑,难以按时完成每天的学习目标。那么如何应对这个问题呢?一款智能的学习计划制定软件或许可以成为解决之道。对于那些......
  • scikit-learn.datasets 机器学习库
    scikit-learn是一个用于Python的机器学习库,提供了大量用于数据挖掘和数据分析的工具。以下是对这些函数和方法的简要描述:clear_data_home:清除数据集目录的内容。dump_svmlight_file:将数据集保存为SVMLight格式的文件。fetch_20newsgroups:下载20个新闻组的文本数据集。f......
  • 云计算学习day2
    第二天学习内容为讲解了Linus系统的分区以及命令的含义以及分别有那些命令首先为分区,linus系统的分区为三部分,分别为:/(根)、/boot、swap:/‘第一个文件夹’想进入到linux系统必须要有根,根分区是最重要的分区/boot存放启动引导文件的swap把硬盘上的一部......
  • 某信息安全研究机构:打造创新人才学习平台,增强企业数字化转型内生安全动力
    某信息安全研究机构是该领域具有重要影响力的研究咨询与决策支撑机构,是保障信息安全的重要机构。该信息安全研究机构聚焦安全主业,加强特色智库建设,为经济高质量发展提供智力支持和决策参考。同时,不断强化信息安全综合保障能力、关键软件产业生态促进能力,加强制度建设和合规管理,提高......
  • # WinDbg学习一(入门)
    前言一直在零零散散的摸索WinDbg知识,但是总是不成体系,所以下定决心整理出来。简介WinDbg是一个调试器,可用于分析故障转储、调试实时用户模式和内核模式代码,以及检查CPU寄存器和内存。那么为什么不用VS呢,一个是VS安装在开发环境上,主要用于源码级调试,生产环境调试比较困难,另外......