Docker入门教程
1. 什么是Docker
-
Docker是开源的应用容器引擎
-
Docker 可以让你将多有应用软件以及它的依赖打包成软件开发的标准话单元。
-
Docker 容器将软件以及它运行安装所需的一切文件(代码、运行时、系统工具、系统库)打包到一起,这就保证了不管是在什么样的运行环境,总是能以相同的方式运行。
-
Docker 是一种“容器即服务”(Docker Containers as a Service ,简称 CaaS),使得开发和IT运营团队可以对于应用的构建、发布、运行更加敏捷和可控。
-
仓库(Repository):镜像仓库,是Docker⽤来集中存放镜像⽂件的地
⽅。
-
容器(Container):类⽐于pthon的实例。容器是镜像创建的应⽤实例,
各容器间相互隔离。镜像只读,容器从镜像启动时,Docker在镜像的上层
创建⼀个可写层。
-
镜像(Image):类⽐于python的类。镜像⽤来给应⽤程序提供运⾏环
境。⼀个Ubuntu镜像就是⼀个包含Ubuntu操作系统的模板,在该镜像
上装上Nginx软件,就可以称为Nginx镜像。
2.Docker与虚拟机的区别
容器与虚拟机有着类似的资源隔离和分配的优点,但不同的架构方法使容器能够更加便携,高效等。
– 虚拟机的架构:
每个虚拟机都包括应用程序、必要的二进制文件和库以及一个完整的客户操作系统(Guest OS),尽管它们被分离,它们共享并利用主机的硬件资源,将近需要十几个 GB 的大小。
– 容器的架构
容器包括应用程序及其所有的依赖,但与其他容器共享内核。它们以独立的用户空间进程形式运行在主机操作系统上。他们也不依赖于任何特定的基础设施,Docker 容器可以运行在任何计算机上,任何基础设施和任何云上。
Docker 的容器利用了 LXC,管理利用了 namespaces 来做权限的控制和隔离,cgroups 来进行资源的配置,并且还通过 aufs 来进一步提高文件系统的资源利用率,而这些技术都不是 Docker 独创。
LXC
LXC 与虚拟机的不同之处在于,它是一个操作系统级别的虚拟化环境,而不是硬件虚拟化环境。他们都做同样的事情,但 LXC 是操作系统级别的虚拟化环境,虚拟环境有它自己的进程和网络空间,而不是创建一个完整成熟的虚拟机。因此,一个 LXC 虚拟操作系统具有最小的资源需求,并启动只需几秒钟。
-
3.安装Docker
下⾯以CentOS为例讲解如何安装Docker,使⽤Ubuntu、macOS或Windows的⽤户可以通过点击对应的链接了解这些平台下如何进⾏安装.
-
确定操作系统内核版本(CentOS 7要求64位,内核版本3.10+;CentOS 6要求64位,内核版本2.6+)。
uname -r
-
更新系统底层的库⽂件(建议⼀定要执⾏,否则在使⽤Docker时可能会出现莫名其妙的问题)。
yum update
- 移除可能存在的旧的Docker版本。
yum erase -y docker docker-common docker-engine
-
安装yum⼯具包和依赖项。
yum install -y yum-utils device-mapper-persistent-data lvm2
-
通过yum⼯具包添加yum源(安装Docker-ce的源)。
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
-
在CentOS下使⽤yum安装Docker-ce并启动。
1. yum -y install docker-ce 2. systemctl start docker
-
查看Docker的信息和版本。
docker version docker info
安装Docker后,由于直接访问dockerhub下载镜像会非常缓慢,建议将服务器更换为国内镜像,可以通过修改 /etc/docker/daemon.json
文件来做到。一般的云服务器会有自己专属的镜像,就不需要手动修改了。
{
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
]
}
4.使用Docker
接下来可以通过下载镜像和创建容器来看看Docker是否可以运转起来。可以使用下面的命令从Docker的镜像仓库下载名为hello-world的镜像文件。
docker pull hello-world
查看所有镜像文件。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/hello-world latest fce289e99eb9 7 months ago 1.84 kB
通过镜像文件创建并运行容器。
docker container run --name mycontainer hello-world
说明:其中mycontainer
是我们给容器起的名字,跟在--name
参数之后;hello-world
就是我们刚才下载的镜像文件。
如果要删除这个容器,可以使用下面的命令。
docker container rm mycontainer
在删除容器之后,我们还可以删除刚才下载的镜像文件。
docker rmi hello-world
说明:如果要在Ubuntu(内核版本3.10+)下面安装和启动Docker,可以按照如下的步骤进行。
apt update
apt install docker-ce
service docker start
国内用户可以通过更换Ubuntu软件下载源来提升下载速度,具体请参照清华大学开源软件镜像站上的《Ubuntu镜像使用帮助》。
5.常用命令
拉取docker镜像
docker pull image_name
查看宿主机上的镜像,Docker镜像保存在/var/lib/docker目录下:
docker images
删除镜像
docker rmi docker.io/tomcat:7.0.77-jre7 或者 docker rmi b39c68b7af30
查看所有容器
docker ps -a
启动、停止、重启容器命令:
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
后台启动一个容器后,如果想进入到这个容器,可以使用attach命令
docker attach container_name/container_id
删除容器的命令
docker rm container_name/container_id
查看当前系统Docker信息
docker info
从Docker hub上下载某个镜像:
docker pull centos:latest
docker pull centos:latest
执行docker pull centos会将Centos这个仓库下面的所有镜像下载到本地repository。
6.使用Docker
运行Nginx
Nginx是⾼性能的Web服务器,同时也是做反向代理服务器的上佳选择。使⽤Docker可以⾮常简单的创
建⼀个运⾏Nginx的容器,命令如下所示。
docker container run -d -p 80:80 --rm --name mynginx nginx
说明:上面的参数-d
表示容器在后台运行(不产生输出到Shell)并显示容器的ID;-p
是用来映射容器的端口到宿主机的端口,冒号前面是宿主机的端口,冒号后面是容器内部使用的端口;--rm
表示容器停止后自动删除容器,例如执行命令docker container stop mynginx
后,容器就不复存在了;--name
后面的mynginx是自定义的容器名字;在创建容器的过程中,需要用到nginx的镜像文件,镜像文件的下载是自动完成的,如果没有指定版本号,默认是最新版本(latest)。
如果需要将自己的Web项目(页面)部署到Nginx上,可以使用容器拷贝命令将指定路径下所有的文件和文件夹拷贝到容器的指定目录中。
docker container cp /root/web/index.html mynginx:/usr/share/nginx/html
如果不愿意拷贝文件也可以在创建容器时通过数据卷操作--volume
将指定的文件夹映射到容器的某个目录中,例如将Web项目的文件夹直接映射到/usr/share/nginx/html
目录。我们先通过下面的命令让刚才创建的容器停止运行。
docker container stop mynginx
然后用下面的命令重新创建容器。
docker container run -d -p 80:80 --rm --name mynginx --volume /root/docker/nginx/html:/usr/share/nginx/html nginx
说明:上面创建容器和拷贝文件的命令中,container
是可以省略的,也就是说docker container run
和docker run
是一样的,而docker container cp
和docker cp
是一样的。此外,命令中的--volume
也可以缩写为-v
,就如同-d
是--detach
的缩写,-p
是--publish
的缩写。$PWD
代表宿主系统当前文件夹,这些对于使用过Unix或者Linux系统的人来说,应该是很容易理解的。
要删除正在运行中的容器,需要使用-f
选项。
docker rm -f mynginx
运行Mysql
我们再来尝试用Docker安装一台MySQL服务器,首先可以先检查一下有没有MySQL的镜像文件。
docker search mysql
下载MySQL镜像并指定镜像的版本号。
docker pull mysql:5.7
如果需要查看已经下载的镜像文件,可以使用下面的命令。
docker images
创建并运行MySQL容器。
docker run -d -p 3306:3306 --name mysql57 -v /root/docker/mysql/conf:/etc/mysql/mysql.conf.d -v /root/docker/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
注意:上面创建容器时我们又一次使用了数据卷操作,那是因为通常容器是随时创建随时删除的,而数据库中的数据却是需要保留下来的。
上面的两个数据卷操作一个是映射了MySQL配置文件所在的文件夹,一个是映射了MySQL数据所在的文件夹,这两个数据卷操作非常重要。我们可以将MySQL的配置文件放在$PWD/mysql/conf
目录下,配置文件的具体内容如下所示:
[mysqld]
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
log-error=/var/log/mysql/error.log
server-id=1
log-bin=/var/log/mysql/mysql-bin.log
expire_logs_days=30
max_binlog_size=256M
symbolic-links=0
进入数据库交互式环境
docker exec -it mysql /bin/bash
7.fastapi项目使用docker部署
准备
项目地址:https://gitee.com/anemo/myproj
(1) 下载镜像
docker pull nginx:latest
docker pull mysql:5.7.30
docker pull python:3.7
查看镜像 :docker images
删除镜像:docker rmi
(2) 通过Dockerfile创建自定义的镜像
Dockerfile:
# 指定基础镜像
FROM python:3.7
# 指定镜像的维护者
LABEL maintainer="jackfrued@126.com"
# 设置工作目录
WORKDIR /root/fastapi/
# 从版本控制克隆代码
RUN git clone --depth=1 https://gitee.com/anemo/carsys3.git carsys
# 设置工作目录
WORKDIR /root/fastapi/carsys
# 安装项目依赖项
RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple/
# 容器启动时要执行的命令
ENTRYPOINT ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"]
# 暴露端口
EXPOSE 8000
(3) 根据Dockerfile 创建自定义镜像
docker build -t "fastapi/api-server" . # 寻找Dockerfile进行执行
(4) 创建依赖的容器
docker run -d -p 3306:3306 -v /root/fastapi/myproj/mysql/data/:/var/lib/mysql -v /root/fastapi/myproj/mysql/conf/:/etc/mysql/mysql.conf.d -e "MYSQL_ROOT_PASSWORD=123456" --name mysql57 mysql:5.7.30
docker run -d -p 8000:8000 -e "DB_USER=hellokitty" -e "DB_PASS=Hellokitty.618" -e "DB_NAME=carsys" --link mysql57 -e "DB_HOST=mysql57" --name api-server fastapi/api-server
1135 docker run -d -p 80:80 --link api-server:api-server -v /root/fastapi/myproj/nginx/html/:/usr/share/nginx/html/ -v /root/fastapi/myproj/nginx/conf/:/etc/nginx/conf.d --name web-server nginx:latest
docker run -d -p 80:80 --link api-server:api-server -v /root/fastapi/myproj/nginx/html/:/usr/share/nginx/html/ -v /root/fastapi/myproj/nginx/conf/:/etc/nginx/conf.d --name web-server nginx:latest
也可以用多容器管理工具(K8S)kuberneted --> for profuction
(1)下载第三方库
pip3 install docker-compose
(2) 编写yml文件docker-compose.yml
1 version: '3'
2 services:
3 api-server:
4 build: ./python
5 ports:
6 - '8000:8000'
7 links:
8 - mysql-server
9 environment:
10 DB_HOST: 'mysql-server'
11 DB_NAME: 'carsys'
12 DB_USER: 'hellokitty'
13 DB_PASS: 'Hellokitty.618'
14 web-server:
15 image: nginx:latest
16 ports:
17 - '80:80'
18 volumes:
19 - ./nginx/html:/usr/share/nginx/html
20 - ./nginx/conf:/etc/nginx/conf.d
21 links:
22 - api-server
23 mysql-server:
24 image: mysql:5.7.30
25 environment:
26 MYSQL_ROOT_PASSWORD: '123456'
27 MYSQL_USER: 'root'
28 MYSQL_PASS: '123456'
29 volumes:
30 - ./mysql/conf:/etc/mysql/mysql.conf.d
31 - ./mysql/data:/var/lib/mysql
32 - ./mysql/init:/docker-entrypoint-initdb.d
33 ports:
34 - '3306:3306'
(3) 使用一行命令执行
docker-compose up -d # 后台执行
docker-compose down
补充:将自己容器拷贝给其他人使用 /将容器托管到hub.docker.com
生成镜像:
docker commit 容器ID “jackfrued/hello”
docker build -t “jackfrued/hello” .
把镜像保存成归档文件
docker save “jackfrued/hello” -o 归档文件的名字
从归档文件导入镜像
docker load -i 归档文件的名字
放到hub.docker.com(镜像托管)
docker login
docker push “jackfrued/hello”
多容器管理
pip3 install docker-compose
docker-compose up -d
docker-compose down