-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
377 lines (338 loc) · 72.9 KB
/
search.xml
File metadata and controls
377 lines (338 loc) · 72.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>利用iostat命令自定义key实现zabbix磁盘io监控</title>
<url>/2021/03/11/iostat/</url>
<content><![CDATA[<p>安装sysstat</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">yum install sysstat -y</span><br></pre></td></tr></table></figure></div>
<a id="more"></a>
<p>安装bc</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">yum install bc -y</span><br></pre></td></tr></table></figure></div>
<p>编写关于iostat的脚本(io_monitor.sh)可以考虑不写bc<br>测试脚本可用性</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">./io_monitor.sh disk_read</span><br></pre></td></tr></table></figure></div>
<p>zabbix_agentd.conf中加入自定义key:</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">UserParameter=io_stats[*],/etc/zabbix/io_monitor.sh <span class="string">"<span class="variable">$1</span>"</span></span><br></pre></td></tr></table></figure></div>
<p>/etc/zabbix/io_monitor.sh 为脚本位置<br>重启zabbix_agentd服务<br>zabbix服务端测试自定义key是否可以使用</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">zabbix_get -s 188.103.189.104 -p 10050 -k <span class="string">"io_stats[disk_read]"</span></span><br></pre></td></tr></table></figure></div>
<p>zbbix页面完成监控配置</p>
]]></content>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>docker-内部端口映射问题</title>
<url>/2020/07/16/docker01/</url>
<content><![CDATA[<h2 id="虚拟机挂起再开启后docker容器映射端口无法访问"><a href="#虚拟机挂起再开启后docker容器映射端口无法访问" class="headerlink" title="虚拟机挂起再开启后docker容器映射端口无法访问"></a>虚拟机挂起再开启后docker容器映射端口无法访问</h2><h2 id="需要在宿主机上设置ipv4端口转发"><a href="#需要在宿主机上设置ipv4端口转发" class="headerlink" title="需要在宿主机上设置ipv4端口转发"></a>需要在宿主机上设置ipv4端口转发</h2> <a id="more"></a>
<p>编辑文件</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$ sudo vim /usr/lib/sysctl.d/50-default.conf</span><br></pre></td></tr></table></figure></div>
<p>添加</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">net.ipv4.ip_forward = 1</span><br></pre></td></tr></table></figure></div>
<p>编辑文件</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$ sudo vim /etc/sysctl.conf</span><br></pre></td></tr></table></figure></div>
<p>添加</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">net.ipv4.ip_forward = 1</span><br></pre></td></tr></table></figure></div>
<p>保存并重启</p>
]]></content>
<tags>
<tag>linux</tag>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title>my-first-blog</title>
<url>/2020/07/14/my-first-blog/</url>
<content><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>使用github pages服务搭建博客的好处有:</p>
<ol>
<li>全是静态文件,访问速度快;</li>
<li>免费方便,不用花一分钱就可以搭建一个自由的个人博客,不需要服务器不需要后台;</li>
<li>可以随意绑定自己的域名,不仔细看的话根本看不出来你的网站是基于github的;</li>
</ol>
<a id="more"></a>
<ol start="4">
<li>数据绝对安全,基于github的版本管理,想恢复到哪个历史版本都行;</li>
<li>博客内容可以轻松打包、转移、发布到其它平台;</li>
<li>等等;</li>
</ol>
]]></content>
</entry>
<entry>
<title>python-collection count函数</title>
<url>/2021/01/08/collection-count/</url>
<content><![CDATA[<p>count函数</p>
<a id="more"></a>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PYTHON"><figure class="iseeu highlight /python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Counter</span><br><span class="line"></span><br><span class="line">file=<span class="string">r"明细.xlsx"</span></span><br><span class="line">sheet_name_spxm = <span class="string">'1228'</span></span><br><span class="line">sheet_name_mas = <span class="string">'1227'</span></span><br><span class="line"></span><br><span class="line">data_spxm = pd.read_excel(file, sheet_name=sheet_name_spxm)</span><br><span class="line">data_spxm = np.array(data_spxm.iloc[:,<span class="number">0</span>])</span><br><span class="line">train_data_spxm = data_spxm.tolist()</span><br><span class="line"></span><br><span class="line">data_mas = pd.read_excel(file, sheet_name=sheet_name_mas)</span><br><span class="line">data_mas = np.array(data_mas.iloc[:,<span class="number">1</span>])</span><br><span class="line">train_data_mas = data_mas.tolist()</span><br><span class="line"></span><br><span class="line">data_spxm_dict = Counter()</span><br><span class="line">data_mas_dict = Counter()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> spxm <span class="keyword">in</span> train_data_spxm:</span><br><span class="line"> data_spxm_dict[spxm] += <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> mas <span class="keyword">in</span> train_data_mas:</span><br><span class="line"> data_mas_dict[mas] += <span class="number">1</span></span><br><span class="line"></span><br><span class="line">result = data_spxm_dict - data_mas_dict</span><br><span class="line">print(result)</span><br><span class="line">print(len(result))</span><br></pre></td></tr></table></figure></div>]]></content>
<tags>
<tag>python</tag>
</tags>
</entry>
<entry>
<title>master变更ip</title>
<url>/2021/06/19/master%E5%8F%98%E6%9B%B4ip/</url>
<content><![CDATA[<p>k8s的master更换ip后,通信问题会出现问题,kubelet日志也会出现node “master.com” not found,需要重新生成config文件和签名文件</p>
<a id="more"></a>
<p>在/etc/kubernetes/manifests中, 将etcd.yaml kube-apiserver.yaml里的ip地址替换为新的ip</p>
<p>生成新的config文件</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">mv admin.conf admin.conf.bak</span><br><span class="line">kubeadm init phase kubeconfig admin --apiserver-advertise-address <新ip></span><br></pre></td></tr></table></figure></div>
<p>删除旧的证书,生成新证书</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">cd pki</span><br><span class="line">mv apiserver.key apiserver.key.bak</span><br><span class="line">mv apiserver.crt apiserver.crt.bak</span><br><span class="line">kubeadm init phase certs apiserver --apiserver-advertise-address <新ip></span><br></pre></td></tr></table></figure></div>
<p>重启docker和kubelet</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SHELL"><figure class="iseeu highlight /shell"><table><tr><td class="code"><pre><span class="line">systemctl restart docker.service</span><br><span class="line">systemctl restart kubelet</span><br></pre></td></tr></table></figure></div>
<p>验证配置文件config</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">kubectl get nodes --kubeconfig=admin.conf</span><br></pre></td></tr></table></figure></div>
<p>将kubeconfig默认配置文件替换为admin.conf</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">mv admin.conf ~/.kube/config</span><br></pre></td></tr></table></figure></div>
<p>node节点需要将bootstrap-kubelet.conf和kubelet.conf的master ip修改为最新的ip并重启kubelet</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">systemctl restart kubelet</span><br></pre></td></tr></table></figure></div>
<p>master中的node节点就会处于ready状态</p>
]]></content>
<tags>
<tag>kubernetes</tag>
</tags>
</entry>
<entry>
<title>python_search</title>
<url>/2020/08/06/python-search/</url>
<content><![CDATA[<h2 id="利用高德地图web服务api实现地理-逆地址编码"><a href="#利用高德地图web服务api实现地理-逆地址编码" class="headerlink" title="利用高德地图web服务api实现地理/逆地址编码"></a>利用高德地图web服务api实现地理/逆地址编码</h2><a id="more"></a>
<h2 id="python第三方库的使用"><a href="#python第三方库的使用" class="headerlink" title="python第三方库的使用"></a>python第三方库的使用</h2><h3 id="利用python第三方库requests实现"><a href="#利用python第三方库requests实现" class="headerlink" title="利用python第三方库requests实现"></a>利用python第三方库requests实现</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import requests</span><br><span class="line">def geocodeG(address):</span><br><span class="line"> par = {</span><br><span class="line"> <span class="string">'address'</span>: address,</span><br><span class="line"> <span class="string">'key'</span>: <span class="string">'21860ea33f506e37966bb669a6e05ff6'</span></span><br><span class="line"> }</span><br><span class="line"> base = <span class="string">'http://restapi.amap.com/v3/geocode/geo'</span></span><br><span class="line"> response = requests.get(base, params=par)</span><br><span class="line"> answer = response.json()</span><br><span class="line"> mp = answer[<span class="string">'geocodes'</span>][0][<span class="string">'location'</span>].split(<span class="string">","</span>)</span><br><span class="line"> <span class="built_in">return</span> mp[0], mp[1]</span><br><span class="line"></span><br><span class="line">res = geocodeG(<span class="string">"浙江"</span>)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">结果</span><br><span class="line">(<span class="string">'120.152791'</span>, <span class="string">'30.267446'</span>)</span><br></pre></td></tr></table></figure></div>
<h2 id="HTTP协议的使用"><a href="#HTTP协议的使用" class="headerlink" title="HTTP协议的使用"></a>HTTP协议的使用</h2><h3 id="基于http协议利用标准库http-client实现"><a href="#基于http协议利用标准库http-client实现" class="headerlink" title="基于http协议利用标准库http.client实现"></a>基于http协议利用标准库http.client实现</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import http.client</span><br><span class="line">import json</span><br><span class="line">from urllib.parse import quote_plus</span><br><span class="line"></span><br><span class="line">base = <span class="string">"/v3/geocode/geo"</span></span><br><span class="line"></span><br><span class="line">def geocode(address):</span><br><span class="line"> path = <span class="string">"{}?address={}&key=21860ea33f506e37966bb669a6e05ff6"</span>.format(base, quote_plus(address))</span><br><span class="line"> connection = http.client.HTTPConnection(<span class="string">"restapi.amap.com"</span>)</span><br><span class="line"> connection.request(<span class="string">"GET"</span>, path)</span><br><span class="line"> rawreplay = connection.getresponse().<span class="built_in">read</span>()</span><br><span class="line"> reply = json.loads(rawreplay.decode(<span class="string">"utf-8"</span>))</span><br><span class="line"> mp = reply[<span class="string">'geocodes'</span>][0][<span class="string">'location'</span>].split(<span class="string">","</span>)</span><br><span class="line"> <span class="built_in">return</span> mp[0], mp[1]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">rep = geocode(<span class="string">'浙江'</span>)</span><br><span class="line"><span class="built_in">print</span>(rep)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">结果</span><br><span class="line">(<span class="string">'120.152791'</span>, <span class="string">'30.267446'</span>)</span><br></pre></td></tr></table></figure></div>
<h2 id="原始的网络会话"><a href="#原始的网络会话" class="headerlink" title="原始的网络会话"></a>原始的网络会话</h2><h3 id="利用基于传输层上socket实现"><a href="#利用基于传输层上socket实现" class="headerlink" title="利用基于传输层上socket实现"></a>利用基于传输层上socket实现</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import socket</span><br><span class="line">from urllib.parse import quote_plus</span><br><span class="line"></span><br><span class="line">request_text = <span class="string">""</span><span class="string">"\</span></span><br><span class="line"><span class="string">GET /v3/geocode/geo?address={}&key=21860ea33f506e37966bb669a6e05ff6 HTTP/1.1\r\n\</span></span><br><span class="line"><span class="string">Host: restapi.amap.com:80\r\n\</span></span><br><span class="line"><span class="string">User-Agent: Foundations of Python Network Programming example search4.py\r\n\</span></span><br><span class="line"><span class="string">Connection: close\r\n\</span></span><br><span class="line"><span class="string">\r\n\</span></span><br><span class="line"><span class="string">"</span><span class="string">""</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">def geocode(address):</span><br><span class="line"> sock = socket.socket()</span><br><span class="line"> sock.connect((<span class="string">"restapi.amap.com"</span>, 80))</span><br><span class="line"> request = request_text.format(quote_plus(address))</span><br><span class="line"> sock.sendall(request.encode(<span class="string">'ascii'</span>))</span><br><span class="line"> raw_reply = b<span class="string">''</span></span><br><span class="line"> <span class="keyword">while</span> True:</span><br><span class="line"> more = sock.recv(4096)</span><br><span class="line"> <span class="keyword">if</span> not more:</span><br><span class="line"> <span class="built_in">break</span></span><br><span class="line"> raw_reply += more</span><br><span class="line"> <span class="built_in">print</span>(raw_reply.decode(<span class="string">'utf-8'</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> geocode(<span class="string">'浙江'</span>)</span><br><span class="line"></span><br><span class="line">结果</span><br><span class="line"></span><br><span class="line">HTTP/1.1 200 OK</span><br><span class="line">Server: Tengine</span><br><span class="line">Date: Thu, 06 Aug 2020 08:05:41 GMT</span><br><span class="line">Content-Type: application/json;charset=UTF-8</span><br><span class="line">Content-Length: 344</span><br><span class="line">Connection: close</span><br><span class="line">Vary: Accept-Encoding</span><br><span class="line">gsid: 011026090152159670114194800019907006955</span><br><span class="line">sc: 0.005</span><br><span class="line">Access-Control-Allow-Origin: *</span><br><span class="line">Access-Control-Allow-Methods: *</span><br><span class="line">Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,key,x-biz,x-info,platinfo,encr,enginever,gzipped,poiid</span><br><span class="line"></span><br><span class="line">{<span class="string">"status"</span>:<span class="string">"1"</span>,<span class="string">"info"</span>:<span class="string">"OK"</span>,<span class="string">"infocode"</span>:<span class="string">"10000"</span>,<span class="string">"count"</span>:<span class="string">"1"</span>,<span class="string">"geocodes"</span>:[{<span class="string">"formatted_address"</span>:<span class="string">"浙江省"</span>,<span class="string">"country"</span>:<span class="string">"中国"</span>,<span class="string">"province"</span>:<span class="string">"浙江省"</span>,<span class="string">"city"</span>:[],<span class="string">"district"</span>:[],<span class="string">"township"</span>:[],<span class="string">"neighborhood"</span>:{<span class="string">"name"</span>:[],<span class="string">"type"</span>:[]},<span class="string">"building"</span>:{<span class="string">"name"</span>:[],<span class="string">"type"</span>:[]},<span class="string">"adcode"</span>:<span class="string">"330000"</span>,<span class="string">"street"</span>:[],<span class="string">"number"</span>:[],<span class="string">"location"</span>:<span class="string">"120.152791,30.267446"</span>,<span class="string">"level"</span>:<span class="string">"省"</span>}]}</span><br></pre></td></tr></table></figure></div>
<p>地理/逆地理编码api开发文档</p>
<h4 id="https-lbs-amap-com-api-webservice-guide-api-georegeo"><a href="#https-lbs-amap-com-api-webservice-guide-api-georegeo" class="headerlink" title="https://lbs.amap.com/api/webservice/guide/api/georegeo/"></a><a href="https://lbs.amap.com/api/webservice/guide/api/georegeo/" target="_blank" rel="noopener">https://lbs.amap.com/api/webservice/guide/api/georegeo/</a></h4>]]></content>
<tags>
<tag>python</tag>
<tag>requests</tag>
<tag>socket</tag>
</tags>
</entry>
<entry>
<title>python random</title>
<url>/2020/07/24/python-OrderedDict/</url>
<content><![CDATA[<h3 id="模块random包含以各种方式生成随机数的函数,其中的randint-返回一个位于指定范围的数"><a href="#模块random包含以各种方式生成随机数的函数,其中的randint-返回一个位于指定范围的数" class="headerlink" title="模块random包含以各种方式生成随机数的函数,其中的randint()返回一个位于指定范围的数"></a>模块random包含以各种方式生成随机数的函数,其中的randint()返回一个位于指定范围的数</h3><a id="more"></a>
<p>例如,下面的代码返回一个 1-6内的整数:</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">from random import randint</span><br><span class="line">x = randint(1, 6)</span><br></pre></td></tr></table></figure></div>
<h3 id="使用模块random创建die类,包含一个sides属性,默认值为6。编写一个roll-die-方法,打印位于1和骰子面数之间的随机数。"><a href="#使用模块random创建die类,包含一个sides属性,默认值为6。编写一个roll-die-方法,打印位于1和骰子面数之间的随机数。" class="headerlink" title="使用模块random创建die类,包含一个sides属性,默认值为6。编写一个roll_die()方法,打印位于1和骰子面数之间的随机数。"></a>使用模块random创建die类,包含一个sides属性,默认值为6。编写一个roll_die()方法,打印位于1和骰子面数之间的随机数。</h3><p>下面代码通过调用roll_die()方法输入一个int类型传递给self.sides,生成骰子面数和投掷次数,投掷次数也可以设置成默认值。</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">from random import randint</span><br><span class="line"></span><br><span class="line">class Die():</span><br><span class="line"> def __init__(self):</span><br><span class="line"> self.sides = 6</span><br><span class="line"></span><br><span class="line"> def roll_die(self):</span><br><span class="line"> self.sides = int(input(<span class="string">"please input your number: "</span>))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(self.sides):</span><br><span class="line"> x = randint(1, self.sides)</span><br><span class="line"> <span class="built_in">print</span>(x)</span><br></pre></td></tr></table></figure></div>
<p>指定一个实例名称,并调用类中的roll_die()方法</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">x = Die()</span><br><span class="line">x.roll_die()</span><br><span class="line">实现效果</span><br><span class="line">please input your number: 5</span><br><span class="line">1</span><br><span class="line">3</span><br><span class="line">5</span><br><span class="line">2</span><br><span class="line">5</span><br></pre></td></tr></table></figure></div>]]></content>
<tags>
<tag>python</tag>
</tags>
</entry>
<entry>
<title>python-unittest</title>
<url>/2020/07/27/python-unittest/</url>
<content><![CDATA[<h2 id="类的测试"><a href="#类的测试" class="headerlink" title="类的测试"></a>类的测试</h2><h3 id="import-unittest导入unittest模块"><a href="#import-unittest导入unittest模块" class="headerlink" title="import unittest导入unittest模块"></a>import unittest导入unittest模块</h3><h3 id="定义一个继承自unittest-TestCase的测试用例类-class-TestSurvey-unittest-TestCase"><a href="#定义一个继承自unittest-TestCase的测试用例类-class-TestSurvey-unittest-TestCase" class="headerlink" title="定义一个继承自unittest.TestCase的测试用例类 class TestSurvey(unittest.TestCase)"></a>定义一个继承自unittest.TestCase的测试用例类 class TestSurvey(unittest.TestCase)</h3><p>unittest类包含方法setUp(),只需要创建一次对象,就可以在每个测试方法中使用它们</p>
<a id="more"></a>
<p>如果在TestCase类中包含了方法setUp(),python将先运行它,再运行各个以test_开头的方法,这样编写的每个测试方法中都可使用在setUp()中创建的对象了<br>定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中</p>
<p>调用unittest.main()启动测试</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">assertEqual(a, b) a == b</span><br><span class="line"></span><br><span class="line">assertNotEqual(a, b) a != b</span><br><span class="line"></span><br><span class="line">assertTrue(x) bool(x) is True</span><br><span class="line"></span><br><span class="line">assertFalse(x) bool(x) is False</span><br><span class="line"></span><br><span class="line">assertIs(a, b) a is b</span><br><span class="line"></span><br><span class="line">assertIsNot(a, b) a is not b</span><br><span class="line"></span><br><span class="line">assertIsNone(x) x is None</span><br><span class="line"></span><br><span class="line">assertIsNotNone(x) x is not None</span><br><span class="line"></span><br><span class="line">assertIn(item, list) item <span class="keyword">in</span> list</span><br><span class="line"></span><br><span class="line">assertNotIn(item, list) item not <span class="keyword">in</span> list</span><br><span class="line"></span><br><span class="line">assertIsInstance(a, b) isinstance(a, b)</span><br><span class="line"></span><br><span class="line">assertNotIsInstance(a, b) not isinstance(a, b)</span><br></pre></td></tr></table></figure></div>
<h3 id="类测试案例"><a href="#类测试案例" class="headerlink" title="类测试案例"></a>类测试案例</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">class AnonymousSurvey():</span><br><span class="line"> <span class="string">""</span><span class="string">"收集匿名调查问卷的答案"</span><span class="string">""</span></span><br><span class="line"> def __init__(self, question):</span><br><span class="line"> <span class="string">""</span><span class="string">"存储一个问题,并为存储答案做准备"</span><span class="string">""</span></span><br><span class="line"></span><br><span class="line"> self.question = question</span><br><span class="line"> self.responses = []</span><br><span class="line"></span><br><span class="line"> def show_question(self):</span><br><span class="line"> <span class="comment"># 显示调查问卷</span></span><br><span class="line"> <span class="built_in">print</span>(self.question)</span><br><span class="line"></span><br><span class="line"> def store_responses(self, new_respones):</span><br><span class="line"> <span class="string">""</span><span class="string">"存储单份调查问卷"</span><span class="string">""</span></span><br><span class="line"> self.responses.append(new_respones)</span><br><span class="line"></span><br><span class="line"> def show_result(self):</span><br><span class="line"> <span class="string">""</span><span class="string">"显示收集到的所以信息"</span><span class="string">""</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"survey result:"</span>)</span><br><span class="line"> <span class="keyword">for</span> response <span class="keyword">in</span> self.responses:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"- "</span> + response)</span><br><span class="line"> <span class="built_in">print</span>(self.responses)</span><br></pre></td></tr></table></figure></div>
<p>关于survey的测试用例</p>
<p>test_survey.py</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import unittest</span><br><span class="line">from survey import AnonymousSurvey</span><br><span class="line"></span><br><span class="line">class TestSurvey(unittest.TestCase):</span><br><span class="line"> <span class="string">""</span><span class="string">"争对AnonymousSurvey类的测试"</span><span class="string">""</span></span><br><span class="line"> def setUp(self):</span><br><span class="line"> <span class="string">""</span><span class="string">"创建一个调查对象和一组答案,供使用的测试方法使用"</span><span class="string">""</span></span><br><span class="line"> question = <span class="string">"what language did you first learn to speak?"</span></span><br><span class="line"> self.my_survey = AnonymousSurvey(question)</span><br><span class="line"> self.responses = [<span class="string">"English"</span>, <span class="string">"Spanish"</span>, <span class="string">"Mandarin"</span>]</span><br><span class="line"></span><br><span class="line"> def test_store_single_response(self):</span><br><span class="line"> <span class="string">""</span><span class="string">"测试单个答案存储"</span><span class="string">""</span></span><br><span class="line"> <span class="comment"># question = "what language did you first learn to speak?"</span></span><br><span class="line"> <span class="comment"># my_survey = AnonymousSurvey(question)</span></span><br><span class="line"> self.my_survey.store_responses(self.responses[1])</span><br><span class="line"></span><br><span class="line"> self.assertIn(self.responses[1], self.my_survey.responses)</span><br><span class="line"></span><br><span class="line"> def test_store_three_responses(self):</span><br><span class="line"> <span class="string">""</span><span class="string">"测试三个答案存储"</span><span class="string">""</span></span><br><span class="line"> <span class="comment"># question = "what language did you first learn to speak?"</span></span><br><span class="line"> <span class="comment"># my_survey = AnonymousSurvey(question)</span></span><br><span class="line"> <span class="comment"># responses = ["English", "Spanish", "Mandarin"]</span></span><br><span class="line"> <span class="keyword">for</span> response <span class="keyword">in</span> self.responses:</span><br><span class="line"> self.my_survey.store_responses(response)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> response <span class="keyword">in</span> self.responses:</span><br><span class="line"> self.assertIn(response, self.my_survey.responses)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> unittest.main()</span><br></pre></td></tr></table></figure></div>
<p>测试效果</p>
<img src="/2020/07/27/python-unittest/%E6%B5%8B%E8%AF%95%E6%95%88%E6%9E%9C.png" class="" title="[title]">]]></content>
<tags>
<tag>python</tag>
</tags>
</entry>
<entry>
<title>split</title>
<url>/2020/07/14/split/</url>
<content><![CDATA[<p>split 选项 文件 拆分后文件的前缀</p>
<p>-b 以文件的大小进行文件切分<br>-d 使用数字作为拆分后的文件的后缀,默认是以字母作为后缀的,配合-a 可以指定数字后缀的位数<br>可以放在后台运行</p>
<a id="more"></a>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$ nohup split -db 25G 00alg.tar 00alg &</span><br></pre></td></tr></table></figure></div>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">window下合并</span><br><span class="line">打开cmd,移动到文件目录</span><br><span class="line">$ copy /b D:\测试\data0* 00alg.tar</span><br></pre></td></tr></table></figure></div>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">linux 下合并</span><br><span class="line">终端移动到指定目录下</span><br><span class="line">如果想要直接解压</span><br><span class="line">$ cat data0* | tar xvf</span><br></pre></td></tr></table></figure></div>
<p>如果不想直接解压,想保存一份合并后的文件再解压</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$ cat data0* > 00alg.tar</span><br><span class="line">可以放在后台运行</span><br><span class="line">$ nohup cat data0* > 00alg.tar &</span><br><span class="line">$ tar xvf 00alg.tar</span><br></pre></td></tr></table></figure></div>]]></content>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>Hexo yilia</title>
<url>/2020/07/14/yilia/</url>
<content><![CDATA[<h2 id="Hexo-yilia配置"><a href="#Hexo-yilia配置" class="headerlink" title="Hexo yilia配置"></a>Hexo yilia配置</h2><h3 id="修改yilia-layout-partial-left-col-ejs"><a href="#修改yilia-layout-partial-left-col-ejs" class="headerlink" title="修改yilia/layout/_partial/left-col.ejs"></a>修改yilia/layout/_partial/left-col.ejs</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line"><img src=<span class="string">"<%- url_for(theme.avatar) %>"</span> class=<span class="string">"js-avatar"</span>></span><br></pre></td></tr></table></figure></div>
<a id="more"></a>
<img src="/2020/07/14/yilia/partial.png" class="" title="[title]">
<h2 id="添加图片"><a href="#添加图片" class="headerlink" title="添加图片"></a>添加图片</h2><h3 id="项目根目录-config-yml修改post-asset-folder"><a href="#项目根目录-config-yml修改post-asset-folder" class="headerlink" title="项目根目录_config.yml修改post_asset_folder"></a>项目根目录_config.yml修改post_asset_folder</h3> <div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">post_asset_folder: <span class="literal">true</span></span><br></pre></td></tr></table></figure></div>
<h3 id="进入到根目录下,新建博客"><a href="#进入到根目录下,新建博客" class="headerlink" title="进入到根目录下,新建博客"></a>进入到根目录下,新建博客</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$ hexo clean</span><br><span class="line">$ hexo n <span class="string">"XXX"</span></span><br></pre></td></tr></table></figure></div>
<p>新建完成后根目录下的source/_posts会有XXX.md和XXX文件夹(两个是同名的)<br>将图片放入文件夹,并在md博客文件中输入</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">{% asset_img 图片名.图片后缀 [title] %}</span><br></pre></td></tr></table></figure></div>
]]></content>
<tags>
<tag>hexo yilia</tag>
</tags>
</entry>
<entry>
<title>ubuntu-mysql</title>
<url>/2020/10/14/ubuntu-mysql/</url>
<content><![CDATA[<h3 id="mysql的基本命令"><a href="#mysql的基本命令" class="headerlink" title="mysql的基本命令"></a>mysql的基本命令</h3><p>安装MySQL相关</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">sudo apt-get install mysql-server</span><br></pre></td></tr></table></figure></div>
<a id="more"></a>
<p>2、查看MySQL安装情况</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">apt-cacche show mysql-server</span><br></pre></td></tr></table></figure></div>
<p>3、查看MySQL的状态</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">service mysql status</span><br></pre></td></tr></table></figure></div>
<p>4、启动</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">service mysql start</span><br></pre></td></tr></table></figure></div>
<p>5、停止</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">service mysql stop</span><br></pre></td></tr></table></figure></div>
<p>6、重启</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">service mysql restart</span><br></pre></td></tr></table></figure></div>
<p>7、查看配置文件的介绍<br>cd /etc/mysql/mysql.conf.dvim mysqld.cnf<br>port:默认端口号<br>datadir:数据库的保存路径<br>bind-address:表示服务器绑定的ip</p>
<p>6、登录MySQL<br>mysql -uroot -p (回车后输入mysql密码)</p>
<p>7、退出数据库<br>exit、quit、ctrl+d<br>以下是SQL语言,每句以;(分号)结尾。</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SQL"><figure class="iseeu highlight /sql"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">### 数据库相关操作</span></span><br><span class="line">```bash</span><br><span class="line">1、创建数据库</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">database</span> databaseName <span class="keyword">charset</span>=utf8;</span><br><span class="line">note:若不指定charset(编码格式)只能是英文。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">2、查看数据库</span><br><span class="line"><span class="keyword">show</span> <span class="keyword">databases</span>;</span><br><span class="line"></span><br><span class="line">3、使用数据库</span><br><span class="line"><span class="keyword">use</span> databaseName;</span><br><span class="line"></span><br><span class="line">4、查看当前所在数据库</span><br><span class="line"><span class="keyword">select</span> datadse();</span><br><span class="line"></span><br><span class="line">5、删除数据库</span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">database</span> databaseName;</span><br></pre></td></tr></table></figure></div>
<h3 id="表结构的相关操作"><a href="#表结构的相关操作" class="headerlink" title="表结构的相关操作"></a>表结构的相关操作</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">1、创建表</span><br><span class="line">create table 表名(属性1 类型 约束,属性2 类型 [约束],...);(不同字段间无空格)</span><br><span class="line"></span><br><span class="line">2、删除整张表</span><br><span class="line">drop tablename;</span><br><span class="line"></span><br><span class="line">3、查看创表语句</span><br><span class="line">show create table 表名;</span><br><span class="line"></span><br><span class="line">查看表结构:</span><br><span class="line">desc 表名;</span><br><span class="line"></span><br><span class="line">4、修改表(alter)-添加字段</span><br><span class="line">alter table tableName add 字段名 类型 约束;</span><br><span class="line"></span><br><span class="line">5、alter - 修改字段属性或约束</span><br><span class="line">alter table tableName modify 属性名 新类型 新约束;</span><br><span class="line"></span><br><span class="line">7、alter-修改字段</span><br><span class="line">alter table tableName change old属性名 new属性名 类型 约束;</span><br><span class="line"></span><br><span class="line">8、alter-删除字段</span><br><span class="line">alter table tableName drop 字段;</span><br></pre></td></tr></table></figure></div>]]></content>
<tags>
<tag>mysql</tag>
</tags>
</entry>
<entry>
<title>了解控制器做了什么以及如何做的</title>
<url>/2021/06/14/%E4%BA%86%E8%A7%A3%E6%8E%A7%E5%88%B6%E5%99%A8%E5%81%9A%E4%BA%86%E4%BB%80%E4%B9%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E5%81%9A%E7%9A%84/</url>
<content><![CDATA[<h2 id="Replication管理器"><a href="#Replication管理器" class="headerlink" title="Replication管理器"></a>Replication管理器</h2><p>ReplicationController的操作可以理解为一个无限循环,每次循环,控制器都会查找符合其pod选择器定义的pod的数量,并且将该数值和期望的复制集(replica)数量作比较。</p>
<a id="more"></a>
<p>启动ReplicationController资源的控制器叫作Replication管理器。<br>当运行pod实例太少,ReplicationController会运行额外的实例,但它自己实际上不会去运行pod。它会创建新的pod清单,发布到API服务器,让调度器以及kubelet来做调度工作并运行pod。</p>
<img src="/2021/06/14/%E4%BA%86%E8%A7%A3%E6%8E%A7%E5%88%B6%E5%99%A8%E5%81%9A%E4%BA%86%E4%BB%80%E4%B9%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E5%81%9A%E7%9A%84/Replication.png" class="" title="[title]">
<p>Replication管理器通过API服务器操纵pod API对象来完成其它工作。所有控制器就是这样运作的。</p>
<h2 id="ReplicaSet、DaemonSet以及Job控制器"><a href="#ReplicaSet、DaemonSet以及Job控制器" class="headerlink" title="ReplicaSet、DaemonSet以及Job控制器"></a>ReplicaSet、DaemonSet以及Job控制器</h2><p>ReplicaSet控制器基本上做了和前面描述的Replication管理器一样的事情。DaemonSet以及Job控制器比较相似,从它们各自资源集中定义的Pod模板创建pod资源。与replication管理器相似,这些控制器不会运行pod,而是将pod定义到发布API服务器,让Kubelet创建容器并运行。</p>
<h2 id="Deployment控制器"><a href="#Deployment控制器" class="headerlink" title="Deployment控制器"></a>Deployment控制器</h2><p>Deployment控制器负责使deploymnet的实际状态与对应Deployment API对象的期望状态同步。<br>每次Deployment对象修改后(如果修改会影响到部署的pod),Deployment控制器都会滚动升级到新的版本。通过创建一个ReplicaSet,直到旧pod被新的代替。并不会直接创建任何pod。</p>
<h2 id="StatefulSet控制器"><a href="#StatefulSet控制器" class="headerlink" title="StatefulSet控制器"></a>StatefulSet控制器</h2><p>StatefulSet控制器,类似于ReplicaSet控制器以及其他相关控制器,根据StatefulSet资源定义创建、管理、删除pod。其他的控制器只管理pod,而StatefulSet控制器会初始化并管理每个pod实例的持久卷声明字段。</p>
<h2 id="Node控制器"><a href="#Node控制器" class="headerlink" title="Node控制器"></a>Node控制器</h2><p>Node控制器管理Node资源,描述了集群工作节点。其中,Node控制器使节点对象列表与集群中实际运行的机器列表保持同步。同时监控每个节点的健康状态,删除不可达节点的pod。<br>Node控制器不是唯一对Node对象做更改的组件。Kubelet也可以做更改,那么显然可以由用户通过REST API调用做更改。</p>
<h2 id="Service控制器"><a href="#Service控制器" class="headerlink" title="Service控制器"></a>Service控制器</h2><p>Service控制器就是用来在LoadBalancer类型服务被创建或删除时,从基础设施服务请求、释放负载均衡器的。</p>
<h2 id="Endpoint控制器"><a href="#Endpoint控制器" class="headerlink" title="Endpoint控制器"></a>Endpoint控制器</h2><p>Service不会直接连接到pod,而是包含一个端点列表(IP和端口),列表要么是手动,要么是根据Service定义的pod选择器自动创建、更新。Endpoint控制器作为活动的组件,定期根据匹配标签选择器的pod的IP、端口更新端口列表。<br>控制器同时监听了Service和pod。当Service被添加、修改,或者pod被添加、修改或删除时,控制器会选中匹配Service的pod选择器的pod,或将其IP和端口添加到Endpoint资源中。请记住,Endpoint对象是个独立的对象,所以当需要的时候控制器会创建它。同样地,当删除Service时,Endpoint对象也会被删除。</p>
<img src="/2021/06/14/%E4%BA%86%E8%A7%A3%E6%8E%A7%E5%88%B6%E5%99%A8%E5%81%9A%E4%BA%86%E4%BB%80%E4%B9%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E5%81%9A%E7%9A%84/Endpoint.png" class="" title="[title]">
<h2 id="Namespace控制器"><a href="#Namespace控制器" class="headerlink" title="Namespace控制器"></a>Namespace控制器</h2><p>当删除一个Namespace资源时,该命名空间里的所有资源都会被删除。这就是Namespace控制器做的事情。当收到删除Namespace对象的通知时,控制器通过API服务器删除所有归属该命名空间的资源。</p>
<h2 id="PersistentVolume控制器"><a href="#PersistentVolume控制器" class="headerlink" title="PersistentVolume控制器"></a>PersistentVolume控制器</h2><p>一旦用户创建了一个持久卷声明,kubernetes必须找到一个合适的持久卷同时将其和声明绑定。这些由持久卷控制器实现。<br>对于一个持久卷声明,控制器为声明查找最佳匹配项,通过选择匹配声明中的访问模式,并且声明的容量大于需求的容量的最小持久卷。实现方法是保存一份有序的持久卷列表,对于每种访问模式按照容量升序排列,返回列表的第一个卷,<br>当用户删除持久卷声明时,会解绑卷,然后根据卷的回收策略进行回收(原样保留、删除或清空)。</p>
<h3 id="所有这些控制器都是通过API服务器来操作API对象的。它们不会直接和Kubelet通信或者发送任何类型的指令。实际上,它们不知道Kubelet的存在。控制器更新API服务器的一个资源后,kubelet和Kubernetes-Service-Proxy(也不知道控制器的存在)会做它们的工作,例如启动pod容器、加载网络存储,或者就服务而言,创建跨pod的负载均衡。"><a href="#所有这些控制器都是通过API服务器来操作API对象的。它们不会直接和Kubelet通信或者发送任何类型的指令。实际上,它们不知道Kubelet的存在。控制器更新API服务器的一个资源后,kubelet和Kubernetes-Service-Proxy(也不知道控制器的存在)会做它们的工作,例如启动pod容器、加载网络存储,或者就服务而言,创建跨pod的负载均衡。" class="headerlink" title="所有这些控制器都是通过API服务器来操作API对象的。它们不会直接和Kubelet通信或者发送任何类型的指令。实际上,它们不知道Kubelet的存在。控制器更新API服务器的一个资源后,kubelet和Kubernetes Service Proxy(也不知道控制器的存在)会做它们的工作,例如启动pod容器、加载网络存储,或者就服务而言,创建跨pod的负载均衡。"></a>所有这些控制器都是通过API服务器来操作API对象的。它们不会直接和Kubelet通信或者发送任何类型的指令。实际上,它们不知道Kubelet的存在。控制器更新API服务器的一个资源后,kubelet和Kubernetes Service Proxy(也不知道控制器的存在)会做它们的工作,例如启动pod容器、加载网络存储,或者就服务而言,创建跨pod的负载均衡。</h3>]]></content>
<tags>
<tag>kubernetes</tag>
</tags>
</entry>
<entry>
<title>数据存储和读取</title>
<url>/2020/07/23/%E5%AD%98%E5%82%A8%E6%95%B0%E6%8D%AE/</url>
<content><![CDATA[<h2 id="使用json-dump-和json-load"><a href="#使用json-dump-和json-load" class="headerlink" title="使用json.dump()和json.load()"></a>使用json.dump()和json.load()</h2><h3 id="存储数据"><a href="#存储数据" class="headerlink" title="存储数据"></a>存储数据</h3><a id="more"></a>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import json</span><br><span class="line"></span><br><span class="line">numbers = [2, 3, 5, 7, 11, 12]</span><br><span class="line"></span><br><span class="line">filename = <span class="string">"numbers.json"</span></span><br><span class="line">with open(filename, <span class="string">"w"</span>) as file_object:</span><br><span class="line"> json.dump(numbers, file_object)</span><br></pre></td></tr></table></figure></div>
<h3 id="读取数据"><a href="#读取数据" class="headerlink" title="读取数据"></a>读取数据</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">import json</span><br><span class="line"></span><br><span class="line">filename = <span class="string">"numbers.json"</span></span><br><span class="line"></span><br><span class="line">with open(filename, <span class="string">"r"</span>) as file_object:</span><br><span class="line"> numbers = json.load(file_object)</span><br><span class="line"> <span class="built_in">print</span>(numbers)</span><br></pre></td></tr></table></figure></div>
]]></content>
<tags>
<tag>python</tag>
</tags>
</entry>
<entry>
<title>关于expect</title>
<url>/2021/06/18/%E5%85%B3%E4%BA%8Eexpect/</url>
<content><![CDATA[<p>expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。</p>
<a id="more"></a>
<p>expect自动交互流程:</p>
<p>spawn启动指定进程–>expect获取指定关键字–>send向指定程序发送指定字符–>执行完成退出.</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">yum install -y expect</span><br></pre></td></tr></table></figure></div>
<p>expect的常用命令:</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SHELL"><figure class="iseeu highlight /shell"><table><tr><td class="code"><pre><span class="line">spawn 交互程序开始后面跟命令或者指定程序</span><br><span class="line">expect 获取匹配信息匹配成功则执行expect后面的程序动作</span><br><span class="line">send exp_send 用于发送指定的字符串信息</span><br><span class="line">exp_continue 在expect中多次匹配就需要用到</span><br><span class="line">send_user 用来打印输出 相当于shell中的echo</span><br><span class="line">exit 退出expect脚本</span><br><span class="line">eof expect执行结束 退出</span><br><span class="line">set 定义变量</span><br><span class="line">puts 输出变量</span><br><span class="line">set timeout 设置超时时间</span><br></pre></td></tr></table></figure></div>
<h3 id="ssh登录远程主机执行命令"><a href="#ssh登录远程主机执行命令" class="headerlink" title="ssh登录远程主机执行命令"></a>ssh登录远程主机执行命令</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SHELL"><figure class="iseeu highlight /shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">!/usr/bin/expect</span></span><br><span class="line">spawn ssh root@192.168.59.131</span><br><span class="line">expect "password:"</span><br><span class="line">send "12345\r"</span><br><span class="line">interact</span><br></pre></td></tr></table></figure></div>
<h3 id="ssh远程登录主机执行命令,在shell脚本中执行expect命令"><a href="#ssh远程登录主机执行命令,在shell脚本中执行expect命令" class="headerlink" title="ssh远程登录主机执行命令,在shell脚本中执行expect命令"></a>ssh远程登录主机执行命令,在shell脚本中执行expect命令</h3><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">#!/bin/bash</span><br><span class="line"></span><br><span class="line">passwd='12345'</span><br><span class="line"></span><br><span class="line">/usr/bin/expect <<-EOF</span><br><span class="line"></span><br><span class="line">set time 30</span><br><span class="line">spawn ssh root@192.168.59.131 df -Th</span><br><span class="line">expect {</span><br><span class="line">"*yes/no" { send "yes\r"; exp_continue }</span><br><span class="line">"*password:" { send "$passwd\r" }</span><br><span class="line">}</span><br><span class="line">expect eof</span><br><span class="line">EOF</span><br></pre></td></tr></table></figure></div>
<p>expect send可能会出现invalid command name或 no such variable 没此变量的报错<br>将特殊符号进行转义,即[如语句里面特殊符号太多,转义太麻烦。</p>
<p>可以使用send – {}格式,将send的内容放到大括号中转义。</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SHELL"><figure class="iseeu highlight /shell"><table><tr><td class="code"><pre><span class="line">send "awk 'BEGIN{FS=[ ,]} { print $2+$4 }' file\r "</span><br></pre></td></tr></table></figure></div>
<p>替换为</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="SHELL"><figure class="iseeu highlight /shell"><table><tr><td class="code"><pre><span class="line">send -- {awk 'BEGIN{FS=[ ,]} { print $2+$4 }' file}</span><br><span class="line">send -- \r</span><br></pre></td></tr></table></figure></div>
]]></content>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>关于StatefulSet</title>
<url>/2021/06/15/%E5%85%B3%E4%BA%8EStatefulSet/</url>
<content><![CDATA[<p>1.StatefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为:</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line">$(podname).(headless servername)</span><br></pre></td></tr></table></figure></div>
<p>也就意味着服务间是通过Pod域名来通信而非 Pod IP,因为当Pod所在Node发生故障时,Pod会被飘移到其它 Node 上,Pod IP 会发生变化,但是 Pod 域名不会有变化。</p>
<a id="more"></a>
<p>2.缩容一个statefulset会最先删除最高索引值的实例(要把一个statefulset从两个实例扩容到三个实例,那么新实例的索引值就会是2,现有实例使用索引值为0和1)。</p>
<p>3.像statefulset创建pod一样,statefulset也需要创建持久卷声明。所以一个statefulset可以拥有一个或多个卷声明模板,这些持久卷声明会在创建pod前创建出来,绑定到一个pod实例上。</p>
<img src="/2021/06/15/%E5%85%B3%E4%BA%8EStatefulSet/pv.png" class="" title="[title]">
<h3 id="statefulset缩容时只会删除pod。不会删除持久卷声明(当一个声明被删除后,与之绑定的持久卷就会被回收和删除"><a href="#statefulset缩容时只会删除pod。不会删除持久卷声明(当一个声明被删除后,与之绑定的持久卷就会被回收和删除" class="headerlink" title="statefulset缩容时只会删除pod。不会删除持久卷声明(当一个声明被删除后,与之绑定的持久卷就会被回收和删除)"></a>statefulset缩容时只会删除pod。不会删除持久卷声明(当一个声明被删除后,与之绑定的持久卷就会被回收和删除)</h3><img src="/2021/06/15/%E5%85%B3%E4%BA%8EStatefulSet/delete_pvc.png" class="" title="[title]">
<h3 id="在部署一个statefulset之前,需要创建一个用于在有状态的pod之间提供网络标识的headless-Service。clusterIP为none-标记了它是一个headless-Service"><a href="#在部署一个statefulset之前,需要创建一个用于在有状态的pod之间提供网络标识的headless-Service。clusterIP为none-标记了它是一个headless-Service" class="headerlink" title="在部署一个statefulset之前,需要创建一个用于在有状态的pod之间提供网络标识的headless Service。clusterIP为none,标记了它是一个headless Service"></a>在部署一个statefulset之前,需要创建一个用于在有状态的pod之间提供网络标识的headless Service。clusterIP为none,标记了它是一个headless Service</h3><img src="/2021/06/15/%E5%85%B3%E4%BA%8EStatefulSet/headless.png" class="" title="[title]">
<h3 id="statefulset会在第一个pod就绪后才创建第二个pod副本,因为状态明确的集群应用对同时有两个集群成员启动引起的竞争情况是非常敏感的。所以依次启动每个成员是比较安全可靠的,特定的有状态应用集群在两个或多个集群成员同事启动所引起的竞态条件是非常敏感的,所以在每个成员完全启动后再启动剩下的会更加安全。"><a href="#statefulset会在第一个pod就绪后才创建第二个pod副本,因为状态明确的集群应用对同时有两个集群成员启动引起的竞争情况是非常敏感的。所以依次启动每个成员是比较安全可靠的,特定的有状态应用集群在两个或多个集群成员同事启动所引起的竞态条件是非常敏感的,所以在每个成员完全启动后再启动剩下的会更加安全。" class="headerlink" title="statefulset会在第一个pod就绪后才创建第二个pod副本,因为状态明确的集群应用对同时有两个集群成员启动引起的竞争情况是非常敏感的。所以依次启动每个成员是比较安全可靠的,特定的有状态应用集群在两个或多个集群成员同事启动所引起的竞态条件是非常敏感的,所以在每个成员完全启动后再启动剩下的会更加安全。"></a>statefulset会在第一个pod就绪后才创建第二个pod副本,因为状态明确的集群应用对同时有两个集群成员启动引起的竞争情况是非常敏感的。所以依次启动每个成员是比较安全可靠的,特定的有状态应用集群在两个或多个集群成员同事启动所引起的竞态条件是非常敏感的,所以在每个成员完全启动后再启动剩下的会更加安全。</h3><img src="/2021/06/15/%E5%85%B3%E4%BA%8EStatefulSet/%E9%87%8D%E6%96%B0%E8%B0%83%E5%BA%A6.png" class="" title="[title]">
]]></content>
<tags>
<tag>kubernetes</tag>
</tags>
</entry>
<entry>
<title>关于初始容器</title>
<url>/2021/06/17/%E5%85%B3%E4%BA%8E%E5%88%9D%E5%A7%8B%E5%AE%B9%E5%99%A8/</url>
<content><![CDATA[<h2 id="理解初始容器"><a href="#理解初始容器" class="headerlink" title="理解初始容器"></a>理解初始容器</h2><p>一个pod里可以运行多个容器,它也可以运行一个或者多个初始容器,初始容器先于应用容器运行,除了以下两点外,初始容器和普通容器没有什么两样:</p>
<ul>
<li>它们总是run to completion</li>
<li>一个初始容器必须成功运行另一个才能运行</li>
</ul>
<a id="more"></a>
<p>如果pod中的一个初始容器运行失败,则kubernetes会尝试重启pod直到初始容器成功运行,如果pod的重启策略设置为从不(never),则不会重启.</p>
<p>创建容器时,在pod spec里添加initContainers字段,则指定容器即为初始容器,它们的返回状态作为数组保存在.status.initContainerStatuses里(与普通容器状态存储字段.status.containerStatuses类似)</p>
<h2 id="初始容器和普通容器的不同"><a href="#初始容器和普通容器的不同" class="headerlink" title="初始容器和普通容器的不同"></a>初始容器和普通容器的不同</h2><p>初始容器支持所有普通容器的特征,包括资源配额限制和存储卷以及安全设置.但是对资源申请和限制处理初始容器略有不同,下面会介绍.此外,初始容器不支持可用性探针(readiness probe),因为它在ready之前必须run to completion</p>
<p>如果在一个pod里指定了多个初始容器,则它们会依次启动起来(pod内的普通容器并行启动),并且只有上一个成功下一个才能启动.当所有的初始容器都启动了,kubernetes才开始启普通应用容器.</p>
<h2 id="初始容器能做什么"><a href="#初始容器能做什么" class="headerlink" title="初始容器能做什么"></a>初始容器能做什么</h2><p>由于初始容器和普通应用容器是分开的镜像,因此他在做一些初始化工作很有优势</p>
<ul>
<li>它们可以包含并且运行一些出于安全考虑不适合和应用放在一块的小工具.</li>
<li>它们可以一些小工具和自定义代码来做些初始化工作,这样就不需要在普通应用容器里使用sed,awk,python或者dig来做初始化工作了</li>
<li>应用构建者和发布者可以独立工作,而不必再联合起来处理同一个pod</li>
<li>它们使用linux namespaces因此它们和普通应用pod拥有不同的文件系统视图.因此他们可以被赋予普通应用容器获取不到的secrets</li>
<li>它们在应用容器启动前运行,因此它们可以阻止或者延缓普通应用容器的初始化直到需要的条件满足</li>
</ul>
<p>示例:</p>
<ul>
<li>通过执行shell命令来等待一个服务创建完成,命令如下:</li>
</ul>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="BASH"><figure class="iseeu highlight /bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> {1..100}; <span class="keyword">do</span> sleep 1; <span class="keyword">if</span> dig myservice; <span class="keyword">then</span> <span class="built_in">exit</span> 0; <span class="keyword">fi</span>; <span class="keyword">done</span>; <span class="built_in">exit</span> 1</span><br></pre></td></tr></table></figure></div>
<ul>
<li>通过downward API把当前pod注册到远程服务器,命令如下:</li>
</ul>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="PLAIN"><figure class="iseeu highlight /plain"><table><tr><td class="code"><pre><span class="line">curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'</span><br></pre></td></tr></table></figure></div>
<ul>
<li>在容器启动之前等待一定时间:例如sleep 60</li>
<li>克隆一个git仓库到存储目录</li>
<li>通过模板工具动态把一些值写入到主应用程序的配置文件里</li>
</ul>
<h2 id="初始容器使用"><a href="#初始容器使用" class="headerlink" title="初始容器使用"></a>初始容器使用</h2><div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="YAML"><figure class="iseeu highlight /yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">myapp-pod</span></span><br><span class="line"> <span class="attr">labels:</span></span><br><span class="line"> <span class="attr">app:</span> <span class="string">myapp</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line"> <span class="attr">containers:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">myapp-container</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">busybox</span></span><br><span class="line"> <span class="attr">command:</span> <span class="string">['sh',</span> <span class="string">'-c'</span><span class="string">,</span> <span class="string">'echo The app is running! && sleep 3600'</span><span class="string">]</span></span><br><span class="line"> <span class="attr">initContainers:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">init-myservice</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">busybox</span></span><br><span class="line"> <span class="attr">command:</span> <span class="string">['sh',</span> <span class="string">'-c'</span><span class="string">,</span> <span class="string">'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'</span><span class="string">]</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">init-mydb</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">busybox</span></span><br><span class="line"> <span class="attr">command:</span> <span class="string">['sh',</span> <span class="string">'-c'</span><span class="string">,</span> <span class="string">'until nslookup mydb; do echo waiting for mydb; sleep 2; done;'</span><span class="string">]</span></span><br></pre></td></tr></table></figure></div>
<p>以上pod定义包含两个初始容器,第一个等待myservice服务可用,第二个等待mydb服务可用,这两个pod执行完成,应用容器开始执行.</p>
<p>下面是myservice和mydb两个服务的yaml文件</p>
<div class="highlight-wrap"autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" contenteditable="true"data-rel="YAML"><figure class="iseeu highlight /yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">kind:</span> <span class="string">Service</span></span><br><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">myservice</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">protocol:</span> <span class="string">TCP</span></span><br><span class="line"> <span class="attr">port:</span> <span class="number">80</span></span><br><span class="line"> <span class="attr">targetPort:</span> <span class="number">9376</span></span><br><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Service</span></span><br><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">mydb</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">protocol:</span> <span class="string">TCP</span></span><br><span class="line"> <span class="attr">port:</span> <span class="number">80</span></span><br><span class="line"> <span class="attr">targetPort:</span> <span class="number">9377</span></span><br></pre></td></tr></table></figure></div>
<h2 id="行为细节"><a href="#行为细节" class="headerlink" title="行为细节"></a>行为细节</h2><ul>
<li>在启动pod的过程中,在存储卷和网络创建以后,初始容器依次创建.上一个容器必须返回成功下一个才能启动,如果由于运行时错误或者其它异常退出,它会依照restartPolicy来重试,然而,如果restartPolicy设置为Always,初始容器实际上使用的是OnFailure策略</li>
<li>如果pod重启了,则所有的初始容器要重新执行</li>
<li>对初始容器的spec的更改仅限于镜像(image)字段的修改,更改了初始容器的镜像字段相当于重启pod</li>
<li>由于初始容器可以被重启,重试和重新执行,因此它里面的代码应当是幂等的,尤其是写入文件到EmptyDirs的代码应当注意文件可能已经存在</li>
<li>容器中的所有初始容器和普通容器名称必须惟一.</li>
</ul>
<h2 id="资源"><a href="#资源" class="headerlink" title="资源"></a><strong>资源</strong></h2><p>基于初始容器的执行顺序,以下关于资源的规则适用:</p>
<ul>
<li><p>对于特定资源,所有初始容器申请的最高的生效</p>
</li>
<li><p>对于pod,相同资源申请取以下两者较高的一个:</p>
</li>
<li><ol>
<li>所有普通应用容器申请的资源总和</li>
<li>初始容器申请的生效的资源(上面说到,初始容器申请资源取所有初始容器申请最大的一个)</li>
</ol>
</li>
<li><p>调度基于生效的初始请求,这就意味着初始容器可以申请预留资源,即便在pod以后的整个生命周期都用不到</p>
</li>
</ul>
<h2 id="pod重启原因"><a href="#pod重启原因" class="headerlink" title="pod重启原因"></a><strong>pod重启原因</strong></h2><p>一个pod基于以下列出的原因,会重启,重新执行初始容器:</p>
<ul>
<li>用户更新初始容器的PodSpec导致镜像发生改变.普通应用容器改变只会使应用容器重启</li>
<li>由于restartPolicy被设置为Always,导致所有容器均被中止,强制重启,由于垃圾回收初始容器的初始状态记录丢失</li>
</ul>
]]></content>
<tags>
<tag>kubernetes</tag>
</tags>
</entry>
</search>