一 前期准备

1.1 基础知识

Heketi提供了一个RESTful管理界面,可以用来管理GlusterFS卷的生命周期。Heketi会动态在集群内选择bricks构建所需的volumes,从而确保数据的副本会分散到集群不同的故障域内。同时Heketi还支持任意数量的ClusterFS集群。
提示:本实验基于glusterfs和Kubernetes分开部署,heketi管理glusterfs,Kubernetes使用heketi提供的API,从而实现glusterfs的永久存储,,而非Kubernetes部署glusterfs。

1.2 架构示意


提示:本实验Heketi仅管理单zone的glusterfs集群。

1.3 相关规划




主机

IP

磁盘

备注
servera
172.24.8.41
sdb
glusterfs节点
serverb
172.24.8.42
sdb
glusterfs节点
serverc
172.24.8.43
sdb
glusterfs节点
heketi
172.24.8.44
Heketi主机





servera

serverb

serverc
PV
sdb1
sdb1
sdb1
VG
vg0
vg0
vg0
LV
datalv
datalv
datalv
bricks目录
/bricks/data
/bricks/data
/bricks/data

1.4 其他准备

所有节点NTP配置;
所有节点添加相应主机名解析:
172.24.8.41 servera
172.24.8.42 serverb
172.24.8.43 serverc
172.24.8.44 heketi
注意:若非必要,建议关闭防火墙和SELinux。

二 规划相应存储卷

2.1 划分LVM

  1 [root@servera ~]# fdisk /dev/sdb				#创建lvm的sdb1,过程略
2 [root@servera ~]# pvcreate /dev/sdb1 #使用/dev/vdb1创建PV
3 [root@servera ~]# vgcreate vg0 /dev/sdb1 #创建vg
4 [root@servera ~]# lvcreate -L 15G -T vg0/thinpool #创建支持thin的lv池
5 [root@servera ~]# lvcreate -V 10G -T vg0/thinpool -n datalv #创建相应brick的lv
6 [root@servera ~]# vgdisplay #验证确认vg信息
7 [root@servera ~]# pvdisplay #验证确认pv信息
8 [root@servera ~]# lvdisplay #验证确认lv信息
提示:serverb、serverc类似操作,根据规划需求创建完所有基于LVM的brick。

三 安装glusterfs

3.1 安装相应RPM源

  1 [root@servera ~]# yum -y install centos-release-gluster
提示:serverb、serverc、client类似操作,安装相应glusterfs源;


安装相应源之后,会在/etc/yum.repos.d/目录多出文件CentOS-Storage-common.repo,内容如下:
  1 # CentOS-Storage.repo
2 #
3 # Please see http://wiki.centos.org/SpecialInterestGroup/Storage for more
4 # information
5
6 [centos-storage-debuginfo]
7 name=CentOS-$releasever - Storage SIG - debuginfo
8 baseurl=http://debuginfo.centos.org/$contentdir/$releasever/storage/$basearch/
9 gpgcheck=1
10 enabled=0
11 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage

3.2 安装glusterfs

  1 [root@servera ~]# yum -y install glusterfs-server
提示:serverb、serverc类似操作,安装glusterfs服务端。

3.3 启动glusterfs

  1 [root@servera ~]# systemctl start glusterd
2 [root@servera ~]# systemctl enable glusterd
提示:serverb、serverc类似操作,所有节点启动glusterfs服务端;


安装完glusterfs之后建议exit退出终端重新登录,从而可以补全glusterfs相关命令。

3.4 添加信任池

  1 [root@servera ~]# gluster peer probe serverb
2 peer probe: success.
3 [root@servera ~]# gluster peer probe serverc
4 peer probe: success.
5 [root@servera ~]# gluster peer status #查看信任池状态
6 [root@servera ~]# gluster pool list #查看信任池列表
提示:加信任池的操作,只需要在servera、serverb、serverc所有集群节点主机中的任意一台上面执行添加其他三个节点的操作即可。


提示:若未关闭防火墙,在添加信任池之前必须放通防火墙相应规则,操作如下:
  1 [root@servera ~]# firewall­cmd ­­permanent ­­add­service=glusterfs
2 [root@servera ~]# firewall­cmd ­­permanent ­­add­service=nfs
3 [root@servera ~]# firewall­cmd ­­permanent ­­add­service=rpc­bind
4 [root@servera ~]# firewall­cmd ­­permanent ­­add­service=mountd
5 [root@servera ~]# firewall­cmd ­­permanent ­­add­port=5666/tcp
6 [root@servera ~]# firewall­cmd ­­reload

四 部署Heketi

4.1 安装heketi服务

  1 [root@heketi ~]# yum -y install centos-release-gluster
2 [root@heketi ~]# yum -y install heketi heketi-client

4.2 配置heketi

  1 [root@heketi ~]# vi /etc/heketi/heketi.json
2 {
3 "_port_comment": "Heketi Server Port Number",
4 "port": "8080", #默认端口
5
6 "_use_auth": "Enable JWT authorization. Please enable for deployment",
7 "use_auth": true, #基于安全考虑开启认证
8
9 "_jwt": "Private keys for access",
10 "jwt": {
11 "_admin": "Admin has access to all APIs",
12 "admin": {
13 "key": "admin123" #管理员密码
14 },
15 "_user": "User only has access to /volumes endpoint",
16 "user": {
17 "key": "xianghy" #普通用户
18 }
19 },
20
21 "_glusterfs_comment": "GlusterFS Configuration",
22 "glusterfs": {
23 "_executor_comment": [
24 "Execute plugin. Possible choices: mock, ssh",
25 "mock: This setting is used for testing and development.", #用于测试
26 " It will not send commands to any node.",
27 "ssh: This setting will notify Heketi to ssh to the nodes.", #ssh方式
28 " It will need the values in sshexec to be configured.",
29 "kubernetes: Communicate with GlusterFS containers over", #在GlusterFS由kubernetes创建时采用
30 " Kubernetes exec api."
31 ],
32 "executor": "ssh",
33
34 "_sshexec_comment": "SSH username and private key file information",
35 "sshexec": {
36 "keyfile": "/etc/heketi/heketi_key",
37 "user": "root",
38 "port": "22",
39 "fstab": "/etc/fstab"
40 },
41 ……
42 ……
43 "loglevel" : "warning"
44 }
45 }

4.3 配置免秘钥

  1 [root@heketi ~]# ssh-keygen -t rsa -q -f /etc/heketi/heketi_key -N ""
2 [root@heketi ~]# chown heketi:heketi /etc/heketi/heketi_key
3 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@servera
4 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@serverb
5 [root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@serverc

4.4 启动heketi

  1 [root@heketi ~]# systemctl enable heketi.service
2 [root@heketi ~]# systemctl start heketi.service
3 [root@heketi ~]# systemctl status heketi.service
4 [root@heketi ~]# curl http://localhost:8080/hello #测试访问
5 Hello from Heketi

4.5 配置Heketi拓扑

       拓扑信息用于让Heketi确认可以使用的存储节点、磁盘和集群,必须自行确定节点的故障域。故障域是赋予一组节点的整数值,这组节点共享相同的交换机、电源或其他任何会导致它们同时失效的组件。必须确认哪些节点构成一个集群,Heketi使用这些信息来确保跨故障域中创建副本,从而提供数据冗余能力,Heketi支持多个Gluster存储集群。
配置Heketi拓扑注意以下几点:
  • 可以通过topology.json文件定义组建的GlusterFS集群;
  • topology指定了层级关系:clusters --> nodes --> node/devices --> hostnames/zone;
  • node/hostnames字段的manage建议填写主机ip,指管理通道,注意当heketi服务器不能通过hostname访问GlusterFS节点时不能填写hostname;
  • node/hostnames字段的storage建议填写主机ip,指存储数据通道,与manage可以不一样,生产环境管理网络和存储网络建议分离;
  • node/zone字段指定了node所处的故障域,heketi通过跨故障域创建副本,提高数据高可用性质,如可以通过rack的不同区分zone值,创建跨机架的故障域;
  • devices字段指定GlusterFS各节点的盘符(可以是多块盘),必须是未创建文件系统的裸设备。
  1 [root@heketi ~]# vi /etc/heketi/topology.json
2 {
3 "clusters": [
4 {
5 "nodes": [
6 {
7 "node": {
8 "hostnames": {
9 "manage": [
10 "172.24.8.41"
11 ],
12 "storage": [
13 "172.24.8.41"
14 ]
15 },
16 "zone": 1
17 },
18 "devices": [
19 "/dev/mapper/vg0-datalv"
20 ]
21 },
22 {
23 "node": {
24 "hostnames": {
25 "manage": [
26 "172.24.8.42"
27 ],
28 "storage": [
29 "172.24.8.42"
30 ]
31 },
32 "zone": 1
33 },
34 "devices": [
35 "/dev/mapper/vg0-datalv"
36 ]
37 },
38 {
39 "node": {
40 "hostnames": {
41 "manage": [
42 "172.24.8.43"
43 ],
44 "storage": [
45 "172.24.8.43"
46 ]
47 },
48 "zone": 1
49 },
50 "devices": [
51 "/dev/mapper/vg0-datalv"
52 ]
53 }
54 ]
55 }
56 ]
57 }
58
59 [root@heketi ~]# echo "export HEKETI_CLI_SERVER=http://heketi:8080" >> /etc/profile.d/heketi.sh
60 [root@heketi ~]# echo "alias heketi-cli='heketi-cli --user admin --secret admin123'" >> .bashrc
61 [root@heketi ~]# source /etc/profile.d/heketi.sh
62 [root@heketi ~]# source .bashrc
63 [root@heketi ~]# echo $HEKETI_CLI_SERVER
64 http://heketi:8080
65 [root@heketi ~]# heketi-cli --server $HEKETI_CLI_SERVER --user admin --secret admin123 topology load --json=/etc/heketi/topology.json

4.6 集群管理

  1 [root@heketi ~]# heketi-cli cluster list					#集群列表
2 [root@heketi ~]# heketi-cli cluster info aa83b0045fafa362bfc7a8bfee0c24ad #集群详细信息
3 Cluster id: aa83b0045fafa362bfc7a8bfee0c24ad
4 Nodes:
5 189ee41572ebf0bf1e297de2302cfb39
6 46429de5666fc4c6cc570da4b100465d
7 be0209387384299db34aaf8377c3964c
8 Volumes:
9
10 Block: true
11
12 File: true
13 [root@heketi ~]# heketi-cli topology info aa83b0045fafa362bfc7a8bfee0c24ad #查看拓扑信息
  1 [root@heketi ~]# heketi-cli node list						#卷信息
2 Id:189ee41572ebf0bf1e297de2302cfb39 Cluster:aa83b0045fafa362bfc7a8bfee0c24ad
3 Id:46429de5666fc4c6cc570da4b100465d Cluster:aa83b0045fafa362bfc7a8bfee0c24ad
4 Id:be0209387384299db34aaf8377c3964c Cluster:aa83b0045fafa362bfc7a8bfee0c24ad
5 [root@heketi ~]# heketi-cli node info 189ee41572ebf0bf1e297de2302cfb39 #节点信息
6 [root@heketi ~]# heketi-cli volume create --size=2 --replica=2 #默认为3副本的replica模式
  1 [root@heketi ~]# heketi-cli volume list						#卷信息
2 [root@heketi ~]# heketi-cli volume info 7da55685ebeeaaca60708cd797a5e391
3 [root@servera ~]# gluster volume info #通过glusterfs节点查看

4.7 测试验证

  1 [root@heketi ~]# yum -y install centos-release-gluster
2 [root@heketi ~]# yum -y install glusterfs-fuse #安装glusterfs-fuse
3 [root@heketi ~]# mount -t glusterfs 172.24.8.41:vol_7da55685ebeeaaca60708cd797a5e391 /mnt
  1 [root@heketi ~]# umount /mnt
2 [root@heketi ~]# heketi-cli volume delete 7da55685ebeeaaca60708cd797a5e391 #验证完毕删除
参考:https://www.jianshu.com/p/1069ddaaea78
https://www.cnblogs.com/panwenbin-logs/p/10231859.html

五 Kubernetes动态挂载glusterfs

5.1 StorageClass动态存储

kubernetes共享存储provider模式:
静态模式(Static):集群管理员手工创建PV,在定义PV时设置后端存储的特性;
动态模式(Dynamic):集群管理员不需要手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种"类型(Class)";此时要求PVC对存储的类型进行说明,系统将自动完成PV的创建及与PVC的绑定;PVC可以声明Class为"",说明PVC禁止使用动态模式。
基于StorageClass的动态存储供应整体过程如下图所示:
  1. 集群管理员预先创建存储类(StorageClass);
  2. 用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);
  3. 存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);
  4. 系统读取存储类的信息;
  5. 系统基于存储类的信息,在后台自动创建PVC需要的PV;
  6. 用户创建一个使用PVC的Pod;
  7. Pod中的应用通过PVC进行数据的持久化;
  8. 而PVC使用PV进行数据的最终持久化处理。
提示:关于Kubernetes的部署参考《附003.Kubeadm部署Kubernetes》。

5.2 定义StorageClass

关键字说明:
  • provisioner:表示存储分配器,需要根据后端存储的不同而变更;
  • reclaimPolicy: 默认即”Delete”,删除pvc后,相应的pv及后端的volume,brick(lvm)等一起删除;设置为”Retain”时则保留数据,若需删除则需要手工处理;
  • resturl:heketi API服务提供的url;
  • restauthenabled:可选参数,默认值为”false”,heketi服务开启认证时必须设置为”true”;
  • restuser:可选参数,开启认证时设置相应用户名;
  • secretNamespace:可选参数,开启认证时可以设置为使用持久化存储的namespace;
  • secretName:可选参数,开启认证时,需要将heketi服务的认证密码保存在secret资源中;
  • clusterid:可选参数,指定集群id,也可以是1个clusterid列表,格式为”id1,id2”;
  • volumetype:可选参数,设置卷类型及其参数,如果未分配卷类型,则有分配器决定卷类型;如”volumetype: replicate:3”表示3副本的replicate卷,”volumetype: disperse:4:2”表示disperse卷,其中‘4’是数据,’2’是冗余校验,”volumetype: none”表示distribute卷
提示:关于glusterfs各种不同类型的卷见《004.RHGS-创建volume》。
  1 [root@k8smaster01 ~]# kubectl create ns heketi		#创建命名空间
2 [root@k8smaster01 ~]# echo -n "admin123" | base64 #将密码转换为64位编码
3 YWRtaW4xMjM=
4 [root@k8smaster01 ~]# mkdir -p heketi
5 [root@k8smaster01 ~]# cd heketi/
6 [root@k8smaster01 ~]# vi heketi-secret.yaml #创建用于保存密码的secret
7 apiVersion: v1
8 kind: Secret
9 metadata:
10 name: heketi-secret
11 namespace: heketi
12 data:
13 # base64 encoded password. E.g.: echo -n "mypassword" | base64
14 key: YWRtaW4xMjM=
15 type: kubernetes.io/glusterfs
16 [root@k8smaster01 heketi]# kubectl create -f heketi-secret.yaml #创建heketi
17 [root@k8smaster01 heketi]# kubectl get secrets -n heketi
18 NAME TYPE DATA AGE
19 default-token-5sn5d kubernetes.io/service-account-token 3 43s
20 heketi-secret kubernetes.io/glusterfs 1 5s
21 [root@kubenode1 heketi]# vim gluster-heketi-storageclass.yaml #正式创建StorageClass
22 apiVersion: storage.k8s.io/v1
23 kind: StorageClass
24 metadata:
25 name: gluster-heketi-storageclass
26 parameters:
27 resturl: "http://172.24.8.44:8080"
28 clusterid: "aa83b0045fafa362bfc7a8bfee0c24ad"
29 restauthenabled: "true" #若heketi开启认证此处也必须开启auth认证
30 restuser: "admin"
31 secretName: "heketi-secret" #name/namespace与secret资源中定义一致
32 secretNamespace: "heketi"
33 volumetype: "replicate:3"
34 provisioner: kubernetes.io/glusterfs
35 reclaimPolicy: Delete
36 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-storageclass.yaml
注意:storageclass资源创建后不可变更,如修改只能删除后重建。
  1 [root@k8smaster01 heketi]# kubectl get storageclasses		#查看确认
2 NAME PROVISIONER AGE
3 gluster-heketi-storageclass kubernetes.io/glusterfs 85s
4 [root@k8smaster01 heketi]# kubectl describe storageclasses gluster-heketi-storageclass

5.3 定义PVC

  1 [root@k8smaster01 heketi]# cat gluster-heketi-pvc.yaml
2 apiVersion: v1
3 metadata:
4 name: gluster-heketi-pvc
5 annotations:
6 volume.beta.kubernetes.io/storage-class: gluster-heketi-storageclass
7 spec:
8 accessModes:
9 - ReadWriteOnce
10 resources:
11 requests:
12 storage: 1Gi
注意:accessModes可有如下简写:




  • ReadWriteOnce:简写RWO,读写权限,且只能被单个node挂载;

  • ReadOnlyMany:简写ROX,只读权限,允许被多个node挂载;

  • ReadWriteMany:简写RWX,读写权限,允许被多个node挂载。
  1 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-pvc.yaml
2 [root@k8smaster01 heketi]# kubectl get pvc
3 [root@k8smaster01 heketi]# kubectl describe pvc gluster-heketi-pvc
4 [root@k8smaster01 heketi]# kubectl get pv
5 [root@k8smaster01 heketi]# kubectl describe pv pvc-5f7420ef-082d-11ea-badf-000c29fa7a79
  1 [root@k8smaster01 heketi]# kubectl describe endpoints glusterfs-dynamic-5f7420ef-082d-11ea-badf-000c29fa7a79
提示:由上可知:PVC状态为Bound,Capacity为1G。查看PV详细信息,除容量,引用storageclass信息,状态,回收策略等外,同时可知GlusterFS的Endpoint与path。EndpointsName为固定格式:glusterfs-dynamic-PV_NAME,且endpoints资源中指定了挂载存储时的具体地址。

5.4 确认查看

通过5.3所创建的信息:
  • volume与brick已经创建;
  • 主挂载点(通信)在172.24.8.41节点,其余两个节点备选;
  • 三副本的情况下,所有节点都会创建brick。
  1 [root@heketi ~]# heketi-cli topology info			#heketi主机查看
2 [root@serverb ~]# lsblk #glusterfs节点查看
3 [root@serverb ~]# df -hT #glusterfs节点查看
4 [root@servera ~]# gluster volume list #glusterfs节点查看
5 [root@servera ~]# gluster volume info vol_e4c948687239df9833748d081ddb6fd5

5.5 Pod挂载测试

  1 [root@xxx ~]# yum -y install centos-release-gluster
2 [root@xxx ~]# yum -y install glusterfs-fuse #安装glusterfs-fuse
提示:所有需要使用glusterfs volume的Kubernetes节点都必须安装glusterfs-fuse以便于正常挂载,同时版本需要和glusterfs节点一致。
  1 [root@k8smaster01 heketi]# vi gluster-heketi-pod.yaml
2 kind: Pod
3 apiVersion: v1
4 metadata:
5 name: gluster-heketi-pod
6 spec:
7 containers:
8 - name: gluster-heketi-container
9 image: busybox
10 command:
11 - sleep
12 - "3600"
13 volumeMounts:
14 - name: gluster-heketi-volume #必须和volumes中name一致
15 mountPath: "/pv-data"
16 readOnly: false
17 volumes:
18 - name: gluster-heketi-volume
19 persistentVolumeClaim:
20 claimName: gluster-heketi-pvc #必须和5.3创建的PVC中的name一致
21 [root@k8smaster01 heketi]# kubectl create -f gluster-heketi-pod.yaml -n heketi #创建Pod

5.6 确认验证

  1 [root@k8smaster01 heketi]# kubectl get pod -n heketi | grep gluster
2 gluster-heketi-pod 1/1 Running 0 2m43s
3 [root@k8smaster01 heketi]# kubectl exec -it gluster-heketi-pod /bin/sh #进入Pod写入测试文件
4 / # cd /pv-data/
5 /pv-data # echo "This is a file!" >> a.txt
6 /pv-data # echo "This is b file!" >> b.txt
7 /pv-data # ls
8 a.txt b.txt
9 [root@servera ~]# df -hT #在glusterfs节点查看Kubernetes节点的测试文件
10 [root@servera ~]# cd /var/lib/heketi/mounts/vg_47c90d90e03de79696f90bd94cfccdde/brick_721243c3e0cf8a2372f05d5085a4338c/brick/
11 [root@servera brick]# ls
12 [root@servera brick]# cat a.txt
13 [root@servera brick]# cat b.txt

5.7 删除资源

  1 [root@k8smaster01 heketi]# kubectl delete -f gluster-heketi-pod.yaml
2 [root@k8smaster01 heketi]# kubectl delete -f gluster-heketi-pvc.yaml
3 [root@k8smaster01 heketi]# kubectl get pvc
4 [root@k8smaster01 heketi]# kubectl get pv
5 [root@servera ~]# gluster volume list
6 No volumes present in cluster

附009.Kubernetes永久存储之GlusterFS独立部署的更多相关文章

  1. 附010.Kubernetes永久存储之GlusterFS超融合部署

    一 前期准备 1.1 基础知识 在Kubernetes中,使用GlusterFS文件系统,操作步骤通常是: 创建brick-->创建volume-->创建PV-->创建PVC--&g ...

  2. 附013.Kubernetes永久存储Rook部署

    一 Rook概述 1.1 Ceph简介 Ceph是一种高度可扩展的分布式存储解决方案,提供对象.文件和块存储.在每个存储节点上,将找到Ceph存储对象的文件系统和Ceph OSD(对象存储守护程序)进 ...

  3. 附014.Kubernetes Prometheus+Grafana+EFK+Kibana+Glusterfs整合解决方案

    一 glusterfs存储集群部署 注意:以下为简略步骤,详情参考<附009.Kubernetes永久存储之GlusterFS独立部署>. 1.1 架构示意 略 1.2 相关规划 主机 I ...

  4. 附014.Kubernetes Prometheus+Grafana+EFK+Kibana+Glusterfs整合性方案

    一 glusterfs存储集群部署 注意:以下为简略步骤,详情参考<附009.Kubernetes永久存储之GlusterFS独立部署>. 1.1 架构示意 略 1.2 相关规划 主机 I ...

  5. 附024.Kubernetes全系列大总结

    Kubernetes全系列总结如下,后期不定期更新.欢迎基于学习.交流目的的转载和分享,禁止任何商业盗用,同时希望能带上原文出处,尊重ITer的成果,也是尊重知识.若发现任何错误或纰漏,留言反馈或右侧 ...

  6. 独立部署GlusterFS+Heketi实现Kubernetes共享存储

    目录 环境 glusterfs配置 安装 测试 heketi配置 部署 简介 修改heketi配置文件 配置ssh密钥 启动heketi 生产案例 heketi添加glusterfs 添加cluste ...

  7. kubernetes存储之GlusterFS

    目录 1.glusterfs概述 1.1.glusterfs简介 1.2.glusterfs特点 1.3.glusterfs卷的模式 2.heketi概述 3.部署heketi+glusterfs 3 ...

  8. 附022.Kubernetes_v1.18.3高可用部署架构一

    kubeadm介绍 kubeadm概述 参考附003.Kubeadm部署Kubernetes. kubeadm功能 参考附003.Kubeadm部署Kubernetes. 本方案描述 本方案采用kub ...

  9. 附024.Kubernetes_v1.18.3高可用部署架构二

    kubeadm介绍 kubeadm概述 参考<附003.Kubeadm部署Kubernetes>. kubeadm功能 参考<附003.Kubeadm部署Kubernetes> ...

随机推荐

  1. c++11::std::is_same/decay

    #include <type_traits> std::is_same 判断类型是否一致 通过std::is_same即可判断两个类型是否一样,特别在模板里面,在不清楚模板的参数时,此功能 ...

  2. HDU 3371 Connect the Cities(并查集+Kruskal)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先 ...

  3. {每日一题}:四种方法实现打印feibo斐波那契数列

    刚开始学Python的时候,记得经常遇到打印斐波那契数列了,今天玩玩使用四种办法打印出斐波那契数列 方法一:使用普通函数 def feibo(n): """ 打印斐波那契 ...

  4. python中的__call__函数

    简单实例: class TmpTest: def __init__(self, x, y): self.x = x self.y = y def __call__(self, x, y): self. ...

  5. Mybatis源码阅读 之 玩转Executor

    承接上篇博客, 本文探究MyBatis中的Executor, 如下图: 是Executor体系图 本片博客的目的就是探究如上图中从顶级接口Executor中拓展出来的各个子执行器的功能,以及进一步了解 ...

  6. 微服务架构 ------ Day01 微服务架构优缺点

    1. 微服务架构的优点 庞大的单体程序 -> 一套微型程序. 每一个服务有明确的边界(服务之间的消息通讯机制) ,每一个服务都能单独的开发和维护,并且更好理解 每一个服务都能由一个团队来开发,当 ...

  7. 源码学习系列之SpringBoot自动配置(篇一)

    源码学习系列之SpringBoot自动配置源码学习(篇一) ok,本博客尝试跟一下Springboot的自动配置源码,做一下笔记记录,自动配置是Springboot的一个很关键的特性,也容易被忽略的属 ...

  8. 明解C语言 入门篇 第四章答案

    练习4-1 #include <stdio.h> int main(void) { int no; int x; do{ printf("请输入一个整数:"); sca ...

  9. C语言I作业06

    问题 答案 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-4/homework/9888 我在 ...

  10. (八)golang--复杂类型之指针

    首先我们要明确:(1)基本数据类型:变量存的就是值,也叫值类型: (2)获取变量的地址,用&,例如var num int,获取num的地址:&num: (3)指针类型:变量存的是一个地 ...