“ 弱小和无知不是生存的障碍,傲慢才是 ”。
学习方式:先理解概念,但是一定要实践,最后实践和理论相结合一次搞定这个知识!1> 多数人以为下属文章内容已经算是熟悉docker,已经能部署服务,启动Docker,这叫真正的用吗?这不算,我告诉你这只能算得上是Docker入门。
2> 玩会 “容器数据卷”、“DockerFile”、“Docker 网络” 才算玩会Docker,这三个是Docker的精髓,但还算不上玩转DOcker。
3> 企业实战,这才是真正的去玩转Docker,不是说你会用就完了。
本文pdf链接:
链接:https://pan.baidu.com/s/1KcQLtoJa8YBYpz-Kl8ekXA
提取码:MZXY
一款产品:开发–上线 两套环境!应用环境,应用配置!
开发 ------ 运维, 问题:我在我的电脑上可以运行! 版本更新,导致服务不可用! 对于运维考验就十分大!
环境配置是十分麻烦的,每一个机器都要部署环境!(费时费力)
发布一个项目(MySQL,Nginx,Apache,Zabbix…),项目能不能带上环境安装打包。
之前在服务器配置应用的环境,MySQL,Nginx等,配置错了就麻烦了,不能跨平台。
Window,最后发布到Linux!
传统:开发丢包,运维来部署。现在:开发打包部署上线,一套流程做完!
开发–环境—打包(带上环境)–镜像(放在DocKer仓库中类似商店)----运维 下载发布的镜像—直接运行就OK。
Docker 的思想就来自于集装箱!
多个应用(端冲突)—原来都是交叉的!
核心思想:隔离! 打包装箱! 每个箱子是相互隔离的。 比如:一个装水果,一个装武器
如果放在一起,一个坏了可能影响另一个,现在镜像隔离,一个坏了不影响另一个
还有一个好处:将Linux服务器压榨到极致,DOcKer通过隔离机制,将服务器应用到极致。
本质:所有的技术都是因为出现了一些问题,我们需要解决,才去学习的。
2010年,几个高it的年轻人,就在美国成立了一家公司 dotCloud
做一些 pass的云计算服务! LXC 有关的容器技术。
他们将自己的容器化技术,命名就是DocKer !
DocKer 刚刚诞生的时候没有引起行业的注意!dotCloud,就活不下去!
开源:开放源代码!(好比最开始的阿里)
2013 年,DOcker 开源!
Docker 越来越多的人发现了Docker的优点!火了,DocKer 每个月更新一个版本!
2014 年 4 月9 日,Docker 1.0 发布!
DocKer为什么这么火? 十分轻巧
在容器技术出来之前,我们都是使用虚拟机技术!(VMwear)
虚拟机:在windos中装一个虚拟机软件Vmware,通过这个软件我们就可以虚拟出来一台或者多台电脑!笨重!
虚拟机也是属于虚拟化技术,DocKer容器技术,也就是一种虚拟化技术!
vm - linux centos 原生镜像(一个电脑) 隔离,需要开启多个虚拟机( 几个G装一个虚拟机)启动几分钟!
DocKer - 隔离,镜像(最核心的环境 4m)+ MysQl 等, 十分的小巧,运行镜像就可以了 (几兆,最小甚至kb)启动秒级!
到现在所以开发人员都要会DocKer!!
DocKer 是基于Go语言开发的!开源项目!
官网:https://www.docker.com/
文档地址:https://docs.docker.com/ Docker的文档是超级详细的!
仓库地址:https://hub.docker.com/
虚拟化技术:
比较Docker和虚拟机技术的不同:
DevOps(开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样!
项目打包成一个镜像(扩展 服务器A! 服务器B 一键运行扩展)
更简单的系统运维
在容器化之后,开发的测试环境都是高度一致的。
更高效的计算资源利用:
DocKer 是 内核级别的虚拟化,可以在一个物理机上运行很多的容器实例! 服务器的性能可以被压榨到极致。
镜像(image):
Docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat 镜像 ==> run ==> romcat01(提供服务),通过这个镜像可以擦黄金多个容器(最终服务运行或者项目运行就是在容器中)。
容器(container):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。
启动,停止,排除,基本命令。
目前就可以把这个容器理解为一个简易的Linux系统。
仓库(repostory):
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库!
DocKer Hub(默认是国外的)
阿里云…都有容器服务器(配置模板加速!)
环境准备
1、需要会Linux基础
2、CentOS 7
3、Xshell远程连接服务器进行操作!
环境查看
1.系统内核
[root@localhost ~]# uname -r
3.10.0-957.el7.x86_642.系统版本
[root@node1 ~]#
[root@node1 ~]# 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”
安装
帮助文档:https://docs.docker.com/engine/install/centos/
卸载旧的版本
$ sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
需要的安装包(yum-utils)
$ sudo yum install -y yum-utils
设置镜像仓库(默认国外的,十分慢)
$ sudo yum-config-manager
–add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
网址:https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.6ee51b11Xt190G
docker-ce 社区版
安装Docker相关的内容
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io
启动 Docker
systemctl start docker
docker version
测试hello word
docker run hello-world
查看 下载的 hello world 镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 10 months ago 13.3kB
卸载Docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“https://77n2hz2x.mirror.aliyuncs.com”]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart
docker回顾hello word 流程
Docker 是一个 client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
DockerServer 接收到Docker-Client 的指令,就会执行这个命令!
1、Docker 有着比虚拟机更少的抽象层。
2、Docker 利用的是宿主机的内核,vm需要是Guest OS.
所以说新建一个容器的时候,Docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导,虚拟机是加载Guest OS,分钟级别的,而Docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。
docker --help 帮助
docker version 版本
docker info 显示Docker详细信息(系统信息、容器数量)
帮助文档的地址:
/ # docker images 查看所有本地的主机上的镜像
[root@node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 10 months ago 13.3kBREPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小可选项:
Options:
-a, --all 列出所有的镜像
-q, --quiet 只显示镜像的ID
网页版搜索 —— 网站:https://hub.docker.com/
搜索命令:# docker search mysql
[root@node1 ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10134 [OK]
搜索出镜像STARS>3000
[root@node1 ~]# docker search mysql --filter=stars=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10134 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3730 [OK]
下载:docker pull 镜像名[:tag] 可以加版本,否则默认最新版
[root@node1 ~]# docker pull mysql
Using default tag: latest // 不写tag默认latest
latest: Pulling from library/mysql
bb79b6b2107f: Pull complete // 分层下载:docker image的核心,联合文件系统
49e22f6fb9f7: Pull complete
842b1255668c: Pull complete
9f48d1f43000: Pull complete
c693f0615bce: Pull complete
8a621b9dbed2: Pull complete
0807d32aef13: Pull complete
a56aca0feb17: Pull complete
de9d45fd0f07: Pull complete
1d68a49161cc: Pull complete
d16d318b774e: Pull complete
49e112c55976: Pull complete
Digest: sha256:8c17271df53ee3b843d6e16d46cff13f22c9c04d6982eb15a9a47bd5c9ac7e2d //签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest // 真实地址注:docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
指定版本下载:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZELFFpOE-1604900424123)(%E5%9B%BE%E5%BA%93/Docker/image-20201107095335062.png)][root@node1 ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bb79b6b2107f: Already exists
49e22f6fb9f7: Already exists
842b1255668c: Already exists
9f48d1f43000: Already exists
c693f0615bce: Already exists
8a621b9dbed2: Already exists
0807d32aef13: Already exists // 已经存在,不需要重复下载
f15d42f48bd9: Pull complete
098ceecc0c8d: Pull complete
b6fead9737bc: Pull complete
351d223d3d76: Pull complete // 只需要更新没有的
Digest: sha256:4d2b34e99c14edb99cdd95ddad4d9aa7ea3f2c4405ff0c3509a29dc40bcb10ef
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7删除镜像:docker rmi [-f id / 镜像名]
docker rmi -f bf756fb1ae65
docker rmi mysql
docker rmi mysql:5.7批量删除:docker rmi -f ${docker images -aq}
说明:有了镜像才可以创建容器,Linuk,下载一个Centos镜像来测试。
docker pull centos
新建容器并启动
docker run [可选参数] image
参数说明:
– name=‘name’ 容器名字
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口 (常用)
-p 容器端口
容器端口-P 随机指定端口
列出所有运行的容器
启动并进入容器
[root@node1 /]# docker run -it centos /bin/bash
[root@3d1be77075d4 /]# ls 查看容器内的centos,基础版本,很多命令都是不支持的
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@3d1be77075d4 /]# exit // 退出容器
exit
[root@node1 /]# ls
bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var www查看当前运行的容器:
-a all 列出历世运行过的容器
-n=? 显示最近创建的容器[root@node1 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES查看曾经运行的容器:
[root@node1 /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d1be77075d4 centos “/bin/bash” 4 minutes ago Exited (0) 2 minutes ago elated_driscoll
退出容器
exit 直接容器停止并退出
ctrl+p+q 容器不停止退出
删除容器
douker rm 容器id 删除指定容器——不能删除运行的容器——rm -f 强制删除
docker rm -f ${docker ps -qa} 删除所有的容器
docker ps -a -q | xargs docker rm 删除所有的容器
启动和停止容器的操作
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
后台启动
[root@node1 /]# docker run -d centos
问题 docker ps 发现 centos停止了。常见的坑,docker容器使用后台运行,就必须要有一个前台运行,就会自动停止
nginx,容器启动后,发现自己没有程序服务,就会立刻停止,就是没有程序了
查看日志命令
[root@node1 /]# docker logs -tf --tail 596f32b8c5c1
-tf 显示所有日志,带上时间戳
–tail number 显示日志的条数
查看容器中进程信息
docker top 容器id
[root@node1 /]# docker top 596f32b8c5c1
UID PID PPID C STIME TTY TIME CMD
root 9296 9281 0 10:56 pts/0 00:00:00
查看镜像原数据
docker inspect 容器ID
[root@node1 /]# docker inspect 9aeed2d3fe5a
[
{
“Id”: “9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f”,
“Created”: “2020-11-07T03:13:07.030570945Z”,
“Path”: “/bin/bash”,
“Args”: [],
“State”: {
"Status": “running”,
“Running”: true,
“Paused”: false,
“Restarting”: false,
“OOMKilled”: false,
“Dead”: false,
“Pid”: 10807,
“ExitCode”: 0,
“Error”: “”,
“StartedAt”: “2020-11-07T03:13:07.309774647Z”,
“FinishedAt”: “0001-01-01T00:00:00Z”
},
“Image”: “sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566”,
“ResolvConfPath”: “/var/lib/docker/containers/9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f/resolv.conf”,
“HostnamePath”: “/var/lib/docker/containers/9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f/hostname”,
“HostsPath”: “/var/lib/docker/containers/9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f/hosts”,
“LogPath”: “/var/lib/docker/containers/9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f/9aeed2d3fe5a61b592693343cf7634391f5dd720f5768ef1f565c2ef3bcb0d3f-json.log”,
“Name”: “/zealous_varahamihira”,
“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/dcc65e601678e89c53be19b83e9636ec21f51682af78a0b2fc477ae36eee24ba-init/diff:/var/lib/docker/overlay2/345bc1cb7c251197f100d6ef47902581206b846870266b77d5fac853ba04f9c3/diff”,
“MergedDir”: “/var/lib/docker/overlay2/dcc65e601678e89c53be19b83e9636ec21f51682af78a0b2fc477ae36eee24ba/merged”,
“UpperDir”: “/var/lib/docker/overlay2/dcc65e601678e89c53be19b83e9636ec21f51682af78a0b2fc477ae36eee24ba/diff”,
“WorkDir”: “/var/lib/docker/overlay2/dcc65e601678e89c53be19b83e9636ec21f51682af78a0b2fc477ae36eee24ba/work”
},
“Name”: “overlay2”
},
"Mounts": [],
“Config”: {
"Hostname": “9aeed2d3fe5a”,
“Domainname”: “”,
“User”: “”,
“AttachStdin”: true,
“AttachStdout”: true,
“AttachStderr”: true,
“Tty”: true,
“OpenStdin”: true,
“StdinOnce”: true,
“Env”: [
“PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”
],
“Cmd”: [
“/bin/bash”
],
“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”: “cb83a1f609a65eaa0f1866dac64c92140c291a5ff7dcf3ed2b5079af854cd3e9”,
“HairpinMode”: false,
“LinkLocalIPv6Address”: “”,
“LinkLocalIPv6PrefixLen”: 0,
“Ports”: {},
“SandboxKey”: “/var/run/docker/netns/cb83a1f609a6”,
“SecondaryIPAddresses”: null,
“SecondaryIPv6Addresses”: null,
“EndpointID”: “23ae0b7b1fea254e7bf9b99c7687904bf5476da02cc787cffd7768f24f553034”,
“Gateway”: “172.17.0.1”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“IPAddress”: “172.17.0.4”,
“IPPrefixLen”: 16,
“IPv6Gateway”: “”,
“MacAddress”: “02:42:ac:11:00:04”,
“Networks”: {
“bridge”: {
“IPAMConfig”: null,
“Links”: null,
“Aliases”: null,
“NetworkID”: “5e7053223ddfa7f6643c4d4f65a129584f16ef63c94c94e05eb74acfa126c58d”,
“EndpointID”: “23ae0b7b1fea254e7bf9b99c7687904bf5476da02cc787cffd7768f24f553034”,
“Gateway”: “172.17.0.1”,
“IPAddress”: “172.17.0.4”,
“IPPrefixLen”: 16,
“IPv6Gateway”: “”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“MacAddress”: “02:42:ac:11:00:04”,
“DriverOpts”: null
}
}
}
}
]
进入当前正在运行的容器
我们通常容器是使用后台运行的,需要进入容器,修改一些配置。
1> docker exec -it 容器ID bashShell[root@node1 /]# docker exec -it 9aeed2d3fe5a /bin/bash
[root@9aeed2d3fe5a /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:13 pts/0 00:00:00 /bin/bash
root 14 0 0 03:26 pts/1 00:00:00 /bin/bash
root 29 14 0 03:27 pts/1 00:00:00 ps -ef2> docker attach 容器id
[root@node1 /]# docker attach 9aeed2d3fe5a
[root@9aeed2d3fe5a /]#两种方式的区别:
1> exec 进入容器后开启一个新的终端
2>attach 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机
命令:docker cp 容器id:容器内路径 目的主机路径
[root@node1 /]# docker exec -it 93b13bd5d8fa /bin/bash
[root@93b13bd5d8fa /]# touch /home/test.conf
[root@93b13bd5d8fa /]# exit
[root@node1 /]# docker cp 93b13bd5d8fa:/home/test.conf /home
[root@node1 /]# ll /home/
total 0
-rw-r–r-- 1 root root 0 Nov 7 11:42 test.conf
小结:
Docker 命令是非常多的!
接下来就是一堆的练习:
Docker 安装 Nginx
步骤:
搜索镜像 search 建议去docker网站搜索,可以看到详细信息
下载镜像 pull
运行测试
注:docker run -d --name nginx01 -p:3344:80 nginx
-d 后台运行
–name 容器命名
-p[root@node1 /]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 13971 [OK] [root@node1 /]# docker pull nginx
Using default tag: latest[root@node1 /]# docker pull nginx
latest: Pulling from library/nginx
bb79b6b2107f: Pull complete
5a9f1c0027a7: Pull complete
b5c20b2b484f: Pull complete
166a2418f7e8: Pull complete
1966ea362d23: Pull complete
Digest: sha256:aeade65e99e5d5e7ce162833636f692354c227ff438556e5f3ed0335b7cc2f1b
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest[root@node1 /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest c39a868aad02 34 hours ago 133MB
centos latest 0d120b6ccaa8 2 months ago 215MB[root@node1 /]# docker run -d --name nginx01 -p:3344:80 nginx
[root@node1 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb5899cc3a4f nginx “/docker-entrypoint.…” 6 seconds ago Up 5 seconds 0.0.0.0:3344->80/tcp nginx01[root@node1 /]# firewall-cmd --permanent --add-port=3344/tcp
[root@node1 /]# firewall-cmd --reload
[root@node1 /]# firewall-cmd --list-all[root@node1 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb5899cc3a4f nginx “/docker-entrypoint.…” 5 minutes ago Up 5 minutes 0.0.0.0:3344->80/tcp nginx01
83040b9b35d9 centos “/bin/bash” 59 minutes ago Up 59 minutes brave_pare
93b13bd5d8fa centos “/bin/bash” About an hour ago Up About an hour lucid_pare
[root@node1 /]# curl localhost:3344
测试通过:进入容器[root@node1 ~]# docker exec -it nginx01 /bin/bash
root@eb5899cc3a4f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
思考问题:我们每次该动nginx配置文件,都需要进入容器内部,十多麻烦,我们是可以在容器外部提供一个映射路径,达到在容器外修改文件名,容器内就可以自动修改? -v 逻辑卷
Docker 来装一个tomcat
注:tomcat是Web 应用服务器,轻量级,开发和调试JSP 程序的首选
官方的使用:
$ docker run -it --rm tomcat:9.0
之前的启动都是在后台,停止了容器后,容器还可以查到,–rm(用完即删,用于测试)
[root@node1 ~]# docker run -it --rm tomcat:9.0
- 下载启动
- 测试
[root@node1 ~]# docker pull tomcat:9.0
[root@node1 ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
进入容器:
[root@node1 ~]# docker exec -it tomcat01 /bin/bas
发现问题:1.linux命令少了,没有webapps。阿里云镜像的原因,默认是最小的镜像,所以不必要都剔除掉,保证最小可运行的环境!
root@781fb07aea0d:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@781fb07aea0d:/usr/local/tomcat# cp -r webapps.dist/* webapps再思考一个问题:以后要部署项目,每次都要进入容器是不是十分的麻烦?我要是可以在容器外部提供一个映射路径,达到在容器修改文件名,webapps,在外部防止项目,自动同步到内部就好了!
docker 容器 tomact+网站 docker mysql,删容易跑路?这个显然不科学,删数据库跑路还*
部署es + kinana
注:
1> es 暴露端口多、十分耗内存、数据一般需要放置到安全目录。
2> kibana工具是提供了一个可视化的界面,es:高扩展、开源的全文检索和分析引擎。官方:docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” elasticsearch:7.9.3
启动:Elasticsearch es十分耗内存
查看: docker stats (服务器总共2个G,它就占了1G,68.52%的内存)
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f0d3429c35b0 elasticsearch 0.27% 1.23GiB / 1.795GiB 68.52% 1.18kB / 942B 456MB / 1.27MB 49测试一下es是否能够成功
关闭,增加内存的限制
[root@node1 ~]# curl localhost:9200
{
“name” : “f0d3429c35b0”,
“cluster_name” : “docker-cluster”,
“cluster_uuid” : “BRZN9DoIRKGkitQkNa1Wdg”,
“version” : {
“number” : “7.9.3”,
“build_flavor” : “default”,
“build_type” : “docker”,
“build_hash” : “c4138e51121ef06a6404866cddc601906fe5c868”,
“build_date” : “2020-10-16T10:36:16.141335Z”,
“build_snapshot” : false,
“lucene_version” : “8.6.2”,
“minimum_wire_compatibility_version” : “6.8.0”,
“minimum_index_compatibility_version” : “6.0.0-beta1”
},
“tagline” : “You Know, for Search”
}增加内存的限制,修改配置文件 -e 环境配置修改
[root@node1 ~]# docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” -e ES_JAVA_OPTS="-Xms64 -Xmx512m" elasticsearch:7.9.3
[root@node1 ~]# docker stats elasticsearch02
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
fd1d1f553e6b elasticsearch02 201.80% 338MiB / 1.795GiB 18.39% 586B / 0B 46.3MB / 344kB 26
问题:使用Kibana连接es
docker run -d -p 8080:9000
–restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
什么是protainer?
Docker图形化界面管理工具!提供一个后台面板供我们操作!
下载安装
docker run -d -p 8088:9000
–restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer测试:http://156.238.***.***:8088/
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基本运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置。
所有的应用,直接打包docker镜像,就可以直接跑起来!
如何得到镜像内:
UnionFS(联合文件系统)
下载的时候看到一层一层的就是。
UnionFS(联合文件系统):Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union 文件系统是Docker镜像基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker 镜像加载原理
因为Docker镜像是分层的,因此在加载一个镜像的时候,会按照从底层到高层的顺序依次加载该镜像所需要的镜像层。在加载的过程中,如果当前镜像层已经存在,则会跳过当前镜像层。比如:已经下载过MySQL镜像,现在要下载Tomcat镜像,而这两个镜像都需要CentOS镜像层,那么下载Tomcat镜像的时候,就会跳过下载CentOS镜像层。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bpptfs文件系统,在Docker镜像的最底层是bootfs,这一层与我们典型的Linxu/Unix系统是一样的,包含boot加载器和内核,当boot加载完成之后整个内核就都在内存中了,此时内存的使用全已由bootfs转交给内核,此时系统会卸载bootfs。
rootfs(root file syste),在boots之上,包含的就是典型Linux系统中的/dev ,/proc,/bin/etc,等标准目录和文件,rootfs就是各种不同操作系统发行版,比如Ubuntu,Centos等等!
平时我们安装进虚拟机的Centos都是好几个G,为什么Docker才200M?
[root@node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0d120b6ccaa8 2 months ago 215MB
对于一个精简的OS,rootfs可以很小,只需要包含最基础的命令,工具和程序就可以了,因为底层直接用Host的kernel,自己之需要提供rootfs就可以了,由此可见对于不同的Linux发行版,rootfs会有差别,因此不同发行版可以公用bootfs
虚拟机分钟级、容器秒级
分层的镜像
可以去下载一镜像,注意观察下载的日志输出,可以看到的是一层一层的在下载
[root@node1 ~]# docker run --name some-redis -d redis
Unable to find image ‘redis:latest’ locally
latest: Pulling from library/redis
bb79b6b2107f: Already exists
1ed3521a5dcb: Pull complete
5999b99cee8f: Pull complete
dd17877d8f2d: Pull complete
4863b56b12a8: Pull complete
069e700bc397: Pull complete
Digest: sha256:a0494b60a0bc6de161d26dc2d2f9d2f1c5435e86a9e5d48862a161131affa6bd
Status: Downloaded newer image for redis:latest
12ecacff2838f7a0ca055fccba2946c5504d8e07671471ed00567faccd2944de
思考:为什么Docker镜像采用分层的结构?
最大的好处,我觉得莫过于资源共享了!比如好多镜像都从相同的Base镜像构建而成,那么宿主机只需要在上保留一份base镜像,同时内存中也之需要加载一份base镜像,这样就可以为所有容器服务了,二镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect 命令!
…[
},
“RootFS”: {
“Type”: “layers”,
“Layers”: [
“sha256:d0fe97fa8b8cefdffcef1d62b65aba51a6c87b6679628a2b50fc6a7a579f764c”,
“sha256:832f21763c8e6b070314e619ebb9ba62f815580da6d0eaec8a1b080bd01575f7”,
“sha256:223b15010c47044b6bab9611c7a322e8da7660a8268949e18edde9c6e3ea3700”,
“sha256:6a9976a8f40851f45dc8c68a04b130e90522f46bb7e8403c6e7eb4331674f213”,
“sha256:c875a9fc3ec72b140e325e1a1b3b57d299b91811e8288a07c6b788b0d7cba185”,
“sha256:d9364cb75b1a364fbcb97b2f51332fc012ae0321e18c3fd3811f5e5a9f8a2d0e”
]
},
“Metadata”: {
“LastTagTime”: “0001-01-01T00:00:00Z”
}
}
]
理解:
所有Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容的时候,就会在当前镜像层之上,创建新的镜像层。
举一个的例子:加入基于Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python 包,将会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三次层。
在添加额外的镜像同时,镜像始终宝石当前所有镜像的组合,理解这一点非常重要,下图中举了一个很简单的例子,每个镜像层包含三个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前的图中的略有区别,主要目的是便于展示文件。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件、这样就使得文件的更新版本作为一个新镜像层添加到镜像中。Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展开为统一的文件系统。
Linux 上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎又是基于Linux 中对应的文件操作系统或者块设备技术、并且每种存储引擎都有其特有的性能特点。
Docker在Windows 上仅支持windowsfilter 一种存储引擎,该引擎基于NTDS文件系统之上实现了分层和CoW
下图展示了与系统显示相同的三层镜像。所有镜像都堆叠并合并,对外提供统一的视图。
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
如何提交一个自己的镜像
docker commit 提交容器为一个新的副本
命令和git原理相似
docker commit -m=“提交的错误信息” -a=“作者” 容器id 目标镜像名:[TAG]
实战测试:
- 启动一个默认的comcat
- 发现官方没有默认webapps没有文件
- 拷贝进入文件
- 将我们操作过的容器通过commit 提交一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像
[root@docker ~]# docker commit -a"admin123" -m=“add webapps app” 6f1af5dcd8f0 tomcat:1.0
sha256:c88bb83dc1d51588bbe15b73a7c27c33b1ddc1b8decf319f641284d3d95a384e
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 1.0 c88bb83dc1d5 13 seconds ago 653MB
tomcat latest dab3cf97dd54 2 days ago 648MB
在这里插入图片描述
学习方式说明:先理解概念,但是一定要实践,最后实践和理论相结合一次搞定这个知识!
如果你想要保存当前容器的状态, 就可以通过commit来提交,获得一个镜像。
就好比我们以前学习VM的时候。快照
到了这里才算是入门
三体中的一句话:弱小和无知不是生存的障碍,傲慢才是。