zoukankan      html  css  js  c++  java
  • Docker Compose、Swarm 集群管理

      docker-machime和compose、swarm被称为docker三剑客。docker-machine是解决docker运行环境问题,之前已经研究过,下面研究compose和swarm。

    1.Docker Compose

      dcoker-compose主要是解决本地docker容器编排问题。当然也可以自己编写shell脚本来解决此类问题。

      一般是通过yaml配置文件来使用它,这个yaml文件里能记录多个容器启动的配置信息(镜像、启动命令、端口映射等),最后只需要执行docker-compose对应的命令就会像执行脚本一样地批量创建和销毁容器。

    1.使用步骤

    一般分为3步:

    使用 Dockerfile 定义应用程序的环境。

    使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

    最后,执行 docker-compose up 命令来启动并运行整个应用程序。

    2.安装compose

    linux下面安装:

    sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose #下载
    sudo chmod +x /usr/local/bin/docker-compose  #赋予可运行权
    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose  #创建软连接

     windows安装docker的时候默认会安装。

    查看版本:

    $ docker-compose --version
    docker-compose version 1.20.1, build 5d8c71b2

    3.开始使用--构造基于tomcat服务和mysql服务的javaweb项目

    (1)准备一个JavaWeb项目,如下:

    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ pwd
    /e/docker/dockerTest/dockertest4
    
    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ ls
    docker-compose.yml  Dockerfile  ssm.war

    (2)文件内容分别如下:

    docker-compose.yml内容如下:

    # yaml 配置
    version: '2'
    services:
      #tomcat服务
      tomcat:
        # 指定基于当前./Dockerfile 构建的镜像,这时候无需指定image,如果指定image会代替当前build指定的镜像
        build: .
        # 指定容器名称
        container_name: tomcat_web
        # 指定端口映射
        ports:
         - "8080:8080"
        #volumes:
          #- "$PWD/tomcat/webapps:/usr/local/tomcat/webapps"
        #指定依赖的服务,会先启动依赖服务,后启动自身。停止的时候顺序相反。
        depends_on:
          - mysql
      #mysql服务
      mysql:
        # 指定镜像
        image: "hub.c.163.com/library/mysql"
        container_name: msql_ssm
        ports:
          - "3306:3306"
        # 指定环境变量
        environment:
          MYSQL_ROOT_PASSWORD: "123456"
          MYSQL_DATABASE: ssm
        # 覆盖容器启动的默认命令。
        command: [
          '--character-set-server=utf8mb4',
          '--collation-server=utf8mb4_unicode_ci'      
        ]
          

      该文件定义了两个服务。tomcat和mysql。

      tomcat:该服务使用从当前目录下Dockerfile构建的镜像(build指定至于当前目录下Dockerfile的镜像)。端口暴露在8080。

      mysql:该服务基于mysql镜像, 

    Dockerfile内容如下:(tomcat服务的镜像制作Dockerfile。也就是运行tomcat服务的时候会先基于下面Dockerfile构建镜像,然后启动容器)

    FROM hub.c.163.com/library/tomcat
    MAINTAINER qlq
    COPY ./ssm.war /usr/local/tomcat/webapps

     ssm.war是一个javaweb项目,和上一篇文章自己手动构造的Javaweb镜像一样。

    (3)使用 Compose 命令构建和运行您的应用

    到 /e/docker/dockerTest/dockertest4目录,也就是docker-compose.yml文件所在的目录。

    docker-compose up

    如果你想在后台执行该服务可以加上 -d 参数:

    docker-compose up -d

    (4)我们运行  docker-compose up -d  之后查看镜像和容器信息

    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ docker images
    REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
    dockertest4_tomcat             latest              ace88b521179        About an hour ago   350MB
    hello_dockerfile               latest              779eab29d6dc        4 days ago          5.59MB
    alpine                         latest              e7d92cdc71fe        4 weeks ago         5.59MB
    ubuntu                         latest              ccc6e87d482b        4 weeks ago         64.2MB
    hello-world                    latest              fce289e99eb9        13 months ago       1.84kB
    hub.c.163.com/library/tomcat   latest              72d2be374029        2 years ago         292MB
    hub.c.163.com/library/nginx    latest              46102226f2fd        2 years ago         109MB
    hub.c.163.com/library/mysql    latest              9e64176cd8a2        2 years ago         407MB
    
    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ docker ps -a
    CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                    NAMES
    7aa9b3cb61ee        dockertest4_tomcat            "catalina.sh run"        About an hour ago   Up 41 minutes       0.0.0.0:8080->8080/tcp   tomcat_web
    279551a99051        hub.c.163.com/library/mysql   "docker-entrypoint.s…"   About an hour ago   Up 41 minutes       0.0.0.0:3306->3306/tcp   msql_ssm

      实际上docker compose帮我们创建了一个tomcat镜像,也就是我们Dockerfile中声明的镜像,并且启动了新建的镜像和mysql镜像。

     补充:yml配置文件参考

     (1)version 指定本 yml 依从的 compose 哪个版本制定的。

    (2)build 指定为构建镜像上下文路径:

    例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:

    version: "3.7"
    services:
      webapp:
        build: ./dir

    或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:

    version: "3.7"
    services:
      webapp:
        build:
          context: ./dir
          dockerfile: Dockerfile-alternate
          args:
            buildno: 1
          labels:
            - "com.example.description=Accounting webapp"
            - "com.example.department=Finance"
            - "com.example.label-with-empty-value"
          target: prod

    context:上下文路径。

    dockerfile:指定构建镜像的 Dockerfile 文件命。

    args:添加构建参数,这是只能在构建过程中访问的环境变量。

    labels:设置构建镜像的标签。

    target:多层构建,可以指定构建哪一层。

    (3)cap_add,cap_drop

    添加或删除容器拥有的宿主机的内核功能。

    cap_add:
      - ALL # 开启全部权限
    
    cap_drop:
      - SYS_PTRACE # 关闭 ptrace权限

    (4) cgroup_parent

    为容器指定父 cgroup 组,意味着将继承该组的资源限制。

    cgroup_parent: m-executor-abcd

    (5)command

    覆盖容器启动的默认命令。

    command: ["bundle", "exec", "thin", "-p", "3000"]

    (6)container_name

    指定自定义容器名称,而不是生成的默认名称

    container_name: my-web-container

    (6)depends_on

    设置依赖关系。

    docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。

    docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。

    docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。

    version: "3.7"
    services:
      web:
        build: .
        depends_on:
          - db
          - redis
      redis:
        image: redis
      db:
        image: postgres

    注意:web 服务不会等待 redis db 完全启动 之后才启动。

    (7) devices

    指定设备映射列表。

    devices:
      - "/dev/ttyUSB0:/dev/ttyUSB0"

    (8)dns 自定义 DNS 服务器,可以是单个值或列表的多个值

    dns: 8.8.8.8
    
    dns:
      - 8.8.8.8
      - 9.9.9.9

    (9)dns_search

    自定义 DNS 搜索域。可以是单个值或列表。

    dns_search: example.com
    
    dns_search:
      - dc1.example.com
      - dc2.example.com

    (10) entrypoint

    覆盖容器默认的 entrypoint。

    entrypoint: /code/entrypoint.sh

    也可以是以下格式:

    entrypoint:
        - php
        - -d
        - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
        - -d
        - memory_limit=-1
        - vendor/bin/phpunit

    (11) env_file

    从文件添加环境变量。可以是单个值或列表的多个值。

    env_file: .env

    也可以是列表格式:

    env_file:
      - ./common.env
      - ./apps/web.env
      - /opt/secrets.env

    (12) environment

    添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。

    environment:
      RACK_ENV: development
      SHOW: 'true'

    (13) expose

    暴露端口,但不映射到宿主机,只被连接的服务访问。

    仅可以指定内部端口为参数:

    expose:
     - "3000"
     - "8000"

    (14)image

    指定容器运行的镜像。以下格式都可以:

    image: redis
    image: ubuntu:14.04
    image: tutum/influxdb
    image: example-registry.com:4000/postgresql
    image: a4bc65fd # 镜像id

    (15)volumes

    将主机的数据卷或着文件挂载到容器里。

    version: "3.7"
    services:
      db:
        image: postgres:latest
        volumes:
          - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
          - "/localhost/data:/var/lib/postgresql/data"

    (16)network_mode

    设置网络模式。

    network_mode: "bridge"
    network_mode: "host"
    network_mode: "none"
    network_mode: "service:[service name]"
    network_mode: "container:[container name/id]"

    2.Swarm

      docker-swarm是解决多主机多个容器调度部署得问题。

      swarm是基于docker平台实现的集群技术,他可以通过几条简单的指令快速的创建一个docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。swarm技术相当不成熟,很多配置功能都无法实现,只能说是个半成品,目前更多的是使用Kubernetes来管理集群和调度容器。

       Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。

    支持的工具包括但不限于以下各项:

    Dokku
    Docker Compose
    Docker Machine
    Jenkins

    1.原理

    如下图所示,swarm 集群由管理节点(manager)和工作节点(work node)构成。

    swarm mananger:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
    work node:即图中的 available node,主要负责运行相应的服务来执行任务(task)。

     2.使用

     以下示例,以 Docker Machine 和 virtualbox 进行介绍。

    1.创建 swarm 集群管理节点(manager)

    创建 docker 机器:

    docker-machine create -d virtualbox swarm-manager

    查看机器:

    $ docker-machine ls
    NAME            ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
    default         *        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.5
    swarm-manager   -        virtualbox   Running   tcp://192.168.99.102:2376           v19.03.5

    2.初始化 swarm 集群,进行初始化的这台机器,就是集群的管理节点。

    (1)查看机器的IP

    $ docker-machine ip swarm-manager
    192.168.99.102

    (2)初始化为集群管理节点(下面的 IP 为创建机器时分配的 ip。)

    docker@swarm-manager:~$ docker swarm init --advertise-addr 192.168.99.102
    Swarm initialized: current node (saxb3bvwb5qp68ulel1ns9oel) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

    以上输出,证明已经初始化成功。需要把以下这行复制出来,在增加工作节点时会用到:

    docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377

    3. 创建 swarm 集群工作节点(worker)

    这里直接创建好俩台机器,swarm-worker1 和 swarm-worker2 

    docker-machine create -d virtualbox swarm-worker1
    docker-machine create -d virtualbox swarm-worker2

    分别进入俩个机器里,指定添加至上一步中创建的集群,这里会用到上一步复制的内容。

    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ docker-machine ssh swarm-worker1
       ( '>')
      /) TC (   Core is distributed with ABSOLUTELY NO WARRANTY.
     (/-_--_-)           www.tinycorelinux.net
    
    docker@swarm-worker1:~$ docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377
    This node joined a swarm as a worker.

      出现This node joined 。。。 代表以经加入成功。

    Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
    $ docker-machine ssh swarm-worker2
       ( '>')
      /) TC (   Core is distributed with ABSOLUTELY NO WARRANTY.
     (/-_--_-)           www.tinycorelinux.net
    
    docker@swarm-worker2:~$ docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377
    This node joined a swarm as a worker.
    docker@swarm-worker2:~$

    4.查看集群信息

    进入管理节点,执行:docker info 可以查看当前集群的信息。

    docker@swarm-manager:~$ docker info
    Client:
     Debug Mode: false
    
    Server:
     Containers: 0
      Running: 0
      Paused: 0
      Stopped: 0
     Images: 0
     Server Version: 19.03.5
     Storage Driver: overlay2
      Backing Filesystem: extfs
      Supports d_type: true
      Native Overlay Diff: true
     Logging Driver: json-file
     Cgroup Driver: cgroupfs
     Plugins:
      Volume: local
      Network: bridge host ipvlan macvlan null overlay
      Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
     Swarm: active
      NodeID: saxb3bvwb5qp68ulel1ns9oel
      Is Manager: true
      ClusterID: o6aztcxmyww6x20z0z2juuvmd
      Managers: 1
      Nodes: 3
      Default Address Pool: 10.0.0.0/8
      SubnetSize: 24
      Data Path Port: 4789
      Orchestration:
       Task History Retention Limit: 5
      Raft:
       Snapshot Interval: 10000
       Number of Old Snapshots to Retain: 0
       Heartbeat Tick: 1
       Election Tick: 10
      Dispatcher:
       Heartbeat Period: 5 seconds
      CA Configuration:
       Expiry Duration: 3 months
       Force Rotate: 0
      Autolock Managers: false
      Root Rotation In Progress: false
      Node Address: 192.168.99.102
      Manager Addresses:
       192.168.99.102:2377
     Runtimes: runc
     Default Runtime: runc
     Init Binary: docker-init
     containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
     runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
     init version: fec3683
     Security Options:
      seccomp
       Profile: default
     Kernel Version: 4.14.154-boot2docker
     Operating System: Boot2Docker 19.03.5 (TCL 10.1)
     OSType: linux
     Architecture: x86_64
     CPUs: 1
     Total Memory: 989.5MiB
     Name: swarm-manager
     ID: G5DI:IQAN:ZROP:SFOZ:4U5A:VNHA:T55G:57GE:DAQX:STGM:RKKN:TCXA
     Docker Root Dir: /mnt/sda1/var/lib/docker
     Debug Mode: false
     Registry: https://index.docker.io/v1/
     Labels:
      provider=virtualbox
     Experimental: false
     Insecure Registries:
      127.0.0.0/8
     Live Restore Enabled: false
     Product License: Community Engine

      通过标红的地方,可以知道当前运行的集群中,有三个节点,其中有一个是管理节点。

    5.部署服务到集群中

    注意:跟集群管理有关的任何操作,都是在管理节点上操作的。

    以下例子,在一个工作节点上创建一个名为 helloworld 的服务,这里是随机指派给一个工作节点:

    docker@swarm-manager:~$ docker service create --replicas 1 --name helloworld alpine ping docker.com
    bwe0epdhxyr9wnhg9fdrjm261
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged

    replicas 参数是指运行实例个数
    name 参数指定服务名称
    alpine 指的是使用的镜像名称
    ping docker.com 指的是容器运行的bash

    6.查看服务部署情况

    查看 helloworld 服务运行在哪个节点上,可以看到目前是在 swarm-manager 节点:

    docker@swarm-manager:~$ docker service ps helloworld
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
    cf4rnafi6zam        helloworld.1        alpine:latest       swarm-manager       Running             Running 8 minutes ago

    查看 helloworld 部署的具体信息:

    docker@swarm-manager:~$ docker service inspect --pretty helloworld
    
    ID:             bwe0epdhxyr9wnhg9fdrjm261
    Name:           helloworld
    Service Mode:   Replicated
     Replicas:      1
    Placement:
    UpdateConfig:
     Parallelism:   1
     On failure:    pause
     Monitoring Period: 5s
     Max failure ratio: 0
     Update order:      stop-first
    RollbackConfig:
     Parallelism:   1
     On failure:    pause
     Monitoring Period: 5s
     Max failure ratio: 0
     Rollback order:    stop-first
    ContainerSpec:
     Image:         alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
     Args:          ping docker.com
     Init:          false
    Resources:
    Endpoint Mode:  vip

    7.扩展集群服务

    将上述的 helloworld 服务扩展到俩个节点。

    docker@swarm-manager:~$ docker service scale helloworld=2  #扩展到两个
    helloworld scaled to 2
    overall progress: 2 out of 2 tasks
    1/2: running   [==================================================>]
    2/2: running   [==================================================>]
    verify: Service converged
    docker@swarm-manager:~$ docker service ps helloworld
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
    cf4rnafi6zam        helloworld.1        alpine:latest       swarm-manager       Running             Running 15 minutes ago
    lvbmq8nyywir        helloworld.2        alpine:latest       swarm-worker1       Running             Running 25 seconds ago

    8.删除服务

    docker@swarm-manager:~$ docker service rm helloworld
    helloworld
    docker@swarm-manager:~$ docke

    9.停止某个节点

    查看所有任务的节点

    docker@swarm-manager:~$ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
    vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
    yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5

      可以看到目前所有的节点都是 Active, 可以接收新的任务分配。

    停止节点 swarm-worker1:

    docker@swarm-manager:~$ docker node ls # 查看节点
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
    vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
    yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5
    <ocker node update --availability drain swarm-worker1  #停掉节点worker1
    swarm-worker1
    docker@swarm-manager:~$ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
    vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Drain                                   19.03.5
    yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5
    docker@swarm-manager:~$ docker node update --availability active swarm-worker1  #重新激活节点worker1
    swarm-worker1
    docker@swarm-manager:~$ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
    vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
    yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5

     补充:swarm集群中部署nginx

    1.管理节点中运行

    docker service create --name my-web --publish published=8080,target=80 --replicas 2 hub.c.163.com/library/nginx

      知道了服务的名字是my-web,启动的节点是2个,镜像是 hub.c.163.com/library/nginx。将nginx容器中的端口80发布到群集中任何节点的端口8080。

    2.查看集群上的服务

    docker@swarm-manager:~$ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE                                PORTS
    n48sms4g6ccv        my-web              replicated          2/2                 hub.c.163.com/library/nginx:latest   *:8080->80/tcp
    docker@swarm-manager:~$ docker service ps my-web
    ID                  NAME                IMAGE                                NODE                DESIRED STATE       CURRENT STATE             ERROR                              PORTS
    y2hfv1i6rqgu        my-web.1            hub.c.163.com/library/nginx:latest   swarm-worker1       Running             Running 52 minutes ago
    n1rkpi1m67xf         \_ my-web.1        hub.c.163.com/library/nginx:latest   swarm-worker1       Shutdown            Rejected 53 minutes ago   "No such image: hub.c.163.com/…"
    od7sw0ju48aa        my-web.2            hub.c.163.com/library/nginx:latest   swarm-manager       Running             Running 53 minutes ago

       service 通过 ingress load balancing 来发布服务,且 swarm 集群中所有 node 都参与到 ingress 路由网格(ingress routing mesh) 中,访问任意一个 node+PublishedPort 即可访问到服务。

      当访问任何节点上的端口8080时,Docker将您的请求路由到活动容器。在群节点本身,端口8080可能并不实际绑定,但路由网格知道如何路由流量,并防止任何端口冲突的发生。

      路由网格在发布的端口上监听分配给节点的任何IP地址。对于外部可路由的IP地址,该端口可从主机外部获得。对于所有其他IP地址,只能从主机内部访问。

      http://192.168.99.102:8080/、103:8080、104:8080端口都可以访问到nginx服务,这样就实现了负载均衡。因为我们指定--replicas 2 启动了2个运行nginx的容器 ,所以2个节点上都运行了一个 nginx 的容器,可以通过改其中一个节点上的nginx的欢迎页 ,然后再访问,来检查是否实现了负载均衡。

      可以通过scale 来指定运行容器的数量。可以看到节点的副本变成1。

    docker@swarm-manager:~$ docker service scale my-web=1
    my-web scaled to 1
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged
    docker@swarm-manager:~$ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE                                PORTS
    n48sms4g6ccv        my-web              replicated          1/1                 hub.c.163.com/library/nginx:latest   *:8080->80/tcp
  • 相关阅读:
    Django-序列化器
    HTTP请求头响应头的信息
    HTTP协议
    IAAS,PAAS,SAAS
    MySQL-部分名词解释
    MySQL-事务和特性
    用Java仿QQ界面聊天小项目
    25篇Java入门技术博客,送给准备入坑的你
    Java自学推荐书籍
    Java中的并发讲解
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/12325925.html
Copyright © 2011-2022 走看看