一次较为完整的Docker入门之旅

1. 构建你的Docker环境(最复杂的问题要用最简单的方式来解决)

  • Docker是一个对于开发者和系统管理员用容器去开发,部署和运行应用程序的一个平台。

  • Docker非常流行的几个因素

    • Flexible(灵活的)
    • Lightweight(轻量级的)
    • Interchangeable(可互换的,可交替的)
    • Portable(便携的)
    • Scalable(可扩展的)
    • Stackable(易叠起堆放的;可叠起堆放的)
  • 镜像和容器


    一次较为完整的Docker入门之旅_第1张图片
    一张图说清楚镜像和容器的关系
    • 镜像
      A container is launched by running an image.镜像就是一个可执行的包,这个包中有程序运行的所有条件,代码,依赖的jar包,环境变量,配置文件。
    • 容器
      容器是一个运行的镜像实例。你可以使用命令docker ps去查看正在运行的容器。
    • 容器和虚拟机的差别


      一次较为完整的Docker入门之旅_第2张图片
      容器和虚拟机的差别
    • 较虚拟机而言,Docker将会更加省内存基于上图。因为虚拟机是逻辑上的一台机器,它共享宿主机器的硬件资源。
  • Docker的Cli命令简介

    [root~]# docker
    Usage:  docker COMMAND
    A self-sufficient runtime for containers
    Options:
    --config string      Location of client config files (default "/root/.docker")
    -D, --debug              Enable debug mode
    -H, --host list          Daemon socket(s) to connect to
    -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
    --tls                Use TLS; implied by --tlsverify
    --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
    --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
    --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
    --tlsverify          Use TLS and verify the remote
    -v, --version            Print version information and quit
    
    Management Commands:
    config      Manage Docker configs
    container   Manage containers
    image       Manage images
    network     Manage networks
    node        Manage Swarm nodes
    plugin      Manage plugins
    secret      Manage Docker secrets
    service     Manage services
    swarm       Manage Swarm
    system      Manage Docker
    trust       Manage trust on Docker images
    volume      Manage volumes
    
    Commands:
    attach      Attach local standard input, output, and error streams to a running container
    build       Build an image from a Dockerfile
    commit      Create a new image from a container's changes
    cp          Copy files/folders between a container and the local filesystem
    create      Create a new container
    diff        Inspect changes to files or directories on a container's filesystem
    events      Get real time events from the server
    exec        Run a command in a running container
    export      Export a container's filesystem as a tar archive
    history     Show the history of an image
    images      List images
    import      Import the contents from a tarball to create a filesystem image
    info        Display system-wide information
    inspect     Return low-level information on Docker objects
    kill        Kill one or more running containers
    load        Load an image from a tar archive or STDIN
    login       Log in to a Docker registry
    logout      Log out from a Docker registry
    logs        Fetch the logs of a container
    pause       Pause all processes within one or more containers
    port        List port mappings or a specific mapping for the container
    ps          List containers
    pull        Pull an image or a repository from a registry
    push        Push an image or a repository to a registry
    rename      Rename a container
    restart     Restart one or more containers
    rm          Remove one or more containers
    rmi         Remove one or more images
    run         Run a command in a new container
    save        Save one or more images to a tar archive (streamed to STDOUT by default)
    search      Search the Docker Hub for images
    start       Start one or more stopped containers
    stats       Display a live stream of container(s) resource usage statistics
    stop        Stop one or more running containers
    tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
    top         Display the running processes of a container
    unpause     Unpause all processes within one or more containers
    update      Update configuration of one or more containers
    version     Show the Docker version information
    wait        Block until one or more containers stop, then print their exit codes
    
    Run 'docker COMMAND --help' for more information on a command.
    

小结

以上是通过运行docker打印出来的所有有关docker的命令。如果想了解具体某部分的命令,比如,我现在想了解镜像相关的命令,可以输入docker image,这样在命令行中就会输出与镜像相关的命令。如果对于某个命令有疑问,可以使用docker image build --help进行命令的查询,在Linux世界中,对于不会的命令,或第一次遇到的命令,可以找man,在Docker中就可以找help了,一切help

  • Docker的版本等相关命令

    #查看Docker的版本
    docker --version
    Docker version 18.03.1-ce, build 9ee9f40
    #查看跟多的信息
    docker version
    Client:
     Version:      18.03.1-ce
     API version:  1.37
     Go version:   go1.9.5
     Git commit:   9ee9f40
     Built:        Thu Apr 26 07:20:16 2018
     OS/Arch:      linux/amd64
     Experimental: false
     Orchestrator: swarm
    
    Server:
     Engine:
      Version:      18.03.1-ce
      API version:  1.37 (minimum version 1.12)
      Go version:   go1.9.5
      Git commit:   9ee9f40
      Built:        Thu Apr 26 07:23:58 2018
      OS/Arch:      linux/amd64
      Experimental: false
    
     #查看Docker一些详细信息
     docker info
     Containers: 3
     Running: 0
     Paused: 0
     Stopped: 3
     Images: 2
     Server Version: 18.03.1-ce
     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 macvlan null overlay
     Log: awslogs fluentd gcplogs gelf journald json-file logentries 
     splunk syslog
     Swarm: inactive
     Runtimes: runc
     Default Runtime: runc
     Init Binary: docker-init
     containerd version:         
     773c489c9c1b21a6d78b5c538cd395416ec50f88
     runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
     init version: 949e6fa
     Security Options:
     seccomp
     Profile: default
     Kernel Version: 3.10.0-693.2.2.el7.x86_64
     Operating System: CentOS Linux 7 (Core)
     OSType: linux
     Architecture: x86_64
     CPUs: 1
     Total Memory: 992.3MiB
     Name: iz2ze6jeqopgq9yoosls6dz
     ID:UIVR:2YDB:XRFJ:PUFM:WFJH:NZVN:LCSM:W7AI:BNLA:RBED:T7RJ:I22F
     Docker Root Dir: /var/lib/docker
     Debug Mode (client): false
     Debug Mode (server): false
     Registry: https://index.docker.io/v1/
     Labels:
     Experimental: false
     Insecure Registries:
     127.0.0.0/8
     Live Restore Enabled: false
     
     #Docker hello world
     docker run hello-world
     #列出下载到本机上的所有镜像文件
     docker image ls
     #遇到不会的命令怎么办呢?
     docker container --help
    

2. 构建一个镜像并且作为容器运行

  • 方便携带的镜像是由一个叫做Dockerfile这个文件定义的。

  • 创建一个Dockerfile文件

    • 首先创建一个路径containers

    • cd进入这个路径cd containers

    • 创建一个Dockerfile文件

      # Use an official Python runtime as a parent image
      # 从python:2.7-slim这个镜像基础之上创建的镜像, FROM命令可以多次使用
      FROM python:2.7-slim
      
      # Set the working directory to /app
      WORKDIR /app
      
      # Copy the current directory contents into the container at /app
      ADD . /app
      
      # Install any needed packages specified in requirements.txt
      RUN pip install --trusted-host pypi.python.org -r requirements.txt
      
      # Make port 80 available to the world outside this container
      EXPOSE 80
      
      # Define environment variable
      ENV NAME World
      
      # Run app.py when the container launches
      CMD ["python", "app.py"]
      
    • Docker提供一种自动化的方式来创建镜像--DockerfileDockerfile包含了创建镜像所需要的全部命令。Docker支持如下语法命令:

      # 指令要大写根据命名规约
      INSTRUCTION argument
      
    • 有趣的Dockerfile命令

      • FROM:基于某个镜像去构建

        FROM ubuntu //基于ubuntu的镜像来构建。
        
      • MAINTAINER:镜像的维护者

        MAINTAINER mark // 镜像的作者mark
        
      • RUN:在Shell或exec环境下执行命令。这个命令会在新创建的镜像上添加新的层面(layer), RUN指令会在shell里使用命令包装器/bin/sh -c来执行。

        RUN pip install --trusted-host pypi.python.org -r requirements.txt
        
      • ADD:复制文件指令。有两个参数src和destinction。destinction是容器内的路径。src是URL或启动配置上下文的一个文件。

        ADD . /app
        
      • CMD:提供容器默认的执行命令。只允许使用一次。

        CMD ["python", "app.py"]
        
      • EXPOSE:暴露容器在Docker虚拟机内部运行时的监听端口。

        EXPOSE 8080
        
      • ENTRYPOINT:配置给容器一个可执行的命令。这意味着在每次使用镜像创建一个容器时一个特定的应用程序可以被设置成默认程序。同时也意味着该镜像被调用时只能运行指定的程序。类似CMD,只允许一个ENTRYPOINT,如果多个出现,以最后一个命令为准。

        ENTRYPOINT ['executable', 'param1', 'param2']
        
      • WORKDIR:指命令RUN, CMDENTRYPOINT的工作目录。

        WORKDIR /app
        
      • ENV:设置环境变量,使用key-value的方式

        ENV NAME World
        
      • USER:镜像运行时设置一个UID.

        USER mark
        
      • VOLUME:授权访问容器内到主机上的目录。

        VOLUME ['/data']
        
    • 在同一路径下创建另外两个文件,requirements.txtapp.py

      • requirements.txt

        Flask
        Redis
        
      • app.py

        from flask import Flask
        from redis import Redis, RedisError
        import os
        import socket
        
        # Connect to Redis
        redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
        
        app = Flask(__name__)
        
        @app.route("/")
        def hello():
            try:
                visits = redis.incr("counter")
            except RedisError:
                visits = "cannot connect to Redis, counter disabled"
        
            html = "

        Hello {name}!

        " \ "Hostname: {hostname}
        " \ "Visits: {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
    • 构建应用
      docker build -t friendlyhello .

      一次较为完整的Docker入门之旅_第3张图片
      执行完后的结果图

    • 查看本地镜像文件
      docker image ls

    • 运行自己制作的docker镜像
      docker run friendlyhello/docker run -p 4000:80 friendlyhello
      运行结果如图所示

      返回结果

    • 将镜像起个别名,准备上传到Docker Hub上
      docker tag friendlyhello gordon/get-started:part2
      docker push username/repository:tag

  • 本小节常用的命令

    docker build -t friendlyhello .  # Create image using this       
    directory's Dockerfile
    docker run -p 4000:80 friendlyhello  # Run "friendlyname" 
    mapping port 4000 to 80
    docker run -d -p 4000:80 friendlyhello  # Same thing, but in detached mode
    docker container ls   # List all running containers
    docker container ls -a    # List all containers, even those not running
    docker container stop    # Gracefully stop the specified container
    docker container kill     # Force shutdown of the specified container
    docker container rm    # Remove specified container from this machine
    docker container rm $(docker container ls -a -q) # Remove all containers
    docker image ls -a  # List all images on this machine
    docker image rm  # Remove specified image from this machine
    docker image rm $(docker image ls -a -q)   # Remove all images from this machine
    docker login # Log in this CLI session using your Docker credentials
    docker tag  username/repository:tag  # Tag  for upload to registry
    docker push username/repository:tag # Upload tagged image to registry
    docker run username/repository:tag  # Run image from a registry
    

3. 扩展您的应用程序以运行多个容器

  • 拆分应用并实现负载均衡,我们必须在分布式应用程序的层次结构中提升一个级别:服务。

  • 在分布式应用中, 会根据不同的业务划分不同的模块,实现不同的功能。拆分服务比较容易,通过写docker-compose.yml文件来实现。docker-compose.yml是一个YAML文件,定义了Docker容器在生产中的表现。

  • docker-compose.yml

    version: "3"
    services:
        web:
          # replace username/repo:tag with your name and image details
          image: username/repo:tag
          deploy:
            replicas: 5
            resources:
              limits:
                cpus: "0.1"
                memory: 50M
              restart_policy:
                condition: on-failure
          ports:
            - "4000:80"
          networks:
            - webnet
    networks:
      webnet:
    
  • 这个文件告诉Docker要做下面的事情。

    • 在Docker Hub上面拉取镜像
    • 运行5个从Docker Hub上面下载下来的镜像实例作为一个web服务。限制每个都要被用到,最多10%的CPU资源和50M的内存资源。
    • 如果一个停止或者fail掉的话,立即重新启动。
    • 通过主机上的4000端口和Docker中容器container进行绑定。
    • 通知web容器共享端口80通过负载均衡网络被称为webnet
    • 用默认的方式定义webnet网络(负载均衡的覆盖网络)。
  • 运行负载均衡app

    • 第一步首先运行docker swarm init
      first step
    • 第二步运行docker stack deploy -c docker-compose.yml getstartedlab
      second step
    • 第三步docker service ls
      third_step
    • 第四步docker service ps helloworld_web
      一次较为完整的Docker入门之旅_第4张图片
      fourth step
    • 第五步docker container ls -q
      一次较为完整的Docker入门之旅_第5张图片
      fifth step
    • 第六步curl http://localhost:4000
      sixth step
  • 扩展你的应用
    通过修改docker-compose.yml文件中replicas值来扩展你的应用,然后运行命令docker stack deploy -c docker-compose.yml getstartedlab

4. 在群集中分发您的应用

  • 你部署一个应用到一个集群,在多台机器上运行。多容器,多机器的应用通过加入更多的机器来进行Dockerized集群的制作,被称为Swarm

  • 一个swarm是一群运行在Docker上机器成为一个集群。一个swarm开始后,你可以运行你熟悉的Docker命令。但他们现在被一个swarm manager在一个集群上执行。在swarm中的机器可以是物理机器也可以是虚拟机。加入swarm后,他们被称为节点。

  • swarm manager运行集群的两种策略:

    • emptiest node
    • global
  • swarm manager是唯一一台可以执行命令,授权其他机器一worker的角色加入swarmworker仅仅可以提供容量并且没有权限告诉其他机器,他们能做或不能做什么。

  • 直到现在,你一直用你的Docker以单主机的模式在本地运行。Docker也可以切换到swarm mode模式。

  • 建立你的swarm

    • 一个swarm有多个节点构成。节点可以是物理节点,也可以是虚拟节点。可以使用命令docker swarm init开启swarm模式并且是自己的机器成为swarm manager。然后运行命令docker swarm join在其他的机器上,使其加入swarm成为worker。现在我们使用虚拟机创建两台机器的集群,然后创建好的两台机器添加到swarm中。虚拟机可以使用win10的Hyper-v或者使用VirtualBox来搭建。在使用Docker Toolbox前,一定要保证VirtualBox已经安装了。
  • 现在用命令docker-machineVirtualBox driver来创建一对虚拟机。

    docker-machine create --driver virtualbox myvm1
    docker-machine create --driver virtualbox myvm2
    
  • 列出虚拟机并且得到他们的IP地址,使用命令docker-machine ls

5. 通过添加后端数据库来堆栈服务

6. 将您的应用部署到生产环境

你可能感兴趣的:(一次较为完整的Docker入门之旅)