一.Docker入门
- Docker 为什么会出现
2. Docker的历史
3. Docker最新超详细版教程通俗易懂
Docker是基于Go语言开发的!开源项目
官网
官方文档Docker文档是超详细的
仓库地址
4. 虚拟化技术和容器化技术对比
4.1. 虚拟化技术的缺点
资源占用十分多
冗余步骤多
启动很慢
2.2. 容器化技术
比较Docker和虚拟化技术的不同
传统虚拟机, 虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内部,容器是没有自己的内核的,也没有虚拟硬件,所以轻便
每个容器间是相互隔离的,每个容器内都有一个属于自己的文件系统,互不影响
应用更快速的交互和部署
传统:一堆帮助文档,安装程序
Docker: 打包镜像发布测试,一键运行
更便捷的升级和扩缩容
更简的系统运维
更高效的计算资源利用
4.3. DevOps
4. 名词解释
5. 镜像(image)
Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像 ===> run ===> tomcat01容器, 通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container)
Docker利用容器技术,独立运行一个或者一组应用, 通过镜像来创建的
启动,停止,删除,基本命令!
就目前可以把这个容器理解为一个建议的linux系统
仓库(repository)
存放镜像的地方
Docker Hub(默认是国外的)
腾讯云,都有容器服务(配置镜像加速!)
4. 腾讯云镜像加速
登录腾讯云服务器,找到容器镜像服务
设置Registry登录密码
找到镜像加速器
配置使用
sudo systemctl daemon-reload
sudo systemctl restart docker
4.2 安装docker
卸载旧版本
较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装 Docker Engine-Community
使用 Docker 仓库进行安装
在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。之后,您可以从仓库安装和更新 Docker。
设置仓库
安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
使用以下命令来设置稳定的仓库。
使用官方源地址(比较慢)
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
可以选择国内的一些源地址:
腾讯云
$ sudo yum-config-manager \
--add-repo \
http://mirrors.tengxun.com/docker-ce/linux/centos/docker-ce.repo
清华大学源
$ sudo yum-config-manager \
--add-repo \
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
安装 Docker Engine-Community
安装最新版本的 Docker Engine-Community 和 containerd,或者转到下一步安装特定版本:
$ sudo yum install docker-ce docker-ce-cli containerd.io
Docker 安装完默认未启动。并且已经创建好 docker 用户组,但该用户组下没有用户。
要安装特定版本的 Docker Engine-Community,请在存储库中列出可用版本,然后选择并安装:
1、列出并排序您存储库中可用的版本。此示例按版本号(从高到低)对结果进行排序。
```bash
$ yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
``
2、通过其完整的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce)加上版本字符串(第二列),从第一个冒号(:)一直到第一个连字符,并用连字符(-)分隔。例如:docker-ce-18.09.1。
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
启动 Docker。
$ sudo systemctl start docker
通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community 。
$ sudo docker run hello-world
- 底层原理
HelloWorld镜像
底层原理
Docker Engine是一个客户端-服务器应用程序,具有以下主要组件:
一个服务器,它是一种长期运行的程序,称为守护进程(dockerd命令)
一个REST API,它指定程序可以用来与守护进程对话并指示它做什么的接口。
Docker是一个Client Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户 端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境就是我们所说的集装箱。
为什么Docker比Vm快
docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。
二,Docker基本命令
- Docker的常用命令
帮助命令
docker version # docker版本信息
docker info # 系统级别的信息,包括镜像和容器的数量
docker 命令 --help
镜像命令
powershell
docker images 查看所有本地主机上的镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 7 months ago 13.3kB
解释
REPOSITORY # 镜像的仓库
TAG # 镜像的标签
IMAGE ID # 镜像的ID
CREATED # 镜像的创建时间
SIZE # 镜像的大小
可选项
--all , -a # 列出所有镜像
--quiet , -q # 只显示镜像的id
docker search 查找镜像
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]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 719 [OK]
可选项
--filter=STARS=3000 # 搜素出来的镜像就是STARS大于3000的
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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]
docker pull 下拉镜像
# 下载镜像,docker pull 镜像名[:tag]
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载,dockerimages的核心,联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
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
# 指定版本下载
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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 删除镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID # 删除指定镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID1 IMAGE ID2 IMAGE ID3 # 删除多个镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f $(docker images -aq) # 删除所有镜像
容器命令
说明: 我们有了镜像才可创建容器,linux,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
参数说明
--name=“Name” 容器名字 tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p 随机指定端口
测试,启动并进入容器
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -it centos /bin/bash
[root@74e82b7980e7 /]# ls # 查看容器内的centos,基础版本,很多命令是不完善的
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
从容器中退回主机
[root@77969f5dcbf9 /]# exit
exit
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# ls
bin dev fanfan lib lost+found mnt proc run srv tmp var
boot etc home lib64 media opt root sbin sys usr
列出所有的运行的容器
docker ps 命令
# 列出当前正在运行的容器
-a # 列出正在运行的容器包括历史容器
-n=? # 显示最近创建的容器
-q # 只显示当前容器的编号
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77969f5dcbf9 centos "/bin/bash" 5 minutes ago Exited (0) 5 minutes ago xenodochial_bose
74e82b7980e7 centos "/bin/bash" 16 minutes ago Exited (0) 6 minutes ago silly_cori
a57250395804 bf756fb1ae65 "/hello" 7 hours ago Exited (0) 7 hours ago elated_nash
392d674f4f18 bf756fb1ae65 "/hello" 8 hours ago Exited (0) 8 hours ago distracted_mcnulty
571d1bc0e8e8 bf756fb1ae65 "/hello" 23 hours ago Exited (0) 23 hours ago magical_burnell
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -qa
77969f5dcbf9
74e82b7980e7
a57250395804
392d674f4f18
571d1bc0e8e8
退出容器
exit # 直接退出容器并关闭
Ctrl + P + Q # 容器不关闭退出
删除容器
docker rm -f 容器id # 删除指定容器
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm -f # 删除所有的容器
启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前的容器
常用的其他命令
后台启动容器
# 命令 docker run -d 镜像名
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos
# 问题 docker ps, 发现centos停止了
# 常见的坑, docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx, 容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了
查看日志
docker logs -tf --tail number 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 1 8d1621e09bff
2020-08-11T10:53:15.987702897Z [root@8d1621e09bff /]# exit # 日志输出
# 自己编写一段shell脚本
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done"
a0d580a21251da97bc050763cf2d5692a455c228fa2a711c3609872008e654c2
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0d580a21251 centos "/bin/sh -c 'while t…" 3 seconds ago Up 1 second lucid_black
# 显示日志
-tf # 显示日志
--tail number # 显示日志条数
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 10 a0d580a21251
查看容器中进程信息ps
# 命令 docker top 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker top df358bc06b17
UID PID PPID C STIME TTY
root 28498 28482 0 19:38 ?
查看镜像的元数据
命令
docker inspect 容器id
[root@VM-24-4-centos /]# docker inspect e3f93a03b35d
[
{
"Id": "e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b",
"Created": "2022-11-20T09:45:00.188586759Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo xuyuan;sleep 1;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 14374,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-11-20T09:45:00.454673816Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b/hostname",
"HostsPath": "/var/lib/docker/containers/e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b/hosts",
"LogPath": "/var/lib/docker/containers/e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b/e3f93a03b35d2d728e90ffd096f38a88369f2df8ad79699d73b4b19c10291b0b-json.log",
"Name": "/competent_tesla",
"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,
"CgroupnsMode": "host",
"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/d55e33e1669cc062b8a1596b2ca3bfa76705d9c93520c128d02684ae9ac5fb89-init/diff:/var/lib/docker/overlay2/ed40f91257ac6d0fc26c89c1c7b88956063a098627eec9c48ac7bc62dbf840ec/diff",
"MergedDir": "/var/lib/docker/overlay2/d55e33e1669cc062b8a1596b2ca3bfa76705d9c93520c128d02684ae9ac5fb89/merged",
"UpperDir": "/var/lib/docker/overlay2/d55e33e1669cc062b8a1596b2ca3bfa76705d9c93520c128d02684ae9ac5fb89/diff",
"WorkDir": "/var/lib/docker/overlay2/d55e33e1669cc062b8a1596b2ca3bfa76705d9c93520c128d02684ae9ac5fb89/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "e3f93a03b35d",
"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 xuyuan;sleep 1;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"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": "1cdb2195311a3ad48ac8ee0e2825836b72e93140cfc63957a85cc5339e908699",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/1cdb2195311a",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "426e027d8803162b9ae58ef598fdf9d5e08b3a496304390b03867d7ba742e794",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "8792ef09f70fffcf023681744b2948d9a03baf1806b0dd14a5e3b75bac11db8a",
"EndpointID": "426e027d8803162b9ae58ef598fdf9d5e08b3a496304390b03867d7ba742e794",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
进入当前正在运行的容器
# 我们通常容器使用后台方式运行的, 需要进入容器,修改一些配置
# 命令
docker exec -it 容器id /bin/bash
# 测试
[root@VM-24-4-centos /]# docker exec -it e3f93a03b35d /bin/bash
[root@e3f93a03b35d /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@e3f93a03b35d /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:44 ? 00:00:01 /bin/sh -c while true;do echo xuyuan;sleep 1;done
root 3369 0 0 10:41 pts/0 00:00:00 /bin/bash
root 3401 1 0 10:41 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bi
root 3402 3369 0 10:41 pts/0 00:00:00 ps -ef
# 方式二
docker attach 容器id
# docker exec # 进入容器后开启一个新的终端,可以在里面操作
# docker attach # 进入容器正在执行的终端,不会启动新的进程
从容器中拷贝文件到主机
docker cp 容器id:容器内路径 目的地主机路径
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker cp 7af535f807e0:/home/Test.java /home
[root@VM-24-4-centos /]# cd /home
[root@VM-24-4-centos home]# ls
lighthouse
[root@VM-24-4-centos home]# touch xuyuan.java
[root@VM-24-4-centos home]# ls
lighthouse xuyuan.java
[root@VM-24-4-centos home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9180714a93c centos "/bin/bash" About a minute ago Up About a minute heuristic_keldysh
进入docker容器内部
[root@VM-24-4-centos home]# docker attach e9180714a93c
[root@e9180714a93c /]# cd /home
[root@e9180714a93c home]# ls\
[root@e9180714a93c home]# ls
在容器内新建文件
[root@e9180714a93c home]# touch test.java
[root@e9180714a93c home]# exit
exit
[root@VM-24-4-centos home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@VM-24-4-centos home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9180714a93c centos "/bin/bash" 3 minutes ago Exited (0) 15 seconds ago heuristic_keldysh
拷贝出来
[root@VM-24-4-centos home]# docker cp e9180714a93c:/home/test.java /home
[root@VM-24-4-centos home]# ls
lighthouse test.java xuyuan.java
命令大全
attach Attach local standard input, output, and error streams to a running container
#当前shell下 attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container's changes #提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem #拷贝文件
create Create a new container #创建一个新的容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
events Get real time events from the server # 从服务获取容器实时时间
exec Run a command in a running container # 在运行中的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images #列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
info Display system-wide information # 显示全系统信息
inspect Return low-level information on Docker objects #查看容器详细信息
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
三,Docker部署软件实战
1.Docker部署软件实战
Docker安装Nginx
1. 搜索镜像 search 建议去docker hub搜索,可以看到帮助文档
2. 下载镜像 pull
[root@VM-24-4-centos /]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a603fa5e3b41: Pull complete
c39e1cda007e: Pull complete
90cfefba34d7: Pull complete
a38226fb7aba: Pull complete
62583498bae6: Pull complete
9802a2cfdb8d: Pull complete
Digest: sha256:e209ac2f37c70c1e0e9873a5f7231e91dcd83fdf1178d8ed36c2ec09974210ba
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
3. 运行测试
[root@VM-24-4-centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 88736fe82739 5 days ago 142MB
centos latest 5d0da3dc9764 14 months ago 231MB
-d 后台运行
-name 给容器命名
-p 宿主机端口:容器内部端口
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d --name nginx01 -p 3344:80 nginx # 后台方式启动启动镜像
fe9dc33a83294b1b240b1ebb0db9cb16bda880737db2c8a5c0a512fc819850e0
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe9dc33a8329 nginx "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 0.0.0.0:3344->80/tcp nginx01
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# curl localhost:3344 # 本地访问测试
进入容器
[root@VM-24-4-centos etc]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98b75ce8bebe nginx "/docker-entrypoint.…" 37 minutes ago Up 37 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@VM-24-4-centos etc]# docker exec -it nginx01 /bin/bash
root@98b75ce8bebe:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@98b75ce8bebe:/# cd /etc/nginx
root@98b75ce8bebe:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
root@98b75ce8bebe:/etc/nginx#
启动容器:
端口暴露概念
- Docker安装Tomcat
3. # 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台的,停止了容器之后, 容器还是可以查到,docker run -it --rm 一般用来测试,用完就删
# 下载再启动
docker pull tomcat
# 启动运行
docker run -d -p 3344:8080 --name tomcat01 tomcat
# 测试访问没有问题
![在这里插入图片描述](https://img-blog.csdnimg.cn/d7dae0772cab4dcf8be2bfe8600fbb04.png)
外网404
# 进入容器
docker exec -it tomcat01 /bin/bash
# 发现问题:1.linux命令少了, 2. webapps下内容为空,腾讯云净吸纳过默认是最小的镜像,所有不必要的都剔除了,保证最小可运行环境即可
- Docker部署es + kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录! 挂载
# --net somenetwork 网络配置
# 启动elasticsearch
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
# 启动了linux就卡主了,docker stats 查看cpu状态
# 测试一下es成功了
[root@VM-24-4-centos /]# curl localhost:9200
{
"name" : "4b4520c63270",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "RwAYLlg7R22xWNvnU0nfjQ",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
# 增加内存限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
可视化
portainer(先用这个)
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 测试
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# curl localhost:8088
外网访问 http://ip:8088
Rancher(CI/CD再用)
四.Docker原理
特点
Docker奖项都是只读的,当容器启动时, 一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层, 容器之下的都叫做镜像层
commit镜像
docker commit 提交容器成为一个新的版本
# 命令和git 原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="xuyuan" -m="add webapps app" 0b63915fc75d tomcat02:1.0
实战测试:
# 1. 启动一个默认的tomcat
# 2. 发现这个默认的tomcat是没有webapps应用, 镜像的原因,官方镜像默认webapps下面是没有内容的
# 3. 我自己拷贝进去了基本的文件
# 4. 将我们操作过的容器通过commit提价为一个镜镜像!我们以后就使用我们自己制作的镜像了
五,容器数据卷
- 容器数据卷
1.1. docker的理解回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享技术!Docker容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录挂载到linux目录上面!
1.2. 使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -it -v /home/ceshi:/home centos /bin/bash
测试文件的同步(在主机上改动,观察容器变化)
再来测试(测试通过)
停止容器
主机上修改文件
启动容器
容器内的数据依旧是同步的!
1.3. 实战:安装MySQL
思考:MySQL的数据持久化的问题!
获取镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker pull mysql:5.7
# 运行容器, 需要做数据挂载! # 安装启动mysql,需要配置密码(注意)
# 官方测试, docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d # 后台运行
-p # 端口隐射
-v # 卷挂载
-e # 环境配置
--name # 容器的名字
[root@VM-24-4-centos home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
b3444df1e067dc125ad8928c6ad600d6a9d99601bec4e122bae667ec53ad9c26
# 启动成功之后,我们在本地使用navicat链接测试一下
# navicat链接到服务器的3344 --- 3344 和 容器的3306映射,这个时候我们就可以连接上mysql喽!
# 在本地测试创建一个数据库,查看下我们的路径是否ok!
1.4. 匿名和具名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx # -P 随机指定端口
# 查看所有volume的情况
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker volume ls
DRIVER VOLUME NAME
local DRIVER VOLUME NAME
local f83b746d8b6ad6b117abd1db1b87124d2d5784fffefe4a59927f5519cf6492c0
local fecdc81070a256d888459aa28c3538eb98b19580d70d27dfd8e81235cf859e69
[root@VM-24-4-centos /]#
# 这里发现,这种情况就是匿名挂载,我们在-v 后面只写了容器内的路径,没有写容器外的路径!
# 具名挂载
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name nginx09 -v juming-nginx:/etc/nginx nginx
26da1ec7d4994c76e80134d24d82403a254a4e1d84ec65d5f286000105c3da17
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
94421e9c72d3 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:49154->80/tcp, :::49154->80/tcp nginx09
f77206b2489b nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx04
b3444df1e067 mysql:5.7 "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp mysql01
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker volume ls
DRIVER VOLUME NAME
local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096
local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882
local juming-nginx
# 通过-v 卷名:容器内的路径
# 查看一下这个卷
# docker volume inspect juming-nginx
[root@VM-24-4-centos /]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-11-22T02:58:52+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /主机路径:容器内路径 # 指定路径挂载
拓展
# 通过 -v 容器内容路径 ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内容无法操作
六,DockerFile
初始DockerFile
DockerFile就是用来狗之间docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
# 创建一个dockerfile文件, 名字可以随机
# 文件的内容 指定(大写) 参数
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "----end----"
CMD /bin/bash
# 这里的每一个命令都是镜像的一层!
启动自己的容器
docker inspect 容器id
测试一下刚才的文件是否同步到主机上了!
这种方式我们未来使用的十分多, 因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
多个mysql同步数据!
启动3个容器,通过我们刚才自己写的镜像启动
挂载在父容器上
多个mysql实现数据共享
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
[root@iZ2zeg4ytp0whqtmxbsqiiZ home]# docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
结论:
容器之间配置信息的传递, 数据卷容器的声明周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
删除docker01 docker02 03 依旧在 达到了数据持久性 测试依旧可以访问
DockerFile
dockerFile是用来构建docker镜像的文件!命令参数脚本!
构建步骤
1. 编写一个dockerFile文件
2.docker build 构建成为一个镜像
3. docker run 运行镜像
4. docker push 发布镜像(DockerHub、阿里云镜像)
查看官方是怎么做的?
很多官方镜像都像是基础包,很多功能都不具备,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,能我们一样可以!
DockerFile的构建过程
基础知识:
每个保留关键字(指令)都是必须大写字母
执行从上到下顺序执行
表示注释
每个指令都会创建提交一个新的镜像层,并提交!
dockerFile是面向开发的, 我们以后要发布项目, 做镜像, 就需要编写dockefile文件, 这个文件十分简单!
Docker镜像逐渐成为企业的交互标准,必须要掌握!
步骤:开发,部署, 运维… 缺一不可!
DockerFile: 构建文件, 定义了一切的步骤,源代码
DockerImages: 通过DockerFile构建生成的镜像, 最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务器
DockerFile指令说明
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤, tomcat镜像, 这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY # 类似ADD, 将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量! es里边用过
创建一个自己的centos
# 1. 编写Dockerfile的文件
[root@VM-24-4-centos dockerfile]# cat mydockerfile-centos-xuyuan
FROM centos
MAINTAINER xuyuan<826463302@qq.com>
ENV MYPATH /user/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
# 2. 通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
docker build -f mydockerfile-centos-xuyuan -t mycentos:0.1 .
Successfully built 605b2ddc4b8d
Successfully tagged mycentos:0.1
我们可以列出本地进行的变更历史
CMD 和ENTRYPOINT区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
# 1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-cmd-test
FROM centos
CMD ["ls", "-a"]
# 2. 构建镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
# 3. run运行, 发现我们的ls -a 命令生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
# 想追加一个命令 -l 变成 ls -al
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 -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.
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 ls -l
# cmd的情况下 -l替换了CMD["ls", "-a"]命令, -l不是命令,所以报错了
测试ENTRYPOINT
1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls", "-a"]
# 2. 构建文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
# 3. run运行 发现我们的ls -a 命令同样生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
# 4. 我们的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test -l
total 56
drwxr-xr-x 1 root root 4096 Aug 13 07:52 .
drwxr-xr-x 1 root root 4096 Aug 13 07:52 ..
-rwxr-xr-x 1 root root 0 Aug 13 07:52 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 13 07:52 dev
drwxr-xr-x 1 root root 4096 Aug 13 07:52 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Aug 9 21:40 lost+found
七,Dockerfile制作tomcat镜像
Dockerfile制作tomcat镜像
准备镜像文件 tomcat压缩包,jdk的压缩包!
编写Dockerfile文件,官方命名Dockerfile, build会自动寻找这个文件,就不需要-f指定了!
FROM centos:7
MAINTAINER xuyuan<826463302@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u221-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.69.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_221
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/toos.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.69
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.69
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.69/startup.sh && tail -F /usr/local/apache-tomcat-9.0.69/bin/logs/catalina.out
构建镜像
# docker build -t diytomcat .
启动镜像
docker run -d -p 3344:8080 --name xuyauntomcat1 -v /home/xuyuan/build/tomcat/test:/usr/local/apache-tomcat-9.0.69/webapps/test -v /home/xuyuan/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.69/logs diytomcat
挂在成功
访问测试
发布项目(由于做了卷挂载, 我们直接在本地编写项目就可以发布了)
在本地编写web.xml和index.jsp进行测试
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello. xiaofan</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs------");
%>
</body>
</html>
发现:项目部署成功, 可以直接访问ok!
我们以后开发的步骤:需要掌握Dockerfile的编写! 我们之后的一切都是使用docker进行来发布运行的!
Docker Hub