docker容器

发表于2023-07-21|更新于2023-07-21

|阅读量:

1.初始docker?

●什么是docker?

●docker和虚拟机的区别

●docker架构

●安装docker

1.1什么是docker?

docker的基本概念

镜像:docker镜像是docker的基础,是一种轻量级、可移植的软件包,包含了将应用程序运行所需要的文件、库、环境变量、配置等。

1
$ docker pull nginx  #下载nginx镜像

容器:docker容器是docker镜像的一个实例,运行应用程序的一个独立的运行环境。

1
2
$ docker run --name my-nginx -d nginx  #在后台运行一个nginx容器
$ docker run nginx #运行停止的容器

仓库:用来存储、发布、管理docker的平台,和代码托管平台类似。Docker hub是最常用的公共仓库,在其中可以找到各种各样的镜像。

1
$ docker pull ubuntu  #下载Ubuntu镜像

dockerfile:是用于构建Docker镜像的脚本文件,可以用来指定镜像的基础映像、添加应用程序和配置运行环境等。

docker的作用

可以将程序及其依赖、运行环境一起打包成一个镜像,镜像可以任意迁移到linux操作系统;运行时利用沙箱机制形成隔离容器,即互相隔离,各个应用互不干扰;启动和运行通过docker命令完成,方便管理。

docker的引入

多模块开发或微服务项目在运行部署时较为复杂,会依赖各种各样的应用,比如node.js、redis、ravvitmq等等组件,而不同的服务所需要的依赖和函数库有差异,所以依赖关系复杂,容易出现兼容性问题。而这时,docker就出现了!

docker如何解决依赖的兼容性问题

docker将应用的依赖、函数库、配置和应用一起打包,即一个镜像文件。各个应用之间属于不同的隔离容器,互不干扰。

eg:ubuntu系统上的应用需要借助msql服务,而把这个应用迁移到centos上时,服务的msql去调用函数库时就会出现问题而报错。docke可以在ubuntu系统上将该应用和所需要的函数库进行打包,然后迁移到centos系统上时,改应用可以直接基于打包的函数库,借助centos的linux内核来运行服务。

docker如何解决大型项目依赖关系复杂,不同组件依赖兼容性问题

在开发多服务项目时,可以将单个服务所需要的应用、依赖、函数库、配置一起打包,形成可移植镜像。

Docker如何解决开发、测试、生产环境有差异的问题

docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行。

1.2docker和虚拟机

docker和虚拟机的差异

虚拟机:虚拟机是操作系统中模拟硬件设备,然后运行虚拟的操作系统,比如在windows系统中使用ubuntu系统。性能较差

docker:docker是封装函数库,是一个系统进程,性能好。

1.3docker架构

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

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

●客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。

1.4docker的安装

企业部署一般都是采用Linux操作系统,而其中又数CentOS发行版占比最多,Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10,CentOS 7满足最低内核要求。

1.卸载(可选,若以前安装错误,可以卸载)

1
2
3
4
5
6
7
8
9
10
11
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.安装yum工具

1
2
3
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken

3.更新本地镜像源,配置阿里云仓库

1
2
3
4
5
6
7
8
# 设置docker镜像源
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

4.安装社区版docker

1
yum install -y docker-ce

5.关闭防火墙

1
2
3
4
# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld

6.启动docker

1
2
3
4
5
6
7
8
# 启动docker服务
systemctl start docker

# 停止docker服务
systemctl stop docker

# 重启docker服务
systemctl restart docker

7.查看版本

1
docker -v

附:配置镜像加速:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors阿里云镜像加速文档

2.docker基本操作

拉取镜像

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
025c56f98b67: Pull complete
ec0f5d052824: Pull complete
cc9fb8360807: Pull complete
defc9ba04d7c: Pull complete
885556963dad: Pull complete
f12443e5c9f7: Pull complete
Digest: sha256:75263be7e5846fc69cb6c42553ff9c93d653d769b94917dbda71d42d3f3c00d3
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

查看镜像

1
2
3
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3964ce7b8458 4 days ago 142MB

导出镜像

1
2
docker save -o [保存的目标文件名称] [镜像名称]
docker save -o nginx.tar nginx:latest

删除本地镜像

1
docker rmi nginx:latest # rmi是remove image的缩写

加载镜像

1
2
docker load -i [镜像压缩文件名]
docker load -i nginx.tar

容器操作

  • docker run:创建并运行一个容器,处于运行状态
    • --name:指定容器名称
    • -p:指定端口映射
    • -d:让容器后台运行
  • docker pause:让一个运行的容器暂停
  • docker unpause:让一个容器从暂停状态恢复运行
  • docker stop:停止一个运行的容器
  • docker start:让一个停止的容器再次运行
  • docker rm:删除一个容器
  • 查看容器状态:
    • docker ps
    • docker ps -a 查看所有容器,包括已停止的
  • 查看容器日志的命令
    • docker logs
    • 添加-f参数可以持续查看日志

3数据卷

概念:是一个虚拟目录,指向宿主机文件系统中的某个目录。将来容器删了,数据卷还在,有新版本的,只要挂载在数据卷上就行了,可以共享以前旧的数据了。

●不便于修改:当我们要修改容器的内容时,比如修改nginx的html内容,需要进入容器内部修改,不方便,可以直接改数据卷。

1
●数据不可复用:在容器内的修改是对外不可见的。即所有修改对新创建的容器时不可复用的。

●升级维护困难:数据在容器内,如果要升级容器必然删掉旧容器,所有的数据就会跟着一起被删除。

数据卷操作:

docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:(常用命令)
●create : 创建一个volume
●inspect : 显示一个或多个volume的信息
●ls : 列出所有的volume
●prune : 删除未使用的volume
●rm : 删除一个或多个指定的volume

数据卷挂载:创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器目录

1
-v html:/root/html\

前半部分是数据卷,后半部分是容器内的目录,将名为“html”的数据卷,挂载到容器的 /root/html 的目录下

●方式1

案例:创建一个nginx容器,修改容器内的html目录内的index.html内容

需求说明:使用Docker-容器命令进入nginx容器内部,已经知道nginx的html目录的所在位置 、/usr/share/nginx/html 我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。

1.创建容器并挂载数据卷到容器内的HTML目录

1
2
3
4
5
6
7
docker volume create html # 创建html数据卷
docker ps -a # 查看容器
docker run --name mn -p 80:80 -v html:/usr/share/nginx/html -d nginx # 创建 nginx容器,并挂载到html数据卷
docker ps # 查看容器已创建
docker inspect html # 查看数据卷的位置
cd /var/lib/docker/volumes/html/_data # 进入数据卷
ls # 查看文件

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

修改内容后使用cat index.html或浏览器访问nginx页面来查看效果

3查看没有数据卷情况下创建容器

1
2
3
4
docker rm -f mn # 删除容器
docker volume prune # 删除数据卷
docker run --name mn -p 80:80 -v html:/usr/share/nignx/html -d nginx # 重新创建容器,并挂载到数据卷上,此时是没有html这个数据卷的,刚刚删除了
docker volume ls # 查看数据卷的时候,有了html这个数据卷

数据卷不存在,docker自动帮我们把这个数据卷创建出来。

●方式2(暂时没搞)

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

●数据卷挂载的方式对比

当我们用数据卷时,我们的docker会全自动帮我创建数据卷对应的目录,这样数据卷就指向了目录。
容器挂载时只需要挂载到数据卷,不用关心目录在哪里,这全交给docker去处理了。但这个劣势是目录不是我们创建的,找目录比较麻烦。(自动化隐藏细节)
第二种方式是目录挂载,目录是我们自己创建的,挂载的时候,容器直接挂载上去。(这个细节自己实现,没有自动化)

本节小结
1.docker run的命令中通过-V参数挂载文件或目录到容器中:

  • -v volume名称:容器内目录
  • -v宿主机文件容器内文件
  • -v宿主机目录容器内目录

2.数据卷挂载与目录直接挂载的

  • 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
  • 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看

4dockerfile自定义镜像

镜像结构

概念:镜像是将应用程序文件以及其所需要的系统函数库、环境、配置、依赖一同打包而成。

本节小结:

镜像是分层结构,每一层称为一个Layer

  • Baselmage层:包含基本的系统函数库、环境变量、文件系统
  • Entrypoint: 入口,是镜像中应用启动的命令
  • 其它:在Baselmage基础上添加依赖、安装程序、完成整个应用的
    安装和配置

dockerfile语法

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

基础命令:

FROM 是指定一个基础镜像,一般是操作系统, FROM centos:7,就是基于centos:7去构建,或者其他系统,就是基于该系统去构建。

ENV (entry value)是环境变量,一般都是键值对,配好后,后续中都可以使用环境变量里面配置好的东西。比如一个目录,配好后都可以使用这个目录。

COPY 复制,比如本地有一个Java的项目包(jar包),需要复制到镜像里面去,都可以使用COPY这个指令复制进去。

RUN 是执行Linux的shell命令,一般都是安装命令,比如有一个依赖需要安装或者解压,都可以使用RUN后面跟上shell的命令就行了。

EXPOSE 是暴露端口,这不是真正暴露端口,之前-p这个才是宿主机和容器暴露什么端口,EXPOSE只是指定容器内监听的是什么端口,是给镜像使用者看的,比如看到的是8080,那-p 8080:8080(冒号后面这一部分就是8080,注意是冒号“:”后面)。

ENTPYPOINT 启动命令,一个镜像要有一个启动脚本,jar的启动脚本有些人可能有接触过,java -jar xx.jar(应该有人在命令控制台启动过吧,没启动过也没关系),ENTPYPOINT java -jar xx.jar。

案例:
基于Ubuntu镜像构建一个新镜像,运行一个java项目
步骤1:新建一个空文件夹docker-demo;
步骤2:拷贝课前资料中的docker-demojar文件到docker-demo这个目录;
步骤3:拷贝课前资料中的jdk8.tar.gz文件到docker-demo这个目录;
步骤4:拷贝课前资料提供的Dockerfile到docker-demo这个目录;
步骤5:进入docker-demo;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 指定基础镜像
FROM ubuntu:16.04

# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local

# 拷贝jdk的到JAVA_DIR目录下
COPY ./jdk8.tar.gz $JAVA_DIR/

# 安装JDK
RUN cd $JAVA_DIR && tar -xf ./jdk8.tar.gz && mv ./jdk1.8.0_44 ./java8

# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 拷贝java项目的包到指定目录下,我这里是/tmp/app.jar
COPY ./docker-demo.jar /tmp/app.jar

# 暴露端口,注意这里是8090端口,如果你之前没有关闭防火墙,请关闭防火墙或打开对应端口,云服务器同理
EXPOSE 8090

# 入口,java项目的启动命令
ENTERPOINT java -jar /tmp/app.jar

步骤6在docker-demo目录下使用docker build命令构建镜像

1
docker build -t docker_demo:1.0 .

步骤7使用docker images命令,查看镜像

1
2
3
[root@localhost docker-demo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker_demo 1.0 c8acd2dd02cf About a minute ago 722MB

步骤8创建并运行一个docker_demo容器

1
docker run --name testDemo -p 8090:8090 -d docker_demo:1.0

步骤9浏览器访问http://192.168.128.130:8090/hello/count,即可看到页面效果(注意修改虚拟机ip)

本节小结:

  1. Dockerfile本质就是一个文件,通过指令描述镜像的构建过程
  2. Dockerfile的第一行必须是FROM,从一个基础镜像来构建
  3. 基础镜像可以使基本操作系统,如Ubunut,也可以是其他人制作好的镜像,例如openjdk:8

docker-compose(暂未学习)

Docker Compose可以基于Compose文件帮我们快速地部署分布式英语,而无需手动一个个创建和运行容器

docker镜像仓库(暂未学习)

搭建私有镜像仓库

推送、拉取镜像