分类 其他 下的文章

ESXi Cloud-init

vSphere环境下使用Cloud-init快速初始化虚拟机, 虚拟机环境: Debian 11.

由于vSphere作为一款商业闭源软件, 开源社区很是看不起, 造成Debian 11自带的Cloud-init版本不支持vSphere环境下Userdata解析, 先需要通过源码安装最新版Cloud-init来支持:

git clone https://github.com/cloud-init/cloud-init.git
cd cloud-init
sudo pip3 install -r requirements.txt 
sudo python3 setup.py build
sudo python3 setup.py install --init-system systemd
sudo cloud-init init --local
sudo cloud-init status

sudo ln -s /usr/local/bin/cloud-init /usr/bin/cloud-init
for svc in cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service; do
  sudo systemctl enable $svc
  sudo systemctl start  $svc
done

来源

当Cloud-init安装完毕后, 可以在虚拟机的设定内设置参数, 来将相关配置传入虚拟机, 以供初始化使用:

非网络相关:

  • guestinfo.userdata
  • guestinfo.userdata.encoding

网络相关:

  • guestinfo.metadata
  • guestinfo.metadata.encoding

Cloud-init配置文件:

#cloud-config

# note that "#cloud-config" must be very first line for everything to work

# guestinfo.userdata: cat cloudinit.yml | base64 | pbcopy
# guestinfo.userdata.encoding: base64

# networking
# this one should be added to:
# guestinfo.metadata:
# guestinfo.metadata.encoding
# ----------

network:
  version: 2
  ethernets:
    ens192:
      addresses:
        - 192.168.0.186/24
      gateway4: 192.168.0.1
      dhcp4: false
      dhcp6: false
      nameservers:
        addresses: [192.168.0.5]

preserve_hostname: false
prefer_fqdn_over_hostname: false
hostname: example
manage_etc_hosts: true

timezone: Asia/Shanghai

disable_root: false

package_update: true
package_upgrade: true
package_reboot_if_required: true

packages:
  - gcc
  - htop
  - telnet
  - mtr
  - curl
  - wget
  - nload
  - iftop
  - screen

来源

当Cloud-init配置完一次后, 如果下次开机还想再让Cloud-init重新配置一次的话可以执行命令:

cloud-init clean

Caddy TLS兼容

tls {
    protocols tls1.2 tls1.3
    ciphers ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-AES256-CBC-SHA ECDHE-RSA-AES128-CBC-SHA ECDHE-ECDSA-AES256-CBC-SHA ECDHE-ECDSA-AES128-CBC-SHA RSA-AES256-CBC-SHA RSA-AES128-CBC-SHA ECDHE-RSA-3DES-EDE-CBC-SHA RSA-3DES-EDE-CBC-SHA
}

利用VMware OVF文件快速部署CentOS7

当新项目上线和测试时候免不了要创建一堆容器或者虚拟机. 然而创建的虚拟机过程很长步骤需要手动人工介入操作很繁琐. 所以VMware有个基于OVF文件来快速部署的功能. 当创建OVF文件时候可以指定OVF内文件的配置文件以供虚拟机来读取做相应自动配置.

目前我们想创建一个基于CentOS7的OVF快速部署文件:

  1. 已标准方式安装CentOS7并安装好VMTools以及使用yum update更新下系统包以及内核.

  2. 在虚拟机vApp options选项卡中勾选Enable vApp options以供可以自定义配置文件项.

    EA3267EC-D270-4889-B37C-8B3413BF7888.png

    同时勾选OVF settings内的OVF environment transport / VMware Tools

    1962D7DA-D549-4C2C-B19A-E7A9A79AB00E.png

  3. 创建OVF自定义配置文件项:

    2D8039BF-E6BB-4239-8B10-B977F12688F6.png

    此时在虚拟机内已经可以通过vmtoolsd --cmd "info-get guestinfo.ovfenv"来获取配置项的值了

    <?xml version="1.0" encoding="UTF-8"?>
    <Environment
         xmlns="http://schemas.dmtf.org/ovf/environment/1"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
         xmlns:ve="http://www.vmware.com/schema/ovfenv"
         oe:id=""
         ve:vCenterId="vm-52">
       <PlatformSection>
          <Kind>VMware ESXi</Kind>
          <Version>6.7.0</Version>
          <Vendor>VMware, Inc.</Vendor>
          <Locale>en</Locale>
       </PlatformSection>
       <PropertySection>
             <Property oe:key="dns1" oe:value=""/>
             <Property oe:key="dns2" oe:value=""/>
             <Property oe:key="gateway" oe:value=""/>
             <Property oe:key="hostname" oe:value=""/>
             <Property oe:key="ip" oe:value=""/>
             <Property oe:key="netmask" oe:value=""/>
       </PropertySection>
       <ve:EthernetAdapterSection>
          <ve:Adapter ve:mac="00:50:56:ab:0d:7e" ve:network="VM Network" ve:unitNumber="7"/>
       </ve:EthernetAdapterSection>
    </Environment>
    
  4. 编写脚本在虚拟机克隆后第一次开机时自动按照给定的配置完成分配IP等操作

  5. 清理环境:

    1. 为了清理环境我们先需要停止日志服务避免操作的时候再次污染环境:

      service auditd stop
      service rsyslog stop
      
    2. 清理yum update留下的老版本内核:

      yum install yum-utils -y
      package-cleanup --oldkernels --count=1
      
    3. 清理yum留下的缓存数据:

      yum clean all && rm -rf /var/cache/yum
      
    4. 删除已经留存的日志:

      /usr/sbin/logrotate -f /etc/logrotate.conf 
      rm -f /var/log/*-???????? /var/log/*.gz 
      rm -f /var/log/dmesg.old 
      rm -rf /var/log/anaconda
      cat /dev/null > /var/log/audit/audit.log 
      cat /dev/null > /var/log/wtmp 
      cat /dev/null > /var/log/lastlog 
      cat /dev/null > /var/log/grubby
      
    5. 删除设备文件:

      rm -f /etc/udev/rules.d/70*
      sed -i '/^(HWADDR|UUID)=/d' /etc/sysconfig/network-scripts/ifcfg-e*
      
    6. 清理/tmp目录

      rm -rf /tmp/* 
      rm -rf /var/tmp/*
      
    7. 清理SSH密钥

      rm -f /etc/ssh/*key*
      rm -rf ~root/.ssh/ 
      rm -f ~root/anaconda-ks.cfg
      
    8. 清理命令历史

      rm -f ~root/.bash_history 
      unset HISTFILE
      history -c
      sys-unconfig
      
    9. 此时系统会自动关闭已经可以将虚拟机转换成模板进行克隆部署或导出为OVF通过OVF来部署.

DP Edit Distance

Edit Distance使用DP解决可以大幅度提高计算性能在对比递归解决情况下.

function editDistance(str1: string, str2: string): number {

    var str1len: number = str1.length;
    var str2len: number = str2.length;

    if (str1len === 0) return str2len;
    if (str2len === 0) return str1len;

    var matrix: Array<Array<number>> = []

    matrix[0] = new Array(str1len + 1);

    for (let i = 0; i <= str1len; i++) {
        matrix[0][i] = i;
    }

    for (let i = 1; i <= str2len; i++) {
        matrix[i] = Array(str1len + 1);
        matrix[i].fill(0);
        matrix[i][0] = i;
    }

    for (let i = 1; i <= str2len; i++) {
        const yChar: string = str2[i - 1];
        for (let j = 1; j <= str1len; j++) {
            const xChar: string = str1[j - 1];
            const a: number = matrix[i - 1][j] + 1;
            const b: number = matrix[i][j - 1] + 1;
            const c: number = matrix[i - 1][j - 1] + (yChar === xChar ? 0 : 1);
            matrix[i][j] = Math.min(a, b, c);
        }
    }

    printMatrix(matrix);

    return matrix[str2len][str1len];
}

function printMatrix(matrix: Array<Array<number>>) {
    for (let i = 0; i < matrix.length; i++) {
        process.stdout.write("[ ");
        for (let j = 0; j < matrix[i].length; j++) {
            process.stdout.write(`${matrix[i][j]} `);
        }
        process.stdout.write("]\n");
    }
}

console.log("edit distance:", editDistance("GCTATAC", "GCGTATGC"));

Edit distance核心在于:

const a: number = matrix[i - 1][j] + 1;
const b: number = matrix[i][j - 1] + 1;
const c: number = matrix[i - 1][j - 1] + (yChar === xChar ? 0 : 1);

6F82A156-5490-4F81-8B3E-E1BFFB0A5B9E.png

参考:
Using dynamic programming for edit distance