docker离线安装

背景

最近在做私有化部署项目,项目的整体方案基于docker。考虑到客户的运行环境可能无法连接到公网,因此需要制作docker的离线安装。整个离线安装分为三个部分:1)准备docker离线安装包,2)docker离线源配置,3)离线安装docker

准备docker离线安装包

目前只考虑Linux及其发行版的服务器。docker对于机器和操作系统的要求:

  • 内核版本3.10及其以上
  • 操作系统位数为64位
  • CPU架构为x86_64或amd64(目前也有别的支持)
  • 内核开启并支持cgroup和命名空间

简单点说来,常用的 CentOS 7及其以上,Ubuntu 14及其以上,Fedora 24及其以上,Debian 8及其以上,还有 Raspbian 等。这个部分具体可以参考[1]。这个是docker官方的在线安装脚本,本文中的内容主要也是参考这个脚本。

对于不同的操作系统,不同的架构,需要的docker安装包不同,所以要分开处理。目前主流的包管理工具是 apt-get 和 yum,这两者也分别对应到UbuntuDebian和CentOSFedora系列操作系统。不管是哪种包管理工具,基本思路都是

  1. 下载docker安装包及其依赖
  2. 对下载下来的安装包制作本地源
  3. 准备本地源配置文件

对于 apt-get 来说,可以执行以下脚本,该脚本抽取自参考链接[1]。对于流程的解释可以参考链接[2]

#!/bin/sh

lsb_dist="ubuntu"
dist_version="xenial"   # 14-trusty 16-xenial 17-zesty

DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
DOWNLOAD_DIR="/home/work/docker-packages/$lsb_dist-$dist_version"

set -e
apt_repo="deb [arch=$(dpkg --print-architecture)] $DOWNLOAD_URL/linux/$lsb_dist $dist_version stable"

if [ ! -x "$DOWNLOAD_DIR" ]; then
    mkdir -p "$DOWNLOAD_DIR"
fi

apt-get update -qq >/dev/null
apt-get install -y -qq apt-transport-https ca-certificates curl dpkg-dev > /dev/null
curl -fsSL "$DOWNLOAD_URL/linux/$lsb_dist/gpg" | apt-key add - > /dev/null
echo "$apt_repo" > /etc/apt/sources.list.d/docker.list
if [ "$lsb_dist" = "debian" ] && [ "$dist_version" = "wheezy" ]; then
    sed -i "/deb-src.*download.docker/d" /etc/apt/sources.list.d/docker-ce.list
fi
# 只下载docker和依赖的安装包
apt-get update -qq >/dev/null
apt-get --download-only -o Dir::Cache="./" -o Dir::Cache::archives=$DOWNLOAD_DIR install -y --no-install-recommends docker-ce > /dev/null

# 为安装包建立索引,方便后续加载为本地源安装
touch $DOWNLOAD_DIR/Packages.gz
dpkg-scanpackages $DOWNLOAD_DIR /dev/null | gzip > $DOWNLOAD_DIR/Packages.gz

我在制作的时候,对于生成的Packages.gz,调整里面每一个软件的 Filename 项,只留下软件名,不保留前面的目录路径。具体可以使用sed命令。

对于 yum 来说,可以执行以下脚本,该脚本也抽取自参考链接[1]。对于流程的解释可以参考链接[3]

#!/bin/sh

lsb_dist="centos"
dist_version="7"

DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
DOWNLOAD_DIR="/home/work/docker-packages/$lsb_dist-$dist_version"

set -e
yum_repo="$DOWNLOAD_URL/linux/$lsb_dist/docker-ce.repo"

if [ ! -x "$DOWNLOAD_DIR" ]; then
    mkdir -p "$DOWNLOAD_DIR"
fi

# 只下载docker和依赖的安装包
yum-config-manager --add-repo $yum_repo
yum makecache
yum install --downloadonly --downloaddir=$DOWNLOAD_DIR docker-ce

# 为安装包建立索引,方便后续加载为本地源安装
createrepo $DOWNLOAD_DIR

准备docker离线源配置

将刚刚准备好的安装包内容($lsb_dist-$dist_version这个目录下)拷贝到目标机器上,比如统一放到/home/work/docker-packages目录下。基于这个路径:

对于 apt-get 系的离线源配置文件为 docker-ce.list,内容如下

deb [trusted=yes] file:/home/work/docker-packages ./

对于 yum 系的离线源配置文件为 docker-ce.repo,内容如下

[Local_docker_yum]
name=Local Docker Yum Repository
baseurl=file:///home/work/docker-packages/
enabled=1
gpgcheck=0

离线安装docker

对于 apt-get 将离线源配置文件 docker-ce.list 拷贝到 /etc/apt/sources.list.d 目录下。如果电脑不能联网,先将 /etc/apt/sources.list 文件重命名;然后执行apt-get update;再把刚刚重命名的 /etc/apt/sources.list 改回来。如果不这么改的话,在apt-get update的时候可能联网失败而无法完成更新。

最后执行 apt-get install docker-ce

对于 yum 将离线源配置文件 docker-ce.repo 拷贝到 /etc/yum.repos.d/ 目录下。如果电脑不能联网,先将 /etc/yum.repos.d/ 目录下其他配置文件重命名;然后执行 yum makecache;最后再把刚刚重命名的文件改回来。这么做的理由同上。

最后执行 yum install docker-ce

使用 Vagrant 管理虚拟机

未分类
使用 Vagrant 可以很方便的管理虚拟机,只需要一行命令可以操作管理虚拟机,也可以重新打包成新的镜像,分享他人使用。

安装 Vagrant

可以通过 Homebrew 使用命令行安装,可以直接去 Vagrant 官网(https://www.vagrantup.com)下载安装包手动安装。

// 命令行安装 Vagrant
brew install Caskroom/cask/vagrant 

虚拟机需要用到虚拟机软件,比如 Virtualbox,VMware,Parallels Desktop 等等,因为 Virtualbox 开源且免费,所以此处使用 Virtualbox。安装 Virtualbox 同样可以通过命令行或者官网(https://www.virtualbox.org)下载安装包手动安装。

// 命令行安装 Virtualbox
brew install Caskroom/cask/virtualbox

Vagrant Box

Box 是 Vagrant 使用的一种包含虚拟机镜像、虚拟机配置和 Vagrant 配置的封装包文件。在 Vagrant 提供的云服务(https://vagrantcloud.com/)上可以下载到其他人制作好的 Box。

添加 Box

Vagrant 添加 Box 的命令为:

vagrant box add <name>

此处以 CentOS 7 为例,如果指定的 Box 在本地电脑上不存在,Vagrant 会到云上自动下载执行:

vagrant box add centos/7

安装成功后界面如下:

未分类

完成以后,可以查看一下在本地上的 Box 列表:

vagrant box list

也可将 Box 手动下载到本地电脑上,再执行 vagrant box add 命令去手工添加 Box:

vagrant box add <name> <path>

升级 Box

检查是否有可用的升级,执行命令:

vagrant box outdated

返回:

Checking if box 'centos/7' is up to date...

执行升级:

vagrant box update

删除 Box

不再需要的镜像可以从电脑中删除掉,执行:

vagrant box remove <box name>

即使你删除了安装在电脑上的镜像,已经使用这个镜像创建的我虚拟机也仍然是可以正常使用的。不过为了更安全一些,你最好在删除镜像之前 ,先去销毁所有使用了这个镜像创建的虚拟机。

创建虚拟机

添加了 Box 以后,我们就可以用 Vagrant 基于这个 Box 去创建虚拟机了。首先需要创建一个目录,这个目录就是项目所在的目录,它会自动跟虚拟机上的某个目录同步,也就是在你电脑上的这个目录里的文件,同样可以在虚拟机里面的某个目录里找到。

我是在桌面上新建了一个 www 有目录,然后再进入到这个目录:

cd ~/desktop
mkdir www
cd www

然后使用 vagrant init 命令进行初始化,完成以后,在上面建的目录中会创建一个叫 Vagrantfile 的文件。

启动虚拟机

启动虚拟机,执行命令:

vagrant up

完成以后,可以使用 vagrant status 命令来查看虚拟机的状态,如果返回的是 running 说明虚拟机启动成功,现在就可以使用 SSH 连接到虚拟机,去控制它了。

控制虚拟机

使用命令行控制虚拟机,首先需要进入到项目的目录。

连接虚拟机 SSH,执行命令:

vagrant ssh

连接成功后,会返回提示符:

[vagrant@localhost ~]$

退出虚拟机 SSH,执行命令:

exit

暂停虚拟机,执行命令:

vagrant suspend

重新恢复启动,执行命令:

vagrant resume

虚拟机重启,执行命令:

vagrant reload

关闭虚拟机,执行命令:

vagrant halt

删除虚拟机

不打算再用的虚拟机,可以把它删除,直接删除项目的目录是不行的,需要使用命令去删除虚拟机。进行到项目所在目录,然后执行:

vagrant destroy

#EOF

awk获取文本的某一行,某一列

打印文件的第一列(域)  awk '{print $1}' filename
打印文件的前两列(域)  awk '{print $1,$2}' filename
打印完第一列,然后打印第二列  awk '{print $1 $2}' filename
打印文本文件的总行数  awk 'END{print NR}' filename
打印文本第一行       awk 'NR==1{print}' filename
打印文本第二行第一列  sed -n "2, 1p" filename | awk 'print $1'

Bash里面的赋值方法有两种,格式为

1) arg=`(命令)`
2) arg=$(命令)

想要把某一文件的总行数赋值给变量nlines,可以表达为:

1) nlines=`(awk 'END{print NR}' filename)`
或
2) nlines=$(awk 'END{print NR}' filename)

——EOF——

修改Nginx与Apache上传文件大小限制

修改 Nginx 上传文件最大值限制

我们使用 ngnix 做 web server 的时候,nginx 对上传文件的大小有限制。

这个时候我们要修改 nginx 参数。

sudo vim /etc/nginx/nginx.conf 
#在http段里面添加:
client_max_body_size 100m;  //举例设置上传最大值为100m

然后重启nginx

systemctl restart nginx

修改 Apache 上传文件最大值限制

打开 php.ini, 找到下面的项并修改之。下面以上传100M为例。

sudo vim /etc/php.ini
file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开 
upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹 
upload_max_filesize = 100m ;望文生意,即允许上传文件大小的最大值。默认为2M 
post_max_size = 100M ;指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值。默认为8M

一般地,设置好上述四个参数后,上传<=8M的文件是不成问题,在网络正常的情况下。

但如果要上传>8M的大体积文件,只设置上述四项还一定能行的通。除非你的网络真有100M/S的上传高速,否则你还得关心关心下面的参数:

max_execution_time = 600 ;每个PHP页面运行的最大时间值(秒),默认30秒 
max_input_time = 600 ;每个PHP页面接收数据所需的最大时间,默认60秒 
memory_limit = 128M ;每个PHP页面所吃掉的最大内存,默认8M

全部设置好之后,重启

systemctl restart httpd

CentOS下apache绑定域名

本文主要介绍在CentOS下apache绑定域名以及apache绑定多个域名,首先要找到apache的配置文件httpd.conf的位置。CentOS操作系统一般在 /etc/httpd/conf 下,有的Linux操作系统版本是在 /etc/Apache2/conf 或 /usr/local/etc/apache 文件夹里面,剩下需要做的是修改配置文件httpd.conf,一般配置文件最下面有如下绑定域名说明:

# VirtualHost example:  
# Almost any Apache directive may go into a VirtualHost container.  
# The first VirtualHost section is used for requests without a known  
# server name.  
#  
#<VirtualHost *:80> 
#    ServerAdmin [email protected]  
#    DocumentRoot /www/docs/dummy-host.example.com  
#    ServerName dummy-host.example.com  
#    ErrorLog logs/dummy-host.example.com-error_log  
#    CustomLog logs/dummy-host.example.com-access_log common  
#</VirtualHost> 

大家可以依葫芦画瓢,也可以结合相关语法加入自己的配置说明,下面是我无忧程序的配置文件:1、* 星号修改成自己网站的IP地址 2、ServerAdmin管理员邮箱(可有可无) 3、DocumentRoot网站文件在服务器的目录路径 4、ServerName绑定相应域名 5、ServerAlias泛解析绑定子域名 6、ErrorLog和CustomLog指定日志文件存放路径。

<VirtualHost 175.102.8.117:80> 
    addDefaultCharset gbk  
    DocumentRoot /chengxu 
    ServerName 66php.com  
    ServerAlias *.66php.com  
    ErrorLog /sym/logs/66php.com-error_log  
    CustomLog /sym/logs/66php.com-access_log common  
</VirtualHost> 

如果一个服务器绑定多个域名不是在ServerName添加多个域名,ServerName 后面只能加一个域名,要重复绑定则需要添加多加多个VirtualHost模块。

Apache/Httpd安装mod_pagespeed加速模块

mod_pagespeed是谷歌发布的加速httpd的优化模块,通过自动优化代码、压缩传输内容、自动缓存加速http,支持Centos/Debian系统

Centos/Fedora下安装:

    #http://www.haiyun.me  
    #32位  
    wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i386.rpm  
    #64位  
    wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_x86_64.rpm  
    yum install at  rpm -U mod-pagespeed-*.rpm

Debina/Ubuntu下安装:

    #32位  
    wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i386.deb  
    #64位  
    wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_x86_64.deb  
    dpkg -i mod-pagespeed-*.deb

重启httpd:

service httpd restart

查看pagespeed是否加载:

httpd -M|grep pagespeed

记录一次Tshark使用异常

记录备忘!

使用tshark抓包时,出现以下异常:

Running as user “root” and group “root”. This could be dangerous. 
Capturing on ‘enp3s0’ 
tshark: The file to which the capture would be saved (“tmp1/test.pcap”) could not be opened: Permission denied.

问题描述:

tshark抓包时必须以root身份运行,在普通用户模式下以sudo su 切换到root身份时,运行报错.

问题原因:

ls -lst 查看权限如下:

drwxr-xr-x 2 yk opuser 4096 Dec 4 16:53 tmp1 

该目录的所有者并非root,也没有提供其他用户的使用权。修改目录权限使root拥有写入权限即可.

chmod o+w tmp1 

权限不一定修改为o,同组时也可以使用g.
或者直接使用root身份创建目录.
如果是多级目录,只修改最下一级目录是不能解决问题的,必须将目标路径上的目录的权限全修改.
再次运行即可解决问题.

APACHE显示目录列表的配置方法

我们可以通过修改Apache配置文件httpd.conf来实现显示文件目录列表,代码如下:

    DocumentRoot  "c:www"

    Options Indexes
    AllowOverride All
    Order allow,deny
    IndexOptions Charset=UTF-8
    Allow from all

注意:”D:WWW”是网站的根目录,参数”Options Indexes”表示启用目录浏览,”IndexOptions Charset=UTF-8″设置字符集,以消除中文乱码。

如果是添加的虚拟主机站点,加在虚拟主机配置文件vhosts.conf内修改以下代码:

    Options Indexes
    AllowOverride All
    Order allow,deny
    IndexOptions Charset=UTF-8
    Allow from all

其中”D:www.test.com”为所添加虚拟主机站点的根目录,”Options Indexes”表示启用目录浏览。

修改好,保存,重启Apache服务,就可以了,如下图:

未分类

OpenResty 访问系统环境变量

在编写程序时,我们经常会依据不同的环境使用不同的配置,之前一直以为 OpenResty 无法访问系统的环境变量,所以使用一种很 low 的方式去加载不同环境的配置。现在才发现自己还是对 Nginx 配置了解的不够全。其实 Nginx 的核心功能中就存在一个 env指令,可以实现我们的需求。下面来说明下这个 env 指令。

env

Syntax: env variable[=value];
Context: main

默认情况下,nginx 会移除所有从父进程继承的环境变量,如果你想使用这些环境变量,需要使用该指令显示告知nginx不要移除你指定的环境变量。而且你也可以更改它们的值或创建新的环境变量。

例如

env PROJECT_MODE;
# 也可以使用env PROJECT_MODE=DEV; 来覆盖父进程的环境变量

则 nginx 会保留系统的 PROJECT_MODE 环境变量,
然后在lua脚本中,我们就可以通过 lua 的os.getenv()来获取对应的环境变量了,并依据不同的环境使用不同的配置

# config.lua
local env = os.getenv("PROJECT_MODE")
local config = {}
-- 开发环境配置
if env == "DEV" then

-- 生产环境配置
elseif env == "PROD" then

end

return config

配置搭建阿里云服务器nginx+uwsgi (python)

关于使用nginx+uwsgi搭建web服务器,网上有很多教程,但是对新手来说都有些不好理解。下面我总结了一下,纯基础、好使。

首先理解一些基本概念:

WSGI是什么?

WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。自从 WSGI 被开发出来以后,许多其它语言中也出现了类似接口。

WSGI 的官方定义是,the Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。

uWSGI是什么?

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

nginx、uwsgi、flask之间的关系

  • 首先nginx 是对外的服务接口,外部浏览器通过url访问nginx

  • nginx 接收到浏览器发送过来的http请求,将包进行解析,分析url,如果是静态文件请求就直接访问用户给nginx配置的静态文件目录,直接返回用户请求的静态文件。如果是动态那么nginx就将请求转发给uwsgi,通过flask框架转换为某一函数或者方法进行调用,并处理后,返回给uwsgi。uwsgi转发给nginx,nginx最终将返回结果返回给浏览器。

  • 由此可见nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程。但是要考虑到某些情况。

  • 安全问题程序不能直接被浏览器访问到,而是通过nginx,nginx只开放某个接口,uwsgi本身是内网接口,这样运维人员在nginx上加上安全性的限制,可以达到保护程序的作用。

  • 负载均衡问题一个uwsgi很可能不够用,即使开了多个work也是不行,毕竟一台机器的cpu和内存都是有限的,有了nginx做代理,一个nginx可以代理多台uwsgi完成uwsgi的负载均衡。

  • 静态文件问题用django或是uwsgi这种东西来负责静态文件的处理是很浪费的行为,而且他们本身对文件的处理也不如nginx好,所以整个静态文件的处理都直接由nginx完成,静态文件的访问完全不去经过uwsgi以及其后面的东西。

好的接下来直接进入搭建过程。 首先你得有一台服务器。这个是我自己的阿里云esc服务器。然后通过ssh root@云服务器ip地址,然后输入密码进行登录。

安装 Python 环境

不多说,一般系统都自带python环境以及pip

安装Nginx

pip install nginx

或者

yum install nginx

安装VirtualEnv

不同的项目可能会引用各种不同的依赖包,为了避免版本与和应用之间的冲突而造成的“依赖地狱”。VirtualEnv 可以为每个Python应用创建独立的开发环境,使他们互不影响。

pip install virtualenv

安装VirtualEnv 后只需要在项目目录内运行 virtualenv 目录名 就可以建立一个虚拟环境文件夹。 假定我的项目目录叫 /home/www/myproj进入该目录后运行

virtualenv venv

项目目录下得到新的venv目录即虚拟环境 (虚拟环境目录可以叫venv,自己随意)

输入

source venv/bin/activate 

进入虚拟环境,前面多了虚拟目录名(venv)

安装 uWSGI

pip install uwsgi

安装 Flask

pip install flask

项目文件

假设到现在为止项目里面只有一个最简单的文件 hello.py,里面内容如下:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"

配置uwsgi

同志们,项目的准备工作准备的差不多了。接下来就是一些配置问题(哎,以前碰到的坑巨多)。

好,在项目目录下新建一个uwsgi.ini

touch uwsgi.ini

创建好了以后,用vim在uwsgi.ini写入以下内容:

[uwsgi]
master = true
home=/home/www/myproj/venv
wsgi-file = hello.py
callable = app
socket=127.0.0.1:5000
stats=127.0.0.1:9191
processes = 4
threads = 4
buffer-size=32768

运行uwsgi试试,如果输出类似以下信息,说明成功。

uwsgi --ini uwsgi.ini
(venv)my_flask root$ uwsgi uwsgi.ini

[uWSGI] getting INI configuration from uwsgi.ini

*** Starting uWSGI 2.0.8 (64bit) on [Tur Sep 19 14:34:11 2017] 
// 此处略去那些无用的启动信息
Stats server enabled on 127.0.0.1:9191 fd: 15 ***

ok,uwsgi已经配置完成,ctrl+c 关闭程序。

配置Nginx

找到配置文件nginx.conf(我的在目录/etc/nginx/nginx.conf),修改以下部分

server {
        charset      utf-8;
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  xxxx域名地址
        root         /home/www/myproj;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
           include      uwsgi_params;
           uwsgi_pass   127.0.0.1:5000;
           uwsgi_param UWSGI_PYHOME /home/www/myproj/venv;
           uwsgi_param UWSGI_CHDIR  /home/www/myproj;
        }
    }

启动Nginx服务器、启动uwsgi服务器

这个地方要注意,我在这卡了我1天。因为有俩个服务器,所以俩个都要启动。

service nginx restart

uwsgi --ini uwsgi.ini

大功告成