Docker 学习

本文详细介绍了Docker的基础知识,包括Docker的安装、镜像和容器的概念及操作,如如何运行容器、创建Dockerfile以及使用volume。通过实例展示了如何构建和运行nginx服务,并探讨了镜像的分层结构和数据持久化的volume操作。此外,还介绍了Docker的常用命令,如docker pull、docker build、docker run和docker ps等。

目录

Docker入门

 docker架构介绍与实战

dockerfile介绍

dockerfile实战

 镜像分层

volume介绍

volume操作


Docker入门

什么是docker:是一个容器,将程序打包隔离,可以粗糙的理解为一个轻量级的虚拟机(的确不是虚拟机 少一个Docker Engine),Docker解决了软件包装的问题。

Docker 镜像(Image)是一个专用的文件系统,你可以将其理解为一个可执行程序,其包含容器运行所需的代码、运行环境、依赖库、环境变量和配置文件等该程序启动和运行所必须的资源。Docker 容器(Container)是镜像(Image)运行(docker run)时产生的实例,容器可以被创建、启动、停止、暂停、删除等。而 Docker 就是一个容器引擎,管理着众多的容器。

 

mac安装docker:进入docker.com官网、点击 Get Started

linux安装docker:

sudo wget -qO- https://get.docker.com | sh
sudo usermod -aG docker xbf

 docker架构介绍与实战

Client 通过命令向 docker_host 中的 Docker deamon 发起指令,Docker deamon 会操作镜像,Registry是互联网的SaaS服务 可以托取、push Images,可以使所有docker用户共享镜像的服务。

// 输入一条指令 用Ubuntu的Images输出 hello docker
GoogoldeMacBook-Pro:/ googol$ docker run ubuntu echo hello docker
hello docker

// 查看本地所有images
GoogoldeMacBook-Pro:/ googol$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              f643c72bc252        12 days ago         72.9MB
ubuntu              15.10               9b9cb95443b5        4 years ago         137MB

// 查看当前正在运行的images
GoogoldeMacBook-Pro:/ googol$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

// 查看所有的images
GoogoldeMacBook-Pro:/ googol$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

// 输入一条指令 运行nginx服务
GoogoldeMacBook-Pro:/ googol$ docker run -p 8080:80 -d daocloud.io/nginx
Unable to find image 'daocloud.io/nginx:latest' locally
latest: Pulling from nginx
bf5952930446: Pull complete 
cb9a6de05e5a: Pull complete 
9513ea0afb93: Pull complete 
b49ea07d2e93: Pull complete 
a5e4a503d449: Pull complete 
Digest: sha256:179412c42fe3336e7cdc253ad4a2e03d32f50e3037a860cf5edbeb1aaddb915c
Status: Downloaded newer image for daocloud.io/nginx:latest
a8d6b8c489fd2d6b2e9be03f049e319df6f0859cc1e1283050ec864c7315b2e4

// 浏览器访问  http://localhost:8080 即可看到运行的nginx

// 替换nginx的访问页面
GoogoldeMacBook-Pro:Desktop googol$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
a8d6b8c489fd        daocloud.io/nginx   "/docker-entrypoint.…"   6 minutes ago       Up 6 minutes        0.0.0.0:8080->80/tcp   trusting_black
GoogoldeMacBook-Pro:Desktop googol$ docker cp test.html a8d6b8c489fd://usr/share/nginx/html

// 停止docker的nginx服务
GoogoldeMacBook-Pro:Desktop googol$ docker stop a8d6b8c489fd
a8d6b8c489fd

 

 

注意:Docker在容器内所做的改动都是暂时的是没有被保存的操作,需要在改动之后输入 ↓↓↓

// 保存docker的改动
GoogoldeMacBook-Pro:/ googol$ docker commit -m '提交的信息' image的id 标签名称
会产生一个新的image

// 删除docker的image
GoogoldeMacBook-Pro:/ googol$ docker rmi image的id
(remove image)
命令小结
docker pull             获取image
docker build            创建image
docker images           列出image
docker run              运行container
docker ps               列出container

dockerfile介绍

FROM 地址(alpine是针对docker做的一个极小的linux环境)、MAINTAINER维护者、CMD

// 创建 dockerfile
GoogoldeMacBook-Pro:Desktop googol$ mkdir d1

// 进入 d1 文件夹
GoogoldeMacBook-Pro:Desktop googol$ cd d1/

// 编辑文件 Dockerfile
GoogoldeMacBook-Pro:d1 googol$ vim Dockerfile 

FROM alpine:latest
MAINTAINER jartins
CMD echo "hello docker"

// 创建images  -t  为标签, . 为当前目录下的所有文件
GoogoldeMacBook-Pro:d1 googol$ docker build -t hello_docker .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine:latest
latest: Pulling from library/alpine
188c0c94c7c5: Downloading 
latest: Pulling from library/alpine
188c0c94c7c5: Pull complete 
Digest: sha256:c0e9560cda118f9ec63ddefb4a173a2b2a0347082d7dff7dc14272e7841a5b5a
Status: Downloaded newer image for alpine:latest
 ---> d6e46aa2470d
Step 2/3 : MAINTAINER jartins
 ---> Running in d4184ea4f9c1
Removing intermediate container d4184ea4f9c1
 ---> feb63ea345e9
Step 3/3 : CMD echo "hello docker"
 ---> Running in 72985be2da4d
Removing intermediate container 72985be2da4d
 ---> 8be1c4ff0d13
Successfully built 8be1c4ff0d13
Successfully tagged hello_docker:latest

// 查看创建的images  docker images images的标签
GoogoldeMacBook-Pro:d1 googol$ docker images hello_docker
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello_docker        latest              8be1c4ff0d13        2 minutes ago       5.57MB

// 运行创建的images
GoogoldeMacBook-Pro:d1 googol$ docker run hello_docker
hello docker

dockerfile实战

// 创建 Dockerfile2 文件夹
GoogoldeMacBook-Pro:Desktop googol$ mkdir Dockerfile2

// 进入文件
GoogoldeMacBook-Pro:Desktop googol$ cd Dockerfile2

// 编辑 Dockerfile
GoogoldeMacBook-Pro:d2 googol$ vi Dockerfile
FROM ubuntu
MAINTAINER jartin
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y nginx
COPY index.html /var/www/html
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
EXPOSE 81

/**
* FROM                               images源
* MAINTAINER                         维护者
* RUN                                执行命令
* COPY                               复制 (在这里是将默认的页面改为index.html的内容)
* ENTRYPOINT                         作为容器运行的命令存在的
* EXPOSE                             端口
*/

// 当前目录级创建 index.html 并写入内容
This is HTML

// 运行Dockerfile
GoogoldeMacBook-Pro:d2 googol$ docker build -t jartins/hello-nginx .
Sending build context to Docker daemon  3.072kB
Step 1/8 : FROM ubuntu
 ---> f643c72bc252
Step 2/8 : MAINTAINER jartin
 ---> Using cache
 ---> 52411b06d15c
Step 3/8 : RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
 ---> Using cache
 ---> 759124ddb603
Step 4/8 : RUN apt-get update
 ---> Using cache
 ---> b030eb7cc47b
Step 5/8 : RUN apt-get install -y nginx
 ---> Using cache
 ---> 49b3e4fec072
Step 6/8 : COPY index.html /var/www/html
 ---> Using cache
 ---> 7f1a525db3c1
Step 7/8 : ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
 ---> Using cache
 ---> 4c3c17d90637
Step 8/8 : EXPOSE 81
 ---> Using cache
 ---> fc5e3ff65a08
Successfully built fc5e3ff65a08
Successfully tagged jartins/hello-nginx:latest

// 运行容器
GoogoldeMacBook-Pro:d2 googol$ docker run -d -p 8080:80 jartins/hello-nginx
42b6dae306eac055dc52ec83da3c587727d4969870e5e69fb3ae9c01cecaccd5

// 访问结果
GoogoldeMacBook-Pro:d2 googol$ curl http://localhost:8080
This is HTML

备注:from 指定基础镜像、run执行命令、add添加文件、copy拷贝文件、cmd执行命令、expose暴露端口。    add 会比 copy更加强大一点,copy可以拷贝文件或目录,add可将远程的文件加入到容器内。

备注:entrypoint和cmd相似 都是设定容器入口,但是两者又不一样,就是在没有指定entrypoint的情况下,就用cmd来启动,如果有Entrypoint cmd所指令的字符传就变成了entrypoint后面的一些argement(论据参数)。

           user执行该命令的用户,通常我们不会用root在容器里面去执行

           volume是指容器内所挂载的卷

 

 镜像分层

 

volume介绍

容器中所作的操作是不会被保存的,而volume可以使数据在容器中共享。

volume操作

执行一个nginx 挂载一个卷 (第一种形式的数据渲染:通过直接修改挂载资源结果达到修改的目的)

// 执行一个nginx挂载一个卷
GoogoldeMacBook-Pro:d2 googol$ docker run -d --name nginx -v /usr/share/nginx/html nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
852e50cd189d: Pull complete 
571d7e852307: Pull complete 
addb10abd9cb: Pull complete 
d20aa7ccdb77: Pull complete 
8b03f1e11359: Pull complete 
Digest: sha256:6b1daa9462046581ac15be20277a7c75476283f969cb3a61c8725ec38d3b01c3
Status: Downloaded newer image for nginx:latest
beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615

// 检查镜像nginx的信息
GoogoldeMacBook-Pro:d2 googol$ docker inspect nginx
[
    {
        "Id": "beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615",
        "Created": "2020-12-09T09:37:58.1506512Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 4454,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-12-09T09:37:59.4087403Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:bc9a0695f5712dcaaa09a5adc415a3936ccba13fc2587dfd76b1b8aeea3f221c",
        "ResolvConfPath": "/var/lib/docker/containers/beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615/hostname",
        "HostsPath": "/var/lib/docker/containers/beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615/hosts",
        "LogPath": "/var/lib/docker/containers/beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615/beb68914b8d5a6498ca9fc606c632ba77fb46d07d2c16cdf8ed90a203a4dd615-json.log",
        "Name": "/nginx",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/c757f3fee8f5970c34d9d05538bfd149d13a46aca5dba1eea856160faf74cfe9-init/diff:/var/lib/docker/overlay2/50aba5679e3ed4a8f3f2dc2fb9c87301955d40d1fbe937d1779d8ffc5bef44c5/diff:/var/lib/docker/overlay2/705ebe3c82981b33619a9399bb947d7015fb37841fa05588d80203617349fcce/diff:/var/lib/docker/overlay2/9ae3e04c9c5a6c7f49b5d17d069f2d663cace7085723d5b3087f04abaa5676b9/diff:/var/lib/docker/overlay2/69dc7cd392944a84b06c70c8a57a0df1920483522bee5136718a1ae8399d0121/diff:/var/lib/docker/overlay2/4d293c111d910084d29cccb5f9ab26cdfd7096a11fdd44a384f4c1bc7446ba7d/diff",
                "MergedDir": "/var/lib/docker/overlay2/c757f3fee8f5970c34d9d05538bfd149d13a46aca5dba1eea856160faf74cfe9/merged",
                "UpperDir": "/var/lib/docker/overlay2/c757f3fee8f5970c34d9d05538bfd149d13a46aca5dba1eea856160faf74cfe9/diff",
                "WorkDir": "/var/lib/docker/overlay2/c757f3fee8f5970c34d9d05538bfd149d13a46aca5dba1eea856160faf74cfe9/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [ 《============================================== 需要注意此处(挂载信息)
            {
                "Type": "volume",
                "Name": "6ad32dc1d24f7a6bf7b43bf4745d838d39bca8f7e121a327c7b94566142262a6",
                "Source": "/var/lib/docker/volumes/6ad32dc1d24f7a6bf7b43bf4745d838d39bca8f7e121a327c7b94566142262a6/_data",// 宿主机中的容器路径挂载到了Destination 修改Source即可
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "beb68914b8d5",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.19.5",
                "NJS_VERSION=0.4.4",
                "PKG_RELEASE=1~buster"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "nginx",
            "Volumes": {
                "/usr/share/nginx/html": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e"
            },
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "1670c2b9bba0ce99785b6d1e28bf6435c83a02b9cb1396156cc5572ee0137a3d",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/1670c2b9bba0",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "93103d9a086f7e31d6be8640b542906e22ef9d1d84ef5e7e6104ab7d7b38e972",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "76506799dce418fb85b1874b788c9be03ca081fc4928fbec640a722dbdcc1478",
                    "EndpointID": "93103d9a086f7e31d6be8640b542906e22ef9d1d84ef5e7e6104ab7d7b38e972",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

 

执行一个nginx 挂载一个卷 (第二种形式的数据渲染: 本地的目录挂载到容器的数据渲染)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<think>嗯,用户想了解Docker学习路径。首先我得理清楚Docker的基础知识,然后分步骤来规划。可能用户是刚开始接触容器技术,需要从最基础的概念讲起。 首先应该介绍Docker是什么,为什么需要它。然后安装和环境配置,这部分可能需要涵盖不同操作系统的安装步骤,比如Windows、macOS和Linux。接着是基本命令,像镜像和容器的管理,这部分比较实用,用户可能需要实际操作例子。 接下来是Dockerfile和镜像构建,这是关键部分,用户需要学会如何自定义镜像。之后是数据管理和网络配置,这些在实际项目中很重要,比如卷的使用和容器间通信。然后是Docker Compose,处理多容器应用,用户可能会用到这个来部署复杂应用。 高级部分可能需要包括Docker Swarm和Kubernetes的基础,但用户可能暂时不需要太深入,可以简要提一下。最后是安全性和最佳实践,确保用户了解如何安全地使用Docker。 还要考虑用户可能的应用场景,比如开发、测试或者生产环境部署。可能需要推荐一些实践项目,比如搭建Web应用,帮助用户巩固知识。另外,学习资源方面,官方文档和社区资源很重要,可以推荐一些书籍或者在线课程。 需要检查是否有遗漏的部分,比如是否提到监控和日志管理,或者与其他工具集成,比如CI/CD。不过作为学习路径,可能先集中在核心内容,高级话题可以后续扩展。 最后,确保结构清晰,步骤由浅入深,让用户能够循序渐进地学习。避免使用过于专业的术语,保持解释的易懂性。同时,注意使用正确的Markdown格式,特别是数学公式部分,不过在这个问题中可能用不上,但需要遵守系统指令中的格式要求。</think>以下是分阶段Docker学习路径(建议配合实践操作): 一、基础入门阶段(1-2周) 1. 核心概念理解 - 容器与虚拟机的本质区别(资源隔离 vs 硬件虚拟化) - 镜像分层存储原理(联合文件系统) - 容器生命周期管理(创建→运行→停止→销毁) 2. 环境搭建 ```bash # Linux安装示例 curl -fsSL https://get.docker.com | bash -s docker sudo systemctl enable --now docker ``` 3. 基础指令实践 ```bash docker run -d -p 80:80 --name web nginx:alpine # 启动Nginx容器 docker exec -it web sh # 进入容器shell docker logs --tail 50 web # 查看日志 ``` 二、进阶应用阶段(2-4周) 1. Dockerfile编写技巧 ```dockerfile FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"] ``` 2. 数据持久化方案 ```bash docker volume create db-data docker run -d -v db-data:/var/lib/mysql mysql:8.0 ``` 3. 网络配置实践 ```bash docker network create app-net docker run -d --net=app-net --name db redis:6 docker run -d --net=app-net -p 8080:80 webapp ``` 三、生产级部署阶段(1-2个月) 1. Docker Compose编排 ```yaml version: '3.8' services: web: build: . ports: - "5000:5000" depends_on: - redis redis: image: "redis:alpine" ``` 2. 镜像优化策略 - 多阶段构建(减少最终镜像体积) - 安全扫描(使用docker scan) - 镜像签名验证 3. 容器监控方案 ```bash docker stats # 实时资源监控 docker run -d -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer ``` 四、持续学习建议 1. 官方文档精读(https://docs.docker.com) 2. 实验平台练习(推荐Play with Docker) 3. 参与社区项目(Docker GitHub仓库issue区) 4. 云原生技术延伸(Kubernetes、Service Mesh) 重点实践项目建议: 1. 构建完整LNMP环境 2. 实现CI/CD流水线 3. 搭建微服务架构演示系统 4. 容器安全加固实验 避坑指南: - 避免使用latest标签 - 容器内不要存储重要数据 - 生产环境限制容器资源配额 - 定期更新基础镜像版本 学习资源推荐: - 《Docker——容器与容器云(第2版)》 - 极客时间《深入剖析Kubernetes》(前4章) - Docker官方认证课程(DCA) - Katacoda交互式学习平台 建议每天保持1小时实践时间,通过实际项目巩固知识体系。遇到问题时,善用docker inspect命令分析容器状态,多查阅Docker官方文档的CLI参考手册。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值