【Docker之轨迹】Docker 入门使用(穿插踩坑经历)


1. 安装 Docker

① 查看服务器环境

cat /etc/os-release:查看系统内核版本(确认在 3.10 以上)
uname -r:查看服务器版本

② 卸载旧的 docker(确保没有下载)

yum remove docker \
           docker-client \
           docker-client-latest \
           docker-common \
           docker-latest \
           docker-latest-logrotate \
           docker-logrotate \
           docker-engine

在这里插入图片描述
显示这个,说明系统中并没有安装旧的 docker,可以进行安装

③ 修改 docker 镜像

# 安装需要的工具包
yum install -y yum-utils
# 设置镜像仓库(默认是国外的)
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

在这里插入图片描述
④ 更新 yum 索引,并安装启动与使用最新的 docker

yum makecache fast

——— 404 错误处理 ———
▲ 如果使用的服务器是(Aliyun Linux 2.1xxx),是这里就有一个巨坑(不是的话请跳过)
在执行这段命令时,会出现一下报错

https://mirrors.aliyun.com/docker-ce/linux/centos/2.1903/x86_64/stable/repodata/repomd.xml: [Errno 14] HTTPS Error 404 - Not Found

起初认为时镜像出问题了,一番查找后,发现时版本出现了问题
这种阿里云的服务器,$releasever 值为 2.1xxx,而 centOS7 的该值为 7
这就导致了版本匹配不上,安装失败
这时,我们只需要将 /etc/yum.repos.d/docker-ce.repo 这个文件夹中的 $releasever 全部替换为 7 ,就可以正常执行了!
附上全局修改命令::%s/$releasever/7 (将所有的 $releasever 替换为 7)
——— 404 处理结束 ———

接下来是安装指令(会由选项,一直 y 就可以了),接着是启动指令与基本使用

安装:yum install docker-ce docker-ce-cli containerd.io

启动:systemctl start docker
验证是否启动成功:docker version
有显示内容,就表示已经启动成功了

基本使用:docker run hello-world
首次使用会出现 Unable to find image 'hello-world:latest' locally 找不到镜像,等它下载完就好了
查看已经安装了的镜像:docker images
	REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
	hello-world   latest    d1165f221234   6 months ago   13.3kB
就可以看到刚刚安装的 hello-world 镜像了

⑤ 卸载 docker
需要卸载时,需要卸载依赖以及资源

# 1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io

# 2. 删除资源(其中 /var/lib/docker 是 docker 的默认工作路径)
rm -rf /var/lib/docker

2. Docker 基本使用

① 镜像命令

1) 查看所有镜像
docker images

2) 搜索镜像
docker search xxx

3) 下载镜像(加上 tag 可以指定版本,不写默认是 lastest 最新
docker pull <镜像名>[:tag]

4) 删除镜像(后面可跟多个名字或者id,同时删除多个镜像)有以下两个
镜像 id 可以取前 n 个(一般 3 个就可以了),只要能唯一找到一个镜像即可
docker rmi [-f] <名字/id>
docker image rm <名字/id>

5) 删除全部镜像($ 中的命令为列出所有 docker 的 id,然后批量删除)
docker rmi -f $(docker image -aq) 

② 容器命令

可以先下载一个 centos 来测试,然后启动容器
docker pull centos

1) 创建并启动容器(注意和下边 docker start 的区别哦)
docker run [选项] <镜像名>
--name="xxx"	给容器起名字
-d		后台方式运行
-i		使用交互式方式运行(让容器的标准输入保持打开)
-t		为容器分贝一个伪终端,并绑定到标准输入上(一般联合使用为 -it)
-p		指定容器的端口
		可以是(主机端口:容器端口,如 8080:8081,将主机 8080 端口映射到容器的 8081 端口)
		也可以直接写容器端口
-P		随机指定端口
	————————
	测试一波(后边的 /bin/bash 是为 -it 交互式指定控制台)
	docker run -it --name='myCentos' centos /bin/bash
	
	接下来就是套娃了~
	可以在这个 centos 容器中做原本服务器可以做的事
	比如前面的
		cat /etc/os-release:查看系统内核版本
		uname -r:查看服务器版本
	内部的这个 centos 和外部我们自己的服务器没有关系,隔离开来了,可以随便玩
	————————
	
2) 退出容器
exit			退出容器,如果容器没有被使用,会自动停止
Ctrl + P + Q	容器不停止并退出,仍和情况下不会停止容器

3) 查看所有运行的容器
docker ps [选项]
-a		加上曾经运行过的容器
-n=?	列出最近的 n 各容器

4) 删除容器(在运行中的容器,需要加上 -f 才能成功删除)
docker rm [-f] <容器id>

5) 进入正在运行中的容器
docker exec <id> 
	可使用 docker exec -it <id> /bin/bash 交互式进入,会新开一个终端
	由于新开了一个终端,故使用 exit 后,原容器并不会停止哦(比较推荐使用)
docker attach <id>(进入容器当前终端)
	
6) 容器四件套
docker start <id>	启动容器(要求容器已经被创建)
docker restart <id>	重启容器
docker stop <id>	停止容器
docker kill <id>	强制停止容器

7) 从容器中拷贝东西到主机上
docker cp <容器id>:<容器内路径> <目前主机路径>

2021-10-1

1) 从主机复制文件(夹)到容器
docker cp <主机路径> <容器id>:<容器路径>

2) 从容器复制文件(夹)到主机
docker cp <容器id>:<容器路径> <主机路径>

③ 辅助命令

1) 显示 docker 版本信息
docker version

2) 显示 docker 详细信息,包括了镜像和容器的数量等等
docker info

3) 查看帮助文档,中间 加上指定命令,可以看到相应命令的帮助c
docker [命令] --help

4) 查看日志
docker logs [选项] <容器id>
-f	动态显示日志(和 tail -f 一样功能)
-t	显示时间戳

5) 查看进程信息
docker top <容器id>

6) 查看容器内部信息
docker inspect <容器id>

7) 提交自己的镜像
docker commit -a="作者" -m="描述信息" <容器id> <镜像名>

2021-10-1

1) 查看 docker 占用的空间
包括井下镜像、容器、数据卷和缓存
加上 -v 可以看到更详细的信息
docker system df [-v]

3. 容器数据卷

之前将应用和环境打成一个包后,数据也一并存放在容器中了
这样将直接导致数据随着容器的删除而一起销毁
所以如果我们希望数据可以分离出来,保存在本地,就需要用到数据卷了

数据卷特性:

  1. 可供一个或多个容器使用,实现容器之间数据的共享和重用
  2. 对数据卷的修改会立即生效
  3. 数据卷将一直存在,即使容器被删除

① 基本操作

1) 查看所有数据卷
docker volume ls

2) 查看指定数据卷的信息
docker volume inspect <数据卷名>

3) 删除数据卷
docker volume rm <数据卷名>
如果想在删除容器时顺便删除数据卷,可使用
docker rm -v
也可以清理无主的数据卷(没有容器使用,但可能该数据还有用,考虑后使用)
docker volume prune

4) 在启动时挂载一个数据卷,两种方式
docker run -v <主机路径>:<容器路径>
docker runb --mount source=<数据卷名>
区别是,-v 会自动创建不存在的文件夹,而 --mount 在文件夹不存在时会抛出错误

例如以下,将 tomcat 的日志文件夹。挂在到主机的指定目录中
docker run -it -v /home/iceclean/docker/tomcat-log:/logs/ tomcat /bin/bash

挂在完毕后,主机和容器任意一个修改,对方该目录下也会相应生成文件,这样,当容器被删除时,数据也会被安全的保存在服务器主机中

② 向已经启动的容器挂载数据卷

具名挂载与匿名挂载
前边的操作,是直接映射了地址,在实际开发中也可以让数据卷存放在 docker 统一的目录下
-v 后面,不写主机目录,默认就是匿名挂载,名字是一串编码
将主机名字写成数据卷名字(区别在于最前面不带 / 号),就可以在统一目录下生成一改名字为文件夹的数据卷


4. DockerFile

dockerfile 是用来构建 docker 镜像的文件
在该文件中,每一个命令就是一层,基本命令如下

① FROM 指定基础镜像 <必须有>

该镜像以一个镜像作为基础,所以首先得有一个基础的镜像(FROM 引入)再进行我们自己个性化的处理
如果不想以任何镜像作为基础,可以使用 FROM scratch,其中 scratch 表示一个虚拟的进项,并不实际存在,是一个空白的镜像

② RUN 执行命令

RUN指令可以用来执行命令行命令,再构建镜像中是经常用到的,其格式有两种

  1. shell 格式:RUN 命令,就像直接再命令行输入命令一样
  2. exec 格式:RUN [“可执行文件”, “参数1”, “参数2” …],这可以启动一个可执行文件

由于每个命令是一层,在执行该命令时,都相当于启动一个容器,然后执行命令
所以如果将 RUN 命令分开写,将会导致层数激增,每次都启动一个新的容器执行一个命令
这将增加部署时间,所以在编写 RUN 命令时,一般做如下改进

RUN touch /usr/local/test.txt
RUN echo 'test' > /usr/local/test.txt
RUN cp /usr/local/test.txt /var/

这样写就相当于三层,但实际上只做了一层的工作量,可以简化为一层,如下
RUN touch /usr/local/test.txt \
	echo 'test' > /usr/local/test.txt \
	cp /usr/local/test.txt /var/

这里还有一个值得注意的点
由于每一个 RUN 都时新开一个容器,所以命令之间是不会互相作用的,如
	RUN cd /xxx
	RUN cat xxx.txt
这两行命令分开写,将直接导致 xxx.cat 并非在 /xxx 目录下寻找,而是在工作目录中寻找
为了避免出这种错误,就更应该写成一层了,如下
	RUN cd /xxx \ cat xxx.txt

通过这两步就可以构建简单的镜像啦
执行 docker build -f <文件所在路径> .

注意:命令的最后有一个 .,该点指定了上下文路径,docker build 命令会将该目录下的文件打包交给 Docker 引擎以协助构建镜像

除此之外,dockerfile 还有很多肺功能强大的命令

③ ENV 设置环境变量

④ VOLUME 挂载匿名卷

该命令可以实现指定容器数据存放的位置,避免当用户没有指定数据卷时,容器中的数据直接写在了容器的存储层中破坏掉容器的无状态化

将容器里 /data 中的数据挂载到服务器主机中
任何向 /data 中写入的信息不会被记录到容器的存储层中,而是保存在服务器主机中
当然,用户在运行容器时也可以手动指定覆盖这个设定
VOLUME /data

⑥ EXPOSE 声明暴露端口

格式为 EXPOSE <端口1> [端口2 端口3 ...]
该指令可以声明容器运行时提供服务的端口
注意:该指令只是一个声明,并不会真正开启这个端口的服务,当用户使用 -P 进行随机端口映射时,会自动映射到这个端口。同时也是方便用户的配置,告知用户建议配置那个端口

⑦ WORKDIR 指定工作目录

格式为:WORKDIR <工作目录路径>
指定后,各层的当前目录会被改成指定的目录(即第一次进入时,就在该目录里边)
目录如果不存在,会自动创建一个

5. Docker 网络

网络模式

  • bridge:桥接模式(默认)
  • none:不配置网络
  • host:和主机共享网络
1) 查看所有的 docker 网络
docker network ls

2) 指定网络(不写 --net xxx,默认为桥接模式)
docker run [--net bridge] <容器名>

6. 自定义脚本安装 Docker

…待


7. 旅行者日记

① 该死,容器里边命令不全,咋整

按照查到的方案,执行以下命令:

更新资源
apt-get update

安装 ping 命令
apt-get install iputils-ping

安装 ps 指令
apt-get install procps

接着出现了下一个问题,容器连不上网?(请往下看)

② docker 端口映射后,外网访问不到

描述:
阿里云安全组和服务器防火墙都打开了对应的映射端口,服务器内可以通过 localhost:xxxx 可以正常访问到容器,但外网却怎么页访问不到

一番查找后,发现了一个大问题:容器内部连接不上网络
在容器中使用 ping 命令无反应(服务器主机可以)

然后按照网上说法,是 docker 的默认网段和阿里云服务器的网段冲突了
所以对 docker 的网桥进行了如下修改:

service docker stop 
ip link set dev docker0 down 
brctl delbr docker0 (这里需要进行下载 yum install bridge-utils)

然后修改 /etc/docker/daemon.json 文件(如果没有的话新建),改为以下
{
”bip“:"192.168.100.1、24"
}

		————————
		中间出现了小插曲
		要启动 docker 时,报以下错误
		# Job for docker.service failed because the control process exited with error
		# Failed to start Docker Application Container Engine
		使用所有的 docker 命令,都报
		# Cannot connect to the Docker daemon at unix:///var/run/docker.sock

		后来发现,是该文件写的不对,和其他配置冲突了
		由于情况很多,这里视情况修改这个文件即可,不需要改动其他
		————————

修改完毕后,执行
systemctl daemon-reload
systemctl restart docker

但是发现还是 ping 不通… 枯了

再一番尝试,发现当容器网络设置为 host 时,容器内部可以联网,如

docker run -it --network=host tomcat /bin/bash

		———— 插曲 ————
		当使用 host 网络可以联网后,这时端口已经和主机是共用的了
		所以诸如 tomcat,nginx 都不能使用默认端口了
		于是我将 nginx 端口修改(阿里云安全组与服务器防火墙已打开)
		但发现外网依旧无法访问容器???
		最后发现,在手机上可以,而不基本不行
		唯一的区别就是,笔记本使用了 VPN ,而收集没有
		是否因为 VPN 导致了访问不了容器?又该怎么解决?

		后来的后来,发现不是 VPN 的问题,换成 tomcat 没问题可以正常访问
		但是奇了怪了,在服务器可以通过域名+端口访问 nginx,为什么到浏览器就不行了呢
		命名 tomcat 也是一样的操作,放到浏览器却可以?
		———— 插曲 ————

到这里已经基本上可以确认,是网桥模式的问题,使得容器无法通过外网访问
… 等我

2021-9-30 联网问题解决了
就在今天,我发现服务器的端口号既然跑到了 10w+,服务器直接崩溃了
很纳闷,端口号的上限,不应该是 65535 嘛?为什么会这样(附上之前很疑惑的一张截图)
请添加图片描述
可以看到此时的 PID 已经到了 7w+ 不知道是什么原因
但就在服务器重启之后,所有的容器内,都能 ping 通了
以前只有指定 --network=host 才能使容器 ping 同外网,现在无论什么操作都 ok 了

仔细检查了配置文件,发现和上边写的一样,难道是必须服务器重启后这它生效吗?
明显不是的,之前重启 docker 时,使用 ifconfig 已经看到它生效了

嘛,虽说问题总算解决了,但又留下了两个坑:
为什么端口号超过了 65535,直到 10w+ 时服务器才崩溃?
为什么 docker 容器突然就能访问外网了?
…继续等我


我一定会回来的 -_-(IceClean)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒冰小澈IceClean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值