docker for centos7
据官方所说,docker在新版本的ubuntu和centos7上表现更好,鉴于我们目前使用的系统是centos6.8,这次我们选择centos7作为docker的宿主系统.
安装
准备工作
删除原来的docker包,一般情况下不用,保险起见,最好按流程走一下
$ sudo yum -y remove docker docker-common container-selinux
删除docker的selinux 同上
$ sudo yum -y remove docker-selinux
开始安装了
使用yum 安装yum-utils
$ sudo yum install -y yum-utils
增加docker源
$ sudo yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
查看docker源是否可用
$ sudo yum-config-manager --enable docker-ce-edge
enable 为True就行
创建缓存
$ sudo yum makecache fast
使用yum安装
docker现在分为两个版本 EE(企业版) CE(社区版),这里我们选择CE版.
$ sudo yum install docker-ce
启动docker
$ sudo systemctl start docker
启动一个helloword
$ sudo docker run hello-world
这条命令会下载一个测试镜像,并启动一个容器,输出hello world 并退出,如果正常说明docker安装成功.
使用docker
使用国内源加速
由于众所周知的原因,国内使用docker的官方源会非常慢,有时候甚至不能连接,因此我们需要使用国内源加速,基于我对阿里相对好的印象,这里我们选择阿里云的docker加速,另外推荐的还有daoCloud的加速,据说也不错.
通过修改daemon配置文件/etc/docker/daemon.json来使用加速器:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ik8akj45.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
tips
导入导出镜像
导入导出镜像
# 导出
$ docker save images > lnmp.tar.gz
# 导入
$ docker load -qi lnmp.tar
docker 常用命令
引用一下一个前辈的总结,docker的命名主要分为以下几类
- 容器生命周期管理 — docker [run|start|stop|restart|kill|rm|pause|unpause]
- 容器操作运维 — docker [ps|inspect|top|attach|events|logs|wait|export|port]
- 容器rootfs命令 — docker [commit|cp|diff]
- 镜像仓库 — docker [login|pull|push|search]
- 本地镜像管理 — docker [images|rmi|tag|build|history|save|import]
- 其他命令 — docker [info|version]
下面具体说明下docker的基本命令
docker 镜像命令
$ sudo docker images 列出机器上的镜像
$ sudo docker search centos 所有镜像
$ sudo docker pull centos 拉取镜像
$ sudo docker history centos7 查看针对于一个镜像的历史操作
$ sudo docker pull dl.dockerpool.com:5000/mongo:latest 从私服拉取镜像
$ sudo docker inspect centos 获取镜像详细信息
$ sudo docker rmi centos 删除镜像 如果有使用这个镜像构建的容器,就不能删除,非要删除的话可以加上 -f 参数,不过 不建议这样操作.
$ sudo docker tag centos centos7 给镜像创建tag,细心的人可以看到镜像id是一致的,说明这还是一个镜像
$ sudo docker save images > lnmp.tar.gz 导出镜像
$ sudo docker load -qi lnmp.tar 导入镜像
# 推送镜像
$ docker push seanlook/mongo
$ docker push registry.tp-link.net:5000/mongo:2014-10-27
# 创建镜像 三种方式
1. 启动一个容器 并在其中进行修改等写入操作 退出 记住容器id 然后提交镜像
$ sudo docker commit -m "Add a test file" -a "I am nick" 容器id test
顺利的话会返回新创建的id信息
然后在本地查看镜像列表,就可以看到新的镜像了
2.使用本地模板导入 推荐下载openvz模板来创建
导入命令
$ cat centos-6.8-minimal.tar.gz |sudo docker import - centos:6.8
然后查看镜像列表,镜像已经存在了.
3. 使用dockerfile 构建镜像
容器命令
$ sudo docker rm 132b910b1ad6 删除容器
$ sudo docker start e86f7599efe9 启动一个容器
$ sudo docker create centos7 创建一个容器 默认是停止状态 可以使用上面的命令启动它
$ sudo docker run -ti 98d35105a391 /bin/echo "hehe" 启动一个容器,输出 hehe 然后退出
$ sudo docker run -ti 98d35105a391 /bin/bash 启动一个容器 -t 让命令分配一个伪终端 -i 让容器的标准输入保持打开
$ sudo docker run -d --name ugg centos7 /bin/bash -c "while true; do echo hello world; sleep 2; done" 后台启动一个名为ugg的docker容器 连入之后 会一直输出hello world 使用ctrl+p ctrl+q 退出到宿主机,Ctrl+C 退出输出
$ sudo docker attach e86f7599efe9 连接一个容器的终端 attach 在多个窗口同时attach一个容器的时候,所有窗口都会同步显示,其中一个窗口阻塞时,其它窗口也没有办法操作,因此推荐使用 exec
$ sudo docker exec -ti 6fdc63f3a4df /bin/bash 基本等同于attach 但是是真正独立的shell
$ sudo docker stop ugg 停止一个容器
$ sudo docker export rose > /tmp/rose.tar 导出一个容器
$ cat /tmp/rose.tar |sudo docker import /tmp/rose.tar rosex 导入一个容器为镜像,rosex为镜像名称
查看容器ip
$ sudo docker inspect homepage |grep "IPAddress" |head -1 |awk '{print $2}' |awk -F """ '{print $2}' # homepage是容器名称
执行完删除容器
在执行容器的时候加上 -- rm 参数 -- rm 和 -d 参数不能同时使用
容器的名称是唯一的,想创建一个名称已存在的容器,必须先删除已经存在那个容器
docker 容器重启IP会变,这个一定要注意,不然踩大坑.
docker 简单应用
实例一 使用docker运行一个静态网站
这个例子主要是可以让我们学会使用docker 映射端口
和如何创建一个支持ssh的容器
创建一个容器
# 这个不一定能用,下面有说明
$ sudo docker run -p 8100:8100 -p 2200:2200 -ti --name homepage centos7
连入容器
$ sudo docker exec -ti bfaedade67b9 /bin/bash
修改容器的root密码
# passwd root
安装ssh
# yum -y install openssh-server openssh-clients
安装nginx
# yum install nginx
nginx默认root在这里,嫌麻烦的直接可以在这里编辑或者把网站文件放这里
/usr/share/nginx/html
nginx 启动 8100端口 sshd启动 2200端口
修改ssh配置文件
$ vi /etc/ssh/sshd_config
RSAAuthentication yes #启用 RSA 认证
PubkeyAuthentication yes #启用公钥私钥配对认证方式
AuthorizedKeysFile .ssh/authorized_keys #公钥文件路径(和上面生成的文件同)
PermitRootLogin yes #root能使用ssh登录
这里提一个bug,就是sshd在容器中不能启动,这个的原因是因为dbus-daemon没能启动。其实systemctl并不是不可以使用。将你的CMD或者entrypoint设置为/usr/sbin/init即可。会自动将dbus等服务启动起来。
所以将上面的创建镜像命令改成
$ sudo docker run -d -p 8100:8100 -p 2200:2200 -ti --name homepage --privileged -ti -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup centos7 /sbin/init
不过这个又带来了另一个问题 agetty CPU占用率100% 参考:http://blog.chinaunix.net/uid-26212859-id-5759744.html
原因就是 "docker run"运行容器时使用了 "/sbin/init"和"--privileged"参数
使用/sbin/init启动容器并加上--privileged参数,相当于docker容器获得了宿主机的全权委托权限。这时docker容器内部的init与宿主机的init产生了混淆。
出于对安全的考虑,在启动容器时,docker容器里的系统只具有一些普通的linux权限,并不具有真正root用户的所有权限。而--privileged=true参数可以让docker容器具有linux root用户的所有权限。
为了解决这个问题,docker后来的版本中docker run增加了两个选项参数"--cap-add"和"--cap-drop"。
--cap-add : 获取default之外的linux的权限
--cap-drop: 放弃default linux权限
所以,在运行容器时,可以不用--privileged参数的尽量不用,用--cap-add参数替代。如果必须使用--privileged=true参数的,可以通过在宿主机和容器中执行以下命令将agetty关闭。
shell> systemctl stop getty@tty1.service
shell> systemctl mask getty@tty1.service
docker vim 中文乱码的解决方案
$ vim .vimrc
加入以下几行设置即可
set fileencodings=ucs-bom,utf-8,gbk,gb2312,cp936,gb18030,big5,latin-1
set encoding=utf-8
set termencoding=utf-8
set fileencoding=utf-8
这些搞完了,就可以看你的网站了.
实例二 使用docker实现lnmp站点搭建
通过这个实例可以学习到容器之间如何互联
还有如何在多台机器上部署lnmp环境
将上一个容器导出
$ sudo docker export homepage > /tmp/web.tar
把这个容器导入为一个镜像
$ cat /tmp/web.tar |sudo docker import /tmp/web.tar web
使用这个镜像启动一个容器
#这个容器里面启动的端口可能跟映射的不一样,可以进去改一下,这个容器启一个mysql服务
$ sudo docker run -d -p 8110:8110 -p 2210:2210 -p 3316:3316 -ti --name homepage01 --privileged -ti -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup web /sbin/init
再用这个镜像启动一个容器,这个容器需要php 和 需要连接数据库的代码
$ sudo docker run -d -p 8120:8120 -p 2220:2220 -p 3326:3326 -ti --name homepage02 --link homepage01:homepage01 --privileged -ti -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup web /sbin/init
连进homepage02容器,使用env 命令可以看到homepage02和homepage01的连接
$ sudo docker exec -ti homepage01 /bin/bash
$ env
ping homepage01 会解析为homepage01的IP
用户可以链接多个子容器到父容器,比如多个web连接到db容器上
这些做完后,你可以给homepage01装一个myql
# 端口号为映射的3316
$ yum install mariadb-server -y
# centos7 自带的是mariadb
# 启动 systemctl start mariadb.service
# 开机启动 systemctl enable mariadb.service
# 修改密码 mysql_secure_installation
mariadb的授权不太一样,搞了半天,老外套路太深...
$ create user root@'172.17.0.4' identified by '123456';
$ grant all privileges on *.* to root@'172.17.0.4';
在给homepage02 装上nginx 和php
# nginx 端口为映射的8120
$ yum install php php-fpm ninx
$ systemctl start nginx
$ systemctl start php-fpm
注意 连接MySQL要注意端口号.
需要安装PHP的MySQL扩展 php-mysql
完成之后启动服务,打开浏览器输入地址,就可以看到我们的PHP项目了.
Dockerfile
如果docker是原子弹的话,那么dockerfile就是核弹头,不使用dockerfile的话,docker永远只是玩具.
使用Dockerfile可以允许用户创建自定义的镜像
Dockerfile一般由一条条语句组成,并支持以 # 开头的注释行
一般来说Dockerfile分为四部分
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
下面是一个简单的例子,具体操作也可以参考这个
# 基于某个镜像
# FROME centos:tag 这样可以指定版本
FROM centos:6
# 将维护人员信息写到镜像中,当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。
MAINTAINER NGINX Docker Maintainers "colder219@163.com"
ENV NGINX_VERSION 1.10.1-1
# 构建指令,RUN可以运行任何被基础image支持的命令。
# 如基础image悬选择了Centos,那么软件管理部分只能使用Centos的命令。
# 该指令有两种格式
# RUN <command> (the command is run in a shell - `/bin/sh -c`)
# RUN ["executable", "param1", "param2" ... ] (exec form)
RUN yum install -y epel-release
RUN yum install -y nginx
RUN sed -i "s/80/8200/g" /etc/nginx/conf.d/default.conf
RUN chkconfig nginx on
CMD ["nginx", "-g", "daemon off;"]
EXPOSE 8200
开始构建
Dockerfile文件在/root目录下
$ sudo docker build -t dblue/centos-nginx /root
现在看看是不是多了个镜像
$ sudo docker images
使用这个镜像,启动一个服务
$ sudo docker run -d -p 8200:8200 -ti --name test000 -ti dblue/centos-nginx
打开浏览器输入: http://10.211.55.6:8200 看到下面的页面,说明就成功了.