一文学会Docker使用

首发地址:我的博客

image

前言

Docker我以前学过,但是太久没用,忘得差不多了。。。这几天准备把写好的Django应用通过Docker部署到服务器,所以重新复习了Docker,于是写了此文,希望对想使用Docker的你有所帮助。

初识Docker

Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

Docker 的整个生命周期由三部分组成:镜像(image)+ 容器(container)+ 仓库(repository)

镜像是一个只读的模板,它包括了运行容器所需的数据。镜像可以包含一个完整的 Linux 操作环境,里面仅安装了 Python 或者其他用户需要的程序。

容器是由镜像创建出来的实例,类似虚拟机,里面可以运行特定的应用,并且容器与容器是相互隔离的。

仓库概念与 Git 和 Github 类似,如果你用过它们就非常容易理解。Docker 使用的默认仓库是由官方维护的 Docker hub 公共仓库,从中上传、拉取的操作类似 Git。

安装Docker

$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun

检验Docker是否安装成功

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
......
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
......
Hello from Docker!
This message shows that your installation appears to be working correctly.
......

官方文档

Docker命令

查看本地已有镜像

$ docker images

REPOSITORY      TAG        IMAGE ID           CREATED           SIZE
hello-world     latest     fce289e99eb9       9 months ago      1.84kB

# 镜像名           版本        ID 号             创建时间           大小

查看本地已有的容器

$ docker ps -a

删除镜像

$ docker rmi [images ID]  

删除容器

$ docker container rm [container ID]  

停止容器

$ docker container stop [container ID] 

启动容器

$ docker container start [container ID]  

Dockerfile

Docker 允许通过文本格式的配置文件来构建镜像,默认名称为 Dockerfile

Dockerfile 的组成部分

部分 命令
基础镜像信息 FROM
维护者信息 MAINTAINER
镜像操作指令 RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME等
容器启动时执行指令 CMD、ENTRYPOINT

FROM:指定基础镜像

FROM <image>                       # 指定基础镜像

FROM <image>:<tag>                 # 指定一个tag版本的基础镜像

例如:FROM ubuntu:18.04

MAINTAINER:声明作者

MAINTAINER [name] [email]

例如 MAINTAINER jwt "jianwentaook@163.com"

RUN:执行命令

RUN <command> 
# shell模式,以#/bin/sh -c command 形式执行, 如RUN echo hello                                                                                 
RUN ["executable", "param1", "param2" ... ] 
# exec模式,指定其他形式的shell来运行指令 ,如RUN ["/bin/bash" ,“-c”,“echo  hello" ]

例如:RUN apt-get update && mkdir /code  

COPY:复制文件\目录

COPY <src> <dest>

例如:COPY index.html /test/

ADD:高级复制文件

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

例如:ADD index.html /var/www/html
例如:ADD /var/share/1.txt /var/www/html

ENV:设置环境变量

ENV <key> <value>
ENV <key>=<value> ...

例如:ENV JAVA_HOME /usr/local/jdk1.8.0_45
例如:ENV PYTHONUNBUFFERED 1

VOLUME:定义匿名卷

VOLUME ["/data"]

例如:VOLUME /myvol
例如:VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

EXPOSE:暴露端口

EXPOSE <port> [<port>/<protocol>...]

例如:EXPOSE 80 443
例如:EXPOSE 80/tcp

WORKDIR:指定工作目录

WORKDIR /path

例如:WORKDIR /data

USER:指定当前用户

USER <user>[:<group>]
USER <UID>[:<GID>]

例如:USER jwt

CMD:容器启动命令

CMD ["executable","param1","param2"] 
CMD ["param1","param2"] 
CMD command param1 param2 

例如:CMD ["/usr/bin/wc","--help"]
例如:CMD echo "This is a test." | wc -

ENTRYPOINT:入口点

ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

例如:ENTRYPOINT ["top", "-b"]
例如:ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

实例

# 从仓库拉取 带有 python 3.7 的 Linux 环境
FROM python:3.7

# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1

# 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code
WORKDIR /code
# 更新 pip
RUN pip install pip -U
# 将 requirements.txt 复制到容器的 code 目录
ADD requirements.txt /code/
# 安装库
RUN pip install -r requirements.txt
# 将当前目录复制到容器的 code 目录
ADD . /code/

Docker compose

在线上环境中,通常不会将项目的所有组件放到同一个容器中;更好的做法是把每个独立的功能装进单独的容器,这样方便复用。比如将 Django 代码放到容器A,将 Mysql 数据库放到容器B,以此类推。

因此同一个服务器上有可能会运行着多个容器,如果每次都靠一条条指令去启动,未免也太繁琐了。 Docker-compose 就是解决这个问题的,它用来编排多个容器,将启动容器的命令统一写到 docker-compose.yml 文件中,以后每次启动这一组容器时,只需要 docker-compose up 就可以了。

Ubantu安装Docker compose

官方文档 | 查看最新版本

根据新版本的变化自行调整下面命令中的版本来安装:

# 下载docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 给docker-compose执行权限
$ chmod +x /usr/local/bin/docker-compose

# 查看docker compose版本,测试是否安装成功
$ docker-compose  version
docker-compose version 1.25.5, build 8a1c60f6

Docker compose

在线上环境中,通常不会将项目的所有组件放到同一个容器中;更好的做法是把每个独立的功能装进单独的容器,这样方便复用。比如将 Django 代码放到容器A,将 Mysql 数据库放到容器B,以此类推。

因此同一个服务器上有可能会运行着多个容器,如果每次都靠一条条指令去启动,未免也太繁琐了。 Docker-compose 就是解决这个问题的,它用来编排多个容器,将启动容器的命令统一写到 docker-compose.yml 文件中,以后每次启动这一组容器时,只需要 docker-compose up 就可以了。

Ubantu安装Docker compose

官方文档 | 查看最新版本

根据新版本的变化自行调整下面命令中的版本来安装:

# 下载docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 给docker-compose执行权限
$ chmod +x /usr/local/bin/docker-compose

# 查看docker compose版本,测试是否安装成功
$ docker-compose  version
docker-compose version 1.25.5, build 8a1c60f6

Docker compose命令

启动容器服务

$ docker-compose up

#Ctrl + C 即可停止开发服务器运行

删除容器

停止服务器后实际上容器还存在,只是停止运行了而已,输入下面命令可以删除容器

$ docker-compose down

后台运行容器

$ docker-compose up -d

重新构建镜像

$ docker-compose build

启动和停止已有的容器:

$ docker-compose start
$ docker-compose stop

查看容器日志

$ docker-compose logs

实例

在项目根目录创建 docker-compose.yml 并写入:

version: "3"
services:
  app:
    restart: always
    build: .  # '点'代表当前目录
    command: "python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"

让我们来分解一下其中的各项含义。

version 代表 docker-compose.yml 的版本,目前最新版为 3,不需要改动它。

接着定义了一个名叫 app 的容器。后面的内容都是 app 容器的相关配置:

  • restart :除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
  • build :指定一个包含 Dockerfile 的路径,并通过此 Dockerfile 来构建容器镜像。注意那个 "." ,代表当前目录。
  • command :容器运行时需要执行的命令。这里就是我们很熟悉的运行开发服务器了。
  • volumes卷,这是个很重要的概念。前面说过容器是和宿主机完全隔离的,但是有些时候又需要将其连通;比如我们开发的 Django 项目代码常常会更新,并且更新时还依赖如 Git 之类的程序,在容器里操作就显得不太方便。所以就有,它定义了宿主机和容器之间的映射:"." 表示宿主机的当前目录,":" 为分隔符,"/code" 表示容器中的目录。即宿主机当前目录和容器的 /code 目录是连通的,宿主机当前目录的 Django 代码更新时,容器中的 /code 目录中的代码也相应的更新了。这有点儿像是在容器上打了一个洞,某种程度上也是实用性隔离性的一种妥协。

严格意义上讲,这里用到的 .:/code 并不是,而是叫挂载,它两是有区别的,只不过 docker-compose 允许将挂载写到卷的配置中。后面章节会讲到。

  • ports :定义了宿主机和容器的端口映射。容器的隔离不止环境,甚至连端口都隔离起来了。但 web 应用不通过端口跟外界通信当然不行,因此这里定义将宿主机的 8000 端口映射到容器的 8000 端口,即访问宿主机的 8000 端口就是访问到了容器的 8000 端口,但要确保端口没有被其他程序占用。

Docker 可视化

Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。

项目地址:https://github.com/portainer/portainer

官方文档:https://www.portainer.io/documentation/

安装

# 拉取镜像
docker pull portainer/portainer

# 一键部署
docker volume create portainer_data
docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

使用

浏览器访问9000端口即可进入到Portainer界面,首次打开需要设置密码

若无法访问,请到云服务器控制台,开启9000端口

image

单机版本选择Local,点击Connect即可连接到本地docker

image

登录后我们可以查看服务器上各个镜像、容器、网络、Volume 等信息,并可以对它们进行管理。

image

image

在页面上就可以直接进行容器的创建、启动、停止、删除等操作

image

可查看容器详细信息,还可查看 log 日志,甚至进入容器执行命令。

image

创建一个容器

Containers 页面中,点击右上角的“Add container” 按钮。

接着填写好容器名、镜像名、端口映射等相关信息后,点击下方的“Deploy the container” 后便会开始自动拉取镜像启动容器。

参考:Portainer - Docker的可视化管理工具使用详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268