1 简介
1.1 docker是什么
docker是一个开源的容器引擎,它可以帮助我们更快地交付应用。docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用docker,可更快地打包、测试以及部署应用程序,并可减少从编写到部署运行代码的周期。
docker是一种轻量级虚拟化技术,在虚拟内核基础之上进行精简,用于快速搭建项目运行所需要的环境,能够做到统一开发、测试、部署时相同的环境。
1.2 docker架构
-
docker客户端(client):docker的用户界面,它可以接受用户命令和配置标识,并与docker daemon通信;图中,docker build等都是docker的相关命令
-
守护进程(docker daemon):运行在宿主机的后台进程,我们可通过docker客户端与之通信
-
镜像(image):docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
-
容器(container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见
-
仓库(registry):docker registry是一个集中存储与分发镜像的服务。我们构建完docker镜像后,就可在当前宿主机上运行。但如果想要在其他机器上运行这个镜像,我们就需要手动拷贝。此时,我们可借助docker registry来避免镜像的手动拷贝。
2 安装docker
- docker 要求 CentOS 系统的内核版本高于 3.10,通过uname -r 查看当前的内核版本
- 如果安装过请先卸载
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
- 安装需要的安装包yum-utils
yum install -y yum-utils
- 设置镜像仓库地址
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo ##此地址为官方的仓库地址,在国内建议不要用
阿里云的镜像仓库地址
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装docker相关的引擎
yum install docker-ce docker-ce-cli containerd.io
- 启动docker
systemctl start docker
- 使用docker version 查看dockers是否启动
docker version
- 使用hello-world镜像测试docker
docker run hello-world
3 常用命令
3.1 基础命令
- docker启动、关闭、重启
systemctl start/stop/restart docker
- docker设置随服务启动而自启动
systemctl enable docker
- docker运行状态
systemctl status docker
3.2 镜像类
- 查看自己服务器中docker 镜像列表
docker images
- 拉取镜像 不加tag(版本号) 即拉取docker仓库中最新版本latest 加tag 则是拉取指定版本
docker pull 镜像名
docker pull 镜像名:tag
- 运行镜像
docker pull ubuntu # 拉取镜像
docker run -it image_id /bin/bash # 以交互式运行
- 删除镜像 ------当前镜像没有被任何容器使用才可以删除
docker rmi -f image_id
- 镜像标签
docker tag 源镜像名:TAG 新的镜像名:新的TAG
3.3 容器类
- 查看正在运行容器列表
docker ps
- 查看所有容器 -----包含正在运行 和已停止的
docker ps -a
- 运行一个容器
# -it 表示 与容器进行交互式启动 -d 表示可后台运行容器 (守护式运行) --name 给要运行的容器 起的名字 /bin/bash 交互路径
docker run -it -d --name 容器名 镜像名:Tag /bin/bash
- 启动/停止/重启/kill 容器
docker start/stop/restart/kill 容器名/容器ID
- 删除容器
#删除一个容器
docker rm -f 容器名/容器ID
#删除多个容器 空格隔开要删除的容器名或容器ID
docker rm -f 容器名/容器ID 容器名/容器ID 容器名/容器ID
#删除全部容器
docker rm -f $(docker ps -aq)
- 容器端口与服务器端口映射
# -p 8888:6379 将容器内部的6379端口与docker宿主机8888端口进行映射,
# 那通过外部访问宿主机8888端口,即可访问到docker容器6379端口了
docker run -itd --name 取别名 -p 宿主机端口:容器端口 镜像名:tag /bin/bash
- 进入容器
docker exec -it 容器名/容器ID /bin/bash
- 容器文件拷贝 ,无论容器是否开启 都可以进行拷贝
#从容器内拷出
docker cp 容器ID:容器内路径 容器外路径
#从外部拷贝文件到容器内
docker cp 容器外路径 容器ID:容器内路径
- 查看容器日志
docker logs -f --tail=末尾多少行(默认all) 容器ID
- 文件挂载
-v 宿主机文件存储位置:容器内文件位置
将容器内的数据与外部宿主机文件绑定起来,类似一个双持久化,当容器删除时,宿主机文件数据目录仍在,下次启动容器只要将数据目录指向宿主机数据所在位置即可恢复
- commit,用于将一个镜像进行提交成一个新的副本
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
4 docker私有仓库
有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。本节介绍如何使用本地仓库。docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。
docker私有仓库本身就是一个docker镜像,所以,首先要安装docker,然后启动这个镜像。
- 拉取私有仓库镜像
#拉取tag为2的私有仓库镜像
docker pull registry:2
- 启动私有镜像的容器
# --restart=always docker重启时,容器自动重启
# -v 挂载本地目录,push到该仓库的镜像会保存在该路径下
docker run --name local-registry -d -p 5000:5000 --restart=always -v /opt/data/registry:/var/lib/registry registry:2
- 在 /etc/docker/daemon.json 下添加如下代码
{
"insecure-registries":["localhost:5000"]
}
- 重启docker服务
systemctl restart docker
- 修改上传镜像的tag
docker tag 源镜像名 localhost:5000/镜像名
- 镜像上传私有仓库
docker push localhost:5000/镜像名
- 查看仓库镜像
curl -XGET localhost:5000/v2/_catalog
- 拉取私有仓库镜像
docker pull localhost:5000/镜像名
5 dockerfile
4.1 FROM
指定基础镜像,必须为第一个命令
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
示例:
FROM mysql:5.6
注:
tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
4.2 RUN
构建镜像时执行的命令
RUN用于在构建镜像时执行命令,其有以下两种命令执行方式:
shell执行
格式:
RUN <command>
exec执行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,
可以在构建时指定--no-cache参数,如:docker build --no-cache
4.3 ADD
将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
4.4 CMD
构建镜像后调用,也就是在容器启动时才进行调用
格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD echo "This is a test." | wc -l
CMD ["/usr/bin/wc","--help"]
注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
4.5 EXPOSE
指定于外界交互的端口
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口如果没有暴露端口,后期也可以通过-p 8080:80方式映射端口,但是不能通过-P形式映射
4.6 WORKDIR
工作目录,类似于cd命令
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)
注:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY
等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
6 docker network
7 docker 资源限制
7.1 查看容器资源使用
docker stats
7.2 对内存进行限制
docker run -d -P --name container_name -m 512m image_name:tag
8 docker compose
9 应用
文件
- main.py文件
# coding=utf-8
import argparse
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET'])
def check_health():
resp = {
'message': 'service alive'
}
return flask.jsonify(resp)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-e', '--env', type=str, default='test')
parser.add_argument('-p', '--port', type=int, default=8080)
args = parser.parse_args()
app.run(host='0.0.0.0', port=args.port, debug=True)
- Dockerfile文件
FROM python:3.9.6-slim
WORKDIR /project
RUN apt-get update && apt-get install -y git tzdata
COPY requirements.txt /project/
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN pip install gunicorn
ENV TZ=Asia/Shanghai
COPY . .
EXPOSE 8080
ENTRYPOINT ["gunicorn", "main:app", "-c", "gunicorn.conf.py"]
- gunicorn.conf.py文件
bind="0.0.0.0:8080"
workers=1
timeout=1200
- requirements.txt文件
attrs==23.2.0
certifi==2023.11.17
chardet==4.0.0
click==8.1.7
dill==0.3.7
Flask==2.0.1
greenlet==3.0.3
gunicorn==20.1.0
idna==2.10
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
multiprocess==0.70.15
numpy==1.20.3
packaging==23.2
pandarallel==1.5.2
pathos==0.2.7
pluggy==0.13.1
pox==0.3.3
ppft==1.7.6.7
py==1.11.0
python-dateutil==2.8.2
pytz==2023.3.post1
requests==2.25.1
six==1.16.0
toml==0.10.2
urllib3==1.26.18
Werkzeug==2.3.7
创建image
docker build -t image_name:tag .
创建容器
docker run -d -P -v 宿主机目录:容器内目录 --name container_name image_name:tag