Docker最新学习
Docker学习
-
参考网址:
https://zhuanlan.zhihu.com/p/1892960016316748037 -
1-docker-image.png
-
镜像(Image): 就好比一个模板,我们可以通过这个模板来创建容器服务
- 这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
-
容器(container): 独立运行一个或者一组应用,可以理解为就是一个简易的linux系统!
- 通过
镜像来创建启动,停止,删除,基本命令
- 通过
-
仓库(repository): 存放
镜像(image)的地方!- 可以分为
公有仓库和私有仓库
- 可以分为
Linux用户权限相关
sudo docker run hello-world # 临时方案
# 将当前用户添加到 docker 组(推荐方案)
sudo usermod -aG docker $USER
# 重新登录或刷新组权限
newgrp docker
# 或者注销后重新登录系统,验证是否成功
groups
第一个例子(Docker安装过程略)
- docker run hello-world
[anning@localhost ~]$ docker run hello-world
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/
- 流程图如下
flowchart TD
A[开始] --> B[Docker会在本机寻找镜像]
B --> C{判断本机是否有这个镜像}
C -- 有 --> D[使用这个镜像运行]
C -- 没有 --> E[去Docker Hub上下载]
E --> F{Docker Hub查看可以找到}
F -- 找到 --> G[下载这个镜像到本地]
G --> D
F -- 找不到 --> H[返回错误,找不到镜像]
D --> I[结束]
H --> I
Docker底层原理
-
docker的架构模式(如何工作)
Docker 是一个Client-Server结构的系统,Docker的守护进程运行在主机上。
通过Socket从客户端访问!
DockerServer 接收到Docker-Client的指令,就会执行这个命令!
flowchart TD
A[客户端] --> B[Linux服务器]
C[客户端] --> B
B --> D[后台守护进程]
D --> E[Docker容器<br>这好比是一个小的linux虚拟机<br>localhost:8080]
D --> F[Docker容器<br>这好比是一个小的linux虚拟机<br>localhost:3306]
- 好比一个餐厅的运作方式:
- 厨师(Docker守护进程)在厨房(主机)里工作,他负责实际做菜(运行容器)。
- 你(客户端)通过服务员(Socket)点菜(发送指令)。
- 服务员(Socket)将你的点菜(指令)传递给厨师(Docker守护进程)。
- 厨师(Docker守护进程)根据点菜(指令)开始做菜(执行命令)。
- 具体到技术细节:
- Docker守护进程(Docker Daemon)运行在主机上,它负责管理Docker对象(镜像、容器、网络、卷等)。
- 客户端(Docker Client)可以是命令行工具(docker命令)或其他使用Docker API的客户端。
- 客户端通过Socket(可以是本地Socket或网络Socket)与守护进程通信。
- 当守护进程收到客户端的指令(如docker run)时,它就会执行相应的操作。
- 好处: 这种结构的好处是,客户端和守护进程可以运行在同一台机器上,也可以分开运行(比如远程管理)。
graph LR
A[Docker Client<br>客户端] --> B[Socket<br>通信接口]
B --> C[Docker Daemon<br>守护进程/服务端]
C --> D[执行命令<br>管理容器/镜像]
- Docker加速镜像
这个错误是因为 Docker 无法连接到 Docker Hub 镜像仓库,通常是网络连接问题。以下是几种解决方案:
1. 配置国内镜像源(推荐)
创建或修改 Docker 配置文件:
# 创建 Docker 配置目录
sudo mkdir -p /etc/docker
# 配置国内镜像源
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com",
"https://mirror.baidubce.com"
]
}
EOF
2. 重启 Docker 服务使配置生效
# 重新加载配置并重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 检查配置是否生效
docker info
在输出中应该能看到配置的镜像地址。
3. 验证网络连接
# 测试网络连接
ping docker.mirrors.ustc.edu.cn
ping hub-mirror.c.163.com
# 测试 Docker Hub 连接
curl -I https://registry-1.docker.io/v2/
4. 临时使用代理(如果网络环境需要)
# 设置环境变量使用代理(根据实际情况修改)
export HTTP_PROXY=http://your-proxy-server:port
export HTTPS_PROXY=http://your-proxy-server:port
docker run hello-world
5. 手动下载镜像并导入
如果上述方法都不行,可以尝试手动下载:
# 从其他渠道下载 hello-world 镜像
# 或者找一台能正常访问的机器导出镜像
docker save hello-world > hello-world.tar
# 在本地导入
docker load < hello-world.tar
6. 测试镜像拉取
配置完成后,重新测试:
# 先删除可能损坏的镜像(如果有)
docker rmi hello-world
# 重新拉取并运行
docker run hello-world
常用的国内镜像源地址:
- 中科大:
https://docker.mirrors.ustc.edu.cn - 网易:
https://hub-mirror.c.163.com - 阿里云:
https://<你的ID>.mirror.aliyuncs.com(需要注册) - 百度云:
https://mirror.baidubce.com
如果问题仍然存在:
检查系统防火墙和网络设置:
# 检查防火墙状态
sudo systemctl status firewalld
# 如果防火墙开启,添加 Docker 相关规则或暂时关闭测试
sudo systemctl stop firewalld
通常配置国内镜像源就能解决这个问题。
- Docker的一些实用配置
# 使用 systemctl 启动 Docker 服务
sudo systemctl start docker
# 设置 Docker 开机自启(可选)
sudo systemctl enable docker
# 检查 Docker 服务状态
sudo systemctl status docker
# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER
# 重新登录或执行以下命令使分组生效
newgrp docker
# 或者注销后重新登录
- 常用命令
docker 命令 --help # 帮助命令
docker images
docker search (搜索镜像)
docker pull 镜像名[:tag]
docker rmi (删除镜像)
解决刚安装Docker各种毛病排除方法
# 1. 确保系统更新到最新(这步最关键)
sudo yum update -y
# 2. 安装必要依赖
sudo yum install -y device-mapper-persistent-data lvm2
# 3. 确保没有冲突的包
sudo yum remove -y docker docker-common docker-selinux docker-engine
# 4. 添加Docker官方仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 5. 安装Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 6. 配置Docker守护进程
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
# 7. 重新加载并启动
sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl start docker
Demo示例演示
- 安装
Centos7并测试效果
- docker pull centos:7 # 精简版的centos,很多命令都木有...
......
- docker run -it centos:7 /bin/bash # 进入容器,测试
......
- exit # 退出容器,回到物理机
- 学习点:
-it和-d
-it: 交互式前台运行模式,会立即进入容器的bash shell,可以交互式地输入命令
- 容器状态:在前台运行,直到你输入exit或Ctrl+D退出
-d: 后台运行模式, 容器在后台启动并立即退出,因为bash没有前台进程保持运行
- 通常不适合直接运行bash,更适合运行服务进程
- 常见的坑:docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止。
比如:nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
- 示例演示
# 正确的方式:进入容器进行操作
docker run -it centos:7 /bin/bash
# 或者先后台运行,再进入
docker run -d --name mycentos centos:7 tail -f /dev/null
docker exec -it mycentos /bin/bash
# 交互式 + 后台(退出时不停止容器)
docker run -itd --name mycontainer centos:7 /bin/bash
# 然后可以随时进入
docker exec -it mycontainer /bin/bash
# 或者
docker attach mycontainer
- 常用命令
- docker ps
- docker ps -a # 包含历史记录
- docker container ls
# 退出容器
exit # 容器直接停止,并退出
ctrl+P+Q # 容器不停止,退出
[root@JWei_0124 //]# docker run -it centos /bin/bash //交互式进入
[root@68b68a9576e0 /]# [root@JWei_0124 //]# //按快捷键 自动输入
[root@JWei_0124 //]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68b68a9576e0 centos "/bin/bash" 2 minutes ago Up 2 minutes peaceful_jemison
[root@JWei_0124 //]#
- 此时想停止容器: docker stop 68b68a # 若执行成功,会返回被停止的容器ID,例如68b68a
# 查看容器中的进程信息: docker top ID
[root@JWei_0124 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25eb9d70b2b4 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp awesome_chatterjee
[root@JWei_0124 ~]# docker top 25eb9d70b2b4
UID PID PPID C STIME TTY TIME CMD
systemd+ 181442 181422 0 09:47 ? 00:00:00 redis-server *:6379
# 查看镜像的元数据(配置信息)
docker inspect containerID
{
......# 一堆的json配置信息,描述镜像的各种信息
}
Docker练习: 从容器内拷贝文件到主机: docker cp 容器id:容器内路径 目的主机的路径
# 进入到容器内部
[root@iZbp13qr3mm4ucsjumrlgqZ home]# docker attach 6eda31ad7987
[root@6eda31ad7987 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@6eda31ad7987 /]# cd /home/
[root@6eda31ad7987 home]# ls
# 在容器的/home路径下创建test.java文件
[root@6eda31ad7987 home]# touch test.java
[root@6eda31ad7987 home]# ls
test.java
# 隐式退出
......
[root@iZbp13qr3mm4ucsjumrlgqZ home]# docker cp 6eda31ad7987:/home/test.java /home
[root@iZbp13qr3mm4ucsjumrlgqZ home]# ls
test.java
# 拷贝是一个手动过程,未来我们使用 -v 卷的技术,可以实现,自动同步(容器内的/home路径和主机上的/home路径打通)
Docker图形化工具---portainer
# 8088 外网访问端口 9000 是内部映射端口
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- 访问: http://yourIP:8088
数据卷介绍(Volumn)
- 作用: 在
主机和容器之间实现共享目录- 注意事项:
卷完全独立于容器的生命周期,意味着即使容器被停止或者删除,卷的数据依然坚挺,保持持久化! - 我们在本地修改数据,会自动同步到容器里面(即使容器被停止,也不会被影响到)
- 注意事项:
- 语法:
docker run -it -v 主机目录:容器目录
- docker run -it -v /home:/home centos:7 /bin/bash # 把主机和容器的home目录进行映射共享
- 在容器的home目录下,新建test666.java,再返回物理机的home目录,发现也新建了一个test666.java文件
- docker inspect 容器ID # 关注Mounts配置项
......
Mounts:[{"Source":"/home","Destination":"/home"}] # 源地址(物理机目录)---目标地址(容器目录)
......
- dokker volume ls # 查看所有的数据卷
- docker volume inspect your-vol # 查看指定数据卷的信息
- docker volume rm your-vol # 删除指定数据卷的信息
- docker volume prune # 清理无主的数据卷
- 使用"--mount"挂载一个指定的本机目录到容器里面去
# 挂载主机的/src/webapp目录到容器的/opt/webapp/目录(默认读写权限,只读权限添加readonly)
- docker run -d -P --name web --mount type=bind,source=/src/webapp,[readonly] target=/opt/webapp training/webapp
具名挂载和匿名挂载
- 匿名挂载: 不指定主机路径,而使用主机的默认路径
- 语法:
-v 容器内路径
- 语法:
- /var/lib/docker/volumes/随机命名文件夹 # Docker所有的数据卷默认在/var/lib/docker/volumes/ 目录下
- 运行并匿名挂载Nginx容器示例
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx # /etc/nginx nginx是容器路径
d3a27b969d122d5516cac75e99b17dff7aaaf1e0c042385c6b05990053f1259
- 此时查看所有的数据卷volume的情况, VOLUME NAME这里的值是真实存在的目录
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker volume ls
DRIVER VOLUME NAME
local 0cd45ab893fc13971219ac5127f9c0b02491635d76d94183b0261953bdb52d26
local 668a94251e562612880a2fdb03944d67d1acdbbdae6ef7c94bee8685644f2956
local e605f3dc4bf11ab693972592b55fb6911e5bf2083425fd58869c5f574998a09a
- 具名挂载: 就是指定文件夹名称(区别于指定路径挂载)
- 语法:
-v /宿主机路径:容器内路径 - 注意,该文件夹是在Docker指定的默认数据卷路径下的
- 语法:
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
4ceaff19e5275dcd3014a8e7a8af618f7f7ce0da18d605c7c41a8653e78bf912
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker volume ls
DRIVER VOLUME NAME
local 0cd45ab893fc13971219ac5127f9c0b02491635d76d94183b0261953bdb52d26
local 668a94251e562612880a2fdb03944d67d1acdbbdae6ef7c94bee8685644f2956
local e605f3dc4bf11ab693972592b55fb6911e5bf2083425fd58869c5f574998a09a
local juming-nginx
- 查看指定的数据卷信息的命令:docker volume inspect 数据卷名称
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-12-29T22:40:25+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # 挂载在主机上面的目录
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
- 指定数据卷映射的相关参数:
- ro —— readonly 只读。设置了只读则只能操作宿主机的路径,不能操作容器中的对应路径。
- rw ----- readwrite 可读可写
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
容器数据卷
- 作用: 建立数据卷,来同步多个容器间的数据,实现容器间的数据同步
# 1. 创建第一个容器,并指定数据卷(如果镜像中没有定义的话,这里数据卷指定为新建的shared-data目录)
docker run -it --name centos01 -v /shared-data centos:7
# 命令执行完,ls查看,果然新增了shared-data目录
# 2. 创建第二个容器,共享第一个容器的数据卷
docker run -it --name centos02 --volumes-from centos01 centos:7
# 命令执行完,ls查看,也新增了shared-data目录
# 3. 在第一个容器中创建文件
docker exec centos01 touch /shared-data/file.txt
# 4. 在第二个容器中查看文件(存在file.txt文件)
docker exec centos02 ls /shared-data/
DockerFile
- 作用: 构建docker镜像的文件,是命令参数脚本!
- 构建步骤
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run运行镜像
- docker push发布镜像(DockerHub、阿里云镜像仓库!)
- 命令参数如下
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的:姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile这个时候就会运行ONBUILD的指令。触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
- 命令脚本演示
# 1. 编写ockerfile的文件
FROM centos:7
MAINTAINER sywl<xxx@qq.com>
ENV MYPATH /usr/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 -t mycentos:0.1 .
Successfully built 285c2064af01
Successfully tagged mycentos:0.1
# 我使用的是(由于网络问题,构建没有成功): docker build -t sys:centos77 .
- 最后查看镜像是否正常: docker images
危险的删除命令
docker rm -f $(docker ps -aq) # 停止容器并删除
# 先查看所有容器
docker ps -a
# 确认后删除所有容器
docker rm -f $(docker ps -aq)
# 只删除已退出的容器
docker rm $(docker ps -q -f status=exited)
# 删除创建时间超过24小时的容器
docker container prune --filter "until=24h"
# 先查看所有容器
docker ps -a
# 然后只删除特定的容器
docker rm -f 容器ID1 容器ID2 容器ID3

浙公网安备 33010602011771号