k8s(十二)、分散式儲存Ceph RBD使用
前言
Ceph儲存有三種儲存介面,分別是:
物件儲存 Ceph Object Gateway
塊裝置 RBD
檔案系統 CEPHFS
Kubernetes支援後兩種儲存介面,支援的接入模式如下圖:
在本篇將測試使用ceph rbd作持久化儲存後端
RBD建立測試
rbd的使用分為3個步驟:
1.服務端/客戶端建立塊裝置image
2.客戶端將image對映進linux系統核心,核心識別出該塊裝置後生成dev下的檔案標識
3.格式化塊裝置並掛載使用
# 建立
[[email protected] ~]# rbd create --size 10240000 rbd/test1 #建立指定大小的node
[ [email protected] ~]# rbd info test1
rbd image 'test1':
size 10000 GB in 2560000 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.31e3b6b8b4567
format: 2
features: layering, exclusive-lock,object-map, fast-diff, deep-flatten
flags:
#對映進核心操作之前,首先檢視核心版本,jw版本的ceph預設format為2,預設開啟5種特性,2.x及之前的核心版本需手動調整format為1
,4.x之前要關閉object-map, fast-diff, deep-flatten功能才能成功對映到核心,這裡使用的是centos7.4,核心版本3.10
[ [email protected] ~]# rbd feature disable test1 object-map fast-diff deep-flatten
# 對映進核心
[[email protected] ~]# rbd map test1
[[email protected] ~]# ls /dev/rbd0
/dev/rbd0
#掛載使用
[[email protected] ~]# mkdir /mnt/cephrbd
[[email protected] ~]# mkfs.ext4 -m0 /dev/rbd0
[[email protected] ~]# mount /dev/rbd0 /mnt/cephrbd/
Kubernetes Dynamic Pv 使用
首先回顧一下上篇cephfs在k8s中的使用方式:
繫結使用流程: pv指定儲存型別和介面,pvc繫結pv,pod掛載指定pvc.這種一一對應的方式,即為靜態pv
例如cephfs的使用流程:
那麼什麼是動態pv呢?
在現有PV不滿足PVC的請求時,可以使用儲存分類(StorageClass),pvc對接sc後,k8s會動態地建立pv,並且向相應的儲存後端發出資源申請.
描述具體過程為:首先建立sc分類,PVC請求已建立的sc的資源,來自動建立pv,這樣就達到動態配置的效果。即通過一個叫 Storage Class的物件由儲存系統根據PVC的要求自動建立pv並使用儲存資源
Kubernetes的pv支援rbd,從第一部分測試使用rbd的過程可以看出,儲存實際使用的單位是image,首先必須在ceph端建立image,才能建立pv/pvc,再在pod裡面掛載使用.這是一個標準的靜態pv的繫結使用流程.但是這樣的流程就帶來了一個弊端,即一個完整的儲存資源掛載使用的操作被分割成了兩段,一段在ceph端劃分rbd image,一段由k8s端繫結pv,這樣使得管理的複雜性提高,不利於自動化運維.
因此,動態pv是一個很好的選擇,ceph rbd介面的動態pv的實現流程是這樣的:
根據pvc及sc的宣告,自動生成pv,且向sc指定的ceph後端發出申請自動建立相應大小的rbd image,最終繫結使用
工作流程圖:
下面開始演示
1.建立secret
key獲取方式參考上篇文章
~/mytest/ceph/rbd# cat ceph-secret-rbd.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret-rbd
type: "kubernetes.io/rbd"
data:
key: QVFCL3E1ZGIvWFdxS1JBQTUyV0ZCUkxldnRjQzNidTFHZXlVYnc9PQ==
2.建立sc
~/mytest/ceph/rbd# cat ceph-secret-rbd.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: cephrbd-test2
provisioner: kubernetes.io/rbd
reclaimPolicy: Retain
parameters:
monitors: 192.168.20.112:6789,192.168.20.113:6789,192.168.20.114:6789
adminId: admin
adminSecretName: ceph-secret-rbd
pool: rbd
userId: admin
userSecretName: ceph-secret-rbd
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
建立pvc
~/mytest/ceph/rbd# cat cephrbd-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cephrbd-pvc2
spec:
storageClassName: cephrbd-test2
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
建立deploy,容器掛載使用建立的pvc
:~/mytest/ceph/rbd# cat deptest13dbdm.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: deptest13dbdm
name: deptest13dbdm
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: deptest13dbdm
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: deptest13dbdm
spec:
containers:
image: registry.xxx.com:5000/mysql:56v6
imagePullPolicy: Always
name: deptest13dbdm
ports:
- containerPort: 3306
protocol: TCP
resources:
limits:
memory: 16Gi
requests:
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/mysql
name: datadir
subPath: deptest13dbdm
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: datadir
persistentVolumeClaim:
claimName: cephrbd-pvc2
這裡會遇到一個大坑:
~# kubectl describe pvc cephrbd-pvc2
...
Error creating rbd image: executable file not found in $PATH
這是因為kube-controller-manager需要呼叫rbd客戶端api來建立rbd image,叢集的每個節點都已經安裝ceph-common,但是叢集是使用kubeadm部署的,kube-controller-manager元件是以容器方式工作的,內部不包含rbd的執行檔案,後面在這個issue裡,找到了解決的辦法:
Github issue
使用外部的rbd-provisioner,提供給kube-controller-manager以rbd的執行入口,注意,issue內的demo指定的image版本有bug,不能指定rbd掛載後使用的檔案系統格式,需要使用最新的版本demo,專案地址:rbd-provisioner
完整demo yaml檔案:
[email protected]:~/mytest/ceph/rbd/rbd-provisioner# cat rbd-provisioner.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-provisioner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
- apiGroups: [""]
resources: ["services"]
resourceNames: ["kube-dns","coredns"]
verbs: ["list", "get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-provisioner
subjects:
- kind: ServiceAccount
name: rbd-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: rbd-provisioner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: rbd-provisioner
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rbd-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: rbd-provisioner
subjects:
- kind: ServiceAccount
name: rbd-provisioner
namespace: default
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: rbd-provisioner
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: rbd-provisioner
spec:
containers:
- name: rbd-provisioner
image: quay.io/external_storage/rbd-provisioner:latest
env:
- name: PROVISIONER_NAME
value: ceph.com/rbd
serviceAccount: rbd-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rbd-provisioner
部署完成後,重新建立上方的sc/pv,這個時候,pod就正常執行起來了,檢視pvc,可以看到此pvc觸發自動生成了一個pv且綁定了此pv,pv繫結的StorageClass則是剛建立的sc:
# pod
~/mytest/ceph/rbd/rbd-provisioner# kubectl get pods | grep deptest13
deptest13dbdm-c9d5bfb7c-rzzv6 2/2 Running 0 6h
# pvc
~/mytest/ceph/rbd/rbd-provisioner# kubectl get pvc cephrbd-pvc2
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
cephrbd-pvc2 Bound pvc-d976c2bf-c2fb-11e8-878f-141877468256 20Gi RWO cephrbd-test2 23h
# 自動建立的pv
~/mytest/ceph/rbd/rbd-provisioner# kubectl get pv pvc-d976c2bf-c2fb-11e8-878f-141877468256
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-d976c2bf-c2fb-11e8-878f-141877468256 20Gi RWO Retain Bound default/cephrbd-pvc2 cephrbd-test2 23h
# sc
~/mytest/ceph/rbd/rbd-provisioner# kubectl get sc cephrbd-test2
NAME PROVISIONER AGE
cephrbd-test2 ceph.com/rbd 23h
再回到ceph節點上看看是否自動建立了rbd image
~# rbd ls
kubernetes-dynamic-pvc-d988cfb1-c2fb-11e8-b2df-0a58ac1a084e
test1
~# rbd info kubernetes-dynamic-pvc-d988cfb1-c2fb-11e8-b2df-0a58ac1a084e
rbd image 'kubernetes-dynamic-pvc-d988cfb1-c2fb-11e8-b2df-0a58ac1a084e':
size 20480 MB in 5120 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.47d0b6b8b4567
format: 2
features: layering
flags:
可以發現,動態建立pv/rbd成功
掛載測試
回顧最上方的kubernetes支援的接入模式截圖,rbd是不支援ReadWriteMany的,而k8s的理念是像牲口一樣管理你的容器,容器節點有可能隨時橫向擴充套件,橫向縮減,在節點間漂移,因此,不支援多點掛載的RBD模式,顯然不適合做多應用節點之間的共享檔案儲存,這裡進行一次進一步的驗證
多點掛載測試
建立一個新的deploy,並掛載同一個pvc:
[email protected]:~/mytest/ceph/rbd# cat deptest14dbdm.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "4"
creationTimestamp: 2018-09-26T07:32:41Z
generation: 4
labels:
app: deptest14dbdm
domain: dev.deptest14dbm.kokoerp.com
nginx_server: ""
name: deptest14dbdm
namespace: default
resourceVersion: "26647927"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/deptest14dbdm
uid: 5a1a62fe-c15e-11e8-878f-141877468256
spec:
replicas: 1
selector:
matchLabels:
app: deptest14dbdm
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: deptest14dbdm
domain: dev.deptest14dbm.kokoerp.com
nginx_server: ""
spec:
containers:
- env:
- name: DB_NAME
value: deptest14dbdm
image: registry.youkeshu.com:5000/mysql:56v6
imagePullPolicy: Always
name: deptest14dbdm
ports:
- containerPort: 3306
protocol: TCP
resources:
limits:
memory: 16Gi
requests:
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/mysql
name: datadir
subPath: deptest14dbdm
- env:
- name: DATA_SOURCE_NAME
value: exporter:[email protected](127.0.0.1:3306)/
image: registry.youkeshu.com:5000/mysqld-exporter:v0.10
imagePullPolicy: Always
name: mysql-exporter
ports:
- containerPort: 9104
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
nodeSelector:
192.168.20.109: ""
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: datadir
persistentVolumeClaim:
claimName: cephrbd-pvc2
使用nodeselector將此deptest13和deptest14限制在同一個node中:
[email protected]:~/mytest/ceph/rbd# kubectl get pods -o wide | grep deptest1[3-4]
deptest13dbdm-c9d5bfb7c-rzzv6 2/2 Running 0 6h 172.26.8.82 h020109
deptest14dbdm-78b8bb7995-q84dk 2/2 Running 0 2m 172.26.8.84 h020109
不難發現在同一個節點中,是可以支援多個pod共享rbd image執行的,在容器的工作節點上檢視mount條目也可以證實這一點:
192.168.20.109:~# mount | grep rbd
/dev/rbd0 on /var/lib/kubelet/plugins/kubernetes.io/rbd/rbd/rbd-image-kubernetes-dynamic-pvc-d988cfb1-c2fb-11e8-b2df-0a58ac1a084e type ext4 (rw,relatime,stripe=1024,data=ordered)
/dev/rbd0 on /var/lib/kubelet/pods/68b8e3c5-c38d-11e8-878f-141877468256/volumes/kubernetes.io~rbd/pvc-d976c2bf-c2fb-11e8-878f-141877468256 type ext4 (rw,relatime,stripe=1024,data=ordered)
/dev/rbd0 on /var/lib/kubelet/pods/1e9b04b1-c3c3-11e8-878f-141877468256/volumes/kubernetes.io~rbd/pvc-d976c2bf-c2fb-11e8-878f-141877468256 type ext4 (rw,relatime,stripe=1024,data=ordered)
修改新deploy的nodeselector指向其他的node:
~/mytest/ceph/rbd# kubectl get pods -o wide| grep deptest14db
deptest14dbdm-78b8bb7995-q84dk 0/2 Terminating 0 7m 172.26.8.84 h020109
deptest14dbdm-79fd495579-rkl92 0/2 ContainerCreating 0 49s <none> h009028
# kubectl describe pod deptest14dbdm-79fd495579-rkl92
...
Warning FailedAttachVolume 1m attachdetach-controller Multi-Attach error for volume "pvc-d976c2bf-c2fb-11e8-878f-141877468256" Volume is already exclusively attached to one node and can't be attached to another
pod將阻塞在ContainerCreating狀態,描述報錯很清晰地指出控制器不支援多點掛載此pv.
進行下一步測試前先刪除此臨時新增的deploy
滾動更新測試
在deptest13dbdm的deploy檔案中指定的更新方式為滾動更新:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
這裡我們嘗試一下,將正在執行的pod,從一個節點排程到另一個節點,rbd 是否能遷移到新的節點上掛載:
# 修改nodeselector
[email protected]:~/mytest/ceph/rbd# kubectl edit deploy deptest13dbdm
deployment "deptest13dbdm" edited
# 觀察pod排程遷移過程
[email protected]:~/mytest/ceph/rbd# kubectl get pods -o wide| grep deptest13
deptest13dbdm-6999f5757c-fk9dp 0/2 ContainerCreating 0 4s <none> h009028
deptest13dbdm-c9d5bfb7c-rzzv6 2/2 Terminating 0 6h 172.26.8.82 h020109
[email protected]:~/mytest/ceph/rbd# kubectl describe pod deptest13dbdm-6999f5757c-fk9dp
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m default-scheduler Successfully assigned deptest13dbdm-6999f5757c-fk9dp to h009028
Normal SuccessfulMountVolume 2m kubelet, h009028 MountVolume.SetUp succeeded for volume "default-token-7q8pq"
Warning FailedMount 45s kubelet, h009028 Unable to mount volumes for pod "deptest13dbdm-6999f5757c-fk9dp_default(28e9cdd6-c3c5-11e8-878f-141877468256)": timeout expired waiting for volumes to attach/mount for pod "default"/"deptest13dbdm-6999f5757c-fk9dp". list of unattached/unmounted volumes=[datadir]
Normal SuccessfulMountVolume 35s (x2 over 36s) kubelet, h009028 MountVolume.SetUp succeeded for volume "pvc-d976c2bf-c2fb-11e8-878f-141877468256"
Normal Pulling 27s kubelet, h009028 pulling image "registry.youkeshu.com:5000/mysql:56v6"
Normal Pulled 27s kubelet, h009028 Successfully pulled image "registry.youkeshu.com:5000/mysql:56v6"
Normal Pulling 27s kubelet, h009028 pulling image "registry.youkeshu.com:5000/mysqld-exporter:v0.10"
Normal Pulled 26s kubelet, h009028 Successfully pulled image "registry.youkeshu.com:5000/mysqld-exporter:v0.10"
Normal Created 26s kubelet, h009028 Created container
Normal Started 26s kubelet, h009028 Started container
[email protected]:~/mytest/ceph/rbd# kubectl get pods -o wide| grep deptest13
deptest13dbdm-6999f5757c-fk9dp 2/2 Running 0 3m 172.26.0.87 h009028
#在原node上檢視核心中對映的rbd image塊裝置描述檔案已消失,掛載已取消
[email protected]:~/tpcc-mysql# ls /dev/rbd*
ls: cannot access '/dev/rbd*': No such file or directory
[email protected]:~/tpcc-mysql# mount | grep rbd
[email protected]:~/tpcc-mysql#
可以看出,是可以自動完成在節點間遷移的滾動更新的,整個排程的過程有些漫長,接近3分鐘,這是因為其中至少涉及如下幾個步驟:
1.原pod終結,釋放資源
2.原node取消掛載rbd,釋放核心對映
3.新node核心對映rbd image,掛載rbd到檔案目錄
4.建立pod,掛載指定目錄
結論:
ceph rbd不支援多節點掛載,支援滾動更新.
後續
在完成了使用cephfs和ceph rbd這兩種k8s分散式儲存的對接方式測試之後,下一篇文章將針對這兩種方式進行資料庫效能測試及適用場景討論
相關推薦
k8s(十二)、分散式儲存Ceph RBD使用
前言 Ceph儲存有三種儲存介面,分別是: 物件儲存 Ceph Object Gateway 塊裝置 RBD 檔案系統 CEPHFS Kubernetes支援後兩種儲存介面,支援的接入模式如下圖: 在本篇將測試使用ceph rbd作持久化儲存後端 RBD建立
k8s(十一)、分散式儲存Cephfs使用
前言 在前篇部署測試完cephfs的基礎上: Ceph叢集生產環境安裝部署 cephfs調優 & 效能測試 & 常用命令 本篇介紹k8s使用 pv/pvc的方式使用cephfs分散式檔案系統 使用 首先解釋一下pv/pvc的相關概
第十二、十三周作業【Linux微職位】
馬哥教育一、結合圖形描述LVS的工作原理;lvs-nat模型主要是修改目標IP地址為挑選出新的RS的IP地址。即請求進入負載均衡器時做DNAT,響應出負載均衡器時做SNAT。1.當用戶請求到達Director Server,此時請求的數據報文會先到達內核的PREROUTING鏈,此時報文的源IP是CIP,目標
十二、十三天總結筆記
異常、io、file一:File 1.1 File:文件和目錄(文件夾)路徑名的抽象表示形式。 1.2 File的構造方法: File(String pathname):把一個路徑名稱封裝成File對象 File(String p
十二、samba服務器配置和管理
samba、文件共享12.1、Samba簡介 Linux和Windows是兩種無論在風格還是在技術上都完全不同的操作系統,它們是兩個對立的陣形。各自都擁有自己的用戶群和市場。但是,要實現這兩種系統之間的資源共享,則需要使用Samba。Samba采用的是C/S工作模式,通過它可以將一臺Linux系統主機配置為
二十二、英文字母和數字不會換行如何處理
英文 一次 bre word-wrap style 英文字母 ron wrap -a 一次偶然的項目中,遇到一個奇怪的問題,為什麽我都寫了換行的css怎麽還是沒有換行?請教宋老師之後才知道“英文字母和數字是不會換行的”,那如何處理呢? 處理辦法,在所在類上增加下面css:
十二、MySQL用戶管理
mysql用戶管理 MySQL是一個多用戶數據庫,具有功能強大的訪問控制系統,可以為不同用戶指定允許的權限。MySQL用戶可以分為普通用戶和root用戶。root用戶是超級管理員,擁有所有權限,普通用戶只擁有被授予的各種權限。12.1、權限表MySQL服務器通過權限來控制用戶對數據庫的訪問,權限表存放在MyS
十二、代理模式
ring style ret 代理類 out 一個 dem public cnblogs 代理模式其實很簡單,就是把具體實現從一個功能類裏面分離,又通過引用的方式把具體實現和功能類關聯,代碼如下: package test; /** * 代理模式 * @author
十二、匿名函數和閉包
lee 內存問題 基於 傳參 不能 更多 垃圾 資源 增強 十二、匿名函數和閉包 匿名函數就是沒有名字的函數,閉包是可訪問一個函數作用域裏變量的函數。聲明:本節內容需要有面向對象和少量設計模式基礎,否則無法聽懂. 1.匿名函數 //普通函數 function b
二十二、事件綁定及深入
dom節點 bili rec tex lin 問題: type onload fin 二十二、事件綁定及深入 事件綁定分為兩種:一種是傳統事件綁定(內聯模型,腳本模型),一種是現代事件綁定(DOM2級模型)。現代事件綁定在傳統綁定上提供了更強大更方便的功能。 1.傳
十二、事件,委托,泛型委托,集合(泛型和非泛型),Lambda表達式(聲明委托,使用委托,簡單的委托示例,action<T>和func<t>委托,多播委托,匿名方法,Lambda表達式,參數,事件)
multicast new 調用方法 多播 ted 被調用 輸入參數 pac cas 事件(Event) 事件是一種對象或類能夠提供通知的成員,客戶端可以通過提供事件處理程序為相應的事件可添加可執行代碼,事件可以理解為一種特殊的委托。 委托(Delegate) 委托是存有對
十二、Hadoop學習筆記————Hive的基本原理
中介 優化 prop 指示 使用 計劃分解 分享 ges 歷史數據 一般用戶用CLI(命令行界面)接口,元數據庫含有表結構 單用戶、多用戶、遠程服務 生成db文件,只能單客戶端使用數據庫 多用戶是最常用的使用模式 配置與多用戶一致 數據格式用戶自定義
二十二、configparser
def ebo efault item for ive import port gpa configparser 用於讀寫文件,但是必須是下面的格式 將這種文件當字典處理: {key:{key1=value}} [DEFAULT] ServerAliv
十二、根搜索算法
mar 如果 運行時常量 log 連接 java 不可 靜態 body 根搜索算法是以根對象集合作為起始點,按照從上至下的方式搜索被根對象集合所連接的目標對象是否可達,如果不可達就意味著已經死亡其OOP中的mark word就會標記為垃圾對象。 根對象集合中存儲的內容如下:
十二、索引
根據 圖片 drop 一個 inf 調整 分享圖片 技術 nbsp 1.定義 索引對應的英文單詞是:index 索引的作用:相當於一本字典目錄,提高程序的檢索/查詢效率;表中每一個字段都可添加索引。 註:主鍵會自動添加索引,能夠通過主鍵查詢的盡量通過主鍵查詢,效率較高
十二、usermod命令、用戶密碼管理、mkpasswd命令
有時 小寫 其他 文件 電話 mod 沒有 happy -- 十二、usermod命令、用戶密碼管理、mkpasswd命令一、usermod命令usermod:更改用戶屬性。格式:usermod -u 111 username;usermod -g 123 username
十二、三大核心特征-多態
div clas abs 派生 pan ima strac function fun 多態指的是面向對象編程時,屏蔽了子類對象之間的差異,可以使調用對象方法的客戶端代碼中代碼保持通用性,而不必針對每個不同的對象寫不同的實現。 多態的實現依靠的是繼承、抽象方法或接口的特性。
十二、雙向鏈表的java實現
rst nod inf ole tmp 插入 頭結點 oid ava 原理圖: 運行結果: Node代碼: public class Node { int data; Node next; Node previous;
三十二、iptables filter表小案例、iptables nat表應用
iptables小案例 iptables應用 三十二、iptables filter表小案例、iptables nat表應用一、iptables filter表小案例需求:只針對filter表,預設策略INPUT鏈DROP,其他兩個鏈ACCEPT,然後針對192.168.188.0/24開通22端口,