Docker
Docker简介
简单介绍一下Docker,我们的软件程序编码完成后需要放到服务器上去运行,需要在服务器上安装各种环境,如java程序的jdk、mysql、redis、tomcat等等。像这样我们直接将项目部署在服务器上,会造成服务器资源的严重浪费,比如服务器200G的内存你只用了10G,还有就是测试运维也麻烦,他们要运行程序就必须安装一套一模一样的环境。
后来人们使用虚拟机来部署我们的应用程序,这样子一台物理服务器上就可以运行多台虚拟机,可以提高服务器的资源利用率,但是还是没有解决,每个运行环境都需要安装一套一模一样的环境这个繁琐的过程。
容器化技术其实就是解决上面问题的。所谓容器化就是将软件的运行环境打成一个包,谁要用把这个包拿过去解开就可以运行了。
总结:
物理机部署应用:各种环境的安装、成本高、资源利用不充分,浪费–>一个物理机安装多个虚拟机虚拟机:虚拟机需要安装操作系统麻烦、也要安装各种环境 —>容器化时代-容器化就是把各种环境打成包,谁要用这个环境拿过去解压一下就行了。
Docker是基于Go语言开发的开源的容器引擎,是容器化技术的代名词
Docker下载安装
-
访问www.docker.com
-
windows 安装docker
下载完成双击安装
安装完成如果报如下错误
请按链接博客的方法处理https://blog.csdn.net/qq_39611230/article/details/108625840
注意需要重启系统
查看docker是否安装成功docker versionC:\Users\admin>docker version Client: Docker Engine - Community Cloud integration: 1.0.12 Version: 20.10.5 API version: 1.41 Go version: go1.13.15 Git commit: 55c4c88 Built: Tue Mar 2 20:14:53 2021 OS/Arch: windows/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.5 API version: 1.41 (minimum version 1.12) Go version: go1.13.15 Git commit: 363e9a8 Built: Tue Mar 2 20:15:47 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.4 GitCommit: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e runc: Version: 1.0.0-rc93 GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec docker-init: Version: 0.19.0 GitCommit: de40ad0 C:\Users\admin>
docker的helloworld演示
使用一下docker:docker pull hello-world/C:\Users\admin>docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world b8dfde127a29: Pull complete Digest: sha256:f2266cbfc127c960fd30e76b7c792dc23b588c0db76233517e1891a4e357d519 Status: Downloaded newer image for hello-world:latest docker.io/library/hello-world:latest
运行一下上面拉取的docker镜像,看到hello from docker说明没有问题
C:\Users\admin>docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ C:\Users\admin>
linux安装docker —centos
注(centos7下载安装有问题的可以查看我的另一篇博文https://blog.csdn.net/weixin_40123223/article/details/115730274)
在命令行执行第一个命令安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
如果执行yum命令的过程中报下面的错误
。。。。。
。。。。。
yum.Errors.ConfigError: File contains no section headers.
file: file:///etc/yum.repos.d/docker-ce.repo, line: 1
解决方法请按照下面的博文
https://blog.csdn.net/weixin_43968936/article/details/84872513
执行第二个命令指定镜像源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
执行第三个命令更新仓库的源信息
sudo yum makecache fast
执行第四个命令下载docker
sudo yum -y install docker-ce
第五个命令启动docker服务
sudo service docker start
查看docker版本
docker version
拉取测试镜像
docker pull hello-world
运行测试镜像
docker run hello-world
看到如下内容docker安装成功
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
几个基本概念
镜像:是一个只读的文件,里面封装了软件及其运行环境,如:如果你想运行redis,可以下载一个包含redis运行环境的镜像
容器:提供镜像的运行环境,即,把上面的redis镜像放到容器里,我们就可以正常操作redis了,容器的创建由docker负责,容器之间彼此隔离
docker的执行流程:我们发送命令给docker。 如:docker pull hello-world ,docker就会检查本地镜像仓库中是否有该镜像,如果没有就去中央仓库去下载,下载完成之后dockers会把镜像放入容器中,我们就可以运行容器中的镜像
利用docker安装tomcat
访问hub.docker.com这是docker的中央仓库
命令行输入docker pull tomcat
查看镜像列表
docker images
运行镜像
docker run -p 8000:8080 tomcat
这里-p指定端口的映射,注意8080是在容器内部的端口,外面不能直接访问,需要做一个端口映射
C:\Users\admin>docker run -p 7800:8080 tomcat
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
21-Apr-2021 07:45:13.901 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/9.0.45
21-Apr-2021 07:45:13.904 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Mar 30 2021 10:29:04 UTC
21-Apr-2021 07:45:13.904 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.45.0
org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.45]
21-Apr-2021 07:45:14.593 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
21-Apr-2021 07:45:14.629 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [140] milliseconds
容器启动起来之后,可以按ctrl+c将命令行停止掉,不用担心tomcat会停掉,容器在后台运行,结束当前命令行不会停止容器
可以进入到容器里面查看其目录结构,执行下面命令
docker exec -it 容器编号 /bin/bash
提示符变了说明已经进入到了docker容器的内部目录结构,退出执行exit
然后打开浏览器访问
localhost:8000 看到猫说明tomcat容器启动成功
上图我启动的是7800,你可以自己定义端口,不要纠结
如果访问显示404 请使用下面方法解决
查看tomcat镜像容器内的目录里情况呢,需要建立与该容器通信的终端,使用下面命令进入容器目录
docker exec -it 容器编号 /bin/bash
查看容器编号使用docker ps
访问不到的主要原因是tomcat镜像目录下webapp目录下是空的,可以将webapps.dist目录下的文件拷贝到webapps下面,具体步骤可以参照下面博文
https://blog.csdn.net/elsostal/article/details/104408838
具体做法:
C:\Users\admin>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6476fbb9ff68 tomcat "catalina.sh run" 10 minutes ago Up 10 minutes 0.0.0.0:7800->8080/tcp strange_almeida
C:\Users\admin>docker exec -it 6476fbb9ff68 /bin/bash
root@6476fbb9ff68:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@6476fbb9ff68:/usr/local/tomcat# cd webapps
root@6476fbb9ff68:/usr/local/tomcat/webapps# ls
root@6476fbb9ff68:/usr/local/tomcat/webapps# cd ..
root@6476fbb9ff68:/usr/local/tomcat# cd webapps.dist/
root@6476fbb9ff68:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@6476fbb9ff68:/usr/local/tomcat/webapps.dist# tar -zcvf web.tar.gz *
ROOT/
manager/META-INF/context.xml
root@6476fbb9ff68:/usr/local/tomcat/webapps.dist# cp web.tar.gz ../webapps
root@6476fbb9ff68:/usr/local/tomcat/webapps.dist# rm web.tar.gz
root@6476fbb9ff68:/usr/local/tomcat/webapps.dist# cd ..
root@6476fbb9ff68:/usr/local/tomcat# cd webapps
root@6476fbb9ff68:/usr/local/tomcat/webapps# ls
web.tar.gz
root@6476fbb9ff68:/usr/local/tomcat/webapps# tar -zxvf web.tar.gz
ROOT/
ROOT/tomcat.svg
manager/META-INF/context.xml
root@6476fbb9ff68:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager web.tar.gz
root@6476fbb9ff68:/usr/local/tomcat/webapps# rm web.tar.gz
root@6476fbb9ff68:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
root@6476fbb9ff68:/usr/local/tomcat/webapps#exit
执行完上面的命令就可以解决问题
docker ps查看正在运行的容器 -a 所有容器,包括被停止的
各个字段的含义如下
容器的编号 镜像名称 容器内运行的命令 创建时间 状态 端口的映射
停止容器,docker stop 容器编号
重启容器 docker restart 容器编号
每次执行run命令都会创建全新的docker
docker run -p 8001:8080 tomcat
docker run -p 8002:8080 tomcat
删除创建的容器
docker rm 容器编号
删除本地仓库的镜像
docker rmi 镜像编号
可以使用docker images 查看镜像编号image_id
把中央仓库换成阿里云的镜像库
访问www.aliyun.com
复制加速器地址,每个人的都不一样,你要加速的话需要注册账户
任务栏-找到docker-右键settings
利用dockerfile构建自定义镜像
dockerfile是镜像的描述文件,告诉镜像要做哪些操作
演示
新建文件夹docker-web
在文件夹下新建index.html,内容如下
创建一个新的文件名叫Dockerfile,注意此文件没有任何扩展名,此文件和docker-web同级
Dockerfile的内容
#利用哪个基准镜像进行扩展
# 镜像名称:镜像版本 不清楚的可以用docker images查看
FROM tomcat:latest
# 指定镜像容器中放置web应用的目录
WORKDIR /usr/local/tomcat/webapps
# 复制本地文件到镜像目录,第一个参数是本地文件名,./对应的是WORKDIR对应的目录
ADD docker-web ./docker-web
查看镜像版本
镜像文件Dockerfile编写完成后就可以构建镜像了
构建新镜像 docker build -t 镜像名称:版本 dockerfile所在的目录
可以启动访问
注意启动的时候要带版本,不带版本默认为latest
docker run -p 7001:8080 my-web:1.0.0
启动后可以访问自己的index.html页面
查看镜像列表 docker images
查看对镜像文件的历史操作 docker history image_id
Dockerfile基本命令
注:为了方便将命令小写
from 基于基准镜像
from centos 制作基准镜像基于centos:latest
from scratch 不依赖任何基准镜像
from tomcat:1.1.2-jdk 限定基准镜像的版本
label 注释
label maintainer = “作者”
label version= “1.0”
label description = “我的镜像”
workdir 设置工作目录,尽量使用绝对路径
workdir /usr/local
workdir /usr/local/aaa 目录不存在会自动创建
add copy 复制文件
add hello / 将hello复制到根路径下
add test.tar.gz / 会自动解压文件,将解压后的文件放入指定目录下
add 除了复制,还具备添加远程文件的功能
add可以替换为copy
env 设置环境常量,尽量使用环境常量,可提高程序的维护性
env JAVA_HOME /usr/local/openjdk8
run ${JAVA_HOME}/bin/java -jar test.jar //运行指令
expose 暴漏容器端口 将容器内端口暴漏给物理机
expose 8080
expose 3306
docker run -p 8000:8080 tomcat
Docker的分层layer
镜像只是个文件,只有把镜像创建成容器才能运行
docker分为镜像层和容器层
镜像层负责存储只读的镜像文件
容器层负责对镜像文件的处理
一个镜像可以创建多个容器并且彼此隔离
演示:
先创建一个docker_mylayer的文件夹,在里面创建Dockerfile文件
Dockerfile的内容
FROM centos
RUN ["echo","我赌你的抢里没有子弹"]
RUN ["echo","你错了"]
RUN ["echo","那就试试吧"]
RUN ["echo","我赌的是子弹你赌的是命"]
构建镜像
docker build -t my-layer-img E:\aa\docker-mylayer
docker构建过程中,每一步都会存储为一个镜像层
如果你把上面的Dockerfile修改一下
FROM centos
RUN ["echo","我赌你的抢里没有子弹"]
RUN ["echo","你错了"]
RUN ["echo","那就试试吧"]
RUN ["echo","我修改了"]
再进行构建
docker build -t my-layer-img E:\aa\docker-mylayer
你会发现构建步骤直接跳过了前面的没变的内容,而是只构建了修改的内容
容器层是运行容器的时候创建
如:docker run docker-mylayer
DockerFile 执行指令
run:在build构建镜像的时候执行命令
entrypoint:容器启动的时候执行命令
cmd:容器启动时执行默认的命令或参数
docker build 创建镜像
docker run 创建容器
run可以修改镜像内部文件
cmd/entrypoint修改容器内部文件
run 构建时运行
run yum install -y vim shell的标准格式会开辟子进程运行该命令
run [“yum”,”install”,”-y”,”vim”] exec命令格式 在主进程运行该命令
entrypoint 容器启动时执行
dockerfile中只有最后一个entrypoint才会被执行
entrypoint 推荐使用exec格式执行命令
entrypoint [“ps”] 显示进程状态
cmd默认命令
cmd用于设置程序启动时默认执行的命令
如果在Dockerfile中出现了多个cmd,则只有最后一个会被执行
如果容器启动时附加了执行,则所有的cmd都被忽略
cmd [“ps”,”-ef”] 推荐使用exec格式的命令
所有命令后都要有空格
cmd和entrypoint在一定成都上可以互换,但是也有区别
FROM centos
RUN [“echo”,“我赌你的抢里没有子弹”]
ENTRYPOINT [“ps”]
CMD [“-ef”]
docker run mylayer -aux
当带有附加命令时会覆盖cmd的内容,并且上面的entrypoint和cmd可以合并使用
在Dockerfile文件中使用上面命令示例:
创建shell文件夹并在其下面创建Dockerfile文件,编写Dockerfile文件
#echo时在控制台打印信息,有点想java中的println
注意双引号和都好都是英文
FROM centos
RUN echo “image building”
CMD [“echo” ,“container starting”]
构建镜像脚本如下
docker build -t shell E:\a\shell
启动容器
cocker run shell
修改Dockerfile文件
FROM centos
RUN echo “image building”
CMD [“echo” ,“container starting”]
CMD [“echo” ,“容器正在启动”]
重新构建镜像
docker build -t shell E:\a\shell
重新启动查看区别
docker run shell
出现了中文乱码,请忽略这些细节
带着默认值启动查看效果
docker run shell echo “starting”
快速部署mysql并初始化数据
先访问hub.docker.com查看mysql镜像
页面往下拉一下可以看到mysql的版本
点击对应的版本,进入到该版本的github界面,并显示器dockerfile构建镜像的脚本
该页面往下拉,可以查看脚本信息
演示
新建文件夹sampledb,把init.sql脚本放到该文件夹下,init.sql内容如下:
create database `docker_mysql`;
use docker_mysql;
-- 建表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL,
`created_at` bigint(40) DEFAULT NULL,
`last_modified` bigint(40) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 插入数据
INSERT INTO `user` (`id`, `created_at`, `last_modified`, `email`, `first_name`, `last_name`, `username`)
VALUES
(0,435345,45345435,'hhh.doe@example.com','kk','uuu','user');
拉取镜像
docker pull mysql:5.7
查看镜像列表
docker images
然后再sampledb目录下在创建Dockerfile文件
FROM mysql:5.7
WORKDIR /docker-entrypoint-initdb.d #这个目录是上面mysql的Dockerfile文件中指定的
ADD init.sql . # . 点表示上面Workdir的目录
构建
docker build -t sampledb E:\aaa\sampledb
创建容器并启动
docker run -p3310:3306 -e MYSQL_ROOT_PASSWORD=root sampledb
-e表示环境常量,这里的这个常量时mysql5.7镜像里面定义的,用于定义密码
netstat -ano 查看是否出现了3310端口
mysql镜像的详细使用可以参看页面文档:进入mysql进行往下拉就是
然后可以访问数据库了
C:\Users\admin>mysql -P 3310 -u root -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>