作業(yè)地址
http://39.104.202.12:8000/monitor/cpu
自動(dòng)化監(jiān)控與報(bào)警
自動(dòng)監(jiān)控CPU,內(nèi)存使用率
安裝wechatpy、cryptography模塊
import psutil, time, datetime
class Monitor():
cpu_data = []
@classmethod
def mem(cls, mem_max=90):
"""內(nèi)存使用監(jiān)控"""
val = psutil.virtual_memory().percent
# print(val)
if val > mem_max:
cls.send_msg('內(nèi)存使用率為{:1f}%,超過(guò){}%,請(qǐng)關(guān)注!??!'.format(val, mem_max))
@classmethod
def cpu(cls, cpu_max=90):
"""CPU使用監(jiān)控"""
val = psutil.cpu_percent(1)
cls.cpu_data.append(val)
print(cls.cpu_data)
if len(cls.cpu_data) >= 3:
avg = sum(cls.cpu_data)/len(cls.cpu_data)
if val > cpu_max:
# cls.send_msg('CPU使用率為{:1f}%,超過(guò){}%,請(qǐng)關(guān)注?。。?.format(avg, cpu_max))
# cls.email('CPU使用率為{:1f}%,超過(guò){}%,請(qǐng)關(guān)注?。。?.format(avg, cpu_max))
cls.weChat('CPU使用率為{:1f}%,超過(guò){}%,請(qǐng)關(guān)注!?。?.format(avg, cpu_max))
print('已向微信發(fā)送警告消息')
cls.cpu_data.pop(0)
@classmethod
def send_msg(cls, content):
"""發(fā)送報(bào)警信息"""
print(content)
@classmethod
def email(cls, content):
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
nickname = '監(jiān)控程序'
sender = '295844041@qq.com'
password = 'wkezvmukjgqjbhjb'
reciever = 'zhengshucheng@idataway.com'
msg = MIMEText(content, 'html', 'utf-8')
msg['From'] = formataddr([nickname, sender])
msg['Subject'] = '自動(dòng)報(bào)警' # 郵件主題
server = smtplib.SMTP_SSL('smtp.qq.com', 465)
try:
server.login(sender, password)
server.sendmail(sender, [reciever], msg.as_string())
except Exception as err:
print(er)
finally:
server.quit()
@classmethod
def weChat(cls, content):
"""發(fā)送微信提醒"""
from wechatpy import WeChatClient
client = WeChatClient('wxfe4f8777c09bd3fe', '71a2f3afbc44cfd56585dbe4e63dbbe8')
template_id = 'XJ-ezE5udUqsPg6XlC_O7y9nX5Ttu3sxwgKp6MUmYF4'
openid = 'oUyaM1Ra-KKjHRaiyNepr1ju1sZI'
data = {
'msg':{'value': content,'color': '#173177'},
'time': {'value': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'color': '#173177'},
}
client.message.send_template(openid, template_id, data)
"""
mem_max = 25
Monitor.mem(mem_max)
"""
cpu_max = 1
while True:
Monitor.cpu(cpu_max)
time.sleep(2)
自動(dòng)化安裝與配置——以ngix為例
自動(dòng)化安裝-以源碼編譯方式
去niginx官網(wǎng)查看文檔:http://nginx.org/en/docs/configure.html,查看所需參數(shù)
自動(dòng)化配置
自動(dòng)化部署
分布式版本工具git的使用
-
為git倉(cāng)庫(kù)創(chuàng)造一個(gè)用戶
useradd -m git #創(chuàng)建一個(gè)git的用戶 -
為git用戶設(shè)置密碼
passwd git -
切換到git用戶
su - git
-
初始化倉(cāng)庫(kù)
git init --bare <projectname>.git # --bare表示創(chuàng)建的是空的倉(cāng)庫(kù)
使用Fabric批量部署項(xiàng)目
Docker
docker安裝
步驟參見(jiàn)官方文檔https://docs.docker.com
service docker stop/start/restart
docker info # 查看當(dāng)前docker更多信息
docker --help # 查看相應(yīng)幫助文檔
鏡像管理
docker hub : http://hub.docker.com
-
docker pull alpine # 拉取未指定標(biāo)簽的alpine
使用docker image 查看相關(guān)命令
docker image
docker image ls 或docker images # 當(dāng)前已拉取的鏡像
docker image rm <imageName> # 刪除鏡像
不要死記硬背命令,要善于查看幫助
容器管理
輸入docker 查看相關(guān)命令
docker
查看管理命令
docker run alpine echo "hello docker"
docker container ls 或docker ps # 查看正在運(yùn)行的鏡像
docker container ls -a # 查看容器
docker container <containerID> # 刪除容器
docker run -d alpine ping www.baidu.com # 后臺(tái)使用alpine 去ping百度
docker stop <containerID> # 停止容器運(yùn)行
docker run --rm <image> <cmd> # 容器停止運(yùn)行后會(huì)自動(dòng)刪除容器,同時(shí)數(shù)據(jù)也會(huì)被刪除
數(shù)據(jù)卷
將物理機(jī)中的目錄映射到容器中
docker run --rm -v /root:/data alpine touch /data/test.txt # 將物理機(jī)中root目錄映射到容器data中去,在容器data中創(chuàng)建一個(gè)文件test.txt,這個(gè)
docker run --rm -v "$(pwd):/data" alpine touch /data/test.txt # 將物理機(jī)中 **當(dāng)前目錄** 映射到容器data中去
docker run --rm -v "$(pwd):/data:ro" alpine touch /data/test.txt # 加上ro表明只進(jìn)行**只讀**映射
在docker中運(yùn)行web服務(wù)
從docker hub中獲取nginx鏡像
docker pull nginx:alpine # 下載標(biāo)簽為alpine的nginx鏡像
docker run --rm nginx:alpine # 運(yùn)行nginx服務(wù),但會(huì)卡在界面中
docker run -d --rm nginx:alpine
docker ps # 查看當(dāng)前運(yùn)行的容器
docker kill <CONTAINER ID > # 關(guān)閉容器
后臺(tái)運(yùn)行nginx后,還不能訪問(wèn)端口,可以(1)
docker run --rm -d -P nginx:alpine #
此時(shí)PORTS顯示 0.0.0.0:32768->80/tcp,表明物理機(jī)中的32768端口映射到了容器中的80端口,這種端口是隨機(jī)綁定映射的
(2)第(1)種方法物理機(jī)端口隨機(jī),無(wú)法提供穩(wěn)定的服務(wù),因此需要重新指定端口
docker run --rm -d -p 8080:80 nginx:alpine
查看所有運(yùn)行中的docker 容器id
docker ps -q
docker kill -$(docker ps -q) # 關(guān)閉所有運(yùn)行中的容器
構(gòu)建鏡像 docker build
構(gòu)建鏡像之前需要先編寫Dockerfile
docker官方文檔中reference:
- FROM: 指定基礎(chǔ)鏡像
- RUN:
- CMD: 指定容器啟動(dòng)時(shí)執(zhí)行的命令
- LABLE: 用于添加擴(kuò)展信息到容器中
- COPY:用于將文件拷貝到容器中
- WORKDIR:設(shè)置工作目錄
利用vi Dockerfile 進(jìn)入編輯頁(yè)面
FROM alpine (也可以使用ubuntu:16.04)
LABEL version = '1.0'
LABEL description = 'my first image'
RUN apk update && apk add python3 #(如果使用ubuntu系統(tǒng),則RUN apt update && apt -y install python3)
COPY . /code # 將當(dāng)前目錄下的文件拷貝到code目錄中。此方式下修改原來(lái)目錄中的文件,運(yùn)行容器時(shí)結(jié)果仍然不變
WORKDIR /code # 指定容器運(yùn)行后的工作目錄
CMD ['<python3>', '<app.py>'] #
編輯完Dockerfile后
docker build -t myapp . # 在當(dāng)前目錄(.)中構(gòu)建一個(gè)tag為myapp的鏡像
docker inspect redis:alpine # 查看鏡像
綜合實(shí)戰(zhàn)
python程序,將數(shù)據(jù)存放在redis中,并且
-
創(chuàng)建目錄存放數(shù)據(jù)
mkdir /redis-data docker run -d --name redis -v /redis-data:/data redis:alpine # 為容器指定一個(gè)名字 --name <ContainerName> -
創(chuàng)建python文件
mkdir myweb cd myweb/ vi app.py編輯app.py 文件
# 使用flask創(chuàng)建一個(gè)web服務(wù) from flask import Flask import redis app = Flask(__name__) # 連接redis r = redis.Redis(host='redis', port=6379) @app.route('/') def hello(): count = r.incr('clicks') return "ZSC love CS! {}".format(count) if __name__ == '__main__': app.run('0.0.0.0', port=5000) -
編輯Dockerfile
FROM python:alpine # docker 提供了python鏡像 COPY . /code RUN pip install flask redis #不用使用pip3 WORKDIR /code EXPOSE 5000 # 開(kāi)放5000的端口 CMD ['python', 'app.py'] -
構(gòu)建鏡像
docker build -t myweb . 啟動(dòng)運(yùn)行app
docker run --rm -d -p 80:5000 myweb
訪問(wèn)地址后,顯示Internal Server Error,但是雖然80已經(jīng)映射到了myweb容器的5000端口,而redis和pythonl兩個(gè)容器之間是隔離的。-
連接redis后啟用鏡像
docker run --rm --link redis -p 80:5000 myweb