Docker使用

 

正文:

  • Docker介绍
  • Docker安装
  • 镜像文件
  • 容器文件
  • 编写Dockerfile
  • 导入导出和发布

 

Docker 官网:https://www.docker.com

Github Docker 源码:https://github.com/docker/docker-ce


 Docker介绍

一、环境配置的难题

Docker的出现是为了解决环境配置的难题,软件开发最大的麻烦事之一,就是环境配置。操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。

环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来

二、虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。

缺点:

  • 资源占用多
  • 冗余步骤多
  • 启动慢

三、Linux容器

由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

优势:

  • 启动快
  • 资源占用少
  • 体积小

四、Docker 是什么

Docker 属于 Linux 容器的一种封装,是一个开源的应用容器引擎,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低

五、Docker 的用途

  • 提供一次性的环境。
    •   比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
  • 提供弹性的云服务。
    •   因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
  • 组建微服务架构。
    •   通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

六、Docker 架构

Docker 包括三个基本概念:

仓库==>镜像==>容器

  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。Docker 容器通过 Docker 镜像来创建。
  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

容器与镜像的关系类似于面向对象编程中的对象与类。容器==>对象/镜像==>类

整体流程:

从仓库拉取一个基础镜像(或本地导入),然后根据Dockerfile进行镜像文件的构建,然后通过构建的镜像文件生成实例容器

Windows上安装centos虚拟机

镜像(image)文件介绍:

(1)Docker 把应用程序及其依赖,打包在镜像文件中。只有通过这个镜像文件才能生成Docker容器(container)。镜像文件可以看作是容器的模板。Docker根据镜像文件生成容器的实例,同一个镜像文件,可以生成多个同时运行的容器实例。

(2)image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image

(3)image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作

# 列出本机的所有 image 文件。
$ docker image ls

# 删除 image 文件
$ docker image rm [imageName]

官方文档:https://docs.docker.com/get-started/overview/


Dcoker安装

1,安装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,安装方式二

rm -rf /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all
sudo yum install docker-ce docker-ce-cli containerd.io
systemctl enable --now docker

启动docker

# service 命令的用法
$ sudo service docker start

# systemctl 命令的用法
$ sudo systemctl start docker

停止docker

systemct1 stop docker

验证是否安装成功

$ docker version
# 或者
$ docker info

Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组(官方文档

$ sudo usermod -aG docker $USER

验证 Docker Engine 是否已正确安装
通过运行 hello-world 映像来验证

sudo docker run hello-world


镜像文件

创建简单的镜像文件

$ docker image pull hello-world
$ docker image pull library/hello-world

查看镜像文件

$ docker image ls

运行镜像文件

$ docker container run hello-world

docker container run命令会从 image 文件,生成一个正在运行的容器实例。

注意,docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的docker image pull命令并不是必需的步骤

运行成功显示:

输出这段提示以后,hello world就会停止运行,容器自动终止。docker ps 可以看到没有在运行的容器

 


 容器文件

镜像文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成了,就会同时存在两个文件:镜像文件和容器文件。关闭容器并不会删除容器文件,只是容器停止运行而已。

# 列出本机正在运行的容器
$ docker container ls

# 列出本机所有容器,包括终止运行的容器
$ docker container ls --all

# 停止容器
$ docker container kill [containID]

# 删除容器
$ docker container rm [containerID]

编写Dockerfile

创建镜像时运行

  • FROM指定基础镜像,必定为第一个命令
格式:
FROM <image>
FROM <image>:<tag>
示例:
FROM mysql:5.7
注意:
tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
  • MAINTAINER镜像维护者的信息
格式:
MAINTAINER <name>
示例:
MAINTAINER jiushao
  • ENV 环境变量
格式:
ENV <key> <value>
ENV <key>=<value>
示例:
ENV myName John
ENV myCat=fluffy
  • COPY|ADD 添加文件到镜像中
格式:
COPY <src>...<dest>
示例:
ADD home* /mydir/        # 添加所有以"home"开头的文件
ADD test relativeDir/       # 添加“test”到 $WORKDIR/relativeDir/
ADD test /absoluteDir/    # 添加“test”到 /absoluteDir/

注意:针对压缩包使用ADD的话,会自动解压缩
  • WORKDIR 工作目录
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为a)
注意:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMDENTRYPOINTADD、COPY等命令都会在该目录下执行

RUN 构建镜像过程中执行命令

格式:
RUN <command>
示例:
RUN yum install nginx
RUN pip install django
RUN mkdir test && rm -rf /var/lib/unusedfiles
注意:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

创建容器时运行

  • CMD构建容器后调用,也就是在容器启动时才进行调用
格式:
CMD ["executable","param1","param2"](执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD ["/usr/bin/wc","--help"]
CMD ping www.baidu.com
注意:
CMD 不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令
  • ENTRYPOINT 设置容器初始化命令,使其可执行化
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件,优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
ENTRYPOINT ["/usr/bin/wc","--help"]
注意:
ENTRYPOINTCMD 非常类似,不同的是通过docker run 执行的命令不会覆盖ENTRPOINT,而docker run 命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT 。Dockerfile中只允许有一个ENTRYPOINT命令,多指令时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令

在docker run时CMD等价于

在docker run时ENTRYPOINT等价于

如果要执行多条命令,则执行shell文件 

ENTRYPOINT ["/bin/sh","run.sh"]

注意点:

1,容器中必须有前台进程,否则创建立即销毁

2,宿主机centos7,运行创建容器是否需要前台?后台?

宿主机后台进程 + 容器内部前台进程

docker run -d -p 80:8000 jiushao

仅:容器内部前台进程

docker run -p 81:8000 jiushao

仅:宿主机后台进程

docker run -d -p 80:8000

导入导出和发布

Dockerfile -> 构建 -> 本地文件库 ,镜像构建完成后可以通过两种方式给其他人用

  • 本地导入导出
  • 发布(注册DockerHub)

本地导入和导出

# 先查看
docker images

# docker image save jiushao/jd:1.0 > /data/jd.tgz

导入(删除镜像docker rmi 镜像ID,一定要提前把容器删除)

# 查看
docker images
# 导入
docker image load -i /data/jd.tgz

发布和下载

1,注册hub.docker.com账号

2,在docker中登录&上传镜像

# 登录
docker login
# 上传
docker push jiushao/jd:1.0

下载

docker pull jiushao/jd:1.0

 


 实际工作的环境只会更复杂,Docker在环境配置方面真是解决了老大难问题,以后的应用程序就像一个APP发布一样简单了。直接导入或从仓库拉取就能用,用了就爱不释手

 一个实战案例:部署Flask网站

1,获取镜像

docker search ubuntu
docker pull ubuntu:18.04

查看镜像

docker images

2,构建镜像

  2.1  Dockerfiel+语法

1)在docker宿主机centos7创建两个文件Dockerfile、app.py

cd /opt/
mkdir demo
cd demo
vim Dockerfile
vim app.py

放入文件内容

# Dockerfile

# Base images 基础镜像
FROM ubuntu:latest

# MAINTAINER维护者信息
MAINTAINER jiushaoing

# RUN 执行以下命令
RUN apt update
RUN apt install python3 python3-pip -y
RUN pip3 install flask
RUN mkdir -p /data/www/

# 拷贝文件至工作目录
COPY app.py /data/www/app.py

# 工作目录
WORKDIR /data/www/

# EXPOSE 映射端口
EXPOSE 80

# 容器启动时执行命令
CMD ["python3","app.py"]

Flask示例程序app.py

from flask import Flask

app = Flask(__name__)

@app.route("/index")
def index():
    return "这是一个测试页面"


if __name__ == "__main__":
    app.run(host="0.0.0.0",port=8000)

2)命令构建自定义镜像(模板),在当前目录下构建

docker build -t v0:0.1 . -f Dockerfile    

2.2  基于镜像创建容器+运行

# 运行
docker run v0:0.1

# 映射端口,将外部端口80映射给容器内的端口8000
docker run -p 80:8000 v0:0.1

# 后台运行
docker run -d -p 80:8000 v0:0.1

列出现在所有运行的容器

docker ps

执行成功会显示如下画面:(输入虚拟机的ip地址然后加上映射的80端口即可)若80端口不行,换其他端口即可如83

浏览器访问{虚拟机IP}:{映射端口}/index。即可显示测试页面

查看所有容器

docker ps -a

给容器设置名字

停止容器,输入容器的前几位ID即可,如:500707。可以空格多个ID停止多个容器  

docker stop 500707

容器删除:docker rm 容器ID

小结:

镜像:模板(基础镜像+自定义镜像)

容器:隔离的环境 

 


 

 

 

学习参考:

阮一峰的网络日志:https://ruanyifeng.com/blog/2018/02/docker-tutorial.html

菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html

路飞学城:https://www.bilibili.com/video/BV1cF411o7Pz/?p=12&spm_id_from=pageDriver&vd_source=8bc93faaf8c822f06e3c15f0c4d2e6d3

posted @ 2023-08-01 23:49  天才九少  阅读(315)  评论(0编辑  收藏  举报