Docker 简介

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。Docker 是一个重新定义了程序开发测试、交付和部署过程的开放平台,Docker 则可以称为构建一次,到处运行,这就是 Docker 提出的”Build once,Run anywhere”。

首先,需要了解一下几个概念:镜像容器仓库

  • 镜像(Image):Docker 镜像就是一个只读的模板,镜像可以用来创建 Docker 容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。镜像是一种文件结构。Dockerfile 中的每条命令都会在文件系统中创建一个新的层次结构,文件系统在这些层次上构建起来,镜像就构建于这些联合的文件系统之上。
  • 容器(Container):容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境,Docker 利用容器来运行应用。
  • 仓库(Registry):仓库是集中存放镜像文件的场所,仓库注册服务器(Registry)上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。目前,最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。

Docker 安装

docker 只能运行在 linux 环境,windows 下是没办法直接运行 docker 的,所以如果要在 windows 下跑 docker 需要安装 linux 虚拟机环境。

Win10 专业版安装

1. 启用 Hyper-V

打开控制面板 - 程序和功能 - 启用或关闭 Windows 功能,勾选 Hyper-V,然后点击确定即可,如图:

点击确定后,启用完毕会提示重启系统,我们可以稍后再重启。

2. 安装 Docker

Docker 下载地址为:https://store.docker.com/editions/community/docker-ce-desktop-windows 点击如图处即可下载安装包:

下载完成后运行安装包,安装完成后界面如图:

单击 Close and log out,这个时候我们重启一次电脑。

3. 启动 Docker

在桌面找到 Docker for Windows 快捷方式,双击启动即可!启动成功后托盘处会有一个小鲸鱼的图标。打开命令行输入命令:docker version 可以查看当前 docker 版本号,如图:

更换镜像源地址,中国官方镜像源地址为:https://registry.docker-cn.com,点击托盘处 docker 图标右键选择 - Settings,然后修改如下:

点击 Apply 后会重启 Docker。

载入测试镜像测试,输入命名 docker run hello-world 可以加载测试镜像来测试。如图:

Win10 家庭版安装

由于 win10 家庭版,没有自带 Hyper-V 功能,所以我们要采用另外一种方式安装:

下载 docker-toolbox 直接安装

下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/

双击下载好的程序:

注意:安装路径千万不要有中文!

对最后一项打上钩,安装虚拟机环境 VirtualBox

注意:如果安装完成后,运行提示找不到 boot2docker.iso 镜像

将 toolbox 安装目录下的 boot2docker.iso 拷贝到这个目录 C:\Users\xxx\.docker\machine\cache

设置 windows 目录共享

采用 docker-toolbox 安装的 docker,实际上是启用的 docker-machine 作为宿主机,docker 是在该宿主机上启动的容器。需要先让该宿主机和 windows 实现目录共享。

查看虚拟器 ip:

Code
1
docker-machine ip

进入虚拟机:
Code
1
docker-machine ssh [default]

设置国内镜像源

  1. 打开终端执行命令:docker-machine ssh
  2. 修改配置文件:sudo vi /var/lib/boot2docker/profile--label provider=virtualbox 的下一行添加:
    --registry-mirror https://xxx.mirror.aliyuncs.com
  3. 重启 docker:docker-machine restart

Linux 安装

使用 yum 进行安装

1. 首先安装依赖项

bash
1
yum install -y yum-utils \  device-mapper-persistent-data \  lvm2

2. 添加软件镜像源

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

3. 安装 docker-ce

bash
1
sudo yum install docker-ce docker-ce-cli containerd.io

4. 启动 docker 服务

bash
1
systemctl start docker

设置国内镜像源

/etc/docker/daemon.json 中添加:

json
1
2
3
4
{
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com`"]
}

重启 docker 服务

bash
1
systemctl restart docker

检查是否配置成功
bash
1
2
3
4
docker info|grep Mirrors -A 1
#输出
#Registry Mirrors:
# https://xxx.mirror.aliyuncs.com/

配置个人阿里云镜像源地址

访问 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
点击镜像加速器查看地址:

实例:搭建 ElasticSearch 环境

安装 ElasticSearch

查看镜像版本

有 2 种方式可以查看要安装的软件有没有 docker 版本:

  1. 通过 docker 仓库官网搜索镜像 https://hub.docker.com/
  2. 通过命令搜索
    bash
    1
    docker search elasticsearch

拉取镜像

bash
1
docker pull elasticsearch:7.6.1

如果不加版本号,默认选择最新版本

启动容器

bash
1
docker run --name es -d -v /es/data:/usr/share/elasticsearch/data -v /es/logs:/usr/share/elasticsearch/logs -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node"  elasticsearch:7.6.1

注意:

9200 是供 http 访问端口,9300 是供 tcp 访问的端口,如果不做端口映射,浏览器就不能访问 elasticsearch 的服务。

如果需要实现数据持久化的话,可以在启动时通过 -v 参数将 docker host 上的目录 mount 到 Elasticsearch 容器里。其中 /es/data/es/logs 是宿主机的目录地址。

安装 Elasticsearch-Head

安装

bash
1
2
docker pull mobz/elasticsearch-head:5
docker run --name es-head -d -p 9100:9100 mobz/elasticsearch-head:5

修改 head 插件的跨域访问问题

  1. 进入 elasticsearch 容器,打开 elasticsearch.yml

    bash
    1
    2
    3
    4
    docker ps -a   #拿到运行容器elasticsearch的id
    docker exec -it ******(容器id) /bin/bash
    cd ./config
    vim elasticsearch.yml
  2. elasticsearch.yml 中添加:

    yaml
    1
    2
    http.cors.enabled: true
    http.cors.allow-origin: "*"
  3. 重启 elasticsearch 容器

    bash
    1
    docker restart  es

提交报 application/x-www-form-urlencoded 不允许的错误

  1. 进入 head 容器后,查找文件 vendor.js

    Code
    1
    find . -name vendor.js  # /usr/src/app/_site/vendor.js
  2. 将文件拷贝到宿主机器:

    bash
    1
    docker cp 11cc:/usr/src/app/_site/vendor.js vendor.js
  3. 修改文件 vendor.js,修改第 6886 行内容:contentType:”application/x-www-form-urlencoded”, 改成 contentType:”application/json”,

  4. 重启 head 服务:

    bash
    1
    docker restart  es-head

Docker 启动参数

docker run 最常用的 3 个参数:

Options Mean
-i 以交互模式运行容器,通常与 -t 同时使用
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-d 后台运行容器,并返回容器 ID

其他参数:

Options Mean
-a stdin 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项
-P 随机端口映射,容器内部端口随机映射到主机的高端口
-p 指定端口映射,格式为:主机 (宿主) 端口:容器端口
–name=“nginx-lb” 为容器指定一个名称
–dns 8.8.8.8 指定容器使用的 DNS 服务器,默认和宿主一致
–dns-search example.com 指定容器 DNS 搜索域名,默认和宿主一致
-h “mars” 指定容器的 hostname
-e username=“ritchie” 设置环境变量
–env-file=[] 从指定文件读入环境变量
–cpuset=“0-2” or —cpuset=“0,1,2” 绑定容器到指定 CPU 运行
-m 设置容器使用内存最大值
–net=“bridge” 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型
–link=[] 添加链接到另一个容器
–expose=[] 开放一个端口或一组端口
–volume , -v 绑定一个卷

生成自定义镜像

生成镜像

找到要发布的文件夹 publish,在和 publish 同一级下,创建 dockerfile 文件,内容如下:

dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
FROM microsoft/dotnet:2.2-aspnetcore-runtime

MAINTAINER xiaoj@mail.taiji.com.cn

RUN mkdir /home/UserBehaviorAPI

COPY ./publish/ /home/UserBehaviorAPI

WORKDIR /home/UserBehaviorAPI

EXPOSE 8090

CMD [ "dotnet","UserBehaviorAPI.dll" ]

dockerfile 指令介绍:

  • FROM

    指定定制镜像的基础镜像

  • MAINTAINER

    镜像的作者信息,只是起标识作用

  • RUN

    在 docker build 过程中执行的命令

  • COPY

    复制指令,从上下文目录中复制文件或者目录到容器里指定路径

  • WORKDIR

    指定的工作目录,必须是提前创建好的

  • EXPOSE

    声明镜像的开放端口,多个连续端口号 EXPOSE 12300-22300

  • CMD

    类似于 RUN 指令,用于运行程序,不同之处是在 docker run 时执行

生成镜像执行命令:

bash
1
docker build -t yourimagename:1.0.0 . #最后的.表示当前目录,默认使用dockerfile文件名,也可指定其他文件名

将镜像导出到文件

bash
1
docker save -o userbehaviorapi.tar userbehaviorapi

部署到服务器

将 userbehaviorapi.tar 拷贝到服务器
导入镜像

bash
1
docker load --input xxx.tar       或       docker load < xxx.tar

查看所有镜像看是否导入成功
bash
1
docker images ls

常用操作

设置容器开机重启

1. 创建容器的时候,使用 --restart=always 参数

bash
1
docker run -d -p 8180:8180 --restart=always --name xxl-job-admin-docker xxl-job-admin-docker

—restart 具体参数值详细信息:

  • no - 容器退出时,不重启容器;
  • on-failure - 只有在非 0 状态退出时才从新启动容器;
  • always - 无论退出状态是如何,都重启容器;

2. 非创建时,通过 update 命令

bash
1
docker update --restart=always 4d3af8cc566d

设置容器时区和宿主机一致

有的 docker 镜像内置的是 UTC 标准时间,需将时区调整为 UTC + (+0800),可以直接将宿主机配置拷贝到容器中

bash
1
docker cp /etc/localtime <container_id>:/etc/

为已创建的容器添加端口映射

方法一

1. 获取容器 ip 地址

bash
1
docker inspect `container_name` | grep IPAddress

2. 设置 iptable 转发端口,将容器的 8000 端口映射到 docker 主机的 8001 端口

bash
1
iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

方法二

1. 停止所有容器
停止容器会覆盖配置,所以先停止容器后再修改

2. 停止 docker 服务

bash
1
sudo systemctl stop docker #或者sudo /etc/init.d/docker stop

3. 修改 hostconfig.json

bash
1
vim /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

找到这个 PortBindings 值。在这个 json 集合里边追加新端口

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
],
"8888/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}
]
}

其中 80/tcp 对应的是容器内部的 80 端口,HostPort 对应的是映射到宿主机的端口 8080

4. 修改 config.v2.json

bash
1
vim /var/lib/docker/containers/[hash_of_the_container]/config.v2.json

config.v2.json 文件里边修改值 : config->ExposedPorts 和 networsettings->Ports

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"Config": {
....
"ExposedPorts": {
"80/tcp": {},
"8888/tcp": {}
},
....
},
"NetworkSettings": {
....
"Ports": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],

另:如果 config.v2.json 里面没有 ExposedPorts,在 config.v2.json 里面添加一个配置项 “ExposedPorts”:{“80/tcp”:{}} , 将这个配置项添加到 “Tty”: true, 前面。

5. 重启 docker 的守护进程

bash
1
service docker restart

查看配置项是否已经修改成功

bash
1
docker inspect 容器名

docker 访问宿主机

有时 docker 是需要访问宿主机的,那么在 docker 中宿主机的 ip 是多少呢?

在宿主机执行 ifconfig,会看到 docker0 那个 ip,docker 中可以使用这个 ip 地址来访问宿主机。