Kubernetes 系列第二篇: 使用 kubectl 命令创建 Kubernetes 应用

1. 简介

k8s 的 API Server 提供了 RESTful 风格的网关接口, 允许用户通过这个接口向 k8s 集群发起请求。如创建一个 Pod 或销毁一个 Pod 等操作
用户可以通过编程语言遵循 API Server 提供的网关接口规范和 API Server 进行通信, 也可以通过 k8s 自带的 kubectl 命令和 API Server 进行通信, 或者通过由 Dashboard 提供的 Web UI 和 API Server 进行通信
其中 kubectl 是官方提供的用于和 API Server 通信的 CLI 工具, 且是最为常用的交互式命令行工具

2. kubectl

2.1. 查看命令帮助

# 查看 kubectl 命令帮助
[[email protected] ~]# kubectl --help
# 基础命令(适合初学者使用)
Basic Commands (Beginner):
  create         创建资源, k8s 支持从 yaml 文件或者命令行参数直接创建资源
  expose         暴露服务
  run            运行 Pod
  set            设置对象属性

# 基础命令
Basic Commands (Intermediate):
  explain
  get            获取资源信息
  edit           编辑资源
  delete         删除资源

# 部署命令
Deploy Commands:
  rollout        更新管理
  scale          手动管理副本
  autoscale      自动管理副本

# 集群管理命令
Cluster Management Commands:
  certificate    证书管理
  cluster-info   查看集群信息
  top            显示资源(CPU/内存/存储)使用情况
  cordon         将指定 node 设定为"不可用"(unschedulable)状态
  uncordon       将指定 node 设定为"可用"(schedulable)状态
  drain          排空节点
  taint          为 node 声明污点及标准行为

# 故障排除和调试命令
Troubleshooting and Debugging Commands:
  describe       显示特定资源或资源组的详细信息
  logs           打印 Pod 中的容器日志
  attach         连接到正在运行的容器
  exec           在容器中执行命令
  port-forward   将一个或多个本地端口转发到 Pod 中
  proxy          运行 k8s API Server 代理
  cp             跨容器之间复制文件或目录
  auth           检查授权

# 高级命令
Advanced Commands:
  apply          基于文件或 stdin 将配置应用于资源
  patch          使用策略合并补丁更新资源字段
  replace        基于文件或 stdin 替换一个资源
  wait           目前处于测试阶段, 在一个或多个资源上等待一个条件
  convert        为不同的 API 版本转换配置文件

# 资源设置
Settings Commands:
  label          更新资源上的标签(label)
  annotate       更新资源的a nnotation
  completion     输出指定的 shell 的补全码

# 其他命令
Other Commands:
  alpha          Commands for features in alpha
  api-resources  在服务器上打印支持的 API 资源
  api-versions   以 "group/version" 格式打印服务器支持的 API 版本信息
  config         修改 kubeconfig 文件
  plugin         运行命令行插件
  version        查看 k8s 版本

# 使用格式
Usage:
  kubectl [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

2.2. 使用 kubectl 运行一个 Pod

# 运行一个由 deployment 管理器管理的 pod
[[email protected] ~]# kubectl run nginx --image=nginx:1.14-alpine --replicas=5
deployment.apps/nginx created

# 查看 pod
[[email protected] ~]# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP           NODE
nginx-65759d8bcb-96kgd   1/1       Running   0          7s       10.244.3.6   node02
nginx-65759d8bcb-97dch   1/1       Running   0          7s       10.244.1.5   node01
nginx-65759d8bcb-mzzwh   1/1       Running   0          8s       10.244.1.4   node01
nginx-65759d8bcb-vxs74   1/1       Running   0          8s       10.244.3.5   node02
nginx-65759d8bcb-z6d4r   1/1       Running   0          8s       10.244.3.4   node02

NAME        Pod 名称
READY       这个 Pod 内应该运行几个容器/已经准备好几个容器
STATUS      运行状态
RESTARTS    Pod 重启次数
AGE         已存在多长时间, 单位秒(s)
IP          Pod IP(这个地址只能在集群内部使用, 且 Pod IP 随时都会发生改变)
NODE        运行节点

# 查看 deployment 管理器
[[email protected] ~]# kubectl get deployment
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     5         5         5            5           18s

NAME            deployment 管理器名称
DESIRED         期望有多少个副本
CURRENT         当前有多少个副本
UP-TO-DATE      处于最新状态的 Pod 数量
AVAILABLE       活跃的 Pod 数量
AGE             已存在多长时间, 单位秒(s)

# 在集群内部访问 Pod
[[email protected] ~]# curl 10.244.1.5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.3. 使用 service 暴露服务

Pod 的客户端主要分为两类, 集群外客户端集群内客户端。集群内客户可以直接通过 Pod IP 访问 Pod 而集群外部客户端则不能通过 Pod IP 访问, 且 Pod IP 随时有可能会发生改变所有即便只是在集群内部访问我们也不应该直接使用 Pod IP 进行访问
而 service 主要就是为了解决这两个问题而存在的, 通过创建 service 给与 service 一个固定的访问接口并且将相关的 Pod 绑定到这个 service 中, 当访问 service 是自动将客户端浏览分发到后端的 Pod 中
如果 k8s 安装了 CoreDNS 则可以通过 CoreDNS 为所有 Pod 都分配一个 DNS, 如果 service 发生改变 CoreDNS 也会更新其内部的解析记录, 以保证 DNS 解析记录的有效性

# 创建 service
[[email protected] ~]# kubectl expose deployment nginx --name=nginx-service --port=80 --target-port=80 --protocol=TCP --type=ClusterIP
service/nginx-service exposed

kubectl expose          创建 service 关键字
deployment nginx        绑定的 Pod 管理器(将会暴露此 Pod 管理器所管理的所有 Pod)
--name                  指定 service 的名称
--port                  暴露的端口
--target-port           目标端口
--protocol              暴露的协议(默认为 TCP)
--type                  service 类型, ClusterIP 为集群 IP, 此类型的 service 在集群外部也不能被访问

# 查看已存在的 service
[[email protected] ~]# kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   6d
nginx-service   ClusterIP   10.107.73.166   <none>        80/TCP    33s

# 查看 service 的详细信息
[[email protected] ~]# kubectl describe service nginx-service
Name:              nginx-service
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
# 关联标签 run 且 run 为 nginx 的所有 pod(通过此项完成 pod 和 service 的绑定)
Selector:          run=nginx
Type:              ClusterIP
IP:                10.107.73.166
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.1.5:80,10.244.3.4:80 + 2 more...
Session Affinity:  None
Events:            <none>

# 显示各 pod 的 label
[[email protected] ~]# kubectl get pod --show-labels
NAME                     READY     STATUS    RESTARTS   AGE       LABELS
client                   1/1       Running   0          54m       run=client
nginx-65759d8bcb-96kgd   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-97dch   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-mzzwh   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-vxs74   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx
nginx-65759d8bcb-z6d4r   1/1       Running   0          5h        pod-template-hash=2131584676,run=nginx

# 使用 service ip 访问 Pod
[[email protected] ~]# curl 10.107.73.166
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.4. 使用 DNS 名称访问 Pod

# 查看 kube-dns(真实使用的为 CoreDNS) 的 service 地址
[[email protected] ~]# kubectl get service -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP   7d

[[email protected] ~]# kubectl get service
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   7d
nginx-service   ClusterIP   10.107.73.166   <none>        80/TCP    46m

# 使用 CoreDNS 解析主机名, nginx-service 为 service 名称, default.svc.cluster.local 为 DNS 后缀
[[email protected] ~]# dig -t A nginx-service.default.svc.cluster.local @10.96.0.10
......
# 解析结果
nginx-service.default.svc.cluster.local. 5 IN A 10.107.73.166

;; Query time: 7 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Thu Feb 28 16:36:29 CST 2019
;; MSG SIZE  rcvd: 123

# 建立一个客户端 Pod
[[email protected] ~]# kubectl run client --image=busybox -it --restart=Never

# 在 Pod 内部使用 service 名称访问
/ # wget -O - -q nginx-service
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

2.5. 动态修改 pod 副本数量

# 将副本数量修改为 2
[[email protected] ~]# kubectl scale --replicas=2 deployment nginx
deployment.extensions/nginx scaled

# 查看 nginx 控制器的详细信息
[[email protected] ~]# kubectl describe deployment nginx
Name:                   nginx
Namespace:              default
CreationTimestamp:      Thu, 28 Feb 2019 12:05:59 +0800
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision=1
Selector:               run=nginx
# 副本详细信息
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-65759d8bcb (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  1m    deployment-controller  Scaled down replica set nginx-65759d8bcb to 2

2.6. 更新

# 查看当前 Pod 的详细信息
[[email protected] ~]# kubectl describe pod nginx-65759d8bcb-97dch
Name:               nginx-65759d8bcb-97dch
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node01/192.168.1.51
Start Time:         Thu, 28 Feb 2019 12:06:00 +0800
Labels:             pod-template-hash=2131584676
                    run=nginx
Annotations:        <none>
Status:             Running
IP:                 10.244.1.5
Controlled By:      ReplicaSet/nginx-65759d8bcb
# pod 内运行的容器
Containers:
  # 容器名称
  nginx:
    Container ID:   docker://2a97be8c74ac715569b4cbd542cb1df0b52f49cd1ee89f1d7bdf15464678d274
    # 容器镜像
    Image:          nginx:1.14-alpine
    Image ID:       docker-pullable://[email protected]:b96aeeb1687703c49096f4969358d44f8520b671da94848309a3ba5be5b4c632
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 28 Feb 2019 12:06:01 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-t9pnn (ro)
# pod 内运行的第二个容器, 这儿只有一个容器
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-t9pnn:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-t9pnn
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>

# 更新镜像版本
[[email protected] ~]# kubectl set image deployment nginx nginx=nginx:alpine
deployment.extensions/nginx image updated

kubectl set image       更新进行关键字
deployment nginx        nginx deployment 控制器
nginx                   pod 内的容器名称(更新时只能指定更新容器)
nginx:alpine            镜像版本

# 查看更新过程
[[email protected] ~]# kubectl rollout status deployment nginx
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out

# 查看更新完成后的 pod
[[email protected] ~]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
client                   1/1       Running   0          1h
nginx-5557945897-87st5   1/1       Running   0          1m
nginx-5557945897-zgggq   1/1       Running   0          1m

# 查看 pod 详细信息
[[email protected] ~]# kubectl describe pod nginx-5557945897-87st5
Name:               nginx-5557945897-87st5
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node02/192.168.1.52
Start Time:         Thu, 28 Feb 2019 17:52:21 +0800
Labels:             pod-template-hash=1113501453
                    run=nginx
Annotations:        <none>
Status:             Running
IP:                 10.244.3.8
Controlled By:      ReplicaSet/nginx-5557945897
Containers:
  nginx:
    Container ID:   docker://fcb8166d53a6c2c6392bc14f80cd9161caf13e3e26cad433ed0d9da133b41c6b
    Image:          nginx:alpine
    Image ID:       docker-pullable://[email protected]:0f7920c93d6b60f3e13c1b847f1863f423c3149d06e53475e64560933d168adc
    ......

2.7. 回滚

# 回滚到指定版本, 默认回滚到上一个版本
[[email protected] ~]# kubectl rollout undo deployment nginx
deployment.extensions/nginx

kubectl rollout undo    关键字
deployment nginx        控制器
--to-revision           指定回滚到那个版本

[[email protected] ~]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
client                   1/1       Running   0          1h
nginx-65759d8bcb-gm4sj   1/1       Running   0          1m
nginx-65759d8bcb-n2222   1/1       Running   0          1m

# 查看回滚后的 pod 信息
[[email protected] ~]# kubectl describe deployment nginx nginx-65759d8bcb-gm4sj
Name:                   nginx
Namespace:              default
CreationTimestamp:      Thu, 28 Feb 2019 12:05:59 +0800
Labels:                 run=nginx
Annotations:            deployment.kubernetes.io/revision=5
Selector:               run=nginx
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>

2.8. 将服务发布到集群外部

# 新创建一个 service, service 的 NodePort 模式允许外部流量访问 k8s 集群
[[email protected] ~]# kubectl expose deployment nginx --name=nginx-service-internet --port=80 --type=NodePort
service/nginx-service-internet exposed

# 在外部访问 k8s 任意节点的 32081 即可访问 nginx pod
[[email protected] ~]# kubectl get service
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP        7d
nginx-service            ClusterIP   10.107.73.166    <none>        80/TCP         18h
nginx-service-internet   NodePort    10.107.217.105   <none>        80:32081/TCP   11s

# 或者修改现有 service 的 type 将其发布到集群外部
[[email protected] ~]# kubectl edit service nginx-service
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2019-02-28T07:50:21Z
  labels:
    run: nginx
  name: nginx-service
  namespace: default
  resourceVersion: "474911"
  selfLink: /api/v1/namespaces/default/services/nginx-service
  uid: 7f7ef303-3b2d-11e9-9b82-000c292a04ff
spec:
  clusterIP: 10.107.73.166
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31987
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  sessionAffinity: None
  # 修改为 NodePort
  type: NodePort
status:
  loadBalancer: {}

# 现在访问任意节点的 31987 和 32081 都能够访问到后端 pod 资源
[[email protected] ~]# kubectl get service
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP        7d
nginx-service            NodePort    10.107.73.166    <none>        80:31987/TCP   18h
nginx-service-internet   NodePort    10.107.217.105   <none>        80:32081/TCP   3m

原文地址:https://blog.51cto.com/hongchen99/2440338

时间: 2024-10-08 11:22:21

Kubernetes 系列第二篇: 使用 kubectl 命令创建 Kubernetes 应用的相关文章

Kubernetes 系列第二篇: Kubernetes 架构设计和部署

1. 架构设计和环境设计 1.1. 架构设计 部署 Haproxy 为 Kubernetes 提供 Endpoint 访问入口 使用 Keepalived 将 Endpoint 入口地址设置为 Virtual IP 并通过部署多台节点的方式实现冗余 使用 kubeadm 部署高可用 Kubernetes 集群, 指定 Endpoint IP 为 Keepalived 生成的 Virtual IP 使用 prometheus 作为 Kubernetes 的集群监控系统, 使用 grafana 作为

【Windows编程】系列第二篇:Windows SDK创建基本控件

在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际上MFC的下层也是通过这些API完成的. 实际上控件也是窗口,只不过是被微软预先创建好的一种窗口类,比如button就是一个类名为“BUTTON”的类.既然控件实际上是窗口,当然也是用CreateWindow或者CreateWindowEx这个函数来完成的,第二个函数除了多一个扩展风格之外,其他完全

ansible系列第二篇(模块使用)

ansible系列第二篇(模块使用) 模块使用 设置ansible提权 在hosts文件加入sudo提权的密码: 18.18.23.102 ansible_become_pass='passwd' 执行: ansible test -S -R root -m shell -a "ls -l /" 查看ansible有那些模块: ansible-doc -l 获取各个模块详细帮助信息 ansible-doc -s ping ping模块: ansible test -m ping 从受控

深入理解javascript作用域系列第二篇——词法作用域和动态作用域

× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作模型导致的,作用域分为词法作用域和动态作用域,分清这两种作用域模型就能够对变量查找过程有清晰的认识.本文是深入理解javascript作用域系列第二篇——词法作用域和动态作用域 词法作用域 第一篇介绍过,编译器的第一个工作阶段叫作分词,就是把由字符组成的字符串分解成

EnjoyingSoft之Mule ESB基础系列第二篇:Mule ESB基本概念

目录 1. 使用Anypoint Studio开发 2. Mule ESB Application Structure - Mule ESB应用程序结构 3. Mule ESB Application整体构造 4. Mule ESB构造元素 - Flow 5. Mule ESB构造元素 - Connector 6. Mule ESB构造元素 - Processor Mule ESB在众多开源的ESB中处于领先者的地位,MuleSoft公司也作为独角兽,2017年在纽交所上市.我们作为MuleSo

chromium浏览器开发系列第二篇:如何编译最新chromium源码

说一下为什么这么晚才发第二篇,上周和这周department的工作太多了,晚上都是十点半从公司出发,回家以后实在没有多余的精力去摸键盘了.所以请大家包涵! 上期回顾: chromium源码下载: 1.找个靠谱的vpn(我试过了,网上说的不用vpn拿代码的都不靠谱): 2.获取depot_tools,解压,设置环境变量; 3.gclient获取python和git,svn,设置环境变量: 4.fetch–nohooks chromium –nosvn=true 获取源码: 5.gclientsyn

chromium浏览器开发系列第二篇:如何编译最新chromium

说一下为什么这么晚才发第二篇,上周和这周department的工作太多了,晚上都是十点半从公司出发,回家以后实在没有多余的精力去摸键盘了.所以请大家包涵! 上期回顾: chromium源码下载: 1.找个靠谱的vpn(我试过了,网上说的不用vpn拿代码的都不靠谱): 2.获取depot_tools,解压,设置环境变量; 3.gclient获取python和git,svn,设置环境变量: 4.fetch–nohooks chromium –nosvn=true 获取源码: 5.gclientsyn

chromium浏览器高级开发系列第二篇:如何编译最新chromium源码

说一下为什么这么晚才发第二篇,上周和这周department的工作太多了,晚上都是十点半从公司出发,回家以后实在没有多余的精力去摸键盘了.所以请大家包涵! 上期回顾: chromium源码下载: 找个靠谱的vpn(我试过了,网上说的不用vpn拿代码的都不靠谱): 获取depot_tools,解压,设置环境变量; gclient获取python和git,svn,设置环境变量: fetch–nohooks chromium –nosvn=true 获取源码: gclientsync --force

浏览器开发系列第二篇:如何编译最新chromium源码

说一下为什么这么晚才发第二篇,上周和这周department的工作太多了,晚上都是十点半从公司出发,回家以后实在没有多余的精力去摸键盘了.所以请大家包涵! 上期回顾: chromium源码下载: 找个靠谱的vpn(我试过了,网上说的不用vpn拿代码的都不靠谱): 获取depot_tools,解压,设置环境变量; gclient获取python和git,svn,设置环境变量: fetch–nohooks chromium –nosvn=true 获取源码: gclientsync --force