前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker入门篇

docker入门篇

作者头像
保持热爱奔赴山海
发布2019-09-18 15:31:33
5350
发布2019-09-18 15:31:33
举报
文章被收录于专栏:饮水机管理员饮水机管理员

基础知识不回顾了,直接上。

docker的安装与启动

yum remove docker -y

yum install docker-io -y # 需要先配置好epel源

/etc/init.d/docker start

chkconfig docker on

获取镜像

docker pull centos       # 从docker仓库下载一个镜像例如:docker pull centos:6.7

docker p_w_picpaths            #列出本地已存在的镜像

docker p_w_picpaths centos # 查看指定的镜像

运行

# docker run centos /bin/echo'Hello world'

# docker run -i -t centos:6.7/bin/bash

    -i表示输入终端保持打开状态

    -t表示开一个伪终端,并绑定到标准输入上

    -c限制运行的某个容器的CPU配额【最大默认是1024】

    --cpuset-cpus=  设置可以绑定使用几个CPU,具体可以看help

    -d 表示后台运行容器,只输出容器的ID到屏幕

    -P表示--publish-all=false     Publish all exposed ports to random ports

    --hostname=docker1.demo.com 表示修改容器的hsotname

    --name=lnmp1      表示给启动的容器命名,不用随机名称

    --dns=xx.xx.xx.xx 自定义DNS服务器地址【不指定该参数的话,就是要外部主机的/etc/resolv.conf来配置容器】

    --add-host "www.demo.com:192.168.2.2"  在容器的/etc/hosts添加一条指定的DNS解析记录

    --expose80 --expose 8080       # 暴露端口在外部Expose a port or a range of ports

    --memory1G       限制容器最大使用的内存

    *centos后面如果不指定版本,则默认选择latest版本

输入exit或者Ctrl+d退出

# docker run -ti --name test3--hostname=docker1.demo.com --dns=192.168.2.2 --dns=8.8.8.8 lanmp:v1 /bin/bash  # 复杂的写法

# docker run -d ubuntu:14.04/bin/sh -c "while true; do echo hello world; sleep 1; done" 以后台进程模式运行

# docker logs 后面跟容器的NAMES

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

检查本地是否存在指定的镜像,不存在就从公有仓库下载

利用镜像创建并启动一个容器

分配一个文件系统,并在只读的镜像层外面挂载一层可读写层

从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去

从地址池配置一个 ip 地址给容器

执行用户指定的应用程序

执行完毕后容器被终止

# docker ps 查看在运行中的docker实例进程

# docker logs insane_babbage    查看容器中的标准输出

# docker stop insane_babbage    停止某个容器

# docker ps可以看到刚才启动的那个centos容器没有了

# docker ps -a 可以看到所有的容器(包括已停止的)

# docker start insane_babbage      # 如果加-i参数可以进入交互式的容器

# docker version     查看docker客户端版本和进程的版本信息

ubuntu容器安装软件:

默认安装好的ubuntu docker是没有vim和ping这些命令的。

进入容器后,执行

# apt-get update

# apt-get install vim -y

然后vi /etc/apt/sources.list 添加阿里云的源地址。

# apt-get install inetutils-ping-y

# ping www.qq.com 即可

查看帮助信息

# docker  只输入docker指令,系统会自动列出全部可用的命令列表

# docker p_w_picpaths --help

创建镜像方法1:修改镜像

# docker run -i -t centos:6.7/bin/bash       记下容器的ID,例如:e2d6c890682f

在容器中添加LAMP环境

# yum install httpd mysql mysql-server php php-mysql -y 

# exit 退出容器

# docker commit -m "Add LAMPenv" -a "CentOS_LAMP" e2d6c890682f 6.7lamp   提交更新后的副本

    -m message

    -a author

# docker p_w_picpaths   可以看到已经生成了一个镜像

# docker run -i -t 6.7lamp/bin/bash      用刚才创建的镜像启动容器

另外,可以使用docker commit -m 'my nignx' e2d6c890682fdemo/my_nginx:v1 这种创建带明显标志的镜像。

启动的话使用docker run -d -p 88:80 --name "ningx_1" demo/my_nginx:v1 即可。

方法2、dockerfile创建基于centos6.7的nginx的容器

mkdir /opt/docker-file

cd /opt/docker-file

mkdir nginx && cd nginx

vi Dockerfile 内容如下:

# This is My First Dockerfile

# Verson 1.0

# Author: Lee

FROM centos:6.7

MAINTAINER Lee

ADD pcre-8.36.tar.gz/usr/local/src       <--- 1、需要事先把这个tar.gz包拷贝到当前目录下,即和Dockerfile在同一个目录下

ADD nginx-1.11.5.tar.gz/usr/local/src <---2、如果是个压缩包,拷到容器后会自动解压的,无需我们解压操作

RUN rm -fr /etc/yum.repos.d/*

RUN wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo

RUN wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo

RUN yum clean all

RUN yum install -y wget gcc gcc-c++ make openssl-devel

RUN useradd -s /sbin/nologin -Mwww

WORKDIR/usr/local/src/nginx-1.11.5

RUN ./configure--prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status--with-pcre=/usr/local/src/pcre-8.36 && make && make install

RUN echo 'daemon off;' >>/usr/local/nginx/conf/nginx.conf

RUN sed 's@#user  nobody;@user www;@g' nginx.conf

ENV PATH/usr/local/nginx/sbin:$PATH

EXPOSE 80

CMD ["nginx"]

docker build -t dockfile:v2 . 这样就可以创建镜像了

启动刚才创建的nginx docker容器的话,使用docker run -d -p 8888:80 dockfile:v2即可。

参数说明:

指令:

FROM <p_w_picpath>[:tag>]  或者FROM <p_w_picpath>@<digest>   # 必须是第一个非注释的行,用于指定所用到的基础镜像

MAINTAINER <author's detail>

COPY ["<src>", ..."<dest>"]       复制本地主机的目录到容器里的指定目录

    <src>是要复制的源文件或目录,支持通配符

    <dest>目标路径,正在创建的镜像文件的文件系统路径(建议使用绝对路径)

说明:所有新复制生成的目录文件的UID和GID都是0

例如: COPY /home/template/server.xml/etc/tomcat/server.xml

          COPY *.conf /etc/httpd/conf.d/

注意:src 必须是build上下文的路径,即不能使用类似../../conf/*.conf,但是还是可以使用绝对路径例如/home/conf.d/*.conf ;src如果是目录的话,递归复制会自动进行;如果有多个src,包括在src上使用了通配符,此时dest必须是目录,而且必须得以/结尾。

       dest如果事先不存在,它会被自动创建,包括其父目录。

ADD 类似COPY指令,额外还支持复制tar格式的文件及URL路径。【ADD比COPY用得更常见些】

例如:ADD haproxy.cfg /etc/haproxy/haproxy.cfg

     ADDlogstash_*.cnf /etc/logstash/

         ADD http://www.demo.com/download/nginx.conf/etc/nginx/ 【URL格式指定的源文件,下载完成后其目标文件权限为600】

如果src是一个宿主机上的tar文件,则它将被解压展开成要给目录(类似tar xf命令,如果通过URL下载的是个tar文件,则不会被自动展开)

ENV    定义环境变量,此些变量可以被当前dockerfile文件中的其它指令所调用,调用格式为$variable_name或${variable_name}

语法:

       ENV<key> <value>  一次定义一个变量

或者 ENV <key>=<value>...  一次可以定义多个变量,如果value中有空白字符,要是\进行转义

如: ENV myName="Tom Lee" myDog='wang cai'

说明:ENV定义的环境变量在镜像运行的整个过程中一直存在,因此可以使用docker inspect查看,甚至可以用docker run --env=xxx 来修改其值

USER 指定运行容器时,或者运行RUN CMD ENTRYPOINT指令指定的程序时使用的用户名或者UID

格式: USER <UID>|<Username>

WORKDIR 为后续的RUN、CMD、ENTRYPOINT、COPY、ADD指令配置工作目录

如:

    WORKDIR/a

    WORKDIRb

    WORKDIRc

    RUNpwd

则最终路径为 /a/b/c

另外,  WORKDIR还可以调用由ENV定义的环境变量的值,如: WORKDIR $STATEPATH

ENTRYPOINT

VOLUME 在目标镜像文件中创建一个挂载点,用来挂载主机上的卷或其他容器的卷。一般用来存放数据库和需要保持的数据等。

    VOLUME<mountpoint>

例如: VOLUME ["/data/mysql","/data/Images"]

注意:如果mountpoint路径下事先有文件存在,则在挂载完成后,会同时显示当前的文件和挂载前的文件(AUFS的叠加原理)。

RUN                          

每个RUN都会另起一层,所以建议将多个命令放到一行,减少AUFS的层数。

格式:

RUN <command>    # 会启动一个shell解释器

或RUN ["<executeable>","<param1>","<parma2>",...]       # 不会启动shell解释器

例如:

       RUNyum install iproute nginx && yum clean all

RUN['/bin/bash','-c','yum','install','httpd']

CMD    设定在docker run时默认执行的命令

格式: CMD <command> 或CMD ["<executeable>","<param1>","<parma2>"]

或CMD["<param1>","<param2>",...]  为ENTRYPOINT指令指定的程序提供默认参数。

如果dockerfile中存在多个CMD指令,则只有最后一个生效。

例如:

       CMD["/usr/sbin/httpd","-c","/etc/httpd/conf/httpd.conf"]

ENTRYPOINT 类似CMD指令,但其不会被docker run的命令行参数指定的指令所覆盖。且这些命令行参数会被当中参数送给ENTRYPOINT指令指定的程序

如果运行docker run时使用了--entrypoint选项,则此选项的参数可以覆盖掉dockerfile默认的entrypoint参数。

格式:

       ENTRYPOUNT<command>

       ENTRYPOUNT["executeable","<param1>","<param2>",...] 

例如:

注意:

如果CMD和ENTRYPOINT都存在的话,则CMD的指令会被附加到ENTRYPOINT后,变成ENTRYPOINT的参数。

EXPOSE     用于为容器指定要暴露的端口

格式:EXPOSE<port>[/protocol>][<port>[/<protocol>]]...

如:

       EXPOSE11211/tcp 11211/udp

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

例如: ONBUILD ADD my.cnf /etc/mysql/my.cnf

注意:ONBUILD不能自我嵌套,且不会触发。

导出镜像

# docker save -o/root/centos_lamp_v3.tar centos/lamp:v3

导入镜像

# docker load--input /root/centos_lamp_v3.tar

或者docker load </root/centos_lamp_v3.tar

# 这将导入镜像以及其相关的元数据信息(包括标签等)

移除镜像

# docker rmicentos/lamp:v3

注意:在删除镜像之前要先用dockerrm 删掉依赖于这个镜像的所有容器。

想要删除untagged p_w_picpaths,也就是那些id为<None>的p_w_picpath的话可以用

# docker rmi$(docker p_w_picpaths | grep "^<none>" | awk "{print $2}")

要删除全部p_w_picpath的话

# docker rmi$(docker p_w_picpaths -q)

删除已停止的容器

# docker rm -f$(docker ps -a -q)

移除容器

# docker rm5d6da6754d01

停止所有的container,这样才能够删除其中的p_w_picpaths:

# docker stop$(docker ps -a -q)

如果想要删除所有container的话再加一个指令:

# docker rm$(docker ps -a -q)

从本地文件系统导入一个镜像

要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建: openvz 的

模板下载地址为 templates 。

比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:

catubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04

上传镜像

docker pushouruser/sinatra

进入容器

在使用 -d 参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,有很多种方法,包括使用docker attach 命令或 nsenter 工具等

# docker attach 容器NAME

或者docker exec-ti 容器ID /bin/bash

但是使用 attach 命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。使用attach进到容器后要退出的话,只能关闭xshell了,使用exit会导致整个容器的退出。

nsenter 这个进入容器的命令也很好用(如果没有的话需要安装util-linux-ng)。

方法:

dockerinspect  --format"``.`State`.`Pid`" 容器NAME或者容器ID号      # 结果会输出一个容器的pid号

nsenter --target 容器的pid号 --mount --uts --ipc --net--pid

上面2条命令可以做成脚本,in.sh 内容如下:

#!/bin/bash

CNAME=$1

CPID=$(dockerinspect  --format"``.`State`.`Pid`" $CNAME)

nsenter--target $CPID --mount --uts --ipc --net --pid

sh in.sh 容器的NAME或者ID号,即可进入容器。

导出容器快照到本地文件

# docker ps -a

# docker export 容器名称 > ubuntu.tar

导入容器快照为镜像

# cat ubuntu2.tar |docker import - test/ubuntu:v1

# docker p_w_picpaths

自己基于centos构建nginx容器:

首先启动一个centos容器,然后在里面安装nginx(我这里是yum安装的nginx)。

修改nginx的配置文件,加上daemon off; 参数。

然后继续。下面有2种方法启动容器时候让它自动启动nginx

方法1:

    dockercommit -m 'nginx_v1' eb919426f773 6.7_nginx_v1

    dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /usr/sbin/nginx

这样就可以了。

方法2:

修改容器的/etc/bashrc 加上/usr/sbin/nginx -c/etc/nginx/nginx.conf

    dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /bin/bash

docker私有仓库的搭建

【作为仓库的虚拟机IP为:192.168.2.11】:

# 必须先启动docker registry【centos6上是这样的。在centos7上则变成了一个守护进程,需要用systemctl来启动】

# docker pullregistry

# docker run -d-p 5000:5000 -v /opt/data/registry:/tmp/registry registry

# docker ps   记下容器NAME为kickass_wright

# 默认情况下,仓库会被创建在容器的 /tmp/registry 下。可以通过 -v 参数来将镜像文件存放在本地的指定路径。

# docker p_w_picpaths   列出当前的镜像

# docker tag88e44a5cbd17 192.168.2.11:5000/centos/lamp 

格式:dockertag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]

# docker p_w_picpaths

Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。

修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。

# docker stopkickass_wright       停掉registry容器

#/etc/init.d/docker restart    重启docker

# docker startkickass_wright      启动registry容器

# docker push192.168.2.11:5000/centos/lamp       将本地镜像推送到本机上的私有服务器上

这样本地镜像就是上次到私有docker 仓库了。

我们可以在其他节点测试能否下载这个镜像。如果没问题的话,就可以在本机上删除原有的docker镜像,如下:

# docker rmi 192.168.2.11:5000/centos/lamp

在Node2节点(192.168.2.12)测试:

# yum installdocker-io -y

修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。

#/etc/init.d/docker restart    重启docker

# docker pull192.168.2.11:5000/centos/lamp          从192.168.2.11的私有仓库下载镜像

# docker p_w_picpaths      可以看到已经下载好了相关的镜像

docker的监控命令:

docker ps [-a]

docker p_w_picpaths

docker stats Container_name # 实时查看某个容器的负载情况

docker top Container_name       # 实时查看某个容器的状态统计(类似top命令)

 dockerinspect   # 查看容器或镜像的底层信息

例如:docker inspect -f'``.`Config`.`Hostname`' d413082da04e  类似ansible的 ansible -m setup的输出格式

此外,还有谷歌提供的CAdvisor web界面的监控工具;Scout工具,Data Dog工具,等。具体可参考: http://dockone.io/article/397

数据卷:

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 卷会一直存在,直到没有容器使用

*数据卷的使用,类似于 Linux 下对目录或文件进行 mount

下面创建一个web 容器,并加载一个数据卷到容器的/webapp 目录:

# docker run -d-P --name web -v /webapp training/webapp python app.py  

# 这样只写名容器中的目录不写宿主机的目录的话,实际上是在宿主机的/var/lib/docker/volumes/xxxx/目录下的。不常用这种写法。

-v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷

*注意:也可以在 Dockerfile 中使用 VOLUME 来添加一个或者多个新的卷到由该镜像创建的任意容器。

挂载一个主机目录src/webapp作为容器的数据卷:

# docker run -d-P --name web2 -v /src/webapp:/opt/webapp training/webapp python app.py

# 格式:-v 本地路径:容器路径

* 上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp 目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。

* 本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。

* 注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。

Docker 挂载数据卷的默认权限是读写,用户也可以通过:ro 指定为只读。

# sudo docker run-d -P --name web -v /src/webapp:/opt/webapp:ro training/webapppython app.py

-v 标记也可以从主机挂载单个文件到容器中

# docker run --rm-it -v ~/.bash_history:/.bash_history ubuntu /bin/bash   【不同shell版本有所不同】

*注意:如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者 sed --in-place ,可能会造成文件inode 的改变,从 Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。

数据卷容器:

如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。

数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:

# docker run -i-t -v /dbdata --name dbdata ubuntu:12.04/bin/bash

再启动2个容器测试

# docker run -i-t --volumes-from dbdata --name db1 ubuntu:12.04/bin/bash

# docker run -i-t --volumes-from dbdata --name db2 ubuntu:12.04/bin/bash

# 注意:--volumes-from后面跟的是具备容器卷的那个容器名

此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。[即便原来的那个数据卷容器已经停止了]

查看数据卷实际的存放路径:

docker inspect -f``.`Volumes` 数据卷容器的NAME或ID

map[/dbdata:/var/lib/docker/volumes/7c12ca73fe29f884ea5bee12c54da521c7450705264f76fe8629877302cd48aa/_data]

可以看到这个容器卷是把文件写入到/var/lib/docker/volumes下面的某个很长的字符串的目录下的_data/里面

容器和宿主机间文件拷贝的解决方法:

docker ps 获取目标容器的ID或者容器的名称    # 我这里的是容器ID为52261df2fab6

docker inspect-f'``.`Id`' 容器的ID      # 获取容器的ID全名称

得到一串类似52261df2fab612b24b3502c4ad98c22aff70ce9fa641c5c9f735ac2415e92da3

cp /root/test.log/var/lib/docker/devicemapper/mnt/52261d...xxx/rootfs/root/   # 这样就把宿主机的test.log拷贝到容器的/root/目录下了。

# 说明:上面的这个方法在CentOS6.7通过yum安装的docker-io测试通过。我另一台测试机安装的是docker-engine,则根本没有/rootfs/这个目录。

还可以使用多个--volumes-from 参数来从多个容器挂载多个数据卷。

# docker run -i-t -v /dbdata --name dbdata ubuntu:12.04/bin/bash

# docker run -i-t -v /webdata --name webdata ubuntu:12.04/bin/bash

# docker run -i-t --volumes-from dbdata --name db1 --volumes-fromwebdata --name web1 ubuntu:12.04 /bin/bash

此外,也可以从其他已经挂载了数据卷的容器来挂载数据卷。

*注意:

使用 --volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。

如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。

如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 "docker rm -v 容器名" 命令来指定同时删除关联的容器。这可以让用户在容器之间升级和移动数据卷。另外,如果启动时候加了--rm参数,则容器关闭时自动删除容器并删除卷。

利用数据卷容器来备份数据

# docker run -i-t -v /dbdata --name dbdata ubuntu:12.04 /bin/bash

# cp /etc/issue/etc/group /dbdata

另外启动一个容器,对刚才的容器数据进行备份操作

# docker run --volumes-fromdbdata -v $(pwd):/backup --name bk1 ubuntu:12.04 tar czf/backup/backup.tar.gz /dbdata

# 格式:dockerrun --volumes-from要备份的容器名-v 宿主机目录:/backup ubuntu:12.04 tar czf /backup/xx.tar.gz 需要备份的容器的卷名称

*容器启动后,使用了 tar 命令来将 dbdata 卷备份为容器下的/backup/backup.tar.gz,这个容器执行完就自动退出了(因为没有-ti 或-d参数),

*同时在宿主机下当前目录下生成backup.tar.gz压缩文件(参数-v $(pwd):/backup就是这个作用).

利用数据卷容器来恢复数据

如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。

# docker run -it-v /dbdata --name dbdata2 ubuntu:12.04 /bin/bash

随便在/dbdata里面复制些文件,以便后面恢复数据时用于识别。

然后创建另一个容器,挂载 dbdata2 的容器,并使用tar解压备份文件到挂载的容器卷中。

#docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu:12.04 tar xf/backup/backup.tar.gz

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-11-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • docker私有仓库的搭建
  • 数据卷:
  • 数据卷容器:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档