文章目录
CentOS
- 常规安装
yum install -y wget
systemctl stop firewalld
systemctl disable firewalld
wget -P /etc/yum.repos.d/ https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
- 安装指定的版本
# 查看安装版本
yum list docker-ce --showduplicates | sort -r
# 安装 Docker CE 的版本 18.03.0
yum install -y docker-ce-18.03.0.ce-1.el7.centos
- 启动服务
systemctl start docker
systemctl enable docker
systemctl status docker
Ubuntu
apt-get remove docker docker-engine docker-ce docker.io
apt-get install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt-get update -y
apt-get install docker-ce -y
docker version
systemctl enable docker
systemctl start docker
systemctl status docker
配置
Docker 配置文件的路径为 /etc/docker/daemon.json。
- 配置国内 DaoCloud 的源,加速镜像的拉取。
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://d6f11267.m.daocloud.io
systemctl restart docker
常用指令
Docker 的操作主要分为两大类:
- 镜像操作
- 容器操作
- 注册表操作
镜像操作
# 查看本地镜像
docker images
# 搜索仓库的镜像
docker search
# 拉取仓库的镜像
docker pull docker.io/centos
# 利用 DockerFile 创建镜像
docker build <dockerfile>
# 删除已经终止的容器
docker rm
# 可以删除正在运行的容器
docker -f rm
# 跟据 ID 将镜像保存成一个文件。
docker save <image_id> > <image_name>.tar
# 同时将多个 image 打包成一个文件。
docker save -o images.tar postgres:9.6 mongo:3.4
# 将容器保存成一个文件。
docker export <container_id> > <image_name>.tar
# 从本地将镜像导入
docker load --input centos.tar
# 或
docker load < centos.tar
# 将容器提交为镜像
docker commit <image_name> <container_id>
# 修改镜像标签
docker tag <OLD REPOSITORY>:<OLD TAG> <NEW REPOSITORY>:<NEW TAG>
# 将打标签的镜像上传镜像到仓库
docker push <REPOSITORY>:<TAG>
容器操作
# 创建一个容器但不启动它
docker create
# 创建并启动一个容器
docker run
# 停止容器运行,发送信号 SIGTERM
docker stop
# 启动一个停止状态的容器
docker start
# 重启一个容器
docker restart
# 删除一个容器
docker rm
# 发送信号给容器,默认为信号 SIGKILL
docker kill
# 进入到一个正在运行的容器
docker attach
# 阻塞一个容器,直到容器停止运行
docker wait
# 显示状态为运行(Up)的容器
docker ps
# 显示所有容器,包括运行中(Up)的和退出的(Exited)
docker ps -a
# 深入容器内部获取容器所有信息
docker inspect
# 查看容器的日志(stdout/stderr)
docker logs
# 得到 Docker Server 的实时的事件
docker events
# 显示容器的端口映射
docker port
# 显示容器的进程信息
docker top
# 显示容器文件系统的前后变化
docker diff
# 在容器里执行一个命令,可以执行 bash 进入交互模式
docker exec
注册表操作
- 创建仓库:
docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
- 修改配置文件,使之支持 HTTP
# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.100:5000"]
}
- 重启生效
systemctl restart docker.service
搭建带 basic 认证的仓库:
- 安装加密工具
yum install httpd-tools -y
- 设置认证密码
mkdir /opt/registry-var/auth/ -p
htpasswd -Bbn fanguiju 123456 > /opt/registry-var/auth/htpasswd
- 启动 Registry 容器,在启动时传入认证参数
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
- 使用验证用户测试
# 登陆用户
$ docker login 10.0.0.100:5000
Username: fanguiju
Password: 123456
Login Succeeded
# 推送镜像到仓库
$ docker push <Image ID>
The push refers to repository [10.0.0.100:5000/clsn/busybox]
4febd3792a1f: Pushed
1.0: digest: sha256:4cee1979ba0bf7db9fc5d28fb7b798ca69ae95a47c5fecf46327720df4ff352d size: 527
# 认证文件的保存位置
$ cat .docker/config.json
{
"auths": {
"10.0.0.100:5000": {
"auth": "Y2xzbjoxMjM0NTY="
},
"https://index.docker.io/v1/": {
"auth": "Y2xzbjpIenNAMTk5Ng=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/17.12.0-ce (linux)"
}
}
docker run options
–link
在实践中,自然会遇到 2 个容器之间互相访问通信的问题,这个时候就用到了 docker run --link 选项。
docker run --link 可以用来链接 2 个容器,使得 Receiving Container(主动去链接的容器)和 Source Container (被链接的容器)之间可以互相通信,并且 Receiving Container 也可以获取到 Source Container 的一些元数据信息,如:环境变量。
格式:
--link <name or id>:alias
# <name or id>:Source Container 的 Name or ID
# alias:Source Container 在 link 下的别名
例子:
# Run Source Container
docker run -d --name selenium_hub selenium/hub
# Run Receiving Container
docker run -d --name node --link selenium_hub:hub selenium/node-chrome-debug
Source Container 和 Receiving Container 之间的数据传递可以通过以下 2 种方式:
- 更新 /etc/hosts 文件。
- 设置环境变量。
更新 /etc/hosts 文件:通过 link 后,Receiving Container: selenium_hub 就可以通过 hostname: selenium_hub/hub 去访问 Source Container: node 了。可见,–link option 指定的 selenium_hub:hub 实际上会成为 Source Container 在 Receiving Container 中的 hostname。
docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 hub 1cbbf6f07804 selenium_hub
172.17.0.3 c4cc05d832e0
root@c4cc05d832e0:~# ping selenium_hub
PING hub (172.17.0.2) 56(84) bytes of data.
64 bytes from hub (172.17.0.2): icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from hub (172.17.0.2): icmp_seq=2 ttl=64 time=0.133 ms
64 bytes from hub (172.17.0.2): icmp_seq=3 ttl=64 time=0.216 ms
root@c4cc05d832e0:~# ping hub
PING hub (172.17.0.2) 56(84) bytes of data.
64 bytes from hub (172.17.0.2): icmp_seq=1 ttl=64 time=0.194 ms
64 bytes from hub (172.17.0.2): icmp_seq=2 ttl=64 time=0.218 ms
64 bytes from hub (172.17.0.2): icmp_seq=3 ttl=64 time=0.128 ms
设置环境变量:当使用 --link 时,Docker 会自动在 Receiving Container 内创建一系列与 Source Container 相关的环境变量。这些环境变量的都会以 name or id or alias
为前缀存在。
- Source Container Dockerfile 中 ENV 标签设置的环境变量。
- Run Source Container 时,通过选项 -e、–env、–env-file 设置的环境变量。
docker exec -it node /bin/bash
seluser@c4cc05d832e0:/$ env | grep -i HUB_PORT_4444_TCP_
HUB_PORT_4444_TCP_PROTO=tcp # Source Container 的 Protocol。
HUB_PORT_4444_TCP_ADDR=172.17.0.2 # Source Container 的 IP 地址。
HUB_PORT_4444_TCP_PORT=4444 # Source Container Dockerfile 中定义的 Port。
–cap-add/–cap-drop
Linux 的 Capability 机制允许你将 Root 相关的高级权限划分成为不同的小单元。目前 Docker 默认只会使用到了以下的 Capability:
- CHOWN
- DAC_OVERRIDE
- FSETID
- FOWNER
- MKNOD
- NET_RAW
- SETGID
- SETUID
- SETFCAP
- SETPCAP
- NET_BIND_SERVICE
- SYS_CHROOT
- KILL
- AUDIT_WRITE
查看 Capability 清单:
$ pscap
在某些场景下,你也许需要调整 Docker Container 所能够使用到的高级权限特性。例如:你正在构建一个用来执行 ntpd 或 crony 的容器,为此该容器需要能够修改宿主机的系统时间。但由于 Docker Container 默认不具备 CAP_SYS_TIME 特性,就会导致无法工作。
为了应对这种情况,旧版本中,Docker Container 必须以特权模式运行(使用 --privileged 选项),但这会禁用所有宿主机的安全机制。在 Docker 1.3 版本中,新添了 --cap-add 和 --cap-drop 选项。
- –cap-add:将指定特性添加到容器中。
docker run -d --cap-add SYS_TIME ntpd
- –cap-drop:将特定特性从容器中移除。
# 容器不会改变任何进程的 UID 和 GID。
docker run --cap-drop SETUID --cap-drop SETGID --cap-drop FOWNER fedora /bin/sh
或者你可以先移除所有特性,然后再需要的添加回去:
docker run --cap-drop ALL --cap-add SYS_TIME ntpd /bin/sh
–user
–user 选项用于指定 Docker Container 使用的 UID 和 GID 启动,这意味着由该进程创建的任何文件也属于 UID 和 GID 的用户。因为 Docker Containers 共享了同一个 Kernel,因此 UID 和 GID 的列表也是相同的,即使 Container 不知道相关的用户名。
docker container run --rm -it \
-v $(app):/app \ # Mount the source code
--workdir /app \ # Set the working dir
--user 1000:1000 \ # Run as the given user
my-docker/my-build-environment:latest \ # Our build env image
make assets # ... and the command!