Docker Basics_Notes

Configure Mirror Accelerator

Alibaba Cloud Mirror Accelerator: https://cr.console.aliyun.com

# 针对Docker客户端版本大于 1.10.0 的用户
# 您可以通过修改/新增daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://onau6ame.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

docker related files

# docker配置文件
# CentOS6
/etc/sysconfig/docker
# CentOS7
/usr/lib/systemd/system/docker.service
# 日志
$ cat /var/log/messages | grep docker

Start/stop docker service

# 启动/停止/重启
systemctl start/stop/restart docker 
# 查看状态
systemctl status docker 
# 开机启动
systemctl enable docker

mirror image

Obtain

​ Docker needs to have a corresponding image locally before running the container. If the image does not exist locally, Docker will download the image from the mirror warehouse (docker pull).

docker pull ubuntu:16.04

​ The Docker mirror warehouse address is not given in the above command, so the mirror will be obtained from Docker Hub. The image name is ubuntu:16.04, so the image labeled 16.04 in the official image library/ubuntu warehouse will be obtained.

run

[root@docker ~]# docker run -it --rm ubuntu:16.04 bash
root@3a31439393f0:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
root@3a31439393f0:/# exit
exit
[root@docker ~]# 

docker run: The command to run the container. If there is no such mirror, it will be pulled first and then run
-it: these are two parameters, one is -i: interactive operation, and the other is -t terminal. Represents an interactive session with a tty attached to it
– rm: it is removed after the container exits. By default, for troubleshooting purposes, the exited container will not be deleted immediately, unless manually docker rm
ubuntu:16.04: refers to using the ubuntu:16.04 image as the basis to start the container
bash: interactive shell, using bash
-d : Run the image in the background
-h: Set a new hostname
exit: Exit the container

Check

# 列表包含了 仓库名 、 标签 、 镜像 ID 、 创建时间 以及 所占用的空间
[root@docker ~]#docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5f2bf26e3524        11 days ago         123MB

Label

​ The image ID is the unique identifier of the image, and one image can correspond to multiple tags. If they have the same ID, they correspond to the same image.

# 修改标签
docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)
docker tag 5f2bf26e3524 ubuntu:new-tag

# 删除标签
docker rmi -f REPOSITORY:TAG(仓库:标签)

Space Occupancy View

# 查看镜像、容器、数据卷所占用的空间
[root@docker ~]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              2                   1                   122.6MB             122.6MB (99%)
Containers          1                   0                   0B                  0B
Local Volumes       0                   0                   0B                  0B
Build Cache         0                   0                   0B                  0B
# docker system df -v 命令可以进一步查看空间占用细节,以确定是哪个镜像、容器或本地卷占用过高空间

virtual mirror

​ In the mirror list, sometimes you can see a special mirror, which has neither a warehouse name nor a label, both

# 列出所有虚悬镜像
[root@docker ~]# docker image ls -f dangling=true
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              00285df0df87        12 days ago         340MB

Generally speaking, the dangling image has lost the value of existence and can be deleted at will. The deletion command: docker image prune The
objects cleaned by this command are as follows:
Stopped containers
Volumes not used by any container
are not associated with any container network of
all dangling mirrors

Middle layer mirroring

​ Only the top-level image will be displayed in the docker images list. If you want to display all images including the intermediate layer image, you need to add the -a parameter.

# docker images -a

​ In this way, you will see many unlabeled images. Unlike the previous virtual images, many of these unlabeled images are intermediate layer images, which are the images that other images depend on. These unlabeled images should not be deleted, otherwise the upper layer image will cause an error due to loss of dependencies.

display in specific format

# 列出镜像ID
[root@docker ~]# docker image ls -q
5f2bf26e3524
5f2bf26e3524
fce289e99eb9
# 列出 镜像ID、仓库名 和 标签
[root@docker ~]# docker image ls --format "{
    
    {.ID}}: {
    
    {.Repository}}  {
    
    {.Tag}}"
5f2bf26e3524: ubuntu  16.04
5f2bf26e3524: ubuntu  new-tag
fce289e99eb9: hello-world  latest
# 以表格等距显示,有标题行,自己定义列
[root@docker ~]# docker image ls --format "table {
    
    {.ID}}\t{
    
    {.Repository}}\t{
    
    {.Tag}}"
IMAGE ID            REPOSITORY          TAG
5f2bf26e3524        ubuntu              16.04
5f2bf26e3524        ubuntu              new-tag
fce289e99eb9        hello-world         latest

delete local image

​ docker image rm [ ID or NAME ] <mirror 1> [<mirror 2> …]

# 删除所有仓库名为 xx 的镜像
$ docker image rm $(docker image ls -q xx)
# 需要停止容器,解除容器对镜像的依赖,才可删除
# 停止所有容器
$ docker stop $(docker ps -a -q)
$ docker image rm fce289

container

start/stop

# 启动
$ docker start [container ID or NAMES]
# 停止所有容器
$ docker stop $(docker ps -aq)
# 启动所有状态为exited的容器
$ docker start $(docker ps -aq -f status=exited) 

into the container

# 方式1
docker exec -it [container ID or NAMES] bash
# 方式2
yum install -y util-linux
docker inspect --format "{
    
    {.State.Pid}}" [container ID or NAMES]	# 获取pid
nsenter --target [PID] --mount --uts --ipc --net --pid	# 进入
# 启动一个名为mynginx的容器
[root@docker ~]# docker run -d --name mynginx nginx
# 编写脚本进入容器
[root@docker ~]# cat in.sh 
#!/bin/bash
CNAME=$1
CPID=$(docker inspect --format "{
     
     {.State.Pid}}" $CNAME)		# 获取容器进程IP
nsenter --target "$CPID" --mount --uts --ipc --net --pid	# 进入容器
[root@docker ~]# ./in.sh mynginx
mesg: ttyname failed: No such device
root@5dc5aff550e4:/#

View container details

$ docker inspect [container ID or NAMES]
[
    {
    
    
        "Id": "23b077ae6d36d5f67f014c290495c15bd911f22043d0523eafb35ee0de087daf",
        "Created": "2023-03-08T06:02:31.267759389Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
    
    
            "Status": "running",
            "Running": true,
...

#  可以用 grep 或 --format 参数(需要一个Go模板)来过滤
#  找出容器的 IP 地址
$ docker inspect [container ID or NAMES] | grep IPAddress
 "IPAddress": "172.17.0.4", 
 "SecondaryIPAddresses": null, 
$ docker inspect ––format {
    
    {
    
    .NetworkSettings.IPAddress}} [container ID or NAMES]
172.17.0.4

View changes in the container

Docker containers use the Union File System (UFS), which allows multiple file systems to be mounted hierarchically and appear as a single file system. The image's filesystem is mounted read-only, and any changes to the running container will only occur on the read-write layer above it. Therefore, Docker only needs to look at the topmost readable and writable layer to find out all the changes that have been made to the running system.

# 显示容器的文件系统的变化
$ docker diff [container ID or NAMES]
D /bin	# 删除
A /basket # 新增
A /basket/bash 
...

container logs

$ docker logs [container ID or NAMES]
# -t:打印时间戳
# -f:持续打印日志变化

resource usage

$ docker stats [container ID or NAMES]
CONTAINER ID	NAME	CPU %	MEM USAGE / LIMIT    MEM %	NET I/O	BLOCK I/O	PIDS
6f95b1d24af5	nginx	0.00%	3.082MiB / 3.84GiB   0.08%	0B / 0B	21.2MB / 0B	5
# 获取所有运行中容器的统计数据
$ docker stats $(docker inspect -f {
     
     {
     
     .Name}} $(docker ps -q))

Note that unless a memory limit is set on the container, the memory limit seen is the total amount of memory on the host, not the amount of memory available to the container.

delete container

# 删除所有容器
$ docker rm $(docker ps -a -q)
# 删除已停止的容器
$ docker rm -v $(docker ps -aq -f status=exited)	# -v:删除关联的数据卷(/var/lib/docker/volumes/...)

$ docker container rm trusting_newton	# 删除一个处于终止状态的容器
# 如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器
$ docker container prune	# 清理掉所有处于终止状态的容器

Data replication for containers

# 容器文件复制到本地
$ docker cp [container ID or NAMES]:/root/A.txt . 
# 本地文件复制到容器
$ docker cp A.txt [container ID or NAMES]:/root/A.txt

Port Mapping

Suppose a web server is running in a container. How to make it accessible to the outside world? The answer is to "publish" the port via the -p or -P option. This command forwards the host's port to the container.

# -P(大写)随机分配端口映射;-p(小写)指定映射端口;
$ docker run -d -P --name mynginx1 nginx	# 让EXPOSE声明的端口都映射到主机的某一个随机端口上
$ docker run -d -p 81:80 --name mynginx2 nginx	# 81指:映射后的端口;80指:容器里的端口

# 例1
$ docker run -d -p 8000:80 nginx 
af9038e18360002ef3f3658f16094dadd4928c4b3e88e347c9a746b131db5444
$ curl localhost:8000
...
<title>Welcome to nginx!</title>
...
# 例2
$ docker run -d -P nginx
3423904dae5ba43a66c94872a8a51907bb613357654719a456aa5deea82ac025
$ docker port 3423904dae5ba 80	# 查看docker分配的端口
0.0.0.0:32770
$ curl localhost:32770
...
<title>Welcome to nginx!</title>
...

Image/container import and export

mirror image

# 1.导出(save)/导入(load)
$ docker save -o xx.tar [REPOSITORY:TAG] or [container ID]
$ docker load -i xx.tar 

# 2.导出(save)/导入(load)
$ docker save > xx.tar [REPOSITORY:TAG] or [container ID]
$ docker load < xx.tar

# 其中-o和>表示输出到文件,xx.tar为目标文件
# 导入后的镜像的tag为空时,需要为镜像做tag
$ docker tag [container ID] [REPOSITORY:TAG]

container

# 1.导出(export)/导入(import)
docker export [container ID or NAMES] > xx.tar	# 将导出容器快照到本地文件(.tar)
docker import xx.tar [REPOSITORY:TAG]
# 它只会导出文件系统;任何元数据,如映射端口、CMD 和 ENTRYPOINT 配置将会丢失。数据卷也不会包含在导出归档中

# 2.导出(export)/导入(import)
docker export -o xx.tar [container ID or NAMES]	# -o:表示输出到文件
cat xx.tar | docker import - [REPOSITORY:TAG]

build image

manual

#  返回镜像id;-m :提交时的说明文字;
$ docker commit -m “xxxx” [container ID] xx/xx:v1
# 例
$ docker run -it --name cowsay --hostname cowsay debian bash
root@cowsay:/# apt-get update
... 
Reading package lists... Done 
root@cowsay:/# apt-get install -y cowsay fortune
...
root@cowsay:/# /usr/games/fortune | /usr/games/cowsay
 _______________________________________
/ You will be aided greatly by a person \
\ whom you thought to be unimportant.   /
 ---------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
root@cowsay:/# exit 
exit 
# 把它转成镜像,执行 docker commit 即可,无论容器是在运行中还是在停止状态都可以。执行 docker commit 时,你需要提供的参数包括容器的名称(“cowsay”)、新镜像的名称(“cowsayimage”),以及用来存放镜像的仓库名称(“test”):
$ docker commit cowsay test/cowsayimage
sha256:4df57a2ceb693148b0b0c0e9a66dba3ef90f80210138f19bd4407cc202205589
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test/cowsayimage    latest              4df57a2ceb69        19 seconds ago      191MB
...
# 相当于创建个在debian基础上安装了 cowsay 的镜像
$ docker run test/cowsayimage /usr/games/cowsay "Moo"
 _____
< Moo >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Dockerfile

​Each instruction in the Dockerfile , and this image layer can actually be used to start the container. The establishment of a new image layer is to start the container with the image of the previous layer, and then execute the instructions of the Dockerfile to save it as a new image.

# 上述操作使用Dockerfile完成
$ mkdir cowsay
$ cd cowsay
$ touch Dockerfile
$ cat Dockerfile
FROM debian:wheezy
RUN apt-get update && apt-get install -y cowsay fortune
# 生成镜像
$ docker build -t test/cowsay-dockerfile .
...
$ docker run test/cowsay-dockerfile /usr/games/cowsay "Moo"

Example: Build a mirror image of nginx

[root@docker nginx]# cat Dockerfile 
# Version 1.0
# Author: zhang san

# 基础镜像
FROM centos
# 维护者信息
MAINTAINER zhangsan
# 向镜像添加文件(文件与Dockerfile在同级目录)
ADD a.txt /usr/local/src
# 向镜像添加文件(如果是压缩包会自动解压)
ADD nginx-1.17.8.tar.gz /usr/local/src
ADD pcre-8.37.tar.gz /usr/local/src
# 执行命令
RUN yum install -y wget gcc gcc-c++ make openssl-devel
RUN useradd -s /sbin/nologin -M www
WORKDIR /usr/local/src/nginx-nginx-1.17.8
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.37 && make install
RUN echo "daemon off;" >> /usr/local/conf/nginx.conf
# 创建环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
# 声明端口
EXPOSE 80
CMD ["nginx"]

# 开始构建,在Dockerfile文件所在目录执行
# 注意最后的"."为环境上下文,即Dockerfile所在目录 
[root@docker nginx]# docker build -t nginx-file:v1 .

FROM

​ **Specify the base image. **FROM must be the first instruction of Dockerfile

Base images are represented in the format IMAGE:TAG (eg debian:wheezy). If the tag is omitted, it is considered the latest (latest), but it is recommended to set the tag to a specific version to avoid any unexpected things.

MAINTAINER

​Author information.

# 查看作者信息
$ docker inspect -f {
    
    {
    
    .Author}} IMAGE

RUN

​Execute the specified command in

RUN <命令行命令>		# <命令行命令> 等同于在终端操作的 shell 命令

COPY

​ Copy files/directories from the context directory to the specified path in the image.

# 两种格式
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

If there are spaces in the path, the format of the JSON array must be used. Wildcards can be used to specify multiple files or directories.
Note that you cannot specify a src path outside of the context.

ADD

​Copy files from . Since the ADD command covers a wide range of functions, it is generally better to use a relatively simple COPY command to copy the files and directories of the build environment context, and use the RUN command to cooperate with curl or wget to download remote resources (this can also be processed in the same command) and delete downloaded files).
​ If <source path> is a tar compressed file, and the compression format is gzip, bzip2 and xz, the ADD command will automatically decompress the compressed file to <target path>. (All file copies use the COPY command, and only use ADD when automatic decompression is required)

Advantages : If <source file> is a tar compressed file, if the compression format is gzip, bzip2 and xz, it will be automatically copied and decompressed to <target path>.
Disadvantage : Cannot copy tar compressed files without decompressing. Will invalidate the image build cache, which may slow down image builds. Whether to use it or not can be decided according to whether automatic decompression is required.

CMD

** Execute the specified command when the container starts. **If ENTRYPOINT is also defined, this directive will be interpreted as an argument to ENTRYPOINT (in this case, make sure you are using the exec format). The CMD command is also overridden by all arguments following the image name in the docker run command. If multiple CMD commands are defined, only the last one will take effect, and all previous CMD commands will be invalid (including those that appear in the base image).

# 格式:
CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] # (推荐使用)
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数,如果docker run命令行结尾有参数指定,那CMD后面的参数不生效
  • Specify the program to run by default for the started container, and when the program finishes running, the container will end;
  • The program specified by the CMD command can be overwritten by the program to be run specified in the docker run command line parameters;
  • If there are multiple CMD instructions in the Dockerfile, only the last one will take effect.

ENTRYPOINT

​Set an executable (and default parameters) to run when the container starts . Any CMD command or arguments following the image name in the docker run command will be passed as arguments to the executable. The ENTRYPOINT directive is typically used to provide a "startup" script to initialize variables and services before parsing parameters.
​ Similar to CMD, but it will not be overwritten by the commands specified by the command line parameters of docker run, and these command line parameters will be sent as parameters to the program specified by the ENTRYPOINT command.

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

# 把参数指定为容器的入口(entrypoint),覆盖任何 Dockerfile 中的 ENTRYPOINT 指令
$ docker run --entrypoint 

However, if the --entrypoint option is used when running docker run, the parameter of this option can be used as the program to be run to override the program specified by the ENTRYPOINT instruction.
​ When ENTRYPOINT is specified, the meaning of CMD changes. Instead of directly running its command, the content of CMD is passed as a parameter to the ENTRYPOINT command. In other words, when it is actually executed, it will become: ""

ENV

​Set environment variables in the image. (These variables are still available in the image!)

# 格式
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
# 例
... 
ENV MY_VERSION 1.3 
RUN apt-get install -y mypackage=$MY_VERSION 
...

ARG

​Build parameter, same as ENV. But the scope is different. The environment variable set by ARG is only valid in the Dockerfile , that is to say, it is only valid during the docker build process, and this environment variable does not exist in the built image.
​ The build command docker build can be overridden with --build-arg <parameter name>=<value>.

# 格式
ARG <参数名>[=<默认值>]

VOLUME

​Define an anonymous data volume . If you forget to mount the data volume when starting the container, it will be automatically mounted to the anonymous volume.
​ Avoid loss of important data due to container restarts; prevent containers from growing larger.

# 格式
VOLUME ["<路径1>", "<路径2>"...]
VOLUME /data	# 同步主机

EXPOSE

​It is declared in

​ Pass -p/P to do port mapping when building the container. (-P randomly assigns port mapping; -p specifies the mapped port; if EXPOSE does not specify a port, then using the -P parameter is invalid)

# 格式
EXPOSE [port1] [port2] ...

# --expose 与 Dockerfile 的 EXPOSE 指令功能一样。指定容器将会使用的端口或端口范围,但并不会把端口打开。只有与 -P 参数同时使用,以及在连接容器时,才有真正意义
$ docker run --expose [port2]

EXPOSE is just a statement, and the actual use is specified by docker run -p host port: container port or -P.

WORKDIR

​Specify the working directory . Use the working directory specified by WORKDIR, and the current directory of each layer will be changed to the specified directory in the future. If the directory does not exist, it will be newly created.
​ This command can be used multiple times. Relative paths are supported, resolved according to the last defined WORKDIR.

# 格式
WORKDIR <工作目录路径>

# 将参数的路径设置为容器的工作目录。此选项会覆盖 Dockerfile 中的 WORKDIR 指令。
$ docker run -w <工作目录路径>

USER

​Specify the user to execute subsequent commands (RUN, CMD, or ENTRYPOINT) ; this is just to switch the user to execute subsequent commands (users and user groups must already exist in advance).

# 新建用户组及用户
RUN groupadd -r [usergroup] && useradd -r -g [usergroup] [user]
USER [user]

# 设置命令运行时所使用的用户。此选项会覆盖 Dockerfile 中的 USER 指令
$ docker run -u <用户名>

ONBUILD

​Specifies instructions that will be executed when an image is used as a base image for another image . This directive will be useful for manipulating some data that will be added to the submirror (for example, to copy code from a selected directory and use it when executing build scripts)

mirror layer

​ After each instruction in the Dockerfile is executed, a new image layer will be generated, and this image layer can actually be used to start the container. The establishment of a new image layer is to start the container with the image of the previous layer, and then execute the instructions of the Dockerfile to save it as a new image.
​ When the Dockerfile instruction is successfully executed, the container used in the middle will be deleted unless the --rm=false parameter is provided. Since the end result of each command is just a static image, essentially nothing other than a file system and some metadata, even if there are any running processes in the command, they will eventually be stopped. This means that although you can execute some persistent processes in the RUN command, such as database or SSH services, by the time the next command is processed or the container is started, they are no longer running. If you need to run a service or process while starting the container, it must be started from the ENTRYPOINT or CMD command.

View all layers of the mirror

$ docker history [REPOSITORY:TAG or IMAGE ID]
$ docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
ubuntu             1.0.0               acf9ad4cfadd        27 hours ago        197MB
$ docker history ubuntu:1.0.0
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
acf9ad4cfadd        27 hours ago        /bin/sh -c useradd -s /sbin/nologin -M www      329kB
b98e8df8a579        27 hours ago        /bin/sh -c #(nop) ADD file:1513396aa805d712d…   10B
13b66b487594        23 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           23 months ago       /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B
<missing>           23 months ago       /bin/sh -c [ -z "$(apt-get indextargets)" ]     0B
<missing>           23 months ago       /bin/sh -c set -xe   && echo '#!/bin/sh' > /…   195kB
<missing>           23 months ago       /bin/sh -c #(nop) ADD file:276b5d943a4d284f8…   196MB
# 可以运行历史镜像层
$ docker run -it  b98e8df8a579
root@81bbf026a7d6:/#

Image layer debugging

$ cat Dockerfile
FROM busybox:latest 
RUN echo "This should work" 
RUN /bin/bash -c echo "This won't" 

# 尝试构建镜像
$ docker build -t echotest .
Sending build context to Docker daemon 2.048 kB 
Step 0 : FROM busybox:latest 
 ---> 4986bf8c1536 
Step 1 : RUN echo "This should work" 
 ---> Running in f63045cc086b # Docker为了执行指令而创建了一个临时容器,这是该容器的ID
This should work 
 ---> 85b49a851fcc # 这是由该容器所建立的镜像的ID
Removing intermediate container f63045cc086b # 临时容器在这里被删除
Step 2 : RUN /bin/bash -c echo "This won't" 
 ---> Running in e4b31d0550cd 
/bin/sh: /bin/bash: not found 
The command '/bin/sh -c /bin/bash -c echo"This won't"' returned a non-zero 
code: 127

# 运行出问题之前的镜像
$ docker run -it 85b49a851fcc
/# /bin/bash -c "echo hmm"
/bin/sh: /bin/bash: not found 
# 可以更清楚地看到问题的原因:busybox 镜像没有包含 bash shell

data volume

​ Mount the configuration file directory inside the container to the specified directory on the host.

Create a new local path as a container data volume

  • Default mount directory: /var/lib/docker/volumes/
  • If the data volume is an existing directory in the container, the original data in the container volume directory will be copied to the local volume directory
  • You cannot specify a single file, only a directory
# 新建本地路径为容器数据卷
# 启动一个容器:名字叫volume-test1,主机名叫centos,创建并使用的数据卷/data
# -v /data:会在容器内创建/data文件夹
[root@docker ~]# docker run -it --name volume-test1 -h centos -v /data centos
[root@centos /]# cd /data/
[root@centos data]# touch aa.txt	# 在容器/data下新建aa.txt

# 查看对应容器/data挂载的本地卷路径
[root@docker ~]# docker inspect volume-test1 | grep Mounts -A 10
# 或者 docker inspect -f {
    
    {.Mounts}} volume-test1
        "Mounts": [
            {
    
    
                "Type": "volume",
                "Name": "cae4c832ed82a3664611672c61239f7fe80aaf4ca63bfa1cf6c5c14b0c9b600c",
                # Source目录对应这容器volume-test1里的/data目录
                "Source": "/var/lib/docker/volumes/cae4c832ed82a3664611672c61239f7fe80aaf4ca63bfa1cf6c5c14b0c9b600c/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
# 此时在本地_data和容器data的操作,都会互相同步。
[root@docker ~]# ls /var/lib/docker/volumes/cae4c832ed82a3664611672c61239f7fe80aaf4ca63bfa1cf6c5c14b0c9b600c/_data/
aa.txt	# 容器中新建的aa.txt文件; 

Specify the local path as the container data volume

  • If the data volume is an existing directory in the container, the original data of the container volume directory will be hidden; and docker rm -v will not delete the local volume directory
  • A single file or directory can be specified
# -v 本地卷:容器卷; 
# -v /AA:/BB:ro	ro:挂载目录只读
[root@docker ~]# docker run -it --name volume-test1 -h centos -v 本地卷目录:容器卷目录[:ro] centos 

share data

data volume sharing

$ docker run -it --name 容器A --volumes-from 容器B 镜像
# 创建容器volume-test1,拥有数据卷/data
$ docker run -it --name volume-test1 -v /data centos
# 创建容器volume-test4,使用容器volume-test1的数据卷
$ docker run -it --name volume-test4 --volumes-from volume-test1 centos
# volume-test1和volume-test4都拥有数据卷/data,并且数据互通

It should be noted that the previous command will work regardless of whether the container associated with the volume (in the previous example, volume-test1) is running or not. As long as there is at least one container associated with the volume, the volume will not be deleted.

data volume container

Scenario: Dedicate a container as the data volume of other containers.

​ A data volume container is also a container, but its purpose is to provide data volumes for other containers to mount. Replicated volumes always have the same mount point, and the lifecycle of the data volume lasts until no container uses it, similar to an inheritance relationship.

Dockerfile的VOLUME

​ It has the same effect as providing the -v /data parameter when executing docker run.

...
VOLUME /data	# 注意:Dockerfile 中 VOLUME 指令之后的所有指令不会对该数据卷有任何修改
...
# 【设置数据卷权限】
# 下面的 Dockerfile 不会有预期中的效果
FROM debian:wheezy 
RUN useradd foo 
VOLUME /data 
RUN touch /data/x	
RUN chown -R foo:foo /data	

# 正确的写法
FROM debian:wheezy 
RUN useradd foo 
RUN mkdir /data && touch /data/x 
RUN chown -R foo:foo /data 
VOLUME /data

container interconnection

​ Scenario: Containers are interconnected not through ip, but through container names or ids.

Docker links are the easiest way to allow containers on the same host to communicate with each other . When using Docker's default networking model, communication between containers goes through Docker's internal network, which means that the host network cannot see the communication.

# 建立一个与指定容器连接的内部网络接口
$ docker run --link [目标容器的名称]:[目标容器别名]

Connections using Docker also add the target container's alias and ID to /etc/hosts in the main container, allowing the main container to find the target container by name.

connect redis

$ docker pull redis
$ docker run --name myredis -d redis
5985b17fba106fb618e6584fdbc3f38295dd41ee797a9c0a335efd7601d69978

## 连接redis

# 方式1
# 主机上安装 redis-cli连接
$ docker inspect --format {
    
    {
    
    .NetworkSettings.IPAddress}}  myredis	# 获取容器IP
172.17.0.2
$ redis-cli -h 172.17.0.2 -p 6379
172.17.0.2:6379>

# 方式2
# 启动一个新的容器来运行 redis-cli,并把这两个容器连接上
$ docker run --rm -it --link myredis:redis redis /bin/bash
root@854ea635d68d:/data# redis-cli -h redis -p 6379
redis:6379> ping
PONG
redis:6379> set 'a' 123
OK
redis:6379> get a
"123"
redis:6379> exit
root@83400ca186aa:/data# exit
# --link myredis:redis 这个参数告诉 Docker 把新容器与现存的“myredis”容器连接起来;

# 并且在新容器中以“redis”作为“myredis”容器的主机名。为了实现这点,Docker 会在新容器中的 /etc/hosts 里添加一个新条目,把“redis”指向“myredis”的 IP 地址。这样就能够在执行redis-cli 的时候直接使用“redis”作为主机名,而不需想办法找出或传递 Redis 容器的 IP地址给 redis-cli
root@c6b90346ab20:/data# cat /etc/hosts
...
172.17.0.2      redis 5985b17fba10 myredis
172.17.0.3      c6b90346ab20

Docker's connectivity capabilities currently leave a little to be desired. Perhaps the biggest drawback is that the connection can only be static. While the connection should still work across container restarts, if the target container is replaced, the connection will not be updated. Also, the target container must be started before the main container, which means bidirectional connections are not possible.

Access the warehouse ( Repository )

Docker Hub

$ docker login 		# 登录
$ docker logout 	# 退出

find mirror

# 查找官方仓库中的镜像 
# --filter=stars=N  以指定仅显示收藏数量为 N 以上的镜像
$ docker search xx

# 查看自己仓库镜像
$ docker search [Docker Hub用户名]	

pull image

$ docker pull xx	# 下载到本地

push image

# 需要先打tag带上Docker Hub用户名
$ docker tag ubuntu:17.10 username/ubuntu:17.10	# username必须是自己Docker Hub用户名
$ docker push username/ubuntu:17.10		# 推送

Guess you like

Origin blog.csdn.net/qq_41210783/article/details/129755596