如何在Docker容器里创建Apache Web服务

作为Linux系统管理员,或多或少都有可能听说过Docker。因为这款软件可以有效降低运营成本,提升系统部署速度,让系统管理工作变得十分轻松。

但这一切也不是变魔术,Docker只是一个容器管理平台,可以跨平台运行各种应用软件及相应工具容器的平台。换句话说,容器化的软件可以在不同系统平台直接运行而不需要任何修改,而由运行在不同系统的Docker来管理容器软件的运行。另外,同虚拟机相比,创建、停止和维护这些容器都相对容易得多,如果想仔细了解Docker同虚拟机之间的差异,可以访问Docker官方网站进行了解。

本文将实例演示如何在CentOS 7系统和Ubuntu 16.04系统安装Docker,并从Docker Hub获得 Apache 2.4容器。之后,我们还会演示如何利用Aapache容器来充当一个Web服务器,显示网页内容,而我们的主机是不需要安装任何Web服务器的。

1. CentOS 和 Ubuntu安装 Docker

安装Docker比较简单,只需要使用如下命令,无论是CentOS系统还是Ubuntu系统都可以执行。该命令实际上执行一个Docker的安装脚本,该脚本会自动将Docker软件库添加到系统,然后安装相应的软件包。

# curl -fsSL https://get.docker.com | sh

如果运行这条命令系统没有反应,也可以直接访问https://get.docker.com将脚本下载下来,然后保存成”.sh”文件在系统里执行,实在不会的话,可以 点击这里 下载安装脚本。安装完成后会看到提示建议使用”docker”用户来执行程序,测试的话不太需要,实际生产环境建议使用非root用户,增加系统安全性。

安装完成后,可以使用如下命令启动docker:

# systemctl start docker
# systemctl status docker

未分类

如果看到如图所示的内容,就表示Docker已经安装成功,并且服务已经启动。使用Docker只需要运行如下命令:

# docker

想要查看特定命令的帮助信息,则使用以下命令:

# docker COMMAND --help

例如想查看Docker的版本信息,则使用以下命令:

# docker version --help
# docker version

执行结果如下图所示:

未分类

2. 创建Apache容器

Docker生态系统最吸引人的地方在于你可以任意下载并使用数以万计的已有容器。接下来,我们将创建一个名为”Rultr-web”的Apache 2.4容器,这个容器将脱离于当前终端独立运行。为实现此功能,我们需要从Docker Hub下载一个apache 2.4的镜像文件。

假设我们将VPS的8080端口重定向到容器的80端口,另外,我们不想从容器中提供web页面,而是使用”/home/user/website”作为容器中Apache的文件目录。想要实现该功能,就需要将”/home/user/website”这个VPS实际目录映射到容器中的”/usr/local/apache2/htdocs/”目录,同时注意执行以下命令时需要具有root用户权限,需要的话适当使用sudo:

# docker run -dit --name Rultr-web -p 8080:80 -v /home/user/website/:/usr/local/apache2/htdocs/ httpd:2.4

未分类

现在,可以查看一下容器的状态,理论上Apache容器已经运行起来了:

# docker ps

未分类

接着要做的就是在系统的”/home/user/website”目录里创建页面文件,以验证容器中的Apache服务器启动成功,并且目录映射正确。

# vi /home/user/website/docker.html

简单起见,”docker.html”文件只有如下内容:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Learn Docker at rultr.com</title>
</head>
<body>
<h1>Learn Docker With Us</h1> 
</body>
</html>

然后,就可以通过浏览器访问VPS的IP地址来访问”docker.html”文件了,还记得我们是将容器的80端口映射到VPS的8080端口了么,所以,访问的地址应该形如”AAA.BBB.CCC.DDD:8080/docker.html”,成功的话就可以见到如下内容:

未分类

之后就是一些操作容器的命令,可以进行容器的停止、删除以及删除容器镜像等。

# docker stop Rultr-web          //停止容器
# docker remove Rultr-web        //删除容器
# docker image remove httpd:2.4  //删除镜像

本文只是简单介绍如何安装Docker和使用容器实例,如果想深入了解Docker的使用,则请访问官方网站学习。

docker 容器搭建 lnmp 环境小记

1.阿里云容器地址

https://cr.console.aliyun.com

2.创建镜像仓库

3.虚拟机修改docker源

修改文件:/etc/docker/daemon.json

内容:

{
"registry-mirrors": ["https://78zjyej0.mirror.aliyuncs.com"]
}

4.虚拟机登录仓库账号

docker login --username= registry.cn-shenzhen.aliyuncs.com

输入账号密码,账号为阿里云账号,密码是在仓库那里另外设置的密码
有时login会出现这个问题: x509: certificate has expired or is not yet valid

这个问题是由于虚机的系统时间没有校正导致的,使用date命令查看时间是否为本地时间 ,使用命令 ntpdate cn.pool.ntp.org 校正时间,如果提示命令不存在,使用命令安装 yum instal ntp ,再使用 date 命令进行查看,确保时间为本地时间,最后重新使用 docker login 命令,输入密码即可。

5.拉取php镜像

docker pull php:7.2-fpm

尝试过很多php镜像,发现还是这个好用一点,配置文件分割清析在 /usr/local/etc 下面,php相关命令较全,在 /usr/local/bin 下可以看到很多命令,包括 phpize php-config 等等,而且改配置立即生效。

6.xdebug扩展

使用镜像开启一个容器 docker run -itd --name php php:7.2-fpm ,进入容器 docker exec -it php bash ,
使用 php -m 命令可看相关模块,笔者自己安装了 xdebug 扩展,使用命令 php -i > phpinfo.txt 获取到环境信息,复制文件里的内容到这个网址获取对应版本的 xdebug https://xdebug.org/wizard.php
,文件是下载到宿主机的,要拷贝文件到docker容器中, docker cp filename containerid:target_file_path ,到容器中解压文件并进入目录

/usr/local/bin/phpize 
./configure --with-php-config=/usr/local/bin/php-config
make && make install

安装完成,添加配置,在目录 /usr/local/etc/php/conf.d 下添加xdebug.ini文件,内容为

;zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20170718/xdebug.so

;xdebug.remote_enable=1
;xdebug.idekey="PHPSTORM"
;xdebug.remote_connect_back=1
;xdebug.remote_port=9900
;xdebug.remote_log="/tmp/xdebug_log/"

使用的时间把”;”删除,使用xdebug生效, php -m 查看安装模块是否有xdebug。如果要安装其他模块,安装命令和配置添加类似,可以下载相应的php安装源码cp到虚拟机安装所需的扩展。(笔者曾经试过自己安装在一个centos容器中安装php环境,跑到最后达到了1.5G,最重要的是fileinfo这个扩展安装不了,提示内存不足,在网上找了很多方法都不行,最后放弃了,直接找现成的php容器)

7.提交镜像

回到宿主机,为保留刚才做的修改,所以重新创建一个镜像 git commit -m 'update php image' songzw/php-fpm:v1 ,此时使用 git images 可以看到多了一个 songzw/php-fpm:v2 镜像

8.提交镜像到阿里仓库

docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/songzw/php:[镜像版本号] 把仓库修改到阿里, docker push registry.cn-shenzhen.aliyuncs.com/songzw/php:[镜像版本号] 完成推送。

9.在php容器中需要安装composer才能安装扩展包,使用composer命令时要用到git,zip,unzip命令,所以要先 apt-get update , apt-get install git zip upzip ,重新构建镜像。

10.docker-compose构建nginx

./nginx/Dockerfile

from nginx
COPY ./*.conf /etc/nginx/conf.d/
run mkdir -p /var/nginx/logs/access /var/nginx/logs/error && chmod -R 777 /var/nginx
CMD nginx

nginx如果本地没有,则会先从远程仓库中拉取,将本地的conf配置文件拷贝到容器,在容器中创建目录并且授权,这个不是必须的,因为我本地的conf文件里配置的日志文件和错误文件是在这个目录,所有本地也要先有这个目录,如果容器起不来,使用docker logs containerid来查看日志,有可能是这个目录问题导致的,最后以nginx进程来运行容器,这个放到docker-compose里面没有生效,导致容器起不来。

11.docker-compose构建mysql

./mysql/Dockerfile

from mysql:5.6
COPY ./*.cnf /etc/mysql/mysql.conf.d/

需要在mysql目录下 touch my.cnf ,里面内容为自定义配置,可以为空,mysql:5.6镜像如果本地不存在也是从远程拉取。

12.docker-compose构建php

from songzw/php-fpm:v5
COPY *.conf /usr/local/etc/php-fpm.d/
COPY *.ini /usr/local/etc/php/conf.d/
run chown -R www-data.www-data /var/www

其中songzw/php-fpm:v5是笔者从php:7.2-fpm拉取下来进行重新构建的镜像,要创建文件 touch my.conftouch my.ini ,这样可以添加自定义配置,/var/www修改属主是因为会出现缓存文件的写权限问题

13.docker-compose.yml

最后呈现docker-compose.yml文件内容

mysql:
  build: ./mysql/
  volumes:
   - /var/mysql/data:/var/lib/mysql
   - /var/mysql/logs:/var/log/mysql
  expose:
   - "3306"
  ports:
   - 3306:3306
  env_file:
   - ./env

 php:
  build: ./php/
  volumes:
   - /var/www/html:/var/www/html
  expose:
   - "9000"
  links:
   - mysql
  command: php-fpm

 nginx:
  build: ./nginx
  volumes_from:
   - php
  volumes:
   - /var/nginx:/var/nginx
  links:
   - php
  ports:
   - "80:80"

使用 docker-compose up -ddocker-compose down 便可以搭建和销毁环境,其中nginx的配置文件在配置连接php时使用php容器ip或者 fastcgi_pass php:9000 ;,php代码连接mysql数据库时使用mysql容器ip或者别名mysql,即links对应的别名。

8 个基本的 Docker 容器管理命令

利用这 8 个命令可以学习 Docker 容器的基本管理方式。这是一个为 Docker 初学者准备的,带有示范命令输出的指南。

在这篇文章中,我们将带你学习 8 个基本的 Docker 容器命令,它们操控着 Docker 容器的基本活动,例如 运行run、 列举list、 停止stop、 查看历史纪录logs、 删除delete 等等。如果你对 Docker 的概念很陌生,推荐你看看我们的 介绍指南,来了解 Docker 的基本内容以及 如何 在 Linux 上安装 Docker。 现在让我们赶快进入要了解的命令:

如何运行 Docker 容器?

众所周知,Docker 容器只是一个运行于宿主操作系统host OS上的应用进程,所以你需要一个镜像来运行它。Docker 镜像以进程的方式运行时就叫做 Docker 容器。你可以加载本地 Docker 镜像,也可以从 Docker Hub 上下载。Docker Hub 是一个提供公有和私有镜像来进行拉取pull操作的集中仓库。官方的 Docker Hub 位于 hub.docker.com。 当你指示 Docker 引擎运行容器时,它会首先搜索本地镜像,如果没有找到,它会从 Docker Hub 上拉取相应的镜像。

让我们运行一个 Apache web 服务器的 Docker 镜像,比如 httpd 进程。你需要运行 docker container run 命令。旧的命令为 docker run, 但后来 Docker 添加了子命令部分,所以新版本支持下列命令:

root@kerneltalks # docker container run -d -p 80:80 httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
3d77ce4481b1: Pull complete
73674f4d9403: Pull complete
d266646f40bd: Pull complete
ce7b0dda0c9f: Pull complete
01729050d692: Pull complete
014246127c67: Pull complete
7cd2e04cf570: Pull complete
Digest: sha256:f4610c3a1a7da35072870625733fd0384515f7e912c6223d4a48c6eb749a8617
Status: Downloaded newer image for httpd:latest
c46f2e9e4690f5c28ee7ad508559ceee0160ac3e2b1688a61561ce9f7d99d682

Docker 的 run 命令将镜像名作为强制参数,另外还有很多可选参数。常用的参数有:

  • -d:从当前 shell 脱离容器
  • -p X:Y:绑定容器的端口 Y 到宿主机的端口 X
  • –name:命名你的容器。如果未指定,它将被赋予随机生成的名字
  • -e:当启动容器时传递环境编辑及其值

通过以上输出你可以看到,我们将 httpd 作为镜像名来运行容器。接着,本地镜像没有找到,Docker 引擎从 Docker Hub 拉取了它。注意,它下载了镜像 httpd:latest, 其中 : 后面跟着版本号。如果你需要运行特定版本的容器,你可以在镜像名后面注明版本名。如果不提供版本名,Docker 引擎会自动拉取最新的版本。

输出的最后一行显示了你新运行的 httpd 容器的唯一 ID。

如何列出所有运行中的 Docker 容器?

现在,你的容器已经运行起来了,你可能想要确认这一点,或者你想要列出你的机器上运行的所有容器。你可以使用 docker container ls 命令。在旧的 Docker 版本中,对应的命令为 docker ps。

root@kerneltalks # docker container ls
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
c46f2e9e4690        httpd               "httpd-foreground"   11 minutes ago      Up 11 minutes       0.0.0.0:80->80/tcp   cranky_cori

列出的结果是按列显示的。每一列的值分别为:

  • Container ID :一开始的几个字符对应你的容器的唯一 ID
  • Image :你运行容器的镜像名
  • Command :容器启动后运行的命令
  • Created :创建时间
  • Status :容器当前状态
  • Ports :与宿主端口相连接的端口信息
  • Names :容器名(如果你没有命名你的容器,那么会随机创建)

如何查看 Docker 容器的历史纪录?

在第一步我们使用了 -d 参数来将容器,在它一开始运行的时候,就从当前的 shell 中脱离出来。在这种情况下,我们不知道容器里面发生了什么。所以为了查看容器的历史纪录,Docker 提供了 logs 命令。它采用容器名称或 ID 作为参数。

root@kerneltalks # docker container logs cranky_cori
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Thu May 31 18:35:07.301158 2018] [mpm_event:notice] [pid 1:tid 139734285989760] AH00489: Apache/2.4.33 (Unix) configured -- resuming normal operations
[Thu May 31 18:35:07.305153 2018] [core:notice] [pid 1:tid 139734285989760] AH00094: Command line: 'httpd -D FOREGROUND'

这里我使用了容器名称作为参数。你可以看到在我们的 httpd 容器中与 Apache 相关的历史纪录。

如何确定 Docker 容器的进程?

容器是一个使用宿主资源来运行的进程。这样,你可以在宿主系统的进程表中定位容器的进程。让我们在宿主系统上确定容器进程。

Docker 使用著名的 top 命令作为子命令的名称,来查看容器产生的进程。它采用容器的名称或 ID 作为参数。在旧版本的 Docker 中,只可运行 docker top 命令。在新版本中,docker topdocker container top 命令都可以生效。

root@kerneltalks # docker container top  cranky_cori
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                15702               15690               0                   18:35               ?                   00:00:00            httpd -DFOREGROUND
bin                 15729               15702               0                   18:35               ?                   00:00:00            httpd -DFOREGROUND
bin                 15730               15702               0                   18:35               ?                   00:00:00            httpd -DFOREGROUND
bin                 15731               15702               0                   18:35               ?                   00:00:00            httpd -DFOREGROUND
root@kerneltalks # ps -ef |grep -i 15702
root     15702 15690  0 18:35 ?        00:00:00 httpd -DFOREGROUND
bin      15729 15702  0 18:35 ?        00:00:00 httpd -DFOREGROUND
bin      15730 15702  0 18:35 ?        00:00:00 httpd -DFOREGROUND
bin      15731 15702  0 18:35 ?        00:00:00 httpd -DFOREGROUND
root     15993 15957  0 18:59 pts/0    00:00:00 grep --color=auto -i 15702

在第一个输出中,列出了容器产生的进程的列表。它包含了所有细节,包括用户号uid、进程号pid,父进程号ppid、开始时间、命令,等等。这里所有的进程号你都可以在宿主的进程表里搜索到。这就是我们在第二个命令里做得。这证明了容器确实是宿主系统中的进程。

如何停止 Docker 容器?

只需要 stop 命令!同样,它采用容器名称或 ID 作为参数。

root@kerneltalks # docker container stop cranky_cori
cranky_cori

如何列出停止的或不活动的 Docker 容器?

现在我们停止了我们的容器,这时如果我们使用 ls 命令,它将不会出现在列表中。

root@kerneltalks # docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

所以,在这种情况下,如果想要查看停止的或不活动的容器,你需要在 ls 命令里同时使用 -a 参数。

root@kerneltalks # docker container ls -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                     PORTS               NAMES
c46f2e9e4690        httpd               "httpd-foreground"   33 minutes ago      Exited (0) 2 minutes ago                       cranky_cori

有了 -a 参数,现在我们可以查看已停止的容器。注意这些容器的状态被标注为 已退出exited。既然容器只是一个进程,那么用“退出”比“停止”更合适!

如何(重新)启动 Docker 容器?

现在,我们来启动这个已停止的容器。这和运行一个容器有所区别。当你运行一个容器时,你将启动一个全新的容器。当你启动一个容器时,你将开始一个已经停止并保存了当时运行状态的容器。它将以停止时的状态重新开始运行。

root@kerneltalks #  docker container start c46f2e9e4690
c46f2e9e4690
root@kerneltalks # docker container ls -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
c46f2e9e4690        httpd               "httpd-foreground"   35 minutes ago      Up 8 seconds        0.0.0.0:80->80/tcp   cranky_cori

如何移除 Docker 容器?

我们使用 rm 命令来移除容器。你不可以移除运行中的容器。移除之前需要先停止容器。你可以使用 -f 参数搭配 rm 命令来强制移除容器,但并不推荐这么做。

root@kerneltalks # docker container rm cranky_cori
cranky_cori
root@kerneltalks # docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

你看,一旦移除了容器,即使再使用 ls -a 命令也查看不到容器了。

使用docker搭建gitlab初体验+数据备份

一. 背景

作为程序员,像GitHub这种好工具是必须得十分了解的,但是有时GitHub并不能满足我们所有的需求,就如作者所在的公司,我们的代码都是商业性的产品,不可能放到GitHub的开放仓库中的,而申请GitHub私人仓库需要钱。这就陷入了尴尬的局面,那有没有一种既能具有GitHub一样的功能,又能保护隐私免费的管理工具呢?答案是肯定的,感谢程序员伟大的开源精神,我们有了GitLab!!!今天笔者在这里就跟大家分享一下自己使用docker搭建GitLab的过程吧,这其中踩了一些坑,希望看过这篇文章的人不用在踩我踩过的坑了!

二. 环境介绍

服务器信息:

CPU : 2
DISK : 30G
RAM : 4G
OS : Linux centos7-0 3.10.0-229.el7.x86_64

这里笔者使用的是自己公司的服务器,也可以使用虚拟机进行搭建

三. 搭建过程

1. 安装docker

因为我们是使用docker搭建的,所以需要先安装docker,docker支持不同的OS,具体的安装信息这里不做详细介绍,可以自己的操作系统,参考官方的安装指南进行安装。http://www.docker.io

2. 安装GitLab及相关组件

GitLab需要用到数据库来存储相关数据,所以需要在安装GitLab的同时安装数据库,这里使用的是postgresql和redis。我在查找相关的镜像,之后发现有很多现成的镜像,这里我使用的sameersbn镜像。但是有一点我认为不是很好的是:这个镜像没有把redis、postgresql集成到gitlab的容器里面,需要先单独pull这两个镜像run一下,然后再pull gitlab的镜像进行安装。

使用如下命令分别拉取最新的镜像:

docker pull sameersbn/redis
docker pull sameersbn/postgresql
docker pull sameersbn/gitlab

这里有第一个坑:因为我们默认都是从docker的官方仓库中拉去镜像,但是由于国内访问国外的网站有墙,而且速度也是十分的慢,所以需要代理。这里推荐Daocloud加速器 https://www.daocloud.io/ 免费使用,但是需要先注册,登录成功后,找到加速器执行相关命令即可。笔者亲测速度明显快很多!

使用如下命令运行postgresql镜像:

docker run --name postgresql -d   
-e 'DB_NAME=gitlabhq_production'   
-e 'DB_USER=gitlab' 
-e 'DB_PASS=password'   
-e 'DB_EXTENSION=pg_trgm'   
-v /home/root/opt/postgresql/data:/var/lib/postgresql   
sameersbn/postgresql

这里需要解释的是:

(1). 以上是一条命令,反斜杠是为了在命令内换行方便阅读,如果不喜欢,也可以写在一行。
(2). -e后面跟的都是容器的环境参数,都是在制作镜像的时候指定好的,所以不要去改动。
(3). -v后面是添加数据卷,这样在容器退出的时候数据就不会丢失,其中 /home/root/opt/postgresql/data是作者自己创建的文件夹,读者可以自己自定义,后面的部分是容器内的文件路径,需要保持不变。
(4). 命令执行成功之后会在控制台显示一串容器的编号,可以使用命令docker ps查看刚刚启动的容器。

使用如下命令运行redis镜像:

docker run --name redis -d   
-v /home/root/opt/redis/data:/var/lib/redis   
sameersbn/redis

这里跟启动postgresql一样。

使用如下命令运行GitLab镜像:

docker run --name gitlab -d 
--link postgresql:postgresql --link redis:redisio 
-p 10022:22 -p 10080:80 
-e 'GITLAB_PORT=10080' 
-e 'GITLAB_SSH_PORT=10022' 
-e 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string'
-e 'GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string' 
-e 'GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string'
-e 'GITLAB_HOST=服务器地址' 
-e 'GITLAB_EMAIL=邮箱地址' 
-e 'SMTP_ENABLED=true' 
-e 'SMTP_DOMAIN=www.sina.com' 
-e 'SMTP_HOST=smtp.sina.com'  
-e 'SMTP_STARTTLS=false'  
-e 'SMTP_USER=邮箱地址' 
-e 'SMTP_PASS=邮箱密码' 
-e 'SMTP_AUTHENTICATION=login' 
-e 'GITLAB_BACKUP_SCHEDULE=daily' 
-e 'GITLAB_BACKUP_TIME=10:30' 
-v /home/root/opt/gitlab/data:/home/git/data 
sameersbn/gitlab

这里需要解释的是:

(1). 网上又很多教程讲关于使用docker安装GitLab,但是讲的不全面,至少我按照他们的方法安装时不能正常运行,这里是第三个坑:一定要加上如下环境参数:

-e 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string'
-e 'GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string' 
-e 'GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string'

有关于这三个环境参数的含义:

未分类

我个人的理解是用来进行加密的key。

(2). 上面有关SMTP的环境参数是配置邮箱的,需要填上对应的邮箱信息,我使用的是新浪邮箱,读者可以根据自己的邮箱进行填写。

(3). 使用GitLab需要两个端口,一个是web端口,一个是SSH端口用于push代码的所以一下代码进行端口映射和指定:

-p 10022:22 -p 10080:80 
-e 'GITLAB_PORT=10080' 
-e 'GITLAB_SSH_PORT=10022' 

(4). GitLab有自带的备份,这里可以通过如下进行配置:

-e 'GITLAB_BACKUP_SCHEDULE=daily' 
-e 'GITLAB_BACKUP_TIME=10:30' 

指定的是每天10:30进行备份。

说到这里基本上GitLab就搭建好了,这里还有一个小坑就是:运行这些容器的时候可以把代码写进shell脚本中,然后通过脚本进行运行,不然直接在终端打的话很麻烦。

一下就是笔者安装完后的截图,直接访问:http://服务器地址:10080 即可,首次访问可能会出现错误页面,刷新几下页面就可以了然后在修改密码默认用户名:root 之后就可以正常使用。

未分类

未分类

未分类

四. 备份

我们可以使用GitLab自带的备份功能,在启动容器的时候就进行设置,然后再使用GitLab的 app:rake gitlab:backup:restore命令进行恢复,这里网上的教程都有说明可以参考以下网站:
sameersbn的GitHub wiki:
https://github.com/sameersbn/docker-gitlab#automated-backups
这个是官方的所以比较全面,里面还有关于各种环境参数的介绍。

这里作者使用的是如下的备份方法:
因为我们在运行postgresql、redis和GitLab的时候都使用了本地的文件夹进行了数据的持久化,而且我们实际需要备份的数据都在本地了,那么其实就可以直接使用rsync命令备份本地的这些卷(刚刚的文件夹)即可,无需再去深入到GitLab内部。如果搭建的GitLab崩溃了,或者服务器崩溃了,直接再使用docker再搭一个,在把刚刚的卷跟对应的postgresql、redis和GitLab内的数据文件夹进行映射即可。这是也不需要修改之前的启动命令,十分的方便而且作者自己测试过,发现能够达到要求,原先的仓库、用户的SSH信息等都在。

在 GitLab CI 中使用 Docker 构建 Go 项目

介绍

这篇文章是我在 CI 环境(特别是在 Gitlab 中)的 Docker 容器中构建 Go 项目的研究总结。我发现很难解决私有依赖问题(来自 Node/.NET 背景),因此这是我写这篇文章的主要原因。如果 Docker 镜像上存在任何问题或提交请求,请随时与我们联系。

dep

由于 dep 是现在管理 Go 依赖关系的最佳选择,因此在构建前之前运行 dep ensure。

注意:我个人不会将我的 vendor/ 文件夹提交到源码控制,如果你这样做,我不确定这个步骤是否可以跳过。

使用 Docker 构建的最好方法是使用 dep ensure -vendor-only。 见这里。

Docker 构建镜像

我第一次尝试使用 golang:1.10,但这个镜像没有:

  • curl
  • git
  • make
  • dep
  • golint

我已经创建好了用于构建的镜像(github / dockerhub),我会保持更新,但我不提供任何担保,因此你应该创建并管理自己的 Dockerhub。

内部依赖关系

我们完全有能力创建一个有公共依赖关系的项目。但是如果你的项目依赖于另一个私人 Gitlab 仓库呢?

在本地运行 dep ensure 应该可以和你的 git 设置一起工作,但是一旦在 CI 上不适用,构建就会失败。

Gitlab 权限模型

这是在 Gitlab 8.12 中添加的,这个我们最关心的有用的功能是在构建期提供的 CI_JOB_TOKEN 环境变量。

这基本上意味着我们可以像这样克隆依赖仓库:

git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/myuser/mydependentrepo

然而,我们希望使这更友好一点,因为 dep 在试图拉取代码时不会奇迹般地添加凭据。

我们将把这一行添加到 .gitlab-ci.yml 的 before_script 部分。

before_script:
  - echo -e "machine gitlab.comnlogin gitlab-ci-tokennpassword ${CI_JOB_TOKEN}" > ~/.netrc

使用 .netrc 文件可以指定哪个凭证用于哪个服务器。这种方法可以避免每次从 Git 中拉取(或推送)时输入用户名和密码。密码以明文形式存储,因此你不应在自己的计算机上执行此操作。这实际用于 Git 在背后使用 cURL。 在这里阅读更多。

项目文件

Makefile

虽然这是可选的,但我发现它使事情变得更容易。

配置这些步骤意味着在 CI 脚本(和本地)中,我们可以运行 make lint、make build 等,而无需每次重复步骤。

GOFILES = $(shell find . -name '*.go' -not -path './vendor/*')
GOPACKAGES = $(shell go list ./...  | grep -v /vendor/)

default: build

workdir:
    mkdir -p workdir

build: workdir/scraper

workdir/scraper: $(GOFILES)
    GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o workdir/scraper .

test: test-all

test-all:
    @go test -v $(GOPACKAGES)

lint: lint-all

lint-all:
    @golint -set_exit_status $(GOPACKAGES)

.gitlab-ci.yml

这是 Gitlab CI 魔术发生的地方。你可能想使用自己的镜像。

image: sjdweb/go-docker-build:1.10

stages:
  - test
  - build

before_script:
  - cd $GOPATH/src
  - mkdir -p gitlab.com/$CI_PROJECT_NAMESPACE
  - cd gitlab.com/$CI_PROJECT_NAMESPACE
  - ln -s $CI_PROJECT_DIR
  - cd $CI_PROJECT_NAME
  - echo -e "machine gitlab.comnlogin gitlab-ci-tokennpassword ${CI_JOB_TOKEN}" > ~/.netrc
  - dep ensure -vendor-only

lint_code:
  stage: test
  script:
    - make lint

unit_tests:
  stage: test
  script:
    - make test

build:
  stage: build
  script:
    - make

缺少了什么

我通常会用我的二进制文件构建 Docker 镜像,并将其推送到 Gitlab 容器注册库中。

你可以看到我正在构建二进制文件并退出,你至少需要将该二进制文件(例如生成文件)存储在某处。

docker部署logstash

logstash

使用ElasticSearch,需要将MySQL内的数据同步到ElasticSearch中去。根据网上文章,觉得logstash属于比较好的同步工具。

不想被logstash环境的搭建与配置困扰。使用docker制作一个镜像,然后可以做到到处运行

Dockerfile

基础镜像:

选择的是dockerhub的logstash。文档地址logstash

镜像文件:

FROM logstash:5

#安装input插件
RUN logstash-plugin install logstash-input-jdbc
#安装output插件
RUN logstash-plugin install logstash-output-elasticsearch
#容器启动时执行的命令.(CMD 能够被 docker run 后面跟的命令行参数替换)
CMD ["-f", "/some/config-dir/logstash-mysql-es.conf"]

build镜像:

docker build -t my-logstash .

条件准备:

创建config目录,创建配置文件logstash-mysql-es.conf
同步MySQL需要MySQL驱动。为了挂载目录的时候,只挂载一个目录。我们把mysql驱动与配置文件放到同一个目录下。

未分类

启动容器:

docker run -d --name logstashmysql -v /root/logstash/config:/some/config-dir/ bc8551a7b495

查看日志:

docker logs -f --tail=30 logstashmysql

Docker安装配置WordPress

本站使用WordPress搭建,之前一直使用Linode $10美刀一个月的服务,机房选择在JP,但是感觉速度不行,在国内链接的响应速度基本都在200-300ms之间,前段时间发现搬瓦工的速度还可以,而且按年付费价格比Linode便宜,所以用了好一段时间来折腾网站迁移的工作。

之前在Linode,网站直接搭建在主机上,上面搭建的服务还很多,迁移非常的困难,于是在新站点服务全面使用基于Docker配置,方便以后迁移。

本站迁移中,使用了两个Docker镜像,官方的WordPress和MariaDB镜像。

安装MariaDB

下载安装最新版的MariaDB镜像

docker pull mariadb

创建一个外部目录/docker/mariadb/var/lib/mysql来存放MariaDB数据文件

mkdir -p /docker/mariadb/var/lib/mysql/

创建并运行MariaDB容器,把本地数据目录映射到容器中的/var/lib/mysql目录,并把3306端口映射到主机地址的3306端口,要注意使用-e MYSQL_ROOT_PASSWORD来指定MariaDB root用户初始密码

docker run --name mariadb -p 3306:3306 -v /docker/mariadb/var/lib/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=XXXXXXXXXX -d mariadb

登入MariaDB容器环境

docker exec -it mariadb bash
mysql -u root -p

创建数据库和数据库维护用户

create database wordpress character set utf8 collate utf8_general_ci;
create user wordpress_user identified by 'XXXXXXXXX';
grant all privileges on wordpress.* to wordpress_user;
flush privileges;

安装WordPress

下载最新版的WordPress镜像安装

docker pull wordpress

创建并运行Docker容器环境,官方的WordPress镜像是基于Ubuntu+Apache+MySQL的,镜像里面使用的是80端口,因为主机上安装了nginx,代理很多服务,所以把容器里面的80端口映射到主机的8081端口,使用–link mariadb:mysql指定使用的MySQL为已安装的MariaDB容器

docker run --name wordpress -p 8081:80 --link mariadb:mysql -d wordpress

这时候通过浏览器打开地址ip:8081即可按照提示安装WordPress了。

使用nginx反向代理

本机上安装了nginx,配置了https给很多服务使用,所以这里也把WordPress的地址通过用nginx反向代理实现https访问。

在/etc/nginx/conf.d/目录下创建一个新的配置文件

server {
    listen 80;
    server_name liangxiaorui.com www.liangxiaorui.com;
    return 301  https://$server_name$request_uri;
}

server {
  listen       443 ssl;
  server_name liangxiaorui.com www.liangxiaorui.com;
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  keepalive_timeout 70; 

  error_log /var/log/nginx/liangxiaorui.com.log error; 

  location  / {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8081; 
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

这里使用proxy_pass反向代理到容器的8081端口实现https访问。这里需要注意的是,一定要加上

proxy_set_header X-Forwarded-Proto $scheme;

因为外部nginx使用的是https,容器里面的Apache使用的是http,添加这句话就是为了识别用户实际发出的是https协议还是http协议,之前没加,导致一直出现127.0.0.1重定向错误。这也是迁移过程中遇到的一个小问题之一。

配置完成之后,就可以通过https访问站点了

未分类

Ubuntu Docker 配置 Tomcat 和 Nginx 使用 HTTPS 访问

安装 Docker

使用脚本自动安装

curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun

更改镜像地址

  • 修改或新建 /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://registry.docker-cn.com"
  ]
}

启动 Docker

sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl start docker

配置 Tomcat

启动 Tomcat 容器

docker pull tomcat
docker run --name tomcat -d -p 8080:8080 tomcat

修改 Tomcat Manager 应用

docker exec -it tomcat /bin/bash
  • 修改 webapps/manager/META-INF/content.xml,允许需要的IP访问,这里运行所有的IP访问
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="^.*$" />
  <Manager sessionAttributeValueClassNameFilter="java.lang.(?:Boolean|Integer|Long|Number|String)|org.apache.catalina.filters.CsrfPreventionFilter$LruCache(?:$1)?|java.util.(?:Linked)?HashMap"/>
</Context>

配置 Tomcat 用户

  • 修改 conf/tomcat-user.xml,添加用户
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>

配置 Nginx

配置目录

  • 新建目录 /home/ubuntu/hellowood/dev/nginx/conf, /home/ubuntu/hellowood/dev/nginx/log, /home/ubuntu/hellowood/dev/nginx/certs
  • 下载并解压相应的Nginx证书文件到 /home/ubuntu/hellowood/dev/nginx/conf

添加 Nginx 配置

  • nginx.conf
server {
      listen 80;
      listen 443 ssl;
      server_name hellowood.com.cn;
      ssl_certificate /etc/nginx/certs/hellowood.com.cn_bundle.crt;
      ssl_certificate_key /etc/nginx/certs/hellowood.com.cn.key;
      location / {
        proxy_pass http://tomcat:8080;
      }
}

http://tomcat:8080: 将所有请求都转发到 tomcat 容器的 8080端口

启动 Nginx 容器

docker pull nginx 
docker run --name nginx -d -p 80:80 -p 443:443 
  --link tomcat:tomcat 
  -v /home/ubuntu/hellowood/dev/nginx/conf:/etc/nginx/conf.d  
  -v /home/ubuntu/hellowood/dev/nginx/log:/var/log/nginx  
  -v /home/ubuntu/hellowood/dev/nginx/certs:/etc/nginx/certs nginx

此时,访问相应的域名:http://hellowood.com.cn和https://hellowood.com.cn会显示Tomcat 的首页,配置完成

Kubernetes监控系列(四):Docker + Kubernetes在WayBlazer的使用案例

【编者的话】本文是关于在生产中使用Kubernetes系列的一部分。第一部分介绍了Kubernetes和监控工具的基础知识;第二部分涵盖了Kubernetes报警的最佳实践;第三部分对Kubernetes故障排除,特别是服务发现进行了介绍,最后一部分是监控Kubernetes的实际使用案例。

将Docker引入生产环境,既是一门科学,同时也是一门艺术。我们与WayBlazer的Kevin Kuhl和Kevin Cashman一起讨论有关Docker和Kubernetes的监控、选择正确的关注指标、决定使用Kubernetes来运行何种程序以及诊断Kubernetes故障转移中的“多米诺效应”。

Update:在写完这篇文章的一年后,我们与Wayblazer的Kevin Kuhl、Kevin Cashman再次进行了讨论,并在他们的Kubernetes部署安全性方面增加了一些新的有洞察力的细节。

WayBlazer介绍

WayBlazer是世界上第一个专注于向旅游行业提供人工智能技术的认知推荐引擎。结合IBM Watson和专有认知计算技术,WayBlazer的AI技术对旅行者搜索历史提供的线索进行分析,以便为他们的旅行提供个性化的酒店推荐、见解、图像和当地文化。个性化内容与酒店推荐相结合可提高在线参与度并提高旅行者转化率。

该公司总部位于得克萨斯州奥斯汀,由经验丰富的旅游、科技企业家领导,其中包括Travelocity的创始人/ Kayak.com的创始人主席,IBM前任总经理Watson,以及Sabre Hospitality Solutions的前总裁。

你的环境是什么样的?

我们是一家AWS商店,所以可以想象我们会大量使用EC2。 同时我们还使用了许多AWS服务,这些服务易于使用,价格可取,而且管理得很好。 这些都能使我们的生活变得更轻松。 不久之前,我们开始使用Kubernetes,现在我们在EC2节点之上运行了十几个Kubernetes工作节点(有时甚至更多)。 每个节点运行约15-20个容器。 另外,我们有许多Kubernetes命名空间,如prod、test以及project-specific。

在上述环境中,我们运行了许多不同的服务。 我们的前端是JavaScript,API服务在Node.js上运行。 同时Java服务处理主要逻辑,还有一些在Python中运行的辅助应用程序。

我们使用Sysdig Monitor和AWS Cloudwatch来监控集群。我们依靠许多Kubernetes和AWS平台功能来保护集群内的应用程序,但同时也开始使用Sysdig Secure来加强集群的运行时防御能力。

你在Kubernetes内运行一切应用吗?

不是的。 我们的方法是首先说“它应该在Kubernetes中运行吗?”,但在有些领域,我们的答案是否定的。 不在Kubernetes中运行的应用,要么是功能需求不匹配,要么是性能达不到要求。

最显而易见的,我们的无状态服务通常运行在Kubernetes中,这简直是个完美的选择。 然而有状态的服务,例如图形数据库,还不是很适合。 也许使用PetSets最终能够做到这一点,但现在不行。 最后,我们的批处理作业或者定时作业通常不会运行在Kubernetes上。 同样,这是Kubernetes正在发展的方向,但现在不能满足我们的需求。

从安全和访问的角度来看,Docker,AWS,Kubernetes和其他服务都需要监控,而且从应用程序性能角度来看也是如此。 是如何做到同时监控这一切呢?

我们先谈谈平台安全保护。 从一开始我们使用kubernetes TLS——这能控制对kube-ctl的访问。 从网络角度来看,Amazon ELB是安全的,并可以保护应用程序免于暴露于外。 这对集群免于外力攻击非常给力。 然而,这些工具无法保证集群内没有发生任何不利事件。接下来当我们深入讨论Sysdig Secure时会再谈这个问题。

从传统的监控角度来看,我们仅依靠AWS Cloudwatch提供的主机级监控。 这在使用Docker和Kubernetes,也就是更静态的体系架构之前是没有问题的。 而且,相对静态的体系架构下,可以从基础设施的监控信息中获得关于应用程序性能的更多信息。 迁移到Kubernetes后发生了改变, 我们需要在容器和服务级别进行监控。

Kubernetes默认提供Heapster和Grafana,这是我们的第一次尝试。 为了使用和管理这些组件,我们投入了大量的时间和努力。 鉴于我们是由两人组成的运维团队,这显然不是值得我们投入大量时间的方式。 我们需要一个功能全面,健壮监控功能,并且易于开展工作的监控工具。

所以对于我们来说,这排除了自己组合组件的方式。 我们最终选择了符合需求的商业产品。 实际上,我们仍然使用CloudWatch监控基本的AWS指标,同时使用Sysdig用于更高级别的内容。 尽管在监控底层基础设施方面存在一些重复,但没有任何影响。

Kubernetes是否会影响Docker的监控? 并保护它?

是的,但Kubernetes影响很多方面,而不仅仅是监控。 如果我们回到为什么选Kubernetes这一问题上,一方面是它能精确地描述它在做什么,并且有它自己的语言来描述它:namespace,deployment等等。 这种“语言”统一了容器技术的使用方式。 这使得与工程师,运维人员或者任何参与到软件开发过程的人员的交流变得容易。

为了获取更加具体的监控信息,到目前为止,迁移到Kubernetes最重要,最明显的原因是对深入了解以Kubernetes为中心和以服务为中心的代码视图。实际上,很多软件可以通过与Docker API交互来监控基础设施级别的Docker容器,但他们不知道容器的具体信息。了解构成API服务的容器组,或者某个容器是某个Pod/ReplicaSet的一部分是非常有价值的,这使我们重新定义了对监控的需求。

对安全性有类似的思路:一个从以服务、Kubernetes为中心角度,且可以了解容器内部所发生事情的安全工具,比只通过镜像名区分容器或容器组的工具强大得多。

好吧,既然我们正在和你一起写这篇文章,我们都可以十分肯定地假设WayBlazer选择了Sysdig。 为什么?

是的。 我们现在使用了整个Sysdig容器智能平台——Sysdig Monitor,Sysdig Secure和开源故障排除工具。 Sysdig是一个优秀的集成基础设施监控、Kubernetes集群监控的工具。 基本上没有其他工具具有如此能力,通常我们都需要这两部分的监控才能在生产环境中运行容器。

Sysdig加强了Kubernetes的语言通用性。 它了解Kubernetes的基本结构。 不需要告诉Sysdig任何信息,也不必去适应它。 一旦部署了Sysdig,就可以获得想要的服务级别的指标信息,命令历史记录以及安全策略违规记录。

所有这些都来自一个统一的Agent。 在添加Sysdig Secure之前,Sysdig Monitor已经运行了大约18个月,我们只需添加一个额外的conf变量到Sysdig agent YAML文件中,Kubernetes Daemonset便会负责剩下的事情。

另外重要的一点是Sysdig可以获得容器内部更多的应用程序或以代码为中心的应用程序视图。 虽然我们十分关注基础架构指标,但同时也关注应用程序的监控信息。 Sysdig可以做到开箱即用,甚至当Kubernetes正在对Docker容器进行扩缩容。

所有这些方面都降低了成本,也提升了我们的效率。 这意味着我们不必为了将Kubernetes元数据转换成衡量指标而花费精力,也不必过多考虑如何使用我们的系统。

一旦应用程序部署在生产环境中,该如何保护呢?

上文已经提到了平台能提供安全性。 但是,我们仍然需要一些能够为运行时行为提供安全性的服务。 这些行为可能发生在主机级别,应用程序级别或系统中其他任何地方。 我欣赏Sysdig Secure,因为除了拥有以服务为中心的策略来提醒或阻止行为之外,还能让我们深入了解系统内发生的所有事情。 明确没有发生的事情的确能使人安心很多。

运行时安全最让人担心的问题是(1)谁在登录系统,他们在做什么;(2)是否有人正在修改系统内重要的文件? Sysdig安全策略默认已经对登录,远程shell连接,未经授权的连接以及其他一些行为进行了防御和提醒,所以只需要为自定义应用程序创建一些特定的策略。 我们需要更高的优先级和更严格定义的安全策略。

就上文所描述的可见性,Secure提供历史命令查看就是一个很好的例子。 它提供查看系统中所执行的一切内容的能力,从微服务、到主机或容器等等,总之,一切我想看的内容。 另外,Sysdig Monitor的另一功能是可以及时查看指标信息,这也非常有用。 现在,如果将这两者结合在一起会非常有用。 如果在监控页面(显示内存,响应时间信息等)中看到不正常信息或事件,便可以回到命令历史记录获得更多信息,如是否有人在该服务或容器上运行了新的东西?

让我们更深入一点。 什么是最重要的监控指标? 你一天到晚最想知道什么?

有趣的是,我们正在讨论Docker监控,但却没有真正地监控Docker。而是专注于监控应用程序,并在某种程度上监控Kubernetes以向我们提供有关应用程序运行的环境信息。 我们经常使用Docker相关信息进行故障排除,这是我们基础架构栈中的另一个层面,并且可能经常提供帮助我们解决棘手问题的信息。 以下是我们在应用程序级别监控的一些关键内容:

  • 请求时间:我们密切关注前端和API的请求和响应时间。如果出现问题或变化,这些是需要首先关注的指标。 例如,一次新构建可能会导致应用程序执行失败,或者,一次网络配置错误可能会对用户产生负面影响。
  • 后端查询响应时间:这些可能直接与数据库或Java后端相关。 当然,这是寻找潜在问题的好地方,也是改善系统的机会。 如果通常情况下,查询运行缓慢,便可以将其返回给团队进行研究和修复。
  • 堆使用和垃圾回收:虽然不经常使用,但我们已经使用这些数据来调试基于JVM级数据的数据仓库。 从应用程序级别来看,我们确实需要关注这些资源指标。

接下来是Kubernetes。 以下是我们关注的内容:

  • Pod重启和容器计数:告诉我们是否有变化发生。
  • 启动失败:这些是可以用来关联其他指标的重要事件,无论是应用还是基础架构。
  • 服务请求延迟:这一点极具挑战。 它涉及汇总来自特定服务的所有容器的延迟信息,并以一个统一的视图呈现。 这是在监控中使用“Kubernetes视点”的最佳例子。
  • 容器平均资源利用率:我们最近在Kubernetes中添加了资源请求和限制机制,这意味着我们可以更有效地追踪资源利用率。 相比根据主机级别CPU和内存信息来监控资源利用率,我们选择根据分配给特定容器的资源来进行监控。 这能在资源分配问题上更早的提示警告,而不是仅仅在主机利用率级别进行监控。

关键节点上高CPU、内存和磁盘使用率,我们已经有了报警机制。 你也需要这些功能。

能谈谈你监控Kubernetes“多米诺骨牌效应”的故事吗?

这是我们在EC2中运行Kubernetes时早就经历的一件事。 我们的第一个警告指标是API高延迟的警报。 但此时延迟时间开始降低,虽然我们已准备好在必要时采取行动,但系统似乎稳定了。

但很快我们明白了问题的严重性。 我们看到了Kubernetes管理的节点缩容的警报。 我们立即查看了Sysdig,注意到蓝线在下降。 这不太好,但事情还没有结束。 Kubernetes正在干掉相关容器,并移到另一个节点。

未分类

然后同时看到磁盘和内存使用率都非常高。 这是最后的警告。 然后整个系统崩溃了。

未分类

基本上这就是多米诺骨牌效应——Kubernetes对第一个节点做了failvoer,它在内存耗尽时清除了所有容器。 此时,某些服务上并不存在对内存使用的请求和限制。

未分类

问题在于集群中的其他节点的磁盘使用已经比较高了,以至于无法为需要迁移的容器保留足够的空间。

未分类

我们很快就能够扩大自动伸缩组并修复一些节点,让系统恢复正常。 但这通常来说比较痛苦,而且很不理想。在之后对此的回顾汇总,我们很有趣的发现,能够通过Sysdig查看到整个事情。 然后在一天内与团队一起发布了一个可靠的关于系统行为的报告。 同时我们整理了一份完整的操作列表,其中有在系统达到特定阈值、限制条件、扩容策略等的具体操作。 这使我们的系统更加健壮。

你能总结一下在Docker监控方面的经验教训吗?

我们的经验表明,采用Kubernetes和Docker会对监控方法产生很大影响。 就像Kubernetes使我们可以从一个更加service-centric的视角来对待整个基础设置,监控策略也会以同样的方式发生变化。

你需要在监控系统中使用基于基础架构的视图(监控的标准方式)和以服务为中心的视图(监控的新方法),以在生产环境中运行容器。

确保你的监控系统能够强化Kubernetes的语言通用性。 它必须了解Kubernetes开箱即用的基本结构。 而且你不应该告诉他任何信息。 一旦部署,就可以获得服务级别的监控信息。

另外重要的一点你的工具应该在容器中看到更多的应用程序信息或以代码为中心的应用程序视图。 尽管我们密切关注基础架构指标,但我们仍然专注于监控应用程序,不管Kubernetes正在启动或停止Docker容器。

所有这些方面都降低了成本,也提升了我们的效率。 这意味着我们不必为了将Kubernetes元数据转换成衡量指标而花费精力,也不必过多考虑如何使用我们的系统。

希望你喜欢Kubernetes监控这一系列文章! 如果你想了解更多,下面我们的首席执行官和创始人Loris Degioanni在CloudNativeCon / KubeCon “You’re Monitoring Kubernetes Wrong”的演讲。

视频: https://v.qq.com/x/page/c0603u1t44l.html

Docker的MySQL官方镜像设置时区

在 Docker Hub 中的 MySQL 官方镜像中,时区是使用了世界标准时间(UTC)。因为在中国使用,所以需要把时区改成东八区的。

方法1

1、查看当前时区

date -R

2、修改设置时区。先输入 tzselect 命令,然后根据提示,通过输入选项前面的数字来确定选项。我的例子,先选择 Asia ,再选择 Hong Kong。香港和中国采用了同样的东八区时间。

3、复制相应的时区文件,替换原来的时区文件。命令如下:

/usr/share/zoneinfo/Asia# cp Hong_Kong /etc/localtime

我们需要的时区文件在目录 /usr/share/zoneinfo/Asia 下。文件名字是 Hong_Kong。把它拷贝覆盖 /etc/localtime 文件。

4、重新输入命令 date -R,就可以看到修改时区后的中国时间了。

方法2

我自己找到了一种不用 tzselect 的方法。
目录/usr/share/zoneinfo/Asia下有各个亚洲地区的时区的文件。查看这个目录下的内容:

/usr/share/zoneinfo/Asia# ls -hl

lrwxrwxrwx 1 root root    6 Jul  6 02:15 Shanghai -> ../PRC
lrwxrwxrwx 1 root root   12 Jul  6 02:15 Singapore -> ../Singapore

从查询结果可以知道,上海的时区文件实际上是个软连接文件。连接到了目录 /usr/share/zoneinfo/ 下的PRC文件。
直接进行拷贝:

cp /usr/share/zoneinfo/PRC /etc/localtime

然后这样就可以了。