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/
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来控制吧???
服务启动参数配置:
参考官方文档:
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.
注意:
两者可以结合使用,不过不要重复,否则会报错,服务不会启动并会打印错误日志
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;
注意:
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
暂时还没有明白docker是怎么调的iptables
{
"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
总结:
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
useradd -u 200 -g users user_00
usermod -a -G docker user_00 #将普通用户加入docker组,docker命令可以正常执行,也就是普通用户user_00可以管理容器
chown -R root:docker /data/docker-data #不是必须
注意:
图片中load和save两个方法箭头刚好都反了
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
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
...
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
#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 #显示本地的可用镜像
守护式容器: 能够长期运行。没有交互式会话,适合运行应用程序和服务
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参数,否则没有终端
注意:
默认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",容器就拥有了访问任何其它设备的权限。
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
★强烈建议不要这样操作,会将宿主机的结果和容器内的结果一起返回!
如果要导出镜像到本地文件,可以使用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
随机映射:
docker run -P
指定映射:
-p hostPort:containerPort
-p ip:hostPort:containerPort
-p ip::containerPort
-p hostPort:containerPort:udp
ctrl+p+q
在使用docker exec -it musing_newton /bin/bash 时,退出的只是此次执行的/bin/bash,第一次启动的docker并没有关闭掉!
docker run —help |grep -E ‘mem|cpu’
查看和删除镜像
列出镜像
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
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
指令格式:
#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]
复杂案例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"
ssh server是否应该包含到镜像里?
用ssh管理容器并不理想
如前面的例子,账号和密码是写死在镜像里面的,如果修改密码,需要重新编译打包。
建议不用。
一个容器究竟运行几个程序?
一个程序比较好,因为docker只管你的前台程序是否正常
程序参数和配置文件的问题?
如果放在镜像中,很麻烦
a、设置为环境变量,用参数传进去,不适合参数比较多和参数比较敏感的情况
b、集中,使用配置管理中心(disconf…),见docker友好程序架构图
程序日志输出的问题?
通过volume
或者syslog方式
docker友好程序架构图:
建议:
在一个Dockerfile中每个命令都会在原来的基础上生成一层镜像。你可以很快的在三十多层的时候就结束了,这未必是一个问题,但也可以通过组合RUN命令,并使用一行EXPOSE命令列出你所有的开放端口,这样可以有效减少镜像的层数。
通过将RUN命令分组,可以在容器间分享更多的层。当然如果你有一组命令可以多个容器通用,那么你应该创建一个独立的基础镜像,它包含你建立的所有镜像。
对于每一层来说你都可以跨多个镜像分享,这样可以节省大量的磁盘空间。