Docker总览
Docker
Docker学习
-
Docker概述
-
Docker安装
-
Docker命令
- 镜像命令
- 容器命令
- 操作命令
-
Docker镜像
-
容器数据卷
-
DockerFile
-
Docker网络原理
-
IDEA整合Docker
-
Docker Compose
-
Docker Swarm
-
CI\CD Jenkins
Docker概述
Docker为什么会出现
一款产品:开发---上线 两套环境 应用环境 应用配置
环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop···)费时耗力
发布一个项目(jar + (Redis Mysql jdk ES)),项目能不能都带上环境安装打包
之前在服务器配置一个应用环境Redis Mysql jdk ES Hadoop,配置超级麻烦,不能够跨平台
传统:开发提供jar包 其他交给运维来做
现在:开发打包部署上线,一套流程做完
java -- apk--发布(应用商店) --张三使用apk ---安装即可用!
java --jar(环境) ---打包带上项目环境(镜像)---(Docker仓库:商店)---下载我们发布的镜像---直接运行即可
DOcker的思想来自于集中箱
隔离:Docker革新思想,打包装箱!每个箱子是互相隔离的
Docker通过隔离机制,可以将服务器利用到极致
Docker历史
2010年,几个搞IT的年轻人,就在美国成立了一家公司dotCloud
做一些pass的云计算服务
为了公司存活,决定开源
2013年,Docker开源!
Docker越来越多的人发现了docker的优点--->火了--->每个月都会更新一个版本!
2014年4月,Docker1.0发布
Docker为什么这么火?十分轻巧!
在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在windows中装一个Vmware,通过这个软件我们可以虚拟出来一台或多台电脑,笨重!
虚拟机也是属于虚拟化技术,Docker容器技术也是一种虚拟化技术
vm linxu centos原生镜像(一个电脑) 隔离 需要开启多个虚拟机 几个G 启动需要几分钟
docdker 隔离 镜像(最核心的环境 4m + jdk + mysql)十分的小巧 运行镜像就可以了 秒级启动
聊聊Docker
Docker 是基于Go语言开发的!开源项目!
Docker能干嘛
虚拟机技术缺点:
- 资源占用十分多
- 冗余步骤多
- 启动很慢
容器化技术
容器化技术不是模拟的一个完整的操作系统
比较Docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一套应急,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个荣期间是互相隔离,每个容器内部都有一个属于自己的文件系统,互不影响
DevOps(开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩编容
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的
更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器性能可以被压榨到极致
Docker安装
Docker的基本组成
镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像--->run--->tomcat01容器(提供服务),通过镜像可以创建很多容器,
容器(container):
Docker利用容器技术,独立运行一个或一组应用,通过镜像来创建的
启动 停止 删除 基本命令
目前可以把这个容器理解为一个简易的linux系统
仓库(repository):
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库
安装Docker
环境准备
- CentOs7
环境查看
#系统内核是 3.10以上
[root@localhost /]# uname -r
3.10.0-1127.el7.x86_64
#系统版本
[root@localhost /]# 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"
安装
# 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 #推荐使用阿里云的
# 更新yum软件包索引
[root@localhost /]# yum makecache fast
# 配置镜像加速器
# 阿里云地址 https://dev.aliyun.com/search.html
# 注册登录后 找到镜像服务 镜像加速器里有加速地址
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://gpj3pquj.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 4、安装docker docker-ce 社区版 docker-ee 企业版
sudo yum install docker-ce docker-ce-cli containerd.io
# 5、启动docker
sudo systemctl start docker
# 6、使用docker version查看是否安装成功
# 7、运行hello-world
# 8、查看一下下载的hello-world镜像
[root@localhost /]# docker images
#镜像名 #版本号 # Id
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 7 months ago 13.3kB
了解:卸载docker
# 1、卸载依赖----》卸载Docker Engine,CLI和Containerd软件包:
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2、删除资源----》主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:
sudo rm -rf /var/lib/docker
# /var/lib/docker docker的默认工作路径
回顾hello-world流程
底层原理
docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过socket从客户端访问
DockerServer接收到Docker-Client的指令,就会执行这个命令
Docker为什么比虚拟机快
- Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。
- Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。
Docker的常用命令
帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
帮助文档的地址:https://docs.docker.com/engine/reference/run/
镜像命令
docker images
docker images 查看所有本地的主机上的镜像
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 7 months ago 13.3kB
# 可选项
-a, --all # 列出所有镜像
-q, --quiet # 只显示id
docker search
docker search 搜索镜像
[root@localhost /]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9822 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]
# 可选性
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
# 通过过滤来显示:显示STARS大于3000的镜像
[root@localhost /]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9822 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]
[root@localhost /]# docker search mysql --filter=STARS=5000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9822 [OK]
docker pull
docker pull 下载镜像
# 下载最新版
[root@localhost /]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载 docker image的核心
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
ff39fdb566b4: Downloading [===============================================> ] 106.6MB/112.5MB
ff39fdb566b4: Pull complete
fff872988aba: Pull complete
4d34e365ae68: Pull complete
7886ee20621e: Pull complete
Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
docker pull mysql
docker pull docker.io/library/mysql:latest
# 下载指定版本 docker pull mysql [:版本号]
[root@localhost /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Already exists
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 718a6da099d8 6 days ago 448MB
mysql latest 0d64f46acfd1 6 days ago 544MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
docker rmi
docker rmi 删除镜像
[root@localhost /]# docker rmi -f 718a6da099d8
Untagged: mysql:5.7
Untagged: mysql@sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
Deleted: sha256:718a6da099d82183c064a964523c0deca80619cb033aadd15854771fe592a480
Deleted: sha256:058d93ef2bfb943ba6a19d8b679c702be96e34337901da9e1a07ad62b772bf3d
Deleted: sha256:7bca77783fcf15499a0386127dd7d5c679328a21b6566c8be861ba424ac13e49
Deleted: sha256:183d05512fa88dfa8c17abb9b6f09a79922d9e9ee001a33ef34d1bc094bf8f9f
Deleted: sha256:165805124136fdee738ed19021a522bb53de75c2ca9b6ca87076f51c27385fd7
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 0d64f46acfd1 6 days ago 544MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
[root@localhost /]#
# 删除指定镜像 docker rmi -f 镜像id
[root@localhost /]# docker rmi -f 718a6da099d8
# 删除多个镜像 docker rmi -f 镜像id 镜像id 镜像id 镜像id
[root@localhost /]# docker rmi -f 718a6da099d8 718a6da099d3 718a6da099d23
# 删除全部镜像 docker rmi -f $(docker images -qa)
[root@localhost /]# docker rmi -f $(docker images -qa)
容器命令
说明:有了镜像才可以创建容器,下载一个centos镜像来测试学习
docker pull centos
docker run
新建容器并启动
docker run[可选参数] image
# 参数说明
--name="name" 容器名字 tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-P 随机指定端口
# 测试
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0d120b6ccaa8 13 hours ago 215MB
mysql latest 0d64f46acfd1 6 days ago 544MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
# 启动并进入容器
[root@localhost /]# docker run -it centos /bin/bash
# 查看容器内的centos
[root@35b18e8a7511 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 退出容器---》退出并停止容器,若只退出容器,不停止使用快捷键 Ctrl + Q + P
[root@35b18e8a7511 /]# exit
exit
[root@localhost /]# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
docker ps
列出所有运行的容器
#docker ps
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器 + 带出历史运行的容器
-n=? # 显示最近创建的容器
-q #只显示容器的编号
# 测试
[root@f2abdaa7f711 /]# [root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2abdaa7f711 centos "/bin/bash" 15 seconds ago Up 14 seconds modest_bell
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2abdaa7f711 centos "/bin/bash" 3 minutes ago Up 3 minutes modest_bell 35b18e8a7511 centos "/bin/bash" 8 minutes ago Exited (0) 6 minutes ago stoic_mendel
fb32d5936b39 hello-world "/hello" 4 hours ago Exited (0) 4 hours ago hungry_faraday
[root@localhost /]# docker ps -a -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2abdaa7f711 centos "/bin/bash" 8 minutes ago Up 8 minutes modest_bell
# 列出当前正在运行的容器 + 带出历史运行的容器的 id
[root@localhost /]# docker ps -aq
f2abdaa7f711 # 正在运行的容器
35b18e8a7511 # 历史运行的容器
fb32d5936b39 # 历史运行的容器
# 列出当前正在运行的容器 id
[root@localhost /]# docker ps -q
f2abdaa7f711
docker rm
删除容器
docker rm 容器id # 删除指定容器---》不会删除正在运行的容器
docker rm $(docker ps -aq) # 删除所有容器---》不会删除正在运行的容器
docker rm -f 容器id # 强制删除指定容器
docker rm -f $(docker ps -aq) # 强制删除所有容器
docker ps -a -q|xargs docker rm # 通过管道符删除所有的容器
# 测试
# 查询所有容器
[root@localhost /]# docker ps -aq
f2abdaa7f711 # 正在运行的容器
35b18e8a7511 # 历史运行的容器
fb32d5936b39 # 历史运行的容器
# 删除所有容器 发现删除了历史运行的容器,正在运行的容器并没有删除
[root@localhost /]# docker rm $(docker ps -aq)
35b18e8a7511
fb32d5936b39
Error response from daemon: You cannot remove a running container f2abdaa7f7117a77d2656954ac983d1609d9e026e2eaae0639758ee0490df617. Stop the container before attempting removal or force remove
# 正在运行的容器不能删除,若要删,使用强制删除
[root@localhost /]# docker ps -aq
f2abdaa7f711
# 强制删除正在运行的容器
[root@localhost /]# docker rm -f $(docker ps -aq)
f2abdaa7f711
[root@localhost /]# docker ps -aq
[root@localhost /]#
启动和停止容器
启动和停止容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
# 测试
# 没有正在运行的容器
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 有一个历史运行的容器
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ea9ccef9929 centos "/bin/bash" 2 minutes ago Exited (0) 9 seconds ago inspiring_payne
# 启动这个历史运行的容器
[root@localhost /]# docker start 0ea9ccef9929
0ea9ccef9929
# 发现这个历史运行的容器已经运行
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ea9ccef9929 centos "/bin/bash" About a minute ago Up 5 seconds inspiring_payne
# 停止这个容器
[root@localhost /]# docker stop 0ea9ccef9929
0ea9ccef9929
# 发现这个容器已经停止
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 重新启动这个容器
[root@localhost /]# docker restart 0ea9ccef9929
0ea9ccef9929
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ea9ccef9929 centos "/bin/bash" 8 minutes ago Up 9 seconds inspiring_payne
# 强制停止当前容器
[root@localhost /]# docker kill 0ea9ccef9929
0ea9ccef9929
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ea9ccef9929 centos "/bin/bash" 8 minutes ago Exited (137) 10 seconds ago inspiring_payne
常用其他命令
开放端口
# 开放4433端口
[root@bogon home]# firewall-cmd --zone=public --add-port=4433/tcp --permanent
success
# 重启防火墙
[root@bogon home]# firewall-cmd --reload
success
# 查看当前所有tcp端口·
[root@bogon home]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1031/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1201/master
tcp6 0 0 :::4433 :::* LISTEN 60497/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 1031/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1201/master
# 查看所有4433端口使用情况·
[root@bogon home]# netstat -ntulp |grep 4433
tcp6 0 0 :::4433 :::* LISTEN 60497/docker-proxy
查看docker容器内部开放有哪些端口
# 不用进入容器bash内部,在linux命令行内输入docker port 容器id 即可查看
[root@localhost yin]# docker port b21706cf612e
8080/tcp -> 0.0.0.0:8080
后台启动容器的坑
# 命令 docker run -d 镜像名
# 测试
# 通过查看 没有容器
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 后台启动,不进入容器
[root@localhost /]# docker run -d centos
d8b368a5b4f89143b8b3655d93a18b15065285ef9b5851a3b1d6a9819a84d3f1
# 启动后发现没有正在运行的容器
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 在历史记录里发现了我们运行的容器
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8b368a5b4f8 centos "/bin/bash" 10 seconds ago Exited (0) 9 seconds ago musing_bhabha
# 常见的坑:docker 容器使用后台运行, 就必须要有一个前台进程(比如 -it 进入容器),docker发现没有引用,就会自动停止
# 容器启动后,发现自己没有提供服务,就会立即停止服务
查看日志命令
dockerlogs -tf --tail number 容器id
-ft #显示日志
--tail number #要显示的日志条数
# 测试一
# 使用交互方式启动centos
[root@localhost /]# docker run -it centos /bin/bash
# docker ps不生效是因为 我们当前所在的位置是在我们的centos容器中,这个容器不支持这个命令
[root@a49c01697fa5 /]# docker ps
bash: docker: command not found
[root@a49c01697fa5 /]# [root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a49c01697fa5 centos "/bin/bash" 44 seconds ago Up 43 seconds blissful_joliot
# 查看日志
[root@localhost /]# docker logs -t -f --tail 10 a49c01697fa5
2020-08-11T08:30:01.439255660Z [root@a49c01697fa5 /]# docker ps
2020-08-11T08:30:01.442523237Z bash: docker: command not found
# 测试二
# 自己编写一段shell脚本
[root@localhost /]# docker run -d centos /bin/sh -c "while true;do echo hello,docker;sleep 5;done"
e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2b54342c047 centos "/bin/sh -c 'while t…" 3 seconds ago Up 2 seconds beautiful_kowalevski # 通过日志命令查看日志
[root@localhost /]# docker logs -ft --tail 10 e2b54342c047
2020-08-11T09:11:51.601900929Z hello,docker
2020-08-11T09:11:56.608352606Z hello,docker
查看容器中进程命令
# 命令 docker top 容器id
# 测试
[root@localhost /]# docker top e2b54342c047
UID PID PPID C STIME TTY TIME CMD
root 43072 43056 0 17:25 ? 00:00:00 /bin/sh -c while true;do echo hello,docker;sleep 5;done
root 43100 43072 0 17:25 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
查看镜像源数据
# 命令
docker inspect 容器id
# 测试
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2b54342c047 centos "/bin/sh -c 'while t…" 16 minutes ago Up 3 minutes beautiful_kowalevski
[root@localhost /]# docker inspect e2b54342c047
[
{
"Id": "e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55", # 容器id
"Created": "2020-08-11T09:11:51.354568576Z", # 创建时间
"Path": "/bin/sh", # 默认的控制台
"Args": [ # 参数
"-c",
"while true;do echo hello,docker;sleep 5;done"
],
"State": { # 状态
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 43072, # 进程id
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-08-11T09:25:28.428312287Z",
"FinishedAt": "2020-08-11T09:12:40.876021118Z"
},
"Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566", # 所用镜像id
"ResolvConfPath": "/var/lib/docker/containers/e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55/hostname",
"HostsPath": "/var/lib/docker/containers/e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55/hosts",
"LogPath": "/var/lib/docker/containers/e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55/e2b54342c047098fbdb4b1fb8598f0d6adcba9ea9791dfc590acf8b24f8adb55-json.log",
"Name": "/beautiful_kowalevski",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/0b10811247f0de22b5b639c3a2e7b2c49ae76313f32cee36dff5b7c3f257926c-init/diff:/var/lib/docker/overlay2/3578edcc08a6f5ea63f0f8aa1f906688ade08c594e1db4bd5cc348283dcfcafe/diff",
"MergedDir": "/var/lib/docker/overlay2/0b10811247f0de22b5b639c3a2e7b2c49ae76313f32cee36dff5b7c3f257926c/merged",
"UpperDir": "/var/lib/docker/overlay2/0b10811247f0de22b5b639c3a2e7b2c49ae76313f32cee36dff5b7c3f257926c/diff",
"WorkDir": "/var/lib/docker/overlay2/0b10811247f0de22b5b639c3a2e7b2c49ae76313f32cee36dff5b7c3f257926c/work"
},
"Name": "overlay2"
},
"Mounts": [], # 挂载
"Config": {
"Hostname": "e2b54342c047",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"while true;do echo hello,docker;sleep 5;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20200809",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "da0d42e7d6b7403b56c55c2bdea59e2f812cc2a4d8282ac6d6194e868f007b1d",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/da0d42e7d6b7",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "febc843ef875befd3694342e88757e08f1baf7841a15bd033fe748be147375ca",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "0b84c64e381f5ed84287c2b7ffcad61b9c23731cd6d9365466b2131dff1026a6",
"EndpointID": "febc843ef875befd3694342e88757e08f1baf7841a15bd033fe748be147375ca",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
进入当前运行的容器
# 我们通常容器都是使用后台方式运行的,需要进入容器 修改配置
# 方式一
# 命令 docker exec -it 容器id bashShell # 进入容器后,打开一个新的终端,可以在里面操作
# 测试
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2b54342c047 centos "/bin/sh -c 'while t…" 16 hours ago Up 16 hours beautiful_kowalevski
[root@bogon ~]# docker exec -it e2b54342c047 /bin/bash
[root@e2b54342c047 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 方式二
# 命令 docker attach 容器id # 进入容器正在执行的终端,不会启动新的进程
# 测试
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2b54342c047 centos "/bin/sh -c 'while t…" 16 hours ago Up 16 hours beautiful_kowalevski
[root@bogon ~]# docker attach e2b54342c047
hello,docker # 正在执行的代码
hello,docker
hello,docker
从容器中拷贝文件到主机
# 命令
docker cp 容器id:文件在容器中的位置 主机位置
# 测试
# 查看当前运行的容器
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 用交互模式启动centos容器
[root@bogon ~]# docker run -it centos /bin/bash
# 容器中的目录
[root@d1504ce8714d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 进入容器中home目录创建test.java文件
[root@d1504ce8714d /]# cd home/
[root@d1504ce8714d home]# touch test.java
[root@d1504ce8714d home]# ls
test.java
# 退出容器后查看正在运行的容器
[root@d1504ce8714d home]# [root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1504ce8714d centos "/bin/bash" 37 seconds ago Up 36 seconds agitated_dijkstra
# 停止当前运行的容器
[root@bogon ~]# docker stop d1504ce8714d
d1504ce8714d
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@bogon ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1504ce8714d centos "/bin/bash" About a minute ago Exited (0) 20 seconds ago agitated_dijkstra
# 拷贝容器中的文件到主机home目录下
[root@bogon ~]# docker cp d1504ce8714d:/home/test.java /home/
[root@bogon ~]# cd /home
[root@bogon home]# ls
test.java
# 拷贝是一个手动过程 后面我们使用 -v 卷的技术 可以实现自动同步
思考:我们以后每次改动nginx配置文件都需要进入容器内部,十分麻烦!我们如果可以在容器外部提供一个映射路径。达到在容器外部修改文件,容器内部可以自动修改, -v 数据卷。
练习
Docker安装Nginx
Docker安装Nginx
# 1、搜索镜像 推荐使用官网搜索
docker search nginx
[root@bogon home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 2、拉取镜像
[root@bogon home]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
bf5952930446: Already exists
ba755a256dfe: Pull complete
c57dd87d0b93: Pull complete
d7fbf29df889: Pull complete
1f1070938ccd: Pull complete
Digest: sha256:36b74457bccb56fbf8b05f79c85569501b721d4db813b684391d63e02287c0b2
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@bogon home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 08393e824c32 7 days ago 132MB
#3、启动镜像
# docker run -d --name mynginx -p 4433:80 镜像名
# --name mynginx # 给我们启动的容器起个名字
# -p 4433:80 # 4433:80 主机端口与容器端口做映射
# 以交互模式启动
[root@bogon ~]# docker run -it --name nginx02 -p 4433:80 nginx /bin/bash
root@76564a344b1b:/#
# 以后台方式启动
[root@bogon home]# docker run -d --name mynginx -p 4433:80 nginx
b583310be4da6790918aab8234f260f9cbe9b3a06cc26d652c955a9aecff6751
# 开放4433端口
[root@bogon home]# firewall-cmd --zone=public --add-port=4433/tcp --permanent
success
# 重启防火墙
[root@bogon home]# firewall-cmd --reload
success
# 查看当前所有tcp端口·
[root@bogon home]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1031/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1201/master
tcp6 0 0 :::4433 :::* LISTEN 60497/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 1031/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1201/master
# 查看所有4433端口使用情况·
[root@bogon home]# netstat -ntulp |grep 4433
tcp6 0 0 :::4433 :::* LISTEN 60497/docker-proxy
[root@bogon home]# lsof -i:4433
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 60497 root 4u IPv6 286143 0t0 TCP *:vop (LISTEN)
# 访问Nginx 成功
[root@bogon home]# curl localhost:4433
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@bogon home]#
Docker安装tomcat
Docker 安装tomcat
# 1、下载tomcat镜像
[root@bogon home]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
d6ff36c9ec48: Pull complete
c958d65b3090: Pull complete
edaf0a6b092f: Pull complete
80931cf68816: Pull complete
bf04b6bbed0c: Pull complete
8bf847804f9e: Pull complete
fa776a6e7e37: Pull complete
586534165c2f: Pull complete
0f6d126a6962: Pull complete
9f3317edffb3: Pull complete
Digest: sha256:9de2415ccf10fe8e5906e4b72eda21649a7a1d0b88e9111f8409062599f3728e
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
[root@bogon home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest 2ae23eb477aa 6 days ago 647MB
# 启动镜像
[root@bogon home]# docker run -d --name tomcat01 -p 8090:8080 tomcat
5c66dfe280f1eec27af86149d792fc572ce6667134c6fc75a6f50cead4d07c99
# 查询容器
[root@bogon home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c66dfe280f1 tomcat "catalina.sh run" About a minute ago Up About a minute 0.0.0.0:8090->8080/tcp tomcat01
# 开放4433端口
[root@bogon home]# firewall-cmd --zone=public --add-port=4433/tcp --permanent
success
# 重启防火墙
[root@bogon home]# firewall-cmd --reload
success
# 测试访问没有问题
# 进入tomcat容器
[root@bogon home]# docker exec -it tomcat01 /bin/bash
# 查看tomcat所在位置
root@5c66dfe280f1:/usr/local/tomcat# whereis tomcat
tomcat: /usr/local/tomcat
root@5c66dfe280f1:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
# 发现问题
1、linux命令少了
2、webapps下没有文件 阿里云镜像的原因,默认是最小的镜像,所有不必要的都删除了,保证了最小可运行环境
# 进入webapp目录 发现没有任何文件
root@5c66dfe280f1:/usr/local/tomcat# cd webapps
root@5c66dfe280f1:/usr/local/tomcat/webapps# ls
root@5c66dfe280f1:/usr/local/tomcat/webapps#
# 发现文件都在webapps.dist目录下
root@5c66dfe280f1:/usr/local/tomcat# cd ../webapps.dist/
root@5c66dfe280f1:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
# 拷贝/webapps.dist目录下的所有文件到webapps下
root@5c66dfe280f1:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@5c66dfe280f1:/usr/local/tomcat# cd webapps
root@5c66dfe280f1:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
思考:我们以后不说项目如果每次都要进入容器是不是十分麻烦!我们可以在容器外部提供一个映射路径。webapps,我们在外部放置项目,自动同步到内部就好了
部署es + kibana
部署es + kibana
# es 暴露的端口很多
# es 十分耗内存
# es 的数据一般需要放置到安全目录
# --net somenetwork 网络配置
# 启动命令
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch
# 先不配网络配置
[root@bogon home]# docker pull elasticsearch
Using default tag: latest
latest: Pulling from library/elasticsearch
05d1a5232b46: Pull complete
5cee356eda6b: Pull complete
89d3385f0fd3: Pull complete
65dd87f6620b: Pull complete
78a183a01190: Pull complete
1a4499c85f97: Pull complete
2c9d39b4bfc1: Pull complete
1b1cec2222c9: Pull complete
59ff4ce9df68: Pull complete
1976bc3ee432: Pull complete
5af49e8af381: Pull complete
42c8b75ff7af: Pull complete
7e6902915254: Pull complete
99853874fa54: Pull complete
596fbad6fcff: Pull complete
Digest: sha256:a8081d995ef3443dc6d077093172a5931e02cdb8ffddbf05c67e01d348a9770e
Status: Downloaded newer image for elasticsearch:latest
docker.io/library/elasticsearch:latest
# 启动
[root@bogon home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch
8be0504fac6a81f495656ae5fdaf9ec320b65464390ea7fb534a6f4e73c10c4b
[root@bogon home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8be0504fac6a elasticsearch "/docker-entrypoint.…" 25 minutes ago Up 25 minutes 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch
# 访问elasticsearch
[root@bogon home]# curl localhost:9200
{
"name" : "1oUS21Q",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "fpFaVNLLQBaVqNlLitvuSg",
"version" : {
"number" : "5.6.12",
"build_hash" : "cfe3d9f",
"build_date" : "2018-09-10T20:12:43.732Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
# 查看docker CPU状态
[root@bogon home]# docker stats
# 占用内存/系统内存 # 占用内存百分比
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
8be0504fac6a elasticsearch 0.03% 511.2MiB / 972.3MiB 52.58% 10.9kB / 10.7kB 0B / 0B 31
# 关闭, 增加内存限制 修改配置文件 使用-e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch
[root@bogon home]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
af15a9678b17 elasticsearch 0.01% 214.6MiB / 972.3MiB 22.07% 656B / 0B 0B / 0B 33
可视化
- portainer
- Rancher
portainer
Docker图形化界面管理工具,提供一个后台面板供我们操作
# 安装并启动
docker run -d -p 9000:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 开放9000端口
[root@bogon home]# firewall-cmd --zone=public --add-port=9000/tcp --permanent
success
# 重启防火墙
[root@bogon home]# firewall-cmd --reload
success
# 测试连接
http://192.168.94.129:9000/
Docker镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
所有的应用直接打包成docker镜像,就可以直接跑起来!
如何得到镜像:
- 从远程仓库下载
- 朋友拷贝
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFs(联合文件系统)
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
Docker的镜像实际上是由一层一层的文件系统组成,这种层级的文件系统叫UnionFs(联合文件系统)。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动的时候会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的是使用权已由boofs转交给内核,此时系统也会卸载boofs。
rootfs(boot file system),在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的Centos都是好几个G,为什么Docker这里才200M?
对于一个精简的OS,bootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供bootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。
分层理解
容器数据卷
什么是容器数据卷
如果数据都在容器中,一旦容器删除,数据就会丢失!
eg : mysql容器删了,就是我们常说的删库跑路。 需求:数据可以持久化,即时删掉容器,我们的数据还在
容器直接可以有一个数据共享的技术!Docker容器产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器的目录挂载到linux上面!
总结:卷技术就是为了实现数据的持久化和同步操作,容器间也是可以数据共享的
使用数据卷
方式一:直接使用命令来挂载 -v
# 命令
docker run -it -v 主机的目录:容器内目录 -p 主机端口:容器端口
# 测试
# 主机home目录下为空
[root@bogon home]# ls
# 启动contes镜像 将主机的home与容器的home进行绑定
[root@bogon home]# docker run -v /home:/home/ -it centos
[root@8dc073caf39c /]# cd home/
# 容器home目录下为空
[root@8dc073caf39c home]# ls
# 在容器目录下创建test.java文件
[root@8dc073caf39c home]# touch test.java
[root@8dc073caf39c home]# ls
test.java
# 切换到主机home目录后发现 出现了test.java文件
[root@8dc073caf39c home]# [root@bogon home]# ls
test.java
# 在主机home目录下创建test2.java文件
[root@bogon home]# touch test2.java
[root@bogon home]# ls
test2.java test.java
[root@bogon home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8dc073caf39c centos "/bin/bash" 3 minutes ago Up 3 minutes focused_nobel
# 进入正在运行的容器
[root@bogon home]# docker exec -it 8dc073caf39c /bin/bash
# 进入容器home目录
[root@8dc073caf39c /]# cd home/
# 发现存在test2.java文件
[root@8dc073caf39c home]# ls
test.java test2.java
# 通过 inspect 命令查看容器信息
[root@bogon home]# docker inspect 8dc073caf39c
"Mounts": [
{
"Type": "bind",
"Source": "/home", # 主机目录
"Destination": "/home", # 容器目录
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
## 结论:如果我们使用 -v 做了数据绑定
# 1、容器停止,主机对数据做出修改 容器启动后 数据也会同步过来
# 2、删除容器,主机该目录下数据还存在
## 好处:在使用了数据卷后,我们以后修改配置文件时,只需要在本地修改,容器内会自动同步
安装mysql
mysql的数据持久化问题
# -e MYSQL_ROOT_PASSWORD=my-secret-pw 设置初始密码为my-secret-pw
# 官方命令: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 测试
# 解读
# -d 后台运行
# -p 3306:3306 绑定端口
# -v /home/mysql/conf:/etc/mysql/conf.d 数据卷挂载技术绑定mysql配置文件
# -v /home/mysql/data:/var/lib/mysql 数据卷挂载技术绑定mysql数据
# -e MYSQL_ROOT_PASSWORD=123456 环境配置---》设置mysql初始密码为123456
# --name mysql0 给容器起名为mysql01
[root@bogon home]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
6d75b6312f725de2c71709116af5755604ea60cd073f1daf3755c578c1e64f57
具名和匿名挂载
# 匿名挂载
-v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 测试匿名挂载
[root@localhost test]# docker run -d -P --name nginx01 -v /etc/nginx nginx
214dab398d9997a730b970b6e3bb08fa7e39bbb0ca91ad59f6b3f235d8f1b9bc
# 查看所有 volume 的情况
[root@localhost test]# docker volume ls
DRIVER VOLUME NAME
local 2c22e1c50ff7330b815b692f8f71a1fca878209223846c95626f7efd9dc2a83b # 匿名挂载
# 测试具名挂载
# 通过 -v 卷名:容器内路径
[root@localhost test]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
a678d79886565601bf466ff41734cb5334bdaf9e881b9cbf11edb84e9d790251
# 查看所有 volume 的情况
[root@localhost test]# docker volume ls
DRIVER VOLUME NAME
local 2c22e1c50ff7330b815b692f8f71a1fca878209223846c95626f7efd9dc2a83b # 匿名挂载
local juming-nginx # 具名挂载
# 查看某个数据卷的信息
# 命令
docker volume inspect 卷名
# 所有docker容器内的卷 在没有指定目录的情况下都在 /var/lib/docker/volumes/XXX/_data
[root@localhost test]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-08-13T09:18:34+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
# 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的----具名挂载
# 如何确定是具名挂载还是匿名挂载 还是指定路径挂载!
# -v 容器内路径 # 匿名挂载
# -v 卷名:容器内路径 # 具名挂载
# -v 主机路径:容器内路径 # 指定路径挂载
拓展
# 通过 -v 卷名:容器内路径:ro rw 改变读写权限
# ro--->read only 只读
# rw--->read write 读写
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx
初识DockerFile
DockerFile就是用来构建 docker 镜像的构建文件!命令脚本! 先体验一下!
[root@localhost docker-test-volume]# cat dockerfile
FORM centos
VOLUME ["volume01", "volume02"]
CMD echo "-----end-----"
CMD /bin/bash
# 构建
# 命令 docker build -f shell脚本文件 -t 镜像名:版本号
[root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["volume01", "volume02"]
---> Running in 4e6de7bc2f15
Removing intermediate container 4e6de7bc2f15
---> f9e48207902b
Step 3/4 : CMD echo "-----end-----"
---> Running in b22adea363e5
Removing intermediate container b22adea363e5
---> a7518e2e1c72
Step 4/4 : CMD /bin/bash
---> Running in ae1b746bef6b
Removing intermediate container ae1b746bef6b
---> d840628c30a9
Successfully built d840628c30a9
Successfully tagged centos:1.0
# 查看镜像
[root@localhost overlay2]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 1.0 d840628c30a9 12 minutes ago 215MB # 我们自己生成的镜像
centos latest 0d120b6ccaa8 2 days ago 215MB
# 启动我们生成的镜像
[root@1af673cf9c88 /]# docker run -it d840628c30a9 /bin/bash
[root@1af673cf9c88 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Aug 13 02:18 dev
drwxr-xr-x. 1 root root 66 Aug 13 02:18 etc
drwxr-xr-x. 2 root root 6 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
drwx------. 2 root root 6 Aug 9 21:40 lost+found
drwxr-xr-x. 2 root root 6 May 11 2019 media
drwxr-xr-x. 2 root root 6 May 11 2019 mnt
drwxr-xr-x. 2 root root 6 May 11 2019 opt
dr-xr-xr-x. 117 root root 0 Aug 13 02:18 proc
dr-xr-x---. 2 root root 162 Aug 9 21:40 root
drwxr-xr-x. 11 root root 163 Aug 9 21:40 run
lrwxrwxrwx. 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 May 11 2019 srv
dr-xr-xr-x. 13 root root 0 Aug 11 09:58 sys
drwxrwxrwt. 7 root root 145 Aug 9 21:40 tmp
drwxr-xr-x. 12 root root 144 Aug 9 21:40 usr
drwxr-xr-x. 20 root root 262 Aug 9 21:40 var
drwxr-xr-x. 2 root root 6 Aug 13 02:18 volume01 # 这是我们生成镜像的时候自动挂载的数据卷目录
drwxr-xr-x. 2 root root 6 Aug 13 02:18 volume02
# 这个卷和外部一定有一个同步的目录!我们来找一下
# 1、 根据容器id查询该容器的信息--》数据卷信息
# docker inspect 1af673cf9c88
# 2、 根据数据卷信息找到 volume01 对应的数据卷名称
# docker volume inspect 8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3
# 3、 根据数据卷名称 查询数据卷的信息--》找到linux中对应的目录
# docker volume inspect 8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3
# 在容器内部创建一个文件 在数据卷 volume01 中创建了test.java文件
[root@1af673cf9c88 volume01]# touch test.java
[root@1af673cf9c88 volume01]# ls
test.java
# 退出容器
[root@1af673cf9c88 volume01]# exit
exit
# 查看该容器的信息
[root@localhost overlay2]# docker inspect 1af673cf9c88
# 找到挂载卷 volume01 对应的的名字, 即:8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3
"Mounts": [
{
"Type": "volume",
"Name": "8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3",
"Source": "/var/lib/docker/volumes/8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "046d0baa3cc0bc3540c5e7248808358371641bfba4e0bbd139c99fe851751da2",
"Source": "/var/lib/docker/volumes/046d0baa3cc0bc3540c5e7248808358371641bfba4e0bbd139c99fe851751da2/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
# 根据数据卷名字 8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3 找到该卷在 linux 所在位置
[root@localhost overlay2]# docker volume inspect 8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3
[
{
"CreatedAt": "2020-08-13T10:27:12+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3/_data",
"Name": "8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3",
"Options": null,
"Scope": "local"
}
]
# 在/var/lib/docker/volumes/8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3/_data/目录下找到我们的test.java文件
[root@localhost volumes]# cd /var/lib/docker/volumes/8c3486526093c755785725111b4063cd93a5ba88f9c2ac09f45741a0f1d08fd3/_data/
[root@localhost _data]# ls
test.java
数据卷容器
多个mysql数据同步!
# 通过 --volumes-from 容器名 实现容器间的数据共享
# 启动一个镜像 名字是docker01
[root@localhost _data]# docker run -it --name docker01 centos:1.0 /bin/bash
[root@a85fbed0ebc9 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 启动同一个镜像 名字是docker02 关联 docker01 此时,docker01被称为数据卷容器
[root@localhost _data]# docker run -it --name docker02 --volumes-from docker01 centos:1.0
[root@a89fb82eeeb5 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 在容器 docker02 的 volume01 目录下创建 test.txt
[root@a89fb82eeeb5 /]# cd volume01/
[root@a89fb82eeeb5 volume01]# ls
[root@a89fb82eeeb5 volume01]# touch test.txt
[root@a89fb82eeeb5 volume01]# ls
test.txt
# 查看容器信息
[root@a89fb82eeeb5 volume01]# [root@localhost _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a89fb82eeeb5 centos:1.0 "/bin/sh -c /bin/bash" About a minute ago Up About a minute docker02
a85fbed0ebc9 centos:1.0 "/bin/bash" 4 minutes ago Up 4 minutes docker01
# 进入容器名为 docker01 的容器
[root@localhost _data]# docker exec -it a85fbed0ebc9 /bin/bash
[root@a85fbed0ebc9 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 进入该容器的 volume01 目录下
[root@a85fbed0ebc9 /]# cd volume01/
# 发现test.txt文件
[root@a85fbed0ebc9 volume01]# ls
test.txt
# 创建 test01.txt
[root@a85fbed0ebc9 volume01]# touch test01.txt
[root@a85fbed0ebc9 volume01]# ls
test.txt test01.txt
# 进入容器名为 docker02 的容器
[root@localhost _data]# docker exec -it a89fb82eeeb5 /bin/bash
[root@a89fb82eeeb5 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@a89fb82eeeb5 /]# cd volume01/
# 发现test01.txt文件
[root@a89fb82eeeb5 volume01]# ls
test.txt test01.txt
# 启动同一个镜像 名字是docker03 关联 docker01
[root@localhost _data]# docker run -it --name docker03 --volumes-from docker01 centos:1.0
# 进入volume01目录下 发现 test.txt test01.txt 文件
[root@11d93f9bcd89 /]# cd volume01/
[root@11d93f9bcd89 volume01]# ls
test.txt test01.txt
#测试过程: 1、运行centos:1.0镜像 容器名为docker01
# 2、运行centos:1.0镜像 容器名为docker02 通过 --volumes-from docker01 与其进行数据共享
# 3、运行centos:1.0镜像 容器名为docker03 通过 --volumes-from docker01 与其进行数据共享
# 4、运行centos:1.0镜像 容器名为docker04 通过 --volumes-from docker03 与其进行数据共享
# 5、运行centos镜像 容器名为docker05 通过 --volumes-from docker03 与其进行数据共享
# 经过测试 发现:
# 1、在任何一个容器的volume01目录中添加文件,其他四个容器中的该目录都会出现添加的这个文件,进行数据共享
# 2、停止并删除 容器名为docker01的容器,其他四个容器中volume01目录下的文件还存在
# 3、停止并删除 容器名为docker01的容器,向其他四个容器任意一个容器的volume01目录下添加文件,其余三个容器也会做数据共享
# 4、各个容器中的数据卷名称不同,但是对应同一个linux系统中数据目录;即各个容器中的数据卷目录都指向linux系统中同一个数据目录
[root@localhost _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78cd51a35c41 centos "/bin/bash" 17 minutes ago Up 17 minutes trusting_tharp
e6e0988c50cd centos "/bin/bash" 17 minutes ago Up 17 minutes docker05
c5ebc03e6819 centos:1.0 "/bin/sh -c /bin/bash" 19 minutes ago Up 19 minutes docker04
11d93f9bcd89 centos:1.0 "/bin/sh -c /bin/bash" 22 minutes ago Up 22 minutes docker03
a89fb82eeeb5 centos:1.0 "/bin/sh -c /bin/bash" 31 minutes ago Up 31 minutes docker02
[root@localhost _data]# docker inspect e6e0988c50cd
"Mounts": [
{
"Type": "volume",
"Name": "fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62",
"Source": "/var/lib/docker/volumes/fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
]
[root@localhost _data]# docker inspect c5ebc03e6819
"Mounts": [
{
"Type": "volume",
"Name": "fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62",
"Source": "/var/lib/docker/volumes/fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
]
[root@localhost _data]# docker inspect 11d93f9bcd89
"Mounts": [
{
"Type": "volume",
"Name": "fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62",
"Source": "/var/lib/docker/volumes/fc54c991eea888057575be45a03fe22a32303a6b1239a0a4099dd201b0b41a62/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
]
多个mysql实现数据共享
docker run -d -p 3306:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql
结论:
容器之间配置信息传递,数据卷容器的生命周期一直持续到没有容器使用位置。
但是一旦持久化到本地,这个时候,本地的数据不会删除。
DockerFile
dockerfile 是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
- 编写一个dockerfile 文件
- docker build 构建成一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库)
# 以contes为例 查看 dockerhub 上 contes 的 dockerfile
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="20200809" \
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-08-09 00:00:00+01:00"
CMD ["/bin/bash"]
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 执行顺序从上到下顺序执行
-
表示注释
- 每个指令都会创建提交一个新的镜像层,并提交
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准!
DockerFile:构建镜像,定义了一切的步骤,源代码;
DockerImages:通过DockerFile构建生成的一个镜像,这个镜像就是我们最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务!
DockerFile的指令
FROM # 基础镜像
MAINTAINER # 镜像是谁写的 姓名 + 邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤 eg:tomcat镜像---》放入tomcat的压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录位置
EXPOST # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承的 DockerFile ,这个时候就会运行 ONBUILD 的指令,触发指令
COPY # 类似ADD,将我们的文件拷贝到镜像中
ENV # 构建的时候设置环境变量
实战测试
Docker Hub 中 99% 的镜像都是从 FROM scratch 这个基础镜像过来的 ,然后配置我们需要的软件和配置来进行构建
创建一个自己的centos
# 1、编写DockerFile的文件
FROM centos
# 作者信息
MAINTAINER yinxiaodong<m15010969094@163.com>
# 配置环境变量
ENV MYPATH /user/local
# 指定镜像的工作目录
WORKDIR $MYPATH
RUN yum install -y vim
RUN yum install -y net-tools
# 暴露80端口
EXPOSE 80
CMD echo $MYPATH
CMD echo "---------end--------"
CMD /bin/bash
# 2、通过文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:版本号 .
[root@localhost dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/9 : FROM centos
---> 0d120b6ccaa8
Step 2/9 : MAINTAINER yinxiaodong<m15010969094@163.com>
---> Running in f79b12ffb083
Removing intermediate container f79b12ffb083
---> 8ee53d3f7a65
Step 3/9 : ENV MYPATH /user/local
---> Running in 659a2c96d5f7
Removing intermediate container 659a2c96d5f7
---> 59ab131ef44c
Step 4/9 : WORKDIR $MYPATH
---> Running in 0b4b8f9c65bb
Removing intermediate container 0b4b8f9c65bb
---> 408b06671488
Step 5/9 : RUN yum install -y net-tools
---> Running in 151f81148a87
CentOS-8 - AppStream 118 kB/s | 5.8 MB 00:50
CentOS-8 - Base 218 kB/s | 2.2 MB 00:10
CentOS-8 - Extras 1.8 kB/s | 7.3 kB 00:04
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.51.20160912git.el8 BaseOS 323 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 323 k
Installed size: 1.0 M
Downloading Packages:
net-tools-2.0-0.51.20160912git.el8.x86_64.rpm 219 kB/s | 323 kB 00:01
--------------------------------------------------------------------------------
Total 66 kB/s | 323 kB 00:04
warning: /var/cache/dnf/BaseOS-f6a80ba95cf937f2/packages/net-tools-2.0-0.51.20160912git.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - Base 162 kB/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 : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.51.20160912git.el8.x86_64
Complete!
Removing intermediate container 151f81148a87
---> c0a0546c9b2a
Step 6/9 : EXPOSE 80
---> Running in 42000936515d
Removing intermediate container 42000936515d
---> fe68114ecf3f
Step 7/9 : CMD echo $MYPATH
---> Running in c393fc53a354
Removing intermediate container c393fc53a354
---> a6924276bf90
Step 8/9 : CMD echo "---------end--------"
---> Running in 5994de56f0a1
Removing intermediate container 5994de56f0a1
---> a8ba0ebb3770
Step 9/9 : CMD /bin/bash
---> Running in d1fa2d436363
Removing intermediate container d1fa2d436363
---> 41bb76be4884
Successfully built 41bb76be4884
Successfully tagged mycentos:0.1
[root@localhost dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 41bb76be4884 7 seconds ago 246MB
centos 1.0 d840628c30a9 6 hours ago 215MB
centos latest 0d120b6ccaa8 2 days ago 215MB
# 启动 mycentos 使用 ifconfig 命令查看ip信息
[root@localhost dockerfile]# docker run -it mycentos:0.1
[root@494c2bc72263 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 6 bytes 516 (516.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 查看所在目录 /user/local 正是我们在dockerfile中指定的目录
[root@494c2bc72263 local]# pwd
/user/local
查看镜像的构建历史记录
# 命令 docker history 镜像id
[root@localhost ~]# docker history 41bb76be4884
IMAGE CREATED CREATED BY SIZE COMMENT
41bb76be4884 16 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
a8ba0ebb3770 16 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
a6924276bf90 16 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
fe68114ecf3f 16 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
c0a0546c9b2a 16 minutes ago /bin/sh -c yum install -y net-tools 31.3MB
408b06671488 17 minutes ago /bin/sh -c #(nop) WORKDIR /user/local 0B
59ab131ef44c 17 minutes ago /bin/sh -c #(nop) ENV MYPATH=/user/local 0B
8ee53d3f7a65 17 minutes ago /bin/sh -c #(nop) MAINTAINER yinxiaodong<m1… 0B
0d120b6ccaa8 2 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 days ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 days ago /bin/sh -c #(nop) ADD file:538afc0c5c964ce0d… 215MB
我们平时拿到一个镜像,可以研究一下它是怎么做的---->docker history 镜像id
CMD 和 ENTRYPOINT 的区别
CMD 和 ENTRYPOINT 的区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
# 测试 CMD
# 编写DockerFile的文件
[root@localhost dockerfile]# cat dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
# 根据 DockerFile 构建镜像
[root@localhost dockerfile]# docker build -f dockerfile-cmd-test -t testcmd:0.1 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 0d120b6ccaa8
Step 2/2 : CMD ["ls","-a"]
---> Running in b3f8ba72222b
Removing intermediate container b3f8ba72222b
---> 561e47f88730
Successfully built 561e47f88730
Successfully tagged testcmd:0.1 # 构建成功
# 查看镜像
[root@localhost dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
testcmd 0.1 561e47f88730 6 seconds ago 215MB
centos latest 0d120b6ccaa8 2 days ago 215MB
# 启动镜像 发现ls -a命令生效
[root@localhost dockerfile]# docker run -it testcmd:0.1
. .dockerenv dev home lib64 media opt root sbin sys usr
.. bin etc lib lost+found mnt proc run srv tmp var
# 启动命令中 追加一个 -l, 我们期望的是 ls -a -l,但是 报错,这里将 ls -a 替换成了 -l,最终的命令是 -l 所以报错。
[root@localhost dockerfile]# docker run -it 561e47f88730 -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.
# 将启动命令替换成 docker run -it testcmd:0.1 ls -al, 成功打印详细信息;
[root@localhost dockerfile]# docker run -it testcmd:0.1 ls -al
total 0
drwxr-xr-x. 1 root root 6 Aug 13 08:20 .
drwxr-xr-x. 1 root root 6 Aug 13 08:20 ..
-rwxr-xr-x. 1 root root 0 Aug 13 08:20 .dockerenv
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Aug 13 08:20 dev
drwxr-xr-x. 1 root root 66 Aug 13 08:20 etc
drwxr-xr-x. 2 root root 6 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
drwx------. 2 root root 6 Aug 9 21:40 lost+found
drwxr-xr-x. 2 root root 6 May 11 2019 media
drwxr-xr-x. 2 root root 6 May 11 2019 mnt
drwxr-xr-x. 2 root root 6 May 11 2019 opt
dr-xr-xr-x. 123 root root 0 Aug 13 08:20 proc
dr-xr-x---. 2 root root 162 Aug 9 21:40 root
drwxr-xr-x. 11 root root 163 Aug 9 21:40 run
lrwxrwxrwx. 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 May 11 2019 srv
dr-xr-xr-x. 13 root root 0 Aug 11 09:58 sys
drwxrwxrwt. 7 root root 145 Aug 9 21:40 tmp
drwxr-xr-x. 12 root root 144 Aug 9 21:40 usr
drwxr-xr-x. 20 root root 262 Aug 9 21:40 var
# 测试二:现在我们把 DockerFile 中 CMD 替换成 ENTRYPOINT 后重新构建,运行 看看结果
[root@localhost dockerfile]# cat dockerfile-cmd-test
FROM centos
ENTRYPOINT ["ls","-a"]
# 重新构建镜像
[root@localhost dockerfile]# docker build -f dockerfile-cmd-test -t testcmd:0.2 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 0d120b6ccaa8
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in c634ca09fabe
Removing intermediate container c634ca09fabe
---> 52d295395f08
Successfully built 52d295395f08
Successfully tagged testcmd:0.2
# 查看镜像
[root@localhost dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
testcmd 0.2 52d295395f08 7 seconds ago 215MB
testcmd 0.1 561e47f88730 12 minutes ago 215MB
centos latest 0d120b6ccaa8 2 days ago 215MB
# 运行testcmd:0.2镜像 并追加 -l ,发现 打印出了详细信息
[root@localhost dockerfile]# docker run -it testcmd:0.2 -l
total 0
drwxr-xr-x. 1 root root 6 Aug 13 08:17 .
drwxr-xr-x. 1 root root 6 Aug 13 08:17 ..
-rwxr-xr-x. 1 root root 0 Aug 13 08:17 .dockerenv
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Aug 13 08:17 dev
drwxr-xr-x. 1 root root 66 Aug 13 08:17 etc
drwxr-xr-x. 2 root root 6 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
drwx------. 2 root root 6 Aug 9 21:40 lost+found
drwxr-xr-x. 2 root root 6 May 11 2019 media
drwxr-xr-x. 2 root root 6 May 11 2019 mnt
drwxr-xr-x. 2 root root 6 May 11 2019 opt
dr-xr-xr-x. 121 root root 0 Aug 13 08:17 proc
dr-xr-x---. 2 root root 162 Aug 9 21:40 root
drwxr-xr-x. 11 root root 163 Aug 9 21:40 run
lrwxrwxrwx. 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 May 11 2019 srv
dr-xr-xr-x. 13 root root 0 Aug 11 09:58 sys
drwxrwxrwt. 7 root root 145 Aug 9 21:40 tmp
drwxr-xr-x. 12 root root 144 Aug 9 21:40 usr
drwxr-xr-x. 20 root root 262 Aug 9 21:40 var
DockerFile中很多命令都十分相似,我们需要了解他的区别,最好的学习就是对比进行测试查看效果!
实战:Tomcat镜像
1、准备镜像文件 tomcat压缩包 jdk压缩包
[root@localhost tomcat]# ls
apache-tomcat-8.5.43.tar.gz Dockerfile jdk-8u211-linux-x64.tar.gz read.txt
2、编写dockerfile文件, 官方命名Dockerfile
,build会自动寻找这个文件,不需要 -f 指定!
# 引入基础
FROM centos
# 作者信息
MAINTAINER yinxiaodoong<m15010969094@163.com>
# copy文件read.txt到容器的 /usr/local/read.txt 目录下
COPY read.txt /usr/local/read.txt
# 添加jdk tomcat ---> 自动解压
ADD jdk-8u211-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.43.tar.gz /usr/local/
# 安装 vim 命令
RUN yum install -y vim
# 配置 MYPATH
ENV MYPATH /usr/local/
# 指定 进入容器默认路径 /user/local/
WORKDIR $MYPATH
# 配置jdk环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV CLASSPATH $JAVA_HOME/lib/dt.jat:$JAVA_HOME/lib/tools.jar
# 配置tomcat环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.43
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.43
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 暴露8080端口
EXPOSE 8080
# /usr/local/tomcat/webapps#
# 启动容器时 启动tomcat
CMD /usr/local/apache-tomcat-8.5.43/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.43/logs/catalina.out
# 构建tomcat镜像
[root@localhost tomcat]# docker build -t mytomcat
[root@localhost tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest a9707559afa1 8 seconds ago 693MB
centos latest 0d120b6ccaa8 4 days ago 215MB
[root@localhost tomcat]# docker run -d -p 8081:8080 --name mytomcat--01 -v /home/yinxiaodong/build/tomcat/test:/usr/local/apache-tomcat-8.5.43/webapps/test -v /home/yinxiaodong/build/tomcat/logs:/usr/local/apache-tomcat-8.5.43/logs mytomcat
发布自己的镜像
发布到 dockerHub
- 地址 https://hub.docker.com/ 注册自己的账号
- 确定自己的账号可以登录
- 在我们的服务器上提交
[root@localhost logs]# 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
[root@localhost logs]#
[root@localhost logs]# docker login -u xxx -p xxx
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
- 登录完毕后就可以提交镜像了
[root@localhost logs]# docker push xxx/mytomcat:1.0
Docker 网络
理解docker0
[root@localhost ~]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:e5:08:5c brd ff:ff:ff:ff:ff:ff
inet 192.168.129.128/24 brd 192.168.129.255 scope global noprefixroute dynamic ens33
valid_lft 1357sec preferred_lft 1357sec
inet6 fe80::7e5d:39f7:3d7a:13b3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 02:78:77:86:6c:99 brd ff:ff:ff:ff:ff:ff
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
# docker0 地址
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:53:7b:70:02 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
问题: docker 是如何处理容器网络访问的?
分别有两个容器:tomcat容器和mysql容器 tomcat里的项目如何访问mysql服务的?
# 测试
# 启动tomcat 容器
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat
# 查看容器内部网络地址 docker exec -it 容器id/容器名 ip addr
[root@localhost ~]# docker exec -it tomcat01 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
7: eth0@if8: <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
# 发现docker启动一个容器的时候会得到一个 eth0@if8 ip地址 ,这个地址是docker分配的!
# linux ping 一下这个容器ip 发现可以 ping 通 docker 容器内部
[root@localhost ~]# 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.082 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms
原理
- 我们只要安装了docker,就会有一个网卡docker0;每启动一个docker容器, docker就会给docker容器分配一个ip
# 再次测试 ip addr
[root@localhost ~]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:e5:08:5c brd ff:ff:ff:ff:ff:ff
inet 192.168.129.128/24 brd 192.168.129.255 scope global noprefixroute dynamic ens33
valid_lft 1355sec preferred_lft 1355sec
inet6 fe80::7e5d:39f7:3d7a:13b3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 02:78:77:86:6c:99 brd ff:ff:ff:ff:ff:ff
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:53:7b:70:02 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:53ff:fe7b:7002/64 scope link
valid_lft forever preferred_lft forever
8: veth8ee6b7e@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether e6:9b:b2:a0:27:ae brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::e49b:b2ff:fea0:27ae/64 scope link
valid_lft forever preferred_lft forever
# 发现 多出来一个 ip--》8: veth8ee6b7e@if7 ,这个ip 与 docker给tomcat容器分配的ip--》7: eth0@if8 及其相似
# 我们再次启动一个容器
[root@localhost ~]# docker run -d -P --name tomcat02 tomcat
7ffaff397ae1ad5ea86265b28796eadacc8814dae08de0c297b844df32dafb0f
# 查看 tomcat02 容器ip
[root@localhost ~]# docker exec -it tomcat02 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
9: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 再次查看 linux 中 ip
[root@localhost ~]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:e5:08:5c brd ff:ff:ff:ff:ff:ff
inet 192.168.129.128/24 brd 192.168.129.255 scope global noprefixroute dynamic ens33
valid_lft 1732sec preferred_lft 1732sec
inet6 fe80::7e5d:39f7:3d7a:13b3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 02:78:77:86:6c:99 brd ff:ff:ff:ff:ff:ff
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:5e:88:8b brd ff:ff:ff:ff:ff:ff
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:53:7b:70:02 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:53ff:fe7b:7002/64 scope link
valid_lft forever preferred_lft forever
8: veth8ee6b7e@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether e6:9b:b2:a0:27:ae brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::e49b:b2ff:fea0:27ae/64 scope link
valid_lft forever preferred_lft forever
10: veth913a4fc@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 7a:6d:fa:f4:5a:31 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::786d:faff:fef4:5a31/64 scope link
valid_lft forever preferred_lft forever
# 再次测试 发现又多了一对网卡!
我们发现这个容器带来的网卡都是一对一对的
evth-pair 就是 一对的虚拟设备接口,他们都是成对出现的, 一段连着协议,一段彼此相连
正因为有这个特性,evth-pair 充当一个桥梁 连接各种虚拟网络设备的
OpenStac Docker 容器直接的连接 , ovs的连接 都是用的 evth-pair 技术
测试下tomcat02 和 comcat01 是否可以ping通!
[root@localhost ~]# 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.193 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.156 ms
# 结论: 容器直接是可以互相ping通的
# docker 中所以的网络接口都是虚拟的 虚拟的转发效率高!
# 容器一旦停止 对应的网桥就没有了
--link
思考一个场景:我们编写了一个微服务,在项目不重启的情况下 ip换掉了,我们怎么处理这个问题!可以通过名字访问服务--->实现高可用
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ffaff397ae1 tomcat "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32769->8080/tcp tomcat02
17465fe4ff5f tomcat "catalina.sh run" About an hour ago Up 9 seconds 0.0.0.0:32770->8080/tcp tomcat01
# tomcat02 ping tomcat01 发现 ping 不通
[root@localhost ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Temporary failure in name resolution
# 如何解决?
# 再次启动一个tomcat03 使用--link 指定tomcat02
[root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
b8302b88ece2db2d116ef48f066495dfac2249e024f82e5262551dc75beadafd
# 发现 tomcat03 可以 ping 通 tomcat02
[root@localhost ~]# 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.140 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.156 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.061 ms
# 但是 tomcat02 不可以 ping 通 tomcat03
[root@localhost ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Temporary failure in name resolution
################################ 探究 ##############################################
# 查看tomcat03的 /etc/hosts 文件, 发现了 tomcat02 的映射
[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 tomcat02 7ffaff397ae1
172.17.0.4 b8302b88ece2
# tomcat02 的 /etc/hosts 文件中 没有tomcat03的映射
[root@localhost ~]# docker exec -it tomcat02 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 7ffaff397ae1
现在使用docker 不推荐使用--link的方式了
使用自定义网络,不使用docker0!
docker0问题:它不支持容器名连接
自定义网络
[root@localhost ~]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
# 查看docker网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4dfeab10f9bd bridge bridge local
3544ab1c8265 host host local
ba0aafb19089 none null local
网络模式
bridge: 桥接 docker(默认)
none: 不配置网络
host: 和宿主机共享网络
container: 容器网络连通(用的少!局限性很大)
测试
# 我们直接启动的命令 docker run -d -P --name tomcat01 tomcat 默认加了--net bridge,而这个--net bridge就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0 特点:是默认的;域名不能访问的 --link可以打通连接
# 我们自定义一个网络
--driver bridge 桥接
--subnet 192.168.0.0/16 子网地址
--gateway 192.168.0.1 网关
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
b82de0e455b464239dd2cd70c0c409aee43cc3b6c5015b00d77e9ab2c4ce708e
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4dfeab10f9bd bridge bridge local
3544ab1c8265 host host local
b82de0e455b4 mynet bridge local
ba0aafb19089 none null local
# 查看我们的自定义网络信息
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "b82de0e455b464239dd2cd70c0c409aee43cc3b6c5015b00d77e9ab2c4ce708e",
"Created": "2020-08-16T13:54:31.417280908+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 启动tomcat容器 走我们自定义的网络
[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
b98cc4bf86e029feb61fbc1f73bb48760635d26238c79a50bb817a65689742a6
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
8536a22077f7f4676ff63ff7f6b60dbe86eac1fd51051725612a448de3886b84
[root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.161 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.055 ms
# 发现 tomcat-net-01 和 tomcat-net-02 容器 网络是互通的
# 再次查看 我们的自定义网络 mynet, 发现 Containers 里已经有了两个容器
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "b82de0e455b464239dd2cd70c0c409aee43cc3b6c5015b00d77e9ab2c4ce708e",
"Created": "2020-08-16T13:54:31.417280908+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"8536a22077f7f4676ff63ff7f6b60dbe86eac1fd51051725612a448de3886b84": {
"Name": "tomcat-net-02",
"EndpointID": "59b045316d51b615e31c6ef2473c4cbd85da8da4a42619b25a14ddb431d20fd7",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"b98cc4bf86e029feb61fbc1f73bb48760635d26238c79a50bb817a65689742a6": {
"Name": "tomcat-net-01",
"EndpointID": "1778ebe20410bcedc65414b8b991624fe835843e378b2e19ada8a2394ba5eb47",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
我们自定义的网络docker已经帮我们维护好了对应关系,推荐我们平时自定义网络使用!
好处:
1. redis--->不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
我们自定义的网络,各个网络直接是不通的
tomcat镜像启动使用的是net01网络,mysql镜像使用的是net02网络,这两个容器直接的网络是不通的,如何打通呢?
# 查看network的帮助命令
[root@localhost ~]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network # 连接一个容器到一个网络
create Create a network # 创建一个网络
disconnect Disconnect a container from a network # 断开一个容器到一个网络
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
# 查看network connect的帮助命令
[root@localhost ~]# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
# 测试
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f5a5a058908c tomcat "catalina.sh run" 3 seconds ago Up 2 seconds 0.0.0.0:32775->8080/tcp tomcat-03
72ffc620842e tomcat "catalina.sh run" 7 seconds ago Up 6 seconds 0.0.0.0:32774->8080/tcp tomcat-01
8536a22077f7 tomcat "catalina.sh run" 52 minutes ago Up 52 minutes 0.0.0.0:32773->8080/tcp tomcat-net-02
b98cc4bf86e0 tomcat "catalina.sh run" 52 minutes ago Up 52 minutes 0.0.0.0:32772->8080/tcp tomcat-net-01
# 打通tomcat-01 ---- mynet
[root@localhost ~]# docker network connect mynet tomcat-01
# 打通后 使用tomcat-01 ping mynet 下的 tomcat-net-01,发现可以ping通
[root@localhost ~]# docker exec -it tomcat-01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.165 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.053 ms
# 查看 mynet 网络信息 容器内多了 tomcat-01
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "b82de0e455b464239dd2cd70c0c409aee43cc3b6c5015b00d77e9ab2c4ce708e",
"Created": "2020-08-16T13:54:31.417280908+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"72ffc620842e842ef2f59161f9c66a2c4c27c49a5cf5bbe20634eb34e2dff651": {
"Name": "tomcat-01",
"EndpointID": "d2f3c68a0b2b75d5a7b36fc738450f9069cc27b602a3dcdb648618f87b645762",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"8536a22077f7f4676ff63ff7f6b60dbe86eac1fd51051725612a448de3886b84": {
"Name": "tomcat-net-02",
"EndpointID": "59b045316d51b615e31c6ef2473c4cbd85da8da4a42619b25a14ddb431d20fd7",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"b98cc4bf86e029feb61fbc1f73bb48760635d26238c79a50bb817a65689742a6": {
"Name": "tomcat-net-01",
"EndpointID": "1778ebe20410bcedc65414b8b991624fe835843e378b2e19ada8a2394ba5eb47",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!
Docker 遇到的问题
number
有一天早上在公司 连接linux后 输入docker images 命令 出现如下错误
原因是docker服务没启
[root@localhost yin]# docker images
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
# 启动 docker 服务
[root@localhost yin]# service docker start
Redirecting to /bin/systemctl start docker.service