docker 简介
Docker 是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的
Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并遵从
Apache2.0协议开源。
Docker是通过内核虚拟化技术(namespaces及cgroups等)
来提供容器的资源隔离与安全保障等。由于Docker通过操作系
统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类
似虚拟机(VM)额外的操作系统开销,提高资源利用率。
docker理念
docker组成
容器和虚拟化的对比
docker和KVM对比
docker能干些什么
docker改变了什么
docker镜像管理命令
搜索镜像:docker search ubuntu
下载一个镜像:docker pull ubuntu
列出本地已经下载的镜像:$ docker images
将已经存在的镜像打包导出:docker save -o ubuntu.tar ubuntu
导入别人已经构建好打包的镜像:docker load --input ubuntu.tar
另外使用重定向导入:docker load < ubuntu.tar
删除镜像:docker rmi +镜像的id
$ docker rmi -f 25bce0f7f3aa
Untagged: toohoo/ubuntu:v2
Deleted: sha256:25bce0f7f3aaf09ce74e4d00717d9f053c4b395cd392d5e6a8784cba96e8c0d8
删除一个镜像时会删除依赖于其的其他镜像
$ docker rmi -f ffc099019bd0
Untagged: toohoo/ubuntu:18.04
Untagged: toohoo/ubuntu:dev
Deleted: sha256:ffc099019bd0a77036d3c5ae4e80469c636b199986d3333cb2e3b343ae289ff8
Deleted: sha256:33f16e9bbcc6f80d5717d3f66ec0c8808c28c71f4d4ec2602e31456ef1c4153f
Deleted: sha256:03978bfaac9301fb9b318758ca7a4497d98269984458588e156305ebb965b7a0
Deleted: sha256:1c056a306ca7a2b588f2e3a10f2b95020199fcfb382afc2352f57bc37a24c1a3
Deleted: sha256:d7d338693fb6ac124f9969e960d54a5816207af15160fb27d3d4bf8eb4dfac1c
Deleted: sha256:0515aedbc96a01eb3a8e328df309136f7ee081fb68a221b66a95087ffe0d43de
Deleted: sha256:50e17c4a7fd7c06f2284c8312f58439fbf9a4a06d4d81fb54e198fc0e080edbb
Deleted: sha256:33b12033efe3f200d2d0d1d9a2228a4c0e1d59b4620a0f3e5e743e65706ccadb
docker容器管理命令
输出Hello World(不加标签会自动选择latest的)
$ docker run ubuntu /bin/echo "Hello world"
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
898c46f3b1a1: Pulling fs layer
63366dfa0a50: Pulling fs layer
041d4cd74a92: Downloading
6e1bee0f8701: Waiting
latest: Pulling from library/ubuntu
898c46f3b1a1: Pull complete
63366dfa0a50: Pull complete
041d4cd74a92: Pull complete
6e1bee0f8701: Pull complete
Digest: sha256:017eef0b616011647b269b5c65826e2e2ebddbe5d1f8c1e56b3599fb14fabec8
Status: Downloaded newer image for ubuntu:latest
Hello world
加上标签之后会在本地查找(例如本地已经有Ubuntu:18.04)
$ docker run ubuntu:18.04 /bin/echo "Hello world"
Hello world
意思:Docker 以 ubuntu18.04 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果
查看已经退出的容器:docker ps -a
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa6494a88e0d ubuntu:18.04 "/bin/echo 'Hello wo…" 4 minutes ago Exited (0) 4 minutes ago stupefied_yalow
edce69937e8c ubuntu "/bin/echo 'Hello wo…" 22 minutes ago Exited (0) 22 minutes ago musing_euler
运行一个指定名称的容器:
$ docker run --name mydocker -t -i ubuntu:18.04 /bin/bash
root@a13bfaf7b0b9:/# ls /
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@a13bfaf7b0b9:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18504 3244 pts/0 Ss 01:15 0:00 /bin/bash
root 11 0.0 0.0 34400 2684 pts/0 R+ 01:17 0:00 ps aux
解析:
docker: Docker 的二进制执行文件。
run:与前面的 docker 组合来运行一个容器。
–name mydocker:指定容器的名称(默认为空会自动分配)
-t:在新容器内指定一个伪终端或终端
-i:允许你对容器内的标准输入 (STDIN) 进行交互(打开标准输入,我要访问)
ubuntu:18.04指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
/bin/bash:是需要运行的前台指定的命令,对应的 PID=1
里面很多命令没有,如果命令执行完毕,容器就退出
需要在后台运行时:加 -d
$ docker run --name mydocker -t -i -d ubuntu:18.04 /bin/bash
docker: Error response from daemon: Conflict. The container name "/mydocker" is already in use by container "a13bfaf7b0b99eeeb7f8ad376c0b2e7716547957896e66da03e0ed7e896516fc". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
toohoo@ubuntu:~/learnDocker$ docker run --name mydocker-demo -t -i -d ubuntu:18.04 /bin/bash
6eb16def1e2e30b70c5b20a9e4d08221d3659c340be6f548618d4a05b9f481e1
toohoo@ubuntu:~/learnDocker$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6eb16def1e2e ubuntu:18.04 "/bin/bash" 24 seconds ago Up 23 seconds mydocker-demo
a13bfaf7b0b9 ubuntu:18.04 "/bin/bash" 13 minutes ago Exited (0) About a minute ago mydocker
fa6494a88e0d ubuntu:18.04 "/bin/echo 'Hello wo…" 32 minutes ago Exited (0) 32 minutes ago stupefied_yalow
edce69937e8c ubuntu "/bin/echo 'Hello wo…" About an hour ago Exited (0) About an hour ago musing_euler
6eb16def1e2e30b70c5b20a9e4d08221d3659c340be6f548618d4a05b9f481e1:表示容器的ID,什么都没有输出就是后台执行/bin/bash之后就退出了
另外注意的是,名字不能是mydocker了,换一个名字:mydocker-demo,没有的话会自动分配一个
查看后台运行的容器:
toohoo@ubuntu:~/learnDocker$ docker run -t -i -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
0dc2c820071a4b8379e8a5f9ce4c045fddfdaf1d94808b85e82312c50fdba10e
toohoo@ubuntu:~/learnDocker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0dc2c820071a ubuntu:18.04 "/bin/sh -c 'while t…" About a minute ago Up About a minute hopeful_goodall
6eb16def1e2e ubuntu:18.04 "/bin/bash" 10 minutes ago Up 10 minutes mydocker-demo
hopeful_goodall:就是自动分配的名字
在容器内使用docker logs命令,查看容器内的标准输出
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
...
期待的hello world在容器后台输出。
启动一个容器:docker start +容器ID
停止一个容器:docker stop +容器ID/名称
再pull一个nginx
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 94e814e2efa8 11 days ago 88.9MB
nginx latest 881bd08c0b08 2 weeks ago 109MB
httpd latest d3a13ec4a0f1 5 weeks ago 132MB
ubuntu 18.04 47b19964fb50 6 weeks ago 88.1MB
创建一个容器
$ docker run --name mynginx -d nginx
f4912a75756b5ae4bc4dd4c2a3379c6cb4a9b133ebaa00a85767e5da16c621d7
toohoo@ubuntu:~/learnDocker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4912a75756b nginx "nginx -g 'daemon of…" 11 seconds ago Up 9 seconds 80/tcp mynginx
docker run --name mynginx -d nginx 后面是没有带启动命令的,因为由docker ps 知道镜像里面已经自带启动命令了,自己做一个镜像可以添加这个命令,也可以让用户进行手动输入,。nginx -g 'daemon off ’ 的意思就是放在前台运行,避免一运行玩就退出。
进入已经启动正在运行的容器中:$ docker attach +容器ID
attach的缺点是,命令行的显示是同步的,其他人也进入到容器的时候也会显示相应的信息,同一个窗口卡住,其他人也没办法操作,生产不用这个。
进入的非常慢,当你使用ctl+c退出时候,也会发现容器也退出了。
使用nsenter进入到容器:(默认的LInux发行版都有的ns:namespace)
1、获取pid:docker inspect --format “{
{ .State.Pid }}” f4912a75756b(容器PID)
2、执行命令进入到容器里面:
toohoo@ubuntu:~/learnDocker$ docker inspect --format "{
{ .State.Pid }}" f4912a75756b
81852
toohoo@ubuntu:~/learnDocker$ nsenter --help
Usage:
nsenter [options] [<program> [<argument>...]]
Run a program with namespaces of other processes.
Options:
-a, --all enter all namespaces
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-C, --cgroup[=<file>] enter cgroup namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork do not fork before exec'ing <program>
-Z, --follow-context set SELinux context according to --target PID
-h, --help display this help
-V, --version display version
For more details see nsenter(1).
toohoo@ubuntu:~/learnDocker$ nsenter -t 81852 -m -u -i -n -p
nsenter: cannot open /proc/81852/ns/ipc: Permission denied
toohoo@ubuntu:~/learnDocker$ sudo nsenter -t 81852 -m -u -i -n -p
[sudo] password for toohoo:
root@f4912a75756b:/#
查看nginx的位置,查看版本和退出:
root@f4912a75756b:/# ps aux
-bash: ps: command not found
root@f4912a75756b:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@f4912a75756b:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@f4912a75756b:/# uname -a
Linux f4912a75756b 4.15.0-46-generic #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 x86_64 GNU/Linux
root@f4912a75756b:/# exit
logout
由上可知此nginx是基于Ubuntu构建的
使用脚本进入到容器:
#!/bin/bash
# Use nsenter to access docker
docker_in(){
NAME_ID=$1
PID=$(docker inspect --format "{
{ .State.Pid }}" $NAME_ID)
nsenter -t $PID -m -u -i -n -p
}
docker_in $1
进入容器并退出容器
$ chmod +x docker_in.sh
toohoo@ubuntu:~/learnDocker$ sudo ./docker_in.sh mynginx
[sudo] password for toohoo:
root@f4912a75756b:/# ps aux
-bash: ps: command not found
root@f4912a75756b:/# exit
logout
使用exec进入到容器
不是真的向进入到这个容器里面,而是想让容器运行一个命令:
toohoo@ubuntu:~/learnDocker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4912a75756b nginx "nginx -g 'daemon of…" About an hour ago Up 41 minutes 80/tcp mynginx
toohoo@ubuntu:~/learnDocker$ docker exec mynginx whoami
root
toohoo@ubuntu:~/learnDocker$ docker exec mynginx uptime
OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"uptime\": executable file not found in $PATH": unknown # 容器里面极度缺少命令啊!
docker 运行一个命令,如果PID=1的进程挂了,容器也就挂了。
如果容器挂掉了,在docker 里面是可以允许的,这也是使用docker的优点。
删除容器:docker rm 容器名/容器ID
开启一个容器,运行一个测试命令,运行完之后删除容器(小技巧)
toohoo@ubuntu:~/learnDocker$ docker run --rm ubuntu:18.04 /bin/echo "haha"
haha
docker访问网络命令
本例使用两个例子:一个是创建一个nginx-test1容器,一个是不指定名称的基于training/webapp镜像的容器。
首先是nginx-test1:容器例子
运行一个web应用
toohoo@ubuntu:~/learnDocker$ docker run -d -P --name nginx-test1 nginx
e441198c9cbf9bce83c4c2aefc32f230c7b53a9100f66cca30ebe522798f8216
root@ubuntu:/home/toohoo/learnDocker# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e441198c9cbf nginx "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:32771->80/tcp nginx-test1
# 过滤一下端口
root@ubuntu:/home/toohoo/learnDocker# netstat -ntlp |grep 32771
tcp6 0 0 :::32771 :::* LISTEN 115854/docker-proxy
可以使用curl --head + URL侦听一下端口:200通过!
root@ubuntu:/home/toohoo/learnDocker# curl --head http://172.19.229.242:32771
HTTP/1.1 200 OK
Server: nginx/1.15.9
Date: Sun, 24 Mar 2019 01:18:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 Feb 2019 14:13:39 GMT
Connection: keep-alive
ETag: "5c754993-264"
Accept-Ranges: bytes
浏览器访问:http://172.19.229.242:32771:成功!
也可以看一下日志:
root@ubuntu:/home/toohoo/learnDocker# docker logs nginx-t