docker深入学习

目录

二. docker的安装

1. docker的组件组成

2. 安装docker(参考官方文档https://docs.docker.com/)

3. 阿里云镜像加速

三. docker的常规使用

1. 工作原理

2. docker镜像常用命令

3. docker容器常用命令

3.1  docker run --help 启动命令参数说明

3.2 其他常用命令

4. docker 的可视化UI界面

5. 镜像加载原理

四. docker的进阶使用

1. docker容器数据卷 -v

1.1 匿名挂载、具名挂载、dockerFile挂载

1.2 数据卷容器:实现容器间数据同步

2. docker File 构建镜像

2.1 dockerFile的指令

2.2 构建一个简单的镜像

2.3 构建一个复杂的镜像(具有JDK环境的centos)

3. 发布镜像

五. docker的网络通讯

1. docker的网络原理 

2.  --link(现在不常用,功能有限,实际中经常使用自定义网络)

3. 自定义网络

3.1 docker的网络模式

3.2 创建自定义网络模式

3.3 网络连通docker network connect跨网络通讯

六. 搭建单机版Redis集群


一. docker简介

docker是为了解决环境配置应用部署的不同环境问题,提供一次性安装,多地拿来即用的解决方案。

docker核心思想:打包装箱,每个包运行在不同的容器中,容器的环境都是互相隔离的。

docker的历史:

docker一开始是美国的一家dotCloud开发云计算的创业公司。主要做Linux虚拟内核容器技术,然后他们搞了一套容器化技术,就叫docker。一开始是无人问津的。知道docker被开源后,逐渐被人熟悉并了解了其强大好用的功能。从而促使docker越来越活跃。至今已经成为了行业不可或缺的解决方案。

它本质上也是一种虚拟化技术,并不是模拟的一个完整的操作系统(共享服务器内核,容器运行在服务器上,容器中只需要安装需要的APP和环境即可),但是它的容量是很小的。体量非常轻,是使用GO语言开发的开源项目。

docker的出现和使用能够极大的提高开发效率:

  • 能够使程序的部署,扩展更加简易,使用docker直接部署即可
  • 使用相同的镜像,保证不同环境是一致的
  • 能够最大效率的利用服务器资源,使服务器利用率达到极致

二. docker的安装

1. docker的组件组成

  • 镜像(image)

docker的镜像就是打包好的一整套服务,形成的镜像文件。镜像可以运行在docker容器中

  • 容器(container)

docker容器就是用来运行docker镜像的隔离环境。一个镜像可以被运行在多个容器中。

  • 仓库(repository)

docker 的仓库就是用来存储docker镜像的云仓库。我们可以从仓库中获取镜像, 也可以将自己的镜像打包上传至仓库中

官方的仓库是docker hub,但是是国外的仓库,所以需要配置镜像加速来访问docker Hub

2. 安装docker(参考官方文档https://docs.docker.com/)

  • 环境准备

centos 7(cat /etc/os-release查看)、  系统内核3.10(uname -r查看)

  • 卸载旧版本docker
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  • 准备安装环境
yum install -y yum-utils   #安装docker环境
  • 设置镜像地址
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo    #官网推荐的是国外的仓库

#我们使用国内的镜像仓库,例如阿里云镜像、网易镜像,中科大镜像
yum-config-manager \
    --add-repo \
     http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#可通过docker info查看docker相关信息
  • 安装docker
#docker-ce 是指docker社区版,企业版是-ee,以及安装docker客户端、容器等
yum install docker-ce docker-ce-cli containerd.io 
#也可以通过指定版本安装docker,默认都是安装最新版本的
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
  • 启动并测试docker
#启动
systemctl start docker
#查看
docker version
#运行测试官方提供的测试镜像
docker run hello-world
  • 卸载docker
#卸载安装包
yum remove docker-ce docker-ce-cli containerd.io
#删除资源文件
rm -rf /var/lib/docker

3. 阿里云镜像加速

登录阿里云--控制台---弹性计算---容器镜像服务---镜像加速

执行这几个命令即可完成镜像加速。能够帮助我们下载上传镜像速度更快。

三. docker的常规使用

1. 工作原理

docker本身是通过service-client模式来完成工作的。 dockerservice守护进程运行在宿主机上。

docker为什么比VM运行速度快?

VM: 创建一个虚拟机,就安装了一整套的操作系统,然后去部署应用,多个虚拟机就是多个操作系统

docker: 安装docker后,应用可以部署在容器中,每个容器都是互相隔离的,就相当于每个容器就是一个操作系统。但是docker容器占用的内存和空间是很小的,因为多个容器是利用宿主机的内存和内核的。不需要在容器中安装过多的重复的东西。

 

2. docker镜像常用命令

帮助命令查询:

docker 命令 --help  例如镜像的帮助命令: docker image --help 

或者通过官方文档查阅reference:https://docs.docker.com/engine/reference/commandline/image_ls/

  • docker images  --help

docker images  = docker images  -a : 显示所有镜像

docker images -q  :只显示docker镜像的ID

  • docker search mysql :  在dockerHub上搜素镜像
  • docker pull mysql:5.7  : 下载指定版本的镜像, 如果不加版本则默认下载最新版本latest
  • docker rmi :删除镜像 

docker rmi -f $(docker images -aq)   删除所有(过滤器传入的是所有的容器ID)、 

docker rmi asdfwe4as   删除指定容器ID 

 

3. docker容器常用命令

3.1  docker run --help 启动命令参数说明

  • docker run --name centos      启动的容器名称别名
  • -d                                               后台方式运行
  • -it                                               使用交互方式运行,即表示能够进入容器查看内容
  • -p                                              指定端口 -p 8888:8080  即表示宿主机的8888端口映射到容器的8080端口
  • -P                                              指定随机端口

docker run -dit --privileged -p21:21 -p30000-30010:30000-30010 --name test centos:centos7 /usr/sbin/init

3.2 其他常用命令

  • docker ps -a : 查询所有的容器  docker ps  查询正在运行的容器
  • docker rm id : 删除指定ID容器,不能删除正在运行的容器
  • docker rm -f $(docker ps -aq):删除所有容器,会把正在运行的容器强制删除
  • docker start id:启动容器
  • docker restart id :重启容器
  • docker stop id : 停止容器
  • docker kill id :强制停止容器
  • docker logs -tf --tail 10  容器id: 查看指定容器指定最新行数的日志
  •  docker top 容器ID  : 查看容器内部的进程信息
  • docker inspect 容器ID :查看容器的元数据
  • docker exec -it 容器ID  /bin/bash : 进入容器
  • docker attach 容器ID :进入容器,并进入正在执行的操作
  • docker cp 容器ID:/文件路径  目标路径  : 将容器中的文件copy到宿主机上,例: docker cp sdfwer11:/opt/test.html /opt,就会将id为sdfwer11的容器中的test.html复制到当前服务器的/opt路径下
  • docker stats : 查看docker容器的CPU情况
  • docker commit -m "msg" -a "author" 容器id 新镜像名:[TAG] :将某个容器打包成镜像存放在本地。eg:docker commit -m "add webapps init" -a "lemon" aea9f1f901ed tom02:1.0

4. docker 的可视化UI界面

简易的图形化管理界面portainer。

docker run -d -p 8091:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer  启动运行portainer即可完成

5. 镜像加载原理

镜像的加载通过联合文件系统来进行镜像的下载。联合文件系统就是一层一层模块化的文件。

例:安装nginx镜像时,可能nginx镜像会分为4层文件(layers【可通过docker inspect  ID 查看元数据】),第一层是centos、第二层是JDK环境、第三层是mysql、第四层是python

此时在宿主机的镜像中,依次下载这四层镜像,如果第一层centos已经存在,则无需下载直接跳过(复用)下载第二层。这就是docker的文件分层。

基层的bootfs相当于是服务器的内核,共用该内核,并一层一层的添加镜像文件。

容器中的centos其实内核还是使用的宿主机内核。

启动操作镜像时

当我们启动下载下来的nginx镜像时(下载下来的nginx镜像文件是只读的不可修改),docker就会在原nginx镜像之上再加一层可写入镜像文件(layers),记录我们自己的操作内容。从而之后我们可以把自己修改的镜像打包后上传。

四. docker的进阶使用

docker在使用过程中,主要是应用于生产应用的部署。所以掌握基础的命令是不够的,我们还需要使用docker完成打包,保证数据的安全性以及docker容器之前是如何通讯的等进阶使用:

docker容器数据卷、dockerFile打包镜像、docker网络通讯

1. docker容器数据卷 -v

应用是通过镜像运行在容器中的,所以一旦容器被删除或者丢失,那容器中应用的数据就会全部丢失。所以需要一个持久化技术,来保证容器即便删除,数据还在。这就是容器数据卷的功能。

他能将容器的文件映射到宿主机的路径中。将容器文件和宿主机文件进行同步,实现数据共享。读写宿主机文件就==读写容器中的文件,相当于文件的挂载。

容器间的数据也可以共享

重启容器后数据会自动同步

使用:

docker run -d -v /opt/ceshi:/home[:ro/rw] centos:centos7 /usr/sbin/init    启动该镜像,并将宿主机的/opt/ceshi与容器内的/home进行同步

ro/rw 代表只读/读写权限的设置,如果设置为ro,则改文件只能通过宿主机修改。容器内只能读取。

此时,该容器与宿主机的目录就实现了同步。可以通过查看元数据docker inspect 容器ID 查看挂载情况

EG:        mysql数据恢复

下载启动mysql镜像:

①将mysql的配置文件/etc/mysql/conf.d 挂载到宿主机/opt/mysql/conf

②将mysql的数据文件/var/lib/mysql挂载到宿主机/opt/mysql/data

实现文件同步

docker run -d -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/data:/var/lib/mysql -p 8096:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7

启动后,创建数据库test库,并随机创建两张表。因为数据卷已经挂载了,所以宿主机上文件已经同步

此时删除正在启动的mysql容器。重新按照以上指令启动一个新的mysql容器。

因为挂载的文件已经记录了mysql的数据,所以启动后数据会同步到新的容器中,实现了数据的恢复

1.1 匿名挂载、具名挂载、dockerFile挂载

docker在进行数据卷挂载的时候,可以通过匿名/具名挂载来实现文件的挂载:

匿名: 不制定宿主机的文件路径,随机分配

docker run -d -p 8891:33306 -v /etc/mysql/conf.d  -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7

具名:在默认的docker数据卷路径下创建一个别名文件夹,用来挂载容器中的数据

# 将容器的路径挂载到具名 sql_data文件夹中
docker run -d -p 8891:3306 -v sql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7

dockerFile: 通过构建镜像时,将文件目录进行挂载。这种方式就不需要每次启动的时候手动-v进行挂载了,只要启动容器,就会进行挂载。构建镜像时非常常用

 

如何查找具名的文件夹呢?可以通过docker volume ls 查看所有的挂载数据卷

1.2 数据卷容器:实现容器间数据同步

如果要实现容器与容器之间的文件挂载共享,可以通过:--volumes-from 容器名    来完成挂在,从而实现不同容器之间,数据的共享和同步

eg1:

创建一个容器,并挂载目录 -v /opt/data:/home  此时,该容器与宿主的完成数据卷挂载。

再启动一个容器:与第一个容器一样,也挂载到当前宿主机的该路径下, --volumes-from 容器名/容器ID ,此时就相当于继承了第一个容器的挂载,实现了,两个容器间的数据共享(同时挂载在了宿主机的/opt/data路径下,共享同步数据)

2. docker File 构建镜像

dockerFile就是用来制作自己的镜像,images都是通过dockerFile构建出来的。

编写脚本 ------ docker build 构建脚本 ------ 生成image镜像

镜像可以被push 到docker Hub或者阿里云镜像仓库中

2.1 dockerFile的指令

  • docker的关键字都是大写
  • 自上而下顺序执行
  • 每一行命令都会创建一层镜像,通过build打包成一个整体镜像

  • FROM : 指定基础镜像,例如基于centos就FROM  centos
  • MAINTAINER:镜像的作者
  • RUN : docker镜像运行时的命令
  • ADD : 添加需要的东西,例如mysql/JDK等之类的,也就是一层一层的镜像从这里添加进去
  • VOLUME : 挂载目录
  • EXPOSE:需要暴露的端口
  • CMD: 指定这个容器启动的时候,需要制定的命令 例如:/bin/bash等,会被最后一个命令替换掉
  • ENTRYPOINT : 相比CMD,指定这个容器启动的时候,需要制定的命令,有多个命令时,会追加不会替换
  • ENV : 构建的时候设置环境变量

2.2 构建一个简单的镜像

在centos镜像的基础上,创建一个安装了vim以及rz命令的centos:

①首先需要在某个路径下,创建一个dockerfile文件,例如创建一个dockerfile_centos文件,文件内容如下:

#基于centos镜像
FROM centos
#作者信息
MAINTAINER lemon<123456@qq.com>

#环境变量
ENV WORKPATH /opt
#工作路径
WORKDIR $WORKPATH

#run :构建时,运行相应的命令
RUN yum -y install vim
RUN yum -y install lrzsz

#暴露8080端口
EXPOSE 8080

#启动容器运行的命令
CMD /bin/bash

②指定 docker build -f dockerfile_centos(构建文件的路径) -t mycentos:1.0(镜像名及版本) .

③显示successful表示构建成功,在本地就可以看到构建出来的images了。

通过docker history 镜像ID的方式可以查看镜像构建的历史,可以通过这个命令,查看别人镜像的构建过程,例如:

2.3 构建一个复杂的镜像(具有JDK环境的centos)

① 创建文件Dockerfile(改文件名为官方规定文件名,启动时可以不用-f指定)

FROM centos
MAINTAINER lemon

# 根据压缩包自动解压文件到容器中该路径
ADD jdk-8u201-linux-x64.tar.gz /usr/local/jdk

RUN yum -y install vim

ENV WKPATH /usr/local
WORKDIR $WKPATH

#添加JDK的环境变量
ENV JAVA_HOME /usr/local/jdk/jdk1.8.0_201
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 8083

#指定启动jar包的命令
CMD nohuo java -jar /usr/local/jar/pms-2.0-SNAPSHOT.jar &

然后通过docker build -t pms . 构建镜像

运行镜像:将宿主机的jar包路径挂载到容器中的jar包路径,然后通过启动命令nohup启动jar包

docker run -dit -v /opt/docker/jar:/usr/local/jar -p 8097:8083 pms nohup java -jar /usr/local/jar/pms-2.0-SNAPSHOT.jar &

此时就完成了自己构建一个具有JDK环境的centos。+

3. 发布镜像

  • 注册dockerHub账号
  • 服务器登录dockerHub账号
  • 提交镜像push到仓库

命令:

①将镜像重新打标记:例如我的dockerHub用户名是:lemon,那如果我的本地镜像的name是pms,我在直接

docker push pms时,是会被拒绝的:“denied: requested access to the resource is denied

此时需要将镜像打标记,标记为用户名格式:lemon/pms 才可以push成功

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

docker tag [本地镜像名:tag]  [需要改成的镜像名:tag]

eg:  docker tag pms:latest lemon/pms:1.0

此时docker images 就发现多个lemon/pms 1.0 这个镜像,我们就提交这个镜像push上去就可以了

②push到远程:docker push [name:tag]  

eg:  docker push lemon/pms:1.0 

 

五. docker的网络通讯

docker中的网络通讯是通过虚拟网卡的形式实现通讯。安装了docker的宿主机会默认分配一个虚拟网关,用来作为桥接docker容器的网桥。从而能够支持宿主机与容器间能够网络通讯容器与容器间也能进行网络通讯

常用命令

  • docker network ls   :查看docker网络模式
  • docker network inspect 网络模式名/ID  :查看该网络模式的元数据
  • docker run --link serverName  :打通容器名的网络通讯
  • docker run --net mynet  :启动时使用指定网络模式
  • docker network connect mynet server01 :将某个容器加入到某个网络中

1. docker的网络原理 

  • docker0 网络

docker0是docker安装后就会有的虚拟网卡,主要用来桥接容器与容器。容器与宿主机间的网络通讯。

  • 启动一个容器后,宿主机就会多出一个网卡信息,在容器中也会有个网卡信息。组成了一对基于evth-pair技术实现的网络桥接模式

也就是说我们每启动一个容器,宿主机都会分配一个虚拟网卡(此时宿主机的docker0就相当于一个路由器,每当一个容器连接后,就分配一个IP地址,路由器可以连接容器,容器也可以通过路由器连接其他的容器)。该网卡信息与容器中的信息组成一个桥接组。实现网络通讯。

  • 宿主机可以与容器通讯,容器也可以与容器进行通讯

容器与容器间网络通讯原理图

  • 查看当前docker网络

可以通过docker network --help 查看docker网络情况

例如查看docker现在所有的网络:docker network ls

 

查看某个容器的网络元数据: docker network  inspect [id]   也可以通过 docker inspect 容器ID ,在元数据中也可以查到

2.  --link(现在不常用,功能有限,实际中经常使用自定义网络

如果要实现容器间的通讯,直接通过分配的IP访问的话,就会存在,如果容器重启就可能会导致IP更换。所以我们可以通过服务名的方式来实现通讯

例如:有两个容器A,B。 A中可以通过B:8080/user/login的方式代替IP来进行访问

eg:

# 运行一个server01的容器
[root@hecs-x-medium-2-linux-20200604093545 docker]# docker run -dit --name server01 centos
1e53ae254d24e5da6d40c40a0d73206660d335c2ad056545a63a16373c0a84cc
[root@hecs-x-medium-2-linux-20200604093545 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
1e53ae254d24        centos              "/bin/bash"         5 seconds ago       Up 4 seconds                            server01
[root@hecs-x-medium-2-linux-20200604093545 docker]# clear
#运行一个server02,并且--link server01 与01建立网络通讯
[root@hecs-x-medium-2-linux-20200604093545 docker]# docker run -dit --name server02 --link server01 centos
34e8ac055fcb90b532f2ab822a576b7725cfd113019351b1ed94d4d858c77228
[root@hecs-x-medium-2-linux-20200604093545 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
34e8ac055fcb        centos              "/bin/bash"         6 seconds ago       Up 4 seconds                            server02
1e53ae254d24        centos              "/bin/bash"         31 seconds ago      Up 30 seconds                           server01
#成功ping 通
[root@hecs-x-medium-2-linux-20200604093545 docker]# docker exec -it server02 ping server01
PING server01 (172.17.0.2) 56(84) bytes of data.
64 bytes from server01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from server01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.039 ms
64 bytes from server01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.034 ms

此时,访问server02的hosts文件发现:

3. 自定义网络

docker可以进行自定义网络连接,也就是说,可以自己规定一种网关,然后启动容器的时候,将容器加入到自己的网关中。自定义网络之间又是互相隔离的。

特点

  • 自定义网络是可以实现容器间、宿主机间通讯的
  • 不通过--link 也可以实现通过容器名进行通讯
  • 可以实现网络隔离,例如mysql集群共用一个网络路由,jar服务共用一个网络路由,就可以通过创建两个不同的自定义网络实现
  • 可以自定义很多配置

3.1 docker的网络模式

  • bridge:桥接模式,默认启动容器就是这种模式,就是使用我们的docker0网关
  • none:不配置网络
  • host:和宿主机共享网络
  • 自定义网络....

如果我们启动一个容器时: docker run -d centos 默认就是使用的bridge网络模式相当于:docker run -d --net bridge centos

但是这种默认的模式会存在很多缺陷和局限性,例如如果容器重启就会导致IP变化,就需要配置一个服务名使用--link来进行通讯,十分麻烦。

所以我们可以通过自定义网络的形式,来替代默认的网络模式

3.2 创建自定义网络模式

通过docker network --help 查看命令可以找到创建网络模式的指令

docker network create

# --driver bridge   模式是桥接模式

#--subnet 192.168.0.0/16   : 子网地址的可分配IP范围是192.168.0.1 ——192.168.255.255

#--gateway 192.168.0.1 : 网关入口是从192.168.0.1开始

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

启动测试:启动时,指定net模式为自定义模式 --net mynet

并且两个容器见,可以通过名字ping通

3.3 网络连通docker network connect跨网络通讯

docker network connect 可以将某个容器加入到某个网络路由中去:docker network connect 网络模式名 容器ID/容器名

如下图:

如果server01想访问server_net01该怎么办呢?

可以通过: docker network connect mynet server01

相当于将server01这个容器,也加入到mynet这个网络模式中,server01就相当于有了两个IP地址。

此时,就可以在server01中直接访问到server_net01中的内容了,两个不同网络中的容器就可以打通了。

测试:

此时,查看mynet的元数据:docker network inspect mynet。

六. 搭建单机版Redis集群

实现:

在一台服务器上,搭建6个Redis,实现一个三主三从的Redis集群

①创建Redis的网络模式:

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 redis

②创建6个Redis配置文件,并开启集群,这里通过shell脚本实现:

六次循环,写入配置文件

for port in $(seq 1 6); \
do \
mkdir -p /opt/docker/redis_cluster/node-${port}/conf
touch /opt/docker/redis_cluster/node-${port}/conf/redis.conf
cat <<EOF>> /opt/docker/redis_cluster/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 192.168.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF

done

③启动6个Redis镜像 端口从6381-6386 通讯端口16381-16386

并将Redis的数据、Redis的配置文件(挂载到脚本自动生成的配置文件路径)进行挂载

docker run -p 6386:6379 -p 16386:16379 --name redis-06 -v /opt/docker/redis_cluster/node-6/data:/data -v /opt/docker/redis_cluster/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 192.168.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

④进入某个Redis容器,创建集群

docker exec -it redis-01 /bin/sh

/data # redis-cli --cluster create 192.168.0.11:6379 192.168.0.12:6379 192.168.0.13:6379 192.168.0.14:6379 192.168.0.15:6379 192.168.0.16:6379 --cluster-replicas 1

⑤测试

集群创建完成。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值