一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
1.Docker是什么
介绍:
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
解决问题:
- 解决了运行环境不一致所带来的问题,Docker会将配置文件进行统一管理;
- 解决耗内存问题,Docker会一开始就为每个程序指定内存分配;
- 让快速扩展,弹性伸缩变得简单。
虚拟机
- 资源占用多
- 冗余步骤多
- 启动速度慢
架构
- 镜像:
镜像是一个只读的模板,可以用来创建容器,两者关系,类似于Java中class类与对象之间的关系,docker提供了一个很简单的机制来创建镜像或者更新已有镜像,用户可以通过下载一个已经做好的镜像来直接使用。 - 容器:
docker利用容器来运行应用,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等,每个容器都是相互隔离的,保证安全的平台,可以把容器看成一个简易版的Linux环境(包括Root用户权限、进程空间、用户空间、网络等)和运行在其中的应用程序。 - 仓库:
仓库是集中存放镜像文件的场所,一个Registry中会有多个Repository,分为公有和私有两种形式,最大的公有Registry是DockerHub,存放了数量庞大的镜像供用户下载使用,用户也可以在本地创建一个私有的Registry。
2.Docker的使用
ubuntu 20的安装
# 更新apt-get 和添加https传输的软件包及CA证书
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 国内源下载 添加GPG密钥保证合法性
$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# sources.list添加docker软件源
$ echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker ce版
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 启动docker
# 开机自启
sudo systemctl enable docker
# 启动
sudo systemctl start docker
因为只有root用户和docker组的用户才能访问Docker引擎,为了简易操作不用每次都输入sudo,我们将当前用户加入docker组
# 添加docker组
sudo groupadd docker
# 添加当前用户到docker组 执行完成之后推出终端重试即可
sudo usermod -aG docker $USER
# 查看当前用户详情
id
#查看所有用户组
groupmod 连按三次tab键
配置国内景象加速
vim /etc/docker/daemon.json
# 写入下面内容
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
docker基本使用 基本命令
先搞一个例子
# 拉取hello-world镜像
docker pull hello-world
# 查看已有镜像 出现类似下方的列表
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# testrd_web latest 22cc8e498ea2 16 hours ago 975MB
# testfe latest d1085806df6b 19 hours ago 142MB
# 生成并运行容器
docker run hello-world
# 输出了下方界面
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
镜像
Docker把应用程序和依赖打包在image中,通过它生成容器,类似于一个模版。镜像内是多层的,每次新生成的镜像就是在之前镜像的基础上新加了一层
# 拉取镜像 如果不指定tag的话 会拉取latest
docker pull nginx
docker inspect nginx:latest
# 打印出的一系列文件 找到 RootFS 就代表这个nginx中由四层组成
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:4b7fffa0f0a4a72b2f901c584c1d4ffb67cce7f033cc7969ee7713995c4d2610",
"sha256:c876aa251c80272eb01eec011d50650e1b8af494149696b80a606bbeccf03d68",
"sha256:7046505147d7f3edbf7c50c02e697d5450a2eebe5119b62b7362b10662899d85",
"sha256:b6812e8d56d65d296e21a639b786e7e793e8b969bd2b109fd172646ce5ebe951"
]
}
# 删除镜像 id只需要输前几位就可以了
docker rmi [imageName/id]
容器
容器就是在镜像上加了一个读写层,同一个镜像生产的容器只是对镜像进行了引用,在运行容器里文件改动时,会先从镜像里要写的文件复制到容器自己的文件系统中,所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制(引用)过来的操作的,并不会修改镜像的源文件,- 若想持久化这些改动,可以通过 docker commit 将容器保存成一个新的镜像。
# -it 分配一个伪终端 -d后台运行
# --restart=always 容器开机自启
# -v 文件夹卷 左边是宿主机文件夹 右边是容器内文件夹
# -p 端口映射 宿主机端口:容器内端口
# 运行访问时 宿主机ip:3000
docker run -itd --restart=always \
-v /home/ubuntu/project/felogs:/var/log/nginx \
-v /home/ubuntu/project/testfe/nginx:/etc/nginx/conf.d \
-v /home/ubuntu/project/testfe/dist:/usr/share/nginx/html \
--name fe -p 3000:80 nginx
# 查看正在运行容器
docker ps
# 查看所有容器
docker ps -a
# 进入容器内部 推出时容器不会停止运行
docker exec -it [containerName] bash
# 进入容器内部 退出时容器停止
docker attch [containnerName] bash
# 进入容器后退出 输入 exit
# 删除容器
docker rm [containerName]
# 强制删除
docker rm -f [containerName]
3.Dockerfile的使用
作用:
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 。
示例 django项目部署Dockerfile
# 建立python3.9 环境
FROM python:3.9
# 作者
MAINTAINER LSG
# 安装netcat
RUN apt-get update && apt-get install -y netcat
# 设置pip源为国内源
COPY pip.conf /root/.pip/pip.conf
# 在容器内/var/www/html/下创建 testrd文件夹
RUN mkdir -p /var/www/html/testrd
# 设置容器内工作目录
WORKDIR /var/www/html/testrd
# 将当前目录文件加入到容器工作目录中(. 表示当前宿主机目录)
ADD . /var/www/html/testrd
# 更新pip版本
RUN /usr/local/bin/python -m pip install --upgrade pip
# 利用 pip 安装依赖
RUN pip3 install -r requirements.txt
# 设置start.sh文件可执行权限
RUN chmod +x ./start.sh
ENTRYPOINT /bin/bash ./start.sh
使用Dockerfile
# 当前目录文件夹下dockerfile文件生成镜像
docker build .
# -f 指定目录 -t 制定镜像名 标签
docker build -f /home/ubuntu/demo/Dockerfile -t nginx/v3
编写Dockerfile规则
# 指定基础镜像
FROM ubuntu
# 维护者信息
MAINTAINER lsg
# RUN 镜像操作指令
RUN echo 'start'
# ADD 父容器目录下文件拷贝到镜像并解压(只允许Dockerfile同级目录之下的,项目外的不允许)
ADD . /usr/html
# COPY 只复制不解压
COPY . /usr/html
# WORKDIR 设置容器工作目录
WORKDIR /usr/html
# VOLUME 挂载主机目录。相当于容器 -v
VOLUME . /usr/html
# EXPOSE 暴漏容器端口
EXPOSE 80/tcp
EXPOSE 80/udp
# CMD 指定容器启动命令,多个CMD只执行最后一个
CMD ["executable","param1","param2"]
# ENV 构建镜像时设置环境变量
4.docker-compose的使用
作用
docker-compose是为了对多个Docker容器集群的快速编排,使用场景在于复杂业务需要多个容器互相配合的情况,通过一个配置文件管理多个容器进行启动、停止、重启。
安装
# 下载
sudo pip3 install docker-compose
# 添加可执行权限
chmod +x docker-compose
# 测试
docker-compose --version
示例
version: '3.3'
networks: # 自定义网络(默认桥接), 不使用links通信
db_network:
driver: bridge
services:
db:
image: mysql:8.0
restart: always
container_name: rddb
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: "test"
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
ports:
- 3306:3306
volumes:
- /home/ubuntu/db:/var/lib/mysql
- ./conf:/etc/mysql/conf.d
- /home/ubuntu/logs:/logs
web:
# 使用目录下的Dockerfile
build: .
container_name: rdweb
restart: always
ports:
- 8010:8000
volumes:
# 挂载项目代码
- .:/var/www/html/testrd
networks:
- db_network
# 依赖关系
depends_on:
- db
environment:
- DEBUG=False
tty: true
stdin_open: true
常用指令
# 启动/更新 -f 执行文件 -d 后台运行
docker-compose -f docker-compose.yml up -d
# 暂停 可以指定某个容器
docker-compose pause
# 恢复 可以指定某个容器
docker-compose unpause
# 停止 并删除相关镜像容器
docker-compose down
# 删除容器(删除前必须关闭容器)
docker-compose rm nginx
# 停止nignx容器
docker-compose stop nginx
# 启动nignx容器
docker-compose start nginx
# 构建镜像 --no-cach不带缓存
docker-compose build --no-cach
# 查看日志
docker-compose logs
编写yml文件
version: compose版本,目前推荐使用的是3.x版本 官网
(3.x)版本已经取消了links指令
networks: 解决多个容器互相依赖,解决网络隔离,每个容器都能通过容器名找到对方
networks:
db_network:
driver: bridge #相同值的容器间可以通过名通信
services: 定义所有的服务
web:
# 使用目录下的Dockerfile # 镜像 Dockerfile文件
build: .
container_name: rdweb # 容器名称
restart: always # 开机自启
ports: #暴漏端口
- 8010:8000
volumes: # 文件挂载
# 挂载项目代码
- .:/var/www/html/testrd
command:
# 容器运行指令
networks: #桥
- db_network
# 依赖关系 会等它起来之后再运行
depends_on:
- db
# 环境变量
environment:
- DEBUG=False
# 容器开启终端输入
tty: true
stdin_open: true