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:15.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 6 months ago 1.84kB ubuntu 15.10 9b9cb95443b5 3 years ago 137MB training/webapp latest 6fae60ef3446 4 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 5000:5000 training/webapp python app.py -p : 是容器内部端口绑定到指定的主机端口。左5000是实际服务器端口,右5000是容器5000端口 docker run -d -p 127.0.0.1:5001:5000 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 8082:80 --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 80 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 80
先构建上面dockerfile为test01
#/mydocker/dockerfile_test02 FROM test01 MAINTAINER rainbol<xxx.com> ENV MYPATH /usr/local WORKDIR $MYPATH EXPOSE 80
当构建上面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.12.tar.gz /usr/local/
#下载vim RUN yum -y install vim
#设置默认进入路径 ENV MYPATH /usr/local WORKDIR $MYPATH
#设置环境变量 ENV JAVA_HOME /usr/local/jdk-9.0.4 ENV CATAINA_HOME /usr/local/apache-tomcat-9.0.12 ENV CATAINA_BASE /usr/local/apache-tomcat-9.0.12 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATAINA_HOME/bin #设置tomcat容器对外端口
EXPOSE 8080 #执行启动和查看打印日志命令
CMD /usr/local/apache-tomcat-9.0.12/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.12/logs/catalina.out
3.build构建镜像
docker build -f /mydocker/dockerfile_test01 -t test01 .
4.启动镜像
docker run -d -p 9876:8080 --name newmt9 -v /mydocker/rainbol/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.12/webapps/test -v /mydocker/rainbol/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.12/logs --privileged=true mt9 #两个-v表示添加两个容器与主机挂载,一个是放应用或服务,一个是存放日志 #--privileged=true 有可能会出现权限不足,那加这个
5.测试 docker ps
有页面返回说明启动成功
安装mysql:
docker pull mysql:5.6 #选择相对稳定的5.6版本
docker run -p 12345:3306 --name mysql -v / docker run --name mysql56 -p 12345:3306 -v /mydocker/rainbol/mydockerfile/mysql5.6/conf:/etc/mysql/conf.d -v /mydocker/rainbol/mydockerfile/mysql5.6/logs:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -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 2345:6379 -v /mydocker/rainbol/mydockerfile/redis3.2/data:/data -v /mydocker/rainbol/mydockerfile/redis3.2/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客户端
发布
本地的镜像发布到阿里云上
1.镜像生成 [root@rainbol redis3.2]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dc2e60009bcb mt9 "/bin/sh -c '/usr/lo…" 12 hours ago Up 12 hours 0.0.0.0:9876->8080/tcp newmt9 [root@rainbol redis3.2]# docker commit -a rainbol -m 'newtomcat' dc2e60009bcb newtomcat1.2 [root@rainbol redis3.2]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE newtomcat1.2 latest 15ce08832084 4 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 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。