docker是一个开源的应用容器引擎,开发者可以打包自己的应用到容器里面,然后迁移到其他机器的docker应用中,可以实现快速部署。如果出现的故障,可以通过镜像,快速恢复服务
优势
- 更快的启动时间:Docker容器启动是几秒钟的事情,因为容器只是一个操作系统进程而已;而虚拟机则需要几分钟来加载
- 更快部署:不需要建立一个新的环境,只需要下载Docker镜像并在不同的服务器上运行
- 一致的运行环境:Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,减少了开发过程中的bug。同时保证了在迁移过程中不会出现运行环境的变化导致应用无法正常运行的情况
- 维护和扩展:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单
-
更高效的利用系统资源:docker不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效
优化
docker pull 拉去镜像对速度实在太慢了,因此我们可以更换docker源
#编辑这个文件,如果没有对话就创建这个文件
root@wosuoai:~# vim /etc/docker/daemon.json
内容如下
{
"registry-mirrors": [
"http://hub-mirror.c.163.com"
]
}
重启服务
root@wosuoai:~# systemctl daemon-reload
root@wosuoai:~# systemctl restart docker
使用
执行docker -v
确认下是否成功安装了docker 如果成功安装了,命令行将会输出入docker的版本号
如下: Docker version 20.10.7, build f0df350
docker的整个流程大致可分为:
- 镜像
- 容器
- 仓库
这里以ubuntu镜像为例,介绍下镜像 在下载ubuntu镜像之前运行下docker images(查看镜像)
查看下本地的镜像。如果你还没下载过镜像的话,会出现空
root@wosuoai:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 c170dde06cb7 43 minutes ago 133MB
使用拉取镜像命令docker pull
拉取ubuntu
镜像:docker pull ubuntu
。当你不指定版本时,默认拉取latest版本
也可安装指定版本镜像:docker pull ubuntu:18.04
root@wosuoai:~# docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
4bbfd2c87b75: Pull complete
d2e110be24e1: Pull complete
889a7173dcfe: Pull complete
Digest: sha256:67b730ece0d34429b455c08124ffd444f021b81e06fa2d9cd0adaf0d0b875182
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
接下来基于ubuntu
镜像启动一个容器
docker run --name first -it ubuntu bash
- –name 用于指定容器名
- -it 用于交互式命令行操作,会打开容器的命令行
- bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是bash
运行上面的命令后,命令行工具就会自动进入容器的命令行。如果想要退出该命令行界面,可输入exit
退出
root@wosuoai:~# docker run -it ubuntu:18.04 bash
root@8821ddd3ac9d:/#
如果想让该容器在后台运行可以通过加-d
配置来让该容器在后台运行。后台运行,命令行工具不会进入该容器
使用docker ps
查看当前运行中的容器
root@wosuoai:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d26e53608e1 nginx:v3 "/docker-entrypoint.…" 52 minutes ago Up 52 minutes 80/tcp angry_yalow
使用-d
来让容器在后台运行
root@wosuoai:~# docker run -itd ubuntu:18.04 bash
4ee49058565581e2e059d9fd32aa3f0b76fbd20d7196be69b671ca6741467efd
命令行会返回容器id
使用docker container ls
查看所有容器列表(不包括停止运行的容器)
root@wosuoai:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ee490585655 ubuntu:18.04 "bash" 7 minutes ago Up 7 minutes blissful_mcnulty
使用docker stop <容器id或容器名称>
停止容器的运行
root@wosuoai:~# docker stop 4ee490585655
4ee490585655
执行命令后,会返回你刚输入容器的id。上面的容器id不需要填全
这个时候通过docker container ls
是查不到容器信息的。需要用docker container ls -a
来查看
root@wosuoai:~# docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ee490585655 ubuntu:18.04 "bash" 9 minutes ago Exited (0) 58 seconds ago blissful_mcnulty
可以看到STATUS处,显示exited表示该容器是处于停止状态,显示up表示该容器是出于运行状态
使用使用docker rm <容器id 或者 容器昵称>,删除容器 执行docker rm 8821 (id可以不输全)
root@wosuoai:~# docker rm 8821
8821
root@wosuoai:~# docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ee490585655 ubuntu:18.04 "bash" 14 minutes ago Exited (0) 5 minutes ago blissful_mcnulty
执行完之后,命令行会返回之前输入的容器id
使用docker container prune
,来清空停用状态的容器
使用docker exec
命令进入运行中的容器
如想进入刚才后台运行的容器的交互式界面:docker exec -it <容器名称 或者 容器id> bash
root@wosuoai:~# docker exec -it blissful_mcnulty bash
root@4ee490585655:/#
了解更多关于docker的命令点击这里
dockerfile
镜像的定制实际上就是定制每一层所添加的配置、文件,如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,去解决之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题。这个脚本就是 Dockerfile
Dockerfile 是一个文本文件,其内包含了一条条的 指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建
创建dockerfile
举个nginx
镜像的例子
在一个空白目录中,建立一个文本文件,并命名为 Dockerfile
root@wosuoai:~# mkdir mynginx
root@wosuoai:~# cd mynginx/
root@wosuoai:~/mynginx# touch Dockerfile
Dockerfile中的内容为
FROM nginx
RUN echo 'Hello, Docker!
' > /usr/share/nginx/html/index.html
FROM指定基础镜像
定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx
镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM
就是指定 基础镜像,因此一个 Dockerfile
中 FROM
是必备的指令,并且必须是第一条指令
官方有很多可以直接拿来使用的服务类的镜像,如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像
FROM scratch
...
如果你以 scratch
为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在
RUN命令
RUN
指令在定制镜像时是最常用的指令之一。其格式有两种:
shell 格式:RUN <命令>
,直接在命令行中输入的命令一样
exec 格式:RUN ["可执行文件", "参数1", "参数2"]
Dockerfile 中每一个指令都会建立一层,RUN
也不例外。每一个 RUN
命令,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,构成新的镜像
要用到多个 RUN
指令时,可以使用 &&
将各个所需命令串联起来。并且,Dockerfile 支持 Shell 类的行尾添加 \
的命令换行方式,以及行首 #
进行注释的格式。良好的格式,比如换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯
FROM debian:stretch
RUN set -x; buildDeps='gcc libc6-dev make wget' \
&& apt update \
&& apt install -y $buildDeps \
构建镜像
在 Dockerfile
文件所在目录执行:
root@wosuoai:~/mynginx# docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM nginx
---> d1a364dc548d
Step 2/2 : RUN echo 'Hello, Docker!
' > /usr/share/nginx/html/index.html
---> Running in 64684f6ce07f
Removing intermediate container 64684f6ce07f
---> c170dde06cb7
Successfully built c170dde06cb7
Successfully tagged nginx:v3
注意:docker build -t nginx:v3
. 最后有一个点,不能省略
从命令的输出结果中,我们可以清晰的看到镜像的构建过程。在 Step 2
中,RUN
指令启动了一个容器 64684f6ce07f
,执行了所要求的命令,最后提交了这一层 c170dde06cb7
,随后删除所用到的这个容器 64684f6ce07f
root@wosuoai:~/mynginx# docker run -p 8080:80 --name mynginx -it nginx:v3 /bin/bash
root@48bce4cd3bbf:/usr/share/nginx/html# exit
exit
root@wosuoai:~/mynginx# docker start mynginx
mynginx
root@wosuoai:~/mynginx# docker attach mynginx
root@48bce4cd3bbf:/# echo "Hello Docker
" > /usr/share/nginx/html/index.html
root@48bce4cd3bbf:/# nginx &
最后效果
docker端口映射
运行之前安装的ubuntu
镜像
root@wosuoai:~# docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48bce4cd3bbf nginx:v3 "/docker-entrypoint.…" 23 minutes ago Up 13 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp mynginx
3ca55da5fdaf ubuntu:18.04 "bash" 4 hours ago Exited (0) 4 hours ago stoic_cohen
0d26e53608e1 nginx:v3 "/docker-entrypoint.…" 5 hours ago Exited (0) 27 minutes ago angry_yalow
b5e983ea39be node "docker-entrypoint.s…" 6 hours ago Exited (0) 7 seconds ago first
root@wosuoai:~# docker start stoic_cohen
stoic_cohen
进入交互模式
root@wosuoai:~# docker attach stoic_cohen
root@3ca55da5fdaf:/#
注意:先更新仓库信息apt update
,否则不能直接用apt安装软件
安装curl
工具
root@3ca55da5fdaf:/# apt curl
root@3ca55da5fdaf:/# curl
curl: try 'curl --help' or 'curl --manual' for more information
安装apache
服务
apt install -y apache2
启动 apache
服务,使用 curl
进行本地访问测试
root@3ca55da5fdaf:/# service apache2 start
* Starting Apache httpd web server apache2 AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
*
root@3ca55da5fdaf:/# curl 127.0.0.1
端口映射
- -P:将容器内部的端口随机映射到宿主机上的端口上
- -p:指定映射的端口,一个指定端口上只能绑定一个容器
IP:HOSTPORT:CONTAINERPORT
:指定ip、指定宿主机port、指定容器port,宿主机port不指定将会映射到任意一个端口上
root@wosuoai:~# docker run -it -d -p 127.0.0.1:2000:80 docker.io/ubuntu:18.04 /bin/bash
0d203067e22576e2b497c682c186c09381e8bcfd545ca79664bd88dbb4f8fe62
docker-compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务
docker-compose的三个步骤:
- 使用 Dockerfile 定义应用程序的环境
- 使用 docker-compose.yml 定义构成应用程序的服务,确保在隔离环境中一起运行
- 执行 docker-compose up 命令来启动并运行整个应用程序
docker-compose最常见的项目是 web 网站,网站包含 web 应用和缓存
创建测试目录
root@wosuoai:~# mkdir docker-compose
root@wosuoai:~# cd docker-compose
创建app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
创建dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
创建docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
运行docker-compose
root@wosuoai:~# docker-compose up
私有仓库
私有仓库
安装运行registry
docker run -d -p 5000:5000 --restart=always --name registry registry
这使用官方的 registry
镜像来启动私有仓库。默认情况下,仓库会被创建在容器的 /var/lib/registry
目录下。可以通过 -v
参数来将镜像文件存放在本地的指定路径
例如将上传的镜像放到本地的 /opt/data/registry
目录
root@wosuoai:~# docker run -d \
> -p 5000:5000 \
> -v /opt/data/registry:/var/lib/registry \
> registry
e3ed3ba4dd9269947e6828ef8c5ad84432a219a51f33aae60415e72f510c9c96
在私有仓库上上传、搜索、下载镜像
先在本机查看已有的镜像
root@wosuoai:~# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 c170dde06cb7 7 hours ago 133MB
node latest d1b3088a17b1 4 days ago 908MB
nginx latest d1a364dc548d 13 days ago 133MB
ubuntu 18.04 81bcf752ac3d 2 weeks ago 63.1MB
registry latest 1fd8e1b0bb7e 7 weeks ago 26.2MB
使用 docker tag
将 nginx:latest
这个镜像标记为 127.0.0.1:5000/nginx:latest
格式为 docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
root@wosuoai:~# docker tag nginx:latest 127.0.0.1:5000/nginx:latest
root@wosuoai:~# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 c170dde06cb7 7 hours ago 133MB
node latest d1b3088a17b1 4 days ago 908MB
127.0.0.1:5000/nginx latest d1a364dc548d 13 days ago 133MB
nginx latest d1a364dc548d 13 days ago 133MB
ubuntu 18.04 81bcf752ac3d 2 weeks ago 63.1MB
registry latest 1fd8e1b0bb7e 7 weeks ago 26.2MB
使用 docker push
上传标记的镜像
1root@wosuoai:~# docker push 127.0.0.1:5000/nginx:latest
The push refers to repository [127.0.0.1:5000/nginx]
075508cf8f04: Pushed
5c865c78bc96: Pushed
134e19b2fac5: Pushed
83634f76e732: Pushed
766fe2c3fc08: Pushed
02c055ef67f5: Pushed
latest: digest: sha256:61191087790c31e43eb37caa10de1135b002f10c09fdda7fa8a5989db74033aa size: 1570
用 curl
查看仓库中的镜像
1root@wosuoai:~# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["nginx"]}
看到 {"repositories":["nginx"]}
,表明镜像已经成功上传
先删除已有镜像,再尝试从私有仓库中下载这个镜像
root@wosuoai:~# docker image rm 127.0.0.1:5000/nginx:latest
Untagged: 127.0.0.1:5000/nginx:latest
Untagged: 127.0.0.1:5000/nginx@sha256:61191087790c31e43eb37caa10de1135b002f10c09fdda7fa8a5989db74033aa
root@wosuoai:~# docker pull 127.0.0.1:5000/nginx:latest
latest: Pulling from nginx
Digest: sha256:61191087790c31e43eb37caa10de1135b002f10c09fdda7fa8a5989db74033aa
Status: Downloaded newer image for 127.0.0.1:5000/nginx:latest
127.0.0.1:5000/nginx:latest
root@wosuoai:~# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 c170dde06cb7 7 hours ago 133MB
node latest d1b3088a17b1 4 days ago 908MB
127.0.0.1:5000/nginx latest d1a364dc548d 13 days ago 133MB
nginx latest d1a364dc548d 13 days ago 133MB
ubuntu 18.04 81bcf752ac3d 2 weeks ago 63.1MB
registry latest 1fd8e1b0bb7e 7 weeks ago 26.2MB
配置非https仓库地址
如果不想使用 127.0.0.1:5000
作为仓库地址,想要使用内网192.168.127.130:5000
作为私有仓库地址,这时发现无法成功推送镜像
这是因为 Docker 默认不允许非 HTTPS
方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,或者查看下一节配置能够通过 HTTPS
访问的私有仓库
注意:以下步骤只争对Ubuntu16.04,Dibian8+,centos7
在 /etc/docker/daemon.json
中写入如下内容(如果文件不存在新建该文件)
{
"registry-mirror": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"insecure-registries": [
"192.168.199.100:5000"
]
}
图形化界面
docker search portainer
docker pull portainer/portainer
docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
构建数据库
docker run --name mymysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
- –name 给mysql容器设置匿名
- -d表示后台运行
- -p表示将容器的3306端口的映射到本地的3308端口,如果不设置的话,本地是无法访问该MySQL服务的
- -e MYSQL_ROOT_PASSWORD 设置root的账号密码
- mysql 不指定版本,默认会最新版本
启动容器后执行:docker exec -it mymysql bash
进入容器
后面内容与实际数据库操作一样,这里不再赘述