关于Docker使用👇
https://yeasy.gitbook.io/docker_practice/container
查看镜像
docker images
删除镜像
docker image rm 镜像名
有些时候会出现不让删除的情况,因为有依赖关系(unable to delete 251b86c83674 (cannot be forced) - image has dependent child images),这是可以强制删除:
sudo docker rmi -f [IMAGE-ID]
查看容器
查看已启动容器
docker container list
docker ps
查看所有容器
docker container ls -a
docker ps -a
停止容器
停止所有容器运行
sudo docker stop $(sudo docker ps -aq)
停止特定容器
docker stop 容器名
启动停止了的容器
docker start <容器ID或名称>
删除容器
删除所有容器
sudo docker rm -f $(sudo docker ps -a -q)
根据镜像创建容器
docker create
命令用于创建一个新的容器,但是不会启动它。你可以通过此命令指定容器的配置,如镜像、命令、环境变量、卷挂载等。
使用格式如下:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
例如:docker create --name containerName imageName
其中:
[OPTIONS]
可以指定网络设置、用户、挂载卷等选项。IMAGE
是你想要创建容器使用的镜像。[COMMAND]
和[ARG...]
是容器启动时要运行的命令及其参数。
创建容器后,你可以使用 docker start
命令来启动它。
根据镜像启动容器
docker run -it -p 9006:9006 --name server webserver:v1 /bin/bash
上面这个例子绑定本机9006端口到容器9006端口,根据镜像webserver:v1生成容器,并启动bash。
增加启动后容器的环境变量:
docker -e ENV_VAR=xxx
如果想后台运行,不用加-it, 换成-d。
保存镜像为tar
要将Docker镜像保存为文件,可以使用docker save
命令将镜像导出为一个tar存档文件。以下是将镜像保存为文件的步骤:
-
打开终端或命令行窗口。
-
运行以下命令以将镜像保存为tar文件:
docker save -o <output_file.tar> <image_name>:<tag>
其中:
<output_file.tar>
是保存的输出文件的路径和文件名,可以自定义。例如,/path/to/output_file.tar
。<image_name>:<tag>
是要保存的镜像的名称和标签。例如,ubuntu:latest
。
例如,将名为
myimage
、标签为latest
的镜像保存为myimage_latest.tar
文件:docker save -o myimage_latest.tar myimage:latest
或者,如果要保存所有标签的镜像,可以使用
<image_name>
来保存整个仓库的镜像:docker save -o myimage.tar myimage
这将将所有标签的镜像导出到
myimage.tar
文件中。 -
执行命令后,Docker将导出镜像并保存为指定的tar文件。
这样,你就可以使用docker save
命令将Docker镜像保存为tar文件,在需要时可以再次使用docker load
命令加载到Docker中。请记住,该文件是一个tar存档文件,可以与其他人共享或在其他计算机上使用。
加载tar镜像
sudo docker load -i ubuntucpp.tar
获取容器元数据
docker inspect : 获取容器/镜像的元数据。
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
OPTIONS说明:
- f :指定返回值的模板文件。
- s :显示总的文件大小。
- -type :为指定类型返回JSON。
查看docker日志
(base) lighthouse@VM-24-9-ubuntu:~$ sudo docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42
minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42
minutes)
sudo docker logs -f [container id]
sudo docker logs [container id]
根据Dockerfile生成镜像
Dockerfile根目录运行:
docker build -t webserver:v1 .
镜像名称为webserver:v1
Dockerfile书写
推荐blog:https://zhuanlan.zhihu.com/p/26904830
一个demo如下:
FROM ubuntu:18.04
ADD ./code/ /server/code
ADD ./CMakeLists.txt /server
ADD ./resources /server/resources
ADD redis-7.0.4.tar.gz /server
ADD hiredis-1.0.2.tar.gz /server
RUN apt-get update
RUN apt-get install -y cmake
RUN apt-get install -y build-essential
RUN apt-get install -y openssl
RUN apt-get install -y libssl-dev
RUN apt-get clean
WORKDIR /server/redis-7.0.4/src
RUN make && make install
WORKDIR /server/hiredis-1.0.2
RUN make && make install
RUN ldconfig
WORKDIR /server
RUN mkdir build
RUN mkdir bin
RUN mkdir log
RUN mkdir redisfiles
RUN mkdir user-msgs
WORKDIR /server/build
RUN cmake ..
RUN make
WORKDIR /server
可以在其中最后添加CMD,在docker run的时候如果不启动/bin/bash就执行CMD,也就无需在进入容器启动自己的服务了。CMD只能添加一条,原则上docker容器的设计原则是一个容器一个进程,但如果想一个容器启动多个进程,可以写一个shell脚本,在其中使用{xxx}&{xxx}&的形式启动多个进程,然后写一个while死循环让shell脚本不退出,之后在Dockerfile中写Entrypoint指向该shell脚本即可。
CMD范例:CMD ["python3", "job_auto_find.py"]
千万别写成CMD python3 xxx.py 这种了,这里是写了个列表。
另外,Dockerfile里不能通过RUN cd xxx,然后理所应当认为之后的语句就在xxx下执行,其实不是这样的,之后的语句还是默认在根目录执行。如果想达到相同效果,应该执行WORKDIR xxx,之后的命令就在该目录下了。
COPY与ADD
ADD 命令的格式和 COPY 命令相同,也是:
ADD <src> <dest>
除了不能用在 multistage 的场景下,ADD 命令可以完成 COPY 命令的所有功能,并且还可以完成两类超酷的功能:
- 解压压缩文件并把它们添加到镜像中
- 从 url 拷贝文件到镜像中
当然,这些功能也让 ADD 命令用起来复杂一些,不如 COPY 命令那么直观。
将宿主机目录挂载到docker目录
docker run -it -v /root/project/ClickHouse-23.4.2.11-stable:/ck iregistry.baidu-int.com/turing/clickhouse-build-base:meg-ubuntu20-clang15-v1.0 /bin/bash
-v来实现,:前面写宿主机目录,后面写要挂载到docker到目录,随后进入容器到指定目录就可以看到挂载的文件了,这种方法修改是会同步的。(挂载更具体讲是将宿主机的文件“替换”容器内的文件,而不是把容器内的文件映射出宿主机,因此在往内挂载时宿主机对应的配置文件要写好,而不是空着)
bind mount 和 docker managed volume
命令上的区别在于前者要写两个路径,一个是host的,一个是容器内部的。而后者只需要写容器内部的,docker会在host自动创建一个目录将容器内对应的文件拷贝到host。
使用场景:
- Docker卷通常用于数据库数据、需要持久存储的应用程序数据等。
- Bind Mounts 通常用于需要让容器访问特定文件或目录的情况,如开发环境中的源代码目录。
注意数据一开始的流向,从容器到host使用managed volume,从host到容器用bind mount。
docker客户端
搜索想要的镜像
启动镜像的时候host填0,系统自动分配一个宿主机端口绑定docker容器端口:
起了一个redis的容器:
可以看到绑定到宿主机的32768端口了:
终端正常使用:
docker compose安装
Docker Compose 是一个用于定义和运行多个容器应用程序的工具。它使用 YAML 文件来配置应用程序的服务、网络和存储等方面,并通过一条简单的命令来启动、停止和管理整个应用程序。
Docker Compose 的主要目标是简化开发、测试和部署多容器应用程序。传统上,创建和管理多个容器需要手动编写 Docker 命令或使用脚本来创建和链接容器。Docker Compose 提供了一个声明式的方式来定义应用程序的服务、环境变量、网络设置以及容器之间的依赖关系。使用 Docker Compose,开发人员可以将整个应用程序定义为一个单一实体,轻松地在多个环境中进行部署、共享和维护。
在一个典型的 Docker Compose 文件中,你可以定义多个服务(service),每个服务都对应一个容器。每个服务可以指定所使用的镜像、环境变量、依赖关系、容器之间的网络连接和卷挂载等配置。通过 Docker Compose,你可以一次性启动或停止所有服务,并可以使用命令行工具来管理、监控和操作容器。
安装:
- 确保已经安装docker
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
docker login
docker login
命令用于用户向 Docker 镜像仓库进行身份验证并登录。在 Docker 中,每个镜像都存储在 Docker 镜像仓库中,并且只有经过身份验证的用户才能访问这些镜像。因此,如果用户想要拉取、推送或管理 Docker 镜像,就需要先使用 docker login
命令进行身份验证以获取访问权限。
具体来说,docker login
命令需要用户提供 Docker 镜像仓库的 URL、用户名和密码等信息,用于验证用户的身份并生成一个身份验证令牌。然后,这个令牌就会被存储在本地的 Docker 凭据存储中,以便在用户向该 Docker 镜像仓库进行后续操作时自动使用。通过 docker login
命令进行身份验证后,用户就可以使用 docker pull
、docker push
、docker tag
等命令来拉取、推送、修改或删除 Docker 镜像。
举个例子,假设用户需要从 Docker 官方仓库中拉取 ubuntu
镜像并使用该镜像来启动容器。在执行这个操作之前,用户首先需要使用 docker login
命令进行身份验证并登录到 Docker 官方仓库,命令如下:
docker login
然后,用户需要使用 docker pull
命令从 Docker 官方仓库中拉取 ubuntu
镜像,命令如下:
docker pull ubuntu
最后,用户可以使用 docker run
命令启动一个新的容器并运行 ubuntu
镜像中的程序,例如:
docker run -it --rm ubuntu /bin/bash
总之,docker login
命令是 Docker 中必不可少的命令之一,可以帮助用户进行身份验证并获取访问权限,为后续的 Docker 镜像操作提供便利。
查看当前登录用户
sudo docker info | grep Username
docker将制作好的容器转为image然后上传docker hub
要将制作好的容器转换为镜像,并上传到 Docker Hub,需要执行以下步骤:
-
提交容器为镜像:
首先,确保你的容器处于停止状态。然后,使用docker commit
命令将容器提交为一个新的镜像。命令的基本格式如下:docker commit <container_id> <image_name>:<tag>
其中
<container_id>
是要提交的容器的 ID,<image_name>
是你要为镜像指定的名称,<tag>
是镜像的标签(可选)。 -
登录到 Docker Hub:
在上传镜像之前,你需要在终端中使用你的 Docker Hub 账号登录到 Docker Hub。使用以下命令:docker login
在提示中输入你的 Docker Hub 用户名和密码。
-
push到docker hub
docker push guangzhengli/hellok8s:v2
docker网络模型
1 )Bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
这里有个比较坑的地方,这个 Docker bridge模式的名字和桥接很像,但是实际上关系不大,Docker bridge模式有点像虚拟机中的 NAT 模式。
2 )Host 模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
这个比较简单,感觉上去就是在网络层面没有隔离容器,当作一个进城来处理,只把其他资源隔离开。
3 )Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
这里其实与 host 模式相比,就是又多划分了一个 namespace,然后将容器放入同一个namespace中,使其共享网络,但是其他资源是隔离的。
4 )None 模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
docker attach & docker exec
docker attach
和 docker exec
是两个用于与运行中的 Docker 容器交互的命令,但它们有不同的行为和用途。
-
docker attach
:docker attach
命令用于附加到一个正在运行的容器的标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)。它会将你的终端连接到容器的主进程,就好像你直接登录到容器一样。- 当使用
docker attach
连接到容器时,你将进入容器的控制台,可以看到容器中的实时输出,但不会创建一个新的 shell 会话。 - 使用
Ctrl + C
可以退出docker attach
,但这会导致容器停止运行,因为它会向容器发送中断信号。
示例:
docker attach <container_name_or_id>
-
docker exec
:docker exec
命令用于在正在运行的容器内部启动新的进程(通常是一个 shell)。它不会连接到容器的控制台,而是在容器内部执行指定的命令,并将命令的输出返回到你的终端。- 使用
docker exec
可以执行多个命令,而且不会影响容器的主进程或容器的运行状态。 docker exec
是更灵活和安全的方式,因为它允许你在容器内部执行命令而不必附加到容器。
示例:
docker exec -it <container_name_or_id> /bin/bash
在总结上,docker attach
用于连接到容器的标准输入/输出,类似于进入容器的控制台,而 docker exec
用于在容器内部执行命令,而不影响容器的运行状态,提供更大的灵活性。选择哪个命令取决于你的具体需求和用例。
docker cp
要将主机上的文件复制到Docker容器内部,可以使用docker cp
命令。以下是将主机文件复制到容器内的步骤:
-
确保Docker容器正在运行。你可以使用
docker ps
命令检查容器状态。 -
使用
docker cp
命令将主机文件复制到容器内。命令的基本语法如下:docker cp <host_path> <container_id>:<container_path>
其中:
<host_path>
是主机上文件的路径(绝对路径或相对路径)。<container_id>
是目标容器的容器ID或容器名称。<container_path>
是容器内的目标路径(绝对路径或相对路径)。
例如,将主机上的
/path/to/host_file.txt
文件复制到容器ID为container1
的容器的/path/to/container_file.txt
路径下:shell docker cp /path/to/host_file.txt container1:/path/to/container_file.txt
注意:如果容器中已存在相同路径的文件,该文件将被覆盖。
使用runlike查看容器创建命令
# 这里使用pip3来安装,因为如果系统里安装了pip2,这时使用pip系统就可能不知道到底是pip3还是pip2了
pip3 install runlike
# 使用docker查看当前容器
docker ps -a
# 使用runlike命令查看
runlike 容器名称
这里pip用的aliyun源可能挂了,换成清华源:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
主要是想找一下mysql 容器的密码来着…
docker备份已启动容器的数据(以mysql为例)
起因:启动mysql容器的时候忘挂载volume了
1.首先停止正在运行的 MySQL 容器。这可以通过以下命令完成:
docker stop my-mysql-container
2.然后备份 MySQL 容器的数据。如果你启动容器时没有挂载数据目录,那么数据是存储在 Docker 的某个匿名卷中的。通过以下命令可以找到这个匿名卷:
docker inspect my-mysql-container | grep -A12 Mounts
上述命令将输出类似以下的内容,其中Source
就是卷在宿主机上的位置:
"Mounts": [
{
"Type": "volume",
"Name": "8ea3...",
"Source": "/var/lib/docker/volumes/8ea3.../_data",
"Destination": "/var/lib/mysql",
...
},
],
3.创建一个新的 docker volume 或选择一个宿主机上存在的目录,然后数据复制到这个新的 volume 或目录。
例如,创建一个新的 docker volume:
docker volume create mysql-data
然后把备份的数据复制到新的 volume :
cp -r /var/lib/docker/volumes/8ea3.../_data/* /var/lib/docker/volumes/mysql-data/_data/
如果你选择了一个宿主机上存在的目录,例如 /home/user/mysql-data
,那么使用以下命令:
cp -r /var/lib/docker/volumes/8ea3.../_data/* /home/user/mysql-data/
4.最后,启动新的 MySQL 容器,并挂载新的 volume 或目录:
docker run --name=my-mysql-container -v mysql-data:/var/lib/mysql -p 3306:3306-e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
如果挂载的是一个宿主机上的目录,那么使用如下命令:
docker run --name=my-mysql-container -v /home/user/mysql-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
上述命令中,mysql-data
和 /home/user/mysql-data
请替换为实际的 volume 名称或目录路径,my-secret-pw
要替换为实际的 root 密码,mysql:tag
要替换为你要使用的 MySQL 版本标签。
docker八股
Docker原理(图解+秒懂+史上最全)_40岁资深老架构师尼恩的博客-CSDN博客
Q&A
**Q:**docker容器之间共享宿主机操作系统,那为什么windows宿主机可以运行ubuntu docker容器呢?
A:
Docker 是基于容器的技术,但它同样提供了一个抽象层,这个抽象层使得在 Windows 上运行基于 Linux 内核的应用程序成为可能。具体的实现方法有两种:Windows Subsystem for Linux(WSL)和 Docker Desktop for Windows。
- Windows Subsystem for Linux (WSL):WSL 在 Windows 内核上实现了一个兼容层,该兼容层可以允许 Linux 二进制可执行文件直接在 Windows 上运行。对于 Docker 来说,WSL 非常有用,因为它允许 Docker 在 Windows 上运行无需任何修改的 Linux 容器。
- Docker Desktop for Windows:对于那些不能使用 WSL 的早期 Windows 版本,Docker Desktop 提供了一个用于运行容器的全功能 Linux 虚拟机。尽管这种方法比使用 WSL 更复杂和资源密集型,但它允许在任何支持 Hyper-V 的 Windows 系统上运行 Docker 容器。
所以,尽管 Docker 容器共享主机操作系统的某些部分(例如内核),但是通过使用 WSL 或 Docker Desktop 这样的工具,Windows 主机上可以运行基于其他操作系统(如 Ubuntu)的容器。
需要注意的是,Windows 容器只能运行在 Windows 主机上,Linux 容器只能运行在 Linux 主机或使用了上述技术的 Windows 主机上。