之前对 docker 只是简单的使用,会操作基本命令。这周末对 docker 进行了复习,这次才真正理解了 docker 的精髓,原来之间的 docker 命令只是简单的入门。理解数据卷、使用 dockerfile 才是在实际项目中可能使用的。
希望这个博客可以系统的帮你了解 docker,领略它的精髓。
1 Docker 概述
1.1 为了解决什么问题?
开发对项目开发完毕后,交给测试人员进行测试的时候会因为环境和配置的问题而导致项目的差异。
开发人员利用Docker可以在安装的时候,把原始环境一模一样地复制过来,消除协作编码时“在我的机器上可以正常运行”的问题。
集群部署过程中为了解决在多台服务器上重复安装软件,配置环境。通过镜像将系统所需要的环境进行打包,达到应用程序跨平台间的无缝接轨运作
1.2 优点
DevOps(开发、运维)
-
应用更快速的交付和部署
- 传统:一对帮助文档,安装程序。
- Docker:打包镜像发布测试一键运行。
-
更便捷的升级和扩缩容
- 使用了 Docker之后,我们部署应用就和搭积木一样
- 项目打包为一个镜像,扩展服务器A!服务器B
-
更简单的系统运维
- 在容器化之后,我们的开发,测试环境都是高度一致的
-
更高效的计算资源利用
- Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
2 Docker安装
2.1 环境要求
Linux 内核 3.0 以上,使用命令进行查看
[root@iz2ze5d0fgh0v0c0oi7xmzz ~]# uname -r
3.10.0-1062.1.1.el7.x86_64
# 查看配置
[root@iz2ze5d0fgh0v0c0oi7xmzz ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
2.2 下载
参考官网文档 https://docs.docker.com/engine/install/
#1.卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2.需要的安装包
yum install -y yum-utils
#3.设置镜像的仓库, 默认是从国外的,不推荐,可以设置为阿里云的
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#推荐使用国内的
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4.更新yum软件包索引
yum makecache fast
#5.安装docker相关的 docker-ce 社区版 而ee是企业版
yum install docker-ce docker-ce-cli containerd.io
#6. 使用docker version查看是否按照成功
docker version
#7. 测试
docker run hello-world
# 查docker镜像
docker images
2.3 卸载 docker
#1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2. 删除资源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默认工作路径!
2.4 添加阿里云的镜像加速
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xy8nrzhm.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3 Docker命令
帮助命令
docker version
docker info
# 查看帮助
docker --help
3.1 镜像命令
# 查看本地镜像
docker images
# 列出本地所有镜像
>docker images -a
# 查看本地镜像只显示 ImageId
docker images -q
# 显示镜像的摘要信息
docker images --digests
# 显示完整的镜像信息
docker images --no-trunc
docker search 某个镜像名字
# 搜索https://hub.docker.com上某个镜像
docker search tomcat
# 搜索点赞超过30的tomcat
docker search -s 30 tomcat
docker pull 某个镜像名字
# 下载镜像,默认是最新版本
docker pull tomcat
# 同
docker pull tomcat:lastest
docker rmi 镜像名字
docker rmi tomcat
# 加入 -f ,强制删除
docker rmi -f tomcat
# 删除多个镜像
docker rmi -f tomcat nginx
# 删除全部
docker rmi -f $(docker images -qa)
3.2 容器命令
# 镜像id 新建容器并启动
docker run
# 列出所有运行的容器 docker container list
docker ps
# 删除指定容器
docker rm 容器id
#启动容器
docker start 容器id
#重启容器
docker restart 容器id
#停止当前正在运行的容器
docker stop 容器id
#强制停止当前容器
docker kill 容器id
退出容器
# 容器直接退出
exit
# 容器不停止退出
ctrl +P +Q
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf
docker rm -f $(docker ps -aq) #删除指定的容器
docker ps -a -q|xargs docker rm #删除所有的容器
3.3 操作命令
后台启动命令
docker run -d centos
进入当前正在运行的容器
# 方式一
docker exec -it 55321bcae33d /bin/bash
# 方式二
docker attach 55321bcae33d
##### 区别 ####
#docker exec #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
#docker attach # 进入容器正在执行的终端
从容器内拷贝数据到主机上
# 1、先进入容器中
docker exec -it dv321bcae33d /bin/bash
# 2、进行复制
docker cp dv321bcae33d:/text.txt / #拷贝
3.4 Demo
docker启动 nginx
# 启动运行 Nginx,指定端口
docker run -d -p 8002:80 nginx
启动 tomcat
# 拉取 tomcat
docker pull tomcat
# 启动
# -p 宿主机端口:容器内部端口
docker run -d -p 8001:8080 --name tomcat docker.io/tomcat
# 进入容器
docker exec -it 133a6c5addd3 /bin/bash
# 发现 webapps 下没有文件,解决办法,将 webapps.dist 下的文件进行复制到 webapps
cp -r webapps.dist/* webapps
再次访问,没有问题
curl localhost:8001
4 Docker镜像
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
4.1 commit 镜像
使用 commit 制作自己的镜像
由于 docker 上的 tomcat webapps 下没有文件,解决办法,将 webapps.dist 下的文件进行复制到 webapps,然后将这个新的进行进行提交保存,这样下次使用 tomcat 镜像,可以直接使用自己的(即 webapps 有文件的)
# docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -m="add webapps app" -a="wmding" 133a6c5addd3 my_tomcat:1.0
# 再次启动 d320039e29a2 为新镜像的 id
docker run -d -p 8001:8080 d320039e29a2
5 容器数据卷
5.1 使用数据卷
# 方式一
docker run -it -v 主机目录:容器内目录
# 挂载
docker run -it -p 8080:8001 -v /home/test:/home d320039e29a2 /bin/bash
# 查看
docker inspect 容器id
docker inspect 156ab0613b8f
如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y3ipTBsC-1592147939783)(/Users/wmding/Desktop/image-20200614101259245.png)]
使用挂载就实现了,主机和容器的连接,实现了数据的同步,
# 停止正在运行的容器
docker stop 156ab0613b8f
# 在主机中添加一个文件,看是否容器类是否可以数据同步
# 启动容器
docker start 156ab0613b8f
# 进入正在运行的容器
docker attach 156ab0613b8f
使用这种方式,之后只需要在本地修改即可,容器内会自动同步,就不容进去容器中进行修改了。
安装MySQL
# 获取镜像
docker pull mysql:5.7
# 注意,在启动mysql时需要制定密码
docker run --name some-mysql -e MY_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动
-d 后台启动
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
docker run -d -p 3301:3306 -v /home/mysql/conf:/ect/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql_5.7 docker.io/mysql
# 启动后,使用工具在进行连接,测试完成
5.2 具名和匿名挂载
上边的挂载,是指定了要挂载的目录;如果不指定目录,即为匿名挂载,如下:
# 匿名挂载
# -v 容器内地址,然后会默认在主机上的 docker 目录下,新建一个映射的文件
docker run -d -p 8001:80 -v /ect/nginx nginx
# 查看该容器挂载的卷
docker inspect 5bec313d13f7
# /var/lib/docker/volumes/578996253fdb969e9d5e05c623503735a5f351359041423ca0360dc1d1783a17/_data
# 具名挂载,指定了主机的文件名,但是没有指定路径,会默认在 docker 目录中
docker run -d -p 8002:80 -v nginx_test:/ect/nginx nginx
# 查看挂载的卷
docker inspect ee4c4f0ee362
# /var/lib/docker/volumes/nginx_test/_data
#######
"Mounts": [
{
"Type": "volume",
"Name": "nginx_test",
"Source": "/var/lib/docker/volumes/nginx_test/_data",
"Destination": "/ect/nginx",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
#######
总结
三种挂载:
-
匿名挂载
- -v 容器内路径
-
具名挂载
- -v 卷名:容器内路径
-
指定路径挂载
-v /宿主机路径:容器内路径
# 通过 -v 容器内路径:
ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
docker run -d -P --name nginx01 -v nginx_test:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nginx_test:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
6 DockerFile
Dockerfile 就是用来构建docker镜像的构建文件,命令脚本。
- 编写一个 dockerfile 文件
- docker build 构建一个镜像
- docker run 运行镜像
- docker push 发布镜像
6.1 Dockerfile 构建过程
-
每个关键字指令,都必须是大写字母
-
执行顺序,从上到下
-
#
表示注释 -
每一个指令都会创建提交一个新的镜像层,并提交。
Dockerfile 是面向开发的,做镜像,就需要编写 dockerfile逐渐成为了我们交付的标准。
Dockerfile:构建文件,定义了一切步骤,源代码
DockerImages:通过Dockerfile 构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务的
6.2 Dockerfile 命令
# 基础镜像,一切从这里构建
FROM
# 镜像是谁写的,姓名 + 邮箱
MAINTAINER
# 镜像构建的时候需要的命令
RUN
# 添加内容
ADD
# 镜像的工作目录
WORKDIR
# 挂载的目录
VOLUME
# 暴露端口
EXPOSE
# 指定这个容器启动的时候要运行的命令
CMD
# 指定这个容器启动的时候要运行的命令,可以追加命令
ENTRYPOINT
# 当构建一个被继承 Dockerfile ,这个时候就会运行 ONBUILD 命令,触发指令
ONBUILD
# 复制,将文件拷贝到容器中
COPY
# 构建的时候设置环境变量
ENV
Centos 的官方例子
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200504" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-05-04 00:00:00+01:00"
CMD ["/bin/bash"]
6.3 实例
6.3.1 编写 Dockerfile
FROM centos
MAINTAINER wmding<546048371@qq.com>
# 设置工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 8001
CMD echo $MAPATH
CMD echo "----end----"
CMD /bin/bash
6.3.2 docker build 镜像
# 命令 docker build -f 文件路径 -t 镜像名:[tag] .
docker build -f dockerfile-centos -t mycentos:1.0 .
# 一定要注意这个点 .
6.3.3 启动
# 因为在构建镜像的时候写版本号了,这里要需要有版本号,否则会要从远端查询
docker run -it mycontos:1.0
列出本地进行的变更历史,可以使用这个命令查看其他镜像是如何制作的
docker history aadfdfdke
6.4 CMD 和 ENTRYPOINT区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
# 想追加一个命令 -l 成为ls -al
$ docker run cmd-test:0.1 -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.
ERRO[0000] error waiting for container: context canceled
# cmd的情况下 -l 替换了CMD["ls","-l"]。 -l 不是命令所有报错
测试ENTRYPOINT
# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
6.5 Tomcat 镜像
6.5.1 准备镜像文件
事先下载好 tomcat 和 jdk 文件,编写 README
6.5.2 编写 dockerfile
FROM centos
MAINTAINER wmding<546048371@qq.com>
COPY README /usr/local/README #复制文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压
RUN yum -y install vim
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是:
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 设置默认命令
6.5.3 构建镜像
# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
$ docker build -t mytomcat:0.1 .
6.5.4 运行镜像
$ docker run -d -p 8080:8080 --name tomcat01 -v /home/docker_test/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/docker_test/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
6.6 SpringBoot微服务打包Docker镜像
6.6.1 构建SpringBoot项目
自行构建
6.6.2 打包项目
mvn package
6.6.3 编写dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
6.6.4 构建镜像
# 1.复制 jar 和 dockerfile到服务器
# 2.构建镜像
docker build -t xxxxx:xx .