微服务day06-Docker

Docker

大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题:

  • 依赖关系复杂,容易出现兼容性问题

  • 开发、测试、生产环境有差异

1.什么是Docker?

大型项目组件很多,运行环境复杂,部署时会遇到各种问题,各个应用依赖各不相同,版本不同等,linux系统不同等...部署时非常复杂,效率很低。
Docker如何解决依赖兼容的问题?

  • 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包

  • 将每个应用放到一个隔离容器去运行,避免互相干扰

虽然解决了不同应用的兼容问题,但是开发、测试等环境会存在差异,操作系统版本也会有差异,怎么解决这些问题呢?

linux系统的原理

分为3层,系统应用层(ubuntu/centos等),linux内核(所有Linux系统使用的都是linux系统内核),计算机硬件;

内核:内核负责与硬件交互,对上层提供内核指令,用于操作硬件;

系统应用:操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,使用更加方便;

应用于计算机交互的流程如下:

1)应用调用操作系统应用(函数库),实现各种功能

2)系统函数库是对内核指令集的封装,会调用内核指令

3)内核指令操作计算机硬件

由于系统应用不同,因此ubuntu的一个应用安装到centos系统上可能无法执行(提示找不到函数等),因此Docker提供了解决方案:

  • Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
  • Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的Linux内核来运行

2.Docker与虚拟机的区分?

Docker可以让一个应用在任何操作系统中非常方便的运行。而以前我们接触的虚拟机,也能在一个操作系统中,运行另外一个操作系统,保护系统中的任何应用。

虚拟机 (virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。

Docker仅仅是封装函数库,并没有模拟完整的操作系统,如图:

二者的性能指标对比:

综上所述,在实际的开发部署中通常Docker>虚拟机。

3.Docker架构

镜像

就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。
容器

镜像中的应用程序运行后形成的进程就是,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。

开源应用程序非常多,打包这些应用往往是重复的劳动。为了避免这些重复劳动,人们就会将自己打包的应用镜像,例如Redis、MySQL镜像放到网络上,共享使用,就像GitHub的代码共享一样。

  • DockerHub:DockerHub是一个官方的Docker镜像的托管平台。这样的平台称为Docker Registry。

  • 国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务阿里云镜像库等。

我们一方面可以将自己的镜像共享到DockerHub,另一方面也可以从DockerHub拉取镜像:

Docker是一个CS架构的程序,由两部分组成:

  • 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等

  • 客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。本地直接使用指令即可,远程使用RestApi发送请求。

4.Docker的安装

企业部署使用最多的时linux系统(Centos最多)

使用虚拟机安装CentOS7系统(满足了Docker CE对linux内核的最低要求)

1.卸载旧版Docker

如果虚拟机中可能存在旧版Docker,则需要删除旧的docker中相关内容

sh 复制代码
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine \
                  docker-ce

2.卸载旧版Docker

2.1 虚拟机联网

记得使用NAT

2.2 安装yum工具

sh 复制代码
yum install -y yum-utils \ 
		   device-mapper-persistent-data \
           lvm2 --skip-broken

2.3 设置docker镜像源

sh 复制代码
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast

2.4 下载以及安装docker-ce(社区免费版)

sh 复制代码
yum install -y docker-ce

2.5 启动Docker(如果是在虚拟机上为了避免逐个关闭端口号可以直接关闭防火墙,并设置禁用防火墙)

sh 复制代码
# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld

2.6 安装成功之后,查看版本

sh 复制代码
docker -v 

显示如下内容表名安装成功

2.7 新安装docker之后如果重启可能导致docker服务没有启动,报错如下,表示docker守护进程未启动:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

此时在root权限下执行

sh 复制代码
systemctl start docker 

5.镜像的命令

首先来看下镜像的名称组成:

  • 镜名称一般分两部分组成:[repository]:[tag]。
  • 在没有指定tag时,默认是latest,代表最新版本的镜像

比如[mysql]:[8.33];

常用命令:

  • 从dockerhub中拉取镜像
sh 复制代码
# 比如拉取nginx1.2.5版本
docker pull nginx:1.25.4
  • 查看本地镜像
sh 复制代码
docker images
  • 导出镜像到磁盘
sh 复制代码
# docker save -o [保存的目标文件名称] [镜像名称]
docker save -o nginx.tar nginx:1.25.4

如果只是指定保存文件名称,则会保存到当前目录下,如果想要保存到某个目录下可以直接指定:

sh 复制代码
docker save -o ./download/nginx.tar nginx:1.25.4
  • 从磁盘中加载镜像
sh 复制代码
# docker load -i [某个位置的镜像包(如果是在当前目录下直接用镜像名即可]
docker load -i ./download/nginx.tar
  • 删除镜像
sh 复制代码
docker rmi nginx:1.25.4

6.容器的命令

基本命令使用

  • 创建一个并运行一个nginx容器:
sh 复制代码
docker run --name contrainerName -p 80:8080 -d ngxin:1.24.5
# docker run 创建并运行一个nginx容器
# --name contrainerName  为容器起一个名字
# -p 80:8080 宿主机与容器的端口映射,左侧是宿主机端口,右侧是容器端口
# -d ngxin:1.24.5运行的容器是哪一个(-d是放到后台邮件)

对端口映射的解读:

sh 复制代码
由于容器是隔离的,所以并不能直接外部主机访问,外部主机可以访问宿主机(你可以将docker容器比作一个寄生虫,计生在宿主体内,外部无法与它直接交流,如果有必要交流,必须通过宿主作为中介,即外部告诉宿主,宿主告诉寄生虫),因此,将宿主机的端口与docker容器的端口作了一个映射之后,外部主机访问宿主机对应端口,宿主机端口再将对应的内容按照端口映射转发给docker容器

创建成功之后会返回该容器的ID:

  • 查看所有容器的状态:
sh 复制代码
docker ps 
  • 查看容器的日志
sh 复制代码
# 普通日志输出
docker logs mv
# 持续跟踪日志输出
docker logs -f mv 
  • 让一个停止的容器再次运行
sh 复制代码
docker start mv 
  • 停止一个容器的运行
sh 复制代码
docker stop mv 
  • 暂停(挂起)一个容器
sh 复制代码
docker pause mv 
  • 将暂停(挂起)的容器拿下来继续运行
sh 复制代码
docker unpause mv 

nginx容器创建之后,直接访问虚拟机对应的端口号:

进入容器,修改文件

进入容器。进入我们刚刚创建的nginx容器的命令为:

sh 复制代码
docker exec -it mn bash 
# docker exec 进入容器内部执行一个命令
# -it 给当前进入的容器一个标准输入,输出终端,允许我们与容器交互
# mn 我们要进入容器的名称
# bash 进入容器之后执行的命令

进入nginx默认页面的目录:

sh 复制代码
cd /usr/share/nginx/html

由于docker容器是阉割版的"系统",只提供了对应的镜像文件,因此不会提供vi等编辑器,如果要在里边修改内容,需要使用sed替换命令。

sh 复制代码
# sed命令详解
sed command file
# commond 针对每行的内容进行处理
	# -i 直接修改文件内容,而不是输出到屏幕上
	# -e 直接在命令行模式上进行sed的操作编辑
	# s 替换,将文件原内容替换为新内容。举例:s/old/new/g "/"是分割符号,用来区分新内容与旧内容的,也开始使用别的符号比如:"#"
	# g 表示行内全面替换
# file 要处理的文件,如果忽略该参数,会将标准输入作为对象进行处理

替换内容命令:

sh 复制代码
sed -i -e 's/传智教育欢迎您/NiHao/g' -e 's#<head>#<head><meta charset="utf-8">#g' index.html

替换之后结果

7.数据卷

在之前的操作中,容器与数据耦合过高,当需要修改更新等操作时,非常麻烦;因此引入数据卷的概念。

数据卷:一个虚拟目录,指向宿主主机文件系统中的某个目录。

可以类比映射,数据卷挂载之后,对etc/nginx/conf就相当于对宿主机中的conf目录下进行操作,html目录同理。

当需要修改/更新等操作时修改的实际上是宿主主机文件系统中的目录下的内容,就算将容器删除之后,数据也是存在的,如果想要获取原来的数据,只需要再将数据卷挂载到宿主文件系统中对应的目录就行了。

常用命令

  • docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:

  • create 创建一个volume

sh 复制代码
# 创建一个名为html的数据卷
docker volume create html 
  • inspect 显示一个或多个volume的详细信息
sh 复制代码
docker volum inspect html

在该命令中我们可以查看该数据卷的详细信息,包括数据卷在宿主机中的存储位置:

可以看到该数据卷在宿主机中的实际位置是"/var/lib/docker/volumes/html/_data".

  • ls 列出所有的volume
sh 复制代码
docker volume ls 
  • prune 删除未使用的volume

  • rm 删除一个或多个指定的volume

数据卷挂载案例

  • 创建容器并挂载数据卷到容器内的目录
sh 复制代码
docker run --name mv -v html:/usr/share/nginx/html -p 80:80 -d nginx
# 创建容器的命令与之前相同,-v html:/usr/share/nginx/html 挂载数据卷html到容器内的/usr/share/nginx/html目录上

进入html数据卷所在位置,并修改HTML内容

sh 复制代码
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html

在宿主机下修改完成之后(或者说是在数据卷下修改之后),容器中的对应的文件也会同步修改。

数据卷挂载案例之二

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:

  • 带数据卷模式:宿主机目录 --> 数据卷 ---> 容器内目录
  • 直接挂载模式:宿主机目录 ---> 容器内目录

目录挂载与数据卷挂载的语法是类似的:

  • -v [宿主机目录]:[容器内目录]
  • -v [宿主机文件]:[容器内文件]

案例:创建并运行一个MySQL容器,将宿主机目录直接挂载到容器

1.创建目录/tmp/mysql/,以及2个子目录:/tmp/mysql/data , /tmp/mysql/conf

sh 复制代码
cd /tmp # /tmp已经存在
mkdir /mysql
mkdir /mysql/data
mkdir /mysql/conf

2.以mysql为例,首先拉取8.0.33版本的mysql镜像

sh 复制代码
docker pull docker:8.0.33

3.查看镜像列表是否成功导入

sh 复制代码
docker images

4.导入mysql的一个额外配置文件hmy.cnf

5.创建mysql容器

sh 复制代码
docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123 \
-p 3306:3306 \
-v /tmp/mysql/conf/hmy.conf:/ect/mysql/conf.d/hmy.cnf \
-v /tmp/mysql/data:/var/lib/mysql \
-d \
mysql:8.0.33

运行成功之后,返回mysql容器ID,使用docker ps命令查看

然后在外部(你的主机)使用mysql客户端连接

提示连接成功则成功

相关推荐
艾伦~耶格尔4 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
wusam5 小时前
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习04(环境准备)
学习·docker·centos
攸攸太上5 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
_.Switch7 小时前
Python机器学习框架介绍和入门案例:Scikit-learn、TensorFlow与Keras、PyTorch
python·机器学习·架构·tensorflow·keras·scikit-learn
wusam8 小时前
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)
运维·服务器·网络·docker·容器
一直在进步的派大星8 小时前
Docker 从安装到实战
java·运维·docker·微服务·容器
神一样的老师13 小时前
构建5G-TSN测试平台:架构与挑战
5g·架构
技术钱13 小时前
docker简介
运维·docker·容器
huaqianzkh13 小时前
付费计量系统通用功能(13)
网络·安全·架构
roman_日积跬步-终至千里14 小时前
【docker】docker常见命令
运维·docker·容器