Docker
一 . Docker是什么
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,
于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现。
docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方案。
docker的接口相当简单,用户可以方便的创建、销毁容器。
docker将应用程序与程序的依赖,打包在一个文件里面。运行这个文件就会生成一个虚拟容器。
程序运行在虚拟容器里,如同在真实物理机上运行一样,有了docker,就不用担心环境问题了。
二 . 为什么要用docker
# 因为以前服务器部署应用的时候最开始用物理机,后来用虚拟机,
1.会很浪费时间
2.成本非常高
3.资源浪费
4.难于迁移和扩展,换机器需要把所有依赖关系都安装一遍
5.可能会别限定硬件厂商,比如在联想电脑上写的,在戴尔电脑就不能用
!!! docker的出现解决了这些问题,并且还解决了最让人头疼的环境配置问题,他可以把所有需要的环境,依赖包放到一个容器里,然后打包发给测试
三 . 物理机,虚拟机,docker的区别
物理机, 虚拟机, docker的关系就好比 物理机是一栋居民楼, 虚拟机是居民楼里的每个房子,docker就相当于房子里面的每个房间.
四 . docker VS 传统虚拟机
五 . docker的三大概念
# 容器三大基本概念
镜像 image
容器 container
仓库 repository
docker整个生命周期就是这三个概念。
镜像(理解成一个压缩版操作系统)
1. Docker镜像就是一个只读的模板。
例如:一个镜像可以包含一个完整的CentOS操作系统环境,里面仅安装了Apache或用户需要的其他应用程序。
2. 镜像可以用来创建Docker容器。
3. Docker提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
容器
1. image和container的关系,就像面向对象程序设计中的 类和实例一样,镜像是静态的定义(class),容器是镜像运行时的实体(object)。
容器可以被创建、启动、停止、删除、暂停
2. Docker利用容器来运行应用。
3. 容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的,保证安全的平台。
4. 可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
!!! 注意:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
仓库
1. 仓库是集中存放镜像文件的场所。有时候把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。
实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
2. 仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
3. 最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,可以提供大陆用户更稳定快读的访问。
4. 当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下载在另外一台机器上使用这个镜像时候,
只需需要从仓库上pull下来就可以了。
!!! 注意:Docker仓库的概念跟Git类似,注册服务器可以理解为GitHub这样的托管服务。
六 . centos安装docker
官宣的安装姿势
1.卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
2.设置存储库
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3.安装docker社区版
sudo yum install docker-ce
4.启动关闭docker
systemctl start docker
阿里云安装方式
yum install docker -y
# 启动docker服务端
systemctl start docker
七 . docker命令的学习
配置一个docker加速器,加速镜像的下载
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io
!!! 注意:一定要修改docker的配置文件才能生效, vim /etc/docker/daemon.json
{"registry-mirrors": ["http://95822026.m.daocloud.io"]} #去掉结尾的逗号
docker和镜像的增, 删, 改, 查
增
#获取一个docker镜像,获取一个基础的ubuntu镜像
docker search ubuntu # 搜索镜像
#下载ubuntu的镜像文件,下载一个微型的ubuntu系统
docker pull ubuntu
#运行一个ubuntu系统!!!!基于微型的ubuntu系统,运行了一个容器实例,里面是ubuntu微型操作系统
docker run ubuntu
#交互式的运行一个ubuntu系统,可以进行命令交互,,并且进入容器空间内,另一个操作系统
docker run -it ubuntu /bin/bash
#参数解释
-i 交互式的运行
-t 开启一个终端 termenl
/bin/bash 就是linux的shell解释器
删
#删除容器记录
docker rm 容器id
#一次性删除所有容器记录
docker rm `docker ps -aq`
`` 反引号是取得命令的结果,保存下来
#删除镜像记录
docker rmi 镜像id
docker rmi -f `docker images -aq` #危险命令 ,这个命令,只能删除没有容器记录依赖的镜像文件 -f 强制删除
改
#进入正在运行的容器空间内
docker exec -it 容器id /bin/bash
#修改docker镜像的名字
docker tag 镜像id 新的镜像名
docker tag 9ed836d5dd03 attila163/s18-aliyun-centos-vim
#启停docker容器
docker start 容器id
docket stop 容器id
#批量停止docker容器
docker stop `docker ps -aq`
查
#查询当前机器拥有的镜像文件 docker image ls #列出镜像文件 docker images #同上,版本升级,命令也就升级了 #运行过镜像后,会产生一个容器记录,容器进程的查看 docker ps #查看正在运行的容器记录 ,容器内必须有后台运行的进程,否则容器挂掉 docker ps -a #显示所有运行过的容器进程记录 #查询容器内的日志信息 docker logs 容器id #一次性打印日志 docker logs -f 容器id #不间断打印容器日志
运行一个一直活着的容器看一下
docker run --name s18foleng -d centos /bin/sh -c "while true;do echo 买了佛冷; sleep 1;done"
#参数解释
docker run 运行镜像
--name 自定义名字
-d daemonize 后台运行
centos 镜像名
/bin/sh 指定shell的sh解释器
-c 指定一段shell代码
"while true;do echo 买了佛冷; sleep 1;done" #死循环的每秒钟打印一个买了佛冷
容器的端口映射
#容器内的端口映射,是在容器空间内,暴露一个端口,供给外部客户端去访问
docker run -d -P training/webapp python app.py
#参数解释
-d 后台运行容器
-P 大写的P 随机端口映射 宿主机端口:容器内端口 随机的映射宿主机的端口:容器内的端口
-p 小写的p 指定端口映射 7777:5000
training/webapp 这个是镜像的名字
python app.py 容器要执行的命令
#docker run 如果运行不存在的镜像,默认会去先docker pull
#指定端口映射,暴露宿主机的7777,指定映射到容器的5000,这个5000是在容器代码内控制的,默认为5000
docker run -d -p 7777:5000 training/webapp python app.py
八 . 提交自定义的docker镜像
1.运行一个centos基础镜像,默认没有vim,在容器空间内安装vim(也可以替换成python),且配置阿里云的yum源
docker run -it centos /bin/bash
2.安装wget,下载阿里云的yum源
yum install wget -y
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
3. 此时基于阿里云的yum源下载vim
yum install vim -y
4.退出容器空间
exit
5.提交这个容器记录,生成一个新的镜像文件, 自动提交到commit hub上,后面写账号id
docker commit 容器id 镜像名
docker commit b6a15b909caa attila163/s18-vim-aliyun-centos
#返回一个sha256哈希的校验值
导出封装好的镜像,让其他人也可以用成品
#导出docker镜像 直接就打包压缩了
docker save 镜像id > /opt/mydocker.tar.gz
#导入docker镜像
docker load < /opt/mydocker.tar.gz
登录dockerhub个人主站,托管docker镜像的网址
# 1.下载docker hub上的镜像
docker pull attila163/s18-hello-docker-world
# 2.在linux登录docker hub,然后推送镜像到公网
docker login
# 3.修改本地镜像的名字,为docker hub的仓库id
docker tag 镜像id dockerhubID/镜像名
# 4.推送镜像到docker hub
docker push 镜像id
九 . Dockerfile的学习
1 FROM scratch #制作base image 基础镜像,尽量使用官方的image作为base image 2 FROM centos #使用base image 3 FROM ubuntu:14.04 #带有tag的base image 4 5 LABEL version=“1.0” #容器元信息,帮助信息,Metadata,类似于代码注释 6 LABEL maintainer=“yc_uuu@163.com" 7 8 #对于复杂的RUN命令,避免无用的分层,多条命令用反斜线换行,合成一条命令! 9 RUN yum update && yum install -y vim \ 10 Python-dev #反斜线换行 11 RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME” 12 13 WORKDIR /root #相当于linux的cd命令,改变目录,尽量使用绝对路径!!!不要用RUN cd 14 WORKDIR /test #如果没有就自动创建 15 WORKDIR demo #再进入demo文件夹 16 RUN pwd #打印结果应该是/test/demo 17 18 ADD and COPY 19 ADD hello / #把本地文件添加到镜像中,吧本地的hello可执行文件拷贝到镜像的/目录 20 ADD test.tar.gz / #添加到根目录并解压 21 22 WORKDIR /root 23 ADD hello test/ #进入/root/ 添加hello可执行命令到test目录下,也就是/root/test/hello 一个绝对路径 24 COPY hello test/ #等同于上述ADD效果 25 26 ADD与COPY 27 - 优先使用COPY命令 28 -ADD除了COPY功能还有解压功能 29 添加远程文件/目录使用curl或wget 30 31 ENV #环境变量,尽可能使用ENV增加可维护性 32 ENV MYSQL_VERSION 5.6 #设置一个mysql常量 33 RUN yum install -y mysql-server=“${MYSQL_VERSION}” 34 35 ------这里需要稍微理解一下了-------中级知识---先不讲 36 37 VOLUME and EXPOSE 38 存储和网络 39 40 RUN and CMD and ENTRYPOINT 41 RUN:执行命令并创建新的Image Layer 42 CMD:设置容器启动后默认执行的命令和参数 43 ENTRYPOINT:设置容器启动时运行的命令 44 45 Shell格式和Exec格式 46 RUN yum install -y vim 47 CMD echo ”hello docker” 48 ENTRYPOINT echo “hello docker” 49 50 Exec格式 51 RUN [“apt-get”,”install”,”-y”,”vim”] 52 CMD [“/bin/echo”,”hello docker”] 53 ENTRYPOINT [“/bin/echo”,”hello docker”] 54 55 56 通过shell格式去运行命令,会读取$name指令,而exec格式是仅仅的执行一个命令,而不是shell指令 57 cat Dockerfile 58 FROM centos 59 ENV name Docker 60 ENTRYPOINT [“/bin/echo”,”hello $name”]#这个仅仅是执行echo命令,读取不了shell变量 61 ENTRYPOINT [“/bin/bash”,”-c”,”echo hello $name"] 62 63 CMD 64 容器启动时默认执行的命令 65 如果docker run指定了其他命令(docker run -it [image] /bin/bash ),CMD命令被忽略 66 如果定义多个CMD,只有最后一个执行 67 68 ENTRYPOINT 69 让容器以应用程序或服务形式运行 70 不会被忽略,一定会执行 71 最佳实践:写一个shell脚本作为entrypoint 72 COPY docker-entrypoint.sh /usr/local/bin 73 ENTRYPOINT [“docker-entrypoint.sh] 74 EXPOSE 27017 75 CMD [“mongod”] 76 77 [root@master home]# more Dockerfile 78 FROm centos 79 ENV name Docker 80 #CMD ["/bin/bash","-c","echo hello $name"] 81 ENTRYPOINT ["/bin/bash","-c","echo hello $name”]
docker容器手动解决yum依赖关系
docker exec -it 交互式的进入容器空间,进入后可以手动yum解决依赖关系
1.手动的yum下载 wget
2.手动的 下载 阿里云的yum源
3.手动的下载vim
4.手动的进入到 /opt目录
自动解决依赖关系
dockerfile
RUN yum下载 wget
RUN 下载 阿里云的yum源
RUN 下载vim
WORDIR /opt
Dockerfile实战,构建自己的flask镜像
第一步
# 创建一个s18dockerfile文件夹 然后touch Dockerfile(必须是这个名)
# 然后在创建一个py文件,这里就叫做s18-flask.py,把flask代码写到里面
# 准备一个flask代码文件,内容如下
#coding:utf8
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello():
return "hello,i am docker"
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)
# python3 s18-flask.py,然后在web上输入192.168.81.132:8080测试一下
第二步
# 编写dockerfile(写在Dockerfile里面)
FROM centos #指定centos基础镜像
COPY CentOS-Base.repo /etc/yum.repos.d/ #拷贝宿主机的文件,到容器空间下
COPY epel.repo /etc/yum.repos.d/ #拷贝宿主机的文件,到容器空间下
RUN yum clean all #执行清空yum缓存的命令
RUN yum install python-setuptools -y #想安装python依赖工具
RUN easy_install flask #是想让docker自动的帮咱们安装python2的flask模块
COPY s18-flask.py /opt/ #把本地的代码文件,拷贝到容器的/opt目录下
WORKDIR /opt #进入到/opt目录下
EXPOSE 8080 #暴露容器的8080端口,供给外部宿主机去访问
CMD ["python","s18-flask.py"] #cmd代表你要执行的命令
第三步
# 确保文件都准备好了,如下所示
# CentOS-Base.repo epel.repo 这两个文件是因为dockerfile里面需要,所以需要copy过来,都在/etc/yum.repos.d/里面
[root@localhost s18dockerfile]# ls
CentOS-Base.repo Dockerfile epel.repo s18-flask.py
第四步
# 构建镜像
docker build -t attila163/flask-hello-docker # -t 是tag 后面写什么就把他命名为什么
第五步
# 通过自己构建的镜像,运行一个flask程序
docker run -d --name flask -p 5555:8080 s18-flask
第六步
通过浏览器去访问linux宿主机的 5555端口,即可访问到flask程序
192.168.81.130:5555
十 . 搭建私有docker仓库
第一步
# 下载docker私有镜像
docker pull registry
第二步
# 修改docker的配置文件
#修改如下配置文件
vim /etc/docker/daemon.json
修改内容如下
{"registry-mirrors": ["http://95822026.m.daocloud.io"],
"insecure-registries":["192.168.81.130:9999"]
}
第三步
# 修改docker的service配置文件,让它加载/etc/docker/daemon.json
# 修改如下文件
vim /lib/systemd/system/docker.service
添加如下配置到 [service]代码块中
EnvironmentFile=-/etc/docker/daemon.json
第四步
# 重启docker的服务
systemctl daemon-reload
systemctl restart docker
第五步
# 重新启动一个私有镜像仓库的容器实例
docker run --privileged=true -d -p 9999:5000 -v /opt/data/registry:/var/lib/registry registry
# --privileged=true docker容器的安全机制:设置特权级运行的容器
第六步
# 推送本地镜像,到私有仓库中
docker push 192.168.81.130:9999/s18-hello-world
第七步
# 检查docker私有仓库的api地址,检查json数据
http://192.168.81.130:9999/v2/_catalog
第八步
#尝试下载私有仓库的镜像
docker pull 192.168.81.130:9999/s18-hello-world