且说有一天,一群物理学家在天堂里闲极无聊,便玩起了抓人游戏。这回轮到爱因斯坦抓人了。待他数到100,便睁开眼睛。只见所有人都藏起来了,只有伏特还趴在不远处。
爱因斯坦走过去,说:“伏特,我抓住你了。”
伏特说:“不,你没有抓到我。”
爱因斯坦说:“你若不是伏特,那你又是谁?”
伏特说:“你且看看我身下是谁?”
爱因斯坦低头一看,趴在伏特身下的,竟是安培!
伏特说:“我身下是安培,我俩就是伏特/安培,所以你抓住的不是我,你抓住的是欧姆!”
爱因斯坦反应何其敏捷,迅速改口道:“欧姆,我抓住你了!” 可是呢,伏特和安培毕竟是欧姆的好哥们。于是,伏特和安培一个鱼跃站了起来,但是仍然紧紧抱在一起,爱因斯坦感到大惑不解。
他俩不紧不慢地说,现在,我们不再是欧姆,而是伏特×安培, 变成瓦特了!
爱因斯坦觉得很有道理,于是喊,那我终于抓到你了,瓦特!
这时,瓦特躲在角落里,慢慢悠悠地开口说:“你看,他俩这样抱着已经有好几秒了,所以,你抓到的不是瓦特,而是瓦特×秒,是焦耳啦!”
这时,爱因斯坦看到牛顿站在不远处。于是他跑过去说:“牛顿,我抓住你了。”
牛顿说:“不,你没有抓到牛顿。”
爱因斯坦说:“你如果不是牛顿,那你是谁?”
牛顿说:“你看,我脚下踩的是什么?”
爱因斯坦低头一看,只见牛顿站在一块长宽都是一米的正方形地砖上。
牛顿说:“我脚下是一块一平方米的方块,我站在上面,就是牛顿/平方米。所以说,你抓住的并不是牛顿,而是帕斯卡呀!”
爱因斯坦屡受挫折,终于忍无可忍,爆发了。于是,他飞起一脚,踹在了牛顿身上,把牛顿踹出了那块一平米的地板砖。
然后他吼道:“说!你还敢说你是帕斯卡吗!”
牛顿慢吞吞地从地上爬起来,说:“不,我已经不是帕斯卡了。你刚刚让我牛顿移动了一米的距离,所以,我现在也是焦耳了!”
焦耳这次学聪明了,一把将阿伏伽德罗扑倒在自己身下,说:“你看,我现在是J/mol啦!”
正当爱因斯坦思考J/mol是什么东西的时候,亥姆霍兹和吉布斯这两个自由能吵了起来,都说是对方。为了不至于两败俱伤,他们一脚把开尔文踹到了焦耳下面,将阿伏伽德罗顶了出来。
“看!”他俩说,“现在是J/K,是熵啦,要抓就抓克劳修斯吧!” 游戏继续。
这次是安培最先被爱因斯坦发现。眼看安培就要被抓了,他顺势往地上一躺,伸直身体对站在身边不远处的爱因斯坦说:“等等,我在你站的地方产生了磁场。”
正当爱因斯坦在考虑该抓高斯还是特斯拉的时候,发现他俩一人找了一块地板砖抱着,说:“不麻烦您老了,我们现在是磁通量B·S,您还是去找韦伯吧!”
等到爱因斯坦要抓住韦伯的时候,却发现韦伯正在做深蹲。
爱因斯坦问:“你干嘛呢?”
韦伯回答说:“你没看到我一会儿变大,一会儿变小吗?我在产生感应电动势呢。”
伏特一下子慌了,他一把抓住密立根的衣领,说:“你成天拿个油壶乱喷什么!”
“测定元电荷。”密立根回答道。
“太好了!”伏特一把抱住密立根说,“从现在起,我们就是eV,也就是焦耳。”
“靠,今天真是邪了门啦!”焦耳嘀咕道。
他一把将赫兹压在胯下,说:“看,我现在是E/v,是普朗克啦!”
普朗克也不是好惹的。他突然发现,远处有个来自东方的长者在地上写下了22/7和355/113,心里很是得意。一打听,此人姓祖,更是心里大喜。
他急忙跑过去,把这两个分数照抄了一遍,然后趴在这四个分数上面,对气喘嘘嘘赶来的爱因斯坦说:“看,我现在是h/4pi啦!”
“那又怎样?”爱因斯坦问。
“这是我的好哥们海森堡教我的,他说这样我就不是我了,有什么事尽管找他。”
“好,那他在哪里?”
“这个,还真说不准。”
爱因斯坦恼羞成怒,正准备对普朗克大打出手。
普朗克说:“等等,海森堡有个姓薛的好哥们,就躲在前面的那个箱子里。”
“这箱子连个通风口都没有,难道他不会被憋死吗?” 爱因斯坦问。
“这个嘛,就得你亲自去打开看看了。”“(??ω??)??”
ubuntu能够ping通ip但是无法ping通域名
故障描述
今天在克隆一个github仓库的时候,突然发现克隆失败了,于是检查了一下,发现域名都ping不通了
开始以为是网络挂掉了,但是使用代理的网络并没有挂掉,于是猜想是dns的问题
接着ping一下ip地址,发现可以ping通,确信是dns的问题无疑
解决方案
找到了问题要解决就很简单了,使用命令
sudo gedit /etc/resolv.conf
把nameserver改成可用的dns服务器即可,如8.8.8.8
nameserver 8.8.8.8
验证
然后再次ping github.com,成功的收到了数据包,故障排除
记录一次nginx配置错误 ERR_SSL_PROTOCOL_ERROR
配置https站点 出现ERR_SSL_PROTOCOL_ERROR等因为证书不可信的故障
出现的原因
原来的server配置中
listen 443;
解决方案
增加ssl协议
listen 443 ssl;
重启nginx服务器,问题解决
dokcer快速入门
docker是什么
对于docker究竟是什么,有很多种的说法.不但不管是什么说法,总没有办法避开一个概念
docker仅仅就是一个工具而已、
听起来或许好像和没有解释是一样的,但是我觉得这就是最好的解释
但是正因为docker是一种工具,只要明白dokcer能做什么,不能做什么,我们就能很好的使用docker这个工具了。
因为对于工具而言,只有在特定的场景才有存在的意义,无脑的跟风和吹捧都是没有意义的。
docker能做什么
- 跨环境无缝迁移
- 项目水平扩展,轻松实现分布式架构
- 自动化运维
- CI/CD 持续集成,持续交付
任何一种工具的使用方法,都是没有办法用穷举法来完成的,但是只需要这几种优点,已经足以成为我学习并学会使用这种工具的推动力了。
docker核心概念
学会一种工具并不需要你完全的吧这种工具发明出来(当然能够发明出来,那说明你不仅仅是学会使用了),只需要工具的每个组成部分就可以了,想要更好的使用docker,有三个核心概念是必要要深刻了解的
- repository 仓库
- image 镜像
- container 容器
什么是镜像?什么是容器?什么又是仓库?
用面向对象的方法来理解,我觉得会更容易一点
镜像和容器之间的关系,就好像面向对象编程中类与实例的关系
仓库和镜像之间的关系,就好像包和类之间的关系
一个镜像可以创建出很多的容器,多个镜像可以组成以的镜像仓库
docker基础命令
docker的基本概念就好比心法口诀,但是想要运用自如,只有通过不断的练习才有可能
但是有组织的练习可以让你事半功倍,docker的操作主要分为两种
- 对镜像的操作
- 对容器的操作
docker镜像操作命令
docker pull #从docker云拉取一个镜像
docker push #把本地镜像推送到docker云上
docker build #根据Dockerfile创建一个docker镜像
docker images #列出当前系统上所有的镜像
docker image #镜像操作命令的集合
docker容器操作命令
docker run # 运行某个容器的镜像
docker ps #显示正在运行的容器
docker rm # 删除一个或者多个容器
docker rename # 对容器进行重命名
docker port # 查看容器运行的端口
docker cp # 拷贝文件到容器
docker快速上手
背诵命令是非常枯燥又低下的,通过一个完整的过程来练习docker才能使你的印象更加深刻,那么亲自运行一个容器就显得的非常有必要了。
容器的运行需要依赖镜像,首先要做的事情就是从docker云上获取一个可用的镜像,因为我的操作系统就是ubuntu,所以我对ubuntu比较熟悉,那么我就使用ubuntu镜像了
docker pull ubuntu # docker pull ubuntu:14.0.4 带上tag的话,可以获取到指定版本的系统
docker images # pull之后 查看当前的iamges 查看自己的镜像是不是拉取成功
接下来使用run来练习了
docker run ubuntu ls -al #ls -al 就是在容器中运行的命令,只要ubuntu下运行的命令,都可以使用这种方法来运行,包括使用bash来登录
docker run -it ubuntu /bin/bash # 注意这里的-it参数,如果没有这个参数,将不能进入bahs终端
因为这是ubuntu默认环境,几乎是没有什么工具的,为了打造自己的环境,那么我们可以稍微配置一下,在这里安装个vim
apt update
apt install vim
安装成功以后,可以把容器重新打包成镜像,制作成属于自己的镜像,重新打开一个终端
使用Dockerfile 来构建自己的镜像会有更好的体验,这里粗暴一点解决,成就感会来的快一点
docker ps # 查看正在运行的ubuntu镜像的容器 找到第一行的contain ID
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ad0ebaa1cd1 ubuntu "/bin/bash" About a minute ago Up About a minute
接着使用commit 对容器重新打包成镜像
docker commit 4ad0ebaa1cd1 crisen/ubuntu # 4ad0ebaa1cd1是容器的id,这是一个随机字符串,不同的电脑上得到的随机字符串是不一样的
docker images # 接着验证自己的镜像是否成功创建
最后验证自己的镜像是不是成功安装上了vim
docker run crisen/ubuntu which vim #这里运行crisen/ubuntu 表示自己创建的镜像的名称
最后得到结果/usr/bin/vim,说明成功个性化了自己的镜像。
ubuntu16.0.4 安装NVIDIA显卡驱动
查看显卡驱动型号
lspci | grep -i vga
01:00.0 VGA compatible controller: NVIDIA Corporation GF108 [GeForce GT 630] (rev a1)
GeForce GT630就是我当前的电脑的显卡型号了(一块比较古老的显卡,基本够用吧)
找到官方提供的驱动程序
NVIDIA的显卡,不是所有的类型都提供了linux版本的,所以要去英伟达官网去搜索一下
很幸运的是,GT630提供了linux64位版本的驱动下载,
那么接下来复制下载地址,用wget获取了
cd ~
wget http://cn.download.nvidia.com/XFree86/Linux-x86_64/390.77/NVIDIA-Linux-x86_64-390.77.run
安装驱动需要的依赖
sudo apt-get update
sudo apt-get install dkms build-essential linux-headers-generic
禁用nouveau驱动
编辑blacklist-nouveau.conf配置文件
sudo vim /etc/modprobe.d/blacklist-nouveau.conf
添加下面的内容
blacklist nouveau
blacklist lbm-nouveau
options nouveau modeset=0
alias nouveau off
alias lbm-nouveau off
使用命令让禁用生效
sudo update-initramfs -u
重启
接着重启操作系统
sudo reboot
进入纯终端环境安装驱动
使用组合快捷键登录ctrl
+alt
+F1
进入纯终端环境
接着关闭图形界面服务
sudo service lightdm stop
赋予驱动安装程序可执行权限,然后运行驱动安装程序
cd ~
sudo chmod a+x NVIDIA-Linux-x86_64-390.77.run
./NVIDIA-Linux-x86_64-390.77.run
中途有几次选择过程,按需选择即可,安装完毕之后重启操作系统,最后使用命令验证,出现了显卡信息则驱动安装成功
sudo nvidia-smi
拥有原生体验版的本地局域网gitlab服务器
场景描述
- gitlab服务器(ubuntu16.0.4),运行在内网,提供git服务
- 云服务器(centos7),提供端口转发功能,为git服务器提供外网连通环境
遇到的问题
我开始使用了ssh远程端口转发功能,把云服务器的8080端口和2222端口分别转发到了git服务器的80和22端口,这样我就能通过121.40.150.93:8080的方式来访问我的git网页了,但是这里出现了一个问题
没有办法使用ssh协议来克隆仓库
虽然我之前找到了解决方案,可以通过一些配置来克隆仓库,但是这对不熟悉ssh或者新手来说太不友好了,这不是我想要的git服务器。
目标
我的目标只有一个,希望我在本地配置的git服务器,能达到gitlab官方服务器一样的使用感觉。
所以我现在需要解决的一个问题就是,使用云服务器的22端口来访问我的本地服务器,从而提供gitlab原声般的体验。
解决过程
因为我现在需要用到云服务器的22端口,那么云服务器原来的ssh服务器就不能走22端口了,所以接下来的任务,隐藏原服务器的22端口,修改成其他任意端口,我这里就用9468好了
阿里云服务器有安全组规则,所以要先在阿里云开启9468端口,要不然云服务器就无法登录了
修改ssh-server默认端口(云服务器)
vim /etc/ssh/sshd_config
在17行代码左右的配置,把Post修改为9468
Port 9468
重启sshd服务
/bin/systemctl restart sshd.service
使用autossh进行转发22端口(git服务器)
因为22端口是特权端口,只能以root运行,而且云服务器已经修改了ssh服务的端口了,为了建立这条隧道,首先要做的事情是添加一个配置配置
vim ~/.ssh/config
添加下面的内容
Host server
hostname 121.40.150.93
user root
port 9468
接着使用ssh远程端口转发功能,把云服务器22端口转发到本地22端口
ssh -NR 22:localhost:22 server
验证
接下来只要验证就可以了,点击我的git服务器进行体验
docker in ubuntu—-安装
系统环境
- 操作系统: ubuntu Xenial 16.04 (LTS)
- 操作系统架构:x86_64
- 目标工具:docker-ce(docker社区版)
移除旧版本(可选)
sudo apt-get remove docker docker-engine docker.io
安装docker-ce依赖
- apt-transport-https:开启https支持
- ca-certificates:CA证书
- curl: curl工具
- software-properties-common:软件源管理工具
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
添加 docker官方GPG秘钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
验证秘钥(可选)
sudo apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
设置稳定版repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
安装docker-ce(核心步骤)
sudo apt-get update
sudo apt-get install docker-ce
需要安装指定版本的docker,可以使用命令sudo apt-get install docker-ce=
验证安装结果
sudo docker hello-world
卸载
# 移除docker二进制包
sudo apt-get purge docker-ce
# 删除已安装的镜像和 容器等数据(可选)
sudo rm -rf /var/lib/docker
配置本地DNS服务器
引言
因为在本地环境搭建了一个git服务器,有很多同事一起使用,每次通过地址访问实在是感觉很不好,通过域名访问,又需要修改hosts,为了一劳永逸解决这个纠结的问题, 配置一个本地dns服务器是最好的选择
系统环境
- dns服务器操作系统: ubutnu16.0.4
- dns服务器地址: 10.0.0.10
- git服务器地址. 10.0.0.11
- dns工具: bind9
目标
通过配置dns地址为10.0.0.10之后
把域名git.crisen.org解析到10.0.0.11的服务器上
安装
安装bind工具,在当前时间节点bind的版本是bind9.使用下列命令安装
sudo apt update
sudo apt install bind9 -y
# centos请使用 sudo yum install bind
配置
打开/etc/bind/named.conf.local 文件
sudo vim /etc/bind/named.conf.local
输入如下内容
zone "crisen.org"{
type master;
file "db.crisen.org";
};
zone 指定域名, file指定域名解析文件
配置域名解析文件
sudo cp /etc/bind/db.local /var/cache/bind/db.crisen.org
sudo vim /var/cache/bind/db.crisen.org
打开看到如下内容
;
; BIND data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
@ IN A 127.0.0.1
@ IN AAAA ::1
最后一行加上
@ IN A 10.0.0.11
细心一点 这里就能发现 @表示泛解析 A表示A记录 10.0.0.11就是解析的ip地址 使用过其他域名服务商的朋友们应该比较熟悉这个配置了,也就是说如果我想添加git.crisen.org的解析到10.0.0.11,那么配置应该是git IN A 10.0.0.11
配置dns服务器访问外网
sudo vim /etc/bind/named.conf.options
在13行左右的位置,修改forwarders配置,这里配置为114.114.114.114,可以替换成任意dns地址
forwarders {
114.114.114.114;
};
重启bind服务并清除缓存
sudo service bind9 restart
sudo rndc flush
测试
将10.0.0.10地址作为首选dns服务器,使用ping命令测试
ping git.crisen.org
#
PING git.crisen.org (10.0.0.11) 56(84) bytes of data.
64 bytes from gitlab.crisen.org (10.0.0.11): icmp_seq=1 ttl=64 time=0.405 ms
...
最后域名成功解析到了10.0.0.11服务器上,DNS服务器配置完毕
统计大文件中IP出现的次数
相关工具与文件
- 操作系统CentOS7
- GNU Awk 4.0.2
- GNU sed 4.2.2
- ss-server 日志文件ss.log
任务目标
统计ss.log中出现的不重复的ip的访问次数
分析过程
首先查看ss.log文件的大小
wc -l ss.log
# 69149 ss.log
...
接着取出其中的5行进行人工分析
tail -n 5 ss.log
# 2018-07-16 14:04:44 INFO connecting sync-624-us-west-2.sync.services.mozilla.com:443 from 105.150.63.146:29776
......
由此可见IP地址出现的位置在第7列,那么接下来使用awk命令把记录中的第7列取出
tail -n 5 ss.log | awk '{pring $7}'
# 105.150.63.146:29776
...
于是得到了带有ip:port 的列表数据,但是我需要的仅仅是ip地址,那么接下来是取出ip地址部分,使用强大的流编辑器sed直接取出ip地址部分
ps:sed使用的是基础正则表达式,不是perl正则表达式, 语法有些差异
tail -n 5 ss.log | awk '{pring $7}' | sed 's/:[0-9]\+//g '
# 105.150.63.146
...
's/:[0-9]+//g' 正则的作用是把:符号以及:符号后面所有的数字全部替换为空
接下来使用awk命令 对ip进行统计
awk '{IP[$1]++}END {for(a in IP) print a"-----"IP[a]}'
tail -n 5 ss.log | awk '{pring $7}' | sed 's/:[0-9]\+//g ' | awk '{IP[$1]++}END {for(a in IP) print a"-----"IP[a]}'
# 105.150.63.146-----3
...
统计末尾的5行文件,得出IP为105.150.63.146的地址请求了3次请求,接下来吧tail命令换成cat命令,对整个文件进行统计
cat ss.log | awk '{pring $7}' | sed 's/:[0-9]\+//g ' | awk '{IP[$1]++}END {for(a in IP) print a"-----"IP[a]}'
# 105.150.63.146-----13503
...
最后把这一串命令写成脚本保存,方便下次继续使用
#! /bin/bash
cat ss.log | awk '{pring $7}' | sed 's/:[0-9]\+//g ' | awk '{IP[$1]++}END {for(a in IP) print a"-----"IP[a]}'
Docker初探(centos7)
系统环境
- Centos7 64位
docker安装
centos下安装docker非常简单
首先移除可能的旧版本(可选)
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
接着安装安装docker-ce依赖环境
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加docker-ce官方安装包
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
然后安装docker-ce
sudo yum install docker-ce
其他环境的安装请参考官方文档
配置DNS
在/etc/docker/daemon.json 文件中添加下列内容
{
"dns": ["114.114.114.114", "8.8.8.8"]
}
定义一个测试用的容器
mkdir app && cd app
创建一个app目录,接着创建三个文件名称如下
- requirements.txt
- app.py
- Dockerfile
requirement.txt
Flask
Redis
app.py
python 代码要注意缩进
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
Dockerfile
Dockerfile是docker的核心文件,必不可少
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
创建docker容器
如果上面的一切配置正常,那么使用ls
命令,应该在app目录下出现三个文件
Dockerfile app.py requirements.txt
接着使用docker build 命令创建一个python容器(ps: 注意命令最后面的符号.)
sudo docker build -t hello-docker .
验证容器是否创建成功
sudo docker image ls
出现了下面的字样,则创建成功
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-docker latest a74bf93b68c9 26 minutes ago 132 MB
如果遇到error creating overlay mount to /var/lib/docker/overlay2 错误,请参考这里
运行
首先重启docker服务
sudo /bin/systemctl restart docker.server
接着运行docker,把宿主机环境的4000端口转发到hello-docker环境中的80端口
sudo docker run -p 4000:80 hello-docker
验证
curl localhost:4000
出现结果如下,则说明docker运行成功
<h3>Hello World!</h3><b>Hostname:</b> 79b3ed825e21<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>