Docker-02-基础

1 常见命令

Docker最常见的命令就是操作镜像、容器的命令,详见官方文档: Docker Docs

视图:

命令:

命令说明文档地址
docker pull拉取镜像docker pull
docker push推送镜像到DockerRegistrydocker push
docker images查看本地镜像docker images
docker rmi删除本地镜像docker rmi
docker run创建并运行容器(不能重复创建)docker run
docker stop停止指定容器docker stop
docker start启动指定容器docker start
docker restart重新启动容器docker restart
docker rm删除指定容器docker rm
docker ps查看容器docker ps
docker logs查看容器运行日志docker logs
docker exec进入容器docker exec
docker save保存镜像到本地压缩文件docker save
docker load加载本地压缩文件到镜像docker load
docker inspect查看容器详细信息docker inspect
docker exec -it 容器名称 bash进入容器内部

默认情况下,每次重启虚拟机都需要手动启动Docker和Docker中的容器,以下命令可以实现开机自启:

# Docker开机自启
systemctl enable docker

# Docker容器开机自启
docker update --restart=always [容器名/容器id]

2 数据卷

容器是隔离环境,容器内程序的文件、配置、运行时产生的数据都在容器内部,与容器绑定。在某些情况下会带来一些问题,例如:

  • 容器被销毁,它的数据也会被一起销毁;

  • 容器运行后,其中的某些配置无法被修改;

  • Nginx容器无法代理容器外的静态资源;

因此,容器提供程序的运行环境,但是 程序运行产生的数据、程序运行依赖的配置等都应该与容器解耦。

2.1 概述

  • 数据卷(volume)是一个虚拟目录,它将宿主机目录映射到容器内目录;

  • 在创建容器时,利用 -v 数据卷名(或本地目录名):容器内目录 完成挂载,本地目录必须以路径开头;

2.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

2.3 挂载数据卷

以Nginx为例,Nginx中有两个关键的目录:

  • html:放置一些静态资源

  • conf:放置配置文件

如果我们要让Nginx代理我们的静态资源,最好是将资源放到html目录;

如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件;

但遗憾的是,容器运行的Nginx所有的文件都在容器内部,读写都非常不方便。所以我们通常会利用数据卷将这两个目录与宿主机目录关联起来,方便我们操作。

视图:

操作:

# 1.创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d \
		--name nginx \
		-p 80:80 \
		-v html:/usr/share/nginx/html \	# 数据卷名(或本地目录名): 容器内目录
		nginx
		
# 2.查看数据卷
docker volume ls
# 结果
DRIVER    VOLUME NAME
local     29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local     html

# 3.查看数据卷详情
docker volume inspect html
# 结果
[
    {
        "CreatedAt": "2023-09-17T19:57:08+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/html/_data",
        "Name": "html",
        "Options": null,
        "Scope": "local"
    }
]

# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2022 50x.html
-rw-r--r--. 1 root root 615 12月 28 2022 index.html

# 5.进入该目录,随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html

# 6.打开页面,查看效果

# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash

2.4 挂载本地目录

  • 在执行docker run命令时,使用 -v 本地目录 : 容器内目录 可以完成本地目录挂载;

  • 本地目录必须以 “/” 或 “./” 开头,如果直接以名字开头,会被识别为数据卷而非本地目录;

    • -v mysql : /var/lib/mysql 会被识别为一个叫mysql,运行时会自动创建这个数据卷

    • -v ./mysql : /var/lib/mysql 会被识别为当前目录下的mysql目录,如果不存在会自动创建

mysql容器挂载本地目录示例: 

# 创建并运行新mysql容器,挂载本地目录
docker run -d \
	--privileged=true \
	--name mysql \
	-p 3306:3306 \
	-e TZ=Asia/Shanghai \
	-e MYSQL_ROOT_PASSWORD=123456 \
	-v /root/mysql/data:/var/lib/mysql \
	-v /root/mysql/log:/var/log/mysql \
	-v /root/mysql/conf:/etc/mysql/conf.d \
	mysql:latest
	
# 查看root/mysql目录
cd root/mysql/
ll 
# 结果:
总用量 4
drwxr-xr-x. 2 root    root    6 9月  23 12:12 conf
drwxr-xr-x. 6 polkitd root 4096 9月  23 12:34 data
drwxr-xr-x. 2 root    root    6 9月  23 12:12 init
drwxr-xr-x. 2 root    root    6 9月  23 12:34 log

# 查看data目录,发现里面有大量数据库数据,说明数据库完成了初始化
ls -l data
# 结果:
总用量 198056
-rw-r-----. 1 polkitd input       56 9月  23 12:34 auto.cnf
-rw-r-----. 1 polkitd input  3116921 9月  23 12:34 binlog.000001
-rw-r-----. 1 polkitd input      156 9月  23 12:34 binlog.000002
-rw-r-----. 1 polkitd input       32 9月  23 12:34 binlog.index
-rw-------. 1 polkitd input     1680 9月  23 12:34 ca-key.pem
-rw-r--r--. 1 polkitd input     1112 9月  23 12:34 ca.pem
-rw-r--r--. 1 polkitd input     1112 9月  23 12:34 client-cert.pem
-rw-------. 1 polkitd input     1676 9月  23 12:34 client-key.pem
-rw-r-----. 1 polkitd input   196608 9月  23 12:37 #ib_16384_0.dblwr
-rw-r-----. 1 polkitd input  8585216 9月  23 12:34 #ib_16384_1.dblwr
-rw-r-----. 1 polkitd input     5678 9月  23 12:34 ib_buffer_pool
-rw-r-----. 1 polkitd input 12582912 9月  23 12:35 ibdata1
-rw-r-----. 1 polkitd input 50331648 9月  23 12:37 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 9月  23 12:34 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 9月  23 12:35 ibtmp1
drwxr-x---. 2 polkitd input      187 9月  23 12:34 #innodb_temp
drwxr-x---. 2 polkitd input      143 9月  23 12:34 mysql
-rw-r-----. 1 polkitd input 31457280 9月  23 12:35 mysql.ibd
drwxr-x---. 2 polkitd input     8192 9月  23 12:34 performance_schema
-rw-------. 1 polkitd input     1676 9月  23 12:34 private_key.pem
-rw-r--r--. 1 polkitd input      452 9月  23 12:34 public_key.pem
-rw-r--r--. 1 polkitd input     1112 9月  23 12:34 server-cert.pem
-rw-------. 1 polkitd input     1680 9月  23 12:34 server-key.pem
drwxr-x---. 2 polkitd input       28 9月  23 12:34 sys
-rw-r-----. 1 polkitd input 16777216 9月  23 12:37 undo_001
-rw-r-----. 1 polkitd input 16777216 9月  23 12:37 undo_002

# 通过以下命令可以登录mysql容器
docker exec -it mysql mysql -uroot -p123456

nginx容器挂载本地目录示例:

docker run -d \
  --name nginx \
  -p 18080:18080 \
  -p 18081:18081 \
  -v /root/nginx/html:/etc/nginx/html \
  -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
  --network hmall \
  nginx

3 自定义镜像

  • DK

  • 上传Jar包

  • 运行jar包

构建Java镜像步骤:

  • 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)

  • 安装并配置JDK

  • 拷贝jar包

  • 配置启动脚本

3.2 镜像结构

  1. 入口(Entrypoint):镜像运行入口,一般是程序启动的脚本和参数;

  2. 层(Layer):在BaseImage基础上添加安装包、依赖、配置等,每次操作都形成新的一层;

  3. 基础镜像(BaseImage):应用依赖的系统函数库、环境、配置、文件等;

3.3 Dockerfile

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指定如下:

指令说明示例
FROM指定基础镜像FROM centos:6
ENV设置环境变量,可在后面指令使用ENV key value
COPY拷贝本地文件到镜像的指定目录COPY ./xx.jar /tmp/app.jar
RUN执行Linux的shell命令,一般是安装过程的命令RUN yum install gcc
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的EXPOSE 8080
ENTRYPOINT镜像中应用的启动命令,容器运行时调用ENTRYPOINT java -jar xx.jar

更多语法可以参考官方文档: Dockerfile reference | Docker Docs

基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装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 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]

JDK基础镜像:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

3.4 构建镜像

当Dockerfile文件写好以后,就可以利用命令来构建镜像。

构建镜像命令:

docker build -t docker-demo:1.0 .
  • docker build: 就是构建一个docker镜像;

  • -t docker-demo:1.0-t参数是指定镜像的名称(repositorytag),不指定tag时,默认为latest;

  • . : 最后的点是指构建时Dockerfile所在路径,.代表当前目录,也可以直接指定目录;

# 直接指定Dockerfile目录
docker build -t docker-demo:1.0 /root/demo

4 网络

  • 容器的网络IP是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP

    发生变化,连接会失败。因此,可以借助于docker的网络功能来解决这个问题;

  • docker的网络功能无需记住IP地址也可以实现容器互联;

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

官方文档:docker network

常见命令有:

命令说明文档地址
docker network create创建一个网络docker network create
docker network ls查看所有网络docker network ls
docker network rm删除指定网络docker network rm
docker network prune清除未使用的网络docker network prune
docker network connect使指定容器连接加入某网络docker network connect
docker network disconnect使指定容器连接离开某网络docker network disconnect
docker network inspect查看网络详细信息docker network inspect

自定义网络:

# 1.首先通过命令创建一个网络
docker network create hmall

# 2.然后查看网络
docker network ls
# 结果:
NETWORK ID     NAME      DRIVER    SCOPE
639bc44d0a87   bridge    bridge    local
403f16ec62a2   hmall     bridge    local
0dc0f72a0fbb   host      host      local
cd8d3e8df47b   none      null      local

# 其中,除了hmall以外,其它都是默认的网络

# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!

# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect hmall mysql --alias db

# 3.2.db容器,也就是我们的java项目
docker network connect hmall dd

# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash

# 4.2.用db别名访问
ping db
# 结果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms

# 4.3.用容器名访问
ping mysql
# 结果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms

5 DockerCompose

5.1 概述

Docker Compose指通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器,帮助我们实现多个相互关联的Docker容器的快速部署;

  • 项目(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义;

  • 服务(service):一个应用的容器,定义某个应用的运行时参数,实际上可以包括若干运行相同镜像的容器实例;

servicedocker run的参数类似。

举例来说,用docker run部署MySQL的命令如下:

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  --network work01
  mysql

如果用docker-compose.yml文件来定义,就是这样:

docker-compose.yml文件的基本语法参考文档:Compose file version 3 reference

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:											# 网络
      - new
      
  hmall:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - new
    depends_on:
      - mysql
      
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/etc/nginx/html"
    depends_on:
      - hmall
    networks:
      - new
      
networks:
  new:
    name: work01

对比如下:

docker run 参数docker compose 指令说明
--namecontainer_name容器名称
-pports端口映射
-eenvironment环境变量
-vvolumes数据卷配置
--networknetworks网络

5.2 基础命令

docker-compose.yml编辑好之后,需要部署docker-compose.yml文件项目,常见的命令如下:

基本语法:docker compose [OPTIONS] [COMMAND]

其中,OPTIONS和COMMAND都是可选参数,比较常见的有:

类型参数或指令说明
Options-f指定compose文件的路径和名称
-p指定project名称。project就是当前compose文件中设置的多个service的集合,是逻辑概念
Commandsup创建并启动所有service容器
down停止并移除所有容器、网络
ps列出所有启动的容器
logs查看指定容器的日志
stop停止容器
start启动容器
restart重启容器
top查看运行的进程
exec在指定的运行中容器中执行命令

示例:

# 1.进入root目录
cd /root

# 2.删除旧容器
docker rm -f $(docker ps -qa)

# 3.删除hmall镜像
docker rmi hmall

# 4.清空MySQL数据
rm -rf mysql/data

# 5.启动所有, -d 参数是后台启动
docker compose up -d

# 结果:
[+] Building 15.5s (8/8) FINISHED
 => [internal] load build definition from Dockerfile                                    0.0s
 => => transferring dockerfile: 358B                                                    0.0s
 => [internal] load .dockerignore                                                       0.0s
 => => transferring context: 2B                                                         0.0s
 => [internal] load metadata for docker.io/library/openjdk:11.0-jre-buster             15.4s
 => [1/3] FROM docker.io/library/openjdk:11.0-jre-buster@sha256:3546a17e6fb4ff4fa681c3  0.0s
 => [internal] load build context                                                       0.0s
 => => transferring context: 98B                                                        0.0s
 => CACHED [2/3] RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo   0.0s
 => CACHED [3/3] COPY hm-service.jar /app.jar                                           0.0s
 => exporting to image                                                                  0.0s
 => => exporting layers                                                                 0.0s
 => => writing image sha256:32eebee16acde22550232f2eb80c69d2ce813ed099640e4cfed2193f71  0.0s
 => => naming to docker.io/library/root-hmall                                           0.0s
[+] Running 4/4
 ✔ Network hmall    Created                                                             0.2s
 ✔ Container mysql  Started                                                             0.5s
 ✔ Container hmall  Started                                                             0.9s
 ✔ Container nginx  Started                                                             1.5s

# 6.查看镜像
docker compose images

# 结果
CONTAINER           REPOSITORY          TAG                 IMAGE ID            SIZE
hmall               root-hmall          latest              32eebee16acd        362MB
mysql               mysql               latest              3218b38490ce        516MB
nginx               nginx               latest              605c77e624dd        141MB

# 7.查看容器
docker compose ps

# 结果
NAME                IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
hmall               root-hmall          "java -jar /app.jar"     hmall               54 seconds ago      Up 52 seconds       0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
mysql               mysql               "docker-entrypoint.s…"   mysql               54 seconds ago      Up 53 seconds       0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp
nginx               nginx               "/docker-entrypoint.…"   nginx               54 seconds ago      Up 52 seconds       80/tcp, 0.0.0.0:18080-18081->18080-18081/tcp, :::18080-18081->18080-18081/tcp

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值