Docker二进制安装及私有仓库的搭建

 

 

 

 

目录

1.下载docker安装包... 2

2.上传到服务器中安装... 2

3.解压安装包... 3

4.移动文件... 3

5.切换到root用户... 3

6.查看docker  --version. 4

7.Docker  info出现... 4

8.查看docker进程... 5

9.配置docker的工作路径... 6

10.用env查看环境变量... 6

11.配置systemctl下管理docker及更改镜像和容器的默认位置... 7

11.1 docker.server的配置... 7

11.2 docker.socket的配置... 8

11.3 配置docker文件... 9

11.4创建docker用户组... 10

11.5加入用户组... 11

11.6更改容器和镜像的默认存储位置/var/lib/docker 11

12 docker的daemon.json的配置参数... 11

13或更改docker的镜像和容器的默认存储位置... 13

13.1方法一 配置文件... 13

13.2方法二、软链接... 15

14 docker+harbor构建私有仓库... 16

1.安装docker-compose. 17

2 安装harbor-offline-installer-v1.5.1.tgz. 18

3 上传镜像到私有仓库... 22

15 docker -v挂载... 27

16 网络路由... 28

17查看SELinux状态... 28

18 harbor部署 SSL 认证... 28

1) 概念理解... 28

2) 创建根证书... 29

3) 创建服务器端证书... 30

4) 修改 Harbor 的配置文件 hardor.cfg. 32

5) 设置 docker 证书... 32

6)重启docker和 重启动Harbor 33

19 docker容器设置时区时间,中文乱码... 34

20.Dockerfile的简介... 35

20.1设置时区时间,中文乱码... 35

20.2 CMD.. 36

20.3 ENTRYPOINT. 37

 

 

1.下载docker安装包

即docker-17.05.0-ce.tgz

下载地址 https://github.com/moby/moby/releases

17.05.0下载 :

https://get.docker.com/builds/Linux/x86_64/ docker-17.05.0-ce.tgz

curl https://get.daocloud.io/docker/builds/Linux/x86_64/docker-17.05.0-ce.tgz

 

 

2.上传到服务器中安装

 

 

3.解压安装包

tar -zxvf docker-17.05.0-ce.tgz

 

4.移动文件 

即将解压的目录下的所有文件移动到/usr/bin/或/usr/local/bin/下面

mv docker/ * /usr/bin/

 

5.切换到root用户

 

在执行操作mv docker/ * /usr/local/bin/(自定义但必须是bin下)

 

6.查看docker  --version

 

7.Docker  info出现

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

 

解决:

进入bin目录

cd /usr/local/bin (对于docker的所有操作都要在该目录下)

启动docker的守护进行:

./dockerd &

 

现在在docker info

 

 

在解决没有docker组及进程问题

 

 

8.查看docker进程

 

现在docker安装成功,命令可用

 

9.配置docker的工作路径(可选)

(可以在任何目录下对docker进行操作)

 

vi /etc/profile

 

在文件最后添加:

 

export DOCKER_HOME=/usr/local/bin(docker安装目录)

export PATH=.:$DOCKER_HOME:$PATH

执行:

source /etc/profile

 

10.用env查看环境变量

 

docker二进制安装就成功

 

11.配置systemctl下管理docker及更改镜像和容器的默认位置

11.1 配置docker文件

 

在/etc/default/下创建docker文件touch /etc/default/docker

编辑文件                           

[yan@bogon ~]$ vim /etc/default/docker

 

DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com --insecure-registry=192.168.19.128:5000 --graph=/data/gdeop/docker --storage-driver=overlay "

DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:5555 --graph=/data/gdeop/docker --storage-driver=overlay"

 

 

11.2 docker.server的配置

 

创建docker.server文件,编辑

[yan@bogon ~]$ vim /etc/systemd/system/docker.service

 

[Unit]

Description=Docker Application Container Engine

Documentation=https://docs.docker.com

After=network-online.target firewalld.service

Wants=network-online.target

Requires=docker.socket

 

[Service]

Type=notify

ExecStart=/usr/local/bin/docker daemon -H fd:// $DOCKER_OPTS

EnvironmentFile=-/etc/default/docker

ExecReload=/bin/kill -s HUP $MAINPID

 

LimitNOFILE=infinity

LimitNPROC=infinity

LimitCORE=infinity

 

TimeoutStartSec=0

 

Delegate=yes

 

KillMode=process

 

Restart=on-failure

#StartLimitBurst=20

#StartLimitInterval=60s

 

[Install]

WantedBy=multi-user.target

 

11.3 docker.socket的配置

 

创建docker.socket文件,编辑

 [yan@bogon ~]$ vim /etc/systemd/system/docker.socket

 

[Unit]

Description=Docker Socket for the API

PartOf=docker.service

 

[Socket]

ListenStream=/var/run/docker.sock

SocketMode=0660

SocketUser=root

SocketGroup=docker

 

[Install]

WantedBy=sockets.target

 

11.4创建docker用户组

groupadd docker

11.5加入用户组

usermod -aG docker gdeop

注:gdeop是用户名

 

11.6更改容器和镜像的默认存储位置/var/lib/docker(11.1或)

11.6.1首先用systemctl stop docker

在用rsync -avz /var/lib/docker 命令

例如:rsync -avz /var/lib/docker  /data/gdeop/

 

 

在进行加载systemctl daemon-reload

 

12 docker的daemon.json的配置参数

注:docker1.13的版本以上有效,默认位置是/etc/docker/ 二进制安装docker中daemon.json是没有的,如果需要daemon.json需要自己创建daemon.json 即执行 touch /etc/docker/daemon.json 命令

 

{

 "api-cors-header":"",

 "authorization-plugins":[],

 "bip": "",

 "bridge":"",

 "cgroup-parent":"",

 "cluster-store":"",

 "cluster-store-opts":{},

 "cluster-advertise":"",

 "debug": true,                     #启用debug的模式,启用后,可以看到很多的启动信息。默认false

 "default-gateway":"",

 "default-gateway-v6":"",

 "default-runtime":"runc",

 "default-ulimits":{},

 "disable-legacy-registry":false,

 "dns": ["192.168.1.1"],             # 设定容器DNS的地址,在容器的 /etc/resolv.conf文件中可查看。

 "dns-opts": [],                     #  容器 /etc/resolv.conf 文件,其他设置

 "dns-search": [],               # 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的 主机时,DNS不仅搜索host,还会搜                            

                                  索host.example.com 。 注意:如果不设置, Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。

 

"exec-opts": [],

 "exec-root":"",

 "fixed-cidr":"",

 "fixed-cidr-v6":"",

 "graph":"/var/lib/docker",              #已废弃,使用data-root代替,这个主要看docker的版本

 "data-root":"/var/lib/docker",          #Docker运行时使用的根路径,根路径下的内容稍后介绍,默认/var/lib/docker 注:可以更改为自己的存储位置

 "group": "",                            #Unix套接字的属组,仅指/var/run/docker.sock

 "hosts": [],                           #设置容器hosts

 "icc": false,

 "insecure-registries": [“”],       #配置docker的私库地址

 "ip":"0.0.0.0",

 "iptables": false,

 "ipv6": false,

 "ip-forward": false,          #默认true, 启用 net.ipv4.ip_forward ,进入容器后使用 sysctl -a | grepnet.ipv4.ip_forward 查看

 

  "ip-masq":false,

 "labels":["nodeName=node-121"],   # docker主机的标签,很实用的功能,例如定义:–label nodeName=host-121

 

 "live-restore": true,

 "log-driver":"",

 "log-level":"",

 "log-opts": {},

 "max-concurrent-downloads":3,

 "max-concurrent-uploads":5,

 "mtu": 0,

 "oom-score-adjust":-500,

 "pidfile": "",                    #Docker守护进程的PID文件

 "raw-logs": false,

 "registry-mirrors":["xxxx"],      #镜像加速的地址,增加后在 docker info中可查看。

 "runtimes": {

 "runc": {

 "path": "runc"

 },

 "custom": {

 "path":"/usr/local/bin/my-runc-replacement",

 "runtimeArgs": [

 "--debug"

 ]

 }

 },

 "selinux-enabled": false, #默认 false,启用selinux支持

 

 "storage-driver":"",

 "storage-opts": [],

 "swarm-default-advertise-addr":"",

 "tls": true,                      #默认 false, 启动TLS认证开关

 "tlscacert": "",                  #默认 ~/.docker/ca.pem,通过CA认证过的的certificate文件路径

 "tlscert": "",                    #默认 ~/.docker/cert.pem ,TLS的certificate文件路径

 "tlskey": "",                     #默认~/.docker/key.pem,TLS的key文件路径

 "tlsverify": true,                #默认false,使用TLS并做后台进程与客户端通讯的验证

 "userland-proxy":false,

 "userns-remap":""

 }

原文:https://blog.csdn.net/u013948858/article/details/79974796

 

 

13或更改docker的镜像和容器的默认存储位置

注意:

13.1方法一 配置文件

  1. 停止docker服务

systemctl stop docker

默认位置/var/lib/docker,如果不改的话后期服务器的存储空间不够需要经常清理很麻烦,所以docker安装好后就更改,先用df -h查看哪个目录空间最大

 

2.在/data目录下面,/data目录大小有207G。 在 /data目录下面建了 /telecom/docker目录,执行的命令是:mkdir -p /data/telecom/docker

 3、迁移/var/lib/docker目录下面的文件到 /data/telecom/docker下面

 cp -R /var/lib/docker/* /data/telecom/docker/

 

注意:

如果文件内容很多的话,为了确保成功最好是一个文件一个文件的拷贝。如果在拷贝过程中报“设备上没有空间”的错误,就使用mv剪切。

4. 修改docker配置(供参考)

(/etc/systemd/system/docker.service.d/devicemapper.conf 路径不唯一根据配置文件位置而定),在文件末添加 --graph=/data/telecom/docker

执行rsync -avz /var/lib/docker /data/telecom/ 命令  同步

devicemapper.conf文件的内容如下:

 [Service]

ExecStart=

ExecStart=/usr/bin/dockerd --insecure-registry=私服地址 --graph=/data/telecom/docker

注意:如果/etc/systemd/system/docker.service.d/devicemapper.conf,这个路径找不到的话,就新建,新建之后加入内容,没有私服地址的话就可以去掉”--insecure-registry=私服地址”。

 

重载配置,重启docker

systemctl daemon-reload;

systemctl restart docker;

systemctl enable docker;

13.2方法二、软链接

默认情况下Docker的存放位置为:/var/lib/docker

可以通过下面命令查看具体位置:

sudo docker info | grep "Docker Root Dir"

解决这个问题,最直接的方法当然是挂载分区到这个目录,但是数据盘还有其他东西,这肯定不好管理,所以采用修改镜像和容器的存放路径的方式达到目的。

这个方法里将通过软连接来实现。

首先停掉Docker服务:

systemctl stop docker

 

systemctl restart docker或者service docker stop

然后移动整个/var/lib/docker目录到目的路径:

mv /var/lib/docker /data/telecom/docker

 

ln -s /data/telecom/docker /var/lib/docker

 

确认文件夹类型为symlink 类型

ls -al /var/lib/docker

 

这时候启动Docker时发现存储目录依旧是/var/lib/docker,但是实际上是存储在数据盘的,你可以在数据盘上看到容量变化。

最后systemctl start docker

 

https://blog.csdn.net/qq_37674858/article/details/79976751

docker使用问题总结

https://www.cnblogs.com/276815076/p/4673607.html

 

 

14 docker+harbor构建私有仓库

相关资料:https://blog.csdn.net/qq_35959573/article/details/80664353

1.安装docker-compose

1.1下载指定版本的docker-compose

 网址 https://github.com/docker/compose/releases

 

1.2 上传包,解压

 

 

1.3 授予执行权限

chmod +x /data/telecom/k8s/compose-1.21.1/bin/docker-compose

 

1.4 查看版本

docker-compose --version

2 安装harbor-offline-installer-v1.5.1.tgz

2.1下载安装包

https://storage.googleapis.com/harbor-releases/release-1.5.0/harbor-offline-installer-v1.5.1.tgz

 

 

 

2.2 解压文件

解压tar xvf harbor-offline-installer-v1.5.1.tgz

 

2.3 进入解压目录

 

2.4 配置harbor.cfg配置文件

 

2.5 执行./install.sh

 

 

 

 

 

依次自动安装完成

2.6 在浏览器中访问

132.121.117.242:80/ 默认端口是80,可以在docker-compose.yml文件中修改端口

 

 

3 上传镜像到私有仓库

3.1后台登录仓库

# 登录仓库

docker login -u admin -p Harbor12345 132.121.117.242

 

私有仓库登陆成功

 

如果出现:

Error response from daemon: Get https://192.168.80.42/v1/users/: dial tcp 132.121.117.242:443: getsockopt: connection refused 错误

 

这是因为 docker1.3.2 版本开始默认 docker registry 使用的是 https,我们设置 Harbor 默认 http 方式,所以当执行用 docker login、pull、push 等命令操作非 https 的 docker regsitry 的时就会报错。解决办法:

 

        如果系统是MacOS,则可以点击“Preference”里面的“Advanced”在“Insecure Registry”里加上192.168.80.42,重启Docker客户端就可以了;

        如果系统是Ubuntu,则修改配置文件/lib/systemd/system/docker.service,修改[Service]下ExecStart参数,增加–insecure-registry 192.168.80.42

        如果系统是Centos或RedHat,可以修改配置 /etc/systemd/system/docker.service,将 ExecStart 增加 –insecure-registry 132.121.117.242

在/etc/default/docker文件中加入--insecure-registry 132.121.117.242 私有仓库地址

 

 

3.2登出仓库

docker logout 132.121.117.242

 

3.3 浏览器访问

输入132.121.117.242:80/

 

3.5 新建镜像项目名

 

3.6 登录私有仓库

docker login 132.121.117.242

 

 

3.7打标签上传镜像

 

 

 

错误解决:

 

上图错误是没有加入私有或公有仓库镜像项目的名字 也等于是路径,这里取得项目名(telecom),如下图红框中

 

 

3.:8打标签

Docker tag打标签规则

Docker tag 本地镜像:版本号 ip或ip+端口/镜像项目名/镜像名:版本号

例:docker tag api_center2018120518008622:1.0 132.121.117.242/telecom/api_center2018120518008622:1.0

 

 

3.9 上传镜像

docker push 132.121.117.242/telecom/api_center2018120518008622:1.0

 

 

3.10 查看harbor的web页面是否成功

 

 

15 docker -v挂载

[telecom@master ~]$ docker run -d -v /data/telecom/logs:/data/telecom/mule/mule-standalone-3.8.1/logs --name api_center2018120518008622 -m 2048m --memory-swap=2048m -p 8622:8622 api_center2018120518008622:1.0

注意:

物理机的/data/telecom/logs目录与容器中/data/telecom/mule/mule-standalone-3.8.1/logs目录一致才有效,切记

 

同理文件共享的话可以-v挂载或在dockerfile中用

 

16 网络路由

241:Route add -net 172.17.0.1/16 gw 132.121.117.242

反之亦然

然后ping。如果不同 用iptables -F

 

 

17查看SELinux状态

/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态

 

18 harbor部署 SSL 认证

 

1) 概念理解

 

        签名证书与自签名证书

        签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西

        自签名证书:由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布

        openssl

        openssl 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用

        KEY与CSR的区别

        Key通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER。证书自身拥有一个密钥对(即一个公钥和一个私钥),由公钥(Public Key)与私钥(Private Key)是通过一种算法得到,公钥是密钥对中公开的部分,私钥则是非公开的部分。一般公钥和密钥的关系为:1,公钥和私钥成对出现、2,公开的密钥叫公钥,只有自己知道的叫私钥、3,用公钥加密的数据只有对应的私钥可以解密、4,用私钥加密的数据只有对应的公钥可以解密、5,如果可以用公钥解密,则必然是对应的私钥加的密、6,如果可以用私钥解密,则必然是对应的公钥加的密

 

        CSR文件必须在申请和购买SSL证书之前创建。也就是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请 者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书

 

2) 创建根证书

 

    # 创建证书存放目录

    mkdir -p /data/cert && cd /data/cert

[telecom@master ~]$ mkdir -p /data/cert && cd /data/cert

 

 

# 创建自己的CA证书(不使用第三方权威机构的CA来认证,自己充当CA的角色)
openssl genrsa -out ca.key 2048 # 生成根证书私钥(无加密)

 

[telecom@master cert]$ openssl genrsa -out ca.key 2048

 

 

# 生成自签名证书(使用已有私钥ca.key自行签发根证书)

openssl req -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj “/CN=Harbor-ca”

 

req  产生证书签发申请命令

-x509 签发X.509格式证书命令。X.509是最通用的一种签名证书格式。

-new  生成证书请求

-key  指定私钥文件

-nodes 表示私钥不加密

-out   输出

-subj 指定用户信息

-days 有效期

 

[telecom@master cert]$ openssl req -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj '/CN=Harbor-ca'

 

 

3) 创建服务器端证书

# 生成服务器端私钥和CSR签名请求
openssl req -newkey rsa:4096 -nodes -sha256 -keyout server.key -out server.csr    # 一路回车

 

[telecom@master cert]$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout server.key -out server.csr

 

 

# 签发服务器证书

echo subjectAltName = IP:132.121.117.242 > extfile.cnf

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extfile extfile.cnf -out server.crt

 

x509  签发X.509格式证书命令。

-req   表示证书输入请求。

-days  表示有效天数

-extensions 表示按OpenSSL配置文件v3_req项添加扩展。

-CA   表示CA证书,这里为ca.crt

-CAkey  表示CA证书密钥,这里为ca.key

-CAcreateserial 表示创建CA证书序列号

-extfile  指定文件

 

 [telecom@master cert]$ echo subjectAltName = IP:132.121.117.242 > extfile.cnf

 

[telecom@master cert]$ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extfile extfile.cnf -out server.crt

 

4) 修改 Harbor 的配置文件 hardor.cfg

 

# 修改成 https

ui_url_protocol = https

 

# 认证文件的路径

ssl_cert = /data/cert/server.crt

ssl_cert_key = /data/cert/server.key

 

 

5) 设置 docker 证书

# 如果如下目录不存在,请创建,如果有域名请按此格式依次创建 mkdir -p /etc/docker/certs.d/192.168.80.42 # mkdir -p /etc/docker/certs.d/[IP2] # mkdir -p /etc/docker/certs.d/[example1.com]

# 如果端口为443,则不需要指定。如果为自定义端口,请指定端口

# /etc/docker/certs.d/yourdomain.com:port

 

[telecom@master cert]$ mkdir -p /etc/docker/certs.d/132.121.117.242

 

[telecom@master cert]$ ls -l /etc/docker/certs.d/

 

# 将 ca 根证书依次复制到上述创建的目录中

[telecom@master cert]$ cp ca.crt /etc/docker/certs.d/132.121.117.242

[telecom@master cert]$

[telecom@master cert]$ cp server.crt /etc/docker/certs.d/132.121.117.242

 

6)重启docker和 重启动Harbor

# 重启 docker
systemctl restart docker

# 启动Harbor
./install.sh

 

 

 

19 docker容器设置时区时间,中文乱码

Docker应用时区与服务器时间同步(dockerfile)

时间:

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN echo 'Asia/Shanghai' >/etc/timezone

设置中文乱码:

ENV LANG=en_US.UTF-8

ENV TZ=Asia/Shanghai

 

Dockerfile

20.Dockerfile的简介

 Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制额外的需求时,只需Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。

 

20.1设置时区时间,中文乱码

Docker应用时区与服务器时间同步(dockerfile)

时间:

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN echo 'Asia/Shanghai' >/etc/timezone

设置中文乱码:

ENV LANG=en_US.UTF-8

ENV TZ=Asia/Shanghai

 

 

Dockerfile文件中的CMD和ENTRYPOINT指令差异对比

http://www.cnblogs.com/lienhua34/p/5170335.html

CMD指令和ENTRYPOINT指令的作用都是为镜像指定容器启动后的命令,那么它们两者之间有什么各自的优点呢?

 

为了更好地对比CMD指令和ENTRYPOINT指令的差异,我们这里再列一下这两个指令的说明,

 

20.2 CMD

支持三种格式

 

    CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;

 

    CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;

 

    CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

 

指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

 

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

 

20.3 ENTRYPOINT

 

两种格式:

 

    ENTRYPOINT ["executable", "param1", "param2"]

 

    ENTRYPOINT command param1 param2(shell中执行)。

 

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

 

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

 

从上面的说明,我们可以看到有两个共同点:

 

都可以指定shell或exec函数调用的方式执行命令;

当存在多个CMD指令或ENTRYPOINT指令时,只有最后一个生效;

而它们有如下差异:

 

       差异1:CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。

 

       差异2:CMD指令可以为ENTRYPOINT指令设置默认参数,而且可以被docker run指定的参数覆盖;

 

下面分别对上面两个差异点进行详细说明,

 

4.1 差异1

CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖;而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。

 

下面有个命名为startup的可执行shell脚本,其功能就是输出命令行参数而已。内容如下所示,

 

#!/bin/bash

 

echo "in startup, args: $@"

通过CMD指定容器启动时命令:

现在我们新建一个Dockerfile文件,其将startup脚本拷贝到容器的/opt目录下,并通过CMD指令指定容器启动时运行该startup脚本。其内容如下,

 

复制代码

FROM ubuntu:14.04

MAINTAINER lienhua34@xxx.com

 

ADD startup /opt

RUN chmod a+x /opt/startup

 

CMD ["/opt/startup"]

复制代码

通过运行docker build命令生成test:latest镜像,然后使用docker run启动两个test:latest镜像的容器,第一个docker run命令没有指定容器启动时命令,第二个docker run命令指定了容器启动时的命令为“/bin/bash -c 'echo Hello'”,

 

lienhua34@test$ sudo docker run -ti --rm=true test

in startup, args:

lienhua34@test$ sudo docker run -ti --rm=true test /bin/bash -c 'echo Hello'

Hello

从上面运行结果可以看到,docker run命令启动容器时指定的运行命令覆盖了Dockerfile文件中CMD指令指定的命令。

 

通过ENTRYPOINT指定容器启动时命令:

将上面的Dockerfile中的CMD替换成ENTRYPOINT,内容如下所示,

 

复制代码

FROM ubuntu:14.04

MAINTAINER lienhua34@xxx.com

 

ADD startup /opt

RUN chmod a+x /opt/startup

 

ENTRYPOINT [“/opt/startup”]

复制代码

同样,通过运行docker build生成test:latest镜像,然后使用docker run启动两个test:latest镜像的容器,第一个docker run命令没有指定容器启动时命令,第二个docker run命令指定了容器启动时的命令为“/bin/bash -c 'echo Hello'”,

 

lienhua34@test$ sudo docker run -ti --rm=true test

in startup, args:

lienhua34@test$ sudo docker run -ti --rm=true test /bin/bash -c 'echo Hello'

in startup, args: /bin/bash -c echo Hello

通过上面的运行结果可以看出,docker run命令指定的容器运行命令不能覆盖Dockerfile文件中ENTRYPOINT指令指定的命令,反而被当做参数传递给ENTRYPOINT指令指定的命令。

 

4.2 差异2

CMD指令可以为ENTRYPOINT指令设置默认参数,而且可以被docker run指定的参数覆盖;

 

同样使用上面的startup脚本。编写Dockerfile,内容如下所示,

 

复制代码

FROM ubuntu:14.04

MAINTAINER lienhua34@xxx.com

 

ADD startup /opt

RUN chmod a+x /opt/startup

 

ENTRYPOINT ["/opt/startup", "arg1"]

CMD ["arg2"]

复制代码

运行docker build命令生成test:latest镜像,下面运行docker run启动两个test:latest镜像的容器,第一条docker run命令没有指定参数,第二条docker run命令指定了参数arg3,其运行结果如下,

 

lienhua34@test$ sudo docker run -ti --rm=true test

in startup, args: arg1 arg2

lienhua34@test$ sudo docker run -ti --rm=true test arg3

in startup, args: arg1 arg3

从上面第一个容器的运行结果可以看出CMD指令为ENTRYPOINT指令设置了默认参数;从第二个容器的运行结果看出,docker run命令指定的参数覆盖了CMD指令指定的参数。

 

4.3注意点

CMD指令为ENTRYPOINT指令提供默认参数是基于镜像层次结构生效的,而不是基于是否在同个Dockerfile文件中。意思就是说,如果Dockerfile指定的基础镜像中是ENTRYPOINT指定的启动命令,则该Dockerfile中的CMD依然是为基础镜像中的ENTRYPOINT设置默认参数

 

例如,我们有如下一个Dockerfile文件,

 

复制代码

FROM ubuntu:14.04

MAINTAINER lienhua34@xxx.com

 

ADD startup /opt

RUN chmod a+x /opt/startup

 

ENTRYPOINT ["/opt/startup", "arg1"]

复制代码

通过运行docker build命令生成test:0.0.1镜像,然后创建该镜像的一个容器,查看运行结果,

 

复制代码

lienhua34@test$ sudo docker run -ti --rm=true test:0.0.1

in startup, args: arg1

复制代码

下面新建一个Dockerfile文件,基础镜像是刚生成的test:0.0.1,通过CMD指定要通过echo打印字符串“in test:0.0.2”。文件内容如下所示,

 

FROM test:0.0.1

MAINTAINER lienhua34@xxx.com

 

CMD ["/bin/bash", "-c", "echo in test:0.0.2"]

运行docker build命令生成test:0.0.2镜像,然后通过运行docker run启动一个test:0.0.2镜像的容器来查看结果,

 

复制代码

lienhua34@test$ sudo docker run -ti --rm=true test:0.0.2

in startup, args: arg1 /bin/bash -c echo in test:0.0.2

复制代码

从上面结果可以看到,镜像test:0.0.2启动的容器运行时并不是打印字符串”in test:0.0.2”,而是将CMD指令指定的命令当做基础镜像test:0.0.1中ENTRYPOINT指定的运行脚本startup的参数。

 

 

 

Dockerfile文件的说明:

格式:

INSTRUCTION arguments

虽然指令忽略大小写,但建议用大写

# 是注释

MAINTAINER命令:

MAINTAINER命令用来指定维护者的姓名和联系方式

FROM命令:

FROM <image>/<image>:<tag>

这个是设置基本的镜像,为后续的命令使用,所以应该作为Dockerfile的第一条指令

比如:

FROM centos6-base

RUN 命令:

会上面FROM 指定的镜像里执行任何命令,然后提交(commit)结果,提交的镜像会在后面继续用到

格式:

RUN <command> (这个命令运行一个shell中 - '/bin/sh -c')

或:

RUN ["executable", "param1", "param2"]

RUN 命令等价于:

docker run image_name command

CMD  and  ENTRYPOINT

命令设置在容器启动时执行命令

ENTRYPOINT,表示镜像在初始化时需要执行的命令,不可被重写覆盖,需谨记
 

CMD,表示镜像运行默认参数,可被重写覆盖
注意切记:

1.ENTRYPOINT/CMD都只能在文件中存在一次,并且最后一个生效 多个存在,只有最后一个生效,其它无效

需要初始化运行多个命令,彼此之间可以使用 && 隔开,但最后一个须要为无限运行的命令,需切记!

ENTRYPOINT/CMD,一般两者可以配合使用,比如:

ENTRYPOINT ["/usr/sbin/sshd"]

CMD ["-D"]

在Docker daemon模式下,无论你是使用ENTRYPOINT,还是CMD,最后的命令,一定要是当前进程需要一直运行的,才能够防容器退出。

以下无效方式:

ENTRYPOINT service tomcat7 start #运行几秒钟之后,容器就会退出

CMD service tomcat7 start #运行几秒钟之后,容器就会退出

这样有效:

ENTRYPOINT service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.out

# 或者

CMD service tomcat7 start && tail -f /var/lib/tomcat7/logs/catalina.out

这样也有效:

ENTRYPOINT ["/usr/sbin/sshd"]

CMD ["-D"]

USER 命令
 

比如指定 memcached 的运行用户,可以使用上面的 ENTRYPOINT or CMD来实现:

ENTRYPOINT ["memcached", "-u", "daemon"]

更好的方式:

ENTRYPOINT ["memcached"]

USER daemon

EXPOSE 命令

 

EXPOSE 命令可以设置一个端口在运行的镜像中暴露在外

在docker使用--link来链接两容器时会用到相关端口

EXPOSEd <port>

ENV命令:

用于设置环境变更

使用此dockerfile生成的image新建container,可以通过 docker inspect CONTAINER ID  看到这个环境变量

也可以通过在docker run时设置或修改环境变量

ADD 命令:
 

从src复制文件到container的dest路径:

ADD <src> <dest>

<src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url

<dest> 是container中的绝对路径

VOLUME 命令
 

VOLUME ["<mountpoint>"]

如:

VOLUME ["/data"]

创建一个挂载点用于共享目录

WORKDIR 命令

 

WORKDIR /path/to/workdir

配置RUN, CMD, ENTRYPOINT 命令设置当前工作路径

可以设置多次,如果是相对路径,则相对前一个 WORKDIR 命令

比如:

WORKDIR /a WORKDIR b WORKDIR c RUN pwd

其实是在 /a/b/c 下执行 pwd

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值