基于docker的WordPress环境搭建

WordPress是一个强大的框架,它的使用者众多,社区十分活跃,我们可以非常轻易地找到很多非常漂亮的主题来装饰个人博客。

根据官方的说法,搭建一个wordpress至少需要系统支持以下特征:

  • PHP 7 以及更高版本
  • MySQL 5.6 以及更高版本或者是 MariaDB 10.0 以及更高版本
  • Apache的mod_rewrite模块支持

对于我这种大白来说,搭建服务并不难,配置软件也不是不可接受。但是我只是搭一个博客而已啊喂,要安装这么多东西把系统弄的乱糟糟的,简直不能忍,有没有更优雅的方式呢?

这时候。docker这一个工具就该派上用场了。它创建了一个与主机系统独立的空间,整洁高效。

mariadb:

$docker run --name db --env MYSQL_ROOT_PASSWORD=example -d mariadb

wordpress:

$docker run --name WordPress --link db:mysql -p 4000:80 -d wordpress

第一条命令创建了一个db容器,并给它创建了一个别名叫db,并设置了MySQL的密码为example。第二条则创建了一个wordpress的容器,由于两个容器有数据交流,这里用了一个–link参数来将它们联系起来,但是注意:用–link containerA参数时需要A已经创建并且已经在运行。在这里我们将docker的80端口和主机的4000端口连起来。访问docker里的wordpress,只需要在主机的浏览器输入http://localhost:4000就可以了。

另外,这个博客就是在docker里面搭建起来的。

docker一键式安装nginx

一、准备Dockerfile文件

FROM hub.c.163.com/library/centos:latest

RUN echo "Asia/shanghai" > /etc/timezone;
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

COPY nginx-1.8.1.sh /usr/local/
COPY run.sh /usr/local

二、创建 nginx-1.8.1.sh 安装脚本

#!/bin/bash
#install nginx-1.8.1

#安装目录
INSTALL_DIR=/opt/
SRC_DIR=/opt/software

[ ! -d ${INSTALL_DIR} ] && mkdir -p ${INSTALL_DIR}
[ ! -d ${SRC_DIR} ] && mkdir -p ${SRC_DIR}

# Check if user is root
if [ $(id -u) != "0" ]; then
    echo "Error: You must be root to run this script!!"
    exit 1
fi

#安装依赖包
for Package in unzip wget gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre pcre-devel
do
    yum -y install $Package
done

Install_Nginx()
{
#更新版本信息
NGINX="nginx-1.8.1"
PCRE="pcre-8.35"
ZLIB="zlib1211"
OPENSSL="openssl-1.0.1i"

NGINXFEATURES="--prefix=${INSTALL_DIR}nginx 
--user=nginx 
--group=nginx 
--with-http_ssl_module 
--with-http_gzip_static_module 
--with-http_stub_status_module 
--with-http_realip_module 
--pid-path=/var/run/nginx.pid 
--with-pcre=${SRC_DIR}/${PCRE} 
--with-zlib=${SRC_DIR}/zlib-1.2.11 
--with-openssl=${SRC_DIR}/${OPENSSL}
"

cd ${SRC_DIR}
#下载所需安装包
echo 'Downloading NGINX'
if [ ! -f ${NGINX}.tar.gz ]
then
  wget -c http://nginx.org/download/${NGINX}.tar.gz
else
  echo 'Skipping: NGINX already downloaded'
fi

echo 'Downloading PCRE'
if [ ! -f ${PCRE}.tar.gz ]
then
  wget -c https://sourceforge.net/projects/pcre/files/pcre/8.35/${PCRE}.tar.gz
else
  echo 'Skipping: PCRE already downloaded'
fi

echo 'Downloading ZLIB'
if [ ! -f ${ZLIB}.zip ]
then
  wget -c http://zlib.net/${ZLIB}.zip
else
  echo 'Skipping: ZLIB already downloaded'
fi

echo 'Downloading OPENSSL'
if [ ! -f ${OPENSSL}.tar.gz ]
then
  wget -c http://www.openssl.org/source/${OPENSSL}.tar.gz
else
  echo 'Skipping: OPENSSL already downloaded'
fi

echo '----------Unpacking downloaded archives. This process may take serveral minutes---------'

echo "Extracting ${NGINX}..."
tar xzf ${NGINX}.tar.gz
echo 'Done.'

echo "Extracting ${PCRE}..."
tar xzf ${PCRE}.tar.gz
echo 'Done.'

echo "Extracting ${ZLIB}..."
unzip ${ZLIB}.zip
echo 'Done.'

echo "Extracting ${OPENSSL}..."
tar xzf ${OPENSSL}.tar.gz
echo 'Done.'

#添加用户
groupadd -r nginx
useradd -r -g nginx nginx

#编译
echo '###################'
echo 'Compile NGINX'
echo '###################'
cd ${SRC_DIR}/${NGINX}
./configure ${NGINXFEATURES}
make
make install
cd ../

mkdir -p ${INSTALL_DIR}/nginx/conf/vhosts

}

Install_Nginx

三、创建运行脚本 run.sh

#!/bin/bash
source /etc/profile

echo `pwd`

sh /usr/local/nginx1.8.sh

/usr/local/nginx/sbin/nginx

while true; do sleep 1; done

四、构建

docker build -t nginx:0.1 .

五、准备yaml文件 nginx.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 10
  template:
    metadata:
      labels:
        app: nginx
        version: V20170907134852
    spec:
      volumes:
        - name: logs
          hostPath:
            path: /data/log
        - name: jdk
          hostPath:
            path: /usr/local/java/jdk1.8.0_102
        - name: project
          hostPath:
            path: /data/appdeploy
      containers:
        - name: nginx
          image: nginx:0.1
          ports:
            - containerPort: 80
          volumeMounts:
          - mountPath: /data/log
            name: logs
          - mountPath: /usr/local/java/jdk1.8.0_102
            name: jdk
            readOnly: true
          - mountPath: /data/appdeploy
            name: project
          env:
            - name: DEPLOYMENT_DEMO_VER
              value: V20170907134852
          command:
            - /usr/local/run.sh
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - name: http
    port: 80
    nodePort: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: nginx

六、启动yaml

kubectl create -f y nginx.yaml

大功告成!

使用 Docker 和 Kubernetes 将 MongoDB 作

介绍

想在笔记本电脑上尝试 MongoDB?只需执行一个命令,你就会有一个轻量级的、独立的沙箱。完成后可以删除你所做的所有痕迹。

想在多个环境中使用相同的程序栈application stack副本?构建你自己的容器镜像,让你的开发、测试、运维和支持团队使用相同的环境克隆。

容器正在彻底改变整个软件生命周期:从最早的技术性实验和概念证明,贯穿了开发、测试、部署和支持。

编排工具用来管理如何创建、升级多个容器,并使之高可用。编排还控制容器如何连接,以从多个微服务容器构建复杂的应用程序。

丰富的功能、简单的工具和强大的 API 使容器和编排功能成为 DevOps 团队的首选,将其集成到连续集成(CI) 和连续交付 (CD) 的工作流程中。

这篇文章探讨了在容器中运行和编排 MongoDB 时遇到的额外挑战,并说明了如何克服这些挑战。

MongoDB 的注意事项

使用容器和编排运行 MongoDB 有一些额外的注意事项:

  • MongoDB 数据库节点是有状态的。如果容器发生故障并被重新编排,数据则会丢失(能够从副本集的其他节点恢复,但这需要时间),这是不合需要的。为了解决这个问题,可以使用诸如 Kubernetes 中的 数据卷volume 抽象等功能来将容器中临时的 MongoDB 数据目录映射到持久位置,以便数据在容器故障和重新编排过程中存留。

  • 一个副本集中的 MongoDB 数据库节点必须能够相互通信 – 包括重新编排后。副本集中的所有节点必须知道其所有对等节点的地址,但是当重新编排容器时,可能会使用不同的 IP 地址重新启动。例如,Kubernetes Pod 中的所有容器共享一个 IP 地址,当重新编排 pod 时,IP 地址会发生变化。使用 Kubernetes,可以通过将 Kubernetes 服务与每个 MongoDB 节点相关联来处理,该节点使用 Kubernetes DNS 服务提供“主机名”,以保持服务在重新编排中保持不变。

  • 一旦每个单独的 MongoDB 节点运行起来(每个都在自己的容器中),则必须初始化副本集,并添加每个节点到其中。这可能需要在编排工具之外提供一些额外的处理。具体来说,必须使用目标副本集中的一个 MongoDB 节点来执行 rs.initiate 和 rs.add 命令。

  • 如果编排框架提供了容器的自动化重新编排(如 Kubernetes),那么这将增加 MongoDB 的弹性,因为这可以自动重新创建失败的副本集成员,从而在没有人为干预的情况下恢复完全的冗余级别。

  • 应该注意的是,虽然编排框架可能监控容器的状态,但是不太可能监视容器内运行的应用程序或备份其数据。这意味着使用 MongoDB Enterprise Advanced [1] 和 MongoDB Professional [2] 中包含的 MongoDB Cloud Manager [3] 等强大的监控和备份解决方案非常重要。可以考虑创建自己的镜像,其中包含你首选的 MongoDB 版本和 MongoDB Automation Agent [4]。

使用 Docker 和 Kubernetes 实现 MongoDB 副本集

如上节所述,分布式数据库(如 MongoDB)在使用编排框架(如 Kubernetes)进行部署时,需要稍加注意。本节将介绍详细介绍如何实现。

我们首先在单个 Kubernetes 集群中创建整个 MongoDB 副本集(通常在一个数据中心内,这显然不能提供地理冗余)。实际上,很少有必要改变成跨多个集群运行,这些步骤将在后面描述。

副本集的每个成员将作为自己的 pod 运行,并提供一个公开 IP 地址和端口的服务。这个“固定”的 IP 地址非常重要,因为外部应用程序和其他副本集成员都可以依赖于它在重新编排 pod 的情况下保持不变。

下图说明了其中一个 pod 以及相关的复制控制器和服务。

未分类

逐步介绍该配置中描述的资源:

  • 从核心开始,有一个名为 mongo-node1 的容器。 mongo-node1 包含一个名为 mongo 的镜像,这是一个在 Docker Hub [5] 上托管的一个公开可用的 MongoDB 容器镜像。容器在集群中暴露端口 27107。

  • Kubernetes 的数据卷功能用于将连接器中的 /data/db 目录映射到名为 mongo-persistent-storage1 的永久存储上,这又被映射到在 Google Cloud 中创建的名为 mongodb-disk1 的磁盘中。这是 MongoDB 存储其数据的地方,这样它可以在容器重新编排后保留。

  • 容器保存在一个 pod 中,该 pod 中有标签命名为 mongo-node,并提供一个名为 rod 的(任意)示例。

  • 配置 mongo-node1 复制控制器以确保 mongo-node1 pod 的单个实例始终运行。

  • 名为 mongo-svc-a 的 负载均衡 服务给外部开放了一个 IP 地址以及 27017 端口,它被映射到容器相同的端口号上。该服务使用选择器来匹配 pod 标签来确定正确的 pod。外部 IP 地址和端口将用于应用程序以及副本集成员之间的通信。每个容器也有本地 IP 地址,但是当容器移动或重新启动时,这些 IP 地址会变化,因此不会用于副本集。

下一个图显示了副本集的第二个成员的配置。

未分类

90% 的配置是一样的,只有这些变化:

  • 磁盘和卷名必须是唯一的,因此使用的是 mongodb-disk2 和 mongo-persistent-storage2

  • Pod 被分配了一个 instance: jane 和 name: mongo-node2 的标签,以便新的服务可以使用选择器与图 1 所示的 rod Pod 相区分。

  • 复制控制器命名为 mongo-rc2

  • 该服务名为 mongo-svc-b,并获得了一个唯一的外部 IP 地址(在这种情况下,Kubernetes 分配了 104.1.4.5)

第三个副本成员的配置遵循相同的模式,下图展示了完整的副本集:

未分类

请注意,即使在三个或更多节点的 Kubernetes 群集上运行图 3 所示的配置,Kubernetes 可能(并且经常会)在同一主机上编排两个或多个 MongoDB 副本集成员。这是因为 Kubernetes 将三个 pod 视为属于三个独立的服务。

为了在区域内增加冗余,可以创建一个附加的 headless 服务。新服务不向外界提供任何功能(甚至不会有 IP 地址),但是它可以让 Kubernetes 通知三个 MongoDB pod 形成一个服务,所以 Kubernetes 会尝试在不同的节点上编排它们。

未分类

配置和启动 MongoDB 副本集所需的实际配置文件和命令可以在白皮书《启用微服务:阐述容器和编排[6]》中找到。特别的是,需要一些本文中描述的特殊步骤来将三个 MongoDB 实例组合成具备功能的、健壮的副本集。

多个可用区 MongoDB 副本集

上面创建的副本集存在风险,因为所有内容都在相同的 GCE 集群中运行,因此都在相同的可用区availability zone中。如果有一个重大事件使可用区离线,那么 MongoDB 副本集将不可用。如果需要地理冗余,则三个 pod 应该在三个不同的可用区或地区中运行。

令人惊奇的是,为了创建在三个区域之间分割的类似的副本集(需要三个集群),几乎不需要改变。每个集群都需要自己的 Kubernetes YAML 文件,该文件仅为该副本集中的一个成员定义了 pod、复制控制器和服务。那么为每个区域创建一个集群,永久存储和 MongoDB 节点是一件很简单的事情。

未分类

下一步

要了解有关容器和编排的更多信息 – 所涉及的技术和所提供的业务优势 – 请阅读白皮书《启用微服务:阐述容器和编排[7]》。该文件提供了获取本文中描述的副本集,并在 Google Container Engine 中的 Docker 和 Kubernetes 上运行的完整的说明。

使用Docker快速创建.Net Core2.0 Nginx负载均衡节点

本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws

一.Self-Host Kestrel

1、在vs2017中新建dotnet core2.0 webapi项目 ApiService

2.、参照官方文档,https://docs.microsoft.com/en-us/aspnet/core/publishing/linuxproduction?tabs=aspnetcore2x 在Startup中增加

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

配置运行Url, 在Program.cs中

未分类

3、发布项目文件,通过FTP上传到linux服务器。 一个core2.0 webapi新项目发布后只有几百kb

4、切换目录,dotnet ApiService.dll

5、运行成功,开放服务器端口,不过目前是运行于Kestrel 的selfhost 状态。

未分类

二. 需要一个代理

ASP.NET Core 的运行环境由新开发的 Kestrel Server 负责,IIS 退回到 HTTP 的侦听器的角色,微软也特别为了这个需求开发了 IIS Platform Handler,以处理 HTTP 与运行环境之间的信息转发工作,微软官方推荐在Linux服务器上使用Nginx,Haproxy等代理Kestrel Server

理解dotnet core host最重要的一点是,它独立运行。不在IIS中运行,也不需要IIS运行。它拥有独立的自宿主Web Server,在内部使用self-host server处理请求。

然而,你依然可以把IIS放在self-host server前面,作为一个前端代理,因为Kestrel是一个只拥有原始功能的web server,它并没有像iis那样完整的web server 功能,比如Kestrel不支持单个ip上,多个应用绑定80端口,IIS还可以提供静态文件服务,gzip压缩,静态文件缓存等其他高级功能,IIS在处理请求时效率非常好,,所以有必要利用这一点,您可以让iis处理它真正擅长的任务,并将动态任务传递到core应用程序。所以说在windows上,iis依然继续扮演着非常重要的角色。

在传统经典的Asp.Net应用中,所有内容都托管在iis工作进程中(w3wp.exe),这就是我们常说的应用程序池。并且应用由IIS内置托管功能加载实例化,经过工作者进程加载aspnet_isapi.dll,在用aspnet_isapi加载.Net运行时。IIS工作者进程中的应用程序池加载应用程序域。一系列工作结束后,由ISAPIRuntime对象调用PR方法,封装HttpWorkerRequest对象,传递给HttpRuntime 创建HttpApplication实例, 然后一系列HttpApplication初始化和管道事件执行。当然加载运行时,应用程序域等都只是第一个请求到达后做的事儿。

在dotnet core中很不同的是,core不会在iis工作进程中运行,而是在自己的Kestrel组件中。通过一个叫做AspNetCoreModule的原生的IIS module,执行外部的应用。Kestrel是一款针对吞吐量性能做了大量优化的dotnet web server的实现,它将网络请求快速传递给你的应用,但它仅仅是一个原始的web server,没有IIS那样全面的Web管理服务。

未分类

虽然IIS站点依然需要应用程序池,但是应该设置为无托管代码,由于应用程序池只作为转发请求的代理,因此不需要实例化.net 运行时。所以在linux上也一样,我们需要一个self-host的前端代理,在这里参考文档使用nginx。

三.nginx做代理

找到/etc/nginx配置nginx.conf

server {
    listen 80;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

我将nginx 的user改为root 5000改成自己的10000

创建service file

nano /etc/systemd/system/apiservice.service

service file的内容,官方示例:

[Unit]
Description=Example .NET Web API Application running on Ubuntu

[Service]
WorkingDirectory=/var/aspnetcore/hellomvc
ExecStart=/usr/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll
Restart=always
RestartSec=10  # Restart service after 10 seconds if dotnet service crashes
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production 

[Install]
WantedBy=multi-user.target

修改了 User为root。还修改了工作目录 就是我项目文件ftp上传后的目录,ExecStart的 dotnet这个目录不要修改 dll目录,改成目标要执行的dll的目录

然后enable service

执行 systemctl enable kestrel-hellomvc.service

start并验证service的状态

systemctl start kestrel-hellomvc.service

systemctl status kestrel-hellomvc.service

访问监听中的80端口,证明服务成功。

四.做负载均衡

按照相同的方式 我们再部署一个10001,修改nginx,配置负载均衡。

未分类

访问证明我们配置成功。

未分类

未分类

五.创建Docker Image

官方提供的dotnet core镜像位 microsoft/dotnet。docker基础命令就不提了,刚开始用也是边学边记。下面基于microsoft/dotnet image创建自己的image。以便快速运行多个docker image,配置更多的负载均衡,而无需手动copy到各个服务器上再配置环境,也就是说无论我们创建几十个甚至上百个,有我们自己的docker hub的话,创建起来是很快的,也不会出现在这台服务器上可用,在另一台服务器上搞出什么其他问题。

下面只是一个学习过程中自己的范例,离最佳实践方式还差得很远,希望能对看随笔的朋友有所帮助。

由于还要在每个image的apiService前面 放置nginx,所以 core application在各个容器中都是使用self-host的形式,在Kestrel上运行。在前端通过nginx 对docker暴露出的端口号进行代理。

在发布的网站目录下 创建Dockerfile。

未分类

保存后 执行docker构建 使用当前目录的Dockerfile创建镜像。docker build -t image/apiservice-v3 . 注意结尾有个 . (使用当前目录)

未分类

docker images 查看镜像

我们可以发现 刚创建的docker image 比我们FROM的microsoft/dotnet 大小大一点。

未分类

下面运行下看看 四行命令 运行了四个我们刚创建的image

docker run -d -p :81:20000 image/apiservice-v3

未分类

docker ps -a 查看下运行中的image进程

未分类

下面配置nginx负载均衡然后service nginx reload,实验完成。

未分类

下面使用docker kill对docker container逐一停止,停止后访问,确认负载均衡成功。当四个container都停止后,nginx返回 502 error.

未分类

使用docker一键部署MariaDB数据库只需要3分钟

摘要:MariaDB是MySQL关系数据库管理系统的一个分支. MySQL的原始开发人员在Oracle收购MySQL后提出的关注之后创建了MariaDB. …

未分类

MariaDB是MySQL关系数据库管理系统的一个分支。 MySQL的原始开发人员在Oracle收购MySQL后提出的关注之后创建了MariaDB。 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。

大多数方面,MariaDB与MySQL几乎一样。所有的命令、接口、库和APIs,存在于MySQL,也存在于MariaDB。切换到MariaDB不需要转换数据库。MariaDB是真正替代MySQL的!

目录结构如下

请看我用dockerfile构建

FROM docker.io/centos:latest
MAINTAINER zailing <[email protected]>

RUN yum clean all
RUN yum install -y yum-plugin-fastestmirror yum-utils epel-release
RUN yum update -y

# utils
RUN yum install -y git hostname sudo less iproute psmisc net-tools 
bash unzip which tar passwd ed m4 patch rsync wget curl tcpdump telnet 
tar bzip2 unzip strace supervisor openssl openssh openssh-server 
openssh-clients util-linux inotify-tools

# dev
RUN yum install -y gcc-c++ libtool make gdb mariadb-devel snappy-devel 
boost-devel lz4-devel zlib-devel libcurl-devel libevent-devel 
libesmtp-devel libuuid-devel libcsv-devel cyrus-sasl-devel 
bzip2-devel libpqxx-devel libxml2-devel libxslt-devel libxslt-python 
libpng-devel jemalloc-devel fontconfig-devel pcre-devel

# deps
RUN yum install -y redis sqlite mariadb mariadb-server postgresql

# python
RUN yum install -y python-pip python-devel python-lxml python-setuptools

RUN mkdir /var/run/sshd
RUN ssh-keygen -t rsa -q -f /etc/ssh/ssh_host_rsa_key -P ""
RUN ssh-keygen -t dsa -q -f /etc/ssh/ssh_host_dsa_key -P ""
RUN ssh-keygen -t rsa -q -f /root/.ssh/id_rsa -P ""
RUN cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys

RUN echo 'root:123456' | chpasswd
RUN sed -i 's/.*session.*required.*pam_loginuid.so.*/session optional pam_loginuid.so/g' /etc/pam.d/sshd
RUN echo -e "LANG="en_US.UTF-8"" > /etc/default/local
RUN localedef -i en_US -f UTF-8 en_US.UTF-8
RUN cp /usr/lib64/mysql/libmysqlclient* /usr/lib64/
RUN rm -rf etc/localtime && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN echo "bind '"e[A":history-search-backward'" >> /root/.bashrc
RUN echo "bind '"e[B":history-search-forward'" >> /root/.bashrc
RUN echo "export HISTTIMEFORMAT='%F %T '" >> /root/.bashrc

EXPOSE 22
RUN chmod u+s /usr/bin/ping

EXPOSE 3306

WORKDIR /usr/local/mysql
VOLUME ["/var/lib/mysql"]
VOLUME ["/etc/my.cnf.d"]

RUN mkdir -p /init
VOLUME ["/init"]

RUN yum clean all

ADD container-files /

RUN chmod +x /config/bootstrap.sh
RUN chmod +x -f /config/init/*.sh; exit 0

ENTRYPOINT ["/config/bootstrap.sh"]

docker-compose的书写格式如下 docker-compose.yml

version: '2'
services:
    mariadb:
        build: .
        image: zailing/mariadb
        container_name: mariadb
        hostname: mariadb
        privileged: true
        read_only: false
        tty: false
        network_mode: "bridge"

        ulimits:
            nofile:
                soft: 102400
                hard: 102400

        ports:
            - "127.0.0.1:2238:22"
            - "3306:3306"

        volumes:
            - /opt/docker/mariadb/data:/var/lib/mysql
            - /opt/docker/mariadb/init:/init
            - /opt/docker/mariadb/conf:/etc/my.cnf.d

        environment:
            - MYSQL_ROOT_PASSWORD=123456

MySQL物理文件组成详解

1、逻辑结构

第一层:服务层(为客户端服务,做请求连接处理,授权认证,安全)
第二层:核心层(查询解析,分析,优化,缓存,提供内建函数,存储过程,视图) 第三层:存储引擎层(做存取数据)

2、日志文件

  • 错误日志:Error Log

记录了MyQLServer运行过程中所有较为严重的警告和错误信息,以及MySQLServer 每次启动和关闭的详细信息。在默认情况下,系统记录错误日志

  • 二进制日志Binary Log & Binary Log Index

name]”打开了记录的功能之后,MySQL会将所有修改数据
库数据的query以二进制形式记录到日志文件中。当然,日志中并不仅限于query

语句这么简单,还包括每一条query所执行的时间,所消耗的资源,以及相关的事务信息

所以binlog是事务安全的

  • 更新日志:update log

其功能和 binlog 基本类似,从版本5.0 开始,MySQL 已经不再支持更新日志

  • 查询日志:query log

记录了所有的 query,包括所有的 select,体积比较大,开启后对性能也有较大的影响, 所以请大家慎用该功能。 一般只用于跟踪某些特殊的sql 性能问题才会短暂打开该功能。

  • 慢查询日志:slow query log

记录了语句执行的时刻,执行所消耗的时间,执行用户,连接主机等相关信息。分析满查询日志的工具程序mysqlslowdump, 用来帮助数据库管理人员解决可 能存在的性能问题

  • Innodb 的在线redo 日志:innodb redo log

Innodb是一个事务安全的存储引擎,其事务安全性主要就是通过在线redo
日志和记录在表空间中的undo信息来保证的。redo日志中记录了Innodb 所做的所有物理变更和事务信息,通过redo日志和undo信息,Innodb 保证了在任何情况下的事务安全性。

3、数据文件

简述:在MySQL中每一个数据库都会在定义好(或者默认)的数据目录下存在一个以
数据库名字命名的文件夹,用来存放该数据库中各种表数据文件。

  • “.frm”文件

与表相关的元数据(meta)信息都存放在“.frm”文件中,包括表结构的定
义信息等。不论是什么存储引擎,每一个表都会有一个以表名命名的“.frm”文
件。

  • “.MYD”文件

“.MYD”文件是MyISAM存储引擎专用,存放MyISAM表的数据。每一个MyISAM
表都会有一个“.MYD”文件与之对应,同样存放于所属数据库的文件夹下,
和“.frm”文件在一起。

  • “.MYI”文件

“.MYI”文件也是专属于MyISAM 存储引擎的,主要存放MyISAM 表的索引相
关信息。

  • “.ibd”文件和ibdata 文件

这两种文件都是存放Innodb 数据的文件,之所以有两种文件来存放Innodb
的数据(包括索引),是因为Innodb 的数据存储方式能够通过配置来决定是使用
共享表空间存放存储数据,还是独享表空间存放存储数据。

使用Docker多阶段构建生成更小的镜像

在使用将源码直接打为Docker镜像的时候,经常纠结的问题就是如何获得更小的镜像。

以一个java项目为例,因为java编译的时候需要jdk,而运行的时候只需要jre。同时由于各种构建工具的存在(比如gradle),下载的构建用的文件也很多,不光是maven的依赖,还有wrapper和一些临时文件。

之前的做法一直是使用两个Dockerfile,其中一个使用jdk构建出需要的jar文件,然后第二个使用jre直接将jar文件复制进去。虽然效果不错,但是还是觉得麻烦。

今天使用Daocloud的时候看到了安全构建这个选项(本质就是两段构建),就突然想到Docker会不会已经有了。结果一搜索还真有,亏我还用多Dockerfile构建了很长时间。

大概使用如下:

FROM openjdk:8 AS build-env
ADD . /java/src/app
WORKDIR /java/src/app
RUN gradlew build

FROM openjdk:jre
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
COPY --from=build-env /java/src/app/build/libs/target.jar /usr/local/bin/app-server
EXPOSE 8080
CMD ["app-server"]

Docker支持的是多阶段构建,所以如果有需要的话,可以从多个不同的构建中获得生成物。

Nginx配合docker安装nextcloud(超简易)|抛弃owncloud

Nextcloud是owncloud母公司破产前核心人员离职出来创建的,免费版里包含了很多owncloud付费版本的功能,因为核心都是一样的,所以我们当然可以选择功能更多的nextcloud版本了。

我安装的nextcloud网盘:https://nextpan.net

安装docker

在使用本教程前,建议您对docker进行一些基本的了解,知道一些简单的命令,比如:

docker images
docker ps –a
docker start
docker stop
docker rm
docker rmi

不了解docker的可以谷歌一下这些命令快速了解,也可以看官方的docker教程。

docker官方安装教程:https://store.docker.com/search?type=edition&offering=community

我贴一下Ubuntu系统的安装方式,依次输入下列命令:

sudo apt–get –y install
  apt–transport–https
  ca–certificates
  curl
curl –fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
sudo add–apt–repository
       “deb [arch=amd64] https://download.docker.com/linux/ubuntu
       $(lsb_release -cs)
       stable”
sudo apt–get update
sudo apt–get –y install docker–ce

安装docker-compose

docker-compose是定义和运用docker的一种工具,使用下列命令安装:

apt install docker–compose

安装完成后,新建docker-compose.yml文件:

vim docker–compose.yml

然后把下列内容复制粘贴,注意这里我选用的是wonderfall的版本,他的版本star数最多,比官方的新,另外注意,修改pwd为自己的密码:

nextcloud:
  image: wonderfall/nextcloud
  links:
    – nextcloud–db:nextcloud–db  
  environment:
    – UID=1000
    – GID=1000
    – UPLOAD_MAX_SIZE=10G
    – APC_SHM_SIZE=128M
    – OPCACHE_MEM_SIZE=128
    – CRON_PERIOD=15m
    – TZ=Aisa/Shanghai
    – ADMIN_USER=admin            
    – ADMIN_PASSWORD=pwd  
    – DOMAIN=localhost
    – DB_TYPE=mysql
    – DB_NAME=nextcloud
    – DB_USER=nextcloud
    – DB_PASSWORD=pwd
    – DB_HOST=nextcloud–db
  volumes:
    – /docker/nextcloud/data:/data
    – /docker/nextcloud/config:/config
    – /docker/nextcloud/apps:/apps2
    – /docker/nextcloud/themes:/nextcloud/themes
  ports:
    – 127.0.0.1:8888:8888/tcp
nextcloud–db:
  image: mariadb:10
  volumes:
    – /docker/nextcloud/db:/var/lib/mysql
  environment:
    – MYSQL_ROOT_PASSWORD=pwd
    – MYSQL_DATABASE=nextcloud
    – MYSQL_USER=nextcloud
    – MYSQL_PASSWORD=pwd

然后在docker—compose.yml所在文件夹里,输入以下命令:

docker–compose up –d

这时候docker版本的nextcloud就已经安装好了,端口是127.0.0.1:8888,我们接下来利用nginx反代这个端口,并且加上https,从而能让外网安全的访问。

安装nginx

apt install nginx

安装letsencrypt

apt install letsencrypt

生成证书

注意替换域名

letsencrypt certonly —webroot –w /var/www/html —domain “abc.example.com”

配置nginx

可以修改默认的,也可以新建一个配置文件,我这里直接修改默认的

vim /etc/nginx/sites–available/default

删掉里面的内容,复制粘贴进这个,注意你的letsencrypt生成的证书路径对不对,一般只需要改一下domain就行了:

server {
  listen 80;
  server_name abc.example.com;
  return 301 https://$host$request_uri;
}
server {

    server_name nextpan.net www.nextpan.net;
    listen 443 ssl http2;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/abc.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/abc.example.com/privkey.pem;
    include /etc/nginx/conf/ssl_params.conf;
    client_max_body_size 10G;
    location / {
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8888;
        proxy_set_header Host $http_host;
    }
    location = /.htaccess {
        return 404;
    }
}

重启nginx:

service nginx restart

然后输入自己的域名就可以直接登陆了。

如果想更新,只需要删掉nextcloud和mariadb的container,重新docker-compose up -d就可以了。

使用Docker配置Flask开发环境

使用Docker+docker-compose,配置最简Flask开发环境

工具

  • Docker
    一种开源容器应用,供开发者打包自己的开发环境,可以任意移植

  • docker-compose
    一种管理多个Docker容器的工具,可以简化我们启动容器的各种命令

配置文件

首先我们需要一个python基础景象,Docker各种基础镜像都可以从官方找到 https://hub.docker.com/_/python/ 。找到基础镜像之后就可以基于它做相应的配置,这些操作都记录在Dockerfile中。

Dockerfile:

FROM python:3.6-slim # 官网中挑选的python基础镜像

ADD requirements.txt requirements.txt # requirements.txt罗列了需要安装的python模块,将文件复制到容器中

RUN pip install -r ./requirements.txt # 执行模块安装

EXPOSE 5000 # 对外暴露5000端口

requirements.txt

Flask # 需要安装的python模块,如有其他需要安装的模块,如下依次写入。
# redis 
# pymongo

配置完Dockerfile之后,开始配置docker-compose文件。

docker-compose.yml

web:
  build: ../../dockerfile/python/3 # DockerFile所在目录
  ports:
    - "5000:5000" # 对外暴露端口,与Dockerfile中端口号一致
  volumes:
    - ~/workspace/python/redis:/code # 本地工作目录与容器中目录映射
  command:
    - /code/app.py # 处理请求的python脚本

app.py

#!/usr/bin/env python

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Flask Dockerized'

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')

容器启动

在docker-compose.yml所在文件夹执行命令 docker-compose up ,在控制台中看到如下输出:

Starting flash_web_1 ...
Starting flash_web_1 ... done
Attaching to flash_web_1
web_1  |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1  |  * Restarting with stat
web_1  |  * Debugger is active!
web_1  |  * Debugger PIN: 166-703-177

同时在浏览器中输入 localhost:5000 ,并正常显示文本 Flask Dockerized ,环境就配置成功啦!对应的log都可以在启动容器的终端中查看到。例如:

web_1  | 172.17.0.1 - - [13/Sep/2017 13:18:17] "GET / HTTP/1.1" 200 -
web_1  | 172.17.0.1 - - [13/Sep/2017 13:18:17] "GET /favicon.ico HTTP/1.1" 404 -

总结

以上配置了最简的Flask开发环境,实际开发中还需要数据库、缓存、nginx等,这些基础容器都可以在Docker官网中找到,并使用docker-compose可以很清晰的将这些容器关联起来。

Ubuntu16.04安装docker

要想使用最新版本的docker需要由以下方法安装

通过docker源安装最新版本

依次输入以下命令

$ sudo apt-get install apt-transport-https
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys     36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker

安装之后启动docker服务

$ sudo service docker start

卸载docker

卸载Docker包:

$ sudo apt-get purge docker-engine

卸载Docker包及其以来不再需要使用下面的命令:

$ sudo apt-get autoremove --purge docker-engine

上面的命令不会移除镜像,容器,卷或者是用户创建的配置文件。如果你想删除所有的镜像,容器和卷,运行下面的命令:

$ rm -rf /var/lib/docker

你必须手动删除用户创建的配置文件。

[docker] 制作base镜像并上传至docker.io

本文在Debian下完成,用于笔记:

制作base镜像

  • 安装debootstrap:
apt-get install debootstrap
  • 安装额外的软件包并制作rootfs:
debootstrap --include=openssh-server --arch i386 wheezy debian-wheezy http://httpredir.debian.org/debian
  • 打包镜像并导入到docker:
tar -c . |docker import - debian-wheezy-i386

上传至docker.io

  • 注册账号.
  • 创建空间.
vicer/debian-wheezy-i386
  • 登陆到Docker Hub:
docker login
  • 创建标签:
#docker tag <imageID> <namespace>/<image name>:<tag>
docker tag debian-wheezy-i386 vicer/debian-wheezy-i386
  • 上传镜像:
#docker push <namespace>/<image name>
docker push vicer/debian-wheezy-i386