Docker介绍与使用

1. 为什么需要Docker

没有docker遇到的问题:

  • 依赖复杂:比如系统的其他应用需要python3.7和gcc9,而你的应用需要python2.7和gcc7,你不便把系统改成你要的环境。
  • 迁移环境耗时:上个环境可以正常工作,但更新环境后出现一堆bug,甚至难以进行环境回退。
  • 新开发者加入团队:代码在他的电脑上跑不起来,为新电脑安装环境费时费力。

docker和虚拟机的区别:

img

从图中可以看到,docker比虚拟机更省内存。

2. Docker的关键概念

  1. Docker结构——Image、Container

    类比面向对象编程,一个image就像一个类,里面包含着所需的环境,image可以被存在云端,需要的时候拉取。一个container就像一个image的实例。

  2. Docker组件——Client、Server

    之前我们一直在用一个笼统的术语“Docker”来描述它的功能,但它其实有很多不同的组件:

    • Docker Registry: Docker官方保存 images的仓库,供大家pull
    • Docker Hub: 分享和获取Images的地方,类似于Github
    • Docker Client: The CLI tool used to interact with the Docker server
    • Docker Daemon: The Docker server process responsible for pulling, pushing, and building the images. It is also used for running the container

    流程为:你可以通过Docker Client要求Docker daemon运行某一个image,daemon就会在系统查找这个image,如果找到了就 run the container forked from that image,否则pull the image from the Docker registry and create a container from the image.

    image-20200828184732363

    如上图所示是Docker client要求daemon: pull a Redis image、run the Ubuntu image. 这些交流是通过Docker server提供的APIs完成的。

3. Docker的安装

Docker为了不同的工业需要有不同的版本,这里使用Docker community edition,简称Docker CE。

  • Docker CE on Windows(略,需要VM)

    Docker CE: https://hub.docker.com/?overlay=onboarding

  • Docker CE for Mac OS(略,需要VM)

    https://hub.docker.com/?overlay=onboarding

  • Docker CE on Linux

    Ubuntu 18.04/16.04:

    移除旧版本docker:

    1
    2
    # use sudo if required
    apt-get remove docker docker-engine docker.io containerd runc

    安装:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 1. Update package index
    sudo apt-get update
    # 2. Install packages to allow apt to use a repository over HTTPS
    sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
    # 3. Add Docker’s official GPG key
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
    # 4. 设置一个稳定的仓库
    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt-get update
    # 5. 安装最新版本的Docker CE and containerd
    apt-get install docker-ce docker-ce-cli containerd.io
    # 6. 检查是否安装成功
    sudo docker info
    docker run hello-world
    # 如果不想在每个docker命令中都加sudo,可以添加用户名到docker group
    sudo usermod -aG docker <your-user>

    CentOS installation : https://docs.docker.com/install/linux/docker-ce/centos/

    Debian: https://docs.docker.com/install/linux/docker-ce/debian/

    Fedora: https://docs.docker.com/install/linux/docker-ce/fedora/

    由于众所周知的原因,国内获取Docker官方镜像的速度很慢,因此配置阿里云镜像加速器

    针对Docker客户端版本大于 1.10.0 的用户

    您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

    1
    2
    3
    4
    5
    6
    7
    8
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
    "registry-mirrors": ["https://prt5jb4d.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker

    在docker中apt-get使用的是国外的源,速度是非常慢的,所以要更换为国内的源:

    进入container,原文件备份,并进入此目录

    1
    2
    cp /etc/apt/sources.list /etc/apt/sources.list.bak
    cd /etc/apt/

    修改sources.list

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    echo "">sources.list
    echo "deb http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse">>sources.list
    echo "deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse">>sources.list
    echo "deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse">>sources.list
    echo "deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse">>sources.list
    echo "deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse">>sources.list
    echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse">>sources.list
    echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse">>sources.list
    echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse">>sources.list
    echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse">>sources.list
    echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse">>sources.list

    备注:在更换软件源时若遇到了如下问题

    1
    2
    3
    Reading package lists... Done
    E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
    E: Unable to lock directory /var/lib/apt/lists/

    表明当前有某个进程正在apt-get,然而我并没有使用任何命令,于是需要kill掉进程。
    解决办法:

    1
    rm /var/lib/apt/lists/lock

    如果报错没有公钥,我们把这个公钥添加到服务器就行了

    1
    2
    3
    # 8D5A09DC9B929006 是我的缺少的公钥,你写你缺少的公钥就行
    # 如果缺少多个就多次执行下面的命令,只是需要修改成相应的公钥就ok
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8D5A09DC9B929006

4. Docker基础使用

从image中创建container并运行

所有docker images的名字格式为<image name>:<version>, 未指定版本号则默认为 :latest

本节用到的命令:

  • docker pull <images-name>:<version> : pulls image from Docker registry
  • docker run <images-name>:<version> : runs container from mentioned image
  • docker ps : shows all running containers
  • docker ps -a: shows all available containers
  • docker exec : executes a command in a running container

解释/参数扩展 & 例子:

  1. -it: The options i & t are used to provide an interactive mode and a pseudo tty terminal.
  2. docker exec -it <cantainer id/name> bash
  3. docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
1
2
3
4
5
6
docker pull python:3.5
docker run python:3.5
docker ps -a
docker run -it python:3.5 bash
docker exec -it 019d4fffb3b3 bash
exit

将container提交为image并push到DockerHub

本节用到的命令:

change and commit

  • docker start <container_id/name>: 重启关掉的container
  • docker exec -it <cantainer id/name> bash
  • docker rm <container_id/name>: 删除某个container
  • docker commit -m "<commit message>" <container_id/name> <new_image_name>:<version>: commit the container
  • docker images: see the images on your system.

把image push到 Docker Hub 的步骤:

  • docker login
  • docker tag <image_name> <your_docker_hub_username>/<image>:<version>
  • docker push <your_docker_hub_username>/<image>:<version>

管理Containers的文件

尽管Docke共享操作系统的内核,但文件系统是分开的。共享文件有两种方法,一种是Bind mount,效果类似于软链接,可以使container访问主机的文件;另一种是Volumes,它是创建在Docker中的空间,通过Docker CLI访问,更多的用于不同的container共享文件的场景,而非主机和container共享文件。

本节用到的命令:

  • docker volume --help: to get the volume help
  • docker volume create (<volume_name>): to create a new volume
  • docker volume inspect <volume_name>: to inspect the created volume
  • docker run -v: to mount a volume

解释/参数扩展 & 例子:

  1. -v: you use the host filesystem and mount it on the container using -v flag with the run command. 这样在container的设定路径中可以看到主机absolute_path中的文件
  2. To mount the file system as read-only, use ro flag.
1
2
3
4
5
6
7
8
9
# docker run -it -v <absolute_path>:<folder path or new folder name> date_project:1.0
docker run -it -v /root/learn/dockerlearn/:/desktop date_project:1.0
# docker run -it -v <absolute_path>:<folder path or new folder name>:ro date_project:1.0

docker volume create project_directory
docker volume ls
docker volume inspect project_directory
docker run -it -v project_directory:/project date_project:1.0
docker run -it -v project_directory:/project_in_second --name second_container date_project:1.0

5. Dockerfile

flask应用案例,文件结构如下

  • .flaskenv: 特别针对Flask的变量环境声明
  • requirements.txt: 运行app需要的所有环境要求,如所需的所有python包
  • templates/form.html: Flask 在 templates 文件夹中寻找 HTML 模板.
  • app.py: python程序
  • Dockerfile: 与app.py处于同一根目录

.flaskenv文件内容如下

1
2
3
FLASK_APP=app.py
FLASK_ENV=development # debug模式
# FLASK_ENV=production

dockerfile一行一个命令。常见的命令如下:

  • FROM: 用来告诉Docker使用哪个base Image或者主平台
  • WORKDIR: 为其他的docker指令如RUN、CMD设置一个工作目录
  • ENV: 设置app所需的环境变量。可以跳过此步而使用.flaskenv
  • COPY: 格式为COPY SOURCE DESTINATION,拷贝文件
  • RUN: 在当前的image新建一个layer,并在这个新的layer运行命令
  • CMD: 在container中运行命令
  • ENTRYPOINT: 将container配置为可执行文件,如 ENTRYPOINT [“flask”, “run”]

更多命令可参考:https://docs.docker.com/engine/reference/builder/#run

dockerfile示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FROM python:3.9-rc-buster

# Setting up Docker environment
WORKDIR /code
# Export env variables.
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
###

#Copy requirements file from current directory to file in
#containers code directory we have just created.
COPY requirements.txt requirements.txt

#Run and install all required modules in container
RUN pip3 install -r requirements.txt

#Copy current directory files to containers code directory
COPY . .

#RUN app.
CMD ["flask", "run"]

构建image

1
2
# 进入Dockerfile所在路径后运行
docker build -t flask_app:1.0 .

构建完后会在本机上创建一个image,可以使用docker images查看。

运行:docker run -p 5000:5000 flask_app:1.0,如果不加-p 5000:5000的话app会运行在container的5000端口,主机的浏览器是无法访问的,添加这个参数之后,会进行端口映射,主机的浏览器就可以访问了。

当你写代码的时候,是主机的文件发生了变化,如果你想把这些变化映射到container中,则需要在运行docker时使用docker run -it -v <host_absolute_path>:<folder path in container> -p 5000:5000 flask_app:1.0。后台运行container,使用-d选项,即docker run -d -v <path_to_code_directory>:/code -p 5000:5000 flask_app:1.0

使用docker ps可以查看container是否在后台运行。

请我喝杯咖啡吧~

支付宝
微信