Docker

  docker说白了就是:环境打包

我们能用docker什么?

  1.如果配置好本地的linux环境交接给其他人,很麻烦,交接时要告诉他,装这个装那个,还可能出现问题,那我直接把这个环境放到docker中打包成镜像给他,原来的环境怎么样的还是怎么样,我们不能去纠结配置环境的问题,而留下更多的时间来解决其他问题

  2.虚拟化技术,很多就用了docker把一些已经装好的资源分配给云用户,让用户购买他们的服务等

帮助文档  

  文档:http://www.dockerinfo.net/document

docker三大要素

  镜像:模板(类似于'类')

  容器:镜像的实例(类似于'对象')

  仓库:存放镜像文件的地方,可能在云,可能在注册服务器上,最大的公开仓库是docker hub,国内阿里云就够用了

docker本身是一个容器运行载体,我们把我们要的配置程序和依赖包形成一个可以交付的运行环境,把这个环境打包成为一个image镜像文件,只有通过这个镜像文件才能生成docker容器,image文件可以看做容器的模板,docker根据image文件生成容器的实例,同一个image文件,可以生成多个同时运行的容器实例

安装:使用 yum 安装(CentOS 7下)

  目前docker要求centos7环境达到64位,系统内核版本3.10以上

cat /etc/redhat-release #查看linux内核版本
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
#移除之前版本 sudo yum install -y yum-utils device-mapper-persistent-data lvm2
#安装一些必要的系统工具 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#添加软件源信息 sudo yum makecache fast
#更新 yum 缓存 sudo yum -y install docker-ce
#安装 Docker-ce sudo systemctl start docker
#启动 Docker 后台服务 docker version
#查看docker版本

docker的基本使用:

创建一个容器并执行命令

docker pull ubuntu:15.10  #拉取官方的乌版图
docker run ubuntu:15.10 /bin/echo "Hello world"
#docker执行docker的二进制文件
#run 结合docker一起使用,表示运行一个容器
#ubuntu:.10指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像
#/bin/echo "Hello world": 在启动的容器里执行的命令

运行交互式容器命令

docker run -i -t ubuntu:15.10 /bin/bash
#-i -t -t:在新容器内指定一个伪终端或终端。 -i:允许你对容器内的标准输入 (STDIN) 进行交互。

  运行exit命令或者使用CTRL+D

启动容器(后台模式)

docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
#返回bf8e12e0315d51a7fb8ee2cc2b788f13b1a651aadbb9194e6ff74825fade3d0a,这个长字符串叫做容器ID,由64位组成,对每个容器来说都是唯一的,我们可以通过容器ID来查看对应的容器发生了什么
docker ps ↓

CONTAINER ID:容器ID    NAMES:自动分配的容器名称

docker logs CONTAINER_ID /或者 NAME 命令,查看容器内的标准输出

docker logs amazing_cori
docker logs -f amazing_cori    #,-f参数可以像tail -f xxx.log一样输出
docker logs tail 3 amazing_cori  #查看倒数三行并持续输出

docker帮助命令

docker ps --help 查看docker ps的帮助
docker info #查看主机个人信息

查看容器

docker ps -a #查看所有容器
docker ps -l #查看最后一次创建的容器
docker ps   #查看正在使用的容器
docker ps -s #查看正在使用的容器,增加参数容器大小 

停止容器

docker stop amazing_cori

启动容器

docker start amazing_cori

运行容器实例

docker pull training/webapp #载入镜像,载入步骤,docker先回去local本地找你输入的镜像名称,如果没有则去你设置的镜像仓库pull拉去
docker run -d -P training/webapp python app.py
#-d 后台运行 -P将容器内部使用的网络端口映射到我们使用的主机上

  运行127.0.0.1:32768显示hello world!

查看dockor端口

  dockor port 容器名

  #或者可以加端口号docker port 容器名 5000 

查看应用程序配置信息

docker inspect 9ac    #查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息

创建容器

#该命令与run命令一样,但唯一区别是只是创建,不启动
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker create --name myrunoob nginx:1.3

kill命令

docker kill [OPTIONS] CONTAINER [CONTAINER...]
docker kill -s KILL nginx #杀掉nginx -s为向容器发送的信号

top命令

docker top 容器名称    #返回容器中的ps -ef 操作

 

移除容器

删除容器时,容器必须是停止状态,否则会报错,除非加-f

docker rm xxx
docker rm -f xxx  #强制删除
docker rm -f xxx01 xxx02 #删除多个
docker rm -f $(docker images -qa)  #删除所有容器

pause/unpause命令

docker pause :暂停容器中所有的进程。

docker unpause :恢复容器中所有的进程。

docker的镜像

  当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载

列出本机docker的所有镜像源

[root@rainbol ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 months ago .84kB
ubuntu 15.10 9b9cb95443b5 years ago 137MB
training/webapp latest 6fae60ef3446 years ago 349MB
  • REPOSITORY:表示镜像的仓库源

  • TAG:镜像的标签,指定不同的镜像标签对应不同的仓库源版本,如果在docker run时不指定镜像仓库源的版本,默认latest最后版本

  • IMAGE ID:镜像ID

  • CREATED:镜像创建时间

  • SIZE:镜像大小

docker images  -a  #列出本地所有镜像,含中间镜像层

          -q   #只显示当前镜像的IMAGE ID

          -qa   #列出本机所有镜像的IMAGE iD 可以做批处理操作,如删除

获取下载镜像  下载完成后就可以使用了

docker pull ubuntu:13.10
docker pull tomcat:7

查看镜像源

docker search httpd
docker search -s 1000 httpd  #查看点赞数超过1000的httpd源

删除镜像

docker rm images [images id]
docker rmi [images id]    #rm images 和 rmi 是一样的
docker rmi -f [images id]   #强制删除

docker镜像原理

  docker镜像基于联合文件系统组成,一层套一层的结构,比如我们要下载tomcat,原理是不同发行版本共用linux内核(rootfs).这是底层,之后下载精简版centos->之后下载jdk->最后才下载tomcat,所以说这一层一层的结构组成了tomcat,镜像删除后会留在主机缓存,第二次安装会比第一次快

端口映射

docker run -d -p : training/webapp python app.py
-p : 是容器内部端口绑定到指定的主机端口。左5000是实际服务器端口,右5000是容器5000端口 docker run -d -p 127.0.0.1:: training/webapp python app.py 也可以指定ip docker run -d -P training/webapp python app.py
-P 是容器内部端口随机映射到主机的高端口 默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp

如何进入一个已经创建了的容器

进入Docker容器比较常见的几种做法如下:

  • 使用docker attach
  • 使用SSH
  • 使用nsenter
  • 使用exec

1.首次创建进入容器时,让/bin/bash可用

docker run -i -t -d ubuntu:15.10 /bin/bash    #-d表示后台运行/bin/bash
docker attach xxx  #进入容器,xxx为容器id,直接进入容器启动命令的终端,不会启动新的进程

  当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作

2.使用SSH进入Docker容器(不推荐)

3.nsenter进入容器

$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz
$ tar -xzvf util-linux-2.24.tar.gz
$ cd util-linux-2.24/
$ ./configure --without-ncurses
$ make nsenter
$ sudo cp nsenter /usr/local/bin docker ps
sudo docker inspect -f {{.State.Pid}} xxx   #xxx为容器id拿到PID为1234 sudo nsenter --target 1234 --mount --uts --ipc --net --pid  #把PID为1234放进入就就可以进入容器了

4. exec命令  在容器中打开命令的终端,不会启动新的进程

docker ps    #拿到容器id为xxxxx
docker exec -it xxxxx /bin/bash  #-it的意义就是开启交互终端的意思
docker exec -it xxxxx ls  #执行或者查看结果指令,会返回给我们,但是不会进入容器内

  

退出容器

exit

docker安装nginx

#nginx的简单部署
docker pull nginx #安装nginx源
docker run --name nginx_test -P -d nginx #创建并运行nginx
nginx自定义部署
mkdir -p ~/nginx/www ~/nginx/logs ~/nginx/conf #首先在目录建立nginx目录 docker run -d -p : --name runoob-nginx-test-web -v ~/nginx/www:/usr/share/nginx/html -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/nginx/logs:/var/log/nginx nginx
#-v为创建挂载,将本地的文件加载到容器中,需指定位置

文件下载与下载

docker cp 容器id:容器文件路径 宿主机路径  #从容器中下载到主机
dockor cp 宿主机路径 容器id:容器路径    #主机上传到容器

docker镜像加速

我们经常发现连接国外的镜像下载很慢,那就使用国内厂商的镜像加速,这里推荐阿里云镜像加速器,登陆阿里云账号后搜索容器镜像服务->镜像加速器->centos->到本机中如linux  $vi /etc/docker/daemon.json (如果没有的话就新建,默认就是没有的) -> 添加 {
"registry-mirrors": ["https://cz6ionug.mirror.aliyuncs.com"]
} 这个字典后保存->重启
sudo systemctl daemon-reload
sudo systemctl restart docker

docker查看容器中的进程

docker top PID

docker commit/pull使用

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-a :提交的作者
-c :使用dockerfile指令来创建镜像
-m:提交时的文字说明
-p :在commit时,将容器暂停 docker commit -a "rainbol" -m "提交了" 65asd2a mydocker:v1 #提交到本地 docker push [OPTIONS] NAME[:TAG] options:--disable-content-trust :忽略镜像的校验,默认开启
docker push rainbol/mydocker:v1 #提交到dockerhub,需要登录账号

docker数据卷  

  容器与主机数据共通,实现持久化和数据共享

docker run -it -v /主机绝对路径:/容器绝对路径  镜像名        #建立数据挂载链接
-v:开启卷
docker inspect sad213d 找到 volumes生成了一个字典并且hostconfig:binds中生成字典说明链接成功了
此时主机和容器内这两个文件夹里面的数据资源共享共存,容器重启后数据同步 docker run -it -v /主机绝对路径:/容器绝对路径:ro 镜像名 #ro(read only只读) 只允许主机单向的操作,容器只能进行读操作 在docker inspect sad213d命令中volumesRw会变成false

    没有指定宿主机docker默认会添加一个路径文件,可在inspect命令中查看

dockerfile形式添加数据卷

  由于docker不支持docker run -it -v /主机绝对路径1:/容器绝对路径1 -v  /主机绝对路径2:/容器绝对路径2  存在迁移性

  引入dockerfile,建立更多的容器卷    

docker数据卷容器

  说白了就是主容器与副容器的挂载链接,实现资源共享

docker run -it --name test1 tomcat    #建立主容器
docker run -it --name test2 --volumes-from test1 tomcat # --volumes-from 被继承容器名,test2继承test1的所有,之后主容器和副容器的数据卷同步共享
容器之间配置信息的传递,数据卷的生命周期一直持续到其没有容器使用为止,也就说在无限被继承中,无论哪个容器挂了,其资源共享,配置信息依旧存在

    1.构建可执行的shell脚本

FROM tomcat
VOLUME ["/data01","/data02"]
CMD echo "finished,----success"
CMD /bin/bash

    2.build生成镜像  

docker build  -f /dockerfile文件绝对路径 -t rainbol/mytomcat /存放目录    #-f指定dockerfile路径 -t命名空间/镜像名称
#如果build的dockerfile文件在当前目录可以不用写'-f dockerfile文件路径'

dockerfile的使用

  dockerfile就是用来构建docker镜像的构建文件,说白了就是个执行参数和命令的脚本而已

  dockerfile文件规则:1.保留字指令必须大写,后面至少一个参数

            2.命令从上到下执行

            3.#表示注释

            4.每条指令都会创建一个新的镜像层,并对镜像进行提交(如FROM centos,加第一层进行,如果要再加其他的,就再加,这就是层层累加)

  FROM

#第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)

FROM <images>   
FROM <image>:<tag>  
FROM centos 
FROM scratch #基础镜像->祖先源镜像

  MAINTAINER

    维护者信息(名字和邮箱)

  RUN

    容器运行时需要的额外命令

RUN <command>
RUN chmod -R 777 tomcat-7 RUN ["executable", "param1", "param2"] #使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]
RUN ["/bin/bash", "-c", "echo hello"]

  EXPOSE 

EXPOSE <port> [<port>...]
EXPOSE 8080 #告诉 Docker 服务端容器暴露的端口号

  WORKDIR

WORKDIR /usr/local    #在创建后终端登录到容器后默认进入的工作目录

  ENV

ENV <key> <value>    #设置环境变量
ENV MY_TEST /usr/local
WORKDIR $MY_TEST

  COPY

格式为 COPY <src> <dest>。
复制本地主机的 <src>(为 Dockerfile 所在目录的相对路径)到容器中的 <dest>。
当使用本地目录为源目录时,推荐使用 COPY。

  ADD

格式为 ADD <src> <dest>。
该命令将复制指定的 <src> 到容器中的 <dest>。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
说白了add = copy + 自解压

  CMD

支持三种格式

CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。 如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

  ENTRYPOINT

两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

说白了cmd是多个会被覆盖,而entrypoint多个会追加

  ONBUILD

ONBUILD [INSTRUCTION]
ONBUILD RUN echo '我被继承了--------ok'
ONBUILD ADD a.txt /usr/local

    配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令

案例1:

  重构centos镜像写一个dockerfile,初始路径为/usr/local,安装ifconfig,vim指令

#/mydocker/dockerfile
FROM centos
MAINTAINER rainbol<xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y vim
RUN yum -y net-tools
EXPOSE 80
CMD /bin/bash

  进入mydocker目录,运行

docker build -t rainbol/mycentos .  #构建镜像

  

docker run -it rainbol/mycentos /bin/bash  #运行

docker history ID    # 查看docker历史构建信息,下图可以看到我们刚刚构建的信息

案例2:

  重构centos镜像写一个dockerfile,初始路径为/usr/local,功能能访问ip.cn返回当前ip地址

#/mydocker/dockerfile2
FROM centos
MAINTAINER rainbol<xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install curl
ENTRYPOINT ["curl","-s","https://ip.cn"]  #注意这里参数不能为单引号,否则会报错
EXPOSE
CMD /bin/bash
docker build -f /mydocker/dockerfile2 -t rainbol/mycentos:1.1 .  

  

docker run rainbol/mycentos:1.1 -i
#-i为curl请求头的参数,此时会在ENTRYPOINT追加参数

案例3:

#/mydocker/dockerfile_test01
FROM centos
MAINTAINER rainbol<xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
ONBUILD RUN echo '我居然被继承了'
EXPOSE

  先构建上面dockerfile为test01  

#/mydocker/dockerfile_test02
FROM test01
MAINTAINER rainbol<xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
EXPOSE

  当构建上面mydockerfile时返回,可以看到执行了ONBUILD中的命令

案例4  自建tomcat服务器

1.在指定路径下存放tomcat.tar包和jdk,dockerfile文件,c.txt自建文档

2. 编写dockerfile脚本

#之前下载了centos,所以这里执行它
FROM centos
#命名作者
MAINTAINER rainbol<xxx@qq.com>
#拷贝c.txt到容器中重命名一个文档(为了测试,意义不是很大)
COPY c.txt /usr/local/cincontainer.txt
#将jdk复制到容器指定位置,注意ADD指令可以自动解压缩
ADD openjdk-9.0.4_linux-x64_bin.tar.gz /usr/local/
#将tomcat复制到容器指定位置
ADD apache-tomcat-9.0..tar.gz /usr/local/
#下载vim
RUN yum -y install vim #设置默认进入路径
ENV MYPATH /usr/local
WORKDIR $MYPATH
#设置环境变量
ENV JAVA_HOME /usr/local/jdk-9.0.
ENV CATAINA_HOME /usr/local/apache-tomcat-9.0.
ENV CATAINA_BASE /usr/local/apache-tomcat-9.0.
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATAINA_HOME/bin
#设置tomcat容器对外端口
EXPOSE
#执行启动和查看打印日志命令
CMD /usr/local/apache-tomcat-9.0./bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0./logs/catalina.out

3.build构建镜像

docker build -f /mydocker/dockerfile_test01 -t test01  .

4.启动镜像

docker run -d -p : --name newmt9 -v /mydocker/rainbol/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0./webapps/test -v /mydocker/rainbol/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0./logs --privileged=true mt9

#两个-v表示添加两个容器与主机挂载,一个是放应用或服务,一个是存放日志
#--privileged=true 有可能会出现权限不足,那加这个

5.测试  docker ps

有页面返回说明启动成功

安装mysql:

docker pull mysql:5.6  #选择相对稳定的5.6版本
docker run -p : --name mysql -v /
docker run --name mysql56 -p : -v /mydocker/rainbol/mydockerfile/mysql5./conf:/etc/mysql/conf.d -v /mydocker/rainbol/mydockerfile/mysql5./logs:/var/lib/mysql -e MYSQL_ROOT_PASSWORD= -d mysql:5.6
docker exec -it mysql56 /bin/bash

安装jenkins

  https://www.jianshu.com/p/12c9a9654f83

安装redis:

docker pull redis:3.2
docker run -p : -v /mydocker/rainbol/mydockerfile/redis3.2/data:/data -v /mydocker/rainbol/mydockerfile/redis3./conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes docker exec -it 0caf0428 redis-cli #连接容器内的redis客户端

发布

  本地的镜像发布到阿里云上 

.镜像生成
[root@rainbol redis3.]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dc2e60009bcb mt9 "/bin/sh -c '/usr/lo…" hours ago Up hours 0.0.0.0:->/tcp newmt9 [root@rainbol redis3.]# docker commit -a rainbol -m 'newtomcat' dc2e60009bcb newtomcat1. [root@rainbol redis3.]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
newtomcat1. latest 15ce08832084 minutes ago 728MB

 https://cr.console.aliyun.com进入阿里云镜像服务,创建完仓库

  第二行的镜像版本号是为你想传到阿里云仓库的版本号

    第三行的镜像版本号和第二行你刚刚填的镜像版本号保持一致

   第三步推送时间比较长要等很久

拉取阿里云的镜像

  私人:复制地址  docker pull 仓库地址:版本号  #注意可能出现多个版本,加版本号选择你想要的版本

  公开:  在镜像中心的镜像搜索进行下载镜像    docker pull 仓库地址:版本号  #注意可能出现多个版本,带版本号选择你想要的版本

docker镜像打包  如果不存在云仓库,因为云上上传和下载很慢,或者是公司没网,怎么办呢,可以使用镜像打包的方法 

  docker save

docker save [OPTIONS] IMAGE [IMAGE...]
docker save -o 要保存的文件名 要保存的镜像id
docker save -o /usr/local/nginx.tar jda090d1

  docker load

docker load [OPTIONS]
-i :指定导出的文件。
-q :精简输出信息。 docker load < /usr/local/nginx.tar
docker load -i /usr/local/nginx.tar -q

版权声明:本文原创发表于 博客园,作者为 RainBol本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

最新文章

  1. Web报表工具FineReport填报界面键盘操作
  2. js 对象合并
  3. Lua学习笔记一
  4. 关于STM32的抢占式优先级说明。——Arvin
  5. PHP高效率写法及原因
  6. java-正则表达式过滤字符串中的html标签
  7. Leaflet交流
  8. 设置lable内容不上下居中
  9. the partition number
  10. android 分辨率自适应
  11. 使用mongodb存取lbs数据
  12. Maven中settings.xml的配置项说明精讲
  13. 如何在 windows server 2008 上面 挂载NFS
  14. [模板] 网络流相关/最大流ISAP/费用流zkw
  15. UTC时间转换为本地时间
  16. 联想ts550服务器安装windows2008R2系统
  17. 综述 - 染色质可及性与调控表观基因组 | Chromatin accessibility and the regulatory epigenome
  18. Cacti的使用
  19. mysql学习(2)-Navicat Premium 12 链接MySQL8.0.11数据库报2059错误
  20. saltstack系列1之salt-api配置与使用

热门文章

  1. Lyrics of the song 99 Bottles of Beer
  2. 带CheckBox美化控件的表格全选
  3. Mahalanobia Distance(马氏距离)的解释
  4. JavaScript原生封装ajax请求和Jquery中的ajax请求
  5. LeetCode 503. 下一个更大元素 II(Next Greater Element II)
  6. mysql网文收录
  7. MVC与MTV模型
  8. int and Integer
  9. golang --iota 用法
  10. java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver 错误解决