Docker 中有三个核心概念:镜像、容器和仓库。因此,准确把握这三大概念对于掌握 Docker 技术尤为重
要。
1、镜像:启动容器的模板
2、容器:对外提供服务的实例
3、仓库:用来保存镜像的仓库。当我们构建好自己的镜像之后,需要存放在仓库中,当我们需要启动一个镜像时,
可 以在仓库中下载下来。
http://www.xuexianqi.top/archives/664.html
1、作用:作为启动容器的模板
2、获取镜像,可以去docker仓库下载
docker pull 镜像名称:镜像版本
docker pull nginx:1.17
docker pull redis
默认:docker pull docker.io/library/redis:latest
3、查看镜像列表
docker images或docker image ls
docker images -a :查看临时镜像文件
REPOSITORY : 镜像名称
TAG :镜像版本号
IMAGE ID : 镜像ID
CREATED : 创建时间到现在的时间
SIZE : 指镜像大小
docker tag 原镜像ID/原镜像名称:版本号 新的名称:新版本号(仓库URL/命名空间或组织/仓库:版本号)
docker tag redis:latest registry.cn-hangzhou.aliyuncs.com/alvinos/redis:v1
5、登陆
docker login 参数 仓库URL
docker login --username=丁聪9215 registry.cn-shanghai.aliyuncs.com
6、推送命令
docker push 镜像名称
docker push registry.cn-shanghai.aliyuncs.com/redis/redis:v1
7、获取镜像详细信息,包括PID、作者、架构等
docker inspect [参数] 镜像ID/镜像名称:版本号
docker inspect redis
-f:过滤某个值
docker inspect -f '{{.id}}' nginx
8、查看镜像构造历史
docker history 镜像名称/镜像ID
9、搜索镜像
docker search [参数] 镜像名称/镜像简介
--limit:限制输出结果
docker search redis --limit 3
-f:过滤查询
docker search redis -f stars=150 查找收藏数大于150的镜像
NAME :镜像名称
DESCRIPTION : 简介
STARS : 收藏个数
OFFICIAL : 是否是官方镜像
AUTOMATED : 是否是自构建的镜像
10、启动镜像
docker run -di centos:centos7
docker 中至少有一个应用程序运行在前台
11、删除镜像
docker rmi 镜像ID/镜像名称:版本号
-f :强制删除
如果该镜像正在使用中,强制删除,实际上是删除标签
12、清理镜像
docker image prune [参数]
-a:清理所有的(未被使用)镜像
13、保存容器为镜像
docker commit [参数] 容器ID 新的镜像名称
-a:指定维护者
-m:简介
-p:当保存容器时,容器暂停运行
docker commit -a "oldboy" -m "redis" ID号 redis:v1
14、删除所有镜像的两种方式
第一种方式:docker rmi $(docker images -q)
docker rmi `docker images -q` -q:只显示id
第二种方式:docker image prune -a
15、删除所有容器
docker rm `docker ps -a -q`
1、创建容器
docker run [参数] 镜像名称 命令
特点:①检查本地是否有所需镜像(如果没有,立即去相应的镜像仓库下载)
②根据参数启动
参数:
-d:以守护进程的方式运行一个容器(代表后台运行容器)
docker run -d nginx:1.19.5
--name : 指定一个容器的名称(将名称解析到Docker DNS当中)
docker run --name nginx -d nginx:1.19.5
-p(小写) : 指定固定端口映射[宿主主机端口号:容器内部端口号]
docker run -d -p 8099:80 nginx:1.19.5
-P(大写) : 指定随机端口映射
docker run -d -P nginx:1.19.5
-v : 挂载存储卷(挂载目录到容器,当使用docker commit保存时,挂载目录无法存到镜像)
docker run -d -v 宿主主机的目录:容器内的目录 镜像名称 启动命令
--rm : 当一个容器的生命周期结束时,立即删除该容器
docker run -d --rm 镜像名称或ID
-e : 在容器内设置一个环境变量
docker run -d -e NGINX_VERSION=1.19.5000 nginx:1.19.5
docker run -d -P -e MYSQL_ROOT_PASSWORD=123456 mysql:latest
docker exec great_bouman printenv
-i:打开标准输出
-t:创建一个伪终端
docker run -it centos:centos7 /bin/bash
2、查看正在运行的容器
docker ps:默认查询的是当前系统正在运行的容器
-a:显示搜索的容器(包括已停止的容器)
-q:只显示容器ID
docker rm -f $(docker ps -qa) -f:强制
3、进入容器
第一种方式:(原理:创建一个管道,链接上容器内的pid=1的那个进程,当attach窗口结束时,容器随即结束生命周期)
docker attach 容器id/容器名称
第二种方式:(原理:相当于在容器内部执行一个命令)
docker exec -it 容器ID /bin/bash
第三种方式:nsenter
第四种方式:ssh
4、导出容器为镜像export
docker export 容器ID/容器名称 > 压缩包名称
docker export nginx_name > nginx.tar
5、导入镜像import
docker import 压缩包名称 镜像名称(自定义)
docker import nginx.tar test/nginx:v1
6、docker export 和 docker commit 区别?
docker export导出的是压缩包
docker commit导出为镜像
7、导出镜像为镜像压缩包save
docker save 镜像ID/镜像名称 > 压缩包名称
docker save test/nginx:v2 > test_nginx.tar
参数-o:指定在一个压缩包内保存多个镜像
docker save -o 压缩包 镜像名称...
docker save -o django.tar django # -o:output 压缩到当前路径
8、导入镜像load
docker load < 镜像压缩包
docker load -i 镜像压缩包
docker load -i django.tar # -i: intput
9、save和load 与 export和import 区别?
1、save保存比较完整,export仅仅保存镜像。
2、save保存的体积大于export保存的体积
3、import可以重命名,load不能重命名
4、save可以保存多个镜像,export只能保存一个容器。
5、export保存的镜像只能由import导入
save保存的镜像只能由load导入
10、save和export 使用场景?
1、打包镜像一般用save, 打包容器一般用export
2、需要构建历史信息的,可以使用save。
11、查看容器的日志
docker logs -f 容器id
-f:可以滚动查看日志的最后几行
12、删除容器(删除前需先停止容器)
docker stop 容器id/容器名称 --->删除指定的容器
docker rm 容器id
docker stop $(docker ps -qa) ----> 全部容器
docker rm $(docker ps -qa)
13、启动容器
docker start 容器id
14、运行mysql容器
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=12345678 daocloud.io/library/mysql:5.7.4
15、复制文件
1、由宿主主机复制到容器内部
docker cp 宿主主机文件路径 容器ID:容器内部路径
2、由容器内部复制到宿主主机
docker cp 容器ID:容器内部路径 宿主主机文件路径
1、创建一个Dockerfile文件,并且指定自定义镜像信息
Dockerfile文件中常用的内容
from:指定当前自定义镜像依赖的环境
copy:将相对路径下的内容复制到自定义镜像中
workdir:声明镜像的默认工作目录
cmd:需要执行的命令(在workdir下执行的,cmd可以写多个,只以最后一个为准)
2、将准备好的Dockerfile和相应的文件拖拽到linux操作系统中,通过Docker的命令制作镜像
docker build -t 镜像名称:版本号
1、命名空间包含了一层网络名称空间(优点:可以在统一台Linux系统上,生成不同的隔离的网络空间)
2、veth设备对:对端与对端之间的网络互通(缺点:只支持一对一)
3、网桥:提供一个网络空间,其他网络空间使用网桥的网络(优点:支持多对多)
4、Iptables(内核级):通过Iptables规则转发网络(缺点:Ibtables规则比较复杂)
1、host
实现原理:dockers容器命名空间网络连接根命名空间的网络(跟根命名空间内的网络互联)
127.0.0.1 通过根命名空间内的lo互通
docker run --network host 镜像名称/镜像ID 命令(默认执行镜像指定的命令)
docker run -d --network host nginx:1.19.2
curl 127.0.0.1
2、contaimer
实现原理:共享一个容器的网络给其它容器使用,端口只能起一个
docker run --network "container:test01" nignx:1.19.2
共享容器网络的其他容器ip地址一样,mac地址也一样
3、none模式
实现原理:不提供任何网络,只提供了一个回环网络:127.0.0.1(只能在本地访问)
docker run --network none 镜像ID/名称 命令(默认)
docker run -dit --network none busybox:latest sh
4、网桥
实现原理:创建一个统一网络(交换机),为与其相连的网络提供网络转发功能
docker network 参数
#查看系统网桥
docker network ls
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
43b9e5667683 bridge bridge local
5c5caadde353 host host local
24e8daf9d9dd none null local
#创建网桥
docker network create 网桥的名称
[root@localhost ~]# docker network create oldboy
52657d62ca2c5170b3316d34bf70bbf29558b21727d8bdc021b8d1750b740a27
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
43b9e5667683 bridge bridge local
5c5caadde353 host host local
24e8daf9d9dd none null local
52657d62ca2c oldboy bridge local
#查看网桥的详细信息
docker network inspect 网桥名称
[root@localhost ~]# docker network inspect oldboy
[
{
"Name": "oldboy",
"Id": "52657d62ca2c5170b3316d34bf70bbf29558b21727d8bdc021b8d1750b740a27",
"Created": "2020-12-03T13:11:15.241891834+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
#删除网桥
docker network rm 网桥名称/id
#清理网桥
docker network prune
#使用网桥
需求:nginx django redis mysql 互连
第一步:创建网桥
docker network create oldboy
第二步:链接网桥
docker run --network 网桥名称 镜像名称/id 命令
第一个容器
docker run -d --name nginx --network oldboy nginx:1.19.2
第二个
docker run -d --name redis --network oldboy redis:latest
第三个
docker run -d --name mysql --network oldboy -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
创建测试容器
docker run -d -it --name test --network oldboy busybox:latest sh
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e92a7ac8f267 busybox:latest "sh" 5 seconds ago Up 4 seconds test
5797df81e849 mysql:5.7 "docker-entrypoint.s…" 10 seconds ago Up 9 seconds 3306/tcp, 33060/tcp mysql
04472914dfbc redis:latest "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp redis
8a4e45e5480d nginx:1.19.2 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp nginx
进入test容器
docker exec -it test sh
访问nginx成功,互通
wget -O- -q 8a4e45e5480d
检测redis是否互通
ping 04472914dfbc
检测mysql是否互通
ping 5797df81e849
--name 设置名称的作用是为了解析到docker dns中,就算容器id变了,名称依然不变,可以检测互通
创建一个镜像是alpine的容器,进入容器内部可以ping test以及以他的,说明新加入的容器也可以互联互通
要求用busybox实现类似于nginx启动时自动执行某些命令
输出hello world
方式一:docker run -d busybox echo "hello world"
docker ps -a
docker logs 名字
构建镜像
1、编写指令的文件名称必须是Dockerfile
touch Dockerfile
2、编写构建镜像的指令
#FROM
指定基础镜像(作为构建新镜像时提供一个基础环境)
FROM 镜像名称:版本号
#RUN
构建镜像时在镜像中执行命令
RUN Linux命令
#ADD
将本地文件复制到镜像中(自动解压压缩包)
ADD 宿主主机文件路径 镜像相对应的文件路径
注:使用相对路径(相对于dockerfile)
#EXPOSE
设置向外暴露的端口
#COPY
复制一个文件进入镜像(不会自动解压)
#ENV
设置环境变量
#ONBUILD
指定当前镜像被用作基础镜像时执行的指令
#WORKDIR
设置工作目录
#VOLUME
设置数据卷
#CMD
指定容器启动时默认执行的命令
CMD 容器启动时在容器内执行的命令
3、开始构建
docker build 参数 自定义镜像名称 dockerfile路径
-t:指定镜像名称
-f:指定Dockerfile路径
1、指定基础镜像
FROM python:3.6.12
2、安装django
RUN pip3 install django==2.2.2 -i https://pypi.douban.com/simple/
RUN pip3 install pymysql -i https://pypi.douban.com/simple/
#创建app项目 RUN django-admin startproject app
#创建application RUN cd app && django-admin startapp docker
#启动 CMD cd /app && python3 manage.py runserver 0.0.0.0:8000
3、添加本地django源码包至镜像内
ADD day91 /root/
4、设置启动命令
CMD cd /root && python3 manage.py runserver 0.0.0.0:8000
安装nginx
1、yum install yum-utils
2、touch /etc/yum.repos.d/nginx.repo
3、vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
4、yum makecache 生成yum缓存
5、yum install nginx -y 安装nginx
6、配置代理
cd /etc/nginx/conf.d/
vim default.conf
> default.conf
vim default.conf
nginx -t :测试配置文件
nginx -g 'daemon;' 在前台启动nginx,是为了在docker里持续运行
# 设置基础镜像
FROM centos:7
RUN yum install wget -y
# 换源
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
RUN cd /etc/yum.repos.d && wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
RUN mv CentOS7-Base-163.repo CentOS-Base.repo
# 创建nginx源的文件
ADD nginx.repo /etc/yum.repos.d/
# 刷新yum缓存
RUN yum makecache
# 安装yum工具
RUN yum install yum-utils -y
# 安装Nginx
RUN yum install nginx -y
# 复制配置文件
ADD default.conf /etc/nginx/conf.d/
# 设置启动命令
CMD nginx -g 'daemon off;'
配置文件
upstream django {
server django:8000;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://django;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
构建镜像
1、编写指令的文件名称必须时:Dockerfile
2、编写构建镜像的指令
3、开始构建
docker build 参数 自定义镜像名称 dockerfile
docker build -t test/busybox:v2 .
-t:指定镜像名称
-f:指定Dockerfile路径
docker images --digests 摘要信息
vim Dockerfile
docker build -t test/busybox :v1
docker images -a 临时镜像
FROM:指定基础镜像(作为构建新镜像时提供一个基础环境)
FROM 镜像名称:版本号
RUN:构建镜像时在镜像中执行命令
RUN Linux命令
CMD:指定容器启动时默认执行的命令
错误调试:查看日志
docker logs 容器名字/容器id
# 1、django项目下要有以下几个文件
requirements.txt
Dockerfile
uwsgi.ini #一般要有
# Dockerfile
FROM python:3.6
MAINTAINER dc
EXPOSE 8080
ADD ./requirements.txt /home/
RUN pip install -r requirements.txt -i https://pypi.douban.com/simple/
RUN pip install uwsgi -i https://pypi.douban.com/simple/
VOLUME ["/home"]
WORKDIR /home/django_test
CMD ["python","/homr/django_test/manage.py","runserver","0.0.0.0:8080"]
# uwsgi.ini
[uwsgi]
;socker=0.0.0.0:8080
;也可以使用http
http=0.0.0.0:8080
chdir=/home/django_test
wsgi-file=udjango_test/wsgi.py
processes=4
threads=2
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log
# 2、django项目用git管理起来
git init
上传到仓库
# 在宿主机创建一个文件
mkdir /opt/lqz/django_test
git clone https://gitee.com/ding_cong123/django_test.git
# 3、Dockerfile构建镜像
docker build -t="django_2.2.2" . # -t表示镜像名称,. 表示使用当前dockerfile构建
# 4、运行容器
docker run -di --name=mydjango_2.2.2 -v /opt/lqz/:/home -v 8080:8080 django_2.2.2
# 5、外部访问网站
宿主机ip:映射端口号
# 6、配置nginx转发以及负载均衡
## 创建文件夹
mkdir -p /opt/nginx/conf /opt/nginx/html /opt/nginx/logs
## 新建配置文件
vim nginx/conf/nginx.conf
## 写入
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream node {
server 101.133.225.166:8080;
server 101.133.225.166:8081;
server 101.133.225.166:8082;
}
server {
listen 80;
server_name localhost;
location / {
#proxy_pass http://101.133.225.166:8080;
#负载均衡配置
proxy_pass http://node;
}
}
}
## docker中运行nginx
docker run --name=nginx -id -p 8888:80 -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/nginx/html:/etc/nginx/html -v /opt/nginx/logs:/var/log/nginx nginx
## 重启nginx
systemctl restart nginx
## docker启动多个容器,即便一个挂了,也不影响服务,修好再启动即可
docker run -di --name=mydjango3 -v /opt/lqz/django_test2/:/home/django_test/ -p 8081:8080 django_1.11.11
docker run -di --name=mydjango3 -v /opt/lqz/django_test2/:/home/django_test/ -p 8082:8080 django_1.11.11
docker login 输入用户名、密码
给镜像打标签 docker tag 5452fa6715c0 dingcong123/django_2.2.2:v1
docker inages
docker push dingcong123/django_2.2.2:v1
1 拉取私有仓库镜像
docker pull registry
2 启动容器
docker run -di --name=registry -p 5000:5000 registry
3 打开浏览器 输入地址http://101.133.225.166:5000/v2/_catalog看到{"repositories":[]} 表示私有仓库搭建成功并且内容为空
4 配置
修改daemon.json
vi /etc/docker/daemon.json
添加以下内容,保存退出。
{"insecure-registries":["101.133.225.166:5000"]}
此步用于让 docker信任私有仓库地址
5 重启docker 服务
systemctl restart docker
6 重启容器
docker start registry
7 打标签
docker tag 5452fa6715c0 101.133.225.166:5000/django1.11.11
8 上传到私有仓库
docker push 101.133.225.166:5000/django1.11.11
9 从私有仓库拉取镜像
docker pull 101.133.225.166:5000/django1.11.11
docker-compose是单机情况下,容器编排的工具。多机目前主流市k8s
通过docker-compose.yml文件来定义多个容器
# 安装
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 变成可执行
chmod +x /usr/local/bin/docker-compose
# 验证
docker-compose -v
# Dockerfile
FROM python:3.6
COPY . /app
WORKDIR /app
RUN pip install flask redis
EXPOSE 5000
CMD [ "python", "app.py" ]
# 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)
@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)
# docker-compose.yml
version: "3" # version:有1,2,3版本,目前都用"3"
services: # 一个service代表一个container,这个container可以从docker hub的image来创建,或者从本地dockerfile build的image来创建
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:5000
environment:
REDIS_HOST: redis
# 启动运行
docker-compose up
# 将上述项目扩展成3个
直接启动docker-compose up --scale web=3 ,会有问题,端口被占用
于是要加一个负载均衡器HAProxy
# docker-compose.yml
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
environment:
REDIS_HOST: redis
lb: # 加了这个,相当于负载均衡
image: dockercloud/haproxy
links:
- web
ports:
- 8080:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# app.py
需要改成监听端口为80,Dockerfile不需要改
# 启动,将项目扩展为3个
docker-compose up --scale web=3 -d
# 减小为1个
docker-compose up --scale web=1 -d
一般密码等重要信息放在环境变量里,在通过os.environ.get()取
在启动容器时设置环境变量
docker run -di --name=mypython -e name=lqz -e age=18 python:3.6 # 这里将name=lqz,age=18放在环境变量中,需要时直接取
docker exec -it mypython /bin/bash
进去容器内部,输入env,可以看见所有的环境变量
# run 的时候指定--link 要通信的容器
docker run -di --name=centos1 centos:centos7
docker run -di --name=centos2 --link centos1 centos:centos7
进入centos2中ping centos1可以通
# 跨主机的容器通信
端口映射