docker 学习

测试环境:Ubuntu 16.04 LTS Linux 4.16.0-999-generic

shell版本: bash

一、docker 排坑

1. network问题

docker-compose 会默认在docker-compose up执行的时候为compose文件里面的所有容器创建bridge network链接,所以如果在单机上操作docker无需自定义网络或者使用links

  • 使用links 来连接容器的话,举例如下:

    links:
      - mongo:mongo    # 后一个mongo是别名或者理解为hostname
    

    然后在代码中连接mongo的话将localhost修改为mongo即可

  • 使用默认的桥接网络

    例如:docker-compose.yml如下

    version: '3'
    
    services:
        learn_docker:
          ...
            container_name: learn_docker_app
            ...
        mongo:
            ...
            container_name: learn_docker_mongo
            ...
    

    则直接使用mongo代替localhost即可

docker network ls    # list network
docker inspect [NETWORK ID]  # 查看network情况
docker network rm [NETWORK ID]  # 删除
docker network create -d bridge my-bridge-network
docker network connect [NETWORK ID | NETWORK NAME] [CONTAINER NAME | CONTAINER ID] # 将容器加入network中
docker network disconnect 。。。。。

更多请查看 官方文档 https://docs.docker.com/engine/reference/commandline/network_create/#extended-description

2. alpine

python的alpine版本中不包含C Compile,而安装uwsgi的时候需要用到gcc,所以需要手动安装gcc,然而安装网上流行的教程发现,gcc每次都安装出错

解决方案:使用Python:3.6而不是Python3.6-alpine版本(精简版),Python:3.6中自带了C Compile

3. WORKDIR

官方说WORKDIR适用于 CMD、RUN、COPY、ADD、ENTRYPOINT等命令,但是发现其实有时候还是不行的,所以尽量用绝对路径,CMD、ENTRYPOINT可以用相对路径

二、Docker CE安装

  • 卸载旧版本

    $ sudo apt-get remove docker docker-engine docker.io
    
  • 添加使用 HTTPS 传输的软件包以及 CA 证书

    $ sudo apt-get update
    
    $ sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        software-properties-common
    
  • 添加软件源的 GPG 密钥

    # 国内源
    $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    
    # 官方源
    # $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
  • source.list 中添加 Docker 软件源

    # 国内源
    $ sudo add-apt-repository \
        "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
        $(lsb_release -cs) \
        stable"
        
    # 官方源
    # $ sudo add-apt-repository \
    # "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    # $(lsb_release -cs) \
    # stable"
    
  • 安装 Docker CE

    $ sudo apt-get update
    
    $ sudo apt-get install docker-ce
    
  • 安装docker-compose

    pip安装: sudo pip install -U docker-compose

三、准备工作

1. 建立用户组
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
2. 测试
$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
Status: Downloaded newer image for hello-world:latest

Hello from Docker!

正常输出以上信息,安装成功

3. 镜像加速

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
  "registry-mirrors": [
    "https://registry.docker-cn.com"
  ]
}

之后重新启动服务。

4. 注册 Docker Hub
  • 注册

    你可以在 https://cloud.docker.com 免费注册一个 Docker 账号。

  • 登录、退出

    $ docker login
    $ docker logout
    
  • 拉取、推送

    $ docker pull [OPTIONS] HOSTNAME:PORT/USERNAME/IMAGE_NAME[:TAG|@DIGEST]
    $ docker push [OPTIONS] HOSTNAME:PORT/USERNAME/IMAGE_NAME[:TAG|@DIGEST]
    

    默认HOSTNAME为Docker Hub, USERNME默认为library, TAG默认为latest

    eg:

    $ docker pull python:3.6
    $ docker pull openresty/openresty
    $ docker pull docker.hostname.com/username/hello:v1
    

四、Dockerfile

常用镜像制作:

build 命令:docker build -t python3.6_uwsgi_flask:v1 .

进入容器:docker exec -it [container id] bash (这样就能进入 进入之后使用bash操作)

python3.6_uwsgi_flask
FROM python:3.6
MAINTAINER Zhao Nan <yun_tofar@qq.com>

COPY requirements.txt /app/requirements.txt
WORKDIR /app

RUN pip install --no-cache-dir -r requirements.txt

requirements.txt

pymongo==3.6.1
PyMySQL==0.8.0
Flask==0.12.2
PyJWT==1.3.0
requests==2.9.1
bcrypt==3.1.4
redis==2.10.6
Werkzeug==0.14.1
uWSGI==2.0.15
Flask-Mail

!!!: 千万别用 python:3.6-alpine版本,虽然这个版本精简,但是没有C compile,导致安装uwsgi不成功,后来在python:3.6-alpine基础上安装gcc,也不一定能成功,但是官方是推荐alpine版本的

五、docker-compose

启动命令:docker-compose up

version: '3'

services:
    learn_docker:
        build: .
        volumes:
            - ./logs:/app/logs
            - /etc/localtime:/etc/localtime:ro
        ports:
            - "3031:3031"
        environment:
            - TZ=Asia/Shanghai
        container_name: learn_docker_app
        depends_on: 
            - mongo
        command: uwsgi --ini uwsgi/uwsgi.ini
    mongo:
        image: mongo:3.6.3
        expose:
            - "27017"
        environment:
            - TZ=Asia/Shanghai
        container_name: learn_docker_mongo
        volumes:
            - ./db:/data/db
            - /etc/localtime:/etc/localtime:ro

注:无需使用links 来在容器之间建立通道,docker-compose会自动创建一个bridge network包含docker-compose中创建的容器

!!!:代码中直接使用mongo代替localhost即可 , expose: 27017使mongo只对docker内暴露

桥接网络自主创建连接方式:

$ docker network create learn_docker-net

$ docker-compose up

$ docker network connect learn_docker-net learn_docker_app

$ docker network connect learn_docker-net learn_docker_mongo

六、docker最佳实践

主要来源:https://github.com/kxxoling/blog/blob/master/sa/docker-best-practice.md

RUN

处于易读性的考虑,过长或者复杂的命令应该使用 \ 分割成多行,一个Dockerfile中的RUN应该尽量少,减少层数

CMD

CMD 命令只应该运行镜像所对应的命令。虽然允许 CMD executable param1 param2 的写法, 但是 CMD ["executable", "param1", "param2"…] 更不容易出错。

示例:

CMD ["apache2","-DFOREGROUND"]
CMD ["perl", "-de0"]

如果你熟悉 ENTRYPOINT 的话,推荐组合使用。

EXPOSE

端口映射应该尽可能地使用默认端口。

ADD COPY

ADD 和 COPY 的功能类似,不过 COPY 命令的功能更加直观一些,因此推荐使用。

相比之下,ADD 支持添加远程资源,并且会自动 tar 打包或者解包。不过下载远程文件更推荐使用 RUN wget 或者 curl

ENTRYPOINT

ENTRYPOINT 应该用于 镜像的主命令,并使用 CMD 作为默认设置,以 s3cmd 为例:

ENTRYPOINT ["s3cmd"]
CMD ["--help"]

获取帮助:docker run s3cmd

执行命令:docker run s3cmd ls s3://mybucket

这在镜像名与程序重名时非常有用。

ENTRYPOINT 也可以用于启动脚本:

COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

这段脚本为用户提供了多种和 Postgres 交互的途径:

你可以简单地启动 Postgres: docker run postgres

或者运行 postgres 并传入参数:docker run postgres postgres --help

你甚至可以从镜像中启动一个完全不同的程序,比如 Bash:docker run --rm -it postgres bash

VOLUME

VOLUME 通常用作数据卷,对于任何可变的文件,包括数据库文件、代码库、配置文件……都应该使用 VOLUME 挂载。

七、docker 常用命令列表

批量删除:

使用 Docker 会遗留一大堆镜像,删除镜像又需要先把已经停止的容器删除,下面我们想办法批量干掉他们

# 删除已经Exited的容器
$ docker ps -a | grep 'Exited' | awk '{print $1}' | xargs docker stop | xargs docker rm
# 删除none的镜像
$ docker images | grep '<none>' | awk '{print $3}' | xargs docker rmi

docker pull [name]获取镜像

docker images 显示Docker镜像列表

docker inspect [镜像ID]获取镜像的详细信息

docker search [关键词]查找关键词镜像列表

docker ps -a 查看Docker后台进程

docker rmi [镜像标签/镜像ID]删除镜像

docker cp [file] [容器ID]:/etc/复制文件到容器指定位置

docker rm [容器ID]删除容器

docker commit -m "description..." -a "author" [容器ID] [New id]基于已有容器创建新的镜像

docker run -it ubuntu /bin/bash使用镜像创建一个容器,并在其中运行bash应用(-t 分配一个伪终端,-i 让容器标准输入保持打开)

docker create -it [镜像]新建一个容器

docker start [容器ID]运行处于终止状态的容器

docker run -d ubuntu [命令]后台运行容器

docker logs [容器ID]查看容器输出信息

docker stop [-t|--time[=10]] [容器ID]终止容器,默认等待10s

docker kill [容器ID]直接强制终止容器

docker ps -a -q查看处于终止状态的容器

docker restart [容器ID]重启一个容器

docker exec -ti [容器ID] /bin/bash进入到创建容器中运行交互命令

docker save -o name.tar ubuntu:14.04存出镜像到本地为name.tar

docker load --input name.tar导入镜像存储文件到本地镜像库

docker export [容器ID] > name.tar导出停止或运行中的容器到文件中去

cat name.tar | sudo docker import - test/ubuntu:v1.0导入容器导出的文件成为镜像

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。