2019年3月13日 星期三

hyper-v 安裝CentOS 7.6

Windows 10 Pro 內建 Hyper-v
安裝 CentOS 7.6 + PHP 7.3 + nginx + laravel 5.8

安裝Hyper-v 和 WSL( Windows Subsystem for Linux ) - 略
ps. WSL可以在Microsoft Store 搜尋Linux 下載不同版本Linux(Kali、ubuntu、Debian...)等Subsystem
ps. Hyper-v 和安卓的夜神模擬器nox無法同時執行,Windows會報錯SYSTEM_SERVICE_EXCEPTION 藍色畫面
https://www.reddit.com/r/windows/comments/9wdmcc/help_bsod_when_i_start_nox_player_hyperv_enabled/
NOX cannot run when Hyper-V is enabled.
ps. BlueStacks 和 Hyper-v 也無法同時執行


該使用WSL還是Hyper-v?
結論:你不應該使用WSL
1. Microsoft did not design or build WSL for production workloads.
微軟設計WSL不是為了生產環境
2. Running a virtual machine (VM) can be more efficient.
虛擬機更高效
3. 4. 5. 略

Windows 10 啟用hyper-v

https://www.itread01.com/content/1550134651.html  WIN10 Hyper-V 安裝 CentOS 7
https://dotblogs.com.tw/gelis/2010/07/30/16892  開啟Hyper-V的內部虛擬網路

下載Minimal版本

開啟hyper-v 功能

設定 =》 應用程式 =》 應用程式與功能 =》 選用功能 =》 更多Windows功能 =》 開啟hyper-v
(開啟後需重開機)

新增虛擬交換器

hyper-v 管理員 =》 虛擬交換器管理員 =》 新虛擬網路交換器 =》 新增【外部網路】,選擇有線網卡


虛擬機器 =》 設定 =》 網路界面卡 =》 選擇剛剛新增的【外部網路】虛擬交換器

新裝的機器要有網路

開機自動啟動eth0網路
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
ONBOOT=no
ONBOOT=yes


hyper-v 虛擬交換器 使用「外部網路」,(ThinkPad T460)不要使用無線網卡,使用網路線連接區域連線,不然虛擬機和win 10 hosts會同一個內網ip,win 10 SSH連不上虛擬機

Hyper-v 儲存後即使重開Windows 10 ,再重開虛擬機器,工作狀態還在,等於沒有重開虛擬機

安裝完CentOS 7.6後


安裝一些常用package
# yum install vim epel-release screen git bash-completion telnet
裝完bash-completion後讓root可以正常使用
# source /etc/profile.d/bash_completion.sh
查裝什麼package才能用netstat
# yum provides */netstat
安裝net-tools以使用netstat
# yum install net-tools

升級git

因為yum安裝的git版本是1.8.3.1 ,用以下方法安裝2.x 最新版本的git

移除git

# yum -y remove git

新增 End Point 倉庫

# yum -y install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.9-1.x86_64.rpm
然後安裝2.x版本的git
# yum install git

檢查

# git --version
git version 2.30.1

End Point 倉庫過期造成yum無法更新

# yum update
...
https://packages.endpoint.com/rhel/7/os/x86_64/repodata/repomd.xml: [Errno 14] curl#6 - "Could not resolve host: packages.endp
oint.com; Unknown error"

解法

# yum-config-manager --disable endpoint

安裝php、php-fpm、nginx

安裝remi
# yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
如果你要最新的php 7.3.x,必須這樣做
# yum --enablerepo=remi,remi-php73 update -y
查remi的版本
# yum info remi-release
開啟remi-php73
# yum-config-manager --enable remi-php73
安裝php7.3
# yum install php73-php
使php能夠呼叫到php 7.3 bash ( 直接加到.bashrc 可以自動enable )
# source /opt/remi/php73/enable
查php版本
# php -v
PHP 7.3.3 (cli) (built: Mar  5 2019 13:50:38) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.3, Copyright (c) 1998-2018 Zend Technologies
安裝 php 7.3的php-fpm
# yum install php73-php-fpm
安裝nginx
# yum install nginx
啟動php-fpm
# systemctl start php73-php-fpm
查php-fpm狀態
# systemctl status php73-php-fpm
啟動nginx
# systemctl start nginx
查nginx 開機是否自動啟動
# systemctl is-enabled nginx
disabled
開機自動啟動nginx、php-fpm
# systemctl enable nginx
# systemctl enable php73-php-fpm.service

訪問網頁不通時,打開80 port
# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
# firewall-cmd --reload
success
檢查配置是否生效
# iptables-save | grep 80
-A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT

關閉端口

https://docs.fedoraproject.org/en-US/quick-docs/firewalld/  Using firewalld
# firewall-cmd --remove-port=port-number/port-type
# firewall-cmd --runtime-to-permanent
如:
# firewall-cmd --remove-port=80/tcp
# firewall-cmd --runtime-to-permanent

查當前zone開放的端口

# firewall-cmd --list-ports


下載composer-steup.php
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# ls
anaconda-ks.cfg  composer-setup.php
# php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Installer verified
安裝composer
# php composer-setup.php
All settings correct for using Composer
Downloading...

Composer (version 1.8.4) successfully installed to: /root/composer.phar
Use it: php composer.phar
# ls
anaconda-ks.cfg  composer.phar  composer-setup.php
刪除 composer-setup.php
# php -r "unlink('composer-setup.php');"
讓composer方便呼叫
# mv composer.phar /usr/local/bin/composer
# which composer
/usr/local/bin/composer

更新composer

$ composer --version
Composer version 1.7.2
$ composer self-update
Updating to version 1.8.5 (stable channel).
   Downloading (100%)
Use composer self-update --rollback to return to version 1.7.2

加速composer

$ composer global require hirak/prestissimo
...
    Failed to download hirak/prestissimo from dist: The zip extension and unzip command are both missing, skipping.
Your command-line PHP is using multiple ini files. Run `php --ini` to show them.
    Now trying to download from source
解決上面黃底的錯誤
# yum install zip unzip php73-php-pecl-zip

安裝 https://laravel.com/docs/5.8/installation  上laravel 5.8 必裝的php extension
檢查php extension有無安裝
# php -m | grep mbstring

安裝laravel 5.8需要的php extension

# yum install php73-php-pdo
# yum install php73-php-mbstring
# yum install php73-php-xml
# yum install php73-php-bcmath

安裝Xdebug

# yum install php73-php-pecl-xdebug

xdebug.ini報 invalid ELF header 錯誤

$ php --ini | grep xdebug
Failed loading /etc/opt/remi/php73/php.d/15-xdebug.ini:  /etc/opt/remi/php73/php.d/15-xdebug.ini: invalid ELF header
Additional .ini files parsed:      /etc/opt/remi/php73/php.d/15-xdebug.ini,
解法:
重新安裝php73-php-common
# yum remove php73-php-common
# yum install php73-php php73-php-fpm php73-php-pdo php73-php-mbstring php73-php-xml php73-php-bcmath php73-php-pecl-xdebug 
當然 php73-php-fpm 需重啟和重新enable
# systemctl start php73-php-fpm
# systemctl enable php73-php-fpm.service

讓XDebug  CLI 生效

.bashrc 加入
export XDEBUG_CONFIG="remote_host=192.168.1.7 idekey=PHPSTORM"
export PHP_IDE_CONFIG="serverName=localhost"
/etc/opt/remi/php73/php.d/15-xdebug.ini 修改:
xdebug.remote_enable = true


安裝 php-process

如果你要用workerman需要安裝php-process,否則啟動時會報錯
Uncaught Error: Call to undefined function posix_getpid()
# yum install php73-php-process

安裝memcached擴展

# yum install php73-php-pecl-memcached

安裝pdo_mysql擴展

# yum install php73-php-pecl-mysql

yum安裝時404報錯

# yum install php73-php-pecl-memcached
...
http://repo.mongodb.org/yum/redhat/7/mongodb-org/4.2/x86_64/repodata/repomd.xml: [Errno -1] Error importing repomd.xml for MongoDB: Damaged repomd.xml file
Trying other mirror.
http://mirror.pregi.net/centos/7.7.1908/os/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
Trying other mirror.
...

解法

# yum clean all --enablerepo=*
Loaded plugins: fastestmirror
Cleaning repos: C7.0.1406-base C7.0.1406-centosplus C7.0.1406-extras ...
...
Cleaning up list of fastest mirrors
必須清除yum緩存。這邊和IP無關,使用 proxychains4 掛代理IP執行無效

避免出現Memcached::get(): could not unserialize value, no igbinary support的錯誤

memcached有個memcached.serializer,預設採用igbinary。但是,當主機上沒有安裝igbinary時,則會改用php模式(standard PHP serializer)。如果有台主機沒有安裝Igbinary,且該主機的程式由memcache取回資料時為Igbinary格式,因無法使用Igbinary而發生錯誤。所以統一改為使用php模式。

檢查當前PHP CLI的memcached.serializer是什麼值:

# php -r "echo ini_get('memcached.serializer');"
igbinary
# php -i | grep memcached.serializer
memcached.serializer => igbinary => igbinary

查配置文件路徑

# php --ini | grep memcached
/etc/opt/remi/php73/php.d/50-memcached.ini,

修改 /etc/opt/remi/php73/php.d/50-memcached.ini 的 memcached.serializer配置為php

memcached.serializer = "php"

檢查修改後的結果(直接生效)

# php -r "echo ini_get('memcached.serializer');"
php
# php -i | grep memcached.serializer
memcached.serializer => php => php


安裝 laravel 5.8

$ composer create-project --prefer-dist laravel/laravel blog

配置nginx

nginx.conf 將server 改成以下
server {
    listen       80;
    server_name  localhost;
    root /var/www/html/blog/public;
    index index.php index.html index.htm;
    location / {
    #   autoindex on; // 如果想要開啟顯示資夾目錄的話加入這條
    #                  // 建議只在debug階段開啟
        try_files $uri $uri/ /index.php?$query_string;
    }
    #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   /usr/share/nginx/html;
    }
    location ~ \.php$ {
        root /var/www/html/blog/public;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }
}
如果前一步驟沒配好,訪問網頁會直接下載index.php 文件
https://stackoverflow.com/questions/25591040/nginx-serves-php-files-as-downloads-instead-of-executing-them/41838767#41838767
I had similar problem which was resolved by emptying the browser cache (also worked fine with different browser).
調好後要清空瀏覽器緩存


當storage 為777時,仍然報錯 storage/logs/laravel.log Permission denied
這個是 selinux 的問題
關掉selinux以證明這個問題
# setenforce 0
(可正常訪問)
這解法不好,因為你把被添加的服務器安全,所以把它改回去
# setenforce 1
應使用 SELinux 所允許的寫檔命令
blog ]$ sudo chcon -R -t httpd_sys_rw_content_t storage

laravel連不同(實體)機器DB時報錯

SQLSTATE[HY000] [2002] Permission denied
但是用mysql 命令或Navicat ssh通道卻能連,只有laravel不能連
https://stackoverflow.com/a/56381932  SQLSTATE[HY000] [2002] Permission denied Laravel PDO Driver (credentials working via artisan migrate)
解法:
# setsebool httpd_can_network_connect_db 1

beanstalk也不通 - 
Socket error 13: Permission denied  
https://stackoverflow.com/a/44092808 SQLSTATE[HY000] [2002] Permission denied
# setsebool httpd_can_network_connect 1


安裝workerman/gateway-worker

$ composer require workerman/gateway-worker
https://learnku.com/articles/13151/using-laravel-to-carry-out-socket-communication-in-workerman

新增 Workerman 啟動文件

用命令 php artisan make:command WorkermanCommand 新增 Workerman 啟動文件 app/Console/Commands/WorkermanCommand.php
  namespace App\Console\Commands;

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use Illuminate\Console\Command;
use Workerman\Worker;

class WorkermanCommand extends Command
{

    protected $signature = 'workman {action} {--d}';

    protected $description = 'Start a Workerman server.';

    public function handle()
    {
        global $argv;
        $action = $this->argument('action');

        $argv[0] = 'wk';
        $argv[1] = $action;
        $argv[2] = $this->option('d') ? '-d' : '';

        $this->start();
    }

    private function start()
    {
        $this->startGateWay();
        $this->startBusinessWorker();
        $this->startRegister();
        Worker::runAll();
    }

    private function startBusinessWorker()
    {
        $worker                  = new BusinessWorker();
        $worker->name            = 'BusinessWorker';
        $worker->count           = 1;
        $worker->registerAddress = '127.0.0.1:1236';
        $worker->eventHandler    = \App\Workerman\Events::class;
    }

    private function startGateWay()
    {
        $gateway = new Gateway("websocket://0.0.0.0:2346");
        $gateway->name                 = 'Gateway';
        $gateway->count                = 1;
        $gateway->lanIp                = '127.0.0.1';
        $gateway->startPort            = 2300;
        $gateway->pingInterval         = 30;
        $gateway->pingNotResponseLimit = 0;
        $gateway->pingData             = '{"type":"@heart@"}';
        $gateway->registerAddress      = '127.0.0.1:1236';
    }

    private function startRegister()
    {
        new Register('text://0.0.0.0:1236');
    }
}

創建事件監聽文件

namespace App\Workerman;

class Events
{

    public static function onWorkerStart($businessWorker)
    {
    }

    public static function onConnect($client_id)
    {
    }

    public static function onWebSocketConnect($client_id, $data)
    {
    }

    public static function onMessage($client_id, $message)
    {
    }

    public static function onClose($client_id)
    {
    }
}
s

啟動Workerman 服務端

$ php artisan workman start --d

檢查是否啟動成功

瀏覽器打開看到這個畫面就是啟動成功
在hyper-v上(不在容器內)竟然也能啟動成功...

設定固定IP

https://www.cyberciti.biz/faq/howto-setting-rhel7-centos-7-static-ip-configuration/

使用 Network Manager 文字GUI,比較無腦
# nmtui edit eth0
IPv4 CONFIGURATION:<Manual>
Addresses:192.168.1.x
Gateway:192.168.1.1
DNS servers:192.168.1.1   (使用host的DNS,沒配置ping 不到域名)

點擊<OK>後即是自動修改了 /etc/sysconfig/network-scripts/ifcfg-eth0
BOOTPROTO="dhcp"
BOOTPROTO=none
IPADDR=192.168.1.x
PREFIX=24
GATEWAY=192.168.1.1

重啟網路服務
# systemctl restart network
機器ip即固定 192.168.1.x ,原本的ssh會斷掉重連 192.168.1.x 即可

如果常常有時候連不上 hyper-v  192.168.1.9 (ping不通,但是瀏覽器打得開的詭異現象),重啟網卡(hyper-v CentOS + Windows) 無效
解法:
Bear-WAN先改【內部網路】再改【外部網路】,再重啟hyper-v 虛擬機

調整pagefile.sys到D碟後ssh無法登陸

http://www.xiaobaixitong.com/win10jiaocheng/31951.html  win10的pagefile.sys是什么文件?文件太大如何移动到其它盘
因為C碟只有100G,使用TreeSizeFreePortable發現pagefile.sys就佔了16G,要把他移動到D碟。
設置完需重啟電腦,移動完發現hyper-v重啟,gitlab更新不了,而且ssh也登陸不上了。以後需要注意此操作