【Docker】Docker基础

发布于:2024-07-23 ⋅ 阅读:(146) ⋅ 点赞:(0)

内容根据B站《Docker最新超详细版教程通俗易懂》课程制作



前言

  • 镜像(image)
    Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务, 通过这个镜像可以创建多个容器,最终服务运行或者项目运行就是在容器中的

  • 容器(container)
    Docker利用容器技术,独立运行一个或者一组应用, 通过镜像来创建的
    启动,停止,删除,基本命令!

  • 仓库(repository)
    存放镜像的地方
    Docker Hub(默认是国外的)
    阿里云,都有容器服务(配置镜像加速!)

在这里插入图片描述


以下是本篇文章正文内容

一、安装Docker

1.1 卸载旧版本

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

1.2 需要的安装包

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

1.3 设置镜像仓库

  1. 阿里云镜像
yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 官方源地址(速度较慢)
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

1.4 安装Docker相关内容

  1. 更新yum软件包索引
yum makecache fast
  1. 安装最新版本的 Docker Engine-Community 和 containerd,或者转到下一步安装特定版本:
yum install docker-ce docker-ce-cli containerd.io
  • docker-ce:代表社区版
  1. 安装成功
docker version
  1. 配置阿里云镜像服务

在阿里云官网的控制台中,找到容器镜像服务->镜像工具->镜像加速器
找到以下代码,在/etc/docker/daemon.json中加入镜像网址

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://niphmcik.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

1.5 启动 Docker

$ sudo systemctl start docker

通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community 。

 $ sudo docker run hello-world

在这里插入图片描述

1.6 删除Docker

  1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
  1. 删除资源
rm -rf /var/lib/docker # docker默认的工作路径

1.7 Docker的run工作流程

在这里插入图片描述

二、 Docker的基本命令

2.1 帮助命令

# 帮助命令
docker version      # 显示docker的版本信息
docker info         # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help   # 帮助命令

帮助文档的地址:docker build | Docker Documentation

2.2 镜像命令

获取镜像:
从远程仓库下载
自己制作一个镜像 DockerFile

docker images //显示镜像信息
# 可选项
#  -a, --all         # 列出所有镜像             
#  -q, --quiet       # 只显示镜像的ID  

在这里插入图片描述

  • REPOSITORY 镜像的仓库源
  • TAG 镜像的标签
  • IMAGE ID 镜像的ID
  • CREATED 镜像的创建时间
  • SIZE 镜像的大小
docker search  镜像名称   #搜索镜像
docker pull    镜像名称:版本号   # 下载镜像,不写版本号默认最新

docker rmi 删除镜像
docker rmi -f 镜像ID     # 删除指定的镜像
docker rmi -f 镜像ID 镜像ID 镜像ID...  # 删除多个镜像
docker rmi -f $(docker images -aq)  # 删除全部的镜像

2.3 commit 提交镜像

docker commit -m="提交的描述信息" -a="作者" 容器id  目标镜像名:[TAG](版本)

三、 容器命令

有了镜像才可以创建容器

比如下载一个centos镜像

docker pull centos
# 1,启动一个默认的tomcat# 2,进入容器,对这个容器进行修改# 3,将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。
docker commit -a="author" -m="add webapps app" 7e119b82cff6 tomcat02:1.0

# 4,通过docker images即可查看提交的镜像,这就相当于VM的快照

3.1 新建容器

docker run [可选参数] imageName
​
# 参数说明
--name="Name"   # 容器名字 例如tomcat01  tomcat02,用来区分容器
-d              # 后台方式运行
-it             # 使用交互方式运行,进入容器查看内容
-P              # 指定容器的端口 
    -P ip:主机端口:容器端口
    -P 主机端口:容器端口 #(常用,这是映射方式)如-P  8080:8080(与主机映射方式)
    -P 容器端口
    容器端口
-p             # 随机指定端口  
-v             # 使用数据卷挂载,详见第六章

常见的坑,docker 容器运行,就必须要有一个前台进程(比如-it进入交互),docker发现没有应用,就会自动停止
nginx, 容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

# 测试,启动并进入容器
[root@centos ~]# docker run -it centos /bin/bash
[root@16f4ee728cb6 /]# 

3.2 启动和停止容器的操作

docker start 容器id       # 启动容器
docker restart 容器id     # 重启容器
docker stop 容器id        # 停止当前正在运行的容器
docker kill 容器id        # 强制停止当前容器

3.3 退出容器

exit # 直接容器停止并退出

快捷键Ctrl + p + Q # 容器不停止退出

3.4 列出运行的容器

docker ps 命令
    #列出当前正在运行的容器
-a  #列出当前正在运行的容器+顺带带出历史运行过的容器
-n=num(参数)    # 显示最近创建的num个容器
-q # 只显示容器的编号

3.5 删除容器

docker rm 容器id          # 删除指定的容器,不能删除正在运行的容器,如果要强制删除要rm -f
docker rm -f $(docker ps -aq)   # 删除所有的容器
docker ps -a -q|xargs docker rm     #删除所有的容器

四、 其它命令

  1. 查看日志
docker logs -tf [--tail num] 容器ID
# --tail num 要显示的日志条数,没有此参数则显示全部
  1. 查看容器内的进程信息
docker top 容器id
  1. 查看镜像的元数据
docker inspect 容器id

镜像的元数据是指与镜像相关的所有信息,包括镜像的名称和标签、作者、描述、创建日期、环境变量、命令等。

  1. 进入当前正在运行的容器

我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

# 方式一
docker exec -it 容器id bashShell(/bin/bash)

# 方式二
docker attach 容器id

# 区别
# docker exec       # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach     # 只是进入容器正在执行的终端,不会启动新的进程!

  1. 查看docker的cpu状态
docker stats
  1. 从容器内拷贝文件到主机上
docker cp 容器id:容器内路径  目的的主机路径

# 拷贝是一个手动过程,未来我们使用 -v 卷的计数,可以实现 自动同步

五、 Docker创建容器示例

Docker 安装 Nginx

  1. 搜索镜像 search 建议去docker搜索,可以看到帮助文档信息
  2. 下载镜像 docker pull nginx
  3. 运行测试 docker images
  4. 后台启动,命名容器位nginx01,映射主机端口位3344
docker run -d --name nginx01 -p 3344:80 nginx
  1. 查看状态 docker ps
  2. 进入容器 docker exec -it nginx01 /bin/bash
  3. 外网访问
    公网访问

公网访问的途径

六、 容器数据卷

挂载(mounts):指的就是将设备文件中的顶级目录连接到 Linux 根目录下的某一目录(最好是空目录),访问此目录就等同于访问设备文件。

卷技术:就相当于目录的挂载,将我们容器内的目录,挂载在Liunx上面!
目的:容器的持久化和同步操作,将容器的数据、目录同步到主机中。
容器间也是可以数据共享的

6.1 使用数据卷

方式一:直接使用命令来挂载 -v(第二种在Dockerfile中)

docker run -it -v 主机目录:容器内目录 镜像name /bin/bash
# 主机目录和容器目录的内容自动互相同步
docker run -it -v 主机目录:容器内目录 -v 主机目录2:容器内目录2.. 镜像name /bin/bash
# 可以映射多个目录

# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash

修改只需要在本地修改即可,容器内会自动同步!

清理无主的数据卷

docker volume prune

6.2 Mysql实例

  1. 获取镜像 docker pull mysql:5.7

  2. 启动MySQL,注意需要配置密码!
    docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

    -d 后台运行
    -p 端口映射,暴露端口
    -v 卷挂载
    -e 环境配置
    – name 容器名字

  3. 主机使用Navicat测试连接
    在这里插入图片描述

  4. 连接成功后,在Navicat中进行数据库操作,会同步到主机的/home/mysql/data目录下
    将容器删除后,这些同步的数据也不会删除

6.3 具名和匿名挂载

# 查看所有的 volume 的情况
docker volume ls
-v 容器内路径        # 匿名挂载
-v 卷名:容器内路径   # 具名挂载(就是有个名字)
-v /宿主机路径:容器内路径     # 指定路径挂载!

匿名挂载

docker run -d -P --name nginx01 -v /etc/nginx nginx  #此为容器内目录

在这里插入图片描述

这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!

具名挂载(常用)

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 通过 -v 卷名:容器内路径,实现具名挂载

-v juming-nginx:/etc/nginx中,juming-nginx即为挂载name,后续为容器内目录
在这里插入图片描述

查看挂载信息

docker volume inspect VOLUME NAME(挂载名)

# 示例
docker volume inspect juming-nginx

所有的docker容器内的卷,没有指定目录的情况下都是在./var/lib/docker/volumes/xxxxxx/_data

通过具名挂载可以方便的找打我们的 卷,大多数情况在使用的具名挂载

拓展

# 通过 -v 容器内路径: ro  rw  改变读写权限
ro    readonly  # 只读,这个路径只能通过宿主机来操作,容器内部无法操作
rw    readwrite  # 可读可写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

七、 Dockerfile

Dockerfile 就是用来构建 docker 镜像的构建文件
DockerFile:构建文件,定义了一切的步骤,源代码
Dockerimages:通过DockerFile 构建生成的镜像,最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务器

7.1 构建步骤

  • 编写一个dockerfile 文件
    • 每个保留关键字(指令)都是必须是大写字母
    • 执行从上到下顺序执行
    • #表示注释
    • 每一个指令都会创建提交一个新的镜像层,并提交!
  • docker build 构建成为一个镜像
  • docker run 运行镜像
  • docker push 发布镜像 (Docker Hub,阿里云镜像仓库!)

7.2 基础命令

FROM                     # 基础镜像,一切从这里开始构建
MAINTAINER               # 镜像是谁写的,姓名+邮箱
RUN                      # 镜像构建(build)的时候需要运行的命令
ADD                      # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WROKDIR                  # 镜像的工作目录
VOLUME                   # 挂载的目录
EXPOSE                   # 暴露端口配置
CMD                      # 指定这个容器启动(run)的时候要运行的命令,只有最后一个会生效,可被替代
# 比如执行命令:docker run cmdtest -l ,想追加-l时,-l会替代dockerfile文件中的cmd命令,而不是追加
ENTRYPOINT               # 指定这个容器启动的时候要运行的命令,可以追加命令
# 比如执行命令:docker run entrypointtest -l ,想追加-l时,-l会追加到dockerfile文件中的entrypoint命令之后一起执行
ONBUTLD                  # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUTLD 的指令,出发指令
COPY                     # 类似ADD,将我们文件拷贝到镜像中
ENV                      # 构建的时候设置环境变量

99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建

创建自定义centos镜像示例

  1. 编写dockerfile文件
cat mydockerfile-centos 


FROM centos:7
MAINTAINER xxx<xxx@qq.com>
​
ENV MYPATH /usr/local
WORKDIR $MYPATH
​
RUN yum -y install vim  # 添加vim命令的相关配置
RUN yum -y install net-tools # net-tools相关
​
EXPOSE 80
​
CMD echo $MYPATH
CMD echo "------end------"
CMD /bin/bash
  1. 通过这个文件构建镜像
    命令 docker build -f dockerfile文件路径 -t 镜像命:[tag]
docker build -f mydockerfile-centos -t mycentos:0.1 .
#  docker build 最后的 . 号,是在指定镜像构建过程中的上下文环境的目录

在Dockerfile中挂载示例

我们可以在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。
下面使用Dockerfile构建一个新的镜像,dockerfile01文件的内容匿名挂载了volume01和volume02两个目录:(方式二挂载)

FROM centos  # 指定基础镜像
VOLUME ["volume01","volume02"]  # 挂载目录

CMD echo "----end----" # 指定这个容器启动的时候要运行的命令,只有最后一个CMD会生效
CMD /bin/bash

执行构建镜像

docker build -f /home/docker-test-volume/dockerfile01 -t mycentos .
#  docker build 最后的 . 号,是在指定镜像构建过程中的上下文环境的目录

完成镜像的生成后,启动自己生成的容器

docker images # 查看镜像ID

docker run -it 镜像ID /bin/bash

ls # 可以查看到挂载目录volume01和volume02

因为dockerfile中没有指定宿主机目录,所以属于匿名挂载,在/var/lib/docker/volumes/目录下生成了随机命名的路径。

发布镜像

  1. 登录阿里云

  2. 在工作台找到容器镜像服务ACR

  3. 需要创建个人实例,创建命名空间,命名空间就是镜像列表的上级目录(命名空间个人只能创建3个)
    在这里插入图片描述

  4. 创建容器镜像仓库,仓库名称也就是你的镜像名称,里面装的此镜像的各个版本
    在这里插入图片描述

  5. 点击仓库名称,查看仓库相关信息及pull和push步骤

  6. 登陆->修改镜像名称->push

docker login --username=登陆名 registry.cn-hangzhou.aliyuncs.com
docker tag 5d0da3dc9764 registry.cn-hangzhou.aliyuncs.com/命名空间/centos:2.0
docker push registry.cn-hangzhou.aliyuncs.com/命名空间/centos:2.0

在这里插入图片描述

  1. 在镜像版本中查看上传此镜像的各个版本

八、 数据卷容器

容器数据卷是指建立数据卷,来同步多个容器间的数据,实现容器间的数据同步
在这里插入图片描述

首先启动容器1,volume01、volume02为挂载目录。

docker run -it --name cnetos01 mycentos

然后启动容器2,通过参数–volumes-from,设置容器2和容器1建立数据卷挂载关系。 此时,容器1也成为数据卷容器。

docker run -it --name centos02 --volumes-from cnetos01 mycentos

在容器2中的volume01中添加文件 ,然后就可以看到容器1的文件也会添加上了

总结:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一但你持久化到了本地,这个时候,本地的数据是不会删除的!

示例

下面同步两个MySQL的数据库和配置文件,与上面的操作相同,首先建立数据卷,然后给另一个MySQL容器建立容器数据卷挂载,示例:

docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 6604:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

九、 Docker网络

9.1 Docker0网络通信

我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术!(可以在docker容器中用ip addr查看)

在容器中,使用ip addr查看,还有一个veth网卡,是一对两个接口,一端连着协议,一端彼此相连。
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
在这里插入图片描述
如下图,tomcat01向tomcat02通信,并不是直接通信,而是经过Docker0网进行间接通信,Docker0就充当的是路由器角色
在这里插入图片描述

Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件)

9.2 link(不推荐使用,推荐用自定义网络)

思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以用名字来访问容器

docker exec -it tomcat02 ping tomcat01 # 直接ping是不通的
# ping: tomcat01: Name or service not known
# 如何解决
docker run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02 # ping通

# 反向不可以ping通,反向也需要配置--link
docker exec -it tomcat02 ping tomcat03
# ping: tomcat03: Name or service not known

–link 就是我们在hosts配置中增加了一些如172.18.0.3 tomcat02,即域名映射

9.3 自定义网络

docker0是默认的,域名不能访问, 但 --link可以打通连接!

可以自定义一个网络!

# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
​
docker network create --driver bridge  --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 定义了一个192.169.0.0/16的局域网

查看网络配置

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
c699015536d2   bridge    bridge    local
195ae44fa95a   host      host      local
7deef8178eef   mynet     bridge    local
82568a72415c   none      null      local

启动两个docker容器

docker run -d -P --name tomcat-net-01 --net mynet tomcat # 指定网络
docker run -d -P --name tomcat-net-02 --net mynet tomcat
# 指定网络后,就会分配该局域网下的ip地址

此时可以互相ping通

docker exec -it tomcat-net-01 ping 192.168.0.3
docker exec -it tomcat-net-01 ping tomcat-net-02 
# 用名字也可以,因为指定网络时,会自动在mynet配置中增加域名映射

优点:不同的集群使用不同的网络,保证集群是安全和健康的

9.4 网络连通

不同自定义网络的容器是不能通信的
可以通过连接网络进行通信

docker network connect 网络名 容器名
# 将容器和网络连通

# 示例,将tomcat01和mynet连通,实质就是将tomcat01放在了mynet网络下,一个容器两个IP
docker network connect mynet tomcat01

十、 部署Redis集群

建立三主三从集群

  1. 设置redis网络
docker network create redis --subnet 172.38.0.0/16

docker network ls # 查看网络列表
  1. 通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
  1. 逐个开启六个redis容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
​
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
​
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
​
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
​
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
​
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  1. 创建集群
docker exec -it redis-1 /bin/sh  # 进入容器

# 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1 


  1. 连接集群
redis-cli -c

# 查看节点信息
cluster nodes
  1. 集群搭建完毕可以进行操作

网站公告

今日签到

点亮在社区的每一天
去签到