1. 安装Docker
1)基础环境配置
- 安装yum源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
清除 & 新建缓存
yum clean all
yum makecache
- 安装epel源
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
- 查看enforce状态
getenforce
2)安装Docker
- 开启Linux内核的流量转发
利用cat和重定向实现文件写入
[root@localhost tester]# cat <<EOF > /etc/sysctl.d/docker.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.conf.default.rp_filter = 0
> net.ipv4.conf.all.rp_filter = 0
> net.ipv4.ip_forward = 1
> EOF
- 加载修改内核的配置文件
sysctl -p /etc/sysctl.d/docker.conf
若出现以下提示:No such file or directory,可按通过以下命令解决
[root@localhost tester]# modprobe br_netfilter
[root@localhost tester]# sysctl -p /etc/sysctl.d/docker.conf
- yum仓库检查
由于此处是通过yum安装docker,则需提前配置好yum仓库
(1. 阿里云自带仓库; 2. 阿里云提供的docker专属repo仓库)
首先查看是否存在可用版本
yum list docker-ce --showduplicates | sort -r
目前yum仓库是没有可用的包的,则可以用阿里云yum源下载repo文件
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
sudo curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# or: sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
重新生成一下缓存就可以下载docker-ce了
- docker安装
# 此处安装20.10.6版本
yum install docker-ce-20.10.6 -y
## 安装旧版本
# yum install -y docker-ce-18.09.9
## 卸载(指定版本)
# yum remove -y docker-xxxxxx
- 配置docker加速器
由于docker hub 站点在国外,可以配置加速器
首先查看是否存在daemon.json文件
touch /etc/docker/daemon.json
若没有,可以通过mkdir生成该文件
通过vim添加以下代码
{
"registry-mirrors" : [
"https://8xpk5wnt.mirror.aliyuncs.com"
]
}
保存后,按顺序执行以下代码
# 由于修改了配置文件,先reload一下
systemctl daemon-reload
# 设置开启自动启动
systemctl enable docker
# 重启docker
systemctl restart docker
此时查看docker进程,显示已经有相关进程了
查看docker容器和镜像文件
# 查看容器
docker ps
#查看镜像文件
docker images
还可以通过docker version
查看docker版本.
2. Docker 的基本使用
此处以nginx为例(由于镜像加速一直存在timeout的问题,博主此处仅通过临时换源的方式拉取镜像)
1)获取镜像
获取镜像,从配置好的docker镜像站中,拉取镜像
sudo docker pull docker.m.daocloud.io/nginx
再通过docker images
可查看已有的镜像
若想删除已有镜像,可通过docker rmi
结合Image id
删除(Image ID
指定前三位也可)
docker rmi 74cc54e27dc4
需注意,被删除的镜像不能有依赖的的容器记录
2)运行镜像&容器
运行镜像,运行出具体的容器,在该容器中就可以跑着nginx服务了
# docker run [[Params], Image Name/ID]
# -d: 后台运行容器
# -p 80:80 端口映射,宿主机端口:容器端口
docker run -d -p 80:80 4e1b6bae1e48
运行前,通过netstat -tunlp
查看,目前是没有80端口运行的
运行后,返回的值为容器的ID
也可以通过docker ps
查看该容器的信息
可以看到该容器是基于镜像4e1b6bae1e48产生的,端口是80映射到80,容器name是goofy_blackwell
再次通过netstat -tunlp
查看,现在已经有80端口在运行了
此时在宿主机上访问80端口,也是已经可以看到nginx了
3)停止/启动 容器
最后,还可以通过docker stop/start 容器id
停止/运行 容器
4)通过docker快速切换发行版
通过docker,切换不同的发行版,使用不同的【系统】(内核使用的都是宿主机的内核)
首先利用docker pull
下载centos和ubuntu的镜像,并查看当前宿主机内核版本
我们目前使用的宿主机内核是centos7.9,且有一个7.8的centos的镜像,以及一个latest的ubuntu镜像
然后通过docker run
运行容器,进入容器内
## 参数解释
# -i: 交互式命令操作 -t: 开启一个终端 afb6fca791e0: centos7.8的Image id
# bash: 进入容器后执行的命令
docker run -it afb6fca791e0 bash
再通过cat /etc/redhat-release
查看内核,发现版本号已经变成了7.8.2003
此时若想切换成ubuntu,需先通过exit
退出当前容器,再通过docker run
进入ubuntu容器
且由于进入的已经变成了ubuntu发行版,查看版本号的命令行也许发生改变
3. Docker的镜像管理
1)查看docker镜像目录
通过docker info
可以查看docker具体的信息,还可以通过docker info |grep Root
找到根目录位置
具体的docker镜像会存放在该根目录下的/var/lib/docker/image/overlay2/imagedb/content/sha256
中
我们会看到这里显示的ID是和docker images
下显示的Image ID
是一一对应的
2)查看镜像
-
只列出镜像id
docker image -q
-
格式化显示镜像
docker images --format "{{.xxx}}--{{.xxx}}"
还可以通过
table
对显示结果进行美化docker images --format "table {{.xxx}}\t{{.xxx}}\t{{.xxx}}"
-
查看镜像详细信息
docker image inspect 镜像ID
3)批量删除镜像【慎用】
通过-aq
组合列出所有image id
,再通过"``"提取出所有id值,最后通过rmi
批量删除
bashdocker rmi `docker -aq images`
慎用!慎用!慎用
4)导出镜像
如默认的centos是不提供vim功能的,我们可以通过yum下载vim后,导出具备vim的centos镜像。
此时docker pull
下来的centos是没有vim功能的,我们用yum下载vim工具
以下部分是报错检查
在yum install
的过程中,提示以下报错,查看ping也没有问题
经检查,发现是由于该容器内没有配置repos导致的
配置好repos后就可以使用yum install vim
了
使用yum install vim -y
成功
再查看vim就会发现安装成功了
最后,通过docker image save
利用重定向以压缩文件tgz的形式将修改后的镜像导出
5)导入镜像
我们这里先删掉一个镜像
此时发现该镜像还存在依赖关系,但是通过docker ps
又发现没有正在运行的容器,此时可以通过docker ps -a
查看进程
再通过docker rm ContainerID
彻底关闭该容器,就可以执行docker rmi
删除该镜像了
我们通过docker image load
导入镜像
这时再通过docker images
就可以看到该镜像已经成功导入了
4. Dokcer的容器管理
1)容器启停状态
容器内的进程必须处于前台运行状态,否则容器会直接退出
我们这里直接运行centos容器,但是通过docker ps
发现没有运行着的容器,这就是因为docker run centos
没有程序在跑,因此挂掉。
这时可以通过-d
参数,让容器处于后台运行的状态
还可以添加--name
给容器重命名
此时我们如果通过docker stop
停掉某个容器,还是可以通过docker ps -a
查到该记录,后续可能导致对镜像进行修改时报错,此时可以添加--rm
参数,使容器在停掉时自动删除该条记录。
2)查看容器日志
我们可以通过docker logs -f 容器ID
查看容器运行的实时日志
此时会显示出特别多的日志,还可以使用tail
参数查看最新的n条记录
3)进入正在运行的容器
通过exec
进入正在运行的容器
4)查看容器详细信息
和docker镜像类似,通过添加inspect
参数查看容器具体信息
5)容器的提交
通过docker commit 容器id 新的镜像名
可以将修改后的容器以新的镜像名出现在docker images
里,启动该镜像后产生的容器,包含了我们在上述容器中所做的修改。
5. Dockerfile实践
dockerfile主要组成部分:
- 基础镜像信息
From centos:7.0
- 制作镜像操作指令
Run yum install openssh-server -y
- 容器启动时执行命令
CMD ["/bin/bash"]
1)dockerfile指令
- FROM: 指定基础镜像
- MAINTAINER: 指定维护者信息
- RUN: 运行指定命令
- ADD: 添加宿主机的文件到容器内(包含自动解压的功能)
- CPOY: 将宿主机文件拷贝到容器内(仅拷贝,不解压)
- WORKDIR: 设置当前工作目录
- VOLUME: 设置卷,挂载主机目录
- EXPOSE: 在容器内暴露一个端口
- CMD: 指定容器启动后要干的事情
2)dockerfile快速使用
需求:通过dockerfile构建nginx镜像,且运行容器后,生成显示指定内容的页面
步骤:
1> 创建dockerfile
2> 构建dockerfile
由于此时learn_docker
目录下只有Dockerfile
,因此直接通过docker build .
构建dockerfile
由于此虚拟机本地的nginx基础镜像名为
docker.m.daocloud.io/nginx
,因此在FROM
处直接写作nginx
时,会因无法找到对应镜像而从dockerhub
内download名为nginx的镜像。此时若将FROM
后改为docker.m.daocloud.io/nginx
,就会使用本地已下载好的nginx镜像
可以看到这里在运行docker build
后,会返回一个Image ID
,这就是构建好后的镜像ID
3> 修改镜像名
由于刚构建的镜像没有设置名字,可以通过docker tag 镜像ID New_name
修改镜像名
4> 运行该镜像
接着就可以运行我们设定好的镜像了
5> 查看宿主机端口
此时在宿主机访问,就会显示我们所设定的内容
3)ENTRYPOINT & CMD
当制定了ENTRYPOINT之后,CMD的语义就发生了变化,CMD的内容会作为参数传递给ENTRYPOINT指令
具体来说,我们先构建一个dockerfile,该dockerfile实现的效果等价于:
docker run centos:7.8 curl -s http://ipinfo.io/ip
我们这里使用的是CMD
,当我们想再添加一个参数-I
去查看请求头信息时,会出现以下结果
这是因为此时-I
会覆盖掉dockerfile中的CMD
命令
而如果我们在dockerfile中使用ENTRYPOINT
(修改了Dockerfile后需重新构建),再使用-I
此时就能正常返回请求头信息了
4)ARG & ENV
ARG和ENV都是用于设置环境变量
ENV MYSQL_VERSION = 5.6
后续就可以直接通过$NAME
获取变量值了。便于维护dockerfile脚本
区别在于:
ENV:无论在构建镜像时,还是运行容器时,都可以使用该变量
ARG:只是用于构建镜像时的变量,容器运行时就消失了
5)VOLUME
容器在运行时,应尽量保证存储层不写入任何数据。因此,可以通过VOLUME将容器内产生的数据写入到宿主机内进行维护。
VOLUME /data
将容器内的/data文件夹,在容器运行时,该目录自动挂载为匿名卷,任何向该目录中写入数据的操作,都不会被容器记录,保证的容器存储层无状态理念
具体如下,我们这里首先重新构建dockerfile,设定/data1
和 /data2
两个目录
运行该镜像后,我们通过docker inspect
查看该容器的具体信息
可以看到,容器中/data1
和 /data2
目录下存储的数据,会相应映射到source后面的目录中。
由于目前/data1
和 /data2
下暂无数据,因此宿主机上该目录下目前也没有任何数据。
6)EXPOSE
用于指定容器运行时对外提供的端口服务
docker port 容器
docker run -p 宿主机端口:容器端口
docker run -P #随机宿主机端口:容器端口
7)WORKDIR
用于在dockerfile中,工作目录的更改
WORKDIR /opt
8)USER
用于在dockerfile中切换用户
USER root
USER XXXX
9)综合练习:构建一个网站镜像
需求:用Python基于flask框架开发一个简单的网站,并构建dockerfile镜像
1> 创建代码文件
2> 创建dockerfile
2.1> 代码解释
# 调用基础镜像,确认基础仓库并开启缓存
FROM centos:7.8
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo;
RUN curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo;
RUN yum makecache fast;
# 安装python并下载flask包
RUN yum install python3-devel python3-pip -y
RUN pip3 install Flask==2.0.3
# 将当前路径下的docker_flask.py文件复制到容器/opt目录下
COPY docker_flask.py /opt
#切换容器目录到/opt
WORKDIR /opt
# 暴露容器的8080端口,与py文件中的port相对应
EXPOSE 8080
# 运行docker_flask.py文件
CMD ["python3","docker_flask.py"]
3> 构建镜像
4> 运行容器
此时宿主机的90端口会映射到容器的8080端口,在宿主机上访问90端口,就可以看到构建好的网站了