容器技術|Docker三劍客之docker-swarm

接以前的文章:node

容器技術|Docker三劍客之docker-machinelinux

容器技術|Docker三劍客之Compose
nginx

docker-swarm簡介

Swarm是Docker官方提供的一款集羣管理工具,其主要做用是把若干臺Docker主機抽象爲一個總體,而且經過一個入口統一管理這些Docker主機上的各類Docker資源。Swarm和Kubernetes比較相似,可是更加輕,具備的功能也較kubernetes更少一些。
swarm集羣提供給用戶管理集羣內全部容器的操做接口與使用一臺Docker主機基本相同。
Swarm集羣目前有兩個版本:V一、V2算法

一、Swarm v1它是master-slave架構。須要經過服務發現來選舉出管理節點,其它各個節點經過運行agent來接受管理節點的統一管理
二、Swarm v2集羣是自動經過Raft協議分佈式選舉出管理節點,不須要配置發現服務,從而避免發現服務的單點故障問題。且它自帶了DNS負載均衡和對外部負載均衡機制的支持docker

Swarm的基本架構以下圖所示

Swarm一些概念說明

  • 一、Swarm
    使用swarmkit嵌入docker Engine中的集羣管理和編排功能。docker容器初始化啓動的一種模式json

  • 二、Node
    節點,是一個已加入到docker swarm集羣中的一個容器實例。vim

  • 三、Service
    服務主要是在工做節點上執行任務,建立服務時,須要指定容器的鏡像。瀏覽器

  • 四、Task
    任務是在容器中執行的命令bash

Swarm 工做方式

  • 一、節點服務器

  • 二、服務、任務、容器

  • 三、任務與調度

  • 四、服務副本與全局服務

Swarm 調度策略

Swarm在scheduler節點(leader 節點)運行容器的時候,會根據指定的策略來計算最適合運行容器的節點,目前支持的策略有:spread, binpack, random.
1)Random
顧名思義,就是隨機選擇一個 Node 來運行容器,通常用做調試用,spread 和 binpack 策略會根據各個節點的可用的 CPU, RAM 以及正在運行的容器的數量來計算應該運行容器的節點。
2)Spread
在同等條件下,Spread 策略會選擇運行容器最少的那臺節點來運行新的容器,binpack 策略會選擇運行容器最集中的那臺機器來運行新的節點。使用 Spread 策略會使得容器會均衡的分佈在集羣中的各個節點上運行,一旦一個節點掛掉了只會損失少部分的容器。
3)Binpack
Binpack 策略最大化的避免容器碎片化,就是說 binpack 策略儘量的把還未使用的節點留給須要更大空間的容器運行,儘量的把容器運行在一個節點上面。

Swarm Cluster模式的特性

1)批量建立服務
創建容器以前先建立一個 overlay 的網絡,用來保證在不一樣主機上的容器網絡互通的網絡模式
2)強大的集羣的容錯性
當容器副本中的其中某一個或某幾個節點宕機後,cluster 會根據本身的服務註冊發現機制,以及以前設定的值–replicas n,在集羣中剩餘的空閒節點上,從新拉起容器副本。整個副本遷移的過程無需人工干預,遷移後本來的集羣的 load balance 依舊好使!
不難看出,docker service 其實不只僅是批量啓動服務這麼簡單,而是在集羣中定義了一種狀態。Cluster 會持續檢測服務的健康狀態並維護集羣的高可用性。
3)服務節點的可擴展性
Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴展或縮減的功能。當容器組想動態擴展時,只需經過 scale參數便可複製出新的副本出來。仔細觀察的話,能夠發現全部擴展出來的容器副本都 run 在原先的節點下面,若是有需求想在每臺節點上都 run 一個相同的副本,方法其實很簡單,只須要在命令中將」–replicas n」更換成」–mode=global」便可!複製服務(–replicas n)將一系列複製任務分發至各節點當中,具體取決於您所須要的設置狀態,例如「–replicas 3」。全局服務(–mode=global)適用於集羣內所有可用節點上的服務任務,例如「–mode global」。若是你們在 Swarm 集羣中設有 7 臺 Docker 節點,則所有節點之上都將存在對應容器。
4)調度機制
所謂的調度其主要功能是 cluster 的 server 端去選擇在哪一個服務器節點上建立並啓動一個容器實例的動做。它是由一個裝箱算法和過濾器組合而成。每次經過過濾器(constraint)啓動容器的時候,swarm cluster 都會調用調度機制篩選出匹配約束條件的服務器,並在這上面運行容器。

Swarm cluster的建立過程

  • 1)發現 Docker 集羣中的各個節點,收集節點狀態、角色信息,並監視節點狀態的變化

  • 2)初始化內部調度(scheduler)模塊

  • 3)建立並啓動 API 監聽服務模塊
    一旦建立好這個 cluster,就能夠用命令 docker service 批量對集羣內的容器進行操做,在啓動容器後,docker 會根據當前每一個 swarm 節點的負載判斷,在負載最優的節點運行這個 task 任務,用」docker service ls」 和」docker service ps + taskID」能夠看到任務運行在哪一個節點上。容器啓動後,有時須要等待一段時間才能完成容器建立。

Swarm命令行說明

docker swarm:集羣管理
init          #初始化集羣
join          #將節點加入集羣
join-token    #管理加入令牌
leave         #從集羣中刪除某個節點,強制刪除加參數--force 
update        #更新集羣
unlock        #解鎖集羣

docker node:節點管理,
demote      #將集羣中一個或多個節點降級
inspect     #顯示一個或多個節點的詳細信息
ls          #列出集羣中的節點
promote     #將一個或多個節點提高爲管理節點
rm          #從集羣中刪除中止的節點,--force強制刪除參數
ps          #列出一個或多個節點上運行的任務
update      #更新節點

docker service:服務管理,
create      #建立一個新的服務
inspect     #列出一個或多個服務的詳細信息
ps          #列出一個或多個服務中的任務信息
ls          #列出服務
rm          #刪除一個或多個服務
scale       #擴展一個或多個服務
update      #更新服務

docker stack/deploy:試驗特性,用於多應用部署
複製代碼

安裝佈署swarm集羣服務

一、修改主機名,配置hosts文件
[root@manager ~]# cat >>/etc/hosts<<EOF
192.168.22.177 manager
192.168.22.175 node1
192.168.22.178 node2
EOF
[root@manager ~]# tail -3 /etc/hosts
192.168.22.177 manager
192.168.22.175 node1
192.168.22.178 node2
[root@manager ~]# ping node1
PING node1 (192.168.22.175) 56(84) bytes of data.
64 bytes from node1 (192.168.22.175): icmp_seq=1 ttl=64 time=3.64 ms
64 bytes from node1 (192.168.22.175): icmp_seq=2 ttl=64 time=1.64 ms
^C
--- node1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1006ms
rtt min/avg/max/mdev = 1.648/2.644/3.641/0.997 ms
[root@manager ~]# ping node2
PING node2 (192.168.22.178) 56(84) bytes of data.
64 bytes from node2 (192.168.22.178): icmp_seq=1 ttl=64 time=9.70 ms
64 bytes from node2 (192.168.22.178): icmp_seq=2 ttl=64 time=1.95 ms
^C
--- node2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 1.951/5.826/9.701/3.875 ms
#node1 node2配置同上一致便可
複製代碼
二、安裝docker環境

具體安裝過程參考前面的文章

配置docker

[root@manager ~]# vim /etc/sysconfig/docker
# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --selinux-enabled --log-driver=journald --signature-verification=false'
#全部節點加上上面標記的部分,開啓2375端口

[root@manager ~]# systemctl restart docker
[root@manager ~]# ps -ef|grep docker
root      11981      1  1 10:55 ?        00:00:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json -H 0.0.0.0:2375 -H unix:///var/run/docker.sock --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2
root      11986  11981  0 10:55 ?        00:00:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root      12076  11823  0 10:55 pts/0    00:00:00 grep --color=auto docker
[root@manager ~]# lsof -i :2375
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
dockerd-c 11981 root    5u  IPv6  41829      0t0  TCP *:2375 (LISTEN)
複製代碼
三、全部節點下載swarm鏡像文件
[root@manager ~]# docker pull swarm
Using default tag: latest
Trying to pull repository docker.io/library/swarm ... 
latest: Pulling from docker.io/library/swarm
d85c18077b82: Pull complete 
1e6bb16f8cb1: Pull complete 
85bac13497d7: Pull complete 
Digest: sha256:406022f04a3d0c5ce4dbdb60422f24052c20ab7e6d41ebe5723aa649c3833975
Status: Downloaded newer image for docker.io/swarm:latest
[root@manager ~]# docker images
REPOSITORY       TAG      IMAGE ID      CREATED      SIZE
docker.io/swarm  latest   ff454b4a0e84  12 days ago  12.7 MB
複製代碼
四、建立swarm並初始化
[root@manager ~]# docker swarm init --advertise-addr 192.168.22.177
Swarm initialized: current node (elyfa6h1lx5o2s98une5vas4x) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya \
    192.168.22.177:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
#執行上面的命令後,當前的服務器就加入到swarm集羣中,同時會產生一個惟一的token值,其它節點加入集羣時須要用到這個token。
#--advertise-addr 表示swarm集羣中其它節點使用後面的IP地址與管理節點通信,上面也提示了其它節點如何加入集羣的命令。
複製代碼
五、查看下當前的信息
[root@manager ~]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 1.13.1
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: journald
Cgroup Driver: systemd
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
**Swarm: active
 NodeID: elyfa6h1lx5o2s98une5vas4x
 Is Manager: true
 ClusterID: vi716cgvw33gzicrfqopasf9p
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
 Node Address: 192.168.22.177
 Manager Addresses:
  192.168.22.177:2377
Runtimes: docker-runc runc
Default Runtime: docker-runc
Init Binary: /usr/libexec/docker/docker-init-current
containerd version:  (expected: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1)
runc version: e9c345b3f906d5dc5e8100b05ce37073a811c74a (expected: 9df8b306d01f59d3a8029be411de015b7304dd8f)
init version: 5b117de7f824f3d3825737cf09581645abbe35d4 (expected: 949e6facb77383876aeff8a6944dde66b3089574)
Security Options:
 seccomp
  WARNING: You're not using the default seccomp profile Profile: /etc/docker/seccomp.json Kernel Version: 3.10.0-693.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 Number of Docker Hooks: 3 CPUs: 1 Total Memory: 2.238 GiB Name: manager ID: 653Y:7CME:GFPW:35SX:IGZL:UJP7:YSPZ:4OMV:J4EV:Z6FS:WFW2:YYHS Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ WARNING: bridge-nf-call-ip6tables is disabled Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Registries: docker.io (secure) [root@manager ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS elyfa6h1lx5o2s98une5vas4x * manager Ready Active Leader #當前節點的信息,這個*表示當前鏈接在這個節點上 複製代碼
六、將node1,node2加入到集羣中
[root@node1 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
This node joined a swarm as a worker.
[root@node2 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
This node joined a swarm as a worker.
#若是加入集羣時報錯以下
[root@node1 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
Error response from daemon: rpc error: code = 13 desc = connection error: desc = "transport: x509: certificate has expired or is not yet valid"
#注意服務器時間同步問題,解決便可。
複製代碼
七、管理節點查看集羣節點狀態
[root@manager ~]# docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x *  manager   Ready   Active        Leader
tcuv2p8wd6rvmwg39pdav5ozk    node1     Ready   Active        
twytwc5dlp77vu1b7cakks9w2    node2     Ready   Active  
#swarm集羣中node的AVAILABILITY狀態有兩種:Active、drain。其中actice狀態的節點能夠接受管理節點的任務指派;drain狀態的節點會結束任務,也不會接受管理節點的任務指派,節點處於下線狀態。

[root@manager ~]# docker node update --availability drain node2
node2
[root@manager ~]# docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x *  manager   Ready   Active        Leader
tcuv2p8wd6rvmwg39pdav5ozk    node1     Ready   Active        
twytwc5dlp77vu1b7cakks9w2    node2     Ready   Drain  
[root@manager ~]# docker node update --availability active node2
node2
[root@manager ~]# docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x *  manager   Ready   Active        Leader
tcuv2p8wd6rvmwg39pdav5ozk    node1     Ready   Active        
twytwc5dlp77vu1b7cakks9w2    node2     Ready   Active 

#在manager節點上查看狀態信息
[root@manager ~]# docker node inspect self
[
    {
        "ID": "elyfa6h1lx5o2s98une5vas4x",
        "Version": {
            "Index": 9
        },
        "CreatedAt": "2018-06-14T15:01:19.850821157Z",
        "UpdatedAt": "2018-06-14T15:01:20.472379584Z",
        "Spec": {
            "Role": "manager",
            "Availability": "active"
        },
        "Description": {
            "Hostname": "manager",
            "Platform": {
                "Architecture": "x86_64",
                "OS": "linux"
            },
            "Resources": {
                "NanoCPUs": 1000000000,
                "MemoryBytes": 2402566144
            },
            "Engine": {
                "EngineVersion": "1.13.1",
                "Plugins": [
                    {
                        "Type": "Network",
                        "Name": "bridge"
                    },
                    {
                        "Type": "Network",
                        "Name": "host"
                    },
                    {
                        "Type": "Network",
                        "Name": "macvlan"
                    },
                    {
                        "Type": "Network",
                        "Name": "null"
                    },
                    {
                        "Type": "Network",
                        "Name": "overlay"
                    },
                    {
                        "Type": "Volume",
                        "Name": "local"
                    }
                ]
            }
        },
        "Status": {
            "State": "ready",
            "Addr": "127.0.0.1"
        },
        "ManagerStatus": {
            "Leader": true,
            "Reachability": "reachable",
            "Addr": "192.168.22.177:2377"
        }
    }
]
複製代碼

Swarm 的Web管理

[root@manager ~]# docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
Unable to find image 'portainer/portainer:latest' locally
Trying to pull repository docker.io/portainer/portainer ... 
latest: Pulling from docker.io/portainer/portainer
d1e017099d17: Pull complete 
0d90a7ef0797: Pull complete 
Digest: sha256:2933caa6e578e94b5d91429ea7f47ae9741ee11b71d7cb740e76c5f234cc1d87
Status: Downloaded newer image for docker.io/portainer/portainer:latest
798b3bea009792321519f5b7144e357ce9c5cea3b9341b5276a4d29f7571684a
[root@manager ~]# docker ps
CONTAINER ID  IMAGE                 COMMAND        CREATED        STATUS        PORTS                    NAMES
798b3bea0097  portainer/portainer   "/portainer"   6 seconds ago  Up 5 seconds  0.0.0.0:9000->9000/tcp   amazing_snyder
複製代碼

瀏覽器訪問

docker-swarm佈署服務

一、佈署服務前建立於個用於集羣內不一樣主機之間容器通訊的網絡
[root@manager ~]# docker network create -d overlay dockernet
pmn1fi6lj421hn1nk7652m41h
[root@manager ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d913c7a275fe        bridge              bridge              local
c737cf269524        docker_gwbridge     bridge              local
pmn1fi6lj421        dockernet           overlay             swarm
eac1d68d35d7        host                host                local
wxshzhdvq52y        ingress             overlay             swarm
c5986aec6119        none                null                local
複製代碼
二、建立服務(nginx爲例)
[root@manager ~]# docker service create --replicas 1 --network dockernet --name nginx-cluster -p 80:80 nginx
k7lupo9xu0cnd5ng1g4f7i7jx
#--replicas 指定副本數量
[root@manager ~]# docker service ls
ID            NAME           MODE        REPLICAS  IMAGE
k7lupo9xu0cn  nginx-cluster  replicated  1/1       nginx:latest
[root@manager ~]# docker service ps nginx-cluster
ID            NAME             IMAGE         NODE     DESIRED STATE  CURRENT STATE           ERROR  PORTS
7t7xjpmao533  nginx-cluster.1  nginx:latest  manager  Running        Running 17 seconds ago         
[root@manager ~]# docker ps
CONTAINER ID   IMAGE                                                                           COMMAND                  CREATED             STATUS              PORTS     NAMES
a9d78079fdc7  nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0   "nginx -g 'daemon ..."   22 seconds ago      Up 22 seconds       80/tcp     nginx-cluster.1.7t7xjpmao5335zaa8wp0c896a
複製代碼
三、在線動態擴容服務
[root@manager ~]# docker service scale nginx-cluster=5
nginx-cluster scaled to 5
[root@manager ~]# docker service ps nginx-cluster
ID            NAME             IMAGE         NODE     DESIRED STATE  CURRENT STATE            ERROR  PORTS
7t7xjpmao533  nginx-cluster.1  nginx:latest  manager  Running        Running 2 hours ago             
vitsgxpdf3bn  nginx-cluster.2  nginx:latest  manager  Running        Running 2 seconds ago           
o9w529mmttsw  nginx-cluster.3  nginx:latest  node1    Running        Preparing 2 seconds ago         
cfz8dkx9p6ih  nginx-cluster.4  nginx:latest  node2    Running        Preparing 2 seconds ago         
9p35iunijoro  nginx-cluster.5  nginx:latest  node2    Running        Preparing 2 seconds ago    
#從輸出結果能夠看出已經將服務動態擴容至5個,也就是5個容器運行着相同的服務
[root@node2 ~]# docker ps
CONTAINER ID   IMAGE                                                                           COMMAND                  CREATED         STATUS        PORTS   NAMES
f3a4fb24480a   nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0   "nginx -g 'daemon ..."   3 minutes ago   Up 3 minutes  80/tcp  nginx-cluster.5.9p35iunijorol1d2ikhyj11oi
f8b0b2e514eb   nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0   "nginx -g 'daemon ..."   3 minutes ago   Up 3 minutes  80/tcp  nginx-cluster.4.cfz8dkx9p6ih40lwwwvd96xdg
#登陸node2查看正在運行的容器,發現與管理節點上顯示的結果相同,node2上運行兩個容器
複製代碼
四、節點故障
[root@manager ~]# docker service ps nginx-cluster
ID            NAME                 IMAGE         NODE     DESIRED STATE  CURRENT STATE           ERROR                             PORTS
7t7xjpmao533  nginx-cluster.1      nginx:latest  manager  Running        Running 2 hours ago                                       
vitsgxpdf3bn  nginx-cluster.2      nginx:latest  manager  Running        Running 10 minutes ago                                    
f13cun1wyxlt  nginx-cluster.3      nginx:latest  manager  Running        Running 9 minutes ago                                     
q60fo5mja1ab   \_ nginx-cluster.3  nginx:latest  node1    Shutdown       Failed 9 minutes ago    "starting container failed: sh…"  
mao4htxp7afr   \_ nginx-cluster.3  nginx:latest  node1    Shutdown       Failed 9 minutes ago    "starting container failed: sh…"  
fhiecco742y4   \_ nginx-cluster.3  nginx:latest  node1    Shutdown       Failed 10 minutes ago   "starting container failed: sh…"  
8qp5kryo62ha   \_ nginx-cluster.3  nginx:latest  node1    Shutdown       Failed 10 minutes ago   "starting container failed: sh…"  
cfz8dkx9p6ih  nginx-cluster.4      nginx:latest  node2    Running        Running 9 minutes ago                                     
9p35iunijoro  nginx-cluster.5      nginx:latest  node2    Running        Running 9 minutes ago  
#若是集羣中節點發生故障,會從swarm集羣中被T除,而後利用自身的負載均衡及調度功能,將服務調度到其它節點上
複製代碼
五、其它經常使用命令介紹

除了上面使用scale來實如今線動態擴容、縮容以外,還可使用update來對服務進行調整

[root@manager ~]# docker service ls
ID            NAME           MODE        REPLICAS  IMAGE
k7lupo9xu0cn  nginx-cluster  replicated  5/5       nginx:latest
[root@manager ~]# docker service update --replicas 2 nginx-cluster
nginx-cluster
[root@manager ~]# docker service ls
ID            NAME           MODE        REPLICAS  IMAGE
k7lupo9xu0cn  nginx-cluster  replicated  2/2       nginx:latest
#將服務縮減到2個

[root@manager ~]# docker service update --image nginx:new nginx-cluster
#更新服務的鏡像版本

[root@manager ~]# docker service --help 

Usage:    docker service COMMAND

Manage services

Options:
      --help   Print usage

Commands:
  create      Create a new service
  inspect     Display detailed information on one or more services
  ls          List services
  ps          List the tasks of a service
  rm          Remove one or more services
  scale       Scale one or multiple replicated services
  update      Update a service

Run 'docker service COMMAND --help' for more information on a command.
[root@manager ~]# docker rm nginx-cluster
#將全部節點上的全部容器所有刪除,任務也將所有刪除複製代碼

相關文章
相關標籤/搜索