史上最全面的Docker容器引擎使用教程

Docker 是一个开源的应用容器引擎,基于 Go 语言] 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

Docker有免费的CE社区版和收费的EE企业版,本文安装的是CE版本。

1.Docker安装

1.1 检查

Docker 要求 CentOS 系统的内核版本高于 3.10 ,可以通过 uname -r 命令查看你当前的内核版本。

1136672-20181109163354835-2006645290.png

如果CentOS版本是7以上并且为64位,那是完全没用问题的。

1.2 安装

安装一些必要系统工具:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

添加软件源信息:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新 yum 缓存:

sudo yum makecache fast

安装 Docker-ce:

sudo yum -y install docker-ce

启动 Docker 后台服务

sudo systemctl start docker

测试运行 hello-world

docker run hello-world

1136672-20181109163422707-515647806.png

由于本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并在容器内运行。

1.3 镜像加速

例如在使用Maven时我们一般会配置阿里云国内镜像加速,在使用Docker时也是如此。我使用的是网易的镜像地址:http://hub-mirror.c.163.com

新版的 Docker 使用 /etc/docker/daemon.json(Linux) 或者 %programdata%\docker\config\daemon.json(Windows) 来配置 Daemon。

请在该配置文件中加入(没有该文件的话,请先建一个):

{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

一定要重启docker服务,如果重启docker后无法加速,可以重新启动OS。

动作指令
概要docker info
启动systemctl start docker
停止systemctl stop docker
重启systemctl restart docker
查看状态systemctl status docker
开机启动systemctl enable docker

1.4 卸载Docker

执行以下命令来删除 Docker CE:

$ sudo yum remove docker-ce
$ sudo rm -rf /var/lib/docker

2.实战Nginx

2.1 查找Docker Hub上的 nginx 镜像
docker search nginx

1136672-20181109164636988-857183543.png

2.2 拉取官方镜像
docker pull nginx
2.3 拉取成功查看本地镜像
docker images nginx

1136672-20181109164654747-317102454.png

2.4 启动Nginx服务器
docker run -p 8080:80 -d nginx
  • -p 8080:80:将本机8080端口映射到Nginx容器的80端口
  • -d:后台启动
2.5 查看Docker当前运行
docker ps

1136672-20181109164706814-497093080.png

2.6 访问测试

1136672-20181109164724953-828773730.png

2.7 拷贝本地文件到容器内

把当前目录下的index.html文件拷贝到容器内,替换Nginx的默认首页。

docker cp index.html dbfc48660aeb://usr/share/nginx/html

dbfc48660aeb是容器内Nginx运行的ID,/usr/share/nginx/html是容器内Nginx的首页默认路径。

1136672-20181109164738521-505644965.png

再次访问浏览器,可以看到首页已经更换为我们自定义的文件内容。

1136672-20181109164754562-76294129.png

2.8 停止Docker容器
docker stop ID

1136672-20181109164805585-25204686.png

刷新浏览器,访问提示无法连接。

2.9 保存容器内更改

再次运行Nginx容器,访问首页,发现更改的首页又复原了。如图:

1136672-20181109170428011-1994394047.png

这是因为在更改后没有提交保存导致的。也就是需要下面这句命令:

docker commit -m 'fun' aaef9a68525a nginx-fun
  • -a ' author':作者名
  • -m 'fun':是说明文字;
  • aaef9a68525a:容器ID,通过ps命令获取;
  • nginx-fun:新生成的image镜像名称;

然后查看现有镜像:

1136672-20181109170440671-632069169.png

发现新生成了一个nginx-fun镜像。

2.10 删除容器

虽然有些容器已经停止了,但是还存有信息,可以通过docker ps -a查看,再通过docker rm [CONTAINER ID]删除。

1136672-20181109170501621-242637554.png

3.Docker命令小结

命令用途
docker pull获取image
docker build创建image
docker images列出image
docker run运行container
docker ps列出container
docker rm删除container
docker rmi删除image
docker cp在host和container之间拷贝文件
docker commit保存改动为新的image

4.DockerFile创建镜像

创建文件Dockerfile文件,该文件名不可更改

vi Dockerfile

写入文本

FROM alpine:latest
MAINTAINER smilevt
CMD echo "Hello Docker!"

保存退出

docker build命令用于使用 Dockerfile 创建镜像,

docker build -t hello_docker .
  • -t : 镜像的名字及标签,通常 name:tag 或者 name
  • path : .点代表当前路径下的所有文件。

运行结果:

1136672-20181109170518224-685965483.png

查看是否成功创建镜像并运行

1136672-20181109170530393-1152999440.png

4.1 Dockerfile构建SpringBoot镜像

将Spring Boot应用打包为Docker镜像是非常简单的,下面介绍一种比较原生的方式。

1.比如我们有一个Spring Boot Web应用,我们将它在本地打包为Jar,并拷贝到一台装有Docker的机器上。

2.在Jar包(docker-demo-0.0.1-SNAPSHOT.jar)所在目录下新建Dockerfile文件,文件内容为:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD docker-demo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

3.执行docker build命令打包为镜像

docker build -t spring-boot-demo:tag .

4.运行刚刚打包的镜像

docker run -p 8080:8080 spring-boot-demo:tag

5.访问你的应用,OK。

延伸阅读:

使用Maven插件构建Spring Boot应用程序镜像

5.Dockerfile安装Nginx

再次新建文件夹并新建Dockerfile文件,写入以下内容;

FROM ubuntu
MAINTAINER anthor
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y nginx
COPY index.html /var/www/html
ENTRYPOINT ["usr/sbin/nginx", "-g", "daemon off;"]
EXPOSE 80

简单说一下文本含义:从(FROM)ubuntu容器中运行(RUN)3条命令,第一条是修改archive.ubuntu.com为mirrors.ustc.edu.cn国内镜像,第二、三条是安装nginx,然后复制(COPY)index.html到容器内,提供容器进入点(ENTRYPOINT),使nginx在前台运行,之所以使用数组是为了隔开命令,最后暴露80端口。

接下来新建index.html文件,执行build命令创建镜像:

docker build -t hello-nginx:tag .

1136672-20181109170542927-582481528.png

使用run命令启动该hello-nginx容器:

docker run -p 8080:80 -d hello-nginx:tag

测试访问host:8080端口如下:

1136672-20181109170553896-2048933428.png

可以看到,Nginx成功启动,并输出自定义的index.html。

6.Dockerfile命令小结

指令说明
FROM设置镜像使用的基础镜像
MAINTAINER设置镜像的作者
RUN编译镜像时运行的脚本
CMD设置容器的启动命令
LABEL设置镜像的标签
EXPOSE设置镜像暴露的端口
ENV设置容器的环境变量
ADD编译镜像时复制文件到镜像中
COPY编译镜像时复制文件到镜像中
ENTRYPOINT设置容器的入口程序
VOLUME设置容器的挂载卷
USER设置运行RUN CMD ENTRYPOINT的用户名
WORKDIR设置RUN CMD ENTRYPOINT COPY ADD指令的工作目录
ARG设置编译镜像时加入的参数
ONBUILD设置镜像的ONBUILD指令
STOPSIGNAL设置容器的退出信号量

6.1 Dockerfile文件中的CMD和ENTRYPOINT指令差异对比

CMD指令和ENTRYPOINT指令的作用都是为镜像指定容器启动后的命令,那么它们两者之间有什么各自的优点呢?为了更好地对比CMD指令和ENTRYPOINT指令的差异,我们这里再列一下这两个指令的说明,

CMD

支持三种格式

CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式; 

CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;

CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

ENTRYPOINT

两种格式:

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

ENTRYPOINT command param1 param2(shell中执行)。

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

从上面的说明,我们可以看到有两个共同点:

  1. 都可以指定shell或exec函数调用的方式执行命令;
  2. 当存在多个CMD指令或ENTRYPOINT指令时,只有最后一个生效;

而它们有如下差异:
差异1:CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。

差异2:CMD指令可以为ENTRYPOINT指令设置默认参数,而且可以被docker run指定的参数覆盖;

详细参考:Dockerfile中ENTRYPOINT和CMD的区别

7.镜像分层

Dockerfile的每一行都会产生一个新层(新ID),比如:

1136672-20181109170605682-25945278.png

已经存在image里面的层是只读的,一旦镜像运行为容器之后,就会产生一个新层(RW读写),分层的好处就是多个image可以共享相同的层,减少存储大小。

8.Volume

我们知道,Docker容器中的改动是不会被保存的,为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。 比如在使用数据库时就可以使用Volume。

9.Volume操作

说白了,Volume只是-v参数而已。容器和宿主机目录挂载的三种方式:

1.第一种方式

运行Nginx容器,-d:后台运行,--name:指定名称nginx,-v /usr/share/nginx/html:运行容器内部用来访问网页的地址,最后的nginx是镜像名。

docker run -d --name nginx -v /usr/share/nginx/html nginx

获取容器/镜像的元数据

docker inspect nginx

可以看到宿主机目录Source和容器内目录Destination:

1136672-20181109170619897-239252455.png

继续查看宿本机目录:

1136672-20181109170628968-1749859828.png

注意:如果是mac,则该路径不是mac上的实际路径,因为mac上运行docker是还有一层虚拟层,这是docker虚拟层中的路径,可以在docker中访问到

2.第二种方式

在启动Nginx容器时使用-v参数挂载本地目录到容器目录

docker run -p 8080:80 --name mynginx -v $PWD:/usr/share/nginx/html -d nginx

这句命令使用PWD环境变量(该变量始终指向当前目录)将当前目录挂载到容器/usr/share/nginx/html目录。

我们访问主机8080端口

1136672-20181109171526331-440909704.png

报错403,因为当前目录啥也没有,没有index.html文件。在当前目录新建该html文件,输入hello,访问网页

1136672-20181109171537528-1021318797.png

3.第三种方式

使用 docker create 创建一个新的容器但不启动它:

docker create -v $PWD/data:/var/mydata --name data_container ubuntu
  • 宿主机目录:$PWD/data

  • docker目录:/var/mydata

  • 容器名:data_container

  • 基础镜像:ubuntu

启动 ubuntu 容器镜像(默认ubuntu基础镜像没有服务):

docker run -it --volumes-from data_container ubuntu /bin/bash
  • -it: 以交互模式运行容器,并为容器重新分配一个伪输入终端
  • --volumes-from data_container:以另外一个容器挂载
  • 最后在容器内执行/bin/bash命令

进入到容器控制台后输入mount,查看挂载:

1136672-20181109171550599-2139311251.png

我们在/var/mydata目录下新建whatever.txt文件后退出,进入data目录查看,可以看到刚刚新建的txt文件。

10.Registry介绍

Registry 是镜像仓库,我们可以从镜像仓库中拉取一些镜像到本地,也可以提交镜像到仓库。

一些术语:

ENGLISH中文
host宿主机
image镜像
container容器
registry仓库
daemon守护程序
client客户端

与registry仓库的交互:

查找镜像

docker search whalesay

拖取镜像

docker pull whalesay

推送镜像

docker push myname/whalesay

国内的docker镜像仓库:

daoclou

时速云

aliyun

11.Registry实战

1.查找镜像

1136672-20181109171602333-120220569.png

STARS可以理解为点赞数,默认是按照这个排序的。

2.拉取镜像

1136672-20181109171700484-1882305245.png

3.查看镜像

1136672-20181109171720756-2053037245.png

可以看到,REPOSITORY是镜像名,TAG是默认的latest,正常情况是版本号,这两个比较重要。

CREATED是创建时间,SIZE是占用空间的大小。

4.运行镜像

1136672-20181109171734989-1317741126.png

5.标记镜像

使用docker tag命令标记本地镜像,将其归入某一仓库。

docker tag docker/whalesay myhaleasy:tag

1136672-20181109171750206-189704523.png

6.上传镜像

可以使用docker push命令上传本地镜像到仓库,但是需要注册登录。

1136672-20181109171800398-195891752.png

注册登录地址:https://hub.docker.com

执行登录命令,输入用户名与密码即可。

docker login

1136672-20181109171811910-1952141407.png

上传镜像前还需要在Docker官网个人中心创建该镜像。

docker push到私有仓库

12.Compose多容器应用

Compose 是一个用户定义和运行多个容器的 Docker 应用程序。在 Compose 中你可以使用 YAML 文件来配置你的应用服务。然后,只需要一个简单的命令,就可以创建并启动你配置的所有服务。

docker-compose 安装

1.Mac/Windows:

​ 安装docker的时候附带安装了。

2.Linux:

curl https://github.com/docker/compose

Linux安装

执行命令

curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose

该命令会下载文件到(>)/usr/local/bin/docker-compose,在下载地址中使用$(uname -s)是获取 unmae -s 命令的输出加到路径中。

下载完成后,可以设置该目录的权限为777,意为所有人都可以读写该目录,最后使用 docker-compose --version 检查是否安装成功。

1136672-20181109171827760-12376734.png

13.Compose搭建博客网站

接下来我们使用docker-compose搭建一个含nginx+ghost+db的博客网站。

1.准备

首先创建如下目录结构:

ghost
  - ghost
    - Dockfile
    - config.js
  - nginx
      - nginx.conf
      - Dockfile
  - data
  - docker-compose.yml

每个文件的具体内容有:

  • ghost/ghost/Dockfile

过时的配置(不使用)

FROM ghost
COPY ./config.js /var/lib/ghost/config.js
EXPOSE 2368
CMD ["npm","start","--production"]

最新版的官方镜像, 把配置文件改到/var/lib/ghost/content/ ,然后注释掉了 CMD["npm","start","--production"] 即可。

FROM ghost
COPY ./config.js /var/lib/ghost/content/ 
EXPOSE 2368
  • ghost/ghost/config.js
var path = require('path'),
    config;

config = {
    production: {
        url: 'http://mytestblog.com',
        mail: {},
        database: {
            client: 'mysql',
            connection: {
                host: 'db',
                user: 'ghost',
                password: 'ghost',
                database: 'ghost',
                port: '3306',
                charset: 'utf8'
            },
            debug: false
        },
        paths: {
            contentPath: path.join(process.env.GHOST_CONTENT, '/')
        },
        server: {
            host: '0.0.0.0',
            port: '2368'
        }
    }
};

module.exports = config;
  • ghost/nginx/Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
  • ghost/nginx/nginx.conf
worker_processes 4;
events {worker_connections 1024;}
http {
    server {
        listen 80;
        location / {
            proxy_pass http://ghost-app:2368;
        }
    }
}
  • ghost/docker-compose.yml
version: '2'

networks:
  ghost:
services:
  ghost-app:
    build: ghost
    networks:
      - ghost
    depends_on:
      - db
    ports:
      - "2368:2368"

  nginx:
    build: nginx
    networks:
      - ghost
    depends_on:
      - ghost-app
    ports:
      - "80:80"

  db:
    image: "mysql:5.7.15"
    networks:
      - ghost
    environment:
      MYSQL_ROOT_PASSWORD: mysqlroot
      MYSQL_USER: ghost
      MYSQL_PASSWORD: ghost
    volumes:
      - $PWD/data:/var/lib/mysql
    ports:
      - "3306:3306"

此处数据库相关的配置要和config.js中的配置(user、password)保持一致。

一旦我们为一个服务指定了一个名字(db),它就可以被其它服务所解析。

nginx 中proxy_pass 设置成 http://ghost-app:2368 也是因为在docker-compose.yml 指定了服务是ghost-app。

2.启动

将所有容器启动,并以daemon的方式后台运行。第一次不需要build,因为会自动创建镜像。

docke-compose up -d

3.查看应用

docker-compose ps

1136672-20181109171846207-664031067.png

因为文件内容输入有误,导致启动未成功,修改文件后还需要停止、删除掉容器再重新构建才行。

4.停止(+)

停止所有容器

docker-compose stop

5.删除(+)

删除时需要输入y手动确认

docker-compose rm

6.构建(+)

非首次运行就需要手动创建镜像了

docker-compose build

最后,在ghost目录下再次启动!

1136672-20181109171859158-1469377436.png

7.测试

访问域名进入搭建的博客网站,可以注册账号发布博客。

`
1136672-20181109172021409-613171506.png

关于ghost的使用这里不做过多介绍。

14.docker-compose.yml常用命令

命令用途
build本地创建镜像
command覆盖缺省命令
depends_on连接容器
ports暴露端口
volumes
imagepull镜像
up启动服务
stop停止服务
rm删除服务中的各个容器
logs观察各个容器的日志
ps列出服务相关的容器

6.Docker资源链接

Docker官方英文资源

docker官网:http://www.docker.com

Docker中文资源

Docker中文网站:https://www.docker-cn.com/

Docker安装手册:https://docs.docker-cn.com/engine/installation/

Docker核心概念(镜像、容器、仓库)及基本操作

Docker 国内镜像

网易加速器:http://hub-mirror.c.163.com

官方中国加速器:https://registry.docker-cn.com

ustc的镜像:https://docker.mirrors.ustc.edu.cn

daocloud:https://www.daocloud.io/mirror#accelerator-doc(注册后使用

转载于:https://www.cnblogs.com/yueshutong/p/9936220.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值