月度归档:2018年12月

使用docker-compose部署LNMP环境


2018年12月29日 15:04:00   1,206 次浏览

1、创建相关compose存放目录

< 5 docker-test - [root]: > mkdir -p /apps/compose_lnmp/nginx
< 5 docker-test - [root]: >  cd !$
< 5  docker-test - [root]: /apps/compose_lnmp/nginx >

2、下载nginx软件包,创建dockerfile

< 6  docker-test - [root]: /apps/compose_lnmp/nginx > # wget http://nginx.org/download/nginx-1.14.2.tar.gz

< 7  docker-test - [root]: /apps/compose_lnmp/nginx > # vim Dockerfile

FROM centos:7
MAINTAINER gujiwork
RUN yum install -y gcc gcc-c++ make openssl-devel pcre-devel
ADD nginx-1.14.2.tar.gz /tmp
RUN cd /tmp/nginx-1.14.2 && ./configure --prefix=/usr/local/nginx && make -j 4 && make install
COPY nginx.conf  /usr/local/nginx/conf
EXPOSE 80
WORKDIR /usr/local/nginx
CMD ["./sbin/nginx", "-g", "daemon off;"]

3、这里面用到了nginx.conf,放到compose_lnmp/nginx目录下,将 fastcgi_pass 127.0.0.1:9000改成php容器名, fastcgi_pass php-cgi:9000;

#user  nginx;
worker_processes  2;
worker_cpu_affinity 0101 1010;
#error_log  logs/error.log;
error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
   worker_connections  10240;
}
http {
   include       mime.types;
   default_type  application/octet-stream;
   server_tokens off;  
   #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
   #                  '$status $body_bytes_sent "$http_referer" '
   #                  '"$http_user_agent" "$http_x_forwarded_for"';
   #access_log  logs/access.log  main;
   sendfile        on;
   tcp_nopush on;
   tcp_nodelay on;
   server_names_hash_bucket_size 128;
   server_names_hash_max_size 512;
   client_header_timeout 15s;
   client_body_timeout 15s;
   send_timeout 60s;
   #tcp_nopush     on;
   #keepalive_timeout  0;
   keepalive_timeout  65;
   #gzip  on;
   server {
       listen       80;
       server_name  localhost;
       #charset koi8-r;
       #access_log  logs/host.access.log  main;
       location / {
           root   html;
           index  index.html index.htm;
       }
       #error_page  404              /404.html;
       # redirect server error pages to the static page /50x.html
       #
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   html;
       }
       # proxy the PHP scripts to Apache listening on 127.0.0.1:80
       #
       #location ~ \.php$ {
       #    proxy_pass   http://127.0.0.1;
       #}
       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
       #
       location ~ \.php$ {
           root           html;
           fastcgi_pass   php-cgi:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
           include        fastcgi_params;
       }
       # deny access to .htaccess files, if Apache's document root
       # concurs with nginx's one
       #
       #location ~ /\.ht {
       #    deny  all;
       #}
   }
   # another virtual host using mix of IP-, name-, and port-based configuration
   #
   #server {
   #    listen       8000;
   #    listen       somename:8080;
   #    server_name  somename  alias  another.alias;
   #    location / {
   #        root   html;
   #        index  index.html index.htm;
   #    }
   #}
   # HTTPS server
   #
   #server {
   #    listen       443 ssl;
   #    server_name  localhost;
   #    ssl_certificate      cert.pem;
   #    ssl_certificate_key  cert.key;
   #    ssl_session_cache    shared:SSL:1m;
   #    ssl_session_timeout  5m;
   #    ssl_ciphers  HIGH:!aNULL:!MD5;
   #    ssl_prefer_server_ciphers  on;
   #    location / {
   #        root   html;
   #        index  index.html index.htm;
   #    }
   #}
include vhost/*.conf;
}

4、创建mysql目录,数据和配置文件做持久化,这里我们使用mysql官方镜像,因此不需要写dockerfile

< 39 docker-test - [root]: /apps/compose_lnmp > # mkdir mysql/{conf,data}

< 39  docker-test - [root]: /apps/compose_lnmp > # tree  mysql/

mysql/

|-- conf

|   `-- my.cnf

`-- data

< 40  docker-test - [root]: /apps/compose_lnmp > # cat mysql/conf/my.cnf

[mysqld]
user=mysql
port=3306
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.socket
pid-file=/var/run/mysql/mysql.pid
log_error=/var/log/mysql/error.log
character_set_server = utf8
max_connections=3600

5、创建php目录及dockerfile,php.ini主要修改了时区为shanghai

< 49  docker-test - [root]: /apps/compose_lnmp > # tree  php/

php/

|-- Dockfile
|-- php-5.6.31.tar.gz
`-- php.ini

< 50  docker-test - [root]: /apps/compose_lnmp > # cat php/Dockfile

FROM centos:7
MAINTAINER gujiwork
RUN yum install -y gcc gcc-c++ gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel make
ADD php-5.6.31.tar.gz /tmp/
RUN cd /tmp/php-5.6.31 && \
   ./configure --prefix=/usr/local/php \
   --with-config-file-path=/usr/local/php/etc \
   --with-mysql --with-mysqli \
   --with-openssl --with-zlib --with-curl --with-gd \
   --with-jpeg-dir --with-png-dir --with-iconv \
   --enable-fpm --enable-zip --enable-mbstring && \
   make -j 4 && make install && \
   cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
   sed -i "s/127.0.0.1/0.0.0.0/" /usr/local/php/etc/php-fpm.conf && \
   cp ./sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm && \
   chmod +x /etc/init.d/php-fpm

COPY php.ini /usr/local/php/etc
EXPOSE 9000
CMD /etc/init.d/php-fpm start && tail -F /var/log/messages

6、创建docker-compose维护文件

< 53  docker-test - [root]: /apps/compose_lnmp > # cat docker-compose.yml

version: '3'
services:
 nginx:
   hostname: nginx
   build:
     context: ./nginx
     dockerfile: Dockerfile

   ports:
     - 80:80
   links:
     - php:php-cgi
   volumes:
     - ./wwwroot:/usr/local/nginx/html


 php:
   hostname: php
   build: ./php
   links:
     - mysql:mysql-db
   volumes:
     - ./wwwroot:/usr/local/nginx/html

 mysql:
   hostname: mysql
   image: mysql:5.6
   ports:
     - 3306:3306
   volumes:
     - ./mysql/conf:/etc/mysql/conf.d
     - ./mysql/data:/var/lib/mysql

   #command: --character-set-server=utf8

   environment:
     MYSQL_ROOT_PASSWORD: 123456
     MYSQL_DATABASE: wordpress
     MYSQL_USER: user
     MYSQL_PASSWORD: user123

7、创建web挂载目录,整体目录结构如下

< 56  docker-test - [root]: /apps/compose_lnmp > # tree .
.
|-- docker-compose.yml
|-- mysql
|   |-- conf
|   |   `-- my.cnf
|   `-- data
|-- nginx
|   |-- Dockerfile
|   |-- nginx-1.14.2.tar.gz
|   `-- nginx.conf
|-- php
|   |-- Dockfile
|   |-- php-5.6.31.tar.gz
|   `-- php.ini
`-- wwwroot


6 directories, 8 files

8、执行build构建镜像

< 81  docker-test - [root]: /apps/compose_lnmp > # docker-compose  build

9、出现success表示构建成功

make[1]: Leaving directory `/tmp/nginx-1.14.2'
Removing intermediate container b7fb79c4671e
---> b756345aac5b
Step 6/9 : COPY nginx.conf /usr/local/nginx/conf
---> cb180351db65
Step 7/9 : EXPOSE 80
---> Running in 20805a3b58a5
Removing intermediate container 20805a3b58a5
---> 9f75c3834969
Step 8/9 : WORKDIR /usr/local/nginx
---> Running in 6abf5341ee7b
Removing intermediate container 6abf5341ee7b
---> 0cb88354c8b8
Step 9/9 : CMD ["./sbin/nginx", "-g", "daemon off;"]
---> Running in a2db489f2b5b
Removing intermediate container a2db489f2b5b
---> 76ae0759f3b1
Successfully built 76ae0759f3b1
Successfully tagged compose_lnmp_nginx:latest

10、启动服务测试

< 82  docker-test - [root]: /apps/compose_lnmp > # docker-compose  up -d

Creating network "compose_lnmp_default" with the default driver
Pulling mysql (mysql:5.6)...
5.6: Pulling from library/mysql
177e7ef0df69: Pull complete
cac25352c4c8: Pull complete
8585afabb40a: Pull complete
1e4af4996053: Pull complete
c326522894da: Pull complete
50ec9776c6b3: Pull complete
b81a89945365: Pull complete
80f5ab6567ca: Pull complete
5caf5e4c5eb0: Pull complete
9295ceea71e2: Pull complete
fb029976ca26: Pull complete
Creating compose_lnmp_mysql_1_32333e982f89 ... done
Creating compose_lnmp_php_1_856b9f701287   ... done
Creating compose_lnmp_nginx_1_c5360c9dc627 ... done



< 144  docker-test - [root]: /apps/compose_lnmp/wwwroot > # echo "111" >index.html


#测试

< 144  docker-test - [root]: /apps/compose_lnmp/wwwroot > # curl localhost/

111

 

Docker主机数据挂载到容器


2018年12月19日 22:11:00   1,299 次浏览

Docker数据管理

Docker提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts 和tmpfs。

olumes

docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。

管理卷

[root@docker-master ~]# docker volume create nginx-vo1
nginx-vo1

[root@docker-master ~]# docker volume ls

DRIVER              VOLUME NAME
local               144c5839b36278cea8b3bc7bf3d10d051c11e7acc5610d420f25314f240ef574
local               a0c117c96d84eeaeebd548eda827577f17926a595c85ea69a9f4ea9f756c1557
local               f0e495702096c6845110ae74e0ed24455059e1265831acca1bb303458b4400ab
local               nginx-vo1

[root@docker-master ~]# docker volume inspect nginx-vo1
[
   {
       "CreatedAt": "2018-12-12T01:05:59+08:00",
       "Driver": "local",
       "Labels": {},
       "Mountpoint": "/var/lib/docker/volumes/nginx-vo1/_data",
       "Name": "nginx-vo1",
       "Options": {},
       "Scope": "local"
   }
]

用卷创建一个容器

docker run -itd --name=nginx-test --mount src=nginx-vo1,dst=/usr/share/nginx/html nginx

进入容器内部查看nginx web目录

[root@docker-master ~]# docker exec -it nginx-test bash

root@23821377e2f7:/# ls /usr/share/nginx/html/
50x.html  index.html

在宿主机docker volumes目录可以发现有相同的两个html文件,无论是在容器内新创建文件还是在宿主机创建文件,内容都不会同步映射到对应目录

[root@docker-master ~]# ll /var/lib/docker/volumes/nginx-vo1/_data/

total 8
-rw-r--r-- 1 root root 494 Nov 27 20:31 50x.html
-rw-r--r-- 1 root root 612 Nov 27 20:31 index.html

清理

docker container stop nginx-test
docker container rm nginx-test
docker volume rm nginx-vo1

注意:

1.如果没有指定卷,自动创建

2.建议使用–mount,更通用

bind mounts

可以存储在宿主机系统的任意位置。将宿主机的目录映射到容器中做持久卷,删除容器后数据存储在宿主机上不会丢失

用卷创建一个容器

[root@docker-master ~]# mkdir /app/wwwroot -p

[root@docker-master ~]# docker run -itd --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
453be5dc46e410c3daa5c34f219ed5d195c134a538b2e5f85d0c1d333fd7e7ff

[root@docker-master ~]# docker exec -it nginx-test bash

root@453be5dc46e4:/# mount

/dev/mapper/docker-8:2-528671-5a0afb1cab58d9e41d9ec2ecfc57b7045452918f77a15ede38aa9acb69d7bdac on / type xfs (rw,relatime,nouuid,attr2,inode64,logbsize=64k,sunit=128,swidth=128,noquota)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,relatime,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (ro,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/net_cls type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
/dev/sda2 on /etc/resolv.conf type ext4 (rw,relatime,data=ordered)
/dev/sda2 on /etc/hostname type ext4 (rw,relatime,data=ordered)
/dev/sda2 on /etc/hosts type ext4 (rw,relatime,data=ordered)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
/dev/sda2 on /usr/share/nginx/html type ext4 (rw,relatime,data=ordered)/dev/sda2 on /usr/share/nginx/html type ext4 (rw,relatime,data=ordered)

进入到容器内使用mount命令可以发现/dev/sda2 on /usr/share/nginx/html type ext4 (rw,relatime,data=ordered)已经挂载了

docker run -itd --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx

验证绑定

docker inspect nginx-test

清理

docker container stop nginx-test
docker container rm nginx-test

注意:

1.如果源文件/目录没有存在,不会自动创建,会抛出一个错误。

docker: Error response from daemon: invalid mount config for type “bind”: bind source path does not exist.
See ‘docker run –help’.

2.如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。

tmpfs

挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统。

Docker容器监控系统 cAdvisor+InfluxDB+Grafana


2018年12月19日 14:54:00   1,559 次浏览

cAdvisor:Google开源的工具,用于监控Docker主机和容器系统资源,通过图形页面实时显示数据,但不存储;它通过宿主机/proc、/sys、/var/lib/docker等目录下文件获取宿主机和容器运行信息

InfluxDB:是一个分布式的时间序列数据库,用来存储cAdvisor收集的系统资源数据。

Grafana:可视化展示平台,可做仪表盘,并图表页面操作很方便,数据源支持zabbix、Graphite、InfluxDB、OpenTSDB、Elasticsearch等

它们之间关系:

cAdvisor容器数据采集—–> InfluxDB容器数据存储—–>Grafana可视化展示

部署InfluxDB

[root@docker-master ~]# docker run -itd  -p8083:8083  --name influxdb  tutum/influxdb
Unable to find image 'tutum/influxdb:latest' locally
latest: Pulling from tutum/influxdb
a3ed95caeb02: Pull complete
23efb549476f: Pull complete
aa2f8df21433: Pull complete
ef072d3c9b41: Pull complete
c9f371853f28: Pull complete
a248b0871c3c: Pull complete
749db6d368d0: Pull complete
db2492acfcc3: Pull complete
b7e7d2e12d53: Pull complete
4272a53eef10: Pull complete
9b2fefdb5321: Pull complete
Digest: sha256:2772d80e80284b801c6ef255f7e185dd5290757f0f031d77762390dd4df2a9a3
Status: Downloaded newer image for tutum/influxdb:latest
docker: Error response from daemon: mkdir /var/lib/docker/overlay/6d0d06de343d70cdd581480780933d4c05904bce9cf381efc1ac630f28acd083-init/merged/dev/shm: invalid argument.

在docker run的时候报了一个错, mkdir /var/lib/docker/overlay/6d0d06de343d70cdd581480780933d4c05904bce9cf381efc1ac630f28acd083-init/merged/dev/shm: invalid argument

解决方法:

[root@docker-master ~]# vim /etc/docker/daemon.json
{
"storage-driver": "devicemapper"
}


[root@docker-master ~]# docker run -idt -p 8083:8083 --name influxdb tutum/influxdb
Unable to find image 'tutum/influxdb:latest' locally
latest: Pulling from tutum/influxdb
a3ed95caeb02: Pull complete
23efb549476f: Pull complete
aa2f8df21433: Pull complete
ef072d3c9b41: Pull complete
c9f371853f28: Pull complete
a248b0871c3c: Pull complete
749db6d368d0: Pull complete
db2492acfcc3: Pull complete
b7e7d2e12d53: Pull complete
4272a53eef10: Pull complete
9b2fefdb5321: Pull complete
Digest: sha256:2772d80e80284b801c6ef255f7e185dd5290757f0f031d77762390dd4df2a9a3

创建数据库用来存放cadvisor采集的数据,再创建数据库用户供grafana连接

create database "cadvisor"

查看数据库可以发现数据库已经创建成功了。

# 创建用户

create user "cadvisor" with password 'cadvisor'

OK,数据库用户也已经创建成功。

show users

 

部署cAdvisor

docker run -d \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--link influxdb:influxdb \
-p 8081:8080 \
--name=cadvisor \
google/cadvisor:latest \
-storage_driver=influxdb \
-storage_driver_db=cadvisor \
-storage_driver_host=influxdb:8086



Unable to find image 'google/cadvisor:latest' locally
latest: Pulling from google/cadvisor
ab7e51e37a18: Pull complete
a2dc2f1bce51: Pull complete
3b017de60d4f: Pull complete
Digest: sha256:9e347affc725efd3bfe95aa69362cf833aa810f84e6cb9eed1cb65c35216632a
Status: Downloaded newer image for google/cadvisor:latest
c4b2aa505f02e01f61a704dfeac9574ca9d36897896bda9be5c8d688d9ed441f

部署Granfana

docker run -d \
-p 3000:3000 \
-e INFLUXDB_HOST=localhost \
-e INFLUXDB_PORT=8086 \
-e INFLUXDB_NAME=cadvisor \
-e INFLUXDB_USER=cadvisor \
-e INFLUXDB_PASS=cadvisor \
--link influxdb:influxsrv \
--name grafana \
grafana/grafana



Unable to find image 'grafana/grafana:latest' locally
latest: Pulling from grafana/grafana
a5a6f2f73cd8: Pull complete
08e6195c0f29: Pull complete
b7bd3a2a524c: Pull complete
d3421658103b: Pull complete
cd7c84229877: Pull complete
49917e11f039: Pull complete
Digest: sha256:b9a31857e86e9cf43552605bd7f3c990c123f8792ab6bea8f499db1a1bdb7d53
Status: Downloaded newer image for grafana/grafana:latest
65e7390c90d8595495a776a66a03df77e474a4fa69d9d248f71236c5b62a580b

访问http://IP:3000 默认用户:admin 密码:admin

添加数据源Add Type里面选择InfluxDB ,最后选择Save&Test 保存测试。

URL填写:http://influxdb:8086  数据库用户及密码填写:cadvisor

在grafana上绘制图表即可展现相关数据

MySQL连接异常java.sql.SQLException: Value ‘0000-00-00’ can not be represen


2018年12月19日 11:30:00   1,131 次浏览

最近准备上线新业务,业务代码使用的是spring框架,将开发提供的代码仓库地址git clone到测试环境机器进行mvn打包部署到另外的测试机器中,在启动服务是报异常

java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date

gg查了一下相关资料,原来是因为实际的字段在数据库中为空,其默认值为“0000-00-0000:00:00”,在mysql中作为一个特殊值存在。但是在java项目编译的时候会被视为不合法的值,被JVM认为格式不正确。

解决方法: 在jdbc url加上zeroDateTimeBehavior=convertToNull参数,重新启动服务后正常。