docker基础(上)

文章目录

  • 一、安装部署
    • 1、新版CE版本安装
    • 2、启动以及启动参数
      • (1)daemon启动:
      • (2)flag启动方式
      • (3)docker服务和iptables共存
      • (4)常见启动参数说明
      • (5)让普通用户可以启动容器
  • 二、docker基础命令
    • 1、docker基础命令
      • (1)启动容器:
      • (2)查看容器:
      • (3)自定义容器名等:
      • (4)镜像简单管理:
      • (5)守护式容器:
      • (6)容器中部署静态网站:
    • 2、总结:
      • (1)进入容器不让容器退出方法扩展:
      • (2)导入导出Docker镜像
      • (3)映射
      • (4)优雅的退出容器,而容器不停止
      • (5)可以对cpu和内存的限制
  • 三、镜像管理
    • 1、基础操作:
    • 3、镜像制作
      • (1)将容器变成镜像:
      • (2)buildfile语法:
      • (3)例子
      • (4)镜像制作中的常见问题:

一、安装部署

Docker采用Linux(内核)技术,所以只能运行在Linux上,官方说Linux kernel至少3.8以上,且要是64位内核;
开发或测试环境:在windows和mac上都是利用boot2docker实现;boot2docker是一个专为docker而设计的轻量级linux发型包(借助virlbox虚拟机实现)
物理机或云主机:docker native(centos、ubuntu、atomic、Coreos)

版本变迁:
历史版本1.7–1.13,然后分ce和ee版本,直接跳到17.0N版本,最新版本是18.06
源码:https://github.com/docker/engine
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

1、新版CE版本安装

centos7:
The centos-extras repository must be enabled!

卸载旧版本:
sudo yum remove docker \
                  docker-common \
                  docker-selinux \
                  docker-engine
安装依赖:
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

可选(不建议enable):
$ sudo yum-config-manager --enable|disable docker-ce-edge
$ sudo yum-config-manager --enable|disable docker-ce-test

安装:
# sudo yum makecache fast
# yum list docker-ce.x86_64  --showduplicates | sort -r  #查看版本
 * updates: mirror.xtom.com.hk
Loading mirror speeds from cached hostfile
Loaded plugins: fastestmirror
 * extras: mirrors.aliyun.com
 * epel: mirror.pregi.net
docker-ce.x86_64            18.06.0.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            18.03.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.0.ce-1.el7.centos             docker-ce-stable

sudo yum install docker-ce #安装最新版本
sudo yum install docker-ce-<VERSION>  #安装特定版本
eg:yum install docker-ce-17.12.1.ce  #尝试安装此版本
# docker
docker                  docker-containerd-ctr   dockerd                 docker-proxy
docker-containerd       docker-containerd-shim  docker-init             docker-runc

★注意:

/usr/lib/systemd/system/docker.service明确指出使用systemd控制docker服务不支持cgroup特性,不过暂时是测试,为了方便,这里还是使用systemctl的方式来启动docker服务。

启动、停止等命令:

systemctl start|status|stop|enable docker

暂时还不确定k8s等编排工具是怎么调docker的,应该不是用的systemctl来控制吧???

2、启动以及启动参数

服务启动参数配置:
    参考官方文档:
        https://docs.docker.com/config/daemon/
        https://docs.docker.com/config/daemon/systemd/
        https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option

There are two ways to configure the Docker daemon:
    Use a JSON configuration file. This is the preferred option, since it keeps all configurations in a single place.
    Use flags when starting dockerd.
注意:

两者可以结合使用,不过不要重复,否则会报错,服务不会启动并会打印错误日志

(1)daemon启动:

mkdir /etc/docker

/etc/docker/daemon.json

{
  "debug": true,
  "hosts": ["tcp://10.40.2.228:2376","unix:///var/run/docker.sock"],
  "data-root": "/data/docker-data",
  "storage-driver": "overlay2",
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/24"
}

参数说明:

开启debug模式;
监听在本地ip地址的2376端口,另外启用sock模式,docker命令默认使用这种方式,
docker存储数据的位置改为/data/docker-data;
存储驱动使用overlay2;
docker0网桥的网关是192.168.1.1;
docker0网段是192.168.1.0/24;

注意:

  • docker的所有数据包括容器、镜像、volumes、service定义、密码等都是统一在/var/lib/docker目录下, 可以使用data-root定制。
  • Docker CE on CentOS支持两种存储驱动:devicemapper, vfs;查看当前docker的存储驱动:docker info
  • 更加详细的配置参考: https://docs.docker.com/engine/reference/commandline/dockerd/

(2)flag启动方式

dockerd --debug \
  --tls=true \
  --tlscert=/var/docker/server.pem \
  --tlskey=/var/docker/serverkey.pem \
  -H tcp://192.168.59.3:2376

# 启动多个daemons时必须指定的参数:
-b, --bridge=                          Attach containers to a network bridge
--exec-root=/var/run/docker            Root of the Docker execdriver
--data-root=/var/lib/docker            Root of persisted Docker data
-p, --pidfile=/var/run/docker.pid      Path to use for daemon PID file
-H, --host=[]                          Daemon socket(s) to connect to
--iptables=true                        Enable addition of iptables rules
--config-file=/etc/docker/daemon.json  Daemon configuration file
--tlscacert="~/.docker/ca.pem"         Trust certs signed only by this CA
--tlscert="~/.docker/cert.pem"         Path to TLS certificate file
--tlskey="~/.docker/key.pem"           Path to TLS key file

# 参考Example script for a separate “bootstrap” instance of the Docker daemon without network: 的方案:
sudo dockerd \
        -H unix:///var/run/docker-bootstrap.sock \
        -p /var/run/docker-bootstrap.pid \
        --iptables=false \
        --ip-masq=false \
        --bridge=none \
        --data-root=/var/lib/docker-bootstrap \
        --exec-root=/var/run/docker-bootstrap

如果docker服务长时间没有回应或者无法回应,可以用下面的命令打印出全栈跟踪信息:

Linux:
$ sudo kill -SIGUSR1 $(pidof dockerd)

# 查看全栈跟踪信息
journalctl -u docker.service
# 或者
tail -f /var/log/message |grep docker

(3)docker服务和iptables共存

暂时还没有明白docker是怎么调的iptables

  • 安装好docker之后,按如下配置文件,启动docker,使用iptables -nL
{
  "debug": true,
  "hosts": ["tcp://10.40.2.228:2376","unix:///var/run/docker.sock"],
  "data-root": "/data/docker-data",
  "storage-driver": "overlay2",
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/24"
}
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

总结:

  • 感觉,docker并没有通过iptables去修改netfilter,而是通过自己的机制去修改netfilter
  • 一旦安装iptables,yum install iptables-services -y并启动iptables之后,发现iptables的规则只有默认的,docker相关项被清空了,restart docker iptables规则回复正常。
  • 也就是说:docker一定要在iptables启动之后才能启动
  • iptables 一旦要reload,必须将现有规则保存进iptables-save > /etc/sysconfig/iptables,否则一旦iptables reload,docker相关规则又被清空了。

(4)常见启动参数说明

Daemon socket option:

默认:unix domain socket,at /var/run/docker.sock;需要root权限
可选:tcp socket,-H tcp://0.0.0.0:2375
可选:借助systemd的通讯方式,dockerd -H fd://3
例如: dockerd -H unix:///var/run/docker.sock -H tcp://192.168.59.106 -H fd://3
客户端:docker -H tcp://0.0.0.0:2375 ps

centos7支持devicemapper和overlay2两种存储,默认是overlay2

overlay2.size
Sets the default max size of the container. It is supported only when the backing fs is xfs and mounted with pquota mount option. Under these conditions the user can pass any size less then the backing fs size.
Example:
sudo dockerd -s overlay2 --storage-opt overlay2.size=1G

dns:

sudo dockerd --dns 8.8.8.8
or
sudo dockerd --dns-search example.com

push版权受限的镜像或者容器:比如window的

–allow-nondistributable-artifacts myregistry:5000
–allow-nondistributable-artifacts 10.1.0.0/16

私有镜像库Insecure registries:

–insecure-registry myregistry:5000
–insecure-registry 10.1.0.0/16
eg: --add-registry=master.example.com:5000 --insecure-registry=master.example.com:5000

Daemon user namespace options:
Node discovery:
Access authorization:

The list of currently supported options that can be reconfigured is this:

debug: it changes the daemon to debug mode when set to true.
cluster-store: it reloads the discovery store with the new address.
cluster-store-opts: it uses the new options to reload the discovery store.
cluster-advertise: it modifies the address advertised after reloading.
labels: it replaces the daemon labels with a new set of labels.
live-restore: Enables keeping containers alive during daemon downtime.
max-concurrent-downloads: it updates the max concurrent downloads for each pull.
max-concurrent-uploads: it updates the max concurrent uploads for each push.
default-runtime: it updates the runtime to be used if not is specified at container creation. It defaults to “default” which is the runtime shipped with the official docker packages.
runtimes: it updates the list of available OCI runtimes that can be used to run containers
authorization-plugin: specifies the authorization plugins to use.
allow-nondistributable-artifacts: Replaces the set of registries to which the daemon will push nondistributable artifacts with a new set of registries.
insecure-registries: it replaces the daemon insecure registries with a new set of insecure registries. If some existing insecure registries in daemon’s configuration are not in newly reloaded insecure resgitries, these existing ones will be removed from daemon’s config.
registry-mirrors: it replaces the daemon registry mirrors with a new set of registry mirrors. If some existing registry mirrors in daemon’s configuration are not in newly reloaded registry mirrors, these existing ones will be removed from daemon’s config.

限制一个容器的资源方式:
https://docs.docker.com/config/containers/resource_constraints/#memory

(5)让普通用户可以启动容器

  • data-root对应目录普通用户要有修改权限(好像不是必须的)
  • /var/run/docker.sock文件权限配置,否则报错:Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
useradd -u 200 -g users user_00
usermod -a -G docker user_00  #将普通用户加入docker组,docker命令可以正常执行,也就是普通用户user_00可以管理容器
chown -R root:docker /data/docker-data  #不是必须

二、docker基础命令

1、docker基础命令


注意:
图片中load和save两个方法箭头刚好都反了

(1)启动容器:

docker run IMAGE [command] [arg……]
    run 在新容器中执行命令

docker run centos echo "hello word"  执行一次的容器

启动交互式容器:
    docker run -i -t IMAGE  /bin/bash
    -i --interactive=ture|fasle 默认是false
    -t --tty=true|false 默认是false

eg:
docker run -it centos /bin/bash

容器内部:
[root@370204a25400 /]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  1 06:44 ?        00:00:00 /bin/bash
root         15      1  0 06:44 ?        00:00:00 ps -ef
[root@370204a25400 /]# ifconfig
bash: ifconfig: command not found
[root@370204a25400 /]# yum install net-tools -y
[root@370204a25400 /]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.3.2  netmask 255.255.255.0  broadcast 192.168.3.255
        ether 02:42:c0:a8:03:02  txqueuelen 0  (Ethernet)
        RX packets 9612  bytes 13816406 (13.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6807  bytes 486039 (474.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


系统层面:
# ps -ef | grep docker
root        810      1  0 13:47 ?        00:00:01 /usr/bin/docker -d
root       1574   1305  0 14:44 pts/1    00:00:00 docker run -i -t centos /bin/bash
root       1619   1560  0 14:44 pts/3    00:00:00 grep --color=auto docker

(2)查看容器:

docker ps [-a][-l]
    -a 列出所有创建的容器
    -l 列出创建的最新的容器
    不加参数,列出docker中正在运行的容器

[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                      PORTS               NAMES
51ba48937ee6        centos              "echo 'hello word'"   15 minutes ago      Exited (0) 15 minutes ago                       lucid_leavitt
370204a25400        centos              "/bin/bash"           17 minutes ago      Up 6 minutes                                    pedantic_minsky

docker inspect 容器的名字或ID
#查看容器相关详细信息
[user_00@server ~]$ docker inspect pedantic_minsky
...

(3)自定义容器名等:

docker run --name=自定义名 -i -t IMAGE /bin/bash
eg:
# docker run --name=docker1 -i -t centos /bin/bash
第二次执行上面的命令的时候将报错!除非将旧的容器删除。

重新启动停止的容器和停止运行的容器

docker start [-i] 容器名
    -i 以交互的方式重新启动容器

docker stop 容器名

删除停止的容器:
    docker rm 容器名
    docker rm -f 容器名(强制删除)

容器的状态是停止的:
[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                     PORTS               NAMES
51ba48937ee6        centos              "echo 'hello word'"   7 minutes ago       Exited (0) 7 minutes ago                       lucid_leavitt
370204a25400        centos              "/bin/bash"           10 minutes ago      Exited (0) 8 minutes ago                       pedantic_minsky
启动容器:
[user_00@server ~]$ docker start 370204a25400
370204a25400
[user_00@server ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
370204a25400        centos              "/bin/bash"         10 minutes ago      Up 5 seconds                            pedantic_minsky
再次进入容器:
[user_00@server ~]$ docker exec -it 370204a25400 /bin/bash
[root@370204a25400 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 10:26 pts/0    00:00:00 /bin/bash
root        16     0  1 10:27 pts/1    00:00:00 /bin/bash
root        32    16  0 10:27 pts/1    00:00:00 ps -ef
可以看到,启动容器有一个/bin/bash进程、这次使用exec进入容器,又有一个/bin/bash进程


附:
docker --help
Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from a container's filesystem to the host path
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Stream the contents of a container as a tar archive
    history   Show the history of an image
    images    List images
    import    Create a new filesystem image from the contents of a tarball
    info      Display system-wide information
    inspect   Return low-level information on a container or image
    kill      Kill a running container
    load      Load an image from a tar archive
    login     Register or log in to a Docker registry server
    logout    Log out from a Docker registry server
    logs      Fetch the logs of a container
    port      Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
    pause     Pause all processes within a container
    ps        List containers
    pull      Pull an image or a repository from a Docker registry server
    push      Push an image or a repository to a Docker registry server
    rename    Rename an existing container
    restart   Restart a running container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save an image to a tar archive
    search    Search for an image on the Docker Hub
    start     Start a stopped container
    stats     Display a stream of a containers' resource usage statistics
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Lookup the running processes of a container
    unpause   Unpause a paused container
    version   Show the Docker version information
    wait      Block until a container stops, then print its exit code

(4)镜像简单管理:

#docker search centos   #查找镜像
可能报错:
error response from daemon:Get https://index.docker.io/v1/search?q=java:dial tcp 52.6.188.70:443: connection refused
重新执行一下即可

去官网下载:
https://www.docker.com ---->docker hub---->

[user_00@server ~]$ docker search --limit 5 mysql
NAME                         DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                        MySQL is a widely used, open-source relation…   7352                [OK]
mysql/mysql-server           Optimized MySQL Server Docker images. Create…   544                                     [OK]
zabbix/zabbix-server-mysql   Zabbix Server with MySQL database support       142                                     [OK]
mysql/mysql-cluster          Experimental MySQL Cluster Docker images. Cr…   35
circleci/mysql               MySQL is a widely used, open-source relation…   7


#docker pull mysql   #下载镜像
[root@docker-01 sysconfig]# docker pull mysql/mysql-server
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/mysql/mysql-server/manifests/latest: Get https://auth.docker.io/token?scope=repository%3Amysql%2Fmysql-server%3Apull&service=registry.docker.io: net/http: TLS handshake timeout
第一次失败
[root@docker-01 sysconfig]# docker pull mysql/mysql-server
Using default tag: latest
latest: Pulling from mysql/mysql-server
10ec637c060c: Pull complete
ad44dea47d8f: Pull complete
f2a38e8c03f9: Pull complete
b457c4515263: Pull complete
Digest: sha256:45fefdaadb8c4f8c4743998eb45e9fec2a935070b219c5339e48ee08207c4ee6
Status: Downloaded newer image for mysql/mysql-server:latest
You have new mail in /var/spool/mail/root
[root@docker-01 sysconfig]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               latest              c73a085dc378        4 days ago          127 MB
mysql/mysql-server   latest              6e908c2b7575        2 weeks ago         369.1 MB

#docker images  #显示本地的可用镜像

(5)守护式容器:

守护式容器: 能够长期运行。没有交互式会话,适合运行应用程序和服务

docker run -i -t IMAGE /bin/bash
exit退出容器的交互式shell

再次进入已经退出了的容器中:
docker attach

docker run -d 镜像名  [command] [args……]
    后台服务的方式启动容器,但是在容器执行完之后依然会停止

docker exec web cat /etc/nginx/nginx.conf
在web容器中执行cat /etc/nginx/nginx.conf,适合故障排查、一次性命令执行

[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                    PORTS               NAMES
51ba48937ee6        centos              "echo 'hello word'"   15 hours ago        Exited (0) 15 hours ago                       lucid_leavitt
370204a25400        centos              "/bin/bash"           15 hours ago        Up 15 hours                                   pedantic_minsky
[user_00@server ~]$ docker run -d --name mycontainer1 centos /bin/bash
01dd6dfe545bda0dc104bbe92d69559387ff4beed85d04e4562f92f73b8dda23
[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                     PORTS               NAMES
01dd6dfe545b        centos              "/bin/bash"           5 seconds ago       Exited (0) 4 seconds ago                       mycontainer1
51ba48937ee6        centos              "echo 'hello word'"   16 hours ago        Exited (0) 16 hours ago                        lucid_leavitt
370204a25400        centos              "/bin/bash"           16 hours ago        Up 16 hours                                    pedantic_minsky
[user_00@server ~]$ docker start mycontainer1
mycontainer1
[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                     PORTS               NAMES
01dd6dfe545b        centos              "/bin/bash"           25 seconds ago      Exited (0) 2 seconds ago                       mycontainer1
51ba48937ee6        centos              "echo 'hello word'"   16 hours ago        Exited (0) 16 hours ago                        lucid_leavitt
370204a25400        centos              "/bin/bash"           16 hours ago        Up 16 hours                                    pedantic_minsky
[user_00@server ~]$ docker rm mycontainer1
mycontainer1
[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                    PORTS               NAMES
51ba48937ee6        centos              "echo 'hello word'"   16 hours ago        Exited (0) 16 hours ago                       lucid_leavitt
370204a25400        centos              "/bin/bash"           16 hours ago        Up 16 hours                                   pedantic_minsky


查看容器的日志:
docker logs [-f] [-t] [] [--tail]
   -f  --follows=true|false 默认为false
   -t  --timestamps=true|false 默认为false
   --tail="all"
centos默认日志是放在/var/log/message文件内,所以也可以使用tailf /var/log/message |grep docker

[user_00@server ~]$ docker run -d --name test -it centos /bin/bash
900376d14efa3b59b7049885ec1aeebee623b669f5f04cba8dd8e8246e6c9ac2
[user_00@server ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                    PORTS               NAMES
900376d14efa        centos              "/bin/bash"           4 seconds ago       Up 3 seconds                                  test
51ba48937ee6        centos              "echo 'hello word'"   16 hours ago        Exited (0) 16 hours ago                       lucid_leavitt
370204a25400        centos              "/bin/bash"           16 hours ago        Up 16 hours                                   pedantic_minsky
[user_00@server ~]$ docker logs -f container1


查看容器内的进程:
docker top 容器名
[user_00@server ~]$ docker top test
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                8740                8721                0                   10:01               pts/0               00:00:00            /bin/bash

如何在运行中的容器内启动新进程:
docker exec [-d] [-i] [-t] 容器名 [command] [arg……]
root@ubuntu:/var/lib/docker# docker exec -i -t container1 /bin/bash
root@99c2f20211c9:/#

建议使用docker exec,而不建议使用docker attach(退出时,docker就停止运行了)


停止守护式容器
docker stop 容器名    发送信号后等待容器的停止
docker kill 容器名    直接杀死容器

使用man命令来查看各种命令的详细介绍:
man docker run
man docker logs
man docker top
man docker ecex等等
注意:
docker exec -it musing_newton /bin/bash   #一定要有t参数,否则没有终端

(6)容器中部署静态网站:

注意:
默认centos的镜像,有网络,只要宿主机能ping通外网,容器内也能ping通
而ubuntu镜像则不然,所以下面用centos镜像

设置容器的端口映射
run [-P] [-p]
-P 将为容器暴露的所有端口进行映射:docker run -P -i -t ubuntu /bin/bash
-p 指定映射容器的端口:docker run -p 80 -i -t ubuntu /bin/bash

containerport:
    docker run -p 80 -i -t centos /bin/bash    #宿主机的端口将是随机映射
hostport:containerport
    docker run -p 8080:80 -i -t centos /bin/bash  #一一对应的映射,将容器的80端口映射到宿主机的8080端口
ip::containerport
    docker run -p 0.0.0.0:80 -i -t centos /bin/bash
ip:hostport:containerport
    docker run -p 0.0.0.0:8080:80 -i -t centos /bin/bash


nginx部署流程:
创建映射80端口的交互式容器
安装nginx
安装文本编辑器vim
创建静态页面
修改nginx配置文件
运行nginx验证网站访问:

root@ubuntu:/var/lib/docker# docker run -p 80 --name=web -i -t centos /bin/bash
[root@7775914d1747 /]yum install epel-release -y
[root@7775914d1747 /]yum install nginx
[root@7775914d1747 /]yum install vim
[root@7775914d1747 /]echo 'hello world!' > /usr/share/nginx/html/index.html
[root@7775914d1747 /]nginx


docker port web查看wb容器端口映射情况
[root@server docker-data]# docker port web
80/tcp -> 0.0.0.0:80
[root@server docker-data]# curl http://127.0.0.1

或者使用容器的ip地址来访问
docker inspect web
  "IPAddress": "192.168.3.2",
[root@server docker-data]# curl http://192.168.3.2


[user_00@server ~]$ docker start web
web
[user_00@server ~]$ docker top web
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                13033               13015               1                   10:41               pts/0               00:00:00            /bin/bash
[user_00@server ~]$ curl http://127.0.0.1
curl: (56) Recv failure: Connection reset by peer
[user_00@server ~]$ docker exec web nginx
[user_00@server ~]$ docker top web
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                13033               13015               0                   10:41               pts/0               00:00:00            /bin/bash
root                13143               13015               0                   10:42               ?                   00:00:00            nginx: master process nginx
systemd+            13144               13143               0                   10:42               ?                   00:00:00            nginx: worker process
systemd+            13145               13143               0                   10:42               ?                   00:00:00            nginx: worker process
systemd+            13147               13143               0                   10:42               ?                   00:00:00            nginx: worker process
systemd+            13148               13143               0                   10:42               ?                   00:00:00            nginx: worker process
早起版本,再次访问会失败,发现容器的ip地址已经发生了改变,映射的端口也不一样了。

(1)docker重启之后,端口映射和ip地址都发生了改变
(2)docker exec来进入到到该容器中,或者attach重新连接容器的会话(attach也可以,但是它是将容器的输出拿过来了,退出时,原运行的docker就停止运行了)
如果宿主机是ubuntu的话,docker exec和docker attach是没有多大的区别,使用Crtl+P Crtl+Q 退出容器的交互式shell
(3)Docker时有自动化的需求,你可以将containerID输出到指定的文件中(PIDfile): --cidfile="";
eg:docker run --cidfile=/etc/docker/pid --name=test -p 8082:82 -it centos /bin/bash
(4)Docker的容器是没有特权的,例如不能在容器中再启动一个容器。这是因为默认情况下容器是不能访问任何其它设备的。但是通过"privileged",容器就拥有了访问任何其它设备的权限。

2、总结:

(1)进入容器不让容器退出方法扩展:

yum install util-linux,包含了nscnter工具

nsenter可以访问另一个进程的名字空间。nsenter需要有root权限。

# yum install -y util-linux   #安装包中有需要用到的nsenter
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
2fba15ad9278        centos              "/bin/bash"         12 minutes ago      Up 12 minutes                           musing_newton
# docker inspect --format "{{.State.Pid}}" 2fba15ad9278
16978
# nsenter -t 16978 -u -i -n -p  #通过这个PID连接到容器

# cat in.sh   #编写成脚本快速进入容器空间
#!/bin/sh
PID=$(docker inspect --format "{{.State.Pid}}" $1)
nsenter -t $PID -u -i -n -p

# ./in.sh 2fba15ad9278

★强烈建议不要这样操作,会将宿主机的结果和容器内的结果一起返回!

(2)导入导出Docker镜像

如果要导出镜像到本地文件,可以使用docker save命令。

[root@docker ~]# docker save centos > /opt/centos.tar.gz  #导出docker镜像至本地
[root@docker ~]# ll /opt/
-rw-r--r--.1 root root 204205056 12月 30 09:53 centos.tar.gz
导入Docker镜像

可以使用docker load从本地文件中导入到本地docker镜像库

[root@docker ~]# docker load < /opt/centos.tar.gz   #导入本地镜像到docker镜像库
[root@docker~]# docker images  #查看镜像导入情况
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos     latest              60e65a8e4030        5 days ago          196.6 MB

(3)映射

随机映射:
    docker run -P
指定映射:
    -p hostPort:containerPort
    -p ip:hostPort:containerPort
    -p ip::containerPort
    -p hostPort:containerPort:udp

(4)优雅的退出容器,而容器不停止

ctrl+p+q
在使用docker exec -it musing_newton /bin/bash 时,退出的只是此次执行的/bin/bash,第一次启动的docker并没有关闭掉!

(5)可以对cpu和内存的限制

docker run —help |grep -E ‘mem|cpu’

三、镜像管理

1、基础操作:

查看和删除镜像
    列出镜像
	docker images [optsions] [repository]
        -a,--all=false  显示所有
        -f,--filter=[]  过滤条件
        --no-trunc=false 不使用截断的方式显示数据,默认会截断唯一id
        -q,--quiet=false 只显示镜像的唯一id

[user_00@server ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              75835a67d134        5 weeks ago         200MB


tag的作用主要有两点:一是为镜像起一个容易理解的名字,二是可以通过docker tag来重新指定镜像的仓库,这样在push时自动提交到仓库。
[root@server /]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
jmf/centos7                   sshd                8a1cddac268e        24 minutes ago      358MB
docker.io/centos              latest              328edcd84f1b        2 weeks ago         193MB

REPOSITORY :包含仓库信息,如docker.io/redis ,表示docker.io仓库的redis名称镜像。
TAG:同一个名称的镜像可能有多个版本,默认为latest版本(最新版),TAG就标明了版本
IMAGE ID :镜像唯一ID

因此可以通过两个方法确定某个唯一的镜像:
1、REPOSITORY:TAG :如docker.io/centos:6.6
2、IMAGE ID : 如12c9d795d85a
★注意:如果直接使用“REPOSITORY”,则默认“TAG”为“latest”,如镜像redis就标识“redis:latest”

镜像的名称“REPOSITORY:TAG ”可以用下面的命令重命名:
[user_00@server ~]$ docker tag --help
Usage:	docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
以前旧的版本支持:将同一IMAGE_ID的所有tag,合并为一个新的

# docker tag Registry/Repos:Tag New_Registry/New_Repos:New_Tag
[user_00@server ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              f991c20cb508        4 days ago          486MB
centos              latest              75835a67d134        5 weeks ago         200MB
[user_00@server ~]$ docker tag f991c20cb508 jiangmf/mysql
[user_00@server ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jiangmf/mysql       latest              f991c20cb508        4 days ago          486MB
mysql               latest              f991c20cb508        4 days ago          486MB
centos              latest              75835a67d134        5 weeks ago         200MB
注意查看:新的镜像id和旧的是一样的。



如果已经为镜像tag指定了仓库信息,这可以使用下面命令提交镜像到仓库中:
# docker push 192.168.1.200:5000/centos:6.6

★
提交镜像到私有docker仓库前,需要修改镜像的tag:
docker tag 66f3b07798c2 node01:5000/centos:sshd
然后我们就可以将这个镜像push到私有仓库了:
docker push node01:5000/centos:sshd

查看私有仓库所有镜像:
# curl -X GET http://node01:5000/v1/search
根据镜像名查看:
# curl -X GET http://node01:5000/v1/search?q=nginx
获取本地私有docker仓库中的镜像:
# docker pull node01:5000/centos:sshd

私有仓库的镜像删除、仓库的备份、还原等等,官方的registry不完善!建议用企业的harbor!


查看镜像的详细信息:
docker inspect [options] container|image [container|image……]
    使用仓库名+tag名的完整名查看镜像
    root@ubuntu:/var/lib/docker/aufs# docker inspect ubuntu:latest

删除镜像:
docker rmi [options] image [image]
    -f,--force=false
    --no-prune=false  do not delete untagged parents
    可以接仓库名+tag的完整名,也可以是image id的简短形式或完整形式
    docker rmi ubuntu:12.04 ubuntu:latest
    docker rmi $(docker images -q  ubuntu)这样会删除ubuntu仓库中所有的镜像


获取和推送docker镜像

查找镜像
https://registry.hub.docker.com
或者
docker search [options] term
  --automated=false  只显示自动构建的docker镜像
  --no-trunc=false   不以截断的方式显示
  -s,--stars=0   限定显示结果最低星级
  最多返回25个镜像

拉取镜像
docker pull [options] name[:TAG]
  -a,--all-tags=false 下载匹配到的所有标记的镜像下载到本地

使用--registry-mirror选项,加速
修改/etc/default/docker
添加:DOCKER_OPTS= "--registry-mirrors=http://MIRROR-ADDR"

DAOCLOUD,需要注册
docker加速器,会生成一个我们的仓库地址
重新启动docker的守护进程
service docker restart


推送镜像
docker push NAME[:TAG]
docker push ubunbu/nginx  #真正推送镜像
需要输入账号名和密码,邮箱
不会将整个镜像头提交上去,只会提交修改的部分

这样可以再docker hub官网找到这个镜像,也可以将它转为私有,别人将无法访问

##2、单机版私有仓库测试:
部分参考:https://www.linuxidc.com/Linux/2018-03/151308.htm

# 下载镜像
docker pull registry

# 查看镜像是否已经下载
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              5182e96772bf        13 days ago         200MB
registry            latest              b2b03e9146e1        6 weeks ago         33.3MB

# 运行registry 容器
docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest
参数说明:
-itd:在容器中打开一个伪终端进行交互操作,并在后台运行;
-v:把宿主机的/data/registry目录绑定 到 容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
-p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了;
--restart=always:这是重启的策略,假如这个容器异常退出会自动重启容器;
--name registry:创建容器命名为registry,你可以随便命名;
registry:latest:这个是刚才pull下来的镜像;


# registry测试镜像仓库中所有的镜像:
# curl http://127.0.0.1:5000/v2/_catalog
{"repositories":[]}


注意:
registry-mirrors参数可以配置加速器
daemon.json中语法比较严格:最后一条后面不能有“,”,列表最后不能有“,”

# 在docker服务所在机器上操作:
# 修改docker服务配置/etc/docker/daemon.json并重启docker服务
# vim /etc/docker/daemon.json
{
   "insecure-registries": ["10.40.2.230:5000"]
}
# systemctl restart docker.service
# docker pull centos
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              5182e96772bf        13 days ago         200MB
ubuntu              latest              735f80812f90        3 weeks ago         83.5MB
registry            latest              b2b03e9146e1        6 weeks ago         33.3MB

# 打标签
[root@server data]# docker tag jenkins:latest 10.40.2.230:5000/jenkins:3.8.6
[root@server data]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mysql                      latest              f991c20cb508        4 days ago          486MB
centos                     latest              75835a67d134        5 weeks ago         200MB
registry                   latest              2e2f252f3c88        2 months ago        33.3MB
10.40.2.230:5000/jenkins   3.8.6               cd14cecfdb3a        4 months ago        696MB
jenkins                    latest              cd14cecfdb3a        4 months ago        696MB
[root@server data]# docker push 10.40.2.230:5000/jenkins
......

# 查看registry中所有镜像
# curl http://10.40.2.229:5000/v2/_catalog
{"repositories":["centos"]}
# 查看registry中centos镜像所有的标签
# curl http://10.40.2.229:5000/v2/centos/tags/list
{"name":"centos","tags":["v1"]}

[root@server data]# docker rmi -f cd14cecfdb3a
......
[root@server data]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              f991c20cb508        4 days ago          486MB
centos              latest              75835a67d134        5 weeks ago         200MB
registry            latest              2e2f252f3c88        2 months ago        33.3MB
[root@server data]# docker pull 10.40.2.230:5000/jenkins:3.8.6
......
[root@server data]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mysql                      latest              f991c20cb508        4 days ago          486MB
centos                     latest              75835a67d134        5 weeks ago         200MB
registry                   latest              2e2f252f3c88        2 months ago        33.3MB
10.40.2.230:5000/jenkins   3.8.6               cd14cecfdb3a        4 months ago        696MB

3、镜像制作

(1)将容器变成镜像:

docker commit <container> [repo:tag]
-a,--author=""  指定制作镜像的作者
-m,--message="" 记录构建镜像的信息
-p,--pause=true docker commit命令会将正在执行的容器暂停,加上-p参数即不暂停运行的容器


优缺点:
方便快速;
不规范、无法自动化


eg:
创建一个centos7.3的sshd服务的镜像
pull官方centos7.3基础镜像略
docker run -d -i --name=hehe centos /bin/bash
docker exec -it hehe /bin/bash
yum install net-tools -y
yum install openssh-server -y
/usr/sbin/sshd  #这里要在前台启动,且用全路径,但是报错,所以有下面的语句:
ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t ecdsa  -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -t ed25519 -b 2048 -f /etc/ssh/ssh_host_ed25519_key
/usr/sbin/sshd  #此时ok
[root@2fba15ad9278 /]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      79/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      79/sshd
[root@2fba15ad9278 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Aug20 pts/0    00:00:00 /bin/bash
root        79     0  0 00:05 ?        00:00:00 /usr/sbin/sshd
root       106     0  0 00:10 pts/1    00:00:00 /bin/bash
root       123   106  0 00:16 pts/1    00:00:00 ps -ef
退出终端

# docker commit -p -a jmf -m "sshd servier" musing_newton jmf/centos7:sshd
sha256:8a1cddac268ea92b8c0295ab7ba7b33d62b3853c25981bb2afad7844c7bf47d2docker commit -p -a jmf -m "sshd servier" hehe jmf/centos7:sshd

[root@server01 docker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jmf/centos7         sshd                8a1cddac268e        18 seconds ago      358MB
centos              latest              328edcd84f1b        2 weeks ago         193MB
# docker run -d -i --name=hello jmf/centos7:sshd /bin/bash
79aac5e754a88942023cf68982a0fb300adcb1cfc0f4466da278f45bdf0bdb36
# docker run -d -i --name=hello jmf/centos7:sshd /bin/bash
79aac5e754a88942023cf68982a0fb300adcb1cfc0f4466da278f45bdf0bdb36
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
79aac5e754a8        jmf/centos7:sshd    "/bin/bash"         19 seconds ago      Up 18 seconds                           hello
不过用docker exec进去后发现sshd并没有启动,要手动去启动,当有多个服务的时候建议用supervisord控制!

# docker rm hello
# docker run -d -i --name=hello jmf/centos7:sshd /usr/sbin/sshd -D #OK


收录一个包含sshd服务的镜像Dockerfile文件:
# cat Dockerfile
FROM centos:7.3
MAINTAINER jmf
ADD selinux/config /etc/selinux/config
RUN yum -y install openssh openssh-server
RUN sed -i 's/\(session.*\)required\(.*pam_loginuid.so\)/\1optional\2/' /etc/pam.d/sshd
RUN /usr/sbin/sshd -D
RUN echo "root:password" | chpasswd
EXPOSE 22
CMD /usr/sbin/sshd -D

(2)buildfile语法:

指令格式:
#comment
INSTRUCTION arguments


#first dockerfile
[root@server data]# mkdir firt-dockerfile
[root@server data]# vim firt-dockerfile/dockerfile
FROM centos:latest
MAINTAINER test "[email protected]"
RUN yum install epel-release -y
RUN yum install nginx -y
RUN echo 'hello world!' > /usr/share/nginx/html/index.html
RUN sed -i '/user nginx;/i\daemon off;' /etc/nginx/nginx.conf
#RUN nginx
EXPOSE 80


注意:
不要直接在dockerfile中跑前台程序,否则images永远都无法制作成功。就像上面的已经将nginx放到前台执行,后面接一行:RUN nginx;

[root@server data]# docker build firt-dockerfile -t 10.40.2.230:5000/nginx:1.8.6
......
[root@server data]# docker run --name web -itd 10.40.2.230:5000/nginx:1.8.6 nginx
426ed490001fbb669b2a6161bbce6d1061ba28594fdee3307cb339e23feef1fa
[root@server data]# docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                    NAMES
426ed490001f        10.40.2.230:5000/nginx:1.8.6   "nginx"                  4 seconds ago       Up 3 seconds        80/tcp                   web
8ee945464e0d        registry:latest                "/entrypoint.sh /etc…"   25 hours ago        Up 24 hours         0.0.0.0:5000->5000/tcp   registry
[root@server data]# curl http://192.168.3.3
hello world!


#second dockerfile
FROM centos:latest
MAINTAINER test "[email protected]"
RUN yum install epel-release -y
RUN yum install nginx -y
RUN echo 'hello world!' > /usr/share/nginx/html/index.html
RUN sed -i '/user nginx;/i\daemon off;' /etc/nginx/nginx.conf
EXPOSE 80
ENTRYPOINT ["nginx"]
[root@server data]# docker build second-dockerfile -t 10.40.2.230:5000/nginx:1.8.7
[root@server data]# docker run -itd --name nginx-2 10.40.2.230:5000/nginx:1.8.7
65fada8dfc88720ebf5bab0d9f26e92c893658e6d062cb77d65a5e622bb4ef6a
[root@server data]# docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                    NAMES
65fada8dfc88        10.40.2.230:5000/nginx:1.8.7   "nginx"                  4 seconds ago       Up 3 seconds        80/tcp                   nginx-2
426ed490001f        10.40.2.230:5000/nginx:1.8.6   "nginx"                  3 hours ago         Up 3 hours          80/tcp                   web
8ee945464e0d        registry:latest                "/entrypoint.sh /etc…"   28 hours ago        Up 28 hours         0.0.0.0:5000->5000/tcp   registry
[root@server data]# curl http://192.168.3.4
hello world!
注意:这里将启动容器是放在前台执行的命令,放在ENTRYPOINT即可,这样启动容器的时候都不需要额外指定需要执行的命令。


注意:下面的指令是很早之前的,请参考官方文档
FROM
    FROM<image>
    RROM<image>:<tag>
    必须是一个已经存在的镜像,基础镜像
MAINTAINER
    MAINTAINER<name>
    指定镜像的作者信息,包含镜像的所有者和联系信息
RUN
    指定当前镜像中运行的命令
    RUN <command>                        (shell模式)     使用/bin/sh -c command
    RUN["executable""param1","param2"]  (exec模式)       可以指定其他的shell
EXPOSE
    EXPOSE<port>[<port>……]
    指定运行该镜像的容器使用的端口,但并不会自动打开端口,需要运行时指定,如
    docker run -p 80 -d test nginx -g "daemon off"
CMD
    RUN["executable""param1","param2"]  (exec模式)
    CMD command param1 param2 (shell模式)
    是在容器运行时指定的并运行的,使用docker run启动容器时,如果指定了容器运行时的命令,cmd中的命令会被覆盖(不会执行)
    CMD ["param1","param"] (作为ENTRYPOINT指令的默认参数)
ENTERYPOINT
    ENTERYPOINT ["executable""param1","param2"]  (exec模式)
    ENTERYPOINT  command param1 param2 (shell模式)
    不会被docker run中指定的命令覆盖
    如果要覆盖,那么需要使用docker run --entrypoint 覆盖

ADD
COPY
    两个命令都是将文件复制到镜像中
    ADD/COPY<src><dest>
    ADD/COPY [""""](使用与文件路径中有空格的情况)
    来源地址:本地,远程url(不推荐,使用curl或wget),本地地址使用构建地址的相对地址
    目标地址:镜像中的绝对路径
    ADD包含类似tar的解压功能

FROM ubuntu:14.04
MAINTAINER test "[email protected]"
RUN apt-get update
RUN apt-get install -y nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]


VOLUME
    用来向基于镜像创建的容器添加卷,一个卷可以存在一个或多个容器的特定目录,提供共享数据或数据持久化功能
    VOLUME ["/data"]
WORKDIR
    WORKDIR  /path/to/workdir
    用来指定基于镜像创建的容器的工作目录,使用绝对路径
ENV
    ENV <key><value>……
    与WORKDIR类似,指定环境变量
USER
    USER daemon
    指定以某用户去执行,可以设置uid,gid,用户组等来配置,甚至组合
ONBUILD
    ONBUILD [INSTRUCTION]
    为镜像添加触发器
    当一个镜像被其他镜像作为基础镜像时执行(也就是当用这个镜像启动容器时不会执行,当基于此创建新镜像,当用新镜像启动容器时会生效)
    会在厚健过程中插入指令

dockerfile构建镜像过程:

从基础镜像运行一个容器
执行一条指令,对容器做出修改
执行类似docker commit的操作,提交一个新的镜像层
再给予刚提交的镜像运行一个新容器
执行dockerfile中的下一条指令,直至所有指令执行完毕

每一步会删除创建的容器,但是不会删除每步(中间层)创建的镜像,我们可以使用docker run来运行基于中间层镜像的容器,从而查看每一步的构建状态
使用中间层镜像进行调试,查找错误

构建缓存:
    再次使用dockerfile构建镜像时,如果步骤相同,会使用缓存,不会每步都重新构建镜像
不使用缓存:
    docker build --no-cache

或者在dockerfile中指定
ENV REFRESH_DATE 2016-03-28来标识缓存刷新时间
在此条命令后的命令都不会使用缓存

查看镜像构建的过程:
docker history [image]

(3)例子

复杂案例1:源码安装nginx

#base images
FROM centos

#MAINTAINER
MAINTAINER JMF

#ADD
ADD pcre-8.37.tar.gz /usr/local/src
ADD nginx-1.9.3.tar.gz /usr/local/src

#RUN
RUN yum install -y wget gcc gcc-c++ make openssl-devel
RUN useradd -s /sbin/nologin -M www

#WORKDIR
WORKDIR /usr/local/src
RUN tar xf pcre-8.37.tar.gz
RUN tar xf nginx-1.9.3.tar.gz

##WORKDIR
WORKDIR /usr/local/src/nginx-1.9.3
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.37 && make && make install
RUN echo "daemon off;" >>/usr/local/nginx/conf/nginx.conf   #docker中的程序不能以服务启动

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

CMD ["nginx"]

docker build -t centos/centos-nginx .

复杂案例2:制作ubuntu+java+tomcat+ssh server镜像

FROM ubuntu
MAINTAINER yongboy "[email protected]"
# 更新源,安装ssh server
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y openssh-server
RUN mkdir -p /var/run/sshd
# 设置root ssh远程登录密码为123456
RUN echo "root:123456" | chpasswd
# 添加orache java7源,一次性安装vim, wget, curl, java7, tomcat7等必备软件
RUN apt-get install python-software-properties
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN apt-get install -y vim wget curl oracle-java7-installer tomcat7
# 设置JAVA_HOME环境变量
RUN update-alternatives --display java
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle">> /etc/environment
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle">> /etc/default/tomcat7
# 容器需要开放SSH 22端口
EXPOSE 22
# 容器需要开放Tomcat 8080端口
EXPOSE 8080
# 设置Tomcat7初始化运行, SSH终端服务器作为后台运行
ENTRYPOINT service tomcat7 start && /usr/sbin/sshd -D   #启动指令

最后一行改为:ENTRYPOINT service tomcat7 start && /usr/sbin/sshd -D &&tailf 日志文件


当有多个服务要运行,且,有一些服务要放在后台运行,此时可以在容器中借助supervisor
让supervisor放在前端执行:

supervisord.conf
[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"

(4)镜像制作中的常见问题:

ssh server是否应该包含到镜像里?

用ssh管理容器并不理想
如前面的例子,账号和密码是写死在镜像里面的,如果修改密码,需要重新编译打包。
建议不用。

一个容器究竟运行几个程序?

一个程序比较好,因为docker只管你的前台程序是否正常

程序参数和配置文件的问题?

如果放在镜像中,很麻烦
a、设置为环境变量,用参数传进去,不适合参数比较多和参数比较敏感的情况
b、集中,使用配置管理中心(disconf…),见docker友好程序架构图

程序日志输出的问题?

通过volume
或者syslog方式

docker友好程序架构图:

建议:

在一个Dockerfile中每个命令都会在原来的基础上生成一层镜像。你可以很快的在三十多层的时候就结束了,这未必是一个问题,但也可以通过组合RUN命令,并使用一行EXPOSE命令列出你所有的开放端口,这样可以有效减少镜像的层数。
通过将RUN命令分组,可以在容器间分享更多的层。当然如果你有一组命令可以多个容器通用,那么你应该创建一个独立的基础镜像,它包含你建立的所有镜像。
对于每一层来说你都可以跨多个镜像分享,这样可以节省大量的磁盘空间。

你可能感兴趣的:(docker)