Docker
本文最后更新于49 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

1、docker简介

(1)应用部署的环境问题

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

  • 依赖关系复杂,容易出现兼容性问题
  • 开发、测试、生产环境有差异

一个项目中,部署时需要依赖于node.js、Redis、RabbitMQ、MySQL等,这些服务部署时所需要的函数库、依赖项各不相同,甚至会有冲突。给部署带来了极大的困难。

(2)Docker解决依赖兼容问题

  • 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
  • 将每个应用放到一个隔离容器去运行,避免互相干扰

打包好的应用包,既包含应用本身,也有应用所需要的Libs、Deps,无需再操作系统上安装这些,自然就不存在应用兼容问题。

(3)Docker解决操作系统环境差异

Ubuntu和CentOS SpringBoot都是基于Linux内核,无非是系统应用不同,提供的函数库有差异。

如果将一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或者不匹配,就会报错了。

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

(4)docker的安装及部署

以CentOS 7 为例
​
// 卸载旧版docker,避免存在旧版本
yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine \
    docker-selinux 
    
// 配置Docker的yum库
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
​
// 设置镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
// 安装docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin  docker-compose-plugin
​
// 版本查看
docker -v
​
// 启动与停止
systemctl start docker
systemctl stop docker
​
// 重启
systemctl restart docker
​
// 设置开机自启
systemctl enable docker
​
// 执行dockerps命令,如果不报错,说明安装启动成功
docker ps
​
// 配置docker镜像加速器
​
// 部署mysql
docker run -d \                             docker run :创建并运行一个容器,-d 是让容器在后台运行
  --name mysql \                            --name mysql :给容器起个名字,必须唯一
  -p 3306:3306 \                            -p 3306:3306 :设置端口映射,前3306为宿主机端口,后为容器内端口,无需改动
  -e TZ=Asia/Shanghai \                     时区,东八区
  -e MYSQL_ROOT_PASSWORD=123 \              -e KEY=VALUE :是设置环境变量,root用户密码123
  -v /root/mysql/data:/var/lib/mysql \
  -v /root/mysql/init:/docker-entrypoint-initdb.d \
  -v /root/mysql/conf:/etc/mysql/conf.d \
  mysql                                     mysql :指定运行的镜像的名字,一般为mysql:版本,不写版本默认最新
​
docker run -d --name mysql -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql
​
# 然后就可以远程连接

2、Docker和虚拟机的区别

虚拟机:在操作系统中模拟硬件设备,然后运行另一个操作系统。

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

Docker和虚拟机的差异:

  • docker是一个系统进程;虚拟机是在操作系统中的操作系统
  • docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般

3、Docker架构

(1)镜像和容器

镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像,是只读的。

容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。

一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的文件。只有运行时,才会加载到内存,形成进程。

一个镜像可以有多个容器。

(2)DockerHub

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

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

可将自己的镜像共享到DockerHub,也可从DockerHub拉取镜像:

(3)Docker架构

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

  • 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等
  • 客户端(client):通过命令或Rest API向Docker服务端发送指令。可以在本地或远程向服务端发送指令。

4、Docker的基本操作

镜像的名称组成:

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

(1)镜像命令

常见的镜像操作命令:

(2)命令别名

// 列出容器的 ID、镜像名称、端口映射、运行状态和容器名称,并以对齐的表格布局输出
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}'
// 命令太长,简化:
// 步骤:
    1. vi ~/.bashrc
    2. 编辑
        alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
        alias dis='docker images'
    3. 生效
        source ~/.bashrc

5、容器操作

(1)容器相关命令

容器保护三个状态:

  • 运行:进程正常运行
  • 暂停:进程暂停,CPU不再运行,并不释放内存
  • 停止:进程终止,回收进程占用的内存、CPU等资源

其中:

  • docker run:创建并运行一个容器,处于运行状态
  • docker pause:让一个运行的容器暂停
  • docker unpause:让一个容器从暂停状态恢复运行
  • docker stop:停止一个运行的容器
  • docker start:让一个停止的容器再次运行
  • docker rm:删除一个容器

(2)创建并运行一个容器

docker run --name containerName -p 80:80 -d nginx
​
docker run :创建并运行一个容器
--name : 给容器起一个名字,比如叫做mn
-p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
-d :后台运行容器
nginx:镜像名称,例如nginx
​
docker ps  查看容器状态
docker logs  添加-f参数可以持续查看日志

可以在宿主机上通过虚拟机的IP+宿主机的映射端口进去查看

(3)进入容器,修改文件

docker exec -it mn bash
​
docker exec : 进入容器内部,执行一个命令
-i : (交互模式):保持标准输入开放,允许用户与容器交互
-t : (伪终端):分配一个虚拟终端,使交互更自然
-it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
mn : 要进入的容器的名称
bash : 进入容器后执行的命令,bash是一个linux终端交互命令
​
//知道nginx的html目录位置在/usr/share/nginx/html
//执行命令,进入该目录:
cd /usr/share/nginx/html
​
//容器内没有vi命令,无法直接修改,我们用下面的命令来修改:
sed -i -e 's#Welcome to nginx#传智教育欢迎您#g' index.html
sed -i -e 's#<head>#<head><meta charset="utf-8">#g' index.html

6、数据卷(容器数据管理)

容器内修改数据很困难,所以诞生了数据卷,这是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。

(1)数据卷

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

一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了,形成双向绑定。

(2)数据集操作命令

命令说明文档地址
docker volume create创建数据卷docker volume create
docker volume ls查看所有数据卷docker volume ls
docker volume rm删除指定数据卷docker volume rm
docker volume inspect查看某个数据卷的详情docker volume inspect
docker volume prune清除数据卷docker volume prune

(3)挂载数据卷

1)给nginx挂载数据卷

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

docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx

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

# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件,用vscode修改
vi index.html

2)给MySQL挂载本地目录

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。

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

  • -v [宿主机目录]:[容器内目录]
  • -v [宿主机文件]:[容器内文件]
docker run \
 --name mysql \ 
 -e MYSQL_ROOT_PASSWORD=cjn \
 -p 3306:3306 \
 -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \
 -v /tmp/mysql/data:/var/lib/mysq \
 -d \
 mysql:latest
docker run --name mysql -e MYSQL_ROOT_PASSWORD=cjn -p 3306:3306 -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf -v/tmp/mysql/data:/var/lib/mysql -d mysql:latest
​
//然后就可以用宿主机连接了

7、Dockerfile自定义镜像

(1)镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。

以MySQL为例:

镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。构建镜像,其实就是实现上述打包的过程。

(2)Dockerfile语法

构建自定义的镜像时,并不需要去拷贝,打包,只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。

描述上述信息的文件就是Dockerfile文件。

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

更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder

(3)构建Java项目

1)基于Ubuntu镜像构建一个新镜像,运行一个java项目

  • 新建一个空文件夹docker-demo
  • 拷贝课前资料中的docker-demo.jar文件到docker-demo这个目录
  • 拷贝课前资料中的jdk8.tar.gz文件到docker-demo这个目录
  • 拷贝课前资料提供的Dockerfile到docker-demo这个目录

Dockerfile的内容如下:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
​
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
​
# 安装JDK
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8
​
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
​
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
  • 进入docker-demo
  • 运行命令:docker build -t javaweb:1.0 .

2)基于java8构建Java项目

# Dockerfile文件
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar

3)运行

docker build -t myImage:1.0 .
-t : 给镜像起名,格式依然是repository:tag的格式,不指定tag时,默认为latest
. : 指定Dockerfile所在目录,在当前目录则指定为"."

8、Docker-Compose

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

(1)初识Docker-Compose

Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下:

version: "3.8"
​
services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall
    networks:
      - hm-net
networks:
  hm-net:
    name: hmall

上面的Compose文件就描述一个项目,其中包含两个容器:

  • mysql:一个基于mysql:5.7.25镜像构建的容器,并且挂载了两个目录
  • web:一个基于docker build临时构建的镜像容器,映射端口时8090

Docker-Compose的详细语法参考官网:https://docs.docker.com/compose/compose-file/

其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,只是语法稍有差异。

(2)安装DockerCompose

(3)部署微服务集群

9、Docker网络

默认情况下,所有容器都是以bridge方式连接到Docker的一个虚拟网桥上:

docker会在启动容器给你分配ip地址,但如果重新启动,那么就会重新分配,所以得自定义网络。

加入自定义网络的容器才可以通过容器名互相访问,Docker的网络操作命令如下:

命令说明
docker network create创建一个网络
docker network ls查看所有网络
docker network rm删除指定网络
docker network prune清除未使用的网络
docker network connect使指定容器连接加入某网络
docker network disconnect使指定容器连接离开某网络
docker network inspect查看网络详细信息
docker network create heima
​
docker network connect heima mysql
​
docker run -d --name dd -p 8080:8080 --network heima docker-demo

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇