LXC更新到Docker之后的存储部分修改

在k8s没有出来之前,我们用的就是LXC,古早版本了。 那时候是1:60的虚拟,一台物理机上跑60个LXC,居然这样运行了8年无异常,现在要升级一下了。 那时候的LXC,存储空间无法单独设定(缺省10G),cpu和mem的limit也有这样那样的问题。 进化到新版本的Docker后,存储部分也需要修改,我们采用overlay2: docker info ... Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: true ... 缺省的就是overlay2和xfs 一、修改boot内核启动参数 vi /etc/default/grub #加上rootflags=uquota,pquota GRUB_CMDLINE_LINUX="console=tty0 crashkernel=auto net.ifnames=0 console=ttyS0 rootflags=uquota,pquota" #更新 grub2-mkconfig -o /boot/grub2/grub.cfg #重启 reboot 二、检验并启动容器 cat /proc/mounts |grep vda /dev/vda1 / xfs rw,relatime,attr2,inode64,usrquota,prjquota 0 0 有prjquota即可 按需启动容器,指定空间大小,size=2G docker run --rm -dit --name=t36 --storage-opt size=2G --net macvlan0 --ip=172.18.31.36 alpine:latest ash docker exec -it t36 ash df -h ...

2023年12月14日

KVM的嵌套虚拟化

kvm生产的虚机内仍然可以再产虚拟机,这就是嵌套虚拟化 我们的目的是要再kvm虚机中安装一套proxmox的系统 首先在实体机上检查当前的Linux是否支持嵌套 Intel的CPU cat /sys/module/kvm_intel/parameters/nested AMD的CPU cat /sys/module/kvm_amd/parameters/nested ​ 修改支持,以intel为例: vi /etc/modprobe.d/kvm.conf options kvm_intel nested=1 reboot就好 不重启的话,可以先卸载模块,然后重新加载 modprobe -r kvm_intel modprobe kvm_intel 然后检查一下 cat /sys/module/kvm_intel/parameters/nested proxmox安装的时候,指定cpu=host: #!/bin/sh qemu-img create -f qcow2 /export/kvm/proxmox-168-86-103/proxmox-168-86-103.qcow2 200G virt-install \ --name=proxmox-168-86-103 \ --cpu=host \ --ram=8192 \ --disk path=/export/kvm/proxmox-168-86-103/proxmox-168-86-103.qcow2,format=qcow2,size=200 \ --cdrom=/export/kvm/iso/proxmox-ve_7.0-2.iso \ --os-type=Linux \ --network bridge=br0 \ --vnc --vnclisten=0.0.0.0 --vncport=5903

2023年12月14日

KVM网络如何设置DHCP

缺省情况下kvm会保留一个nat的网络,ip a命令查看,会看到virbr0和virbr0-nic 8: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN link/ether 52:54:00:6c:22:2c brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 9: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 500 link/ether 52:54:00:6c:22:2c brd ff:ff:ff:ff:ff:ff 这个如果虚机都是静态IP,且不做NAT的话,则无必要保留,可以彻底删掉。 kvm删除掉缺省网络 virsh net-destroy default virsh net-undefine default 那么如果非用不可,还需要给特定虚机用dhcp指定固定IP 方法如下: 查看缺省网络 $ virsh net-list Name State Autostart Persistent ---------------------------------------------------------- default active yes yes 找出虚机的mac地址 $ virsh dumpxml vis-16-10-33 | grep -i '<mac' <mac address='f0:00:ac:10:0a:21'/> 编辑网络 $ virsh net-edit default <network> <name>default</name> <uuid>58e86841-ef4b-4d63-bf4f-7888515b8474</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='on' delay='0' /> <mac address='52:54:00:6C:22:2C'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254' /> </dhcp> </ip> </network> 在range下面来一列 ...

2023年12月14日

Shell中变量、字符串、数组、参数的技巧

变量子串 ${var} 返回变量var的内容,单独使用时有没有{}一样,混合多个变量和常量时,用{}界定变量名 ${#var} 返回变量var内容的长度 ${var:offset} 从变量var中的偏移量offset开始截取到字符串结尾的子字符串,offset从0开始 ${var:offset:length} 从变量var中的偏移量offset开始截取长度为length的子字符串 ${var#*.} 从变量var中删除第一个匹配的点(.)及其左边的所有字符 ${var##*.} 从变量var中删除最后一个匹配的点(.)及其左边的所有字符 ${var%.*} 从变量var中删除最后一个匹配的点(.)及其右边的所有字符 ${var%%.*} 从变量var中删除第一个匹配的点(.)及其右边的所有字符 示例: var=file.txt.tar.gz ${var#*.} #内容为"txt.tar.gz" ${var##*.} #内容为"gz" ${var%.*} #内容为"file.txt.tar" ${var%%.*} #内容为"file" 也可以使用其它Pattern和表达式,示例: var=/home/xxx/aaa/file.txt #假设xxx为当前用户 # 从路径中获取文件名 ${var##*/} #内容为"file.txt" # 将绝对路径转为相对路径 # whoami是获取当前用户名,使用$()执行子shell,$(whoami)将得到xxx ~${var#*$(whoami)} #内容为"~/aaa/file.txt" ${var/pattern/string} 使用string代替第一个匹配的pattern ${var//pattern/string} 使用string代替所有匹配的pattern ${var,} 首字母转小写 ${var,,} 全部转小写 ${var^} 首字母转大写 ${var^^} 全部转大写 特殊扩展变量 ${var-word} 如果变量var未赋值,则返回字符串word ${var:-word} 如果变量var未赋值或者值为空,则返回字符串word ${var+word} 如果变量var有值(包括空串""),则返回字符串word var1=foo var2= ${var1-word} # 内容为"foo" echo ${var2-word} # 内容为"" echo ${var2:-word} # 内容为"word" ${var:+word} 如果变量var有值且不为空,则返回字符串word ${var=word} 如果变量var未赋值,则返回字符串word,并为var赋值为字符串word ${var:=word} 如果变量var未赋值或者值为空串,则返回字符串word,并为var赋值为字符串word ${var?word} 如果变量var未赋值,将字符串word作为标准错误输出,否则返回变量var的值 ...

2023年12月13日

Librenms使用ldap认证用户

我们openldap中用户和组的设置 用户: ou=People,dc=ddky,dc=com #uid;#givenName;#sn;#uidNumber;#gidNumber 组: ou=group,dc=ddky,dc=com #cn;#gidNumber;#memberUID;#description 到librenms中, 172.18.31.10 cd /opt/librenms vi config.php $config['auth_mechanism'] = 'ldap'; $config['auth_ldap_server'] = '172.18.31.27'; $config['auth_ldap_port'] = 389; $config['auth_ldap_starttls'] = False; // Disable TLS on port 389 $config['auth_ldap_binddn'] = 'cn=admin,dc=ddky,dc=com'; // overrides binduser $config['auth_ldap_bindpassword'] = 'nishiwode'; $config['auth_ldap_prefix'] = 'cn='; $config['auth_ldap_suffix'] = ',ou=People,dc=ddky,dc=com'; // appended to usernames $config['auth_ldap_groupbase'] = 'ou=group,dc=ddky,dc=com'; // all groups must be inside this $config['auth_ldap_groups']['admins']['level'] = 10; // set admins group to admin level $config['auth_ldap_groups']['pfy']['level'] = 5; // set pfy group to global read only level $config['auth_ldap_groups']['support']['level'] = 1; // set support group as a normal user $config['auth_ldap_debug'] = false; // enable for verbose debug messages 说明: 我们的openldap因为是内部使用,所以无法设置证书,TLS是被禁止的。 openldap是禁止anonymous用户查询的,所以需要设置binddn和bindpassword 实际用户是cn=zhangranrui,ou=People,dc=ddky,dc=com,所以要设prefix librenms缺省用户有三个级别,10 5 1,对应的用户组是admins pfy support ...

2023年12月13日

Librenms集成进prometheus

librenms是个非常强悍的工具,对网络不清楚的可以透过这个工具,对网络环境有清晰的了解。 如何通过prometheus对librenms进行集成呢? 一、装pushgateway wget https://github.com/prometheus/pushgateway/releases/download/v1.2.0/pushgateway-1.2.0.linux-amd64.tar.gz 把pushgateway放到/usr/local/bin cat << EOF >>/etc/systemd/system/pushgateway.service [Unit] Description=Codis Exporter Wants=network-online.target After=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/pushgateway --web.listen-address=:50004 [Install] WantedBy=multi-user.target EOF systemctl daemon-relaod systemctl enable --now pushgateway.service 二、配置librenms cd /opt/librenms vi config.php $config['prometheus']['enable'] = true; $config['prometheus']['url'] = 'http://127.0.0.1:50004'; $config['prometheus']['job'] = 'librenms'; # Optional 三、配置prometheus - job_name: 'librenms' scrape_interval: 300s honor_labels: true static_configs: - targets: ['172.18.31.10:50004'] labels: sms_to: '18618197196' 首先访问prometheus,http://172.18.31.8:9090/targets 这样弄好后,再访问 http://172.18.31.10:50004/metrics 里面的东西是十分癫狂的,从交换机端口到F5,应有尽有 东西收进prometheus后,可以通过grafana对各种指标进行画图和报警

2023年12月13日

Librenms强制修改密码

librenms对密码的强度有要求,必须使用非常复杂的密码策略才能满足要求. 这就鬼畜了,想改成至少能记得住的密码。 如何强制修改呢? 首先弄一段php程序来生成加密串: <?php echo password_hash("xxxxxxxx", PASSWORD_DEFAULT); ?> 运行后得到加密的字符串: $2y$10$EUvwg5kVGXQUPBw4obdPJ.AKCSVgu8ximyyoFKW7hXed0s.sh/ud6 或者直接到下面的网站来生成: https://phppasswordhash.com/ 然后登录librenms的机器, 172.18.31.10 mysql -uroot -p use librenms; select * from users; update users set password='$2y$10$EUvwg5kVGXQUPBw4obdPJ.AKCSVgu8ximyyoFKW7hXed0s.sh/ud6' where user_id=1; 这样就强制把密码修改成自己习惯的了。

2023年12月13日

xxl-job的动态编辑并执行java脚本

数据库管理员有个特殊的需求: 需要一个msyql客户端,可以定时去连接mysql服务器执行SQL语句。且可以自己动态编辑SQL语句。 找来找去,数据库管理员对spring java这类东西吧一无所知,但是通晓SQL,这种情形XXL-JOB的EXECUTOR代位执行就比较适合。 主控地址:http://172.18.31.13/xxl-job-admin/ 使用很简单,我们在172.18.31.14装一个被控端的executor,运行模式选择GLUE(Java)模式,GLUE模式就可以随便编辑 JAVA+SQL源代码了。设置执行频率是每30分钟执行一次。 选择GLUE模式后,我们就可以在GLUE IDE里编辑代码: 代码如下: 注:在172.18.31.14上面已经装了一个MySQL服务端,有一个user库。 package com.xxl.job.service.handler; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.IJobHandler; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; public class DemoGlueJobHandler extends IJobHandler { @Override public void execute() throws Exception { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/users?characterEncoding=UTF-8&useSSL=false"); ds.setUsername("root"); ds.setPassword("xxxxxxxx"); JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(ds); List rows = jdbcTemplate.queryForList("select * from user"); Iterator it = rows.iterator(); while(it.hasNext()) { Map userMap = (Map) it.next(); XxlJobHelper.log(userMap.get("id") + "\t"); XxlJobHelper.log(userMap.get("name") + "\t"); } XxlJobHelper.log("XXL-JOB guning, Hello World."); } } 为了实现mysql客户端可以对MySQL进行读写,我们需要在xxl-job的xxl-job-executor-sample-springboot示例项目中,pom.xml中增加spring-jdbc和mysql-connector-java的jar包部分。打出一个xxl-job的executor的执行端程序。 ...

2023年12月12日

检查证书是否过期的脚本

证书会经常面临过期而没有及时续费的情况,写个脚本提醒一下自己吧: crontab -l 0 8 * * * /usr/local/bin/check_ssl.sh www.ddky.com check_ssl.sh的内容: #!/bin/bash # Print the number of days till certificate expiration # # Example: # $ check_cert.sh sleeplessbeastie.eu # 81 # $ check_cert.sh lwn.net # 630 # # Exit codes: # 0 - certificate is not expired # 1 - certificate is expired # 254 - certificate is empty # 255 - DNS resolution failed # # temporary file to store certificate certificate_file=$(mktemp) # delete temporary file on exit trap "unlink $certificate_file" EXIT if [ "$#" -eq "1" ]; then website="$1" host "$website" >&- if [ "$?" -eq "0" ]; then echo -n | openssl s_client -servername "$website" -connect "$website":443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $certificate_file certificate_size=$(stat -c "%s" $certificate_file) if [ "$certificate_size" -gt "1" ]; then date=$(openssl x509 -in $certificate_file -enddate -noout | sed "s/.*=\(.*\)/\1/") date_s=$(date -d "${date}" +%s) now_s=$(date -d now +%s) date_diff=$(( (date_s - now_s) / 86400 )) echo "$date_diff" if [ "$date_diff" -le 37 ]; then /usr/local/bin/mailsend -q -to "zhangranrui@ddky.com" -from monit@ddky.com -ssl -port 465 -auth -auth-plan -smtp smtp.exmail.qq.com -sub "证书就要到期了" -v -user "monit@ddky.com" -pass "xxxxxxxx" -cs "utf-8" -enc-type "base64" -M "$website 还有 $date_diff 天就要到期了!!!" fi if [ "$date_s" -gt "$now_s" ]; then exit 0 # ok else exit 1 # not ok fi else exit 254 fi else exit 255 fi fi

2023年12月12日

root的crontab由于root密码失效导致不能正常工作

数据库管理员的 172.18.20.10 和 172.18.20.25 数据库备份脚本是以 root 身份运行的,在 crontab 里跑: 26 11 * * * /root/scripts/mysql_backup_full_3306.sh > /dev/null 2>&1 但是由于 root 密码会每三个月变更一次,如果没有及时变更,会导致 root 密码失效,从而 crontab 无法正常运行。 解决方法很简单: 找到 /etc/pam.d/password-auth , 其中 account 的有四行 account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_permit.so 在前面增加两行: account required pam_access.so account [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_permit.so 这样就可以了,不用重启任何服务。 ...

2023年12月11日