作者归档:imliuda

linux配置多级服务器登录和隧道映射

通常,办公环境的电脑无法直接连接到开发测试服务器,往往需要进行多次ssh跳转。这时可通过配置ssh支持自动跳转登录功能。假设有2台服务器A和B在我们的开发测试环境中,本地我们只能连接到A服务器,而A服务器可以连接到B服务器。编辑~/.ssh/config文件,输入下列内容:

Host serverA
    User root
    HostName 10.1.2.3
    IdentityFile /home/myusername/.ssh/id_rsa
    Port 22

Host serverB
    User root
    HostName 192.168.1.3
    IdentityFile /home/myusername/.ssh/id_rsa
    port 22
    ProxyJump mypub

此时,在本地即可通过ssh serverB直接连接到服务器B的ssh服务。如果要使用免密方式进行登录。则需要执行ssh-copy-id root@serverA和ssh-copy-id root@serverB进行配置免密。

在进行了这样的配置之后,我们也可以更加方便的建立隧道来使用了。比如在服务器上有一个8080的http服务,想要在本地浏览器里访问。那么,可以执行下列命令建立隧道:

ssh -Nf -Llocalhost:8080:192.168.1.3:8080 serverB

此命令会将serverB上的8080端口映射到本地的8080端口上,在浏览器中我们只需要输入http://localhost:8080可以访问到serverB上的web服务。

同样,也可以通过-R选项将本地端口映射到serverB的某个端口上,比如在微信公众号开发测试的时候,可以将配置在公众平台的服务器地址上的服务映射到本地。

为了避免网络连接中断导致隧道断开连接,可以使用systemd来保活,隧道进程退出后自动将其拉起:

# cat /lib/systemd/system//my-http-proxy.service
[Unit]
Describe=Kmr nginx agent
After=network.target
[Service]
LimitNOFILE=10000
Type=simple
User=root
Group=root
ExecStart=/usr/bin/ssh -oExitOnForwardFailure=yes -oPubkeyAuthentication=yes -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oServerAliveInterval=5 -oServerAliveCountMax=3 -Llocalhost:8080:localhost:8080 -N root@serverB
Restart = always
RestartSec = 1s
StartLimitInterval = 0

[Install]
WantedBy=network.target

执行systemctl daemon-reload和systemctl start my-http-proxy来启动服务。

linux下tcp keepalive相关参数调整测试

首先说明下面三个和keepalive相关的内核参数以及默认的值

# sysctl -a | grep keepalive
# 在会后一次发送数据包后多久向对方发起探测
net.ipv4.tcp_keepalive_time = 7200
# 在没有收到对方确认时,会按照这个时间间隔再次探测
net.ipv4.tcp_keepalive_intvl = 75
# 在没有收到对方确认时,进行探测的次数
net.ipv4.tcp_keepalive_probes = 9

下面通过在本地环境上测试这些参数,首先将本地的默认keepalive参数进行修改

# sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 20

下载并编译带keepalive功能支持的netcat命令行工具

git clone https://github.com/cyberelf/netcat-keepalive.git
cd netcat-keepalive/
make linux

运行tcpdump进行抓包

tcpdump -iany port 18888

启动服务端监听

./nckl-linux -v4K -l 18888

使用nc去连接

nc -v -p55666 localhost 18888

可以看到抓包内容如下

root@debian:/home/blue# tcpdump -iany port 18888
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
15:42:49.840078 IP localhost.55666 > localhost.18888: Flags [S], seq 4147250120, win 65495, options [mss 65495,sackOK,TS val 3777822786 ecr 0,nop,wscale 7], length 0
15:42:49.840104 IP localhost.18888 > localhost.55666: Flags [S.], seq 2015925109, ack 4147250121, win 65483, options [mss 65495,sackOK,TS val 3777822786 ecr 3777822786,nop,wscale 7], length 0
15:42:49.840124 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777822786 ecr 3777822786], length 0
# 这里三次握手结束并且在客户端发送了一个字符
15:42:50.991399 IP localhost.55666 > localhost.18888: Flags [P.], seq 1:4, ack 1, win 512, options [nop,nop,TS val 3777823937 ecr 3777822786], length 3
15:42:50.991421 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777823937 ecr 3777823937], length 0
# 从这里开始下面是每隔20秒钟进行一次探测
15:43:11.005311 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777843951 ecr 3777823937], length 0
15:43:11.005343 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777843951 ecr 3777823937], length 0
15:43:31.101311 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777864047 ecr 3777843951], length 0
15:43:31.101346 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777864047 ecr 3777823937], length 0
15:43:51.325306 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777884271 ecr 3777864047], length 0
15:43:51.325328 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777884271 ecr 3777823937], length 0
# 在这里执行了一个iptables -A INPUT -p tcp --dport 55666 -j DROP命令,可以看到在没有收到对方应答的情况下会每隔5秒进行一次探测,连续9次没有收到应答,操作系统重置了这个连接
15:44:11.549314 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777904495 ecr 3777884271], length 0
15:44:16.669304 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777909615 ecr 3777884271], length 0
15:44:21.789312 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777914735 ecr 3777884271], length 0
15:44:26.909310 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777919855 ecr 3777884271], length 0
15:44:32.029305 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777924975 ecr 3777884271], length 0
15:44:37.149314 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777930095 ecr 3777884271], length 0
15:44:42.269309 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777935215 ecr 3777884271], length 0
15:44:47.389304 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777940335 ecr 3777884271], length 0
15:44:52.509319 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777945455 ecr 3777884271], length 0
15:44:57.629320 IP localhost.18888 > localhost.55666: Flags [R.], seq 1, ack 4, win 512, options [nop,nop,TS val 3777950575 ecr 3777884271], length 0

记一次k8s集群pod一直terminating问题的排查

现象描述

pod一直处于terminating状态,或者很久才能删除,内核日志中持续打印unregister_netdevice: waiting for XXX to become free. Usage count = 1。

故障诊断

经过定位和排查,定位到是内核的一个bug导致网络设备无法删除。具体参考https://github.com/torvalds/linux/commit/ee60ad219f5c7c4fb2f047f88037770063ef785f

另外在github的k8s的issues里也有该bug的相关讨论。有人给出了付现这个问题的方式,以及验证上面提到的修复方法是否有效。下面是按照他给出的方案做的复现和验证。具体可参考https://github.com/moby/moby/issues/5618#issuecomment-549333485

问题排查

从kubelet内核日志来看是在删除pod的网卡设备时因为内核的引用计数bug,导致无法删除。后续对网卡信息的查询和再次删除操作应该也会导致超时失败(根据日志推断,暂时还未在代码中找到对应调用,线上环境也没法重启调整日志级别和调试)。

首先需要看一个概念:PLEG。

PLEG (pod lifecycle event generator) 是 kubelet 中一个非常重要的模块,它主要完成以下几个目标:

  • 从 runtime 中获取 pod 当前状态,产生 pod lifecycle events
  • 从 runtime 中获取 pod 当前状态,更新 kubelet pod cache

接下来分析一下造成问题的原因应该是k8s的PLEG在同步pod信息时,可能要查询网卡详情(ip地址),由于内核bug导致超时,致使syncLoop中每执行一次遍历的时间过长(4分钟左右),因此新建pod和删除pod的时候,node上的信息和server上的信息更新不及时。用busybox测试创建和删除时,通过docker ps可以看到响应容器很快就可以启动或删除掉。

从图中可以看到该日志:Calico CNI deleting device in netns /proc/16814/ns/net这条。这是在pod执行删除是产生的。在正常情况下后面会有删除完成的日志信息,如下图:

但上面的日志里的无此信息,并且10s后打印了unregister_netdevice xxx的日志。这里是触发了内核bug。通过ps aux | grep calico也可以看到在对应时间有一个calico进程启动去执行操作,目前这个进程还在(10.209.33.105),这里估计k8s也有bug,没有wait pid,导致calico成为僵尸进程。

下图是kubelet日志。其中的PLEG is not healthy日志也是在对应的时间点出现。

问题本地复现

要在本地复现这个问题,首先需要给内核打补丁来协助复现。

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a0163c5..6b9e7ee 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -133,6 +133,8 @@

 static int ip_min_valid_pmtu __read_mostly	= IPV4_MIN_MTU;

+static int ref_leak_test;
+
/*
  *	Interface to generic destination cache.
  */
@@ -1599,6 +1601,9 @@ static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
 	fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock));
	while (fnhe) {
 		if (fnhe->fnhe_daddr == daddr) {
+			if (ref_leak_test)
+				pr_info("XXX pid: %d, %s: fib_nh:%p, fnhe:%p, daddr:%x\n",
+					current->pid,  __func__, nh, fnhe, daddr);
 			rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
 				fnhe->fnhe_next, lockdep_is_held(&fnhe_lock)));
 			fnhe_flush_routes(fnhe);
@@ -2145,10 +2150,14 @@ static struct rtable *__mkroute_output(const struct fib_result *res,

		fnhe = find_exception(nh, fl4->daddr);
 		if (fnhe) {
+			if (ref_leak_test)
+				pr_info("XXX pid: %d, found fnhe :%p\n", current->pid, fnhe);
 			prth = &fnhe->fnhe_rth_output;
 			rth = rcu_dereference(*prth);
 			if (rth && rth->dst.expires &&
`			    time_after(jiffies, rth->dst.expires)) {
+				if (ref_leak_test)
+					pr_info("eXX pid: %d, del fnhe :%p\n", current->pid, fnhe);
				ip_del_fnhe(nh, fl4->daddr);
 				fnhe = NULL;
 			} else {
@@ -2204,6 +2213,14 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
 #endif
 	}

+	if (fnhe && ref_leak_test) {
+		unsigned long  time_out;
+
+		time_out = jiffies + ref_leak_test;
+		while (time_before(jiffies, time_out))
+			cpu_relax();
+		pr_info("XXX pid: %d, reuse fnhe :%p\n", current->pid, fnhe);
+	}
 	rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0);
 	if (lwtunnel_output_redirect(rth->dst.lwtstate))
 		rth->dst.output = lwtunnel_output;
@@ -2733,6 +2750,13 @@ static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write,
		.proc_handler	= proc_dointvec,
	},
 	{
+		.procname	= "ref_leak_test",
+		.data		= &ref_leak_test,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
+	{
		.procname	= "max_size",
		.data		= &ip_rt_max_size,
 		.maxlen		= sizeof(int),

编译内核的详细步骤参考:https://wiki.centos.org/zh/HowTos/Custom_Kernel

添加用户useradd kernel-build

下载内核源码kernel-3.10.0-693.el7.src.rpm,拷贝到/home/kernel-build,并切换到kernel-build用户。

执行rpm -i kernel-3.10.0-693.el7.src.rpm | grep -v exist解压源码包。

进入cd /home/kernel-build/rpmbuild目录。

修改rpm打包文件vim SPECS/kernel.spec,添加patch说明。

ApplyOptionalPatch netdev-leak.patch

编辑并生成patch文件,保存到SOURCES/netdev-leak.patch,其内容为:

--- a/net/ipv4/route.c	2017-07-07 07:37:46.000000000 +0800
+++ b/net/ipv4/route.c	2020-05-06 17:33:19.746187091 +0800
@@ -129,6 +129,7 @@
 static int ip_rt_min_advmss __read_mostly	= 256;
 
 static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
+static int ref_leak_test;
 /*
  *	Interface to generic destination cache.
  */
@@ -1560,8 +1561,15 @@
 	fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock));
 	while (fnhe) {
 		if (fnhe->fnhe_daddr == daddr) {
+			if (ref_leak_test)
+				pr_info("XXX pid: %d, %s: fib_nh:%p, fnhe:%p, daddr:%x\n",
+					current->pid,  __func__, nh, fnhe, daddr);
 			rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
 				fnhe->fnhe_next, lockdep_is_held(&fnhe_lock)));
+			/* set fnhe_daddr to 0 to ensure it won't bind with
+  			 * new dsts in rt_bind_exception().
+ 			 */
+			// fnhe->fnhe_daddr = 0; 这行是修复代码,复现问题的时候不需要,注释掉
 			fnhe_flush_routes(fnhe);
 			kfree_rcu(fnhe, rcu);
 			break;
@@ -2054,10 +2062,14 @@
 
 		fnhe = find_exception(nh, fl4->daddr);
 		if (fnhe) {
+			if (ref_leak_test)
+				pr_info("XXX pid: %d, found fnhe :%p\n", current->pid, fnhe);
 			prth = &fnhe->fnhe_rth_output;
 			rth = rcu_dereference(*prth);
 			if (rth && rth->dst.expires &&
 			    time_after(jiffies, rth->dst.expires)) {
+				if (ref_leak_test)
+					pr_info("eXX pid: %d, del fnhe :%p\n", current->pid, fnhe);
 				ip_del_fnhe(nh, fl4->daddr);
 				fnhe = NULL;
 			} else {
@@ -2122,6 +2134,14 @@
 #endif
 	}
 
+	if (fnhe && ref_leak_test) {
+		unsigned long  time_out;
+
+		time_out = jiffies + ref_leak_test;
+		while (time_before(jiffies, time_out))
+			cpu_relax();
+		pr_info("XXX pid: %d, reuse fnhe :%p\n", current->pid, fnhe);
+	}
 	rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0);
 	if (lwtunnel_output_redirect(rth->dst.lwtstate))
 		rth->dst.output = lwtunnel_output;
@@ -2661,6 +2681,13 @@
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
+	},
+	{
+		.procname	= "ref_leak_test",
+		.data		= &ref_leak_test,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
 	},
 	{
 		.procname	= "max_size",

执行rpmbuild -bb –target=`uname -m` SPECS/kernel.spec 2> build-err.log | tee build-out.log

安装新内:

yum localinstall RPMS/x86_64/kernel-3.10.0-693.el7.centos.x86_64.rpm

编辑ref_leak_test_begin.sh

#!/bin/bash

# constructing a basic network with netns
# client <-->gateway <--> server
ip netns add svr
ip netns add gw
ip netns add cli

ip netns exec gw sysctl net.ipv4.ip_forward=1

ip link add svr-veth type veth peer name svrgw-veth
ip link add cli-veth type veth peer name cligw-veth

ip link set svr-veth netns svr
ip link set svrgw-veth netns gw
ip link set cligw-veth netns gw
ip link set cli-veth netns cli

ip netns exec svr ifconfig svr-veth 192.168.123.1
ip netns exec gw ifconfig svrgw-veth 192.168.123.254
ip netns exec gw ifconfig cligw-veth 10.0.123.254
ip netns exec cli ifconfig cli-veth 10.0.123.1

ip netns exec cli route add default gw 10.0.123.254
ip netns exec svr route add default gw 192.168.123.254

# constructing concurrently accessed scenes with nerperf
nohup ip netns exec svr  netserver -L 192.168.123.1

nohup ip netns exec cli  netperf -H 192.168.123.1 -l 300 &
nohup ip netns exec cli  netperf -H 192.168.123.1 -l 300 &
nohup ip netns exec cli  netperf -H 192.168.123.1 -l 300 &
nohup ip netns exec cli  netperf -H 192.168.123.1 -l 300 &

# Add delay
echo 3000 > /proc/sys/net/ipv4/route/ref_leak_test

# making PMTU discovery exception routes
echo 1 >  /proc/sys/net/ipv4/route/mtu_expires
for((i=1;i<=60;i++));
do
  for j in 1400  1300 1100 1000
  do
	echo "set mtu to "$j;
	ip netns exec svr ifconfig  svr-veth  mtu $j;
	ip netns exec cli ifconfig  cli-veth  mtu $j;
	ip netns exec gw ifconfig svrgw-veth  mtu $j;
	ip netns exec gw ifconfig cligw-veth  mtu $j;
	sleep 2;
  done
done

编辑ref_leak_test_end.sh

#!/bin/bash

echo 0 > /proc/sys/net/ipv4/route/ref_leak_test

pkill netserver
pkill netperf

ip netns exec cli ifconfig cli-veth down
ip netns exec gw ifconfig svrgw-veth down
ip netns exec gw ifconfig cligw-veth down
ip netns exec svr ifconfig svr-veth down

ip netns del svr
ip netns del gw
ip netns del cli

执行测试,首先执行bash ref_leak_test_begin.sh,等待数秒至一分钟时间。Ctrl + C结束,执行bash ref_leak_test_end.sh。大概在10秒钟之内会打印下列信息:

[root@VM_1_72_centos ~]# bash ref_leak_test_begin.sh 
net.ipv4.ip_forward = 1
nohup: 忽略输入并把输出追加到"nohup.out"
nohup: 把输出追加到"nohup.out"
nohup: 把输出追加到"nohup.out"
set mtu to 1400
nohup: 把输出追加到"nohup.out"
nohup: 把输出追加到"nohup.out"
set mtu to 1300
set mtu to 1100
set mtu to 1000
set mtu to 1400
set mtu to 1300
^C^C
[root@VM_1_72_centos ~]# bash ref_leak_test_end.sh 
[root@VM_1_72_centos ~]# ip netns list
Message from syslogd@VM_1_72_centos at May  6 17:43:49 ...
 kernel:unregister_netdevice: waiting for cli-veth to become free. Usage count = 1

[root@VM_1_72_centos ~]# ip netns list
[root@VM_1_72_centos ~]# 
Message from syslogd@VM_1_72_centos at May  6 17:43:59 ...
 kernel:unregister_netdevice: waiting for cli-veth to become free. Usage count = 1

Message from syslogd@VM_1_72_centos at May  6 17:44:09 ...
 kernel:unregister_netdevice: waiting for cli-veth to become free. Usage count = 1

Message from syslogd@VM_1_72_centos at May  6 17:44:19 ...
 kernel:unregister_netdevice: waiting for cli-veth to become free. Usage count = 1

Message from syslogd@VM_1_72_centos at May  6 17:44:29 ...
 kernel:unregister_netdevice: waiting for cli-veth to become free. Usage count = 1

现在可以复现出unregister_netdevice: waiting for XXX to become free. Usage count = 1的问题。

修复和验证

问题修复的patch是修改内核代码net/ipv4/route.c中的下列内容:

@@ -1303,6 +1303,10 @@ static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
		if (fnhe->fnhe_daddr == daddr) {
			rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
				fnhe->fnhe_next, lockdep_is_held(&fnhe_lock)));
			/* set fnhe_daddr to 0 to ensure it won't bind with
			 * new dsts in rt_bind_exception().
			 */
			fnhe->fnhe_daddr = 0;
			fnhe_flush_routes(fnhe);
			kfree_rcu(fnhe, rcu);
			break;

将这段补丁代码打入内核中,可参考netdev-leak.patch中,重新编译、安装内核。

再次执行上面的bash ref_leak_test_begin.sh和bash ref_leak_test_end.sh发现不会在打印unregister_netdevice: waiting for XXX to become free. Usage count = 1的日志。说明这段代码起作用了。

除了等待eth0这个问题,还有一个等待lo的类似问题,也有可能会出现。新版内核得到修复(v4.15),不过目前还没遇到这个问题。

另外对于pod terminating问题我们的内部环境上还没复现,个人觉得可参考ref_leak_test_begin.sh中的做法,在一个pod内向另一个pod发起大量的tcp连接请求进行测试。

参考

轮指和修指甲小计

轮指

拇指要放松才能弹均匀,四个手指头下意识去独立控制,ima拨弦时要快速发力。90左右慢速练习时要把声音弹足够大和清晰。

指甲

由于m型指甲,斜坡不用太长,斜坡太长会有指甲摩擦琴弦的声音,最高坡点在手指中心偏向小指方向一点点的位置。指甲不用太长,从正面看相对于指肚多出1至2毫米即可。拨弦方向在标准姿势稍垂直于琴弦一点点,可以有效利用m型指甲中间凹点带动下压琴弦。合理的指甲形状可以通过拨弦时的阻力确定,阻力太小太顺滑发不出圆润的声音,因为无法有效的下压琴弦,要调整到一个阻力合适的形状。

古典吉他学习第十七十八节课总结

课上主要看练习效果。注意练习的时候声音要大,要放开。注意保留指,旋律音不要用保留指,是多少时值就响多久。伴奏是和弦的话可以。要区分出旋律和伴奏,也要注意多个声部以及旋律在声部之间的变换。还需在深入。

对于节奏的把握需要继续练,尤其附点音符。

练习

1. 和声音程

2. 《铜壶的四周》

八分音符 = 75 90 105

3. 《古典舞蹈》

八分音符 = 70 80 90

4. 《土拨鼠》

八分音符 = 70 80 90

5. 视奏《小精灵》、《多年以后》、《冒险记》

古典吉他学习第十三十四节课总结

课上主要看练习效果。

练习

1. 卡鲁里

1~9型 1:2 85   100  115, 1:3 60 70 80

10,11型 1:1 110 120 130

2. 和声音程

变型 1:1 90 105 120

标准 2:1 60 70 80

1-9型 1:1 140 155 170

3. 《我怎能离开你》 低音版

四分音符 110 120 130

4. 《我怎能离开你》 高音版

四分音符 60 70 80

5. 《视奏《古典舞蹈》》

古典吉他学习第十一十二节课总结

本节课的问题是演奏没有区分强弱因,强弱弱的节奏谈成了一样的,低音是主旋律,高音是伴奏。注意低音的强度,回来发现和拇指指甲修剪的形状有关,重新调整之后,稍微再用力些按弦,确实低音的音量更加饱满。同时锻炼手指灵活度。

练习

1. 和声音程

变型 1:1 90   105  120

正常 2:1 60 70 80

2. 卡路里

10型,11型 1:1 70 85 100

12型 2:1 70 85 100

1-9型 1:1 140 155 170

3. 我怎能离开你 P指

四分音符 = 60 70 80

4. 视奏高音版 我怎能离开你

 

保持打拨弦和开指练习,加入右手反弹,左右手交替练习。

 

同时记录下回来之后找到的最好发音拨弦和指甲形状

古典吉他学习第九十节课总结

老师说发音很饱满,拨弦还不够稳定,需要再进一步加强稳定性练习,只之前的速度上继续提升一些,巩固一下发音,不可过快,打好基本功很重要。

练习

1.和声音程

变型 1:1 55 70 85

Pi Pm pi pm pi mp

Pm Pa pm pa pm pa

正常 2:1 60 75 90

2. 卡鲁里

1-9型 1:1 110 125 140 (155)

视奏10-12型

3. 我怎能离开你

八分音符 = 80 95 110 (125)

4. 开指

1:1 60 90 100

5. 打拨弦

1:1 90 100 110

 

古典吉他学习第七八节课总结

上课老师指出手指不够稳定,要放慢练习速度,把动作练熟,形成肌肉记忆,速度提升是很快的事情。放慢节奏继续练习基本功,每个动作做到位。节奏不稳表现在手指控制能力不够,不能准确一致的发音,同一个音可能声大声小,音色不同或者有杂音。另外听老师弹出的声音确实不一样。要重视基本功练习!

练习

我怎能离开你

四分音符 = 70 80 90

卡鲁里

1至4型 1:1 60 70 80 90(一音一拍)

视奏5至9型

打拨弦

1:1 60 70

开指

1:1 60:70

视奏和声音程

可依次弹出单音,在弹和声