docker技术的应用
1安装
(1)卸载旧版
sudo yum remove docker-ce \
docker-ce-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
(2)安装一组工具
sudo yum install -y yum-utils
(3)设置yum仓库地址
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)更新yum缓存
sudo yum makecache fast #yum 是包管理器
(5)安装新版docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
2docker入门实践
1基本操作
(1)启动docker
sudo systemctl start docker
(2)设置docker开机启动
sudo systemctl enable docker
(3)镜像加速
由于国内网络问题,需要配置加速器来加速。修改配置文件 /etc/docker/daemon.json
下面命令直接生成文件 daemon.json
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/var/lib/docker"
}
EOF
说明:在执行如上指令时,保证你的登录用户为root管理员用户。
(4)重新启动服务
重新加载docker配置
sudo systemctl daemon-reload
重启docker服务
sudo systemctl restart docker
(5)查看镜像配置
docker info
(6)运行hello-world镜像,验证docker
sudo docker run hello-world
(7)检查docker镜像
docker images
(8)检查已启动的docker服务(正在运行的)
docker ps
假如希望查看所有镜像,包含没有运行的镜像容器,可以执行如下指令:
docker ps –all
(9)停止dockere服务
docker stop 服务id
(10)删除docker镜像
docker image rm hello-world
假如镜像被占用着是不可以直接被删除的,需要先删除应用此镜像的容器,例如
docker container rm 容器名或容器id
(11)查看日志信息
docker container logs xxx
例如查看docker中的redis日志信息
docker container logs redis
也可以根据id查看docker容器中的日志
docker container logs 9fcf8
(12)查看docker挂载信息
docker inspect xxx
例如,查看redis的挂载信息
docker inspect redis
3核心对象分析
1镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
2容器
镜像(Image)和容器(Container)的关系,就像是光盘和光驱,容器是镜像运行时的载体。容器可以被创建、启动、停止、删除、暂停等。
容器的本质是进程,但与直接在宿主机执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
3数据卷
镜像使用的是分层存储方式,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层(我们可以称这个为容器运行时执行读写操作而准备的存储层)
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
4镜像操作实践
(1)下载
下载 CentOS 镜像 (说明,假如是自己制作镜像,都会先下载一个空的centos镜像,官方镜像仓库地址为https://hub.docker.com/),假如后面我们要自己做镜像,都需要这样的一个空的系统镜像文件。
docker pull centos:7
(2)查看centos7镜像文件
docker images
或者
docker image ls
(3)运行镜像
通过docker启动运行 centos7镜像
docker run -it xxxx bash
xxxx - 镜像名, 或 image id 的前几位
-it 这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
bash 放在镜像名后的是命令,这里我们希望有个交互式,因此用的是。
(4)删除镜像文件
假如镜像不需要了可删除镜像,案例如下:
删除镜像id前缀为345的 镜像,一般三位以上,足够区分即可。
docker image rm 345
删除指定镜像名的镜像
docker image rm centos
4docker容器操作实践
1启动分析
通过 docker run 来创建启动容器(这个容器相当于一个独立的集装箱)
docker run -it centos:7 bash
docker 在后台运行的标准操作包括:
-
检查本地是否存在指定的镜像,不存在就从公有仓库下载
-
利用镜像创建并启动一个容器
-
分配一个文件系统(简版linux系统),并在只读的镜像层外面挂载一层可读写层
-
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
-
从地址池配置一个 ip 地址给容器
-
执行用户指定的应用程序
后台运行
docker run -dit centos:7
-d 后台运行容器
容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。
2查看容器信息
查看后台运行的容器输出结果
docker container logs 802
查看docker中的容器
docker container ls -a
或
docker ps -a
其中,-a all, 全部
列出正在执行的container
sudo docker container ls
列出所有执行过的container记录
sudo docker container ls --all
列出所有的container ID
sudo docker container ls -a -q
查看运行状态
sudo docker ps
history 运行状态与container 类似
sudo docker ps -all
3停止或重启容器
停止运行的容器,代码如下:
docker container stop 802
重新启动容器,代码如下:
docker container restart 802
4进入指定容器
当需要进入容器进行操作时(容器运行着),可以使用 docker exec 命令,例如:
docker exec -it 802 bash #802为容器id
5退出容器
假如从宿主机进入了启动的容器,退出容器需要使用exit指令,例如:
exit
6删除容器
如容器不用了,可执行删除操作,例如:
docker container rm 802 #802为容器id
其中,如果删除运行中的容器,需要添加 -f 参数。
清理所有终止状态容器,例如
docker container prune
5docker数据管理实践
1概述
在容器中管理数据主要有两种方式:
挂载主机目录 (Bind mounts)-最常用 (docker run –v 宿主机目录:容器目录)
数据卷(Volumes)
2数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,可以在容器之间共享和重用,默认会一直存在,即使容器被删除。
3数据卷操作(了解)
(1)创建数据卷
docker volume create container-vol
(2)查看所有数据卷
docker volume ls
查看指定数据卷的信息
docker volume inspect container-vol
查询的结果:
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/container-vol/_data",
"Name": "container-vol",
"Options": {},
"Scope": "local"
}
]
(3)启动挂载数据卷的容器
docker run -it --mount source=container-vol,target=/root centos:7 bash
(4)删除数据卷(如果数据卷被容器使用则无法删除)
docker volume rm container-vol
清理无主数据卷
docker volume prune
(5)挂载主机目录
docker run -it -v /usr/app:/opt/app centos:7 bash
其中:
1)/usr/app:为宿主机目录
2)/opt/app: 为启动容器的一个目录
3)-v 用于指定挂载目录,如果本地目录(宿主机目录)不存在, Docker 会自动为你按照挂载目录进行目录的创建。
查看挂载目录信息
docker inspect 91a #91a 为容器id
显示结果:
...
"Mounts": [
{
"Type": "bind",
"Source": "/usr/app",
"Destination": "/opt/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...
(5)什么是Docker容器数据卷
首先,我们来回顾下Docker的理念:
- 将应用和运行的环境打包形成镜像,然后再由镜像创建容器并运行,这过程随着容器的运行,可能会产生一些数据,但是Docker容器产生的数据,如果不通过docker-commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。
所以,为了能保存容器运行过程中产生的数据,我们使用数据卷来实现持久化。 另外,也可以实现容器间继承+共享数据。
(6)Docker容器数据卷的特点
数据卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
- 1:数据卷可在容器之间共享或重用数据
- 2:卷中的更改可以直接生效
- 3:数据卷中的更改不会包含在镜像的更新中
(7)给容器添加数据卷
命令格式:
命令格式:
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
比如:
docker run -it -v /hostDatavolume:/containerDatavolume centos /bin/bash
(8)查看是否挂载成功
1,查看相关的目录是否创建成功
2,查看绑定关系是否已经建立
docker inspect 容器ID
(9)数据共享测试
1,容器和宿主机之间数据共享
我们通过在宿主机的环境和容器的环境下,分别操作文件,观察数据是否可以同步
2,容器停止退出后,主机修改后数据是否同步
(1),容器先停止退出
(2),宿主机修改文件
(3),重新启动容器
(4),观察文件是否同步
(10)设置制度数据卷
命令格式:docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
例如:
docker run -it -v /hostDatavolumeRo:/containerDatavolumeRo:ro centos
在容器内执行创建文件:
(11)创建并启动容器
命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
docker run -it -v /宿主机目录:/容器目录 镜像名 /bin/bash
OPTIONS说明:
--name="容器名字": 为容器指定一个名称;
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-p: 指定端口映射,hostPort:containerPort
-e: 设置环境变量;
-v 操作在容器创建的过程时候可以将宿主机的目录挂载到容器内
根据一个镜像,创建并且启动一个容器,如果本地没有该镜像会自动去远程库中拉取
举例:
docker run --name tomcat -d -p 8080:8080 [docker.io/tomcat](https://link.zhihu.com/?target=http%3A//docker.io/tomcat)
在容器内部该目录下,或者宿主机内部该目录下,修改文件、创建文件,彼此都会同步修改
容器和宿主机之间数据共享默认情况下,对于容器而言是读写的权限,可以使用 ro ,使容器只有读权限
sudo docker run -itd -v ~/docker_test:/home:ro ubuntu /bin/bash
(12)docker --restart=always 参数 docker重启容器自动重启
docker --restart=always 参数 docker重启容器自动重启
创建容器时添加参数 --restart=always
后,当 docker 重启时,容器自动启动。
使用方法:
docker container update --restart=always 容器名字
(13)docker容器与宿主机之间文件相互拷贝
从宿主机拷文件到容器里面
示例: 假设容器id da96d9c8f2ea,现在要将宿主机 /mnt/jar_file/eureka-0.0.1-SNAPSHOT.jar 文件拷贝到容器里面的/tmp 路径下面,那么命令该怎么写呢?
[root@localhost]# docker cp /mnt/jar_file/eureka-0.0.1-SNAPSHOT.jar da96d9c8f2ea:/tmp
一定要看清楚,冒号后没有空格,网上有的文章有空格,切记
docker cp [宿主机路径] 容器id:[容器目录]
从容器里面拷文件到宿主机
示例: 假设容器id da96d9c8f2ea,要从容器里面拷贝的文件路为:/tmp/tomcat.1484336096545995294.8761, 现在要将test.js从容器里面拷到宿主机的/mnt/jar_file/路径下面
[root@localhost jar_file]# docker cp da96d9c8f2ea:/tmp/tomcat.1484336096545995294.8761 /mnt/jar_file/
docker cp 容器id:[容器中文件] [宿主机路径]
cp -a 在保留原文件属性的前提下复制文件
在linux中""反斜线使行得以继续,命令可以正常输入。
(14)option说明
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
--name="nginx-lb": 为容器指定一个名称;
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
实例
使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。
docker run --name mynginx -d nginx:latest
使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。
使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。
docker run -P -d nginx:latest
使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。
docker run -p 80:80 -v /data:/data -d nginx:latest
绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。
绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。
docker run -p 127.0.0.1:80:8080/tcp ubuntu bash
使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
runoob@runoob:~$ docker run -it nginx:latest /bin/bash
root@b8573233d675:/#
6Dockerfile文件应用实践
1概述
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。我们通常会基于此文件创建docker镜像。
2准备工作
(1)centos:7镜像 (所有的镜像文件创建时都需要有一个空的centos镜像,就类似通过一个空的光盘或u盘创建一个系统启动盘是一样的)
(2) jdk压缩包 jdk-8u51-linux-x64.tar.gz(可以从官网去下载:oracle.org),基于此压缩包,制作jdk镜像。
3Dockerfile文件
在创建新的镜像时都需要有一个Dockerfile文件(文件名一定要注意大小写),这个文件要与你的资源放在一起(例如你下载的jdk),我们可以通过linux系统中的touch指令创建此文件(touch Dockerfile)
现在,以centos7为基础,构建oracle jdk8的镜像,首先通过vim打开Dockerfile,这个文件不存在会自动创建。然后进入编辑模式(按i字母),在编辑模式下可以拷贝如下语句(自己手动写也可以,但确保写的单词正确,大小写,空格)。
第一步:编写FROM语句(关键字一定要大写,例如FROM不能写小写)
FROM centos:7
第二步:通过ADD命令将宿主机中的压缩包传入镜像容器中的指定目录,并同时解压缩
ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker
第三步:设置环境变量(通过ENV关键字实现,目录启动容器中的目录)
ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \
PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH
第四步:指定命令行操作(所有指令与后面内容要有空格)
CMD [‘bash’]
完整示例如下:(注意关键字与后面内容之间的空格,可以将如下完成示例拷贝Dockerfile文件,但是一定要注意你的jdk名字是什么)
FROM centos:7
ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker
ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \
PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH
CMD ['bash']
使用 Dockerfile 构建镜像(在Dockerfile所在目录执行docker指令)
docker build -t jdk:8 . #不要丢掉这里的点
注意末尾的点,表示构建过程中从当前目录寻找文件,jdk:8为我们创建的镜像名。
4运行镜像文件
docker run –it jdk:8 bash
进入容器以后,可以通过echo $PATH查看环境变量,并可以通过java –version查看JDK版本信息。
FAQ:如何通过此镜像运行一个web服务,例如zipkin(链路监控),sentinel等。
第一步:将zikin,sentinel拷贝宿主机指定目录,例如/root/servers目录(servers目录不存在可以自己创建)。
第二步:启动镜像容器,通过java执行运行web服务
基于jdk:8镜像启动运行zipkin服务(服务启动后可在宿主机通过localhost:9411进行访问).
docker run –dit -p 9411:9411 --name zipkin –v /root/servers:/usr/sca jdk:8 java –jar /usr/sca/zipkin-server-2.23.2-exec.jar
基于jdk:8镜像启动运行sentinel服务(服务启动后可在宿主机通过localhost:8180进行访问)
docker run –dit -p 8180:8080 --name sentinel –v /root/servers:/usr/sca jdk:8 java –jar /usr/sca/sentinel-dashboard-1.8.0.jar
5镜像导出导入操作
镜像导出(linux系统中的镜像文件下载到本地-例如window),导出后给他人使用
docker save jdk:8 | gzip > jdk8.tar.gz
镜像导入(要在jdk8.tar.gz文件所在目录下执行)
docker load < jdk8.tar.gz