Docker学习笔记

1. Docker入门

  • 镜像(image):镜像包含应用本身,以及应用所需的环境、配置、系统函数库等
  • 容器(container):Docker在运行镜像时会创建一个隔离环境,称为容器
  • 镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库(Docker Hub)

docker

镜像命名规范:

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

2. 常用命令

2.1 命令介绍

docker最常用的命令就是操作镜像、容器的命令

# Docker开机自启
	systemctl enable docker

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

# 镜像操作常用命令
	docker pull 	# 拉取镜像
	docker push 	# 推送镜像
	docker images 	# 查看本地镜像
	docker rmi 		# 删除镜像
	docker load 	# 加载本地压缩文件到镜像
	
# 容器操作常用命令
	docker run 		# 创建并运行容器
	docker stop 	# 停止指定容器
	docker start 	# 启动指定容器
	docker restart 	# 重启指定容器
	docker rm 		# 删除指定容器
	docker ps 		# 查看容器
	docker logs 	# 查看容器日志
	docker exec 	# 进入容器
	docker save 	# 保存容器到本地压缩文件
	docker inspect 	# 查看容器详细信息

常用命令


2.2 命令演示

以Nginx为例给说明上述命令:

# 第1步,去 DockerHub查看 nginx镜像仓库及相关信息

# 第2步,拉取 Nginx镜像
docker pull nginx

# 第3步,查看镜像
docker images
# 结果如下:
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    605c77e624dd   16 months ago   141MB
mysql        latest    3218b38490ce   17 months ago   516MB

# 第4步,创建并允许Nginx容器
docker run -d --name nginx -p 80:80 nginx

# 第5步,查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第6步,访问网页,地址:http://虚拟机地址

# 第7步,停止容器
docker stop nginx

# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第9步,再次启动nginx容器
docker start nginx

# 第10步,再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第11步,查看容器详细信息
docker inspect nginx

# 第12步,进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p

# 第13步,删除容器
docker rm nginx
# 发现无法删除,因为容器运行中,强制删除容器
docker rm -f nginx

2.3 命令别名

简化命令书写

# 修改/root/.bashrc文件
vi ~/.bashrc

# 新增别名
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'

# 更新修改
source ~/.bashrc

命令别名

3. 数据卷

容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。

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

3.1 什么是数据卷

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。

# 数据卷相关命令
	docker volume create 	# 创建数据卷
	docker volume ls 		# 查看所有的数据卷
	docker volume rm 		# 删除指定的数据卷
	docker volume inspect 	# 查看某个数据卷的详情
	docker volume prune 	# 清除数据卷

注意:

  • 容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的,需要删除重新创建
  • 在执行docker run命令时,使用 -v 数据卷:容器内目录可以完成数据卷挂载
  • 创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷

3.2 挂载本地目录

# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件
# 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v mysql:/var/lib/mysql 
# 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
-v ./mysql:/var/lib/mysql 

注意:本地目录或文件必须以 / 或 ./开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。

# 例子:创建并运行新mysql容器,挂载本地目录
cd ~
docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  mysql

4. 镜像

镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包,构建镜像的过程就是把上述文件打包的过程。

基本过程:

  • 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
  • 安装并配置JDK
  • 拷贝jar包
  • 配置启动脚本

4.1 镜像结构

镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。

镜像结构如下:

  • 入口(Entrypoint):镜像运行的入口,一般是程序启动的脚本和参数
  • 层(Layer):添加安装包、依赖、配置等,每次操作都形成新的一层
  • 基础镜像(BaseImage):应用依赖的系统函数库、环境、配置、文件等

4.2 Dockerfile

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

基于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"]

4.3 构建镜像

# 构建镜像命令
docker build -t myImage:1.0 .
# -t 镜像起名,格式:repository:tag
# . 指定docker所在目录,.代表当前目录

在这里插入图片描述

5. 容器网络互联

默认情况下,所有容器都是以bridge方式连接到docker的一个虚拟网桥上。
在这里插入图片描述
但是容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

所以需要借助于docker的网络功能来解决这个问题,官方文档:docker网络功能

常见命令有:
在这里插入图片描述

教学演示:自定义网络

# 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

总结:

  • 在自定义网络中,可以给容器起多个别名,默认的别名是容器名本身
  • 在同一个自定义网络中的容器,可以通过别名互相访问

6. 项目部署

6.1 java后端项目部署:

打包成jar包,编写dockerfile

# 1.构建项目镜像,不指定tag,则默认为latest
docker build -t hmall .

# 2.查看镜像
docker images
# 结果
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
hmall         latest    0bb07b2c34b9   43 seconds ago   362MB
docker-demo   1.0       49743484da68   24 hours ago     327MB
nginx         latest    605c77e624dd   16 months ago    141MB
mysql         latest    3218b38490ce   17 months ago    516MB

# 3.创建并运行容器,并通过--network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name hmall --network hmall -p 8080:8080 hmall

6.2 前端部署

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

6.3 DockerCompose

Docker Compose可以帮助我们实现多个相互关联的Docker容器的快速部署。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器。
在这里插入图片描述

6.3.1 基本语法

编写docker-compose.yml文件:

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

6.3.2 基础命令

# 命令格式如下:
docker compose [OPTIONS] [COMMAND]

在这里插入图片描述

# 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

本文参考自黑马程序员Docker课程及笔记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值