Docker容器
docker入门介绍
虚拟化:
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件 对资源充分利用
虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等
Docker:
Docker 的基础是 Linux 容器(LXC)等技术
用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单:把docker容器当成一个虚拟机装了一个操作系统
docker的好处
轻量级
统一环境
可以快速扩展到多台机器
docker组件介绍
docker 是C/S架构:数据通信使用http协议的resful
服务端:docker 主进程,负责接受docker 客户端传过来的命令
Images:重点,镜像,一堆文件:当成虚拟机上装的操作系统的iso文件(操作系统+某个软件)
Containers:重点:容器,运行的:当成在虚拟机上装了操作系统后开机了(centos系统,centos+redis)
网络:网络模式,容器间通信,容器跟宿主机通信
Volumes:数据卷,存放容器中软件,文件的地方
Registry:远程仓库,镜像是从远程仓库下载下来的
Docker安装与启动
安装依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2
添加阿里云docker源:
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker-ce:
yum install docker-ce -y
启动docker服务:
systemctl start docker
关闭docker服务:
systemctl stop docker
设置开机自启
systemctl enable docker
查看docker信息:
docker info
加速配置
配置Docker加速器,将会提升在国内获取Docker官方镜像的速度,否则后面下载镜像(docker pull)的过程会很慢,甚至有可能无法下载镜像。
方式一(json 配置文件的方式):
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
'''
几个速度比较快的镜像地址
Docker 官方中国区: https://registry.docker-cn.com
网易: http://hub-mirror.c.163.com
中科大: https://docker.mirrors.ustc.edu.cn
'''
方式二(阿里云方式,同方式一,只是阿里云分配的私有地址,自己用自己的):
"""
参考教程:https://help.aliyun.com/document_detail/60750.html?spm=a2c4g.11186623.6.545.OY7haW
"""
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://私有id.mirror.aliyuncs.com"]
}
配置完要重启docker
镜像相关命令
官方的远程仓库地址:https://hub.docker.com/
搜索镜像:也可以进入官方仓库搜索,搜索的结果好看一点。
docker search 镜像名称
docker search mysql
"""搜索结果中:
NAME:仓库名称
DESCRIPTION:镜像描述
STARS:用户评价,反应一个镜像的受欢迎程度
OFFICIAL:是否官方
AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的
"""
下载镜像:
docker pull 镜像名字:版本
docker pull centos:centos7
docker pull mysql:5.7
# 不写版本默认下载最新
docker pull redis
查看本地镜像:
docker images
镜像删除:
docker rmi 镜像名字:镜像id
一次性删除所有镜像:
docker rmi `docker images -q`
容器相关命令
查看正在运行的容器:
docker ps
查看所有容器,无论停止还是运行:
docker ps -a
创建容器并启动:
docker run -i --name -v 宿主机路径:容器路径 -p 宿主机端口:容器端口
"""
-i:表示运行容器 镜像名字:tag
-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。
-d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i -t两个参数,创建后就会自动进去容器)。
--name :为创建的容器命名。
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。
-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射
"""
# 运行centos:centos7镜像,并进入容器内部
# exit退出,容器也就停止运行
docker run -it centos:centos7
# 后台运行centos:centos7镜像,容器名字命名为mycentos7
docker run -id --name=mycentos7 centos:centos7
# 映射文件,在容器内部操作xxx文件与宿主机操作是一样的
docker run -id -v /root/xxx:/home/xxx centos:centos7
# 端口映射,连接宿主机的6380就相当于链接容器的6379端口
docker run -id --name=myredis -p 6380:6379 redis
# mysql做目录映射后,即使容器被删,用别的容器运行,数据库还在
mkdir /home/mysql
mkdir /home/mysql/conf.d
mkdir /home/mysql/data/
# 创建my.cnf配置文件
vi /home/mysql/my.cnf
"""
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
"""
# 运行容器
docker run -di -v /home/mysql/data/:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 3306:3306 --name mysqlmy -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
进入后台运行的容器内部:
docker exec -it 容器id /bin/bash
停止容器:
docker stop 容器id
删除容器:必须先停止再删
docker rm 容器id
# 连续删除多个
docker rm 容器id 容器id 容器id
从宿主机copy文件到容器:
docker cp 需要拷贝的文件或目录 容器id:容器目录
docker cp a.txt ff78cece7d61:/home
查看容器详情,ip地址:
# 容器详情
docker inspect 容器id
docker inspect ff78cece7d61
# 查看ip地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' ff78cece7d61
应用部署
部署mysql
# mysql做目录映射后,即使容器被删,用别的容器运行,数据库还在
mkdir /home/mysql
mkdir /home/mysql/conf.d
mkdir /home/mysql/data/
# 创建my.cnf配置文件
vi /home/mysql/my.cnf
"""
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
"""
# 运行容器
docker run -di -v /home/mysql/data/:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 3306:3306 --name mysqlmy -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
部署redis,设置密码为123456
mkdir /home/redis
vi /home/redis/redis.conf
"""
bind 0.0.0.0
daemonize no
protected-mode no
requirepass 123456
"""
docker run -di --name=myredis -v /home/redis/redis.conf:/data/redis.conf -p 6379:6379 redis redis-server /data/redis.conf
运行nginx
docker run -di --name=mynginx -p 80:80 nginx
镜像打包
镜像打包用于将装了软件(python, django)的容器打包成镜像,以后使用这个镜像就不再需要进入容器后安装了。
容器打包成镜像:
docker commit 容器id 打包后的镜像名:标签
docker commit 9ef33edfbdba python-django:v1
这时候输入docker images就可以看到打包后的镜像了。
查看分层历史,镜像会有分层,如果底层文件有了就不需要再下载了:
docker history 镜像id
docker history d27c6e1b93b9
把镜像备份成压缩包:
docker save -o 文件名.tar 镜像id
docker save -o python-django-v1.tar d27c6e1b93b9
把压缩包,load成镜像:
docker load -i 文件名
Dockerfile
利用Dockerfile中定义的一系列命令,可以生成一个新的镜像(定制镜像)。
创建Dockerfile文件(一点要命名为Dockerfile):
vim Dockerfile
"""
FROM python:3.8
RUN pip install django==2.2.2 -i https://pypi.doubanio.com/simple
CMD ["pip", "list"]
"""
# 参数说明
FROM: 指定基础镜像
RUN: 构建镜像过程中需要执行的命令。可以有多条。RUN mkdir xxx
CMD:添加启动容器时需要执行的命令。多条只有最后一条生效。可以在启动容器时被覆盖和修改。
ENTRYPOINT:同CMD,但这个一定会被执行,不会被覆盖修改。
MLABELAINTAINER:表明镜像的作者。将被遗弃,被LABEL代替。
EXPOSE:设置对外暴露的端口。
ENV:设置执行命令时的环境变量,并且在构建完成后,仍然生效
ADD:将本地文件或目录拷贝到镜像的文件系统中。能解压特定格式文件,能将URL作为要拷贝的文件
COPY:将本地文件或目录拷贝到镜像的文件系统中。
VOLUME:添加数据卷
WORKDIR:设置工作目录
通过Dockerfile构建镜像:
docker build -t='镜像名' Dockerfile所在路径
docker build -t='django' .
Docker私有仓库
docker hub
自己的公共仓库:Docker Hub Container Image Library | App Containerization
把自己做的镜像,传到公共仓库:
# 相当于将镜像复制重命名,但不会占你内存空间,相当于做了个连接
docker tag 镜像id 自己的用户名/镜像名称:版本
docker login
docker push 自己的用户名/镜像名称:版本
# 举例,一点要以自己公共仓库账号的用户名开头
docker tag ea7aa7609919 zbh332525/my-django:v1
docker push zbh332525/my-django:v1
从公共仓库拉取:
docker pull zbh332525/my-django:v1
自己搭建私有仓库
1.拉取私有仓库镜像(此步省略)
docker pull registry
2.启动私有仓库容器
docker run -di --name=registry -p 5000:5000 registry
3.打开浏览器 输入地址,看到{"repositories":[]} 表示私有仓库搭建成功并且内容为空
http://你的虚拟机ip地址:5000/v2/_catalog
4.修改daemon.json
vi /etc/docker/daemon.json
"""
# 添加以下内容
{ "insecure-registries":["你的虚拟机ip地址:5000"] }
"""
5.重启docker 服务
systemctl restart docker
6.标记此镜像为私有仓库的镜像
docker tag 镜像id 虚拟机ip地址:5000/镜像名称:版本
docker tag ea7aa7609919 10.0.0.200:5000/private-django
7.再次启动私服容器
docker restart registry
8.上传标记的镜像
docker push 镜像名称:版本
docker push 10.0.0.200:5000/private-django
9.打开浏览器 输入地址,看到有内容说明上传成功
http://你的虚拟机ip地址:5000/v2/_catalog
http://10.0.0.200:5000/v2/_catalog
Docker-compose
Docker Compose是一个能一次性定义和管理多个Docker容器的工具,单机容器编排,通过yaml文件。
安装:
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.9.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
给权限:
chmod +x /usr/local/bin/docker-compose
docker-compose命令:
docker-compose up # 启动,会自动搜索当前路径下的 docker-compose.yml文件
docker-compose -f 指定文件 up
docker-compose up -d # 后台执行,一般我们看日志输出,不用这个
docker-compose stop # 停止,不会删除容器和镜像
docker-compose down # 停止,并删除关联的容器
docker-compose start # 启动yml文件管理的容器
docker-compose ps # docker-compose管理的正在运行的容器
docker-compose images # docker-compose管理的容器和镜像
docker-compose exec yml文件中写的service /bin/bash # 进入到容器内
部署flask项目:
vi app.py
# 写入以下内容
"""
from flask import Flask
from redis import Redis
import os
import socket
app = Flask(__name__)
# redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return '你好! 查看 %s 次, hostname 是 %s.\n' % (redis.get('hits'),socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
"""
vi Dockerfile
"""写入以下内容
FROM python:3.8
COPY . /app
WORKDIR /app
RUN pip install flask redis -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
CMD [ "python", "app.py" ]
"""
vi docker-compose.yml
"""写入以下内容
version: "3"
# services下相当于是一个个容器
services:
# 服务名字
redis:
# 使用的镜像
image: redis
web:
# 通过Dockerfile构建镜像
build:
context: .
dockerfile: Dockerfile
# 端口映射
ports:
- 8080:5000
# 环境变量
environment:
REDIS_HOST: redis
"""
启动docker-compost:
docker-compose up
"""
访问:
服务器ip:8080
"""
yml配置解释:
version: "3"
services:
nginx:
image: nginx
# 容器名字
container_name: my_nginx
# 端口映射
ports:
- "80:80"
- "8000:8000"
# 停止就会重启
restart: always
# 文件映射
volumes:
- ./dist:/var/www/html
- ./docker_compose_files/nginx:/etc/nginx/conf.d
# 依赖于,代表django服务启动后它才启动
depends_on:
- django
networks:
- web
django:
# Dockerfile构建镜像
build:
context: .
dockerfile: Dockerfile
# 容器名字
container_name: my_django
restart: always
ports:
- "8080:8080"
volumes:
- ./django_project:/soft
environment:
- TZ=Asia/Shanghai
depends_on:
- mysql
- redis
networks:
- web
redis:
image: redis:latest
container_name: my_redis
ports:
- "6379:6379"
volumes:
- ./docker_compose_files/redis/data:/data
- ./docker_compose_files/redis/redis.conf:/etc/redis/redis.conf
# 容器启动后执行的命令
command: redis-server /etc/redis/redis.conf
networks:
- web
mysql:
image: mysql:5.7
container_name: my_mysql
restart: always
ports:
- "3306:3306"
env_file:
- ./docker_compose_files/mysql.env
volumes:
- ./docker_compose_files/mysql/data:/var/lib/mysql
- ./docker_compose_files/mysql/logs:/var/log/mysql
- ./docker_compose_files/mysql/conf:/etc/mysql/conf.d
networks:
- web
networks:
web: