docker概述
开始docker的学习!!
镜像就是模版,根据模版可以创建容器; (基础镜像+自定义镜像<编写Dockerfile文件,里面有很多指令>) 容器就是隔离的环境, 类似于创建了一个操作系统, 把代码和相关配置扔进去, 并让它跑起来.
docker version # 查看docker信息
docker info # 查看docker信息
systemctl start docker # 启动
systemctl enable docker # 开机自启
sudo systemctl restart docker # 重启
docker search 镜像名称 # 搜索远程有哪些基础镜像
docker rmi 镜像ID # 删除镜像
docker pull 镜像名称:18.04 # 拉取指定版本的某镜像
docker pull 镜像名称:latest # 拉取最新版本的镜像
docker images # 查看本地有哪些镜像
"""Docker容器的创建运行、停止、删除、查看 都是一条命令的事!!很方便!"""
# - 基于初始镜像自定义构建新的镜像
docker build -t 镜像名:镜像版本 . -f Dockerfile文件名 # 默认使用缓存
docker build -t 镜像名:镜像版本 . -f Dockerfile文件名 --no-cache # 不使用缓存 比如,Dockerfile文件中有git克隆时
# - 基于镜像创建容器并运行 <宿主机的80端口转发到容器的5000端口>
# 若不 --name 指定容器名, 容器名就是随机生成的; -d后台运行 ; -p端口映射 ;
# 该条命令返回的是容器ID
docker run -d -p 80:5000 镜像ID
# - 停止容器,可一条命令停止多个容器 (容器ID写前3位即可
docker stop 容器ID 容器ID 容器ID
# - 删除容器,可一条命令删除多个容器 (那些停止的容器就没啥用了,删除即可) ★删除镜像,一定要先把相关容器删除
docker rm 容器ID 容器ID 容器ID
# 批量停止容器 <谨慎操作>
docker stop `docker ps -aq`
# 批量删除容器 <谨慎操作>
docker rm `docker ps -aq`
docker ps # 查看目前正则运行的容器
docker ps -a # 查看所有的容器,包含运行的、停止的、因某些原因创建失败的
# ############ 在正式开发时 ###############
# 创建容器(eg该容器中有个flask前台进程)
docker run -d -p 80:5000 镜像ID
# 后期想要进入正在存活的容器
docker exec -it 容器ID bash
# 创建容器,并进入容器内,退出时结束容器后,自动删除.
docker run -ti --rm centos bash
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# docker是什么?
三个关键词: 软件、多个隔离的环境、节省资源
-1- docker就是一个 软件, 支持在win、mac、linux系统上进行安装.
-2- 可以帮助我们在一台电脑上创建出多个 隔离的环境.
为啥要创建隔离的环境?
假设你现在有一个centos7.6系统运行程序,而这个程序需要依赖[ubuntu系统的服务A]+[centos7.9的服务B]
- 传统的方式: 买新服务器,就需要3个服务器
- 虚拟化方式: 在原来的服务器上利用虚拟化技术创建虚拟机(vmware、kvm等),用虚拟机做隔离去跑新的业务.
- docker的方式:
利用docker软件创建一个新的容器,用容器去做隔离区跑新的业务!
在centos7.6上创建两个容器,分别装ubuntu和centos去跑服务A和服务B.
-3- docker比传统的虚拟机 极大的 节省资源,管理起来也更方便!
- 虚拟机的方式,是在电脑完整的创建一个操作系统!
- docker的方式,创建的容器不是完整的操作系统,而是充分利用宿主机内核+进程. 只是创建了一些必备的资源!!
> 两种常用的 Linux 发行版: Ubuntu 和 CentOS
> 常用的虚拟化技术: vmware 和 kvm
> ★ 在window系统上利用虚拟化技术创建虚拟机,和从阿里云平台购买云主机.本质上是一样的!!
云主机就是阿里云平台通过虚拟化技术得到的虚拟机!!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 必备概念
三个名词: DockerHub远程镜像仓库、Images本地镜像仓库、Containers容器
-1- DockerHub 远程镜像仓库 https://hub.docker.com/
仓库中有官方的一些镜像文件,也有开发者自定义的镜像文件.
-2- Images 本地镜像仓库
可以去远程仓库下载镜像到本地仓库,后续再根据镜像为“模版”去创建容器. 本地的镜像也可以发布到远程镜像库.
Q: 镜像是之前用虚拟机创建操作系统时的ISO文件吗?
A: 不是,此处是docker中的特殊的文件!可以将镜像理解是成一个模版!
★★ 将镜像就是充当模版来使用,在它的内部包含打包好了 > 运行所需依赖 + 业务代码.
★★ 后期基于镜像一键创建出的容器也就会自动包含依赖和业务代码,直接就可以运行了,不需要再安装相应依赖 + 拷贝代码啦!
-3- Containers 容器
容器就是根据镜像创造出来的一个个隔离的环境!
docker软件从官方下载镜像到本地,也可以自定义镜像上传发布到官方 > 基于本地镜像来创建多个容器
类似于 PPT软件使用官方的模版,我们自定义加上了一些logo等,将新ppt模版发到群里供其它人用!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# docker的安装和配置
centos系统常用安装包
yum install net-tools -y
yum install -y wget bash-completion vim lrzsz wget expect net-tools nc nmap tree dos2unix htop iftop iotop unzip telnet sl psmisc nethogs glances bc ntpdate openldap-devel
2
3
安装docker-ce社区版 <够用了.>
- 配置repo源
curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all && yum makecache
- 查看可下载版本
yum list docker-ce --showduplicates | sort -r
- 安装
# 最新版
yum install -y docker-ce
# 指定版本(选它
yum install -y docker-ce-23.0.6
2
3
4
5
6
7
8
9
10
11
12
13
启动docker
systemctl start docker
systemctl enable docker
""" 其他
systemctl restart docker
systemctl stop docker
docker version # 查看docker信息
docker info # 查看docker信息
which docker # docker-client
ps -ef |grep docker # docker daemon
"""
2
3
4
5
6
7
8
9
10
11
12
# docker常用操作
# 配置镜像加速
访问该地址 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
得到阿里云给的加速地址,依次执行以下命令
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://tew43ju4.mirror.aliyuncs.com",
"https://docker.m.daocloud.io",
"https://jockerhub.com"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载镜像
从远程拉取镜像到本地
执行docker search influxdb查询命令时,可能会超时,不用管,点击那个连接在浏览器里可查看,pull拉取式不受影响的.
或者你还可以科学上网 https://hub.docker.com/
在官网进行搜索, 跟执行search命令的结果是一样的.
[root@iZ2vcassvhmuty1upbxbeeZ etc]# docker search ubuntu
Error response from daemon: Get "https://index.docker.io/v1/search?q=ubuntu&n=25": dial tcp 128.242.250.157:443: i/o timeout
# 相当于 docker pull ubuntu:latest 拉取的是最新版本.
[root@iZ2vcassvhmuty1upbxbeeZ etc]# docker pull ubuntu
[root@iZ2vcassvhmuty1upbxbeeZ etc]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
influxdb latest 1f5a04237d8e 3 years ago 346MB
2
3
4
5
6
7
8
# 自定义镜像
比如,我下载了个ubuntu18.04的版本的镜像, 我们需要对这个基础镜像进行自定义, 将项目代码和项目所需依赖都扔进这个镜像里.
以一个最简单的flask项目为例.
# Step1: 下载基础镜像
[root@iZ2vcassvhmuty1upbxbeeZ etc]# docker pull ubuntu:18.04
[root@iZ2vcassvhmuty1upbxbeeZ etc]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest ba6acccedd29 3 years ago 72.8MB
ubuntu 18.04 5a214d77f5d7 3 years ago 63.1MB
2
3
4
5
# Step2: 编写文件
dockerfile文件 (该文件有自己的语法,不能乱写)、flask程序的app.py文件
[root@iZ2vcassvhmuty1upbxbeeZ opt]# mkdir demo
[root@iZ2vcassvhmuty1upbxbeeZ opt]# cd demo
[root@iZ2vcassvhmuty1upbxbeeZ demo]# pwd
/opt/demo
[root@iZ2vcassvhmuty1upbxbeeZ demo]# vim Dockerfile
[root@iZ2vcassvhmuty1upbxbeeZ demo]# vim app.py
[root@iZ2vcassvhmuty1upbxbeeZ demo]# ls
app.py Dockerfile
2
3
4
5
6
7
8
Dockerfile
此处暂且不用深究Dockerfile文件中的每个指令是啥意思, 后面会详解..
# Base images基础镜像/ 基于哪个基础镜像自定义的
FROM ubuntu:18.04
# MAINTAINER 维护者信息
Maintainer OnePiece@live.com
# RUN 在基础镜像里依次执行以下命令
RUN apt update
RUN apt install python3 python3-pip -y
RUN pip3 install flask
RUN mkdir -p /data/www/
# 将容器的宿主机(即阿里云服务器)里的app.py文件拷贝到容器里的/data/www/app.py位置
# 此处的app.py放的位置是和dockerfile文件同级的 所以这里写app.py这个相对路径是找的到的!
COPY app.py /data/www/app.py
# 容器的工作目录
WORKDIR /data/www/
# EXPOSE 映射端口,没啥用,可以不写
# EXPOSE 80
#容器启动时执行命令
CMD ["python3","app.py"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app.py
from flask import Flask
app = Flask(__name__)
# http://127.0.0.1:5000/index 能访问的; http://127.0.0.1:5000/index/ 访问不到!
# 在docker里,是别人访问宿主机(阿里云)的80端口(默认访问的也是80端口),然后转发到5000端口,让对应的容器提供服务!!
@app.route('/index')
def index(): # ★视图函数为啥没有request参数?因为flask的请求不像Django的请求是传递过来的,它请求是放在某地,自取
return "hello world" # 返回一个字符串,相当于Django里的HttpResponse
if __name__ == '__main__':
app.run(host="0.0.0.0",port=5000)
2
3
4
5
6
7
8
9
10
11
12
13
# Step3: 构建自定义的镜像
# docker build -t意思是tag 名字:版本 .表示当前目录下 -f基于哪个文件进行自定义镜像的构建
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker build -t flask_web:0.1 . -f Dockerfile
[+] Building 232.2s (12/12) FINISHED docker:default
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
... ... ..
=> => naming to docker.io/library/flask_web:0.1 0.0s
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
flask_web 0.1 c66c3244279c 16 seconds ago 513MB
ubuntu latest ba6acccedd29 3 years ago 72.8MB
ubuntu 18.04 5a214d77f5d7 3 years ago 63.1MB
2
3
4
5
6
7
8
9
10
11
12
# Step4: 基于镜像创建容器并运行
基于同一个镜像创建多个容器,并运行这多个容器..
(只不过,这里的多个容器都提供的是同一个服务, 因为它们都是基于同一个镜像创建出来的.
# 通过 -p <宿主机端口>:<容器端口> 的方式进行端口映射. 也就是说,宿主机的 80 和 81 端口分别被映射到容器的 5000 端口
# 通过 -d 即可后台运行
# 在浏览器上输入网址,默认访问的是服务器的80端口. 这里,容器的宿主机是阿里云服务器!
# 这里的c66c3244279c是本地镜像哈(模版)!
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker run -d -p 80:5000 c66c3244279c
2368e28193e0e59020b1a709f9cf8470039128c3335da2d85681d16d5ad8b8c5 # 此处返回的是容器ID
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker run -d -p 81:5000 c66c3244279c
aeb774c1331d2ad3c5b38e68e15632260fd39407ecee8c6efa3b4f44b6e0b85a
# 查看目前正在运行的所有容器,可以看到它两都用的同一个镜像
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aeb774c1331d c66c3244279c "python3 app.py" About an hour ago Up About an hour 0.0.0.0:81->5000/tcp, :::81->5000/tcp inspiring_borg
2368e28193e0 c66c3244279c "python3 app.py" About an hour ago Up About an hour 0.0.0.0:80->5000/tcp, :::80->5000/tcp elegant_diffie
2
3
4
5
6
7
8
9
10
11
12
13
14
(´▽`) 记得开放阿里云服务器的80端口和81端口..
至此, 阿里云服务器上运行着两个容器, 当用户访问.
http://47.109.154.134/index
和 http://47.109.154.134:81/index
时, 都能成功看到flask项目的内容.
# Dockerfile指令
# 基础指令
一个简单示例..
FROM ubuntu:18.04
LABEL maintainer wupeiqi [email protected]
# 环境变量(这里设置的环境变量跟后面的 WORKDIR /data/www/ 一样的
ENV PRO_PATH /data/www
RUN mkdir -p $PRO_PATH
RUN mkdir -p $PRO_PATH/mediea
# COPY 拷贝文件至工作目录
COPY *.py $PRO_PATH/
# ADD 拷贝文件至工作目录+解压
ADD *.tgz $PRO_PATH/mediea/
# 工作目录 在[★该指令后面]的RUN等指令,会先进入该容器的工作目录,然后再执行RUN等指令
WORKDIR /data/www/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 镜像构建时执行的指令
- FROM
FROM ubuntu:18.04
, 可以基于官方的基础镜像 或者 本地已经自定义后的镜像 来进行自定义.
格式:
FROM <image>
FROM <image>:<tag>
示例:
FROM ubuntu:5.7
注意:
tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
2
3
4
5
6
7
- MAINTAINER 镜像维护者的信息
Maintainer OnePiece@live.com
- WORKDIR 容器的工作目录
WORKDIR /data/www/
# 通过WORKDIR设置工作目录后,Dockerfile中在[★该指令后面]的RUN、CMD、ENTRYPOINT、ADD、COPY等指令都会默认在该目录下执行
# 相当于执行Dockerfile中的RUN等命令时,先进入该容器的工作目录,然后再执行RUN等命令
2
3
4
- ENV 相当于环境变量
格式:
ENV <key> <value>
ENV <key>=<value>
示例:
ENV myName John
ENV myCat=fluffy
RUN mkdir -p /data/www/
COPY app.py /data/www/app.py
等同于
ENV XX /data/www
RUN mkdir -p $XX
COPY app.py $XX/app.py
2
3
4
5
6
7
8
9
10
11
12
13
- RUN 构建镜像过程中执行命令.
- 比如执行RUN指令安装好一些包到自定义镜像中后,后期容器就可以直接使用了
- 注意: RUN指令创建的中间镜像会被缓存, 并会在下次构建中使用.. 就那些安装包的过程被缓存了.
- 比如, 我基于Dockerfile文件创建了flask_web这个镜像, 会有漫长的安装过程.
同样的, 我基于同一个Dockerfile文件创建了dc镜像, 就不会有那些漫长的安装过程.. 因为被缓存了..
但有一点不好, 万一是git从远程仓库克隆呢, 为了自定义镜像时拉取的是最新的, 我们就不需要那些缓存.. - 如果不想使用这些缓存镜像, 可以在构建镜像时指定--no-cache参数
如:docker build -t flask_web:0.1 . -f Dockerfile --no-cache
- 比如, 我基于Dockerfile文件创建了flask_web这个镜像, 会有漫长的安装过程.
格式:
RUN <command>
示例:
RUN yum install nginx
RUN pip install django
RUN mkdir test && rm -rf /var/lib/unusedfiles
2
3
4
5
6
- COPY|ADD 添加/拷贝 本地文件/宿主机中的文件 到镜像中
copy和add都有拷贝的动作,但若拷贝的是压缩文件,add拷贝过去后,会帮你自动解压
# 容器构建并启动时执行的指令
- CMD、ENTRYPOINT 在Dockerfile文件中只能选择其中一个指令并只能写一条.(写多条也只认最后一条)
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令时不会覆盖ENTRYPOINT
docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT.
Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令!
2
3
# 关于前后台的理解
-1- 启动的容器中/镜像内部,必须的有一个前台进程,否则Docker会认为容器已完成工作并自动退出该容器.
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker run -d ubuntu:18.04
feefc358d11b63056eab5ff04b5a5fd7c8067123652a7e3ca8b3e5a9af8935b7
[root@iZ2vcassvhmuty1upbxbeeZ demo]# docker ps
你不会看到feefc开头的正在运行的容器 (有前台进程时,容器才会保持运行)
-2- 前提,镜像含前台进程(eg:flask的python3 app.py)
宿主机基于镜像创建进程并启动,应该用后台运行的方式进行, 则docker run 命令需加上 -d参数.
docker run -d -p 80:5000 c66c3244279c
-3- 宿主机基于不含前台进程的镜像,创建容器并启动
我们可以进入镜像中进行一点操作,在进入镜像操作的过程中,该容器处于存活状态,操作完成后退出,该容器会自动销毁
docker run -ti -rm ubuntu:18.04 bash
docker run -ti -rm ubuntu:18.04 sh
> 用于启动一个基于ubuntu:18.04镜像的Docker容器,并进入容器的交互式 Bash shell,同时在容器退出时自动删除该容器.
-4- 进入正在存活的容器
docker exec -ti 容器ID bash
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ★ 用docker来部署Django
想法:
一个基础镜像,里面是python3.9和gcc,用于后续安装Python时编译源码以及python的相关依赖
一个根据基础镜像自定义的django镜像
一个mysql容器
一个nginx容器
> 项目部署共需要启动三个容器 django+nginx+uwsgi进行部署.
> 容器编排、容器网络、容器挂载、容器卷、dockerfile.
> 镜像的导入与导出、发布和下载.
2
3
4
5
6
7
8
暂略吧.. 过程中有很多细节需要捣鼓. 后面系统学习了运维 或 工作用到了, 再回头捣鼓.