第一章 初识Docker
1.1 符合标准1.0
待补充的部分
[root@master ~]# yum install wget net-tools vim yum-utils -y
yum --config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
1.2 安装docker
删除系统可能存在的docker
[root@master ~]# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
[root@docker ~]# yum search docker-ce #可省略
[root@docker ~]# yum install docker-ce-19.03.6 docker-ce-cli-19.03.6 containerd.io
[root@docker ~]# service docker start
[root@docker ~]# chkconfig docker on #开机启动
查看docker版本
[root@template ~]# docker version
Client: Docker Engine - Community
Version: 19.03.6
API version: 1.40
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:29:29 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.6
API version: 1.40 (minimum version 1.12)
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:28:07 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.22
GitCommit: 8165feabfdfe38c65b599c4993d227328c231fca
runc:
Version: 1.1.8
GitCommit: v1.1.8-0-g82f18fe
docker-init:
Version: 0.18.0
GitCommit: fec3683
查看docker的基本信息
[root@template ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.6
Storage Driver: overlay2 #一定得是overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs #一定得是cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive #不活跃状态
Runtimes: runc #运行时 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 8165feabfdfe38c65b599c4993d227328c231fca
runc version: v1.1.8-0-g82f18fe
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-1160.95.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 7.638GiB
Name: template
ID: KSTG:266G:AKUX:XYZH:CEWZ:WEAB:WNPY:74NB:EPLA:RJ53:UJXD:3GK2
Docker Root Dir: /var/lib/docker #容器存放的地方
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
1.3 修改Docker存储目录
[root@template ~]# vim /usr/lib/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/dockerd --graph=/data/docker -H fd:// --containerd=/run/containerd/containerd.sock
[root@template ~]# systemctl daemon-reload
[root@template ~]# systemctl restart docker
添加镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://th8d5hdw.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
启动第一个容器
[root@template ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
1.4 Docker C/S 模式
Docker客户端和服务端是使用Socket方式连接的,主要有以下几种方式:
1)本地的Socket文件unix:///var/run/docker/sock (默认)
2)tcp://host:port
3)fd://socketfd
[root@template ~]# vim /usr/lib/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock
[root@template ~]# systemctl daemon-reload
[root@template ~]# systemctl restart docker
[root@template ~]# netstat -anltup | grep 2375
tcp6 0 0 :::2375 :::* LISTEN 25417/dockerd
第二章 Docker镜像
2.1 容器运行基础
镜像是Docker运行的基础,就好比计算机硬件需要安装操作系统一样。使用Docker Image命令可以看到当前系统中存在的镜像。当运行容器时,使用的镜像如果在本地系统中不存在,Docker就会自动从Docker镜像仓库或者配置的私有仓库中下载;默认是Docker Hub公共镜像源下载。
上节在Docker C/S架构逻辑图中提到了私有仓库。这节主要讲镜像的基本操作。
2.2 Docker加载镜像流程
1)检查本地是否有与启动镜像相匹配的镜像。
2)查询与镜像地址中是否有启动的镜像。
3)如果在镜像地址中没有完整的地址,则从默认的Docker Hub(http://registry.hub.docker.com/)下载。
Docker加载镜像的两种方式:
公共仓库与私有仓库
2.3 Docker镜像基本操作
搜索Docker Hub有哪些镜像
docker search [镜像名字]
[root@template ~]# docker search nginx
从Docker Hub下载镜像
下载镜像(没有指定版本,则会下载最新版的latest)
docker pull nginx:latest = docker pull nginx
[root@template ~]# docker pull nginx:latest
从第三方Docker镜像仓库或者私有仓库下载镜像方法
[root@template ~]# docker pull abc.cn/nginx:latest
镜像加速器
在下载Docker Hub镜像非常慢的情况下,可以使用镜像加速功能。配置加速可以用官网提供的,也可以使用私有仓库。
[root@template ~]# sudo mkdir -p /etc/docker
[root@template ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://th8d5hdw.mirror.aliyuncs.com"]
}
EOF
[root@template ~]# sudo systemctl daemon-reload
[root@template ~]# sudo systemctl restart docker
基于容器创建镜像系统(容器快照功能)
#类似虚拟机的克隆功能
#在运行当中的容器基础上创建一个新的镜像(相当于VM的完整的快照)或者是容器备份
[root@template ~]# docker ps -a # -a 显示所有容器
[root@template ~]# docker run -d -P nginx
0bbba19e95365ffb549e03a41d6dd76cd43f77e64c04494874e40c58b96dc13a #返回容器ID
[root@template ~]# docker ps
基于这个已经创建好了的容器再去创建一个容器
[root@template ~]# docker container commit 0bbba19e9536 nginx-test:1.0
sha256:80af4ca141d13047189ce21f4f84cced54a0c546e3f81cbe8d902d7f615d0cd3
#0bbba19e9536 容器运行的ID
查看镜像
[root@template ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-test 1.0 80af4ca141d1 2 minutes ago 141MB
nginx latest 605c77e624dd 20 months ago 141MB
hello-world latest feb5d9fea6a5 23 months ago 13.3kB
⚠️不能删除原来的镜像(父镜像)
[root@template ~]# docker rmi nginx
Error response from daemon: conflict: unable to remove repository reference "nginx" (must force) - container 0bbba19e9536 is using its referenced image 605c77e624dd
删除镜像(子镜像)
[root@template ~]# docker rmi nginx-test:1.0
Untagged: nginx-test:1.0
Deleted: sha256:80af4ca141d13047189ce21f4f84cced54a0c546e3f81cbe8d902d7f615d0cd3
Deleted: sha256:ef0d56dc3a57737b77013bc40756eee7ab41883671764296329da17bdc35ac3e
如何正确删除镜像?
方式一:
1、先删除容器
[root@template ~]# docker rm 0bbba19e9536 #0bbba19e9536 是容器的ID
0bbba19e9536
2、查询该容器是否还在运行
[root@template ~]# docker ps -a
3、删除镜像
[root@template ~]# docker rmi nginx
Untagged: nginx:latest
Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Deleted: sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
Deleted: sha256:b625d8e29573fa369e799ca7c5df8b7a902126d2b7cbeb390af59e4b9e1210c5
Deleted: sha256:7850d382fb05e393e211067c5ca0aada2111fcbe550a90fed04d1c634bd31a14
Deleted: sha256:02b80ac2055edd757a996c3d554e6a8906fd3521e14d1227440afd5163a5f1c4
Deleted: sha256:b92aa5824592ecb46e6d169f8e694a99150ccef01a2aabea7b9c02356cdabe7c
Deleted: sha256:780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5
Deleted: sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
方式二:强制删除
[root@template ~]# docker rmi -f nginx
Untagged: nginx:latest
Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
❓小问题:强制删除后,正在运行的容器和镜像快照怎么样了?
答案:依旧存在
[root@template ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-test 1.0 76fb45b4e3f6 4 minutes ago 141MB
[root@template ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cfa8d04941c1 605c77e624dd "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 0.0.0.0:32769->80/tcp nervous_dhawan
使用克隆的镜像创建一个容器
[root@template ~]# docker run -d -p 8090:80 nginx-test:1.0
18903b78e259f1c9b842229c343ff22e70c31353477cdd372191b8ab50a68ef8
导出镜像
导出镜像为tar包
[root@template ~]# docker image save nginx:latest > nginx.tar.gz
[root@template ~]# ll
总用量 142712
-rw-r--r-- 1 root root 145905152 9月 6 03:32 nginx.tar.gz
导入镜像
直接使用tar包导入镜像,注意如果原来导出的源镜像还是存在于系统中,那么新导入的镜像在系统中将不可见。
[root@template ~]# docker image load -i nginx.tar.gz
Loaded image: nginx:latest
#强制删除原来的镜像
[root@template ~]# docker rmi nginx:latest --force
Untagged: nginx:latest
Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
#再次执行导入
[root@template ~]# docker image load -i nginx.tar.gz
Loaded image: nginx:latest
镜像tag标签
#语法:docker image tag 源_Image[:Tag] 目标_Image[:Tag]
#类似Linux硬链接,在推送镜像到私有仓库时,需要添加tag。
[root@template ~]# docker image tag nginx:latest repo.zxm.com/nginx:v1.0
[root@template ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
repo.zxm.com/nginx v1.0 605c77e624dd 20 months ago 141MB
#推送镜像到镜像仓库
[root@template ~]# docker push repo.zxm.com/nginx:v1.0
#使用新的tag标签启动容器
[root@template ~]# docker run -d -p 9091:80 repo.zxm.com/nginx:v1.0
ff7ffb5c14044fd5a70d988bed6f646d2cb7cfeb96b4ee5333be29b30fe83700
构建Java基础镜像(JDK)
之前使用的为Docker自带镜像仓库中的镜像,现在我们自己来构建私有镜像
❓在Java镜像中为什么要构建alpine-glib?
#Java Dockerfile
[root@template ~]# mkdir -p /root/jdk/
[root@template ~]# vim Dockerfile
FROM frolvlad/alpine-glibc #模版镜像
MAINTAINER Tony #创建人
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main/" > /etc/apk/repositories #修改源
RUN apk add --no-cache bash #安装bash
ADD jre1.8.0_211.tar.gz /usr/java/jdk/ #添加文件
ENV JAVA_HOME /usr/java/jdk/jre1.8.0_211 #设置环境变量
ENV PATH ${PATH}:${JAVA_HOME}/bin
RUN chmod +x /usr/java/jdk/jre1.8.0_211/bin/java
WORKDIR /opt #工作目录
构建镜像
#需要把jre_1.8.0_211.tar.gz放到与Dockerfile同级目录
[root@template jdk]# docker pull frolvlad/alpine-glibc
[root@template jdk]# docker build -t jre8:1.0 .
[root@template jdk]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jre8 1.0 7917424f51a1 7 seconds ago 137MB
查看容器构建的历史
#missing 为当前镜像的源镜像的构建历史
#
[root@template jdk]# docker history jre8:1.0
查看镜像的详情
[root@template jdk]# docker image inspect jre8:1.0
2.4 Docker镜像与Overlay2关系
Docker 需要OverlayFS文件系统存储
1)Docker中的镜像采用分层构建设计,每层都可以称为“layer”,镜像文件默认存在目录:/var/lib/docker/overlay2
2)Docker支持的文件存储如下:AUFS、OverlatFS、VFS、Brtfs等。
3)通过Docker info命令查看当前的存储驱动
[root@template jdk]# docker info | grep -E "Storage Driver|Server Version"
Server Version: 19.03.6
Storage Driver: overlay2
3.1)修改Docker的存储驱动为Overlay2
[root@template jdk]# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://th8d5hdw.mirror.aliyuncs.com"],
"log-driver": "json-file",
"log-opts":{
"max-size":"100m"
},
"storage-driver": "overlay2"
}
4)通常Ubuntu类的系统默认采用的是AUFS,CentOS7.1+系列采用的是OverlayFS。
第三章 Docker镜像存储机制
本章节是对上章节Docker镜像原理理解的巩固;从Linux系统运行基础到OverlayFS存储机制去了解与分析;在底层,镜像是怎么实现存储到;并且会详细说明存储文件的作用。
3.1 Linux系统运行基础
Linux系统正常运行,通常需要两个文件系统:
3.1.1 boot file system(bootfs)
- 包含Boot Loader与kernel文件,用户不能修改这些文件。并且在系统启动过程完成之后,整个系统的内核都会被家在进内存。此时bootfs会被卸载,从而释放出所占的系统内存。
- 在容器中可以运行不同版本的Linux,说明对于同样内核版本的不同的Linux发行版的bootfs都是一致的,否则会无法启动。因此可以推断,Docker运行时需要内核支持的。
- Linux系统中典型的bootfs目录:(核心)/boot/vmlinuz、(核心解压缩所需 RAM Dis k)/boot/initramfs
3.1.2 root file system(rootfs)
- 不同的Linux发行版本,bootfs相同,rootfs不同(二进制文件)
- 每个容器都有自己的rootfs,它来自不同的Linux发行版本的基础镜像,包括Ubuntu、Debian、和SUSE等。
- 使用不同的rootfs就决定了,在构建镜像的过程中,可以使用哪些系统的命令。
- 典型的rootfs目录:/dev、/proc、/etc、/lib、/usr
3.2 OverlayFS层次
OverlayFS结构分为了三个层:LowerDir、Upperdir、MergeDir
-
LowerDir(只读)
只读的image layer,其实就是roots,在使用Dockerfile构建镜像的时候,Image Layer可以分很多层,所以对应的lowerdir会很多(源镜像)。
-
Upperdir(读写)
Upperdir则是在lowerdir之上的一层,为读写层。容器在启动的时候会创建,所有对容器的修改,都是在这层。比如容器启动写入的日志文件,或者是应用程序写入的临时文件。
-
MergeDir(展示)
mergeDir目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。
LowerDir、Upperdir、MergeDir关系图
3.3 查看镜像存储目录结构
获取镜像存储路径
通过镜像信息获取到物理存储位置
[root@template jdk]# docker image inspect jre8:1.0
3.4 查看容器的存储目录结构
启动容器
前台启动,直接进入到容器
[root@template jdk]# docker run -it jre8:1.0
查看容器挂载信息
容器启动以后,挂载merged、lowerdir、upperdir以及workdir目录
lowerdir是只读的image layer,其实就是roots
#获取容器ID
[root@template ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27d755b69076 jre8:1.0 "bash" About a minute ago Up About a minute pensive_ritchie
容器存储目录信息
注意在所有的启动容器中会自动添加init目录,此目录是存放系统的hostname与域名解析文件。
[root@template ~]# docker inspect 27d755b69076
[
{
"Id": "27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706",
"Created": "2023-09-08T06:24:04.376632294Z",
"Path": "bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 2507,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-09-08T06:24:04.704758518Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:7917424f51a13ad1c5ca650347d76b0cf151eee71a26b21626f7265a8a73198c",
"ResolvConfPath": "/data/docker/containers/27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706/resolv.conf",
"HostnamePath": "/data/docker/containers/27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706/hostname",
"HostsPath": "/data/docker/containers/27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706/hosts",
"LogPath": "/data/docker/containers/27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706/27d755b6907645bccf2528d88bcfa652e4a08e6fb4a87c8a8f8a1e7566726706-json.log",
"Name": "/pensive_ritchie",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {
"max-size": "100m"
}
},
"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": "/data/docker/overlay2/19a77cb63dcb95ab5c942d83e280d4c7e34d5e0effa341d9f2a09805117bceda-init/diff:/data/docker/overlay2/ca16304c1570bb49cb16b14c85fbdf1500e4bf0b403083bebfd62e76d35f4a17/diff:/data/docker/overlay2/ce674c6b9a1d62652171ebfe592237e249ee16fc10132605d42249c1a78fbd7f/diff:/data/docker/overlay2/e62c418de52bc27b3835abdb387c6569d9e8af45e85798ea28a31213d9a5d395/diff:/data/docker/overlay2/4ef4d01f24a7e01d38f3131efcb38899c224a29478873b88b54d5ab2acfe22b2/diff:/data/docker/overlay2/b33b4c6939ff8bd2454b32e4eaa497977454c9da56073783a76603d6c90333a8/diff:/data/docker/overlay2/08894f5a26ecfca0c0aad5bbc86cf0f946ca8eaa551a744618e7a61a19d54f98/diff",
"MergedDir": "/data/docker/overlay2/19a77cb63dcb95ab5c942d83e280d4c7e34d5e0effa341d9f2a09805117bceda/merged",
"UpperDir": "/data/docker/overlay2/19a77cb63dcb95ab5c942d83e280d4c7e34d5e0effa341d9f2a09805117bceda/diff",
"WorkDir": "/data/docker/overlay2/19a77cb63dcb95ab5c942d83e280d4c7e34d5e0effa341d9f2a09805117bceda/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "27d755b69076",
"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:/usr/java/jdk/jre1.8.0_211/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/java/jdk/jre1.8.0_211"
],
"Cmd": [
"bash"
],
"Image": "jre8:1.0",
"Volumes": null,
"WorkingDir": "/opt",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "6bc9eef7140a0695367e70b72fb3ed0a5a3c6b75fc29c58226fb41c8b38de6b8",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/6bc9eef7140a",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "8364e08bf711c06e0f2b405c8fdb1b8f6fef37baca92ec1a38e915d613decf3e",
"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": "92619e79ee875cb1d8bcd2ab45903d1a6dc04428041888ecf06450720e09d454",
"EndpointID": "8364e08bf711c06e0f2b405c8fdb1b8f6fef37baca92ec1a38e915d613decf3e",
"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
}
}
}
}
]
3.5 容器文件存储
查看init层地址指向
容器在启动的过程中,Lower会自动挂载init的一些文件
init层主要内容是什么?
init层是一个uuid+-init结尾表示,放在只读层和读写层之间,作用只是存放在/etc/hosts、/etc/resolv.conf等文件
为什么需要init层
- 容器在启动以后,默认情况下lower层是不能修改内容的,但是用户有需求需要修改主机名与域名地址,那么就需要添加init层的文件(hostname、resolv.conf),用于解决此类问题。
- 修改的内容只对当前的容器生效,而在docker commit提交为镜像时候,并不会将init层提交。
- init文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff
查看init层文件
hostname与resolve.conf全部为空文件,在系统启动以后由系统写入。
总结
- 镜像所挂载的目录层为 Lower 层,然后通过 Merged 展示所有的文件目录与文件。用户写入的所有文件都是在 UpperDir 目录,并且会在 UpperDir 建立于 Merged 层展示的文件目录结构,所以用户就可以看到写入的文件。并且底层的镜像是不能被修改(如果挂载目录为 UpperDir,则可以修改源镜像)。
- 在下次重新启动己经停止的容器的时候,如果容器的 ID 没有发生改变,那么所写入的文件是存在物理系统中的;反之就会是一个新的容器,之前手工创建的文件是不存在的。
- 基于容器创建的镜像,就相当于容器的快照,可以删除原来的容器,但是不能删除原来的镜像
第四章 容器基本操作
本章节主要讲解 Docker 容器的基本操作指令,学会查看指令的帮助;并且掌握容器常用的操作命令,对之后容器的操作会有很大的帮助。
4.1 查看 Docker 命令行帮助
查看帮助的方法
Docker 操作命令分为:管理命令与直接命令参数
- 管理命令为区分每个项目的命令,比如说镜像操作,就是以docker image 开头
- 直接命令参数就是在docker 命令之后直接的命令,比如说删除镜像 docker rmi管理命令相对于直接命令参数,更加严谨。
[root@template ~]# docker --help
4.2 常用基本操作列表
可以通过以下命令来启动一个Docker容器:
`docker run -d -p host_port:container_port image_name`
其中,“-d”选项使容器在后台运行,“-p”用于映射主机端口到容器端口,“image_name”是你要运行的Docker镜像的名称。
例如,如果你有一个名为“myapp”的镜像并想在主机的8080端口和容器的80端口之间建立映射,你可以使用以下命令:
`docker run -d -p 8080:80 myapp`
如果你想给Docker容器设置一个名称,可以通过添加“--name”选项来实现:
`docker run -d -p 8080:80 --name my_container myapp`
[root@template ~]# docker --help
Usage: docker [OPTIONS] COMMAND
Options:
--config string Location of client config files (default "/root/.docker")
这是一个 Docker 命令选项,用于指定 Docker daemon 的配置文件路径。默认情况下,Docker daemon 的配置文件位于 `/etc/docker/daemon.json`。
命令行 | 解释 |
---|---|
查看容器日志
启动容器,-P 生成随机映射端口
[root@template ~]# docker run --name t1 -P -d nginx
查看日志
[root@template ~]# docker logs -f t1
标签:容器,template,镜像,Docker,root,docker From: https://www.cnblogs.com/zxm1/p/17789143.html