最通俗的理解DOCKER是什么?
DOCKER的专业解释是“容器”,对于非计算机科班出身的人来说,对这个概念非常模糊。
对比,生活中的物品来说。他更像是收纳箱。或者是乐高玩具里的各种功能模块。
它们都有一个共同的能力,就是通过不同的排列组合。满足你的不同需求。
现在软件的重点是服务能力?
现在的抖音,可以发视频、可以开直播、可以买东西、可以交友,可以做教学,可以做远程测试。这样的一个软件,背后有着几十上百的独立软件支持。同时,这些软件功能又要同时服务于百万,千万的在线客户。每个独立软件的安全可靠性都非常重要。最可靠的方法是给每个独立软件分配一个独立的主机。但实际上,你的公司并没有抖音那样的规模。不可能有几部台主机。最好的方式,就是把每个独立软件打包到一个容器中,集中安装到几台主机上。
在每个容器里,相当于每个独立软件来说,就是一个独立的主机。独立的功能软件出故障了,我们只需要修复这个容器。并不影响其他功能的运行。或者用相同功能的容器替换下,故障容器,是系统故障快速修复。
DOCKER容器部署的示意图
docker的安装
docker 容器支持 window、linux、macos 安装,具体步奏推荐下面这篇文章,这里不在累述
10分钟学会Docker的安装和使用_docker安装-CSDN博客
docker使用的基本概念
docker的最基本概念是 镜像(Image),容器(Container)。镜像可以看做货架上的商品,容器是商品买回家后开包使用。
第一步、pull 拉取镜像(下载镜像到本地)
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
NAME
: 镜像名称,通常包含注册表地址(如docker.io/library/ubuntu
)。TAG
(可选): 镜像标签,默认为latest
。DIGEST
(可选): 镜像的 SHA256 摘要。
常用选项:
--all-tags, -a
: 下载指定镜像的所有标签。--disable-content-trust
: 跳过镜像签名验证。
例:拉取 ubuntu:20.04 镜像
docker pull ubuntu:20.04
第二步、run 运行容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用参数说明:
-d
: 后台运行容器并返回容器 ID。-it
: 交互式运行容器,分配一个伪终端。--name
: 给容器指定一个名称。-p
: 端口映射,格式为host_port:container_port
。-v
: 挂载卷,格式为host_dir:container_dir
。--rm
: 容器停止后自动删除容器。--env
或-e
: 设置环境变量。--network
: 指定容器的网络模式。--restart
: 容器的重启策略(如no
、on-failure
、always
、unless-stopped
)。-u
: 指定用户。
例:运行交互式运行并分配终端
docker run -it ubuntu /bin/bash
第二步(另一种方法)、用docker-compose.yaml 运行容器
编辑docker-compose.yaml文件内容:(这里,同时开启 数据库和 nginx容器)
version: '3' # 版本不同,件格式特性不一样
services: # 应用程序中需要运行的服务
webserver: # 服务名称
image: nginx:alpine # 程序镜像
ports: # 端口映射(把容器的端口映射到物理主机的端口上,不设置网络无法直接访问这个容器)
- "80:80"
depends_on: # 前置程序,需求先启动
- db
db: # 服务名称(数据库)
image: mysql:latest
container_name: mysql
environment: # 这里设置mysql数据库账号密码
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_USER=admin
- MYSQL_PASSWORD=zrp080411
ports:
- "3306:3306"
volumes: # 挂载db-data到容器data目录下
- db_data:/var/lib/mysql
- ./mysql:/docker-entrypoint-initdb.d/
restart: always #开机重启策略
volumes: # 创建卷
db-data:
然后在docker-compose.yaml文件所在目录,执行
docker-compose up -d
这时docker-compose 中涉及的容器都被启动了。
用docker exec 对容器内的内容进行修改
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
常用参数
-d, --detach
: 在后台运行命令。--detach-keys
: 覆盖分离容器的键序列。-e, --env
: 设置环境变量。--env-file
: 从文件中读取环境变量。-i, --interactive
: 保持标准输入打开。--privileged
: 给这个命令额外的权限。--user, -u
: 以指定用户的身份运行命令。--workdir, -w
: 指定命令的工作目录。-t, --tty
: 分配一个伪终端。
例:docker exec 以交互模式运行命令:
docker exec -it my_container /bin/bash
用docker cp 拷贝 文件到容器或从容器拷贝到本地
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
例: 从容器复制文件到宿主机
docker cp my_container:/path/in/container /path/on/host
例: 从宿主机复制文件到容器
docker cp /path/on/host my_container:/path/in/container
这个功能主要用于自己创造镜像展开的容器是,需要不停给容器打补丁。
用DOCKERFILE生成自己的镜像文件
首先,编写DOCKERFILE文件 (例:flask 工程镜像)
FROM python:3.8 #引入基础python版本
WORKDIR /index # 设置镜像上传程序的根目录
COPY . /index # 本地程序到这个根目录
RUN python -m pip install --upgrade pip
RUN apt-get update && apt-get install -y dmidecode
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 8360 # 开放端口
ENV FLASK_APP=app.py # 设置flask主程序
ENTRYPOINT ["python","app.py"] 设置启动命令
执行命令生成flask程序镜像
docker build -t flaskend:latest .
问题一、不同容器之间如何相互访问
首先,大部分容器中执行的程序只是为主程序提供功能,直接对外网开放会增大安全风险。因此,只需要容器之间相互访问即可。官方给出的容器间的访问方法有多种。这里只讲bridge(网桥)方法。
容器在建立的时候,都会被分配独立的IP。IP编号是跟随容器的生成的顺序。一台某个容器被重建编号和IP将会被重排。因此,为了保证更换容器,可以正常使用。必须用容器名代理IP。
比如:我们在程序中引用数据库时,host地址中 需填写容器名。
"Containers": {
"2ac483eadb9ca7aeba6f7c664f4d7296403d5c8a45a55bc1d025cb4f461d225d": {
"Name": "redis6.2.14",
"EndpointID": "d032a30dd138902af18a3bd220b4308cefd52ef8c0aee7b2d0433185e1b18f0d",
"MacAddress": "02:42:ac:17:00:02",
"IPv4Address": "172.23.0.2/16",
"IPv6Address": ""
},
"c75b1941e377aeeb1372aa600810677f236a0db407d247f502037d130326dd5c": {
"Name": "shopend",
"EndpointID": "5e442309398d0c2334ab0afcc7422f504e7db10388e255928daeb3561ff29ced",
"MacAddress": "02:42:ac:17:00:03",
"IPv4Address": "172.23.0.3/16",
"IPv6Address": ""
},
"f49682348fe83218620c6a72e9fef452a37db358ef26be9b275f86630eb9dd1e": {
"Name": "cmysql",
"EndpointID": "ba686efea33124b5a12b2924656ee61b59511f5511af2ecccc627a6dbcfaf2ae",
"MacAddress": "02:42:ac:17:00:04",
"IPv4Address": "172.23.0.4/16",
"IPv6Address": ""
}
},
比如:数据库镜像的名称为 ‘cmysql’,下面是python片段
问题二、不同的服务号如何调用相同功能程序
已商城和点餐程序为例。一般单位自建这类系统时,由于商城和点餐隶属于不同的部门,这两套系统都是单独建设的。但是,这两套系统在用户信息层面的需求又是统一的。都需要实时获取用户的基本信息、在职状态、等级权限等。
这时,我们需要确保信息系统独立运行。并且和另外两个系统通讯正常。这里有一个前提,需要确保商城和点餐系统和信息系统都能组成一个网桥。
下面我们用docker启动了两套服务: 用户信息服务(数据库服务)、商城服务
两套服务是相互独立的。如果,让两套服务相互通讯,不需保证两套服务在同一网段上。
backenddemo 服务的 docke-compose1.yaml文件
version: "3"
services:
database:
image: mysql:latest
container_name: cmysql
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_USER=admin
- MYSQL_PASSWORD=zrp080411
volumes:
- db_data:/var/lib/mysql
- ./mysql:/docker-entrypoint-initdb.d/
restart: always
cache: #内存数据库
image: redis:6.2.14 # redis 镜像版本
container_name: redis6.2.14 #容器名称
volumes:
- ./redis6.2.14/conf/redis.conf:/etc/redis/redis.conf:rw # 映射配置文件目录,宿主机:容器
- ./redis6.2.14/data:/data:rw # 映射数据目录,宿主机:容器
privileged: true # 获取宿主机root权限
command: [ "redis-server","/etc/redis/redis.conf" ] # 指定配置文件启动redis-server进程
restart: always
volumes:
db_data:
在 docke-compose1.yaml 所在目录 执行 docker-compose up -d
执行下面命令,查询到backenddemo的网桥名 backenddemo_default
docker network ls
修改 app-server-master-python 服务的 docke-compose2.yaml文件
version: '3'
services:
flaskend:
image: flaskend:so
container_name: shopend
networks:
- backenddemo_default
ports:
- 8360:8360
restart: always
networks:
backenddemo_default:
external: true
这里networks:添加backenddemo_default网段。
在 docke-compose2.yaml 所在目录 执行 docker-compose up -d
这时,我们用户信息服务和商城服务放在一个网桥下了,独立的商城服务,就可以正常获取用户数据了。