docker由浅入深

整理一下docker的用法与原理

持续更新中。。。

1.基本概念

1-1.关于docker

Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。[1]

——维基百科

1-2.docker和虚拟机

docker比虚拟机有更少的抽象层。

1-3.为什么用docker

个人理解:

首先虚拟机和docker的最主要作用都是进行应用的隔离,我们不希望各个应用之间相互影响,即一个应用或一个环境坏了,导致另外的应用也有问题。经常出现的问题:

  • 开发环境没问题、测试环境没问题、生成环境出问题。
  • 开发环境引入了一个新的依赖、或版本的升级,对应其他所有的环境都要同步更新。
  • 有一个新的环境要装这个应用,从头到尾安装环境各种依赖,十分繁琐耗时且容易出错。
  • 各个应用之间的依赖版本冲突。
  • ……

于是,有了虚拟化的技术。

虚拟机,隔离级别最高,不取宿主机的操作系统,每个虚拟机都要模拟一个完整的操作系统,包括各种硬件的模拟、库的模拟等,一开启就占用了所有分配给它的资源。由于相当于一台完整的计算机,所以启动是分钟级的,而且普通的宿主机也装不了几个虚拟机。

docker,还是直接利用宿主机的资源。 docker Engine可以简单看成对Linux的NameSpace、Cgroup、镜像管理文件系统操作的封装 。它还是利用宿主机的操作系统内核,只是进行资源和环境的隔离。启动是秒级的,由于十分轻量,docker容器可以创建很多,新增删除十分便捷。

2.安装docker

自备服务器。

2-1.卸载旧版本
1
2
3
4
5
6
7
8
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2-2.安装包管理工具
1
yum install -y yum-utils
2-3.配置仓库地址
1
2
3
4
5
6
7
8
#官方(国外,慢)
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
2-4.安装docker引擎
1
2
3
4
#默认最新版
yum install docker-ce docker-ce-cli containerd.io
#指定版本
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
2-5.启动docker
1
systemctl start docker

启动完可以查看一下docker信息

1
docker info
2-6.验证
1
docker run hello-world

3.配置镜像加速

登录阿里云,打开容器镜像服务,配置镜像加速器。

4.常用命令

5.容器数据卷

容器数据持久化。

容器内的数据会随着容器的删除而被删除,“挂载”是一个很好的保存数据的方法,它将容器内的数据自动同步到宿主机,下面是两种具体的方法。

5-1.bind mount

指定路径挂载。

1
2
# 例子:将容器内的centos下的/home/test挂载到宿主机的/home/test
docker run -itd -v /home/test:/home/test --name centos01 centos

创建完进入宿主机home目录:

可以看到自动创建了test目录,且test内为空。

进入到容器内home目录:

同样,容器内也创建了test目录。

然后,我们在宿主机创建文件test.java:

在容器内:

也能查到这个文件。

同理,在容器内创建文件test2.java,宿主机也查到了这个文件。

然后直接删除这个容器,宿主机依然保留了这些文件:

这样,就有效解决容器内数据持久化的问题。

注意,若文件已存在,已宿主机为准。

  • 如果container中的目录已经有内容,那么docker会使用host上的目录将其覆盖掉
5-2.volume

除了指定路径挂载,还有两种方式:

  • 具名挂载。

    1
    2
    3
    # 例子:将容器内的/var/lib/mysql地址挂载,取名为mysql-volume
    # 注意mysql设置密码
    docker run -itd -p 4306:3306 -v mysql-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql

    创建后进入docker volume的路径查看:

    image-20210408155242979

    这里是容器内mysql的数据。

    现在通过可视化工具,直接连到容器内的mysql并创建一个表。(注意防火墙开启端口)

    再次查看数据:

    发现数据在宿主机上能成功同步。

  • 匿名挂载。

    所谓匿名就是在挂载是不指定名称。

    1
    2
    3
    # 例子:将容器内的/var/lib/mysql地址挂载,不取名
    # 注意mysql设置密码
    docker run -itd -p 4307:3307 -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql

    结果将以容器id作为volume的名称。

完成测试后删除所有卷:

1
docker volume rm -f $(docker volume ls -q)

6.Dockerfile

6-1.关于Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

有没有想过,在一个完全干净没有任何依赖的地方,跑起来一个应用?

一般来说,对于java项目,一个开发交付的war包或jar包,都需要有一定的环境要求,比如war包得放进tomcat那起码安装tomcat,比如需要安装mysql、redis等等。

然而,有了上面关于docker的介绍,似乎我们可以直接省略这部分的步骤?那就是把所有东西,打包成一个镜像,运维只需要运行这个镜像,就完事了。

这也是现在的趋势:开发不再交付war包或jar包,而是直接交付一个镜像!

但是,每次手动完成镜像的打包工作那肯定不是上策,于是有了Dockerfile,利用它,一步生成镜像。

  • 指令介绍:

(这里从网上找来了一个比较通俗易懂的高清无码大图)

6-2.实践一,制作一个自定义的centos

首先通过官方的centos镜像启动一个容器,发现这个centos镜像仅仅是包含最基础的功能(阉割版centos),连ifconfig、vim等命令都没有:

下面通过Dockerfile来创建一个自定义centos镜像(增强版)。

写一个dockerfile文件,命名为dockerfile01:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM centos
MAINTAINER lizxing

#安装vim编辑器和网络工具
RUN yum -y install vim
RUN yum -y install net-tools

#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH

#容器运行时暴露的端口
EXPOSE 80

#启动时附加的命令
CMD echo "---end---"
CMD /bin/bash

运行它:

1
docker build -f dockerfile01 -t my-centos:1.0 . #(记得这个点)
  • 注意:当文件名为Dockerfile时(官方约定),不需要指定-f,会自动在本目录下执行Dockerfile。

  • 构建时,可以看到它以centos为基础,一层一层的往上面叠加,这正是docker核心技术——联合文件系统(后面详细介绍)的体现。

完成后通过这个自定义的镜像启动一个容器:

  • 注意,运行时需带上版本号。

该自定义的my-centos:1.0内已包含vim和网络工具,测试成功。

6-2.实践二,制作一个自定义的tomcat

准备两个压缩包:

  • apache-tomcat-9.0.45.tar.gz
  • jdk-linux-x64.tar.gz

并上传到服务器。按照国际规范创建一个readme.md文件。

编写Dockerfile:

1
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
FROM centos
MAINTAINER lizxing

#把宿主机当前上下文的readme.md拷贝到容器/usr/local/路径下
COPY readme.md /usr/local/readme.md

#把java与tomcat添加到容器中
ADD jdk-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.45.tar.gz /usr/local/

#安装vim编辑器
RUN yum -y install vim

#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH

#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_131
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.45
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.45
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

#容器运行时暴露的端口
EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.45/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.45/bin/logs/catalina.out

同上,build命令执行:

1
docker build -f Dockerfile -t my-tomcat:1.0 .

启动容器:

1
docker run -d -p 9090:8080 --name my-tomcat01 -v /home/dockerfile-test/tomcat9/webapps:/usr/local/apache-tomcat-9.0.45/webapps -v /home/dockerfile-test/tomcat9/logs/:/usr/local/apache-tomcat-9.0.45/logs my-tomcat:1.0

准备一个简单的项目test,放进宿主机的/home/dockerfile-test/tomcat9/webapps下。项目结构:

test

┝ index.html

┕ WEB_INFO

┕ web.xml
通过公网访问9090端口(记得配置安全组):

成功访问(中文乱码忽略)。

7.上传镜像

7-1.上传至Docker Hub
  • 在dockerhub注册个人账户。登录:
1
docker login
  • 将做好的镜像打好tag并按规范命名:用户名/镜像名,如:
1
docker tag my-tomcat:1.0 lizxing/my-tomcat:1.0
  • 推送镜像:
1
docker push lizxing/my-tomcat:1.0

完成后可以在个人的 repositories 处查看到该镜像。

7-2.上传至阿里云Docker镜像仓库

登录阿里云,打开容器镜像服务。创建镜像仓库。在仓库管理中,就可以看到完整的操作指南:


至此,docker基本的使用就算是入门了。

若要了解更深一层,需要学习Docker网络、Docker Compose、Docker Swarm等知识,下次继续研究。。。