Docker容器
1.1、Docker容器是什么

Docker容器运行起来本质上就是宿主机里面的一个进程。

1.2、容器的相关操作
操作作用
docker run创建、启动一个容器
docker start启动指定容器
docker restart重新启动指定容器
docker stop停止指定容器
docker ps查看容器的状态
docker cp容器和宿主之间复制文件
docker exec执行容器中的命令
docker attach进入容器中
docker rm删除指定容器
docker inspect查看指定容器的详细信息
docker logs查看容器的操作日志
1.3、进入容器的正确姿势

注意:最好不要进入容器进行操作,尤其是在生产环境中!

有时候, 我们只是想要频繁的使用UbuntuCentOS等容器,并且也不是生产环境, 那么进入容器去执行命令是个好主意!

进入容器的方式主要有四种:

  • 使用docker exec -it <containerName|containerId> /bin/bash
  • 使用docker attach <containerName|containerId>
  • 使用SSH
  • 使用nsenter
1.3.1、使用docker exec -it <containerName|containerId> /bin/bash进入容器

docker exec =>

1.3.2、使用docker attach <containerName|containerId>进入容器

docker attach =>

1.3.3、使用SSH进入容器

既然docker execdocker attach进入容器这两种方法不推荐使用, 相信大家第一个想到的就是SSH。在没有使用Docker之前, 我们就是用SSH进入服务器进行操作的。

很不幸,仍然是不建议使用SSH进入到容器。至于为什么不建议这么做,请参考下面这篇文章:

https://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker

中文翻译版本:

http://www.oschina.net/translate/why-you-dont-need-to-run-sshd-in-docker

建议你看原文,尤其是下面的帖子回复!非常精彩!

1.3.4、使用nsenter进入容器

参考

nsenterutil-linux中的一个小工具, 所以,要使用它,就先安装util-linux

安装完util-linux后,我们查看nsenter的使用帮助:

nsenter可以访问另一个进程的名称空间。而容器运行起来实际上就是宿主机器的一个进程。 所以为了进入某个容器我们还需要获取该容器的第一个进程的PID。 可以使用docker inspect命令来拿到该信息,如下:

sudo docker inspect -f {{.State.Pid}} ubuntu

这样,我们就可以使用nsenter命令访问该容器了:

sudo nsenter --target 3326 --mount --uts --ipc --net --pid

这么长的命令谁能记住呢?幸好有人帮我们做了简化工作,我们可以下载一个bash脚本.bashrc_docker,把它放到环境变量里面就可以使用了。

wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc

这个文件中定义了很多方便使用Docker的命令,例如docker-pid可以获取某个容器的PID; 而docker-enter可以进入容器或直接在容器内执行命令。

docker-pid <containerName|containerId>
docker-enter <containerName|containerId>
1.4、容器之间的通信

一个Docker容器就是一个宿主机上的进程!所以,一般一个容器就是一个应用,比如, 我们使用nginx + Tomcat + MySQL开发一个Java Web应用, 我们使用Docker容器应该如何部署呢?

假设我们的这个Java Web App的名字叫做app1,所以,我们在创建容器的时候, 给容器命名的时候,都以app1开头,这样我们就很容器看出容器是哪个app使用了。

当然,nginxTomcatMySQL这些软件都是可以被多个app同时使用的, 为了便于管理,我们就不共用了。

假设我们这里的nginx做负载均衡使用,MySQL使用了主从复制。

下面是app1的架构图:

我们需要创建5个Docker容器:

app1-mysql-master用作MySQL主服务器。

app1-mysql-slave用作MySQL从服务器。

app1-tomcat-load-1是第一个负载。它肯能访问app1-mysql-master容器, 也可能访问app1-mysql-slave容器。

app1-tomcat-load-2是第二个负载。它肯能访问app1-mysql-master容器, 也可能访问app1-mysql-slave容器。

app1-nginx是负载均衡调度器。 它只访问app1-tomcat-load-1app1-tomcat-load-2这两个容器。

1.4.1、link机制实现容器之间的通信

参考文档

很不幸,这种方式已经不建议使用了,被更好的方法取代了。官方为了兼容老版本, 这个特性仍然保留了,但是很可能在以后的某个版本被彻底废弃!

link原理图:

link的容器被称为received-container

link的容器被称为source-container

received-container容器可以访问source-container容器。

实现方式是通过docker run命令的--link <source-containerName|source-containerId:source-containerAlias>参数。

我们使用link机制实现一下这个例子:

1、创建app1-mysql-master容器:

sudo docker run -d -p 3306:3306 -v ~/app1/mysql/data/master:/usr/local/mysql/data --name app1-mysql-master mysql:5.6

2、创建app1-mysql-slave容器:

sudo docker run -d -p 3307:3306 -v ~/app1/mysql/data/slave:/usr/local/mysql/data --name app1-mysql-slave mysql:5.6

3、创建app1-tomcat-load-1容器:

sudo docker run -d -p 8080:8080 -v ~/app1/tomcat/load-1/log:/usr/local/tomcat/log --name app1-tomcat-load-1 --link app1-mysql-master:app1-mysql-master --link app1-mysql-slave:app1-mysql-slave tomcat:8

4、创建app1-tomcat-load-2容器:

sudo docker run -d -p 8081:8080 -v ~/app1/tomcat/load-2/log:/usr/local/tomcat/log --name app1-tomcat-load-2 --link app1-mysql-master:app1-mysql-master --link app1-mysql-slave:app1-mysql-slave tomcat:8

5、创建app1-nginx容器:

sudo docker run -d -p 80:80 -v ~/app1/nginx/conf:/usr/local/nginx/conf --name app1-nginx --link app1-tomcat-load-1:app1-tomcat-load-1 --link app1-tomcat-load-2:app1-tomcat-load-2 nginx:1.11
1.4.2、network机制实现容器之间的通信

参考文档