Docker 学习笔记
时间:2023-02-15 20:30:00
Docker 学习笔记
学习大纲
-
Docker概述
-
Docker安装
-
Docker命令
-
镜像命令
-
镜像命令
-
操作命令
-
...
-
-
Docker镜像
-
镜像数据卷
-
DockerFile
-
Docker网络原理
-
IDEA整合Docker
-
Docker Compose
-
Docker Swarm
-
CI\CD jenkins
全栈开发程序员优秀的学习心态:
再小的帆,也可以远行!
只要学不死,就去死里学!
呼吸,学习!
拥抱变化,一切不变的只有变化本身!
Docker概述
Docker为什么会出现?
生命周期代理的问题和挑战:
产品:开发上线 多套环境!应用环境,应用配置!
开发... 操作和维护。问题:我可以在电脑上操作!版本更新导致服务器不可用!对于运维来说,考验很大?
环境配置很麻烦,每个环境都要部署环境(集群Redis、ES、Hadood...)费事费力。
发布一个项目(jar (Redis Mysql jdk ES))项目可以带环境一起安装包装吗?
以前的服务器配备了应用环境Redis Mysql jdk ES Hadood 超级麻烦,不能跨平台。
通常在Windows上开发终于到了linux上!
Docker给出解决方案:
传统:开发Jar 运维来做!
现在:开发包装部署在线一套环境,一套流程完成!
jar -> jar -> 发布(应用商店) -> 张三使用apk -> 可使用安装!
java --> jar (环境)-->带环境(镜像)的包装项目->(Docker仓库:店) --> 下载我们发布的镜像 -> 直接运行!
以上就是Docker解决上述问题!
Docker集装箱的思想:
JRE -- 多应用(端口冲突) -- 原来都是交叉的!
隔离:Docker核心思想,包装箱,每个箱子都是相互隔离的。
集装箱思维:水果、生化武器、相互隔离!D
Docker 服务器可以通过镜像机制使用到极致!
本质:随着问题的出现,我们需要找到解决方案才能学习!
Docker的历史
2010年,几个搞IT年轻人在美国成立了公司 dotCloud
做一些pass云计算服务!LXC镜像技术!
他们把自己的技术(镜像技术)命名为Docker
Docker刚出生的时候,并没有引起业界的关注!dotCloud,活不下去!
开源
开放源代码
2013年,Docker开源!
Docker 越来越多的人发现了它的优点!
Docker几乎每个月都更新一个版本!
2014年4月9号,Docker1.0发布!
Docker为什么这么火?
Docker十分轻巧!
在镜像技术出现之前,我们都使用虚拟机技术!
虚拟机:在windows上利用Vmware这个软件虚拟出一台或多台电脑!
虚拟机也属于虚拟技术,Docke容器技术也是一种虚拟技术!
vmware linux centos 原生镜像(一台电脑) 隔离需要多个虚拟机!
Docker 隔离 镜像(核心环境 4m jdk mysql )非常小,操作镜像,小,几个M KB 秒级启动!
到目前为止,所有开发人员都必须具备技术!
聊聊Docker
Docker是基于Go语言编写!开源项目!
-
官网:https://www.docker.com
-
文档: https://docs.docker.com
-
仓库地址:https://hub.docker.com
Docker能干嘛
以前的虚拟机技术
虚拟机技术缺点:
-
资源占用很多!
-
冗余步骤多!
-
启动很慢!
比较Docker和虚拟机技术的不同:
-
传统的虚拟机,虚拟一套硬件,操作一个完整的操作系统,然后安装和操作软件
-
镜像中的应用程序直接运行在宿主机的核心。镜像没有自己的核心或虚拟硬件,所以它很轻
-
每个镜像都是相互隔离的,每个镜像都有自己的文件系统,不相互影响。
DevOps(开发、运维)
应用更快的交付和部署
传统:一堆安装文件,安装程序
Docker:包装镜像发布测试,一键操作
升级和扩展更方便
使用Docker之后,我们部署的应用就像积木一样
项目包装镜像,扩展服务器A!服务器B
系统运维更简单
镜像化后,我们的开发、测试和生产环境是一致的。
利用更有效的计算资源
Docker它是内核级别的虚拟化,可以在物理机器上运行多个镜像实例!服务器的性能可以压到极致。
只要学不死,就去死里学!
Docker安装
Docker的基本组成
镜像(Image):
docker镜像就像一个可以用这个模板创建镜像的模板。tomcat镜像==>run ==>tomcat01容器(提供服务器)
镜像(container):
Docker利用镜像技术,独立运行一组或一组应用程序。
启动,停止,删除,基本命令
目前,镜像可以理解为简单linux系统
仓库(repository):
仓库是存放镜像的地方!
仓库分为共有仓库和私有仓库!
Docker Hub (国外仓库默认)
阿里云……都有镜像服务器(配置镜像加速)
安装Docker
环境准备:
-
需要一点linux的基础
-
Centos7以上
-
我们使用xshell来连接远程服务器进行操作练习
环境查看
#系统内核为3.10以上内核即可 [root@iZwz9j1nogjvor6cio432eZ ~]# uname -r 4.18.0-147.5.1.el8_1.x86_64
#系统版本 [root@iZwz9j1nogjvor6cio432eZ ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="8 (Cre)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"
安装
官方帮助文档
https://docs.docker.com/
#1、卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2、需要的安装包
yum install -y yum-utils
#3、设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默认国外镜像,国内不推荐用
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推荐使用阿里云的镜像,国内十分快速
#更新yum软件包索引
#yum makecache fast
#centos8以后没有fast参数
yum makecache
#4、安装docker相关的引擎 docker-ce 社区 ee 企业版本
#默认安装最新版本
yum install docker-ce docker-ce-cli containerd.io
#指定版本
##列出在本地仓库可用的版本:
yum list docker-ce --showduplicates | sort -r
#docker-ce.x86_64 18.03.1.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 18.03.0.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.12.1.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.12.0.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.09.1.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.09.0.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.06.2.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.06.1.ce-1.el7.centos docker-ce-stable
#docker-ce.x86_64 17.06.0.ce-1.el7.centos docker-ce-stable
##安装指定版本:
yum install docker-ce- docker-ce-cli- containerd.io
例子:
yum install docker-ce-18.03.1 docker-ce-cli-18.03.1 containerd.io
#Installed:
# docker-ce-3:20.10.2-3.el7.x86_64 docker-ce-cli-1:20.10.2-3.el7.x86_64 docker-ce-rootless-extras-20.10.2-3.el7.x86_64
# fuse-overlayfs-1.1.2-3.module_el8.3.0+507+aa0970ae.x86_64 fuse3-libs-3.2.1-12.el8.x86_64 libcgroup-0.41-19.el8.x86_64
# libslirp-4.3.1-1.module_el8.3.0+475+c50ce30b.x86_64 slirp4netns-1.1.4-2.module_el8.3.0+475+c50ce30b.x86_64
#
#Complete!
#5、启动Docker
systemctl start docker
#6、使用docker -version 测试是否按照成功!
#7、hello-word
docker run hello-world
#8、查看一下下载的这个hello-world 镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 12 months ago 13.3kB
卸载Docker
#1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
rm -rf /var/lib/docker
# /var/lib/docker docker的默认工作目录
阿里云镜像加速
1、登录阿里云找到镜像服务
2、找到镜像加速器
3、配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://gcp5abpr.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
回顾HelloWorld
底层原理
Dockers是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
Docker Server 接收到Docker-Client的指令,就会执行这个命令!
Docker为什么比VM快?
1、Docker有比虚拟机更少是抽象层。
2、docker利用的是宿主的内核,vm需要的是Guest OS.
所以说,新建一个镜像的时候,docker不需要像虚拟机一样从新加载一个虚拟机的内核,避免了引导,虚拟机是加载Guset OS,分钟级别而Docker是利用宿主机的操作系统,省略了这个过程,秒级启动!
之后学习完毕所有命令,再回头过来看下这段
Docker的常用命令
帮助命令
docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和镜像的数量
docker 命令 --help #帮助命令 万能
帮助文档地址:https://docs.docker.com/engine/reference/commandline/
镜像命令
docker images 查看所有本地主机上的镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 12 months ago 13.3kB
#解释
REPOSITORY #镜像的仓库
TAG #镜像的标签
CREATED #镜像的创建时间
SIZE #镜像的大小
#可选项
-a --all #列出所有的镜像
-q ---quiet #只显示镜像的ID
docker search 搜索镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10380 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3848 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 758 [OK]
percona Percona Server is a fork of the MySQL relati… 519 [OK]
#可选项,通过搜索来过滤
--filter=STARS=3000 #搜索出的镜像就是STARS大于3000的
[root@iZwz9j1nogjvor6cio432eZ ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10380 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3848 [OK]
docker pull 下载镜像
#下载镜像docker pull 镜像名[:tag]
[root@iZwz9j1nogjvor6cio432eZ ~]# docker pull mysql
Using default tag: latest #如果不写明tag 默认就会下载最新版本
latest: Pulling from library/mysql
a076a628af6f: Pull complete #分层下载,docker iamges 的核心 联合文件系统
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1a8c919e89bf: Pull complete
9f3cf4bd1a07: Pull complete
80539cea118d: Pull complete
201b3cad54ce: Pull complete
944ba37e1c06: Pull complete
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c #签名
Status: Downloaded newer image for mysql:latest
[root@iZwz9j1nogjvor6cio432eZ ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
a076a628af6f: Pull complete
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1a8c919e89bf: Pull complete
9f3cf4bd1a07: Pull complete
80539cea118d: Pull complete
201b3cad54ce: Pull complete
944ba37e1c06: Pull complete
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
#真实地址
docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
#指定版本下载
[root@iZwz9j1nogjvor6cio432eZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
a076a628af6f: Already exists
f6c208f3f991: Already exists
88a9455a9165: Already exists
406c9b8427c6: Already exists
7c88599c0b25: Already exists
25b5c6debdaf: Already exists
43a5816f1617: Already exists
1831ac1245f4: Pull complete
37677b8c1f79: Pull complete
27e4ac3b0f6e: Pull complete
7227baa8c445: Pull complete
Digest: sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808df
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker rmi -f a70d36bc331a #删除指定的镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker rmi -f 镜像id1 镜像id2 镜像id3 #删除多个镜像
[root@iZwz9j1nogjvor6cio432eZ ~]# docker rmi -f $(docker images -aq) #删除全部镜像
容器命令
说明:我们有了镜像才可以创建容器,linux, 下载一个contos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
--name="Name" 容器的名字 tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-P (大写) 随机指定端口
#测试,启动并进入容器
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -it centos /bin/bash
[root@8d317a4f73cc /]# ls 查看容器内的contos,基础版本,很多命令都是不完善的!
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
#从容器中退回到主机(直接容器停止并且退出)
[root@fd17746636a9 /]# exit
exit
[root@iZwz9j1nogjvor6cio432eZ ~]# ls
install.sh package.xml
#退出容器 容器不停止退出
Ctrl + P + Q #容器不停止退出快捷键
列出所有运行的容器
#docker ps 命令
#列出当前正在运行的容器
-a #列出当前正在运行的容器+带出历史运行过的容器
-n=? #显示最近运行的容器
-q #只显示容器的编号
[root@iZwz9j1nogjvor6cio432eZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZwz9j1nogjvor6cio432eZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd17746636a9 centos "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago intelligent_mccarthy
a55c57e71499 centos "/bin/bash" 4 minutes ago Exited (127) 3 minutes ago nice_lederberg
删除容器
docker rm 容器id #删除指定的容器 不能删除正在运行中的容器 如果要删除要加参数 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
启动和停止容器的操作
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
常用的其他命令
后台启动
#命令 docker run -d centos
# 问题docker ps 发现 centos 停止了
# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用后,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
docker logs
#自己编写了一段shell脚本
run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1; done"
[root@iZwz9j1nogjvor6cio432eZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8bded8b1dc93 centos "/bin/sh -c 'while t…" 6 hours ago Up 6 hours peaceful_gates
#显示日志
-tf #显示日志
-tail number #要显示日志的条数
[root@iZwz9j1nogjvor6cio432eZ ~]# docker logs -tf --tail 10 8bded8b1dc93
2021-01-23T16:05:42.469005189Z kuangshen
2021-01-23T16:05:43.470964356Z kuangshen
2021-01-23T16:05:44.472987287Z kuangshen
2021-01-23T16:05:45.474860613Z kuangshen
2021-01-23T16:05:46.476780034Z kuangshen
2021-01-23T16:05:47.478800165Z kuangshen
2021-01-23T16:05:48.481193073Z kuangshen
2021-01-23T16:05:49.490360044Z kuangshen
2021-01-23T16:05:50.493086207Z kuangshen
2021-01-23T16:05:51.494865358Z kuangshen
2021-01-23T16:05:52.496736751Z kuangshen
2021-01-23T16:05:53.497663079Z kuangshen
2021-01-23T16:05:54.503506869Z kuangshen
查看容器中的进程信息
#命令 docker top 容器id
[root@iZwz9j1nogjvor6cio432eZ ~]# docker top 8bded8b1dc93
UID PID PPID C STIME
root 11940 27619 0 00:09
root 27619 27599 0 Jan23
查看容器的源数据
#命令 docker inspect 容器id
#测试
[root@iZwz9j1nogjvor6cio432eZ ~]# docker inspect 8bded8b1dc93
[
{
"Id": "8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634",
"Created": "2021-01-23T09:36:31.339903754Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo kuangshen;sleep 1; done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 27619,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-01-23T09:36:36.43730251Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634/hostname",
"HostsPath": "/var/lib/docker/containers/8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634/hosts",
"LogPath": "/var/lib/docker/containers/8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634/8bded8b1dc93a6a750fb7a2f85a84d60944a98ccc653556ced6bba56d9566634-json.log",
"Name": "/peaceful_gates",
"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/39dd1a0e59f84f2e0fa126e038d11fc416a9ef95a52bb3b12cb4e3db7e865828-init/diff:/var/lib/docker/overlay2/3871c2fb277e335acfa215dd8d087ec78f60b86e320a86c144fd11272dccda88/diff",
"MergedDir": "/var/lib/docker/overlay2/39dd1a0e59f84f2e0fa126e038d11fc416a9ef95a52bb3b12cb4e3db7e865828/merged",
"UpperDir": "/var/lib/docker/overlay2/39dd1a0e59f84f2e0fa126e038d11fc416a9ef95a52bb3b12cb4e3db7e865828/diff",
"WorkDir": "/var/lib/docker/overlay2/39dd1a0e59f84f2e0fa126e038d11fc416a9ef95a52bb3b12cb4e3db7e865828/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "8bded8b1dc93",
"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 kuangshen;sleep 1; done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20201204",
"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": "eb927f207c6de0f373287ccb8330baeba0647ef798fffc7c47a12bfb4524dfe7",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/eb927f207c6d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "78fbdeef98c55ba031a9c1608b968656b817657bf3b15349fdd08c07c88f47ba",
"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": "a4453bfa54c2b70c6de8520158410b1136e4b5ea836315b88471de6649bbad49",
"EndpointID": "78fbdeef98c55ba031a9c1608b968656b817657bf3b15349fdd08c07c88f47ba",
"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@iZwz9j1nogjvor6cio432eZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8bded8b1dc93 centos "/bin/sh -c 'while t…" 7 hours ago Up 7 hours peaceful_gates
[root@iZwz9j1nogjvor6cio432eZ ~]# docker exec -it 8bded8b1dc93 /bin/bash
[root@8bded8b1dc93 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@8bded8b1dc93 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:36 ? 00:00:07 /bin/sh -c while true;do echo kuangshen;sleep 1; done
root 24819 0 6 16:30 pts/0 00:00:00 /bin/bash
# 方式二 命令
docker attach 容器id
# 测试
[root@iZwz9j1nogjvor6cio432eZ ~]# docker attach 8bded8b1dc93
正在执行当前代码……
# 区别
# docker exec # 进入容器后开启了一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程!
从容器内拷贝文件到主机服务器上
docker cp 容器id:容器内路径 目的地主机路径
# 后台运行
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -it centos /bin/bash
[root@945c042f628b /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@945c042f628b /]# [root@iZwz9j1nogjvor6cio432eZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
945c042f628b centos "/bin/bash" 27 seconds ago Up 23 seconds quirky_blackburn
# 进入docker容器内部
[root@iZwz9j1nogjvor6cio432eZ ~]# docker attach 945c042f628b
[root@945c042f628b /]# cd /home/
[root@945c042f628b home]# ls
# 在容器内新建一个文件
[root@945c042f628b home]# touch test.java
[root@945c042f628b home]# ls
test.java
[root@945c042f628b home]# exit
exit
# 将这个文件拷贝出来到主机上
[root@iZwz9j1nogjvor6cio432eZ home]# docker cp 945c042f628b:/home/test.java /home
[root@iZwz9j1nogjvor6cio432eZ home]# ls
li5220008.java redis test.java www
# 拷贝是一个手动过程,未来我们使用 -v 卷的技术, 可以实现
学习方式:将我的所有命令全部敲一遍,加深记忆!
小结
attach
docker的命令是十分多的,上面我们学习的都是最常用的容器和镜像命令,之后我们还会学习很多命令!
接下来就是一堆练习
作业练习
Docker 安装Nginx
# 1、搜索镜像 search 建议通过官方的网站搜索,可以看到镜像的详细信息
# 2、下载镜像 pull
# 3、运行测试
[root@iZwz9j1nogjvor6cio432eZ home]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a076a628af6f: Pull complete
0732ab25fa22: Pull complete
d7f36f6fe38f: Pull complete
f72584a26f32: Pull complete
7125e4df9063: Pull complete
Digest: sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@iZwz9j1nogjvor6cio432eZ home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f6d0b4767a6c 11 days ago 133MB
centos latest 300e315adb2f 6 weeks ago 209MB
# -d 后台运行
# --name 给容器实例命名
# -p 宿主机端口:容器内部端口
[root@iZwz9j1nogjvor6cio432eZ home]# docker run -d --name nginx01 -p 3344:80 nginx
461579aed62fd1ce47db651d3dbb3b58ec9f2cc51c2eacf5280942f80a369364
[root@iZwz9j1nogjvor6cio432eZ home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
461579aed62f nginx "/docker-entrypoint.…" 10 seconds ago Up 2 seconds 0.0.0.0:3344->80/tcp nginx01
[root@iZwz9j1nogjvor6cio432eZ home]# curl localhost:3344
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
# 进入容器
[root@iZwz9j1nogjvor6cio432eZ ~]# docker exec -it nginx01 /bin/bash
root@461579aed62f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@461579aed62f:/# cd /etc/nginx
root@461579aed62f:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
root@461579aed62f:/etc/nginx#
端口暴露的概念
思考一个问题:我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可以在容器外面提供一个映射路径,达到在容器修改文件名,容器内就可以自动修改? -v 后面我们就会用到容器数据卷的功能!
作业:docker 来装一个tomcat
# 官方使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台,停止了容器之后,容器还可以查到,docker -it --rm 用完即删除,一般用于测试
# 下载再启动
docker pull tomcat
# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat
# 测试访问没有问题
# 进入容器
[root@iZwz9j1nogjvor6cio432eZ ~]# docker exec -it tomcat01 /bin/bash
# 发现问题:1、 linux 命令少了;2、没有webapps 阿里云镜像的原因,morning是最小的镜像,所有不必要的都会剔除掉,保证最小的可运行环境!
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
e2656e05441ec8bc83816de5e779e0f1a0470206b465dc8b726095ac6cbeaee5
思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分的麻烦?我要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步到内部就好了!
作业:部署es + kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般都需要放置在安全目录,挂载!
# 启动elasticsearch
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
# 启动es linux就卡住了docker stats 查看 cup状态
# es是十分耗内存 1.xg 1核2G
# 查看docker stats
# 测试一下es是否成功了
#卡死……
# 赶紧关闭,增加内存的限制,修改配置文件 -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
docker stop c1d7c8435eba14eb4e87b842d53a334d5f579ffe907cac30fd5bacf862736c24
作业:使用kibana连接es? 思考网络如何才能连接过去!
可视化
-
portainer(先用这个)
-
Rancher(CI/CD再用)
什么是portainer?
Docker图形化界面管理工具!提供一个后台面板供我们操作!
Docker镜像详解
镜像是什么?
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
要想更深入的了解 Docker 镜像,镜像的原理也必不可少,而这其中最重要的概念就是镜像层(Layers)(如下图)。镜像层依赖于一系列的底层技术,比如文件系统(filesystems)、写时复制(copy-on-write)、联合挂载(union mounts)等,幸运的是你可以在很多地方学习到这些技术,这里就不再赘述技术细节。
1.镜像是一种轻量级、可执行的独立软件包;
2.镜像是用来打包“软件运行环境”和基于“运行环境”开发的软件;
3.镜像包含运行某个软件所需的所有内容,如代码、库、环境变量和配置文件等;
总结:镜像就是软件安装包,所有的应用只要打包成docker镜像,都可以通过docker直接下载、安装并运行。
加载原理
因为Docker镜像是分层的,因此在加载一个镜像的时候,会按照从底层到高层的顺序依次加载该镜像所需要的镜像层。在加载的过程中,如果当前镜像层已经存在,则会跳过当前镜像层。比如:已经下载过MySQL镜像,现在要下载Tomcat镜像,而这两个镜像都需要CentOS镜像层,那么下载Tomcat镜像的时候,就会跳过下载CentOS镜像层。
分层理解
UnionFS(联合文件系统)
UnionFS:联合文件系统,是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层地叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
UnionFS是Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(根镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
为什么会被比喻成集装箱式服务?
主要原因就在于Docker镜像。简单举个例子,把Docker镜像比作一个箱子,这个箱子里有桌子、椅子、餐盘,然后饭店就可以专门订购这种箱子,用来给客户提供吃饭的服务。我们把箱子拆开,把里面的桌子、椅子、餐盘摆放好,它就可以提供吃饭服务了,这就是容器(运行起来的镜像就是容器)。然后饭店会根据实际需求,在桌子上加一双筷子,那么就是中餐馆,加上一副刀叉,那么就是西餐馆。而且,如果饭店愿意,他们可以选择把桌子、椅子、餐盘加筷子重新封装成一个新箱子,下次可以让别的中餐馆直接订购这个箱子。同样,加上刀叉重新封装, 就可以让西餐馆直接订购了。
Commit镜像
#提交容器成为一个新的副本
docker commit
#命令和git原理类似
docker commit -m="提交描述信息" -a="作者" 容器ID 目标镜像名[TAG]
实战测试
# 1、启动一个tomcat发现默认的tomcat
# 2、发现启动一个tomcat发现默认的tomcat根目录webapps下没有东西,这是镜像为了简化自己的原因!
# 3、我自己copy文件进去,定制化一个自己的tomcat容器
# 4、我们将操作过的镜像通过commit提交为一个镜像!我们以后就可以使用我们自己修改过的镜像,这就是我们自己的镜像!
[root@iZwz9j1nogjvor6cio432eZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2cacaa9c915 tomcat "catalina.sh run" 25 minutes ago Up 25 minutes 0.0.0.0:8081->8080/tcp brave_taussig
[root@iZwz9j1nogjvor6cio432eZ ~]# docker commit -a="li5220008" -m="my custom tomcat" e2cacaa9c915 tomcat02:1.0
sha256:1aef0ba1267915da66e1598bfd253790ce3151a1ce979e95680a0956eb07c120
[root@iZwz9j1nogjvor6cio432eZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 1aef0ba12679 14 seconds ago 654MB
tomcat 9.0 040bdb29ab37 3 weeks ago 649MB
tomcat latest 040bdb29ab37 3 weeks ago 649MB
elasticsearch 7.6.2 f29a1ee41030 10 months ago 791MB
[root@iZwz9j1nogjvor6cio432eZ ~]#
学习方式:理解概念,但是一定要实践,最后实践和理论相结合一次搞定这个知识。
如果你想要保存当前容器的状态,就可以通过commit来提交,获取一个镜像,
就好比vm里面的快照的概念!
到了这里才算是入门!
容器数据卷
什么是容器数据卷?
docker的理念回顾
将应用和容器打包成一个镜像!
数据,如果数据都在容器中,那么我们如果容器删除,数据就会被删除,数据就会丢失!
需求:数据可以持久化!
Mysql,容器删除了,删库跑路!需求:MYSQL数据可以存储到本地!
容器之间可以有一个共享的技术,Docker 容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录挂载到服务中!
总结一句话:容器的持久化和同步操作,容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
#测试
[root@iZwz9j1nogjvor6cio432eZ home]# docker run -it -v /home/ceshi:/home centos /bin/bash
#启动起来我们可以通过docker inspect 容器ID 查看容器卷挂载目录的详情信息
# 测试容器双向绑定过程:
# 1、停止容器
# 2、宿主机上修改文件
# 3、启动容器
# 4、容器内的数据依旧是同步的!
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
实战:安装Mysql
思考:MySQL数据持久化问题!
# 拉取mysql镜像
[root@iZwz9j1nogjvor6cio432eZ home]# docker pull mysql:5.7
# 运行容器,需要做数据挂载!#安装启动mysql,需要配置密码的,这是要注意的点
# 官方测试, docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的mysql
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -d -p 8082: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
cc2fbe9fc11570c6ab3a2d04dacb039c122f7d21d495c8b8f802d28dcba1cb21
# 启动成功后我们用本地的dbms navicat for mysql工具连接上mysql
# dbms 连接到服务器的8082---8082和容器中的3306端口映射,这个时候我们就可以连接上了
# 在本地创建一个数据test 查看一下我们映射的路径是否OK
假设我们将容器删除
发现我们挂载到本地数据卷依旧没有丢失,这就实现了容器数据持久化的功能
具名和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有卷的情况
[root@iZwz9j1nogjvor6cio432eZ home]# docker volume ls
DRIVER VOLUME NAME
local 9e9b0e2cef7ebb2cba1dd3ebf901c1097825427aeacd33ffa7d1b49b77335c0b
# 这种就是匿名挂载,我们在 -v的时候只写了容器内的路径,没写容器外的路径
# 具名挂载
[root@iZwz9j1nogjvor6cio432eZ home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
77a1ac62dfe7a56c1b006c95ab6ba332bb4a471eee940820734c2a60b6dc478a
[root@iZwz9j1nogjvor6cio432eZ home]# docker volume ls
DRIVER VOLUME NAME
local 9e9b0e2cef7ebb2cba1dd3ebf901c1097825427aeacd33ffa7d1b49b77335c0b
local juming-nginx
# 通过 -v 卷名:容器内路径
# 查看下这个卷
[root@iZwz9j1nogjvor6cio432eZ home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-02-07T14:20:14+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/xxx/_data目录下
# 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况都使用 具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 容器名称:容器内路径 # 具名挂载
-v 容器外路径:容器内路径 # 指定路径挂载
# 拓展
# 通过 -v 容器内路径:ro rw 改变路径的读写权限
ro readonly # 只读
rw readwrite # 可写
# 一旦这个设置了容器读写权限,容器对我们挂载出来的路径只能有对应的读写权限
[root@iZwz9j1nogjvor6cio432eZ home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@iZwz9j1nogjvor6cio432eZ home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到ro 就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!
DockerFile
初识Dockerfile
Dockerfile就是用来构建Docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本就是一个个命令,每个命令就是一层
# 创建一个dockerfile文件 名字可以随意起,建议 Dockerfile 官方推荐
# 文件中的内容 指令(大写) 参数
[root@iZwz9j1nogjvor6cio432eZ docker-test-volume]# cat dockerfile
FROM centos
#匿名挂载
VOLUME ["volumes01","volume02"]
CMD echo "----end----"
CMD /bin/bash
# 这里的每一个命令都是镜像中的一层
# 启动自己的构建的容器
# 这个卷和宿主机外面一定有一个对应的目录
[root@iZwz9j1nogjvor6cio432eZ data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a661eb9017bb f8c973a10088 "/bin/bash" 12 seconds ago Up 12 seconds interesting_meitner
77a1ac62dfe7 nginx "/docker-entrypoint.…" 50 minutes ago Up 50 minutes 0.0.0.0:49154->80/tcp nginx02
e83abe18ef1c nginx "/docker-entrypoint.…" 58 minutes ago Up 58 minutes 0.0.0.0:49153->80/tcp nginx01
[root@iZwz9j1nogjvor6cio432eZ data]# docker inspect a661eb9017bb
•~~~~
"Mounts": [
{
"Type": "volume",
"Name": "26073bb3584a359650b2274f358b31a477d2812477e07b294de61a5376166af2",
"Source": "/var/lib/docker/volumes/26073bb3584a359650b2274f358b31a477d2812477e07b294de61a5376166af2/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "7d65e6573ec96ff179c52d894c34eb76d63e3e18d129afb2268d6a95755b4770",
"Source": "/var/lib/docker/volumes/7d65e6573ec96ff179c52d894c34eb76d63e3e18d129afb2268d6a95755b4770/_data",
"Destination": "volumes01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
•~~~
# 测试一下刚才我们挂载的目录是否同步出去
[root@iZwz9j1nogjvor6cio432eZ data]# ls /var/lib/docker/volumes/26073bb3584a359650b2274f358b31a477d2812477e07b294de61a5376166af2/_data/
container.txt
# 这种方式我们未来使用的非常多,因为我们通常会构建自己的镜像!
# 假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
多个mysql同步数据!
# 启动三个容器,通过我们刚才自己写的镜像启动
# 测试,可以删除docker01,查看一下docker01和docker03是否还可以访问这两个文件
# 测试依旧存在,可以正常访问
多个mysql实现数据共享
# 启动我们的mysql
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -d -p 8082: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
[root@iZwz9j1nogjvor6cio432eZ ~]# docker run -d -p 8083:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 volumes-from mysql01 mysql:5.7
# 这个时候可以实现两个容器数据同步
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直维持到没有容器使用为止。
但是一旦你持久化到本地,这个时候本地的数据不会被删除的!
Dockerfile介绍
Dockerfile就是用来构建Docker镜像的构建文件!命令脚本!
构建步骤:
-
编写一个dockerfile文件
-
docker build 构建成为一个镜像
-
docker run 运行镜像
-
docker push 发布镜像(DockerHub、阿里云镜像仓库)
查看一下官方是如何构建镜像的
很多官方镜像都是基础包,很多功能没有,我们通常需要自己搭建自己的镜像!
官方既然可以制作镜像我们也可以!
DockerFile构建过程
基础知识
-
每个保留关键字(指令)都必须是大写字母
-
从上到下按顺序执行
-
#标识注释
-
每一个指令都会创建提交一个镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分重要!
Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发、部署、运维 缺一不可!
DockerFile: 构建文件,定义了一切的步骤,源代码
Dockerimages:通过DockerFile 构建生成的镜像,最终发布和运行的产品