1 docker概述
1.1 docker是什么?
开发和运维的环境不同,可能导致程序在开发的环境中可以正常运行而在运维的环境中出错。为了解决这个问题, docker可以将项目和环境一起打包,可以保持项目和环境保持一致。(问题驱动,需求驱动)
1.2 docker发展
1. Docker 公司位于旧金山,由法裔美籍开发者和企业家 Solumon Hykes 创立,起初是一家名为 dotCloud 的提供Paas的公司。
2. 2013年,dotCloud 的 PaaS 业务并不景气,公司需要寻求新的突破。于是他们聘请了 Ben Golub 作为新的 CEO,将公司重命名为“Docker”,放弃dotCloud PaaS 平台,怀揣着“将 Docker 和容器技术推向全世界”的使命,开启了一段新的征程。
- 现今的Docker 公司已经通过多轮融资,吸纳了来自硅谷的几家风投公司的累计超过 2.4 亿美元的投资。
- docker相比于虚拟机,十分的小巧,启动快速
1.3 docker的特点
与传统虚拟化方法相比, 传统的虚拟机虚拟完整的硬件, 然后在系统上运行软件,而容器没有硬件和内核,所以非常轻便, 而且容器之间隔离的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmn5vXcT-1632447380520)(E:\blogpic\docker1.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRa8IowA-1632447380524)(E:\blogpic\docker2.png)]
1.4 使用docker后 DevOps 开发与运维的变化
- 应用更快速的交付和部署,传统一堆帮助文档需要安装环境,现在一键部署
- 更便捷的升级和扩缩容,项目打包成一个镜像,像搭积木一样部署
- 更简单的系统运维,开发测试运维的环境高度一致
- 更高效的计算资源利用,一个服务器上可以运行多个容器,提高资源利用效率。
2 docker的使用
2.1 docker基本概念
docker镜像就像模板,可以通过模板来创建容器服务,
通过容器可以独立运行一个或一组应用,就像一个简易的linux系统
仓库就是存放镜像的地方,分为共有仓库和私有仓库
2.2安装docker
2.2.1环境准备
服务器:腾讯云服务器
系统: centos 7
内核版本: 3.10.0-1160.31.1.el7.x86_64
系统版本:[root@VM-4-6-centos ~]$ 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.2 安装
-
[docker官网](Get Docker | Docker Documentation)选择适合的系统,版本 -
若安装过,卸载旧的版本 sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
-
通过库安装 # 1 安装依赖库
sudo yum install -y yum-utils
# 2 安装docker仓库
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
# 3 安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
-
启动docker
sudo systemctl start docker
docker version
Client: Docker Engine - Community
Version: 20.10.8
API version: 1.41
Go version: go1.16.6
Git commit: 3967b7d
Built: Fri Jul 30 19:55:49 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.8
API version: 1.41 (minimum version 1.12)
Go version: go1.16.6
Git commit: 75249d8
Built: Fri Jul 30 19:54:13 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.19.0
GitCommit: de40ad0
- docker hello word
sudo docker run hello-world
2.2.3 卸载dcoker
分为两步,卸载docekr,删除文件
# 1 卸载
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2删除文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
2.2.4 配置腾讯云镜像加速
使用腾讯云 Docker 镜像源加速镜像下载
安装 Docker 软件后,如果未配置镜像加速源,直接拉取 DockerHub 中的镜像,通常下载速度会比较慢。 为此,我们推荐您使用腾讯云 Docker 镜像源加速镜像下载。
适用于 Linux 操作系统实例:
#1 找到配置文件
cd /etc/docker/daemon.json
#2 vim编辑配置文件
vim /etc/docker/daemon.json
#3 添加以下内容并保存
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
#4 重启docker生效
systemctl restart docker
3 docker是如何工作的?
3.1运行docker run image发生什么
3.2 docker 底层原理
docker是一个client-server结构的系统,docker的守护进程运行在宿主机上,通过socket连接。
dockerserver 接收到dockerclient的指令,就好执行这个命令。
- docker比vm更少的抽象层,不需要guest os,省去了很多启动引导过程。
4 docker 命令
docker官网有所有的命令说明(Reference documentation | Docker Documentation), 菜鸟网也有中文版本的命令说明。命令详细用法在help和文档中都可以查到,这个不再赘述,主要给出常用命令,对docker能做什么以及怎么做有个概念。
4.1基础命令
docker command --help # 帮助命令
docker info # 系统信息
docker version # 版本信息
4.2 镜像命令
docker images # 查看镜像
docker search image # 搜索镜像
decher pull image # 下载镜像
docker rmi image # 删除镜像
4.3 容器命令
有了镜像才可以下载容器
docker run container # 启动容器
exit # 停止运行并退出容器
ctrl + p + q # 退出容器
docker ps # 查看运行的容器
docker rm container # 删除容器
docker start container # 启动容器
docker restart # 重启容器
docker stop container # 停止容器运行
docker kill container # 强制停止容器
4.4 其他常用命令
docker logs # 查看日志
docker ps # 查看容器进程
docker top # 查看容器内进程
docker inspect # 查看镜像的元数据
docker exec container_id # 进入在执行的容器打开新的终端
docker attach container_id # 进入容器正在执行的终端
docker ps container_id:path hostpath # 容器内复制文件到宿主机
按照字母排序总结:
attach Attach to a running container #当前shell下attach连接指定运行镜像
build Build an image from a Dockerfile #通过Dockerfile定制镜像
commit Create a new image from a containers changes #提交当前容器为新的镜像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同run 但不启动容器
diff Inspect changes on a containers filesystem #查看docker容器变化
events Get real time events from the server#从docker服务获取容器实时事件
exec Run a command in a running container#在已存在的容器上运行命令
export Export a containers filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
history Show the history of an image #展示一个镜像形成历史
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
info Display system-wide information #显示系统相关信息
inspect Return low-level information on a container or image #查看容器详细信息
kill Kill a running container #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Register or log in to a Docker registry#注册或者登陆一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within a container#暂停容器
port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
rename Rename a container #重命名容器
restart Restart a running container #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image(s) to a tar archive#保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在docker
hub中搜索镜像
start Start one or more stopped containers#启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop a running container #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within a container #取消暂停容器
version Show the Docker version information#查看容器版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
5 docker实例操作
5.1 部署Nginx
1 搜索nginx镜像
root@VM-4-6-centos /]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 15374 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 2060 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 816 [OK]
jc21/nginx-proxy-manager Docker container for managing Nginx proxy ho… 236
docker hub可以看大更详细的镜像信息
2 下载镜像
[root@VM-4-6-centos /]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
e1acddbe380c: Pull complete
e21006f71c6f: Pull complete
f3341cc17e58: Pull complete
2a53fa598ee2: Pull complete
12455f71a9b5: Pull complete
b86f2ba62d17: Pull complete
Digest: sha256:4d4d96ac750af48c6a551d757c1cbfc071692309b491b70b2b8976e102dd3fef
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
# 下载成功
3 查看镜像
[root@VM-4-6-centos lighthouse]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest dd34e67e3371 10 days ago 133MB
4 运行容器
[root@VM-4-6-centos lighthouse]# docker run -d --name nginx001 -p 80:80 nginx
44c86d145d151622d0e7512050c4fead714047be0256c7f6af098ec0452ba428
5 查看容器
[root@VM-4-6-centos lighthouse]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44c86d145d15 nginx "/docker-entrypoint.…" 35 minutes ago Up 35 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp nginx001
6 测试
[root@VM-4-6-centos lighthouse]# docker exec -it nginx001 /bin/bash
root@44c86d145d15:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
外网访问:
7关闭容器
[root@VM-4-6-centos lighthouse]# docker stop nginx001
nginx001
5.2 部署tomcat
1 搜索nginx镜像
[root@VM-4-6-centos lighthouse]# docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementati… 3106 [OK]
tomee Apache TomEE is an all-Apache Java EE certif… 92 [OK]
dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 base… 58 [OK]
kubeguide/tomcat-app Tomcat image for Chapter 1 30
consol/tomcat-7.0 Tomcat 7.0.57, 8080, "admin/admin" 18 [OK]
cloudesire/tomcat Tomcat server, 6/7/8 15 [OK]
aallam/tomcat-mysql Debian, Oracle JDK, Tomcat & MySQL 13 [OK]
docker hub可以看大更详细的镜像信息
2 下载镜像
[root@VM-4-6-centos lighthouse]# docker pull tomcat Using default tag: latestlatest: Pulling from library/tomcat1cfaf5c6f756: Pull complete c4099a935a96: Pull complete f6e2960d8365: Pull complete dffd4e638592: Pull complete a60431b16af7: Pull complete 4869c4e8de8d: Pull complete 9815a275e5d0: Pull complete c36aa3d16702: Pull complete cc2e74b6c3db: Pull complete 1827dd5c8bb0: Pull complete Digest: sha256:1af502b6fd35c1d4ab6f24dc9bd36b58678a068ff1206c25acc129fb90b2a76aStatus: Downloaded newer image for tomcat:latestdocker.io/library/tomcat:latest# 下载成功
3 查看镜像
[root@VM-4-6-centos lighthouse]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtomcat latest 266d1269bb29 9 days ago 668MBnginx latest dd34e67e3371 10 days ago 133MB
4 运行容器
[root@VM-4-6-centos lighthouse]# docker run -d --name tomcat001 -p 80:8080 tomcat4400a14a931baa9fbc324d003ce26e06debba3456435b233ed5b77eccf7b4379
5 查看容器
[root@VM-4-6-centos lighthouse]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4400a14a931b tomcat "catalina.sh run" 25 seconds ago Up 25 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 8080/tcp tomcat001
6 测试
[root@VM-4-6-centos lighthouse]# docker exec -it tomcat001 /bin/bashroot@4400a14a931b:/usr/local/tomcat# lsBUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.distCONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps workroot@4400a14a931b:/usr/local/tomcat# cp -r webapps.dist/* webapps
外网访问:
7关闭容器`
[root@VM-4-6-centos lighthouse]# docker stop tomcat001tomcat001
经过实例的练习之后,前面学的命令熟练了许多。
6 图形交互面板
6.1portainer
- portainer是什么?
Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer可以轻松构建,管理和维护Docker环境。 而且完全免费,基于容器化的安装方式,方便高效部署。
-
安装 # 1. 下载镜像
docker pull portainer/portainer
# 2. 启动服务
docker run -d --name portainerUI -p 80:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
示例: [root@VM-4-6-centos lighthouse]# docker pull portainer/portainer
Using default tag: latest
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
docker.io/portainer/portainer:latest
[root@VM-4-6-centos lighthouse]# docker run -d --name portainerUI -p 80:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
b9be7097fe79eecbff8f201103c641692684cad7726a5103dbc33a68bfff8e71
-
使用 使用服务器ip:端口,即可打开
7 docker镜像加载原理
7.1联合文件系统(Union Filesystem)
联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。 联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
7.2 docker 镜像加载
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。 boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。 rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
7.3 分层
当我们去观察镜像的下载的输出日志,是在一层一层下载。这中分层最大的好处就是资源共享。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令
[root@VM-4-6-centos lighthouse]# docker image inspect tomcat
[
{
"Id": "sha256:266d1269bb298d6a3259fc2c2a9deaedf8be945482a2d596b64f73343289a56c",
"RepoTags": [
"tomcat:latest"
],
"RepoDigests": [
"tomcat@sha256:1af502b6fd35c1d4ab6f24dc9bd36b58678a068ff1206c25acc129fb90b2a76a"
],
"Parent": "",
"Comment": "",
"Created": "2021-08-18T20:48:04.549796116Z",
"Container": "d2ecb6a64fdc3e7fef05d7909154d295574519fa144d8507cf7c9a5a6c5ea8b3",
"ContainerConfig": {
"Hostname": "d2ecb6a64fdc",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"JAVA_HOME=/usr/local/openjdk-11",
"LANG=C.UTF-8",
"JAVA_VERSION=11.0.12",
"CATALINA_HOME=/usr/local/tomcat",
"TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib",
"LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib",
"GPG_KEYS=48F8E69F6390C9F25CFEDCD268248959359E722B A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243",
"TOMCAT_MAJOR=9",
"TOMCAT_VERSION=9.0.52",
"TOMCAT_SHA512=35e007e8e30e12889da27f9c71a6f4997b9cb5023b703d99add5de9271828e7d8d4956bf34dd2f48c7c71b4f8480f318c9067a4cd2a6d76eaae466286db4897b"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"catalina.sh\" \"run\"]"
],
"Image": "sha256:5196276371ce4bad78ffcbb6032a04d381437b0719075d11ae1c24f496303f32",
"Volumes": null,
"WorkingDir": "/usr/local/tomcat",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"JAVA_HOME=/usr/local/openjdk-11",
"LANG=C.UTF-8",
"JAVA_VERSION=11.0.12",
"CATALINA_HOME=/usr/local/tomcat",
"TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib",
"LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib",
"GPG_KEYS=48F8E69F6390C9F25CFEDCD268248959359E722B A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243",
"TOMCAT_MAJOR=9",
"TOMCAT_VERSION=9.0.52",
"TOMCAT_SHA512=35e007e8e30e12889da27f9c71a6f4997b9cb5023b703d99add5de9271828e7d8d4956bf34dd2f48c7c71b4f8480f318c9067a4cd2a6d76eaae466286db4897b"
],
"Cmd": [
"catalina.sh",
"run"
],
"Image": "sha256:5196276371ce4bad78ffcbb6032a04d381437b0719075d11ae1c24f496303f32",
"Volumes": null,
"WorkingDir": "/usr/local/tomcat",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 667866261,
"VirtualSize": 667866261,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/14d6effb2d8347a8f2140b8eb6bb914ffe5209cc9ed880c55657cb8e6c30f0b4/diff:/var/lib/docker/overlay2/304d8484e5dd5fd4386fd5fefcd8e32ef38743801a7bf3ba513fb3ff8f38ad89/diff:/var/lib/docker/overlay2/bd7bfc9ebc87f6f5c11e110877e54b7e2180aac478637a207b105b4b319e925e/diff:/var/lib/docker/overlay2/00ca651a87602d2e11175f932c6f32fd7b43ae98159416ad908fa050b47b3fed/diff:/var/lib/docker/overlay2/aa5cce0f487b2a05c13bb8929a2411314690d2b4d305cd3e1bc171cb1b173089/diff:/var/lib/docker/overlay2/3815d6dbfabe611f9dc4ffac4690fb4c72870794c7ea9d2e930487d0eaa6d5f4/diff:/var/lib/docker/overlay2/f14c65162848b2a6061d043343db3ccff14c64bf99d6fe3bb947331fc7882778/diff:/var/lib/docker/overlay2/7acfe353937d2289e2cbf8b63e938e579b5a5d952cefe0973125b38555c04416/diff:/var/lib/docker/overlay2/67693c8b74406bd5c6603fe38ce5e5ac9380eca61504103ae70e35c5703d8d57/diff",
"MergedDir": "/var/lib/docker/overlay2/517208d37dec0c6abf702063df2aec59802520e1e5ef5b6bcefce7a6f3a379aa/merged",
"UpperDir": "/var/lib/docker/overlay2/517208d37dec0c6abf702063df2aec59802520e1e5ef5b6bcefce7a6f3a379aa/diff",
"WorkDir": "/var/lib/docker/overlay2/517208d37dec0c6abf702063df2aec59802520e1e5ef5b6bcefce7a6f3a379aa/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:c2ddc1bc2645ab5d982c60434d8bbc6aecee1bd4e8eee0df7fd08c96df2d58bb",
"sha256:62d14713f2e98841ec3927e3ab611b13e414a21fb82fc0e604a9008ac53e45dc",
"sha256:1235daf38153d083ae5b4f605acc54f9401143b5fbd033801ba373a8cfb04845",
"sha256:7d890913ab6955350bdd25d04c60dd444db13890c401cbcdc8e00e9bd29c90fc",
"sha256:c2e2307780ac2fa0d39cec874c4545156da890c1bcc42b3259114ac29bb598f1",
"sha256:75f6a0e6e441cd3d74125443fc73eb26bf9ceb557b269b25bddaa2ef459227f7",
"sha256:b19f17003e5ae07f7aba99f95736627aaa1ff3c92832f7d6920158dc6b138bcf",
"sha256:2dad09b8a57e12408adc0366cbd2a642eaab1c82bbfb2b442245928b60d337f1",
"sha256:83a14c3e974e700768197a3061f840618a924d3154fcb338a85b6da5fd4eb886",
"sha256:19f8bd134bcf7c5870f8294b1d3bba4c970d0b622772865e44d200d248ed2676"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
理解:
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示,在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
文种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
第八讲 docker容器数据卷
8.1 容器数据卷是什么
当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们关闭docker容器时是会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。容器数据卷可以帮助我们实现这个需求。docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
特点:
1:数据卷可以在容器之间共享或重用数据
2:数据卷中的更改可以直接生效
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止
8.2 如何添加容器数据卷
8.2.1 通过命令挂载
# 1 通过docker run -v 挂载
[root@VM-4-6-centos lighthouse]# docker run -it -v /home/test:/home centos
[root@672f22246a83 /]# [root@VM-4-6-centos lighthouse]#
[root@VM-4-6-centos lighthouse]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
672f22246a83 centos "/bin/bash" 22 seconds ago Up 22 seconds # 2 通过
# 2 docker inspect containerID 查看挂载是否成功
[root@VM-4-6-centos lighthouse]# docker inspect 672f22246a83
"Mounts": [
{
"Type": "bind",
"Source": "/home/test",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
# 3手动查看挂载是否成功,能否同步文件
[root@VM-4-6-centos lighthouse]# cd /home/test
# 新建测试文件mounttest.tet
[root@VM-4-6-centos test]# touch mounttest.tet
[root@VM-4-6-centos test]# ls
mounttest.tet
[root@VM-4-6-centos test]# docker exec -it 672f22246a83 /bin/bash
[root@672f22246a83 /]# cd /home
# 查看容器对应文件是否同步
[root@672f22246a83 home]# ls
mounttest.tet
# 生成反向同步测试文件
[root@672f22246a83 home]# touch mounttest111.tet
[root@672f22246a83 home]# read escape sequence
[root@VM-4-6-centos test]# ls
mounttest111.tet mounttest.tet
# 双向同步
案例: 部署mysql容器数据卷
# 启动mysql容器并挂载文件
[root@VM-4-6-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest 266d1269bb29 2 weeks ago 668MB
nginx latest dd34e67e3371 2 weeks ago 133MB
mysql latest 5a4e492065c7 2 weeks ago 514MB
centos latest 300e315adb2f 8 months ago 209MB
[root@VM-4-6-centos ~]# docker run -d -p 1433:3306 -v /home/mysql/conf:/etc/mysql/conf.d
-v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql001 mysql:latest
8988e75401bcbbc73d018ae14c8fce9f53ae3e9e4f15058436f839039dd9cdcf
[root@VM-4-6-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8988e75401bc mysql:latest "docker-entrypoint.s…" 12 seconds ago Up 11 seconds 33060/tcp, 0.0.0.0:80->3306/tcp, :::80->3306/tcp mysql001
672f22246a83 centos "/bin/bash" 6 hours ago Up 6 hours interesting_tu
[root@VM-4-6-centos ~]# docker inspect mysql001
"Mounts": [
{
"Type": "bind",
"Source": "/home/mysql/data",
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/home/mysql/conf",
"Destination": "/etc/mysql/conf.d",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
具名挂载和匿名挂载
# 匿名挂载
-v 容器内路径!
$ docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume(卷)的情况
$ docker volume ls
DRIVER VOLUME NAME # 容器内的卷名(匿名卷挂载)
local 21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0
local b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c
# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!
# 具名挂载 -P:表示随机映射端口
$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
9663cfcb1e5a9a1548867481bfddab9fd7824a6dc4c778bf438a040fe891f0ee
# 查看所有的volume(卷)的情况
$ docker volume ls
DRIVER VOLUME NAME
local 21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0
local b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c
local juming-nginx #多了一个名字
# 通过 -v 卷名:查看容器内路径
# 查看一下这个卷
$ docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-05-23T13:55:34+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", #默认目录
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在**/var/lib/docker/volumes/自定义的卷名/_data**下, 如果指定了目录,docker volume ls 是查看不到的。
区分三种挂载方式
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
拓展:
# 通过 -v 容器内路径: ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
8.3 通过dockerfile挂载
dockerfile就是是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
# 创建一个dockerfile文件,名字可以随便建议Dockerfile
# 文件中的内容: 指令(大写) + 参数
$ vim dockerfile1
FROM centos # 当前这个镜像是以centos为基础的
VOLUME ["volume01","volume02"] # 挂载卷的卷目录列表(多个目录)
CMD echo "-----end-----" # 输出一下用于测试
CMD /bin/bash # 默认走bash控制台
# 这里的每个命令,就是镜像的一层!
# 构建出这个镜像
-f dockerfile1 # f代表file,指这个当前文件的地址(这里是当前目录下的dockerfile1)
-t caoshipeng/centos # t就代表target,指目标目录(注意caoshipeng镜像名前不能加斜杠‘/’)
. # 表示生成在当前目录下
$ docker build -f dockerfile1 -t caoshipeng/centos .
Sending build context to Docker daemon 2.56kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
8a29a15cefae: Already exists
Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
Status: Downloaded newer image for centos:latest
---> 470671670cac
Step 2/4 : VOLUME ["volume01","volume02"] # 卷名列表
---> Running in c18eefc2c233
Removing intermediate container c18eefc2c233
---> 623ae1d40fb8
Step 3/4 : CMD echo "-----end-----" # 输出 脚本命令
---> Running in 70e403669f3c
Removing intermediate container 70e403669f3c
---> 0eba1989c4e6
Step 4/4 : CMD /bin/bash
---> Running in 4342feb3a05b
Removing intermediate container 4342feb3a05b
---> f4a6b0d4d948
Successfully built f4a6b0d4d948
Successfully tagged caoshipeng/centos:latest
# 查看自己构建的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
caoshipeng/centos latest f4a6b0d4d948 About a minute ago 237MB
启动新建的镜像
[root@VM-4-6-centos lib]#docker run -it new/centos /bin/bash
#
[root@VM-4-6-centos lib]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0da4c77e1a9 new/centos "/bin/bash" 5 minutes ago Up 5 minutes priceless_hawking
# 查看挂载
[root@VM-4-6-centos lib]# docker inspect d0da4c77e1a9
"Mounts": [
{
"Type": "volume",
"Name": "575269012a409d421b59c45cc5591a7ac7b44d4fa5cbf80a196817c589ea3848",
"Source": "/var/lib/docker/volumes/575269012a409d421b59c45cc5591a7ac7b44d4fa5cbf80a196817c589ea3848/_data",
"Destination": "colume2",# 挂载成功
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "099c9f4fe900e5550ca4ad2aff381b09e969c158ca62591b1817d9a8b26d1967",
"Source": "/var/lib/docker/volumes/099c9f4fe900e5550ca4ad2aff381b09e969c158ca62591b1817d9a8b26d1967/_data",
"Destination": "volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
8.4 数据卷容器
多个容器数据之间实现数据共享 。 实例:
[root@VM-4-6-centos /]# docker images
hello-world latest d1165f221234 6 months ago 13.3kB
centos latest 300e315adb2f 9 months ago 209MB
# 容器1
[root@VM-4-6-centos /]# docker run -it --name centos01 new/centos
[root@fff6b286c371 /]# ls
bin colume2 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume1
[root@fff6b286c371 /]# cd volume1/
# 容器1 挂载目录下 新建测试文件
[root@fff6b286c371 volume1]# touch test.txt
[root@fff6b286c371 volume1]# ls
test.txt
[root@fff6b286c371 volume1]# [root@VM-4-6-centos /]#
# 容器2继承容器1
[root@VM-4-6-centos /]# docker run -it --name centos02 --volumes-from centos01 new/centos
[root@41f919150a90 /]# ls
bin colume2 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume1
[root@41f919150a90 /]# cd volume1
[root@41f919150a90 volume1]# ls
test.txt
# 容器2 与容器1 实现数据共享
[root@41f919150a90 volume1]# [root@VM-4-6-centos /]#
# 查看挂载宿主机地址
[root@VM-4-6-centos /]# docker inspect centos01
"Mounts": [
{
"Type": "volume",
"Name": "b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b",
"Source": "/var/lib/docker/volumes/b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b/_data",
"Destination": "volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
[root@VM-4-6-centos /]# docker inspect centos01
"Mounts": [
{
"Type": "volume",
"Name": "b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b",
"Source": "/var/lib/docker/volumes/b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b/_data",
"Destination": "volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
# 发现两个容器挂载在宿主机的同一位置
# 即使所有挂载的容器被删除, 宿主机的文件不受影响
[root@VM-4-6-centos /]# docker rm centos02
centos02
[root@VM-4-6-centos /]# docker rm centos01
centos01
[root@VM-4-6-centos home]# cd /var/lib/docker/volumes/
[root@VM-4-6-centos volumes]# cd b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b/
[root@VM-4-6-centos b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b]# ls
_data
[root@VM-4-6-centos b83567b3f8e3818762cd87e5dc7c48a98846929f4c035d5eadc3c89ea364746b]# cd _data
[root@VM-4-6-centos _data]# ls
test.txt
# 测试表明, 即使删除所有容器,宿主机上的文件也会持久化储存。
第九讲 dockerfile 开发
9.1 什么是dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
9.2 dockerfile构建镜像的流程
- 编写一个dockerfile文本
- docker bulild构建一个镜像
- docker run 运行镜像
- docker push 发布镜像(dockerhub, 阿里云镜像仓库)
9.3 dockerfile 命令
9.4 实例测试——新建一个带vim和net-tools的centos镜像
-
编写dockerfle [root@VM-4-6-centos mydocker]# vim dockerfile1
FROM centos
MAINTAINER ywl<yuan.wanli@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD ehco $MYPATH
CMD /bin/bash
-
构建镜像 [root@VM-4-6-centos mydocker]# docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
[root@VM-4-6-centos mydocker]# docker build -f dockerfile1 -t mycentos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/9 : FROM centos
---> 300e315adb2f
Step 2/9 : MAINTAINER ywl<yuan.wanli@qq.com>
---> Running in 2f009ebbce45
Removing intermediate container 2f009ebbce45
---> 3e039c5d5963
Step 3/9 : ENV MYPATH /usr/local
---> Running in 902ec92baf9a
Removing intermediate container 902ec92baf9a
---> 0d77fd7a4baf
Step 4/9 : WORKDIR $MYPATH
---> Running in 9d8012ef4523
Removing intermediate container 9d8012ef4523
---> 7f363b93ec76
Step 5/9 : RUN yum -y install vim
---> Running in 9e54c5f8edfe
CentOS Linux 8 - AppStream 6.7 MB/s | 8.8 MB 00:01
CentOS Linux 8 - BaseOS 4.6 MB/s | 5.6 MB 00:01
CentOS Linux 8 - Extras 21 kB/s | 10 kB 00:00
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-17.el8 appstream 39 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 30 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-17.el8.x86_64.rpm 425 kB/s | 39 kB 00:00
(2/5): vim-filesystem-8.0.1763-15.el8.noarch.rp 1.6 MB/s | 48 kB 00:00
(3/5): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 4.6 MB/s | 1.4 MB 00:00
(4/5): which-2.21-12.el8.x86_64.rpm 280 kB/s | 49 kB 00:00
(5/5): vim-common-8.0.1763-15.el8.x86_64.rpm 9.4 MB/s | 6.3 MB 00:00
--------------------------------------------------------------------------------
Total 5.2 MB/s | 7.8 MB 00:01
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-17.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-15.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/5
Verifying : which-2.21-12.el8.x86_64 5/5
Installed:
gpm-libs-1.20.7-17.el8.x86_64 vim-common-2:8.0.1763-15.el8.x86_64
vim-enhanced-2:8.0.1763-15.el8.x86_64 vim-filesystem-2:8.0.1763-15.el8.noarch
which-2.21-12.el8.x86_64
Complete!
Removing intermediate container 9e54c5f8edfe
---> 5dea379858f6
Step 6/9 : RUN yum -y install net-tools
---> Running in a238f0f61bd1
Last metadata expiration check: 0:00:11 ago on Wed Sep 8 05:20:26 2021.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 322 k
Installed size: 942 k
Downloading Packages:
net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 1.1 MB/s | 322 kB 00:00
--------------------------------------------------------------------------------
Total 547 kB/s | 322 kB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.52.20160912git.el8.x86_64
Complete!
Removing intermediate container a238f0f61bd1
---> fe15f2802369
Step 7/9 : EXPOSE 80
---> Running in dd05e3d35f52
Removing intermediate container dd05e3d35f52
---> 8b2ed813e0cc
Step 8/9 : CMD ehco $MYPATH
---> Running in 3abafde69c99
Removing intermediate container 3abafde69c99
---> 7a93ce354052
Step 9/9 : CMD /bin/bash
---> Running in 0737c0226cf2
Removing intermediate container 0737c0226cf2
---> b531a51cbc3e
Successfully built b531a51cbc3e
Successfully tagged mycentos:1.0
-
测试 查看镜像 [root@VM-4-6-centos mydocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 b531a51cbc3e 4 minutes ago 307MB
centos latest 300e315adb2f 9 months ago 209MB
运行一个容器 [root@VM-4-6-centos mydocker]# docker run -it b531a51cbc3e
[root@915fe46d200b local]# ls
bin etc games include lib lib64 libexec sbin share src
[root@915fe46d200b local]# pwd
/usr/local
[root@915fe46d200b local]# vim test.txt
-
查看镜像构建历史 [root@VM-4-6-centos mydocker]# docker history --human b531a51cbc3e
IMAGE CREATED CREATED BY SIZE COMMENT
b531a51cbc3e 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
7a93ce354052 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "ehco… 0B
8b2ed813e0cc 14 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
fe15f2802369 14 minutes ago /bin/sh -c yum -y install net-tools 29.5M
5dea379858f6 14 minutes ago /bin/sh -c yum -y install vim 68.1MB
7f363b93ec76 14 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
0d77fd7a4baf 14 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
3e039c5d5963 14 minutes ago /bin/sh -c #(nop) MAINTAINER ywl<yuan.wanli… 0B
300e315adb2f 9 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 9 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
9.5 CMD 于 ENTRYPOINT区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令*
测试CMD
# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"] # 启动后执行 ls -a 命令
# 构建镜像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1 # 由结果可得,运行后就执行了 ls -a 命令
.
..
.dockerenv
bin
dev
etc
home
# 想追加一个命令 -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 build -f dockerfile-test-entrypoint -t cmd-test:0.1 .
# 运行镜像
$ 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 ....
Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果!
实战:Tomcat镜像
1、准备镜像文件
准备tomcat 和 jdk 到当前目录,编写好README
2、编写dokerfile
$ vim dockerfileFROM centos # 基础镜像centosMAINTAINER cao<1165680007@qq.com> # 作者COPY README /usr/local/README # 复制README文件ADD jdk-8u231-linux-x64.tar.gz /usr/local/ # 添加jdk,ADD 命令会自动解压ADD apache-tomcat-9.0.35.tar.gz /usr/local/ # 添加tomcat,ADD 命令会自动解压RUN yum -y install vim # 安装 vim 命令ENV MYPATH /usr/local # 环境变量设置 工作目录WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_231 # 环境变量: JAVA_HOME环境变量ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 # 环境变量: tomcat环境变量ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35# 设置环境变量 分隔符是:ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin 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 # 设置默认命令
3、构建镜像
# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件$ docker build -t mytomcat:0.1 .
4、run镜像
# -d:后台运行 -p:暴露端口 --name:别名 -v:绑定路径 $ docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
5、访问测试
$ docker exec -it 自定义容器的id /bin/bash$ cul localhost:8080
6、发布项目
(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
第十讲 发布docker镜像
10.1 发布到dockerhub
1、地址 https://hub.docker.com/
2、确定这个账号可以登录
3、登录
$ docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
$ docker login -u 你的用户名 -p 你的密码
4、提交 push镜像
# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法:
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t kuangshen/mytomcat:0.1 .
# 第二种 使用docker tag #然后再次push
$ docker tag 容器id kuangshen/mytomcat:1.0 #然后再次push
$ docker push kuangshen/mytomcat:1.0
10.2 发布到阿里云镜像
看官网 很详细https://cr.console.aliyun.com/repository/
$ sudo docker login --username=zchengx registry.cn-shenzhen.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:[镜像版本号]
# 修改id 和 版本
sudo docker tag a5ef1f32aaae registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:1.0
# 修改版本
$ sudo docker push registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:[镜像版本号]
总结:
第十一讲 docker网络
清空镜像
docker rmi -f $(docker images -aq)
查看网卡
[root@VM-4-6-centos ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:e6:fb:2d brd ff:ff:ff:ff:ff:ff
inet 10.0.4.6/22 brd 10.0.7.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fee6:fb2d/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:d6:9a:ed:b7 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d6ff:fe9a:edb7/64 scope link
valid_lft forever preferred_lft forever
docker如何处理容器于宿主机的网络
# 测试 运行一个tomcat
$ docker run -d -P --name tomcat01 tomcat
# 查看容器内部网络地址
$ docker exec -it 容器id ip addr
# 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配!
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
$ ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms
-
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术! -
再启动一个容器测试,发现又多了一对网络.
我们发现这个容器带来网卡,都是一对对的,veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、我们来测试下tomcat01和tomcat02是否可以ping通
#获取tomcat01的ip 172.17.0.2
$ docker-tomcat docker exec -it tomcat01 ip addr
550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 让tomcat02 ping tomcat01
$ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
# 结论:容器和容器之间是可以互相ping通
网络模型图
结论:tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
小结
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
–-link
$ docker exec -it tomcat02 ping tomca01 # ping不通
ping: tomca01: Name or service not known
# 运行一个tomcat03 --link tomcat02
$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef
# 3连接2
# 用tomcat03 ping tomcat02 可以ping通
$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms
# 2连接3
# 用tomcat02 ping tomcat03 ping不通
探究:
docker network inspect 网络id 网段相同
docker inspect tomcat03
查看tomcat03里面的/etc/hosts发现有tomcat02的配置
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
自定义网络
docker network
connect -- Connect a container to a network
create -- Creates a new network with a name specified by the
disconnect -- Disconnects a container from a network
inspect -- Displays detailed information on a network
ls -- Lists all the networks created by the user
prune -- Remove all unused networks
rm -- Deletes one or more networks
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
测试
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
$ docker network inspect mynet;
启动两个tomcat,再次查看网络情况,在自定义的网络下,服务可以互相ping通,不用使用–link.
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
容器和网卡的网路连通
# 测试两个不同的网络连通 再启动两个tomcat 使用默认网络,即docker0$ docker run -d -P --name tomcat01 tomcat$ docker run -d -P --name tomcat02 tomcat# 此时ping不通
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!
查看tomcat03里面的/etc/hosts发现有tomcat02的配置
[外链图片转存中…(img-IV7ISb15-1632447380551)]
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
自定义网络
docker network
connect -- Connect a container to a network
create -- Creates a new network with a name specified by the
disconnect -- Disconnects a container from a network
inspect -- Displays detailed information on a network
ls -- Lists all the networks created by the user
prune -- Remove all unused networks
rm -- Deletes one or more networks
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
测试
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[外链图片转存中…(img-VQpRBRbV-1632447380552)]
$ docker network inspect mynet;
[外链图片转存中…(img-i1ByXXaq-1632447380553)]
启动两个tomcat,再次查看网络情况,在自定义的网络下,服务可以互相ping通,不用使用–link.
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
容器和网卡的网路连通
[外链图片转存中…(img-kSj5c9Wq-1632447380554)]
# 测试两个不同的网络连通 再启动两个tomcat 使用默认网络,即docker0$ docker run -d -P --name tomcat01 tomcat$ docker run -d -P --name tomcat02 tomcat# 此时ping不通
[外链图片转存中…(img-iZD6LTom-1632447380556)]
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!
|