1,服務器目前的架構 cpu 內存 io 網絡
一主 -》 多從(14) 主服務器宕機 切換從服務器慢
監控指標 :qps和tps (慢sql占用cpu時間太長,每個sql只能是一個cpu執行,qps超高造成阻塞)
并發量和cpu使用率 (連接數被占滿,cpu資源耗盡出現宕機)
磁盤IO
網卡IO
大表(千萬行數據,文件10g數據,查詢條件復雜)
查詢慢容易產生慢sql,產生大量的磁盤IO,更改列會很慢,建立索引時間長,主從延遲大
ddl操作會長時間鎖表,造成主從延遲,正常數據會被阻塞,大量的鏈接超時
分庫分表:主鍵選擇 跨分區數據查詢和統計
數據歸檔:時間點的選擇(歷史數據的查詢做單獨的入口,分離冷熱數據,歷史數據的統計和計算數據做異步處理)
歸檔操作的方式選擇
大事務(關系型數據庫的特性,原子性操作,原子性 一致性 隔離性 持久性)
要么全部成功要么失敗回滾,
事務操作前和操作后完整性不能被破壞,
事務未提交之前對事務的操作不可見(未提交讀,已提交讀(默認隔離級別),可重復讀(mysql默認),可串行化)
事務執行完之后持久化到磁盤不會丟失
運行時間比較長,操作數據比較多的事務叫做大事務
鎖定的數據太多,造成大量的阻塞和鎖超時
回滾所需的時間比較長
執行時間比較長,主從同步延遲太大
避免一次處理太多數據(分批處理)
移除不必要的select操作
2,影響性能的幾個方面
硬件
服務器系統
存儲引擎(插件式的存儲引擎選擇)
myisam 不支持事務,表級鎖
innodb 事務,行級鎖 ACID特性
數據庫配置參數
表結構的設計和sql語句
3,硬件的影響
cpu 頻率和核數,
mysql單條sql無法使用多個cpu,qps:每秒處理sql數量,核數比處理能力重要
內存大小
內存的io大于磁盤很多 熱數據 > 可用內存數據
myisam 把索引緩存在內存中,數據通過操作系統緩存
innodb 同時緩存 數據和索引到內存
讀減少磁盤io,寫減少磁盤io
磁盤IO和網絡資源
存儲大小,傳輸速度,訪問時間,主軸轉速,物理尺寸
RAID技術:磁盤冗余隊列,小磁盤組成大磁盤,提供數據冗余保持數據完整性
RAID0 沒有冗余和數據修復能力,多個磁盤串聯在一起,并發寫入,容量相加
RAID1 磁盤鏡像,生成數據備份鏡像,并發寫同時備份,磁盤冗余,容量減少50%
RAID5 奇偶校驗磁盤陣列,任何數據失效都可以從奇偶校驗塊中重建
READ10 分片鏡像 RAID1+READ0
固態硬盤SSD, PCIE SSD 比機械盤有更好的隨機讀寫的性能,更好的支持并發,更容易損壞
SSD SATA接口 直接替換傳統磁盤,同樣支持RAID技術
PCI-E SSD 無法使用SATA接口,需要獨特的驅動配置,貴性能更好
適用于大量隨機IO,解決單線程負載的IO瓶頸
網絡存儲NAS和SAN
SAN -》服務器-》SAN 通過光纖訪問服務器
緩存 大量順序讀寫 隨機讀寫慢
NAS 使用網絡連接,通過文件協議 NFS和SMB訪問
網絡設備 (延遲和帶寬)
高性能高代開網絡接口設備
多個網卡綁定增加可用性和帶寬
網絡隔離 內外網隔離 業務隔離
總結,64位架構運行在64位系統
并發高的場景cpu核數比頻率重要,cpu密集型和復雜sql頻率越高越好
選擇主辦能使用的最高內存,盡可能的大
IO子系統 PCIe-》SSD-〉Raid10-》磁盤-〉SAN
3,服務器的影響
mysql比較常見的運行到linux,window對大小寫不敏感,強制使用小寫
window FreeBSD Solaris Linux
centos 參數優化
/etc/sysctl.conf
net.core.somaxconn=65535
net.core.netdev_max_backlog=65535
net.ipv4.tcp_max_syn_backlog=65535
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.core.wmem_default=87380
net.core.wmem_max=16777216
net.core.rmem_default=87380
net.core.rmem_max=16777216
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3
kernel.shmmax=429497295
vm.swappiness=0
/etc/security/limit.conf
* soft nofile 65535
* hard nofile 65535
/sys/block/devname/queue/scheduler
磁盤調度策略
文件系統
windows (FAT NTFS)
linux(EXT3 EXT4 XFS)
4,mysql架構
插件式存儲引擎,數據處理和存儲相分離
cs結構
客戶端(java php c ODBC JDBC),負責連接處理,授權認證,安全等,一個連接智能化用到一個cpu,所有的操作都是在一個線程操作
服務層 連接管理()->查詢緩存-》查詢解析-〉查詢優化 所有跨存儲引擎的功能都在這一層
存儲引擎層 針對于表的,不這對庫文件
myisam: mysql5.5只前的默認存儲引擎,
系統表,臨時表(排序分組操作,數量超過一定大小,由查詢優化器建立臨時表)使用的存儲引擎。
MYD和MYI兩個文件存儲數據,frm存儲表結構。
表級別鎖,讀寫混合的并發性不好;
表修復check table tablename;repair table tablename;
全文索引(mysql5.7之前唯一原生支持全文索引的引擎),對text和blog的前500字符的前綴索引
支持表數據壓縮(myisampack),壓縮表的只讀表不能插入和更新
mysql5.0之前單表最大4G(MAX_Rows AVG_ROW)LENGTH),mysql5.0之后最大256TB
使用場景:非事務應用,只讀類型的并發性好,空間類應用(空間函數 5.0之前的必選)
Innodb:mysql默認存儲引擎,表空間存儲數據,(innodb_file_per_table: on 獨立表空間 .ibd , off系統表空間 ibdataX)
.frm和表空間文件
系統表空間無法簡單收縮文件大小造成磁盤碎片,獨立表空間使用optimize table命令重建表空間收縮文件系統
系統表空間產生IO瓶頸,獨立表空間可以同時刷新多個文件數據,mysql5.6之后默認獨立表空間
frm存儲的是服務器層的數據字典跟引擎無關的,系統表空間存放引擎相關的數據字典,回滾段
事務型存儲引擎ACID,redolog和undolog實現;行級鎖,在存儲引擎層實現,服務層不可見
鎖(管理共享資源的并發訪問,實現事務隔離),共享鎖(讀鎖),獨占鎖(寫鎖)
阻塞:等待其他的鎖釋放資源,慢查詢產生大量的阻塞
死鎖:事務相互占用資源,系統自動識別死鎖,并釋放占用資源較少的事務,使得事務繼續運行
show engine innodb status ;//狀態檢測
除了5.7之前的空間應用和全文索引情況都要默認innodb引擎
CSV存儲引擎 存儲文件.csv文件,一文件方式存儲,myisam和innodb是二進制文件存儲的
.frm表結構 .csv存儲表數據內容 .csm存儲表的元數據 數據量 表狀態等
所有的列不能是null,不支持索引,不適合做發表和在線處理數據,可以直接對數據進行編輯
適合做數據交換中間表
Archive 以zlib對表數據進行壓縮,占用更少的磁盤IO和存儲空間,數據問價 .frm和.arz文件
只支持insert和select操作,行級鎖,專用的緩沖區,支持高并發插入,只支持自增ID建立索引
適合 日志和數據采集的應用
memory引擎 數據存儲在內存中,表結構保持在磁盤,也叫HEAP引擎
支持HASH(默認)和BTREE索引,等于查詢時hash索引快,btree索引做范圍查找快
所有字段都是固定長度 varchar(10)=char(10)
不支持blog和text字段類型
表級鎖,并發性能有影響,max_heap_table_size決定最大表數據
系統自動創建: tmp-table-size 或 max-heap-table-size
1,超過限制使用myisam臨時表 2,未超過現在使用memory臨時表
主動創建: create temporary table
適用于映射表查找表,保存分析數據的中間表 緩存周期性聚合結果表
federated引擎 提供遠程訪問mysql服務器上表的功能,本地不存儲數據,本地保存表結構和遠程服務器的連接信息
默認mysql禁止使用,性能不好。
設置federated=1開啟;
適用于 手動統計分析查詢
存儲引擎選擇,沒有特殊需求innodb是最佳選擇
事務支持:innodb最穩定,select和insert 選myisam insert選archive
備份:innodb有在線熱備份方案,mysqldump不是熱備份(會加鎖的邏輯備份)
崩潰恢復 innodb比myisam好很多
特殊引擎特性需求
mysql服務器配置
mysql配置文件 my.conf
參數作用域 全局set global 參數=值
會話 set session 參數=值
內存相關參數:可使用內存上限(單進程運行)
每個sql連接的使用內存
(sort_buffer_size 需要排序的sql會分配這部分內存)
(join_buffer_size 每個線程使用的連接緩沖區,每個連表分配一個)
(read_buffer_size 讀緩沖區 全表掃描myisam時分配,4k的倍數)
(read_rnd_buffer_size 索引緩沖區)
緩存池分配的內存
innodb_buffer_poll_size 緩存索引和數據,延遲寫入(合并多個寫入一起寫入磁盤)
總內存 - 單個線程內存*連接數 -系統保留內存 建議服務器內存的75%
key_buffer_size 主要是myisam用,緩存索引,數據依賴操作系統緩存
IO相關的配置參數:性能 安全 做平衡 貴啊
innodb:innodb_log_file_size * innodb_log_files_in_group=事務日志總大小
innodb_log_buffer_size 事務日志緩沖區秒級持久化
innodb_flush_log_at_trx_commit 0秒級寫入chach并flush到磁盤
1每次事務提交都寫入cache并flush到磁盤
2每次都寫入cache,每秒flush到磁盤
innodb_flush_method=O_DIRECT 操作系統不緩存數據
innodb_file_per_table=1 innodb的表空間
innodb_foublewrite=1 雙寫緩存,避免葉沒寫完整就寫到文件中
myisam:delay_key_write OFF ON ALL
安全相關配置:
expire_log_days 指定binlog自動清理的天數
max_allowed_packet 控制mysql可接收的包的大小
skip_name_resolve 禁用DNS查找
syadate_is_now 確保sysdate()返回確定日期
read_only 禁止super全縣用戶的寫權限
skip_slave_start 禁止slave自動恢復
sql_mode 設置mysql使用的sql模式
(strict_trans_tables, no_engine_subtitution,no_zero_date,no_zero_in_date,only_full_group_by)
其他配置的影響
sysc_binlog 默認為0 ,操作系統決定什么時候刷新binlog;1,每次事務都會有寫binlog操作
tmp_table_size 和 max_heap_table_size 內存臨時表的大小,超過就會生產磁盤臨時表
max_connections 控制最大連接數
結構設計和sql優化
表的列太多,由于插件式引擎設計,mysql的服務層和引擎層是分離的,在引擎層的api和服務器層需要緩存格式來拷貝數據,然后在服務器層解析轉換成各個列。
關聯太多的表 10個是極限
OLTP環境不恰當使用分區表
外鍵的使用 保證數據完整性,效率低,修改和備份時候,要檢查約束,額外的鎖的開銷
總結:數據庫結構設計 和 sql優化 > 數據庫的存儲引擎和參數配置 > 系統參數的優化 > 硬件的升級
5,mysql性能測試
基準測試 直接簡單,易于比較,評估服務器處理能力,不涉及邏輯處理
壓力測試 正式業務數據進行測試,獲得真實的業務系統的壓力
指標:TPS QPS 響應時間(最大 最小平均 響應時間 各個時間百分比) 并發請求數量(同時操作的數量 不是同時存在的進程)
收集信息:cpu使用率 IO 網絡流量 狀態 計數器信息等
工具:ab,mysqlslap(mysql5.1之后自帶),sysbench ,Super Smack
6,表結構設計對性能的影響
良好的數據庫邏輯設計和物理設計是數據庫良好性能的jichu
目標:減少數據的冗余,避免數據的依賴維護異常,節約數據的存儲空間,提高查詢效率
步驟:需求分析(存儲需求,處理需求,安全性和完整性)
邏輯設計(設計數據的邏輯存儲結構,數據實體之間的邏輯關系,解決數據冗余,維護數據異常)
物理設計(表結構的設計)
維護優化(根據實際業務情況進行索引,存儲結構的優化)
表邏輯設計 范式+反范式結合=高性能
范式:...... 減少冗余,體積小,更新快
查詢關聯表多,查詢效率低;索引優化更加困難
反范式化: 空間換時間,更加方便查詢條件的設計,提高查詢效率,減少關聯表,更好的索引優化(覆蓋索引等)
物理設計
命名規范:庫,表,字段的命名規范,不能用大小寫區分,可讀性,表意義的表達,完整單詞
存儲引擎:沒特殊要求就用innodb,上邊寫過各個引擎的使用場景
表字段:合適的數據類型
數字》日期〉二進制》字符 (字符的比較排序等是根據字符集排序規則相關的,數字二進制日期等不用二進制大小可以直接比較)
同時占用空間越小越好(數據處理以頁為單位的 innodb是16k,列越小每頁的數據量就越多)
tinnyint 1字節 -128,128 0,255
smallint 2字節
mediuint 3字節
int 4字節
bigint 8字節
float 4字節
double 8個字節
decimal 每4字節存儲9個數字,小數點占一個字節
varchar 變長字符串,只占用必要的存儲空間
額外的字節存儲字符串長度,列的長度超過255需要兩個字節存儲字符串長度,最大就是65535長度,所以不可能用3個字節
使用最小符合需求的長度(改變長度會鎖表,5.7之后不超過255不會鎖表)
varchar(5)和varchar(200)性能比較,mysql在加載數據到內存中使用的是固定寬度,緩存和內存臨時表的時候消耗的內存比較多
適合存儲長度比較分散的數據,很少被更新的數據(字符長度變化,可能引起存儲頁的分裂,產生磁盤碎片),多字節字符集
char 固定寬度字符串,末尾的空格會被過濾刪除,最大寬度255
適合存儲長度比較集中,長度短小的字符串,經常被更新的字符列
日期類型 datetime類型 以yyyy-mm-dd hh:mm:ss 存儲,與時區無關,占用8個字節存儲空間
date 和 time 類型
timestamp類型 時間戳,顯示格式yyyy-mm-dd hh:mm:ss,只占用4個字節,依賴時區,自動修改更新
存儲空間比字符串少,日期可以對比,日期函數方便計算;不要用int來代替timestamp存儲時間,并沒有什么好處
7,mysql架構設計
主從復制:分擔mysql的讀負載,高可用,災難恢復備份,通過二進制日志同步數據,異步處理,有延遲
二進制日志增量進行復制,不需要太多帶寬,基于行的復制在大批量修改時會帶來帶寬壓力
mysql的二進制日志,慢查詢日志,通用日志屬于服務層日志,innodb的重做日志和回滾日志屬于引擎層日志
二進制日志:記錄了mysql數據庫的修改事件,增刪改事件和表結構變化
binlog_format=STATEMENT 基于段的日志格式,記錄sql和上下文信息,日志量少,節約磁盤和網絡io
但是使用非確定性函數,導致上下文信息無法確定的情況時無法復制的、
binlog_format=ROW 基于行的日志格式 默認格式 官方推薦,記錄每行數據的修改
更加安全的復制,復制的效率高,降低主從延遲時間
日志的量比較大,binlog_row_image=FULL | MINIMAL | NOBLOB
binlog_format=MIXED 混合行和段的日志格式 系統根據sql內容一定的算法確定
主從復制過程:
1,開啟主服務器二進制日志,主服務器將寫入更新寫入二進制日志
2,從服務器讀取主服務器二進制增量寫入到relay_log中,io線程,轉儲線程
3,從服務器重新執行relay_log的內容
基于日志的復制建立過程:初始化從庫數據(mysqldump 等工具)-》啟動復制(指定 master 用戶 密碼 二進制文件 偏移量)
基于GTID的復制:GTID全局事務ID,每個主庫上提交的事務生成唯一ID,從服務器會告訴主服務器已執行的事務的GTID值,主庫會告訴從哪些GTID事務沒有被執行。
故障處理麻煩,沒有skip沖突的操作
GTID=source_id:transsction_id
參考:https://www.jianshu.com/p/169315f2124a?utm_source=oschina-app
mysql5.7之后支持多主多從
一主多從 mysql5.7之前一直支持
配置簡單,
多個從庫分擔讀負載,分擔主庫的讀負載
不同的業務使用不同的從庫,不同的業務使用不同的索引
雙主復制 互為主從
容易產生沖突,盡量分開每個庫操作的表
主備復制 高可用方案
一臺mysql只讀,做熱備份,主庫故障才會切換成主服務器
一臺mysql做主服務器,切換后作為備份服務器的從庫
主從延遲 主從延遲不可避免
主庫寫入二進制的時間(大事務),控制事務的大小,分割成小事務
二進制的傳輸時間(日志量,磁盤IO,網絡帶寬),設置給予MIXED的日志格式
從庫重放sql,單線程串行處理重放sql(主庫的并發寫入從庫變成串行),mysql5.6后支持單庫的多線程復制
mysql5,7支持邏輯時鐘的多線程復制
主從復制中斷
數據損壞丟失,主從的二進制日志損壞
從庫數據被修改,造成數據沖突
不唯一的server_id,server_uuid
高可用 High Availability 縮短故障和系統維護的停機時間,提高可用性
服務器磁盤空間耗盡,性能糟糕的sql,表結構索引沒有優化,人為操作失誤,主從故障等
建立完整的監控系統,備份數據的恢復測試,及時歸檔和清理不需要的數據
增加系統的冗余,避免單點故障,主從切換故障轉移
單點故障
利用SUN共享存儲或DRDB磁盤鏡像解決mysql單點故障
多寫集群(pxc)或NDB集群解決單點故障
主從復制來解決單點故障
MMM(perl):監控管理mysql主主復制的拓撲,切換主備服務器的切換和故障轉移,提供讀寫虛擬ip
同一時間只有一臺主mysql對外服務,其他的事只讀模式
監控主從中斷,延遲過大時,進程故障轉移
MHA(perl) : 監控主從復制的拓撲,切換主從服務器完成故障轉移
監控主服務器是否可用,不可以就從眾多的從服務器選舉出一個做主服務器
讀寫分離 負載均衡
寫操作在主服務器進行,讀操作在多個從庫進行負載均衡
程序實現讀寫分離,更靈活控制連接主從數據庫,直接連接效率高,但是增加工作量程序復雜,人為控制容易出錯
讀寫中間件實現 mysql-proxy maxScale 根據語法分析解析出時讀操作還是寫操作,存儲過程等直接算主操作,多程序透明,節約開發成本;但是增加了中間層,對查詢效率損耗很大,對延遲敏感的業務無法在主庫執行
負載均衡:程序輪循,軟件(LVS Haproxy MaxScale) ,硬件F5等
8,索引查詢的優化
索引作用是快速查找到需要的數據(太多,太少的索引都會損耗性能),mysql在存儲引擎層實現的索引,不同的存儲引擎索引的使用是不一樣的;減少存儲引擎掃描的數據量(innodb的每次io以頁為單位默認16k),幫助排序避免臨時表的產生,把隨機i 哦轉變為順序io。
同時,索引會增加更新插入成本,要維護索引和統計信息,innodb引入了插入緩存把多次插入操作合并操作;同時mysql的查詢優化器會分析索引選擇合適的索引,太多的索引也會增加查詢優化器的時間。
b-tree索引:以B+樹的結構存儲數據,是一個平衡查找樹。能加快查找數據的速度,更加合適范圍查找
每個葉子到根的距離是相同的,每個節點按照鍵值的大小順序存放
全值匹配查詢,匹配最左前綴查詢,匹配列前綴的查詢,匹配范圍值的查詢,精確匹配左前列并范圍匹配下一列,索引覆蓋,order by 排等;
not in, !=,<> 等否定查詢在b-tree不會用到索引(網上查的待求證 跟引擎有關)
索引列上不能使用表達式和函數
innodb 索引最大大小不能超過767個字節,myisam是1000個字節,大字符串要使用前綴索引,前綴索引就要考慮到索引的選擇性
聯合索引 mysql5.0之前一條sql只能使用到一個列上的索引;mysql5.0之后引入了索引合并,可以合并多個列上的索引進行過濾,但是需要更多的內存和磁盤IO來緩存這些索引獲取的數據,聯合索引更好;
列的順序:經常被使用的列優先,選擇性高的列優先,寬度小的列優先
覆蓋索引 除了where條件之外,可以直接通過索引獲取查詢的數據,也就沒必要去讀取數據行的數據了,避免innodb主鍵索引的二次查詢,避免myisam的系統調用
hash索引:基于hash表實現,只有查詢精確匹配到hash索引所有的列才會用到索引,存儲引擎會為每一行計算hash碼,hash索引存儲的就是hash碼,就是說查找會很快,必須二次查找;存儲順序是按照hash碼的大小存儲的,不能用于排序、范圍查找等;hash沖突
索引優化排序:通過索引掃描數據,索引的順序和order by字段完全一致,排序方向也要完全一致,連表查詢必須在主表中
索引優化鎖:減少鎖定的行數量,加快處理速度,加快行釋放的速度
刪除重復和冗余的索引,查找不會被使用的索引,更新索引的統計信息,減少索引碎片(analyze table table_name, optimize table會鎖表)
9,sql查詢的優化
獲取性能有問題的sql:通過用戶反饋,慢日志獲取,實時獲取性能有問題的sql
慢日志 開銷主要是磁盤的IO和磁盤存儲空間
慢查詢開啟 slow_query_log
慢查詢日志存儲路徑 slow_query_log_file
慢查詢日志sql時間伐值 long_query_time
是否記錄未使用索引的sql log_queries_not_using_indexes
mysqldumpslow ,pt-query-digest慢日志分析工具
實時獲取有問題的sql show processlist
infomation_schema 數據庫下的processlist表:SELECT user, host, time, command, time FROM [mysql|information_schema].processlist WHERE user='me' and state IS NOT NULL;
mysql的執行sql的生命周期分析
客戶端通過mysql的接口發送sql給服務器
這個影響微乎其微
服務器檢查查詢緩存是否命中該sql,命中則直接返回結果
打開查詢緩存,優先查詢緩存是否命中,通過一個大小寫敏感的hash查找實現,hash是全值匹配,所以sql必須完全一樣,每次更新查詢緩存涉及的表時緩存都會被刷新,而且在緩存查詢是否命中時候會對緩存加鎖,在并發高和讀寫太頻繁的系統中很可能是降低查詢處理效率
query_cache_type=ON | OFF | DEMAND
query_cache_size 查詢緩存內存大小1024 * n
query_cache_limit 查詢緩存可存儲的最大值
query_cache_wlock_invalidate 數據表鎖住是否返回緩存中的數據 默認關閉
query_cache_min_res_unit 查詢緩存分配的內存最小單位
在sql上加sql_no_cache 不去查詢緩存
服務器對sql進行解析,預處理,優化器生成執行計劃
mysql的解析器通過關鍵字對mysql進行語句解析,使用mysql的語法規則和解析查詢,生成一顆解析樹
預處理是進一步檢查解析樹是否合法(查詢中涉及的表和數據列是否存在,名字別名歧義等)
查詢優化器生成查詢計劃,一條sql可用有很多執行方式,優化器會對每種執行方式存儲引擎提供的統計信息進行比較,找到成本最低的計劃;可能重新定義表的關聯順序,將外連接轉化為內連接,等價變換,將表達式轉換為常數表達式,子查詢轉換為關聯表
索引太多會導致優化器耗時太多;
存儲引擎提供的統計信息不準確、執行計劃的成本骨斷可能并不是實際執行計劃的成本,服務層并不知道存儲層的所有信息,那些數據是在內存中還是磁盤上,那些數據是順序讀還是隨機讀,就會錯誤的選擇讀區數據少的執行計劃
優化器認為的最優結果可能不是想要的(執行時間,資源利用最少)
優化器不會考慮并發問題,也就是鎖的問題對執行的影響
優化器會基于一些固定的規則生成執行計劃,不會考慮執行成本
根據執行計劃,調用引擎api查詢數據
這個影響微乎其微
返回客戶端結果
這個影響微乎其微
獲取sql執行各個階段的時間 profile(官方要廢棄) performance_schema(mysql5.5官方推薦的性能分析存儲引擎)
set profile=1
執行sql
show profiles;
show profile for query N;
show profile cpu for query N;
...
開啟performance_schema 會記錄所有sql的階段執行時間監控
update `setup_instruments` SET enabled='YES' where NAME like 'stage&';
update `setup_consumers` SET enabled='YES' where NAME like 'event%';
sql執行優化
大表的數據修改要分批次處理,中間有間隔時間
大表結構的修改(表中的字段類型和寬度)會鎖表,先從從服務器修改,再主從切換,再修改老的主服務器再切換回來;
(pt-online-change-schamel)
not in 和 <> 等優化 ,使用連表等方式重寫sql
使用匯總表優化查詢
10,分庫分表
分擔數據庫的讀負載,可用做主從讀寫分離;數據量激增,數據庫的性能急劇下降,可用把服務器拆分
把一個實例的多個庫分到不同的數據庫
把一個實例中一個庫中不同的表拆分到多個庫
表水平拆分到不同的實例中
分區鍵的選擇,盡量避免跨分片查詢發生,盡可能平均分配數據到分片中,熱數據也要平均
分區鍵的hash值取模來分片,范圍分片,分區鍵和分片的映射表來分配數據
redis生成全局id并緩存
11,數據庫監控
數據庫的穩定性決定系統的穩定性,監控軟件有nagios和zabbix等。
可用性聯通監控 mysqladmin -umonitor_user -p -h ping
telnet ip db_port
代碼模擬真實應用連接數據庫
監控數據庫連接數
數據庫性能監控 QPS和TPS
數據庫的并發數量監控
數據庫的innodb的阻塞監控
主從復制的監控
pt-table-checksum
因工作需求,最近開始研究docker及k8s相關的資料,本文主要記錄 kubernetes 安裝過程及踩過的坑。坑是挺多,過來就好了!如有錯漏,望予指正。
CentOS 7.4
IP地址機器名稱角色10.8.51.76server主節點10.8.51.77node-1從節點10.8.51.78node-2從節點
初始化環境之后,建議重新啟動機器
修改主機名,建議統一
hostnamectl set-hostname server hostnamectl set-hostname node-1 hostnamectl set-hostname node-2
修改/etc/hosts 文件增加主機映射
#node-2 為當前節點的主機名稱 127.0.0.1 localhost node-2 localhost4 localhost4.localdomain4 ::1 localhost node-2 localhost6 localhost6.localdomain6 10.8.51.76 server 10.8.51.77 node-1 10.8.51.78 node-2
免身份認證(建議弄上,主要是方便)
ssh-keygen #一路回車即可 ssh-copy-id server ssh-copy-id node-1 ssh-copy-id node-2
關閉防火墻、關閉Swap、關閉Selinux
#關閉防火墻 systemctl stop firewalld systemctl disable firewalld #關閉交換內存,必須關閉.不關容易出錯 swapoff -a sed -i 's/.*swap.*/#&/' /etc/fstab #關閉selinux setenforce 0 sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/sysconfig/selinux sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/selinux/config #更改文件最大打開數 echo "* soft nofile 65536" >> /etc/security/limits.conf echo "* hard nofile 65536" >> /etc/security/limits.conf echo "* soft nproc 65536" >> /etc/security/limits.conf echo "* hard nproc 65536" >> /etc/security/limits.conf echo "* soft memlock unlimited" >> /etc/security/limits.conf echo "* hard memlock unlimited" >> /etc/security/limits.conf #配置IP轉發,充許 編輯 /etc/sysctl.d/k8s.conf 文件,增加 net.bridge.bridge-nf-call-ip6tables=1 net.bridge.bridge-nf-call-iptables=1 #完成后使其生效 sysctl -p /etc/sysctl.d/k8s.conf
Kubernetes 1.10.0 與期相附的docker版本,不指定版本會導致docker版本過高,k8s無法正常啟動
#下載指定版本docker wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm #安裝 rpm -ivh docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm rpm -ivh docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm #設置開機自啟 systemctl enable docker #啟動docker systemctl start docker #查看狀態 docker info #查看版本 docker version
此處可配置一下國內鏡像加速
使用阿里云鏡像加速器:阿里云容器hub https://dev.aliyun.com/search.html;登錄之后,進入管理中心-->鏡像加速器-->操作文檔,根據提示進行設置即可。 如下圖:
這里要是不修改,容器無法透過自身的防火墻
開啟iptables filter表的FORWARD鏈
編輯/lib/systemd/system/docker.service,在ExecStart=..上面加入如下內容:
ExecStartPost=/usr/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT ExecStart=/usr/bin/dockerd
拉取鏡像,由于國內無法連上google(k8s.gcr.io)相關服務,需要事先將所需鏡像拉取過來。此處要是可以翻墻的話,可以省略以下步驟
server節點 #拉取鏡像 docker pull keveon/kube-apiserver-amd64:v1.10.0 docker pull keveon/kube-scheduler-amd64:v1.10.0 docker pull keveon/kube-controller-manager-amd64:v1.10.0 docker pull keveon/kube-proxy-amd64:v1.10.0 docker pull keveon/k8s-dns-kube-dns-amd64:1.14.8 docker pull keveon/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker pull keveon/k8s-dns-sidecar-amd64:1.14.8 docker pull keveon/etcd-amd64:3.1.12 docker pull keveon/flannel:v0.10.0-amd64 docker pull keveon/pause-amd64:3.1 #修改鏡像名稱,與k8s原服務需求鏡像保持一致 docker tag keveon/kube-apiserver-amd64:v1.10.0 k8s.gcr.io/kube-apiserver-amd64:v1.10.0 docker tag keveon/kube-scheduler-amd64:v1.10.0 k8s.gcr.io/kube-scheduler-amd64:v1.10.0 docker tag keveon/kube-controller-manager-amd64:v1.10.0 k8s.gcr.io/kube-controller-manager-amd64:v1.10.0 docker tag keveon/kube-proxy-amd64:v1.10.0 k8s.gcr.io/kube-proxy-amd64:v1.10.0 docker tag keveon/k8s-dns-kube-dns-amd64:1.14.8 k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8 docker tag keveon/k8s-dns-dnsmasq-nanny-amd64:1.14.8 k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker tag keveon/k8s-dns-sidecar-amd64:1.14.8 k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8 docker tag keveon/etcd-amd64:3.1.12 k8s.gcr.io/etcd-amd64:3.1.12 docker tag keveon/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64 docker tag keveon/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1 #刪除原鏡像 docker rmi keveon/kube-apiserver-amd64:v1.10.0 docker rmi keveon/kube-scheduler-amd64:v1.10.0 docker rmi keveon/kube-controller-manager-amd64:v1.10.0 docker rmi keveon/kube-proxy-amd64:v1.10.0 docker rmi keveon/k8s-dns-kube-dns-amd64:1.14.8 docker rmi keveon/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker rmi keveon/k8s-dns-sidecar-amd64:1.14.8 docker rmi keveon/etcd-amd64:3.1.12 docker rmi keveon/flannel:v0.10.0-amd64 docker rmi keveon/pause-amd64:3.1
node節點,拉取鏡像,其中 dashboard以及heapster也可放到主節點上
node 節點 #拉取鏡像 docker pull keveon/kube-proxy-amd64:v1.10.0 docker pull keveon/flannel:v0.10.0-amd64 docker pull keveon/pause-amd64:3.1 docker pull keveon/kubernetes-dashboard-amd64:v1.8.3 docker pull keveon/heapster-influxdb-amd64:v1.3.3 docker pull keveon/heapster-grafana-amd64:v4.4.3 docker pull keveon/heapster-amd64:v1.4.2 #修改鏡像名稱 docker tag keveon/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64 docker tag keveon/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1 docker tag keveon/kube-proxy-amd64:v1.10.0 k8s.gcr.io/kube-proxy-amd64:v1.10.0 docker tag keveon/kubernetes-dashboard-amd64:v1.8.3 k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.3 docker tag keveon/heapster-influxdb-amd64:v1.3.3 k8s.gcr.io/heapster-influxdb-amd64:v1.3.3 docker tag keveon/heapster-grafana-amd64:v4.4.3 k8s.gcr.io/heapster-grafana-amd64:v4.4.3 docker tag keveon/heapster-amd64:v1.4.2 k8s.gcr.io/heapster-amd64:v1.4.2 #刪除原鏡像 docker rmi keveon/kube-proxy-amd64:v1.10.0 docker rmi keveon/flannel:v0.10.0-amd64 docker rmi keveon/pause-amd64:3.1 docker rmi keveon/kubernetes-dashboard-amd64:v1.8.3 docker rmi keveon/heapster-influxdb-amd64:v1.3.3 docker rmi keveon/heapster-grafana-amd64:v4.4.3 docker rmi keveon/heapster-amd64:v1.4.2
每個節點均需要執行
修改 kubernetes 源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 EOF
安裝kubeadm
最新版使用 yum install -y kubeadm安裝,我們需要安裝指定版本,執行
#查看有那些版本可以安裝 yum list kubeadm --showduplicates #安裝指定版本 yum install kubeadm-1.10.0 kubectl-1.10.0-0 kubelet-1.10.0-0 #開機啟動 systemctl enable kubelet #啟動 systemctl start kubelet 這時系統啟動時,會報錯,先不用管他。因為還沒有初始化。初始化后就沒事了。
修改kubeadm 配置文件
#這里的坑不少,一定要注意文件編碼格式,行的未尾有沒有其它不可見字符.要不初始化的時候過不去 vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf #修改這一行,此處cgroupfs 要與docker info 中的一致 Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs" #添加這一行 Environment="KUBELET_EXTRA_ARGS=--v=2 --fail-swap-on=false --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/k8sth/pause-amd64:3.0" #完整版如下 [Service] Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true" Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local" Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt" Environment="KUBELET_CADVISOR_ARGS=--cadvisor-port=0" Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs" Environment="KUBELET_CERTIFICATE_ARGS=--rotate-certificates=true --cert-dir=/var/lib/kubelet/pki" Environment="KUBELET_EXTRA_ARGS=--v=2 --fail-swap-on=false --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/k8sth/pause-amd64:3.0" ExecStart=ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CADVISOR_ARGS $KUBELET_CGROUP_ARGS $KUBELET_CERTIFICATE_ARGS $KUBELET_EXTRA_ARGS $KUBELET_EXTRA_ARG 配置好后可使用 scp /etc/systemd/system/kubelet.service.d/10-kubeadm.conf root@node-1:/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 命令將文件傳輸至子節點
重新加載配置
#重新載入配置 systemctl daemon-reload #重啟kubelet服務 systemctl restart kubelet
初始化集群
#初始化集群時,增加自己本機IP地址,我們前的服務器為多網卡,指定其中主IP即可 kubeadm init --apiserver-advertise-address 10.8.51.76 --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.10.0 #初始化失敗時重置命令 kubeadm reset
這里很關鍵,我有好幾次都是死在了這個地方。出錯不要擔心,避免如下幾點可大大增加成功機率
1.配置文件中/etc/systemd/system/kubelet.service.d/10-kubeadm.conf cgroupfs的設置與docker info的一致 2.編輯配置文件時,注意行尾的不可見字符*******特別是ctrl +c ctrl + v 的朋友 3.拉取鏡像后的名稱不要忘記修改 4.查看出錯日志 /var/log/messages
成功后的效果圖如下:(自己的忘記截了,這是網上找的)
將上圖信息中的
#這個的意思是就是將k8s配置到環境變量中,在那個目錄都可以任使用k8s命令,也可將此文件考備到其他節點,在子節點上也可執行集群的命令了 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config #這個要記好,子節點加入主節點需要執行的命令,將下邊的命令在node-1,node-2中執行,就可以將 node-1,和 node-2加入集群中 kubeadm join 10.8.51.76:6443 --token tncyyh.jycputhrslcs6f6d --discovery-token-ca-cert-hash sha256:099ebf2e5b7d07f35e**********fb7b20cdf923**********9fa70734f6acc73a48
查看集群狀態
kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health": "true"}
安裝網絡插件 flannel
#只要server端安裝即可 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl apply -f kube-flannel.yml clusterrole.rbac.authorization.k8s.io "flannel" created clusterrolebinding.rbac.authorization.k8s.io "flannel" created serviceaccount "flannel" created configmap "kube-flannel-cfg" created daemonset.extensions "kube-flannel-ds" created
安裝完成后,可使用kubectl get pod --all-namespaces 查看
kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system etcd-server 1/1 Running 0 4h kube-system heapster-676cc864c6-g4jfj 1/1 Running 0 4h kube-system kube-apiserver-server 1/1 Running 0 4h kube-system kube-controller-manager-server 1/1 Running 0 4h kube-system kube-dns-86f4d74b45-pm8z2 3/3 Running 0 4h kube-system kube-flannel-ds-amd64-6xlzz 1/1 Running 0 4h kube-system kube-flannel-ds-amd64-78clr 1/1 Running 0 4h kube-system kube-flannel-ds-amd64-qgjp2 1/1 Running 0 3h kube-system kube-proxy-5pqsw 1/1 Running 0 4h kube-system kube-proxy-85m2p 1/1 Running 0 3h kube-system kube-proxy-zgns8 1/1 Running 0 4h kube-system kube-scheduler-server 1/1 Running 0 4h kube-system kubernetes-dashboard-7d5dcdb6d9-bv8l2 1/1 Running 0 3h kube-system monitoring-grafana-69df66f668-ndcwk 1/1 Running 0 4h kube-system monitoring-influxdb-78d4c6f5b6-pgb89 1/1 Running 0 4h
讓server 參與負載
kubectl taint nodes server node-role.kubernetes.io/master-
向集群中加入 node
#這個是初始化后顯示出來的 kubeadm join 10.8.51.76:6443 --token tncyyh.jycputhrslcs6f6d --discovery-token-ca-cert-hash sha256:099ebf2e5b7d07f35e3ace5809f********3c2f758ab9f*******73a48
查看集群節點
kubectl get nodes NAME STATUS ROLES AGE VERSION node-1 Ready <none> 4h v1.10.0 node-2 Ready <none> 3h v1.10.0 server Ready master 4h v1.10.0
查看api服務
#瀏覽器執行 https://10.8.51.76:6443
這是沒受限了,此時可以配置一個代理,使用非https訪問即可
nohup kubectl proxy --port=8081 --address=10.8.51.76 --accept-hosts=^*$ & #瀏覽器執行 http://10.8.51.76:8081
妥了..要是能堅持 到這里,就說明k8s集群,已經搭建成功了.下邊內容可以選看了
#下載kubernetes配置文件 wget https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml #編輯kubernetes-dashboard.yaml 文件,指定端口
由于 K8S在1.6版本以后kube-apiserver 啟用了 RBAC 授權,而官方源碼目錄的 dashboard-controller.yaml 沒有定義授權的 ServiceAccount,所以后續訪問 API server 的 API 時會被拒絕
創建一個kubernetes-dashboard-admin的ServiceAccount并授予集群admin的權限,創建kubernetes-dashboard-admin.rbac.yaml
--- apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-admin namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard-admin labels: k8s-app: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard-admin namespace: kube-system #執行命令 kubectl create -f kubernetes-dashboard.yaml kubectl create -f kubernetes-dashboard-admin.rbac.yaml
安裝heapster插件
mkdir heapster
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/grafana.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml
wget https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml
#查看以上下載配置誰的中的鏡像版本是否與下載時的一致,不一致時修改成本地鏡像版本
kubectl create -f ./
查看token
kubectl get secret -n kube-system | grep dashboard-admin kubectl describe -n kube-system secret/kubernetes-dashboard-admin-token-4lk94
訪問dashboard
#瀏覽器輸入,這個30000端是我們剛才自己指定的 https://10.8.51.76:30000
此處選擇令牌輸入剛才查看的token,點擊登錄
好了.這回是完事了.
要是你的瀏覽器不能訪問https,可參考,我用的瀏覽器chrmoe 各種方式都試了,都不行,最后使用下邊連接的方式成功了.可以看到了.
Dashboard使用自定義證書
https://blog.csdn.net/chenleiking/article/details/81488028
本文參考綜合了網上的一些成功案例.
https://www.jianshu.com/p/42772740f09a
https://www.kubernetes.org.cn/3808.html
我用的這個,實現了通過ymal文件對pod的增、刪、改、查等一些基本操作
https://github.com/fabric8io/kubernetes-client
#################################################################### apiVersion: v1 //版本 kind: pod //類型,pod metadata: //元數據 name: String //元數據,pod的名字 namespace: String //元數據,pod的命名空間 labels: //元數據,標簽列表 - name: String //元數據,標簽的名字 annotations: //元數據,自定義注解列表 - name: String //元數據,自定義注解名字 spec: //pod中容器的詳細定義 containers: //pod中的容器列表,可以有多個容器 - name: String //容器的名稱 image: String //容器中的鏡像 imagesPullPolicy: [Always|Never|IfNotPresent]//獲取鏡像的策略,默認值為Always,每次都嘗試重新下載鏡像 command: [String] //容器的啟動命令列表(不配置的話使用鏡像內部的命令) args: [String] //啟動參數列表 workingDir: String //容器的工作目錄 volumeMounts: //掛載到到容器內部的存儲卷設置 - name: String mountPath: String //存儲卷在容器內部Mount的絕對路徑 readOnly: boolean //默認值為讀寫 ports: //容器需要暴露的端口號列表 - name: String containerPort: int //容器要暴露的端口 hostPort: int //容器所在主機監聽的端口(容器暴露端口映射到宿主機的端口,設置hostPort時同一臺宿主機將不能再啟動該容器的第2份副本) protocol: String //TCP和UDP,默認值為TCP env: //容器運行前要設置的環境列表 - name: String value: String resources: limits: //資源限制,容器的最大可用資源數量 cpu: Srting memory: String requeste: //資源限制,容器啟動的初始可用資源數量 cpu: String memory: String livenessProbe: //pod內容器健康檢查的設置 exec: command: [String] //exec方式需要指定的命令或腳本 httpGet: //通過httpget檢查健康 path: String port: number host: String scheme: Srtring httpHeaders: - name: Stirng value: String tcpSocket: //通過tcpSocket檢查健康 port: number initialDelaySeconds: 0//首次檢查時間 timeoutSeconds: 0 //檢查超時時間 periodSeconds: 0 //檢查間隔時間 successThreshold: 0 failureThreshold: 0 securityContext: //安全配置 privileged: falae restartPolicy: [Always|Never|OnFailure]//重啟策略,默認值為Always nodeSelector: object //節點選擇,表示將該Pod調度到包含這些label的Node上,以key:value格式指定 imagePullSecrets: - name: String hostNetwork: false //是否使用主機網絡模式,棄用Docker網橋,默認否 volumes: //在該pod上定義共享存儲卷列表 - name: String emptyDir: {} //是一種與Pod同生命周期的存儲卷,是一個臨時目錄,內容為空 hostPath: //Pod所在主機上的目錄,將被用于容器中mount的目錄 path: string secret: //類型為secret的存儲卷 secretName: String item: - key: String path: String configMap: //類型為configMap的存儲卷 name: String items: - key: String path: String
Docker本身有自己的目錄掛載, 但功能太單一, 一般也只能掛載本地目錄, K8S作為Docker容器的管理服務, 除了能夠掛載本地的還能在線文件存儲目錄, 比如說nfs
1. 本地目錄掛載
yml文件中配置如下
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: goserver spec: replicas: 2 template: metadata: labels: run: goserver spec: containers: - name: goserver image: registry.cn-hangzhou.aliyuncs.com/magina-centos7/goserver:1.0 ports: - containerPort: 4040 volumeMounts: - mountPath: /mnt/logs name: go-logs volumes: - name: go-logs hostPath: path: /mnt/logs/kubernetes/goserver
最后的volumes指定掛載目錄的名稱和路徑, 這個目錄是本地的, 也就是說pod只會掛載當前宿主機的目錄, 但當我們有多個節點, 而這些節點上又有運行著相同的項目, 而我們需要收集這些項目的日志, 用本地掛載的方式顯得很麻煩, 當然, 我們可以用分布式日志工具去處理, 這里介紹另外一種方式, 網絡文件系統nfs
2. 網絡文件系統nfs
yml文件中配置如下
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: goserver spec: replicas: 2 template: metadata: labels: run: goserver spec: containers: - name: goserver image: registry.cn-hangzhou.aliyuncs.com/magina-centos7/goserver:1.0 ports: - containerPort: 4040 volumeMounts: - mountPath: /mnt/logs name: go-logs volumes: - name: go-log nfs: server: nfs4.yinnote.com path: /prod/logs/goserver
這里使用了nfs標簽, 也就是將當前目錄掛載到了遠程文件系統, 這里的server指的是遠程文件系統路徑, 需要自己去配置, 或者直接買其他云服務廠商的文件系統, 這樣做的好處是, 不管哪個節點, 哪個pod, 都可以將日志打到統一的地方
另外, 如果我們使用了nfs文件系統, 必須要在每臺節點上面安裝nfs-utils工具包, 否則pod會無法啟動
yum install nfs-utils
pull不下來鏡像。
可以通過 docker 提供把鏡像導出export(保存save)為文件的機制,這樣就可以把鏡像copy到任意地方了。
1. 導出 export - 導入 import
格式:docker export CONTAINER(容器)
使用 docker ps -a 查看本機已有的容器,如:
[root@docker1 LAMP]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dd43b6de6b33 weblogic:jdk1.6 "/run.sh" 3 days ago Up 3 days 0.0.0.0:32771->22/tcp, 0.0.0.0:32770->7001/tcp peaceful_saha aca388afeddf sshd:centos "/run.sh" 4 days ago Up 4 days 0.0.0.0:32769->22/tcp grave_turing ...... [root@docker1 LAMP]# docker export dd43b6de6b33 >/home/weblogic:jdk1.6.tar [root@docker1 LAMP]# cd /home [root@docker1 home]# ls weblogic:jdk1.6.tar
導出完成后,就可以使用 import 導入了
[root@docker1 home]# docker import - /home/weblogic:jdk1.6.tar
2.保存save - 加載 load
格式:docker save IMAGE(鏡像)
使用 docker images 查看本機已有的鏡像(也可以使用 docker commit <CONTAIN-ID> <IMAGE-NAME>命令把一個正在運行的容器保存為鏡像),如:
[root@docker1 LAMP]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ...... docker.io/tutum/lamp latest 3d49e175ec00 22 months ago 426.9 MB ...... [root@docker1 LAMP]# docker save 3d49e175ec00 >lamp.tar [root@docker1 LAMP]# ls Dockerfile lamp.tar [root@docker1 LAMP]# sz lamp.tar rz Starting zmodem transfer. Press Ctrl+C to cancel. Transferring lamp.tar... 100% 430366 KB 14345 KB/sec 00:00:30 0 Errors
有點慢,稍微等待一下,沒有任何warn信息就表示保存OK。3d49e175ec00 是鏡像ID
現在就可以在任何裝 docker 的地方加載 剛保存的鏡像了
[root@docker1 home]# docker load < /lamp/lamp.tar
3.導出 export 與 保存 save 的區別
(1).export導出的鏡像文件大小 小于 save保存的鏡像
(2).export 導出(import導入)是根據容器拿到的鏡像,再導入時會丟失鏡像所有的歷史,所以無法進行回滾操作(docker tag <LAYER ID> <IMAGE NAME>);而save保存(load加載)的鏡像,沒有丟失鏡像的歷史,可以回滾到之前的層(layer)。(查看方式:docker images --tree)
注:導入加載進來覺得不合適可以使用 docker rm 容器ID 、 docker rmi 鏡像ID 來刪掉。
移除所有的容器和鏡像(大掃除):
代碼如下: