随着云计算的发展,一系列类似PaaS、SaaS、IaaS的词汇如春笋般萌生,迅速在这个互联网中滋长。比如,我们用到的云主机其实就是IaaS(基础设施即服务)的一种。这一类XaaS通常利用虚拟化(通常指Hypervisor那一类)达到对资源的充分利用。在对内核独立性要求不高的环境中,由于Linux Container技术的诞生,使得虚拟化共用宿主机达到了新的一种高度,CaaS(容器即服务)因此诞生,其中docker就是这类技术的应用。

请注意,下文介绍的可能涉及但并非以下事物

  • 云虚拟主机,虚拟主机,Web虚拟主机;
  • 弹性服务器,云主机,虚拟专用服务器(VPS)

敲黑板!记笔记时间!

目前的LXC使用下列内核功能来控制进程:

  • 内核命名空间(进程间通信、uts、mount、pid、network和user)
  • AppArmor和SELinux配置
  • Seccomp策略
  • chroot(使用pivot_root)
  • Kernel Capibilities
  • 控制组(cgroups)

——摘自维基百科词条“LXC”

这个意味着:

  • 所有容器和宿主机共用同一内核;
    (如果在Windows或macOS下,为共用虚拟Linux的内核。)
  • 各个容器可以拥有不同的系统文件。

所以,少去了Hypervisor层,容器的无需再启动自身内核,启动速度快(几秒内),内存占用少(有见过64MB内核搭WordPress的)。但是,万一一个容器触发了内核的bug,宿主机连同所有容器都会受到牵连。

安装docker注意事项

出门左转docker官网,点击“Get Docker”下的选项,选一个适用自己的版本。对于ubuntu,安装就是一个添加自定义源的过程,命令如下:

//请注意!!复制命令时请去掉前面代表普通用户的提示符“$”!!
$ sudo apt update
//更新软件源
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
//为软件源添加做准备
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
//添加gpg签名密钥
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
//添加软件源
//这里要求在amd64条件下跑,意味着你需要amd64架构的系统~
$ sudo apt update
//再更新软件源
$ sudo apt install docker-ce
//安装个免费纯天然的社区版~
  • 如果系统为macOS或Windows两个非Linux的系统,docker会调用系统的虚拟层(macOS为自带kvm;Windows为Hyper-V,需自行开启。)启动其“宿主机”。
  • 如果系统为Linux,docker会直接在本机内核运行,请保证为内核为2.6.32-431以上版本。

一般桌面版本docker安装后会在状态栏出现一条小鲸鱼:
点击即可查看状态和配置。

一般Linux版本安装为添加一个软件源并安装docker-ce软件包,由于不需要虚拟的宿主系统,下载大小明显会比桌面版本小。注意,如果想在非root环境中管理docker,需要执行以下命令把你的用户加入docker用户组。

$ sudo usermod -a -G docker <你的用户名>
$ sudo reboot

初试docker

安装好docker,做的第一步事情,或者就是跑一下hello-world,对,年轻人的第一句docker命令

$ docker run hello-world 
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
5b0f327be733: Pull complete 
Digest: sha256:07d5f7800dfe37b8c2196c7b1c524c33808ce2e0f74e7aa00e603295ca9a0972
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/


容器最大的特点就是,它内置了软件所需的运行环境,比如运行库、解释器等依赖条件,只要不涉及过多的内核操作,这种“容器”在“运输”后基本上一个命令就可以开始运行。

$ docker run [参数] <你要的程序名> [命令(可选)]

对,就如你所见那么优雅。按照docker官方对说法,比较“政治正确”的运行方法是:一个容器运行一个服务。比如,nginx运行一个容器,php-fpm运行一个,MySQL运行一个,redis同样是运行一个。这种叫做瘦容器,每个容器都有独立运行的主进程,管理方便,环境相互独立也比较安全。在这个时候,docker容器间和容器内外就要存在联系。其中,最常见的参数如下:

简写 参数 备注
 –name <容器名>  给一个容器起名。
 –expose <端口号>  暴露端口号,用于容器间通信。
 –link <别的容器名>  获得别的容器暴露的端口。
 -p  –publish <[绑定地址:]端口:容器端口>  将端口映射至容器外。
 -v  –volume <本机路径:容器路径>  将本机文件系统映射至容器内。

这里可以来个简单的栗子:

$ docker run --name ngx -p "80:80" nginx:stable-alpine

等到拉取好image的时候,如果你的80端口没有被占用,nginx就会在容器中运行,现在就可以打开你的浏览器,访问http://localhost/ 这个链接,就可以看到熟悉的nginx测试页面。

多docker容器连接运行WordPress

按下^C,关闭现在的容器,执行下面的命令删除这个容器,同时释放80端口的映射关系。

$ docker rm ngx

这时候需要一个大杀器,叫做Docker Compose,Ubuntu下需用apt命令单独安装:

$ sudo apt install docker-compose

这个Docker Compose大杀器工作起来很粗暴,其实就是根据当前文件夹下的docker-compose.yml文件来创建一系列的容器,从而实现协作。这里给出的文件实例是:

nginx:
    restart: always
    image: nginx:stable-alpine
    ports:
        - "80:80"
        #- "443:443"
    volumes:
        - $PWD/html:/www
        - $PWD/nginx/nginx.conf:/etc/nginx/nginx.conf
        - $PWD/nginx/conf.d:/etc/nginx/conf.d
    links: 
        - phpfpm

phpfpm:
    restart: always
    build: $PWD/docker/php
    volumes:
        - $PWD/html:/www
    expose: 
        - 9000
    links: 
        - mysql
        - redis

    
mysql:
    restart: always
    image: mysql:latest
    volumes:
        - $PWD/mysql:/var/lib/mysql
    ports: 
        - "127.0.0.1:3306:3306"
    expose: 
        - 3306
    environment: 
        - MYSQL_ROOT_PASSWORD=alphaxz

redis:
    restart: always
    image: redis:alpine
    expose: 
        - 6379

其中restart:always代表容器崩溃了会自动重新启动,$PWD代表当前目录。最最特别的一项就是在php-fpm中的build: $PWD/docker/php,因为原本的php-fpm镜像不包含mysqli和PECL Redis插件,需要在其中的docker/php文件夹下放置一个Dockerfile,用以构建自定义的一个镜像,内容如下:

FROM php:fpm-alpine

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
&& apk add --no-cache $PHPIZE_DEPS \
&& pecl install -o -f redis \
&& docker-php-ext-install mysqli \
&& rm -rf /tmp/pear \
&& docker-php-ext-enable redis \
&& apk del $PHPIZE_DEPS

这里代表在php:fpm-alpine基础上依次操作了:

  1. 更改软件源为中国科大源;
  2. 安装扩展编译依赖条件;
  3. 新增PECL Redis插件;
  4. 新增mysqli插件;
  5. 删除编译临时文件;
  6. 启用PECL Redis插件;
  7. 删除依赖;
  8. 收工保存!

这个文件会引导Docker Compose在运行时创建我们要的有Redis和mysqli的镜像。需要的文件可以在这里下载,而拿到文件的我们,只需要在文件夹内简单地运行一下:

$ docker-compose up -d

事情都会好起来的~
在玩耍之前,我们需要下载一个WordPress博客解压在html文件夹内,此外,我们需要初始化一下数据库:

$ docker exec -it 上面提示的MySQL容器名 /bin/bash
# mysql -p
输入密码“alphaxz”进入:
create database wordpress;
exit;
然后输入这个退出MySQL的shell
# exit

随后就可以打开浏览器,访问http://localhost/ 开始WordPress的安装啦。其中数据库的地址为mysql,用户名是root,密码为alphaxz(由于docker-compose.yml的定义)。


然后就是熟悉的WordPress安装哦,这个应该很简单,就不再阐述了哦。

停止也只需要简单地运行一下:

$ docker-compose down

提示需要FTP权限时处理方法

设置里面html文件夹群组为docker,然后给予群组读写执行权限,重启下容器。

$ chown -R <你的用户名>:docker ./html
$ chmod -R 770 ./html
$ docker-compose restart

未完待续,还要忙学生会之星,就先和docker“初见”到这里啦。

alphaxz@SCUT
19 Oct, 2017