Docker这玩意流行已经有一阵子,之前一直不愿意去碰它,是觉得它还不够稳定。虽说各类软文铺天盖地,什么Paas微服务,容器引擎,轻量级虚拟机(当然底层的cgroups,lxc技术早已耳熟能详)等等,对这些往往不置可否,原因只有一个:大规模工业级场景应用还未曾出现,或者说未曾亲历。
时间来到了最近,由于工作需求,需要做一些MQ镜像,所以系统化的学习了Docker(当然,催生我系统化学习的动力不仅是要深度使用它,还有Go语言这两年本身的实践魅力)。这篇文章简单记录了Docker的一些使用心得及其感受,欢迎大家轻拍。
作为忠实的Linuxer,Ubuntu是我最钟爱的办公平台,当然自己的实践也是基于该平台的,如果是其它平台,请查看我参考文档里面的那几个在线文章。安装脚本如下:
sudo sh -c "echo deb http://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
apt-get install lxc-docker
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8
sudo groupadd docker
# 添加当前用户到docker用户组里,这里我是以von登陆的
sudo gpasswd -a von docker
sudo service docker restart
docker version
#若未生效,则系统重启
sudo reboot
Giving non-root access
The docker daemon always runs as the root user, and since Docker version 0.5.2, the docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root, and so, by default, you can access it with sudo.
Starting in version 0.5.3, if you (or your Docker installer) create a Unix group called docker and add users to it, then the docker daemon will make the ownership of the Unix socket read/writable by the docker group when the daemon starts. The docker daemon must always run as the root user, but if you run the docker client as a user in the docker group then you don't need to add sudo to all the client commands. As of 0.9.0, you can specify that a group other than docker should own the Unix socket with the -G option.
Warning: The docker group (or the group specified with -G) is root-equivalent; see Docker Daemon Attack Surface details.
一旦安装ok,找个官方Helloworld示例玩玩,执行如下命令:
docker pull learn/tutorial
docker run learn/tutorial /bin/echo hello world
############################################################
# Dockerfile to run JDK Containers
# Based on Ubuntu Image
############################################################
# Set the base image to use to Ubuntu
FROM ubuntu
# Set the file maintainer (your name - the file's author)
MAINTAINER gosling "[email protected]"
# Update package repository
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list
RUN apt-get update -y
# Install python tools (so you can do add-apt-repository)
RUN apt-get install -y -q python-software-properties software-properties-common
#Install Oracle jdk7
#RUN \
# echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
# add-apt-repository ppa:webupd8team/java -y && \
# apt-get update -y && \
# apt-get install oracle-java8-installer -y && \
# apt-get clean && \
# update-alternatives --display java && \
# echo "JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> /etc/environment
RUN \
add-apt-repository ppa:webupd8team/java -y && \
apt-get update -y && \
echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \
apt-get -y install oracle-java7-installer && \
apt-get clean && \
update-alternatives --display java && \
echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle" >> /etc/environment
WORKDIR /data
CMD ["bash"]
docker run -i -t -p 22222:33333 ubuntu /bin/bash
nc localhost 9999 < /etc/hosts
root 3024 1 0 09:17 ? 00:00:00 /usr/bin/docker -d
von 13101 12489 0 10:19 pts/25 00:00:00 grep --color=auto docker
root 3024 1 0 09:17 ? 00:00:00 /usr/bin/docker -d
von 13581 12489 0 10:48 pts/25 00:00:00 docker run -it --rm tomcat
von 13675 12771 0 10:50 pts/26 00:00:00 grep --color=auto docker
root 3024 1 0 09:17 ? 00:00:00 /usr/bin/docker -d
von 13968 12771 0 10:59 pts/26 00:00:00 docker run -p 9999:9999 vongosling/rocketmq
root 13978 3024 0 10:59 ? 00:00:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9999 -container-ip 172.17.0.4 -container-port 9999
root 13984 3024 0 10:59 ? 00:00:00 /bin/sh -c /var/docker/source/alibaba-rocketmq/bin/play.sh
root 14013 13984 0 10:59 ? 00:00:00 /bin/sh /var/docker/source/alibaba-rocketmq/bin/play.sh
root 14020 14014 0 10:59 ? 00:00:00 sh /var/docker/source/alibaba-rocketmq/bin/runserver.sh com.alibaba.rocketmq.namesrv.NamesrvStartup
root 14025 14018 0 10:59 ? 00:00:00 sh /var/docker/source/alibaba-rocketmq/bin/runbroker.sh com.alibaba.rocketmq.broker.BrokerStartup -n 172.17.0.4:9876
root 14026 14020 1 10:59 ? 00:00:01 /usr/lib/jvm/java-7-oracle/bin/java -server -Xms4g -Xmx4g -Xmn2g -XX:PermSize=128m -XX:MaxPermSize=320m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -verbose:gc -Xloggc:/root/rmq_srv_gc.log -XX:+PrintGCDetails -XX:-OmitStackTraceInFastThrow -Djava.ext.dirs=/var/docker/source/alibaba-rocketmq/bin/../lib -cp .:/var/docker/source/alibaba-rocketmq/bin/../conf: com.alibaba.rocketmq.namesrv.NamesrvStartup
root 14028 14025 8 10:59 ? 00:00:05 /usr/lib/jvm/java-7-oracle/bin/java -server -Xms4g -Xmx4g -Xmn2g -XX:PermSize=128m -XX:MaxPermSize=320m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -verbose:gc -Xloggc:/root/rmq_bk_gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-OmitStackTraceInFastThrow -Djava.ext.dirs=/var/docker/source/alibaba-rocketmq/bin/../lib -cp .:/var/docker/source/alibaba-rocketmq/bin/../conf: com.alibaba.rocketmq.broker.BrokerStartup -n 172.17.0.4:9876
von 14121 12278 0 11:00 pts/16 00:00:00 grep --color=auto docker
仔细观察一下,能看出什么端倪?没错,所有进程都是3024 docker进程的子进程,关于Docker进程间管理的原理,后续有机会会继续分析一下~
ifconfig eth0:1 10.0.0.11 netmask 255.255.255.0 up
docker run -p 10.0.0.10:5000:5000 -name container1
docker run -p 10.0.0.11:5000:5000 -name container2
docker0
bridge between the host's network and the containers. Docker tries to guess an IP range that does not conflict with your local network, but it's not omniscient
. Until 1558
is fixed, you're best bet is to set up your own bridge. If you already have a
docker0
bridge:
$ ip addr show dev docker0
5: docker0: mtu 1500 qdisc noqueue state DOWN
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 10.0.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
…
then you can just change it's address:
# ip addr del 10.0.42.1/16 dev docker0
# ip addr add 172.31.42.1/16 dev docker0
If the docker0
bridge doesn't already exist, you'll have to create it yourself:
# brctl addbr docker0
# ip addr add 172.31.0.1/16 dev docker0
# ip link set dev docker0 up
If you want to start over from scratch, you can stop docker and remove the bridge:
# /etc/init.d/docker stop
# ip link set dev docker0 down
# brctl delbr docker0
1. Docker中文指南, http://www.widuu.com/chinese_docker/installation/ubuntu.html
2. Docker从入门到实践, http://yeasy.gitbooks.io/docker_practice/
3. Dockerfile 最佳实践, https://docs.docker.com/articles/dockerfile_best-practices/
4. Ubuntu Docker安装, https://docs.docker.com/installation/ubuntulinux/#ubuntu-trusty-1404-lts-64-bit
5. Docker如何去掉sudo, https://docs.docker.com/installation/ubuntulinux/#giving-non-root-access
6. 操作系统虚拟化方案, http://en.wikipedia.org/wiki/Operating-system-level_virtualization
7. Docker源码分析, http://www.infoq.com/cn/articles/docker-source-code-analysis-part1
8. Docker技术预览, http://www.infoq.com/cn/articles/docker-core-technology-preview
9. Docker实践, http://dockerone.com/article/126
10. Docker 常用命令详解,https://docs.docker.com/reference/commandline/cli/
11. 理解Linux进程,http://tobegit3hub1.gitbooks.io/understanding-linux-processes/
12. 多IP与路由架设, http://linux.vbird.org/linux_server/0230router/0230router.php
13. 扩展, http://khornberg.github.io/articles/change-docker-ip/