Docker

写在前面:本文根据该视频学习编写https://www.bilibili.com/video/BV1og4y1q7M4?p=40

1.Docker概述

Docker简单的讲就是一个虚拟化工具,容器化技术,可以实现快速实现简化服务部署之类的功能,它的核心是一次构建,到处部署,在通过build以后,会构建完可用的docker镜像,如果以后需要使用或者在别的服务器启动,只需要将镜像发布到远程,通过几行命令拉取镜像,然后根据镜像创建出一个容器,将服务跑起来即可。

1.1 Docker介绍

Docker的意思是码头工人,思想就是"集装箱",表示在物流中简化了运输中多次装货和卸货的时间 ,只需要进行一次封装,节省了大量的资源和时间成本

Docker不像传统的方式一样,只给你打包后的jar包或者war包以及说明安装文档,然后再去根据文档安装环境部署,而Docker是直接给一个docker镜像,这个镜像不仅包含运行的jar包和war包,还有运行服务所依赖的环境,只需要直接拉取镜像,然后创建容器,直接运行就可以。

那么我们现在知道Docker是为了一次构建,到处部署,那么如果只有一台服务器,也不会迁移,只需要部署一次,那么还需要使用Docker吗?如果你确信你的应用都是一次性的,而且只提供给自己使用,那么docker在这种场景下的优势不是特别明显,但是,你真的真的确信,你所做的工作只是一次性的吗?

总结一下Docker带来的好处:

更高效的交付和部署引用

  • 传统:一堆帮助文档,安装运行程序
  • Docker:打包镜像发布测试 ,只需几条命令

更便捷的升级和扩展:

  • 要增加服务器?打包镜像分分中扩展一个服务器

更高效的计算资源利用

  • Docker是内核级别的虚拟机化,可以在一个物理机运行很多个容器实例,可以将服务器的性能提高到最佳

参考:Docker是什么?

1.2 Docker组成

镜像(Images)

镜像就是一个模版,可以通过镜像构建多个容器,镜像不可以直接运行的,避免在运行中或者配置中损坏,最终服务运行或者项目运行就是在容器中运行的

容器(Container)

Docker利用容器技术,由镜像创建容器,独立运行一个或者一组应用,每个容器由自己的专用文件系统,通过命令启动、停止、删除应用等!

仓库(Registry)

仓库就是存放镜像的地方,分为共有仓库和私有仓库,镜像就是从仓库下载的

默认使用的是Docker Hub(国外的)下载很慢,可以使用国内的仓库,比如阿里云...

1.3 Docker为什么比虚拟机快

1.Docker不需要硬件资源虚拟化,运行在Docker容器上的应用直接使用的物理机资源,所以在内存、CPU上比虚拟机的利用率更高

2.Docker利用的是宿主机的内核,当新建一个容器的时候,不需要和虚拟机一样重新加载操作系统,省去了大量的时间

2.Docker安装

2.1 开始安装

1.卸载旧的版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2.下载需要的安装包

sudo yum install -y yum-utils

3.设置镜像存储库

#这是国外的,下载很慢
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo 

#这是阿里云的,推荐
sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4.安装的Docker引擎、客户端、容器;ce是社区版,ee是企业版,官方推荐使用社区版

#安装最新版本
sudo yum install docker-ce docker-ce-cli containerd.io


#安装指定版本
#1.列出可用版本
yum list docker-ce --showduplicates | sort -r 

docker-ce.x86_64  3:18.09.1-3.el7                     docker-ce-stable
docker-ce.x86_64  3:18.09.0-3.el7                     docker-ce-stable
docker-ce.x86_64  18.06.1.ce-3.el7                    docker-ce-stable
docker-ce.x86_64  18.06.0.ce-3.el7                    docker-ce-stable

#2.通过软件包的名称+版本字符串进行安装 VERSION_STRING:第二列第一个:一直到-前的字符,比如18.09.1
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

5.启动Docker

sudo systemctl start docker

6.测试是否安装成功

docker version

7.运行hello-world

sudo docker run hello-world

run的执行流程:

8.查看下载的镜像

docker images

9.卸载Docker

#1.卸载Docker Engine,CLI和Containerd软件包:
sudo yum remove docker-ce docker-ce-cli containerd.io

#2.删除主机上的映像,容器,卷或自定义配置文件 /var/lib/docker:docker的默认工作路径
sudo rm -rf /var/lib/docker

2.1 阿里云镜像加速器

因为很多镜像在国外,下载非常慢,配上加速器会更快

阿里云官网容器镜像地址:https://cr.console.aliyun.com/cn-beijing/instances/mirrors

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://e859w42o.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

3.常用命令

3.1 镜像命令

查看本地主机上的所有镜像

$ docker images [-a] [-q]
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        5 months ago        13.3kB

# 解释
REPOSITORY:镜像名称 
TAG:镜像版本
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小

# 可选项
-a,--all:列出所有镜像
-q,--quiet:只显示镜像ID

搜索镜像

镜像搜索网址:https://hub.docker.com/

$ docker search imagename 

# 搜索mysql
$ docker search mysql [--limit]
NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql               MySQL is a widely used, open-source relation…   9574                [OK]
mariadb             MariaDB is a community-developed fork of MyS…   3478                [OK]

# 可选项
--limit 5:只显示前5条镜像
--filter=stars=3000:只显示stars大于3000的镜像

下载镜像

$ docker pull imagename[:tag]

# 下载mysql
$ docker pull mysql
Using default tag: latest    #默认下载最新版 
latest: Pulling from library/mysql  
afb6ec6fdc1c: Pull complete  #分层下载,它下载过以后,下载其他mysql镜像版本时重复的就不需要下载了
0bdc5971ba40: Pull complete
97ae94a2c729: Pull complete
f777521d340e: Pull complete
1393ff7fc871: Pull complete
a499b89994d9: Pull complete
7ebe8eefbafe: Pull complete
597069368ef1: Pull complete
ce39a5501878: Pull complete
7d545bca14bf: Pull complete
211e5bb2ae7b: Pull complete
5914e537c077: Pull complete
Digest: sha256:a31a277d8d39450220c722c1302a345c84206e7fd4cdb619e7face046e89031d
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #mysql的真实地址

# 下载mysql5.7版本的,版本号必须是存在才可以下载,如果下载99.99版本肯定会报错找不到的
$ docker pull mysql:5.7

删除镜像

$ docker rmi -f IMAGE ID 

# 根据镜像ID删除镜像
$ docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               5.7                 a4fdfd462add        12 days ago         448MB
mysql               latest              30f937e841c8        12 days ago         541MB
hello-world         latest              bf756fb1ae65        5 months ago        13.3kB
$ docker rmi -f a4fdfd462add

#  根据镜像ID删除多个镜像
docker rmi -f a4fdfd462add 30f937e841c8

# 删除全部镜像,意思就是先查询出来所有的ID,然后全部删除
$ docker rmi -f $(docker images -aq)

3.2 容器命令

说明:有了镜像才可以创建容器,下载一个centos镜像来学习

$ docker pull centos

新建容器并启动

$ docker run [可选项] imagename

# 可选项
--name : 容器名字
-d.    : 以后台方式运行
-it    : 进入容器
-p     : 指定容器端口
	-p 主机端口:容器端口(常用)
	
# 启动并进入容器
$ docker run  -it centos

退出容器

# 退出并停止容器
$ exit

# 退出但不停止容器
Control + P + Q

查看容器状态

$ docker ps [-a] [-q]

# 查看当前运行的容器
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
64ac46420f91        centos              "/bin/bash"         14 seconds ago      Up 13 seconds                           vigorous_ishizaka

# 查看所有的容器
$ docker ps -a

# 查看所有的容器ID
$ docker ps -aq

删除容器

$ docker rm [-f] containerId

# 根据ID删除指定的容器
$ docker rm 64ac46420f91

# 删除全部容器
$ docker rm -f $(docker ps -aq)

# 可选项 
-f :强制删除,运行中的容器不能直接删除,需要-f参数

启动和停止容器

docker start containerID 		#启动容器
docker restart containerID 	#重启容器
docker stop containerID 		#停止当前运行中的	容器
docker kill containerID  		#强制停止当前容器

3.3 其他命令

查看日志

$ docker logs [-t] [-f] [--tail num] containerID

# 可选项
-t : 显示时间戳
-f : 跟踪显示日志
--tail num:显示num行日志

# 跟踪查看全部日志
docker logs -tf containerID

查看当前容器的元数据信息

$ docker inspect containerID

进入容器

# 进入后开启一个新的终端
$ docker exec -it containerID /bin/bash

# 进入容器正在执行的终端
$ docker attach containerID

将容器中的文件拷贝到主机上

$ docker cp containerID:容器文件路径 主机路径

eq:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              
51c13cc979ed        centos              "/bin/bash"         4 minutes ago       Up 1 
# 1.进入容器
$ docker exec -it 51c13cc979ed /bin/bash
# 2.在容器创建一个文件
$ touch /home/test.java
# 3.退出容器
$ exit
# 4.将容器中的test.java拷贝到主机的/home下
$ docker cp 51c13cc979ed:/home/test /home

3.4 安装Nginx

# 1.搜索镜像
$ docker search nginx

# 2.下载nginx镜像
$ docker pull nginx

# 3.新建容器并启动
$ docker run -d --name nginx01 -p 3344:80 nginx

3.5 安装Tomcat

# 1.搜索镜像
$ docker search tomcat

# 2.下载tomcat9.0版本的镜像
$ docker pull tomcat:9.0

# 3.新建容器并启动,后面需要添加版本
$ docker run -d --name tomcat01 -p 8080:8080 tomcat9.0

# 4.启动后浏览器访问http://ip:8080会出现404,这是因为tomcat的webapps目录下默认没有内容,需要将webapps.dist目录下的文件拷贝到webapps目录
$ docker exec -it 容器id /bin/bash
$ cp -r webapps.dist/* webapps

# 然后再访问就出现了tomcat默认页面
  • -d:在后台启动
  • —name:容器名字为nginx01
  • -p:指定端口映射,在浏览器访问 http://ip:3344会映射到80端口

为什么需要端口映射呢?

这是外网可以访问Linux,而Linux无法直接访问Docker,需要进行一个端口映射才可以访问

3.6 可视化面板

Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。

首先下载Portainer镜像

# 下载镜像
$ docker pull docker.io/portainer/portainer

然后启动Portainer

$ docker run -d -p 9000:9000 \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    --name prtainer-test \
    docker.io/portainer/portainer

启动成功,访问http://IP:9000

第一次登录会先创建账户

如果只有一个Docker宿主机就选择Local,Docker集群选择Remote

然后会进入主页面,可以查看容器、镜像、并进行启动删除等操作

4.Docker镜像

4.1镜像原理

镜像是一个轻量级、可执行的软件包,用来打包软件以及它的运行环境,包含代码、环境、配置文件等内容

Docker镜像加载原理

docker镜像实际是由一层一层的文件系统构成的,叫做联合文件系统,以pull为例,当下载镜像的时候,会发现是一层一层的进行下载,这样做的好处就是共享资源,因为多个镜像可能都从相同的base镜像构建而来,那么宿主机只需要保存一份镜像,就可以为所有镜像服务了

docker是只读的,当运行的时候,会构建一个可写层,也就是容器层,所有的操作都是对于容器层的

4.2 Commit镜像

# 提交容器成为一个新的镜像
$ docker commit -a="作者" -m="提交信息" 容器id 镜像名:[TAG]

比如docker下载下来的tomcat镜像默认访问是404的,还需要进行一个拷贝才可以访问,那我们就可以将我们第一次拷贝后的容器进行提交,提交成一个新的镜像,下次运行的时候直接运行这个提交后的镜像即可

5.容器数据卷

5.1 什么是容器数据卷

我们知道,数据都是保存在容器中,那如果容器删除,数据也就会丢失!比如MySQL,当容器删除,那它的配置文件以及数据库信息都会被删除,这无疑是要命的。

那如何保证数据不会丢失,将数据持久化到主机就是容器数据卷技术所做的事情,将容器的目录与主机的目录进行挂载,文件会自动完成同步。

有了容器数据卷,对于Nginx的配置文件就不需要每次修改都进入容器,可以在主机中创建一个文件与Nginx配置文件挂载,然后直接修改主机的文件即可。

5.2 使用数据卷

-v:直接使用使用命令来挂载

$ docker run -d -v 主机路径:容器路径 imagename 

# 测试,将主机的/home/ceshi与centos容器的/home目录挂载
$ docker run -it -v /home/ceshi:/home centos /bin/bash

# 挂载以后,可以使用命令查看是否挂载成功
$ docker inspect 容器ID

无论是添加、删除、修改文件都会进行同步,如果需要删除容器,那么当下次新建容器并启动的时候通过-v命令进行挂载还是会进行同步。

5.3 安装MySQL

# 下载MySQL
[root@aliyun ~]# docker pull mysql:5.7

# 启动mysql
-d : 后台启动
--name :容器命名
-p :端口映射
-v :挂载MySQL的配置文件和数据目录
-e :设置全局变量,MYSQL_ROOT_PASSWORD:mysql root用户密码
$ docker run -d --name mysql01 -p 3306:3306 -v /home/mysql/conf:/etc/conf.d -v /home/mysql/data:/var/lib/data -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

使用数据库连接工具连接测试,并且新建一个数据库会发现主机的/home/mysql/data目录也会新增一个目录就是新建的数据库,这样即使容器删除,数据库信息也不会丢失。

5.4 具名挂载和匿名挂载

除了指定路径挂载,还有不指定路径挂载,不指定路径挂载分为两种,具名挂载和匿名挂载

# 匿名挂载:只需指定容器内的路径
-v 容器路径
# 具名挂载:卷名:容器路径(常用,可以很方便的找到卷)
-v 卷名:容器路径

# 查看所有的卷情况
[root@aliyun ~]# docker volume ls
DRIVER              VOLUME NAME
# 这种就是匿名挂载
local               38e923e0eb2c97b615da006ebe828fa79beb428bd9690d8d9291fafd7f35e63a

# 具名挂载,以启动nginx为例
[root@aliyun ~]# docker run --name nginx01 -P -d -v juming-nginx:/etc/nginx nginx

# 在查看所有的卷情况
[root@aliyun ~]# docker volume ls
DRIVER              VOLUME NAME
local               38e923e0eb2c97b615da006ebe828fa79beb428bd9690d8d9291fafd7f35e63a
local               juming-nginx #这种就是具名挂载

# 查看具体的卷情况
[root@aliyun ~]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2020-06-04T09:14:41+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]
# 所有没有指定目录的容器中的卷,都存在/var/lib/docker/volumes/目录下

拓展,挂载后操作文件的权限:

# ro 与 rw

# 如果在-v容器路径后面添加ro,代表这个路径只能通过宿主机进行操作,容器只能读,不能修改
[root@aliyun ~]# docker run --name nginx01 -P -d -v juming-nginx:/etc/nginx:ro nginx
# 当你尝试去修改文件或者删除等操作时,会提示 Read-only file system
root@dbf2edeab1e0:/etc/nginx# rm -f nginx.conf
rm: cannot remove 'nginx.conf': Read-only file system

# 如果在-v容器路径后面添加rw,容器可读可写
[root@aliyun ~]# docker run --name nginx01 -P -d -v juming-nginx:/etc/nginx:rw nginx

6.DockerFile

DockerFile是用来构建Docker镜像的文件,一个命令脚本,通过脚本可以生成镜像

6.1 DockerFile构建过程

1.编写一个dockerfile文件

2.docker build 构建一个镜像

3.docker run 运行镜像

4.docker push 发布镜像到仓库

首先,定义一个DockerFile脚本

FROM centos
# 挂载容器目录,匿名挂载
VOLUME ["volume01","volume02"]
CMD echo  "---end---"
CMD /bin/bash

然后,用命令通过脚本构建出一个镜像

# docker build -f 脚本路径 -t 镜像名称 . 小数点不要忘记写
[root@aliyun ~]# docker build -f dockerfile01 -t dingjn/centos0 .

# 查看生成的镜像
[root@aliyun docker-test-volume]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
dingjn/centos         latest              a62f2759bc90        5 minutes ago       237MB

# 查看挂载的目录,这就是volume01和volume02挂载的目录,属于匿名挂载
[root@aliyun ~]# docker volume ls
DRIVER              VOLUME NAME
local               0ca3a36c0d38ac06941173bd3a98c2d3750f11ac4a8c48b1609da933c6048bf9
local               e44535e081df4011333688be151fdaaf252877f17e4f06cabe4b76528c94f0ba

# 查看挂载的具体信息
[root@aliyun ~]# docker volume inpect 0ca3a36c0d38ac.....

# 然后测试是否同步

6.2 DockerFile指令

通过这些指令来编写一个构建镜像的脚本!

FROM  			# 指定基础镜像,指基于哪个镜像构建的,centos、Ubonto、windows....
MAINTAINER  # 镜像是谁写的,姓名+邮箱
RUN					# 镜像构建时执行的命令
ADD   			# 添加文件,并且会自动将文件解压
WORKDIR 		# 镜像的工作目录
VOLUME  		# 挂载目录
EXPOSE  		# 端口配置
CMD 				# 容器启动时执行的命令,会覆盖
ENTRYPOINT  # 容器启动时执行的命令。会追加
COPY				# 将文件拷贝到镜像中,不会自动解压
ENV					# 构建的时候设置环境变量,比如mysql的MYSQL_ROOT_PASSWORD

CMD和ENTRYPOINT的区别

测试,

# 1.首先编写一个测试cmd的dockerfile文件,叫做dockerfile-cmd-test
FROM CENTOS
CMD ["ls","-a"]

# 2.构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .

# 3.运行镜像
docker run cmdtest

.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 4.运行时添加参数
docker run cmdtest -l

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
#提示错误,这是因为-l会替换掉["ls","-a"]

#而如果将dockerfile中的CMD替换成ENTRYPOINT,就不会报错,因为会追加为["ls","-a","-l"]

6.3 实战测试

构建一个centos镜像

1.编写dockerfile文件

# 基于centos镜像构建
FROM centos

# 作者信息
MAINTAINER dingjn<codedjn@163.com>

# 环境变量
ENV MYPATH /usr/local

# 工作目录
WORKDIR $MYPATH

# run时下载vim和net-tools
RUN yum -y install vim
RUN yum -y install net-tools

# 暴露端口
EXPOSE 80

# 运行容器时执行
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash

2.构建

docker build -f mydockerfile -t mycentos .

6.4 发布镜像

发布到DockerHub

1.在DockerHub注册自己的账号

2.开始提交镜像

# 1.登录,注册的账号和密码
[root@aliyun ~]# docker login -u dingjn
Password:
....
Login Succeeded

# 2.开始push,自己发布的镜像带上版本号
[root@aliyun ~]# docker push dingjn/centos:1.0

发布到阿里云镜像仓库

1.进入阿里云镜像地址

2.创建命名空间

3.创建镜像仓库

4.开始上传:

# 登录
$ sudo docker login --username=java丁江楠hh registry.cn-hangzhou.aliyuncs.com

# 修改镜像添加版本号
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/djn-basic/test:[镜像版本号]

#推送
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/djn-basic/test:[镜像版本号]

如果出现denied: requested access to the resource is denied,是因为镜像名称不对,需要使用registry.cn-hangzhou.aliyuncs.com/djn-basic/test作为前缀,替换为自己的命名空间+镜像仓库名称

7.整合Springboot

# 1.首先创建一个Springboot项目,然后打成jar包		--- demo.jar

# 2.编写DockerFile文件			---DockFile
FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

CMD echo "---end---"

# 3.将jar包和文件传输到服务器

# 4.然后执行dockerbuild命令执行DockerFile文件打成镜像
docker build -t demo .

# 5.docker run运行镜像
docker run demo

# 6.如果需要将镜像给别人运行,就发布到阿里云
sudo docker login --username=java丁江楠hh registry.cn-hangzhou.aliyuncs.com
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/djn-basic/test/demo:1.0
sudo docker push registry.cn-hangzhou.aliyuncs.com/djn-basic/test/demo:1.0
posted @ 2020-06-03 04:57  范特西-  阅读(429)  评论(0)    收藏  举报