跳到主要内容

Docker

目录结构

  • /var/lib/docker - 数据目录 - /etc/docker/daemon.json data-root 配置
    • image/ - 镜像
    • volumes/ - 临时 volume
    • builder/
    • buildkit/
    • containers/SHA/ - 容器信息
      • SHA-json.log
      • checkpoints
      • config.v2.json
      • hostconfig.json
      • hostname
      • hosts
      • mounts
      • resolv.conf
      • resolv.conf.hash
    • network/files/local-kv.db
    • overlay2/SHA/
      • committed
      • diff
      • link
      • lower
      • work
    • trust/
    • plugins/
  • /var/lib/docker/containerd/daemon - ContainerD 目录
    • 镜像没有使用 containerd 存储

SSHD service

  • Dockerfile
FROM java:8
MAINTAINER Wener <[email protected]>

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
docker build -t local-sshd .
docker run -d -p 2331:22 --name dock-1 local-sshd

# Run a lot
NUM=5
VOLUME=~/opt/volume
for i in $(seq 1 $NUM); do
mkdir -p $VOLUME/dock-$i
docker run -d -v $VOLUME/dock-$i:/opt -p 233$i:22 --name dock-$i local-sshd
done

# Cleanup
for i in $(seq 1 $NUM); do docker stop dock-$i;docker rm dock-$i; done

# Generate ansible inventory

# 不一样的工具,获取的 IP 不同,如果 ansible 也是在 docker 中,则可用后者
# 使用前者只能用于 SSH, 不能用于容器内部服务通信地址
# docker-machine ip default
# docker inspect --format '{{ .NetworkSettings.IPAddress }}' dock-my

for i in $(seq 1 $NUM); do
echo "dock-$i ansible_host=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' dock-$i) ansible_port=233$i ansible_user=root ansible_ssh_pass=screencast";
done


docker run --rm -it -v ~:/host williamyeh/ansible:ubuntu14.04-onbuild bash

修改镜像

# 标准配置位于 /etc/sysconfig/docker
# Boot2docker 位于 /var/lib/boot2docker/profile
# 配置参数格式为 --registry-mirror=镜像地址
# 基于 https://docs.docker.com/engine/installation/linux/centos/ 在 CentOS 7 上安装时
# 需要修改 service 启动参数 /usr/lib/systemd/system/docker.service
# 然后加载配置并重启服务
sudo systemctl daemon-reload
sudo service docker restart

安装

# 使用安装脚本安装
curl -sSL https://get.docker.com/ | sh

# 二进制安装
# 官方文档 http://docs.master.dockerproject.org/engine/installation/binaries/
# init 脚本 https://github.com/docker/docker/tree/master/contrib/init

# 安装最新构建的 dev 版
curl -LOk https://master.dockerproject.org/linux/amd64/docker-1.13.0-dev.tgz
tar -xvzf docker-*.tgz
mv docker/* /usr/bin/
curl -LOk https://raw.githubusercontent.com/docker/docker/master/contrib/init/systemd/docker.service
curl -LOk https://raw.githubusercontent.com/docker/docker/master/contrib/init/systemd/docker.socket
mv docker.{service,socket} /lib/systemd/system/

systemctl daemon-reload
systemctl restart docker

# 如果有旧的 sysv 启动脚本 /etc/init.d/docker 启动时可能会使用该脚本

https://www.daocloud.io/mirror

# 使用阿里提供的仓库进行安装会非常快
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
# 安装完毕后为当前用户添加权限,需要退出重新登录才能生效
sudo usermod -aG docker $USER

Ubuntu

apt-get update
apt-get install apt-transport-https ca-certificates
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
# 添加 Docker 仓库
nano /etc/apt/sources.list.d/docker.list
# 14.04 LTS
# deb https://apt.dockerproject.org/repo ubuntu-trusty main
# 16.04 LTS
# deb https://apt.dockerproject.org/repo ubuntu-xenial main
# 更新 APT 包索引
# 在国内可使用阿里镜像仓库 http://mirrors.aliyun.com/docker-engine
apt-get update
# 删除旧的包
apt-get purge lxc-docker
# 验证 APT 是从正确的仓库拉取的
apt-cache policy docker-engine
# 安装基础内容
apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
apt-get install docker-engine
service docker start

Tips

  • Docker machine root 密码为 tcuser
  • 也可以通过 sudo su root 切换为 root
  • Linux 下的配置文件 /etc/default/docker
# stats 中显示容器名字
docker stats $(docker ps --format={{.Names}})

# 可通过 JSON 文件来配置 docker daemon, 但目前没有办法检测配置是否成功 https://github.com/docker/docker/issues/21559
# /etc/docker/daemon.json

# Boot2docker
# 配置文件
vi /var/lib/boot2docker/profile
# 重启服务
/etc/init.d/docker restart

# 移除停止容器
docker rm `docker ps --no-trunc -aq`
# 数据清理
docker images --no-trunc | grep '<none>' | awk '{ print $3 }' | xargs -r docker rmi
docker volume ls -qf dangling=true | xargs -r docker volume rm

# 回收旧数据
apt-get autoclean
apt-get autoremove
cd /var/discourse
./launcher cleanup

# https://github.com/spotify/docker-gc
# 可以直接 Docker 运行
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc

# 使用 Docker Machine 启动
docker-machine start default
eval $(docker-machine env default)
docker pull java:8

# Docker machine 只会将 home 下的目录挂载到虚拟机中,如果要挂载其他的目录需要自己添加
docker-machine stop
VBoxManage sharedfolder add default --name /hetc --hostpath /etc --automount
docker-machine start
docker-machine ssh default 'sudo mkdir --parents /hetc'
docker-machine ssh default 'sudo mount -t vboxsf hetc /hetc'
docker run --rm -v /hetc:/hetc ubuntu


# 将一个已经启动的容器修改为自动重启
# https://docs.docker.com/engine/reference/commandline/update/
docker update --restart=always web

# 清空日志
echo "" > $(docker inspect --format='{{.LogPath}}' web)

INCLUDE

由于 Dockerfile 不支持 INCLUDE, 可以考虑使用 cpp

Dockerfile: Dockerfile.in *.docker
cpp -o Dockerfile Dockerfile.in

build: Dockerfile
docker build -rm -t my/image .
FROM ubuntu:latest
MAINTAINER me

#include "imagemagick.docker"
#include "redis.docker"

代理

Docker 会使用 HTTP_PROXY 作为代理,代理配置成功后可在 docker info 看到代理配置

代理配置文件

  • /etc/default/docker

如果代理配置不生效,可直接修改 systemd 定义文件,例如在 Ubuntu 16.04 下为 /lib/systemd/system/docker.service,在 Service 节下添加 Environment=HTTP_PROXY=http://10.0.0.1:7777, 然后 systemctl daemon-reload 再重启 docker 即可,配置可通过 systemctl show --property=Environment docker 查看

时区

启动时修改时区

$ docker run --rm busybox date
Thu Mar 20 04:42:02 UTC 2014
$ docker run --rm -v /etc/localtime:/etc/localtime busybox date
Thu Mar 20 14:42:20 EST 2014
$ FILE=$(mktemp) ; echo $FILE ; echo -e "Europe/Brussels" > $FILE ; docker run --rm -v $FILE:/etc/timezone -v /usr/share/zoneinfo/Europe/Brussels:/etc/localtime busybox date
/tmp/tmp.JwL2A9c50i
Thu Mar 20 05:42:26 CET 2014
$ docker run -t -i --rm -e TZ=Europe/London busybox date

Dockerfile 修改时区

RUN echo America/New_York | sudo tee /etc/timezone && sudo dpkg-reconfigure --frontend noninteractive tzdata

修改 MySQL 的时区

# 方法一 修改容器时区,重启 mysql
docker exec -it MySQL bash
# 时区信息 /usr/share/zoneinfo
# 直接修改 echo Asia/Shanghai > /etc/timezone
# 获取所有时区 timedatectl list-timezones
# 直接修改时区 timedatectl set-timezone Europe/Athens
# 在容器里可能 timedatectl 无法使用

# 交互式选择时区
dpkg-reconfigure tzdata
/etc/init.d/mysql restart

# 方法二 SET GLOBAL time_zone = 'Asia/Shanghai';
# 方法三 my.cnf [mysqld] default-time-zone='Asia/Shanghai'

macOS

# 进入 docker for mac 的虚拟机
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh

baseimage

Refernece