0%

虚拟机扩容

第一步、PVE扩容

进入pve后台

服务器视图->对应的服务器->硬盘->Disk Action

image-20221118173140832

选择需要扩容的大小

image-20221118155056000

重启后进入系统

第二步、分配空间

执行fdisk -l

image-20221118164904032

看到磁盘已经扩容,但是分区没有变化,需要分配新增的磁盘大小到分区上

执行parted /dev/sda

image-20221118165431829

resizepart 2 100%是把剩余空间全部分配

第三步、更新物理卷

image-20221118165619867

pvresize /dev/sda2

第四步、更新逻辑卷

1
lvresize --extents +100%FREE --resizefs /dev/mapper/centos-root

一、Docker

需要安装Docker plugin、Docker pipeline plugin
1、系统管理->全局工具配置->Docker,安装对应的docker版本
2、系统管理->节点管理->配置集群
3、需要挂载/.docker文件夹到Jenkins服务上,默认没有root权限生成不到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stage('镜像打包') {
steps {
script {
sh """
# 这里可以切换到指定目录执行
cd ${WORKSPACE}/dist
"""

docker.withServer('tcp://<IP>:<PORT>', '') {
def customImage = docker.build("<JOBNAME>:${env.BUILD_ID}")
docker.withRegistry('http://<IP>:<PORT>/<PROJECT>/', 'harbor') {
customImage.push()
}
}
}
}
}

部署

一、准备机器

master1
router1
node1
node2
master 主要作为控制机器,並不属于openshift,主要用来跑ansible,可以使用上面的任何一台机器替代

如果本地安装的centos,需要配置网络,网卡名字可能不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 编辑网卡配置文件
vi /etc/sysconfig/network-scripts/ifcfg-eth0

# 配置内容
ONBOOT=yes
BOOTPROTO=none
# 下面配置根据实际情况配置
IPADDR=192.168.242.140
PREFIX=16
GATEWAY=192.168.1.3
DNS1=192.168.1.3

# 重启网卡
service network restart

二、配置yum

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 取消快速查找插件,修改plugins=1为plugins=0
vi /etc/yum.conf

yum update

# 备份所有源
cp -rp /etc/yum.repos.d/ /etc/yum.repos.d.bak/

# 删除所有源
rm -rf /etc/yum.repos.d/*

# 新增阿里云源,配置文件如下
vi all.repo

# 更新
yum clean all
yum makecache

all.repo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[base]
name=CentOS-$releasever - Base
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
gpgcheck=0

[updates]
name=CentOS-$releasever - Updates
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
gpgcheck=0

[extras]
name=CentOS-$releasever - Extras
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
gpgcheck=0

[openshift]
name=Openshift
baseurl=http://mirrors.aliyun.com/centos/$releasever/paas/$basearch/openshift-origin311/
gpgcheck=0

[epel]
name=Centos EPEL
baseurl=http://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck=0

三、安装ansible

在master机器上进行

1
2
3
curl https://releases.ansible.com/ansible/rpm/release/epel-7-x86_64/ansible-2.6.8-1.el7.ans.noarch.rpm -O
yum install ansible-2.6.8-1.el7.ans.noarch.rpm
yum install httpd-tools java-1.8.0-openjdk-headless python-passlib pyOpenSSL

四、配置hosts和免密登录

在master机器上进行

1、配置master的hosts文件

1
2
3
4
5
192.168.242.140 master
192.168.242.141 master1
192.168.242.142 router1
192.168.242.143 node1
192.168.242.144 node2

2、配置免密登录

1
2
3
4
5
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub master1
ssh-copy-id -i ~/.ssh/id_rsa.pub router1
ssh-copy-id -i ~/.ssh/id_rsa.pub node1
ssh-copy-id -i ~/.ssh/id_rsa.pub node2

五、准备inventory

更多详细参数请参考官方文档:https://access.redhat.com/documentation/zh-cn/openshift_container_platform/3.11/html/installing_clusters/multiple-masters

vi /etc/ansible/hosts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[OSEv3:children]
masters
nodes
etcd

[OSEv3:vars]
ansible_ssh_user=root
openshift_deployment_type=origin
#openshift_release="3.11"
openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]

openshift_public_hostname=okd.yuako.dev
openshift_master_default_subdomain=yuako.dev
openshift_ca_cert_expire_days=3650
openshift_node_cert_expire_days=3650
openshift_master_cert_expire_days=3650
etcd_ca_default_days=3650

#openshift_hosted_manage_registry=false
openshift_disable_check=memory_availability,disk_availability,docker_image_availability,docker_storage
#openshift_enable_service_catalog=false
#template_service_broker_install=false
#ansible_service_broker_install=false
#osn_storage_plugin_deps=[]
#openshift_enable_service_catalog=false
#openshift_cluster_monitoring_operator_install=false

[masters]
master1

[etcd]
master1

[nodes]
master1 openshift_node_group_name='node-config-master'
node1 openshift_node_group_name='node-config-compute'
node2 openshift_node_group_name='node-config-compute'
router1 openshift_node_group_name='node-config-infra'

六、安装

主机名:

1
ansible all -m shell -a "hostnamectl set-hostname --static {{ inventory_hostname }}"

YUM:

1
2
3
4
cp /etc/yum.repos.d/all.repo /tmp/
ansible all -m shell -a "rm -rf /etc/yum.repos.d/*"
ansible all -m shell -a 'sed -i "s/plugins=1/plugins=0/g" /etc/yum.conf'
ansible all -m copy -a "src=/tmp/all.repo dest=/etc/yum.repos.d/all.repo"

/etc/hosts:

1
ansible all -m copy -a 'src=/etc/hosts dest=/etc/hosts'

集群节点selinux设置(需要重启生效)

1
2
ansible all -m shell -a 'sed -i "s/^SELINUX=disabled/SELINUX=permissive/g" /etc/selinux/config'
ansible all -m shell -a 'reboot'

下载安装程序,https://github.com/openshift/openshift-ansible/tags,选择一个最新的3.11版本下载,解压。
禁用集群安装默认的repos源

1
2
cd openshift-ansible-release-3.11
sed -i "s/^enabled=1/enabled=0/g" roles/openshift_repos/templates/CentOS-OpenShift-Origin311.repo.j2

安装

1
2
ansible-playbook ~/openshift-ansible/playbooks/prerequisites.yml
ansible-playbook ~/openshift-ansible/playbooks/deploy_cluster.yml

卸载

1
ansible-playbook ~/openshift-ansible/playbooks/adhoc/uninstall.yml

七、创建管理员用户和密码

1
2
ansible masters -m shell -a 'htpasswd -b /etc/origin/master/htpasswd admin admin'
ansible masters -m shell -a 'oc adm policy add-cluster-role-to-user cluster-admin admin'

即可用admin/admin登录

八、常见问题

1、Privileged containers are not allowed spec.initContainers[1].securityContext.privileged: Invalid value: true

权限问题,-n后面是namespace也就是project

1
oc adm policy add-scc-to-user privileged -z default -n efk

2、Error: EACCES: permission denied, mkdir

权限问题,没有写入到指定目录权限

  • 配置私有存储,指定分配路径
  • 直接分配权限(生产环境不建议)
1
oc adm policy add-scc-to-user anyuid -z default

安裝

brew安装

1
2
3
4
5
# 安装
brew install ansible

# 建立默认hosts文件
sudo mkdir /etc/ansible && sudo touch /etc/ansible/hosts

yum安装

1
2
3
4
5
# 添加EPEL源
yum -y install epel-release

# 安装
yum install ansible -y

配置

1
vi /etc/ansible/ansible.cfg
1
2
3
host_key_checking=False
log_path=/var/log/ansible.log
module_name=command
1
2
3
4
5
# 配置的主机需要配置免密登录
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@{ip}

vi /etc/ansible/hosts
1
2
3
4
5
6
7
# 单个主机
192.168.5.10

# 主机组
[openshift]
192.168.5.11
192.168.5.12

ansible命令

ansible命令又被称为ad-hoc命令,他主要是用来快速在多个远程机器Hosts上执行单个任务(task)

列出所有主机

ansible all --list-hosts

ping

默认用户是当前机器的用户
ansible all -m ping

指定用户
ansible all -m ping -u root

执行shell指令

下面是执行了ls命令

ansible all -m shell -a ls

复制文件到主机

ansible -i /etc/ansible/hosts test -m copy -a "src=/tmp/ansible.tar.gz dest=/home/root/ owner=root group=root mode=0777"

解压文件

ansible -i test -m unarchive -a 'src=/etc/bin/ansible.tar.gz dest=/usr/local copy=no mode=0755'

ansible -i /etc/ansible/hosts test -m shell "tar -zxvf /etc/bin/ansible.tar.gz -C /usr/local"

批量杀掉进程

ansible test -m shell -a "ps -ef | grep zabbix |grep -v grep |awk '{print \$2}' | xargs kill -9"

设置cron

ansible all -m cron -a 'name="custom job" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate 172.16.254.139"'

建立组

ansible all -m group -a 'gid=2017 name=a'

建立用户

ansible all -m user -a 'name=aaa groups=aaa state=present'

删除用户

ansible all -m user -a 'name=aaa groups=aaa remove=yes'

在节点上安装httpd

ansible all -m yum -a "state=present name=httpd"

在节点上启动服务,并开机自启动

ansible all -m service -a 'name=httpd state=started enabled=yes'

执行远程命令

ansible all -m command -a 'uptime'

执行主控端脚本

ansible all -m script -a '/root/test.sh'

执行远程主机的脚本

ansible all -m shell -a 'ps aux|grep zabbix'

类似shell

ansible all -m raw -a "ps aux|grep zabbix|awk '{print $2}'"

创建软链接

ansible all -m file -a "src=/etc/resolv.conf dest=/tmp/resolv.conf state=link"

删除软链接

ansible all -m file -a "path=/tmp/resolv.conf state=absent"

复制文件到远程服务器

ansible all -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0644"

在节点上运行hostname

ansible all -m raw -a 'hostname|tee'

将指定url上的文件下载到/tmp下

ansible all -m get_url -a 'url=http://10.1.1.116/favicon.ico dest=/tmp'

帮助

ansible --help

ansible-playbook命令

ansible-playbook主要用来执行ansible的playbook。他可以用来在多个远程机器Hosts上执行一个或多个任务(task),这个命令执行时可以指定一个或多个playbook的名字。

ansible-playbook playbook.yml [options]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-u REMOTE_USER, --user=REMOTE_USER # ssh 连接的用户名 
-k, --ask-pass #ssh登录认证密码
-s, --sudo #sudo 到root用户,相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER #sudo 到对应的用户
-K, --ask-sudo-pass #用户的密码(—sudo时使用)
-T TIMEOUT, --timeout=TIMEOUT # ssh 连接超时,默认 10 秒
-C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
-e EXTRA_VARS, --extra-vars=EXTRA_VARS # 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e
-f FORKS, --forks=FORKS # 进程并发处理,默认 5
-i INVENTORY, --inventory-file=INVENTORY # 指定 hosts 文件路径,默认 default=/etc/ansible/hosts
-l SUBSET, --limit=SUBSET # 指定一个 pattern,对- hosts:匹配到的主机再过滤一次
--list-hosts # 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook
--list-tasks # 列出该 playbook 中会被执行的 task
--private-key=PRIVATE_KEY_FILE # 私钥路径
--step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍
--syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook
-t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔
--skip-tags=SKIP_TAGS # 当 play 和 task 的 tag 不匹配该参数指定的值时,才执行
-v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。

ansible-config

这个命令主要用来初始化或者查看当前机器ansible的配置信息

ansible-config [-h] [-version] [-v] {list,dump,view,init}

ansible-inventory

该命令主要用于显示或者导出ansible配置好的Inventory

ansible-inventory {--list/--host/--graph}

ansible-doc

该命令主要用于通过获取当前安装的plugin的一些api

ansible-doc [plugin [plugin ...]]

刪除admin賬號,並插入默認的admin

1
2
delete from ofUser where username='admin';
INSERT INTO ofUser (username, plainPassword, name, email, creationDate, modificationDate) VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');

修改openfire配置文件,重新配置openfire
vi /opt/openfire/conf/openfire.xml
setup->false

重啟openfire服務
systemctl restart openfire

下载和安装

下载地址:
https://download.liquibase.org/

1
liquibase --driver=com.mysql.cj.jdbc.Driver --classpath=~/development/lib/mysql-connector-java-8.0.30.jar --changeLogFile=./init-table.xml --url="jdbc:mysql://localhost:3306/yudb" --username=root generateChangeLog

配置

新建tomcat配置文件

1
vi /etc/logrotate.d/tomcat

配置文件内容如下

1
2
3
4
5
6
7
8
9
/usr/local/tomcat/logs/catalina.out {
daily
rotate 5
missingok
dateext
compress
notifempty
copytruncate
}

参数详解:

  • daily 指定转储周期为每天
  • rotate 5 指定日志文件删除之前转储的次数,0指没有备份,5指保留5个备份
  • missingok 如果日志不存在则忽略该警告信息
  • dateext 文件后缀是日期格式,也就是切割后文件是:xxx.log-20150828.gz
  • compress 通过gzip压缩转储以后的日志(gzip -d xxx.gz解压)
  • notifempty 如果是空文件的话,不转储
  • copytruncate 用于还在打开中的日志文件,把当前日志备份并截断

立即截断日志

1
logrotate --force /etc/logrotate.d/tomcat

一、设置单个容器的日志大小

1、通过运行时参数配置日志大小

1
docker run -d --log-driver json-file --log-opt max-size=1g nginx

2、通过docker-compose配置文件限制

1
2
3
4
5
6
7
nginx: 
image: nginx:latest
restart: always
logging:
driver: "json-file"
options:
max-size: "1g"

二、全局设置所有容器的日志大小

修改docker默认配置文件

1
vi /etc/docker/daemon.json

将配置文件内容改成如下,增加log-driver和log-opts配置项

1
2
3
4
5
6
7
8
9
10
{
"registry-mirrors": [
"https://registry.docker-cn.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}

重新加载配置和重启docker

1
2
systemctl daemon-reload
systemctl restart docker

三、开启远程访问(非安全方式)

1
2
3
4
5
6
7
vi /usr/lib/systemd/system/docker.service

# 主要增加-H参数
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375

systemctl daemon-reload
systemctl restart docker

四、开启远程访问(安全方式)

https://docs.docker.com/engine/security/protect-access/#create-a-ca-server-and-client-keys-with-openss

一、缓存穿透

  • 数据库和缓存中都没有数据,用户每次查询都查询数据库但是没法写入到缓存
  • 查询的KEY不存在,例如id:-1

解决方法:

  • 过滤不正常的参数key
  • 将查询空的结果设置短时间的key-null缓存

二、缓存击穿

  • 数据库中有数据,但是缓存没有,首次请求或者是缓存的KEY过期

解决方法:

  • 限流、熔断、降级
  • key不过期(注意使用)
  • 佈隆过滤器,快速查询key是否存在
  • 互斥锁(常用)

三、缓存雪崩

  • 缓存中大批量数据过期

解决方法:

  • 缓存数据随机时间
  • 分散缓存到不同缓存系统
  • key不过期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* @param key 缓存的key
* @param loader lambda方法,通过这个方法获取数据
*/
public T get(String key, Callable<? extends T> loader) {
String cache = redisHelper.get(key);
if (StringUtils.isNotBlank(cache)) {
if ("null".equals(cache)) {
return null;
}
return JSONObject.parseObject(cache, this.entityClass);
}
String lockKey = "lock:" + key;
String lockVal = String.valueOf(RandomUtils.nextInt(1000, 9999));
//通过加锁防止击穿
if (redisHelper.lock(lockKey, lockVal, 3, TimeUnit.SECONDS)) {
// 通过回调方式调用获取数据
T entity = loader.call();
if (entity != null) {
redisHelper.set(key, JsonHelper.toJson(entity), RandomUtils.nextInt(3600, 7200));
} else {
//防止缓存穿透
redisHelper.set(key, "null", 10);
}
redisHelper.unlock(lockKey, lockVal);
return entity;
} else {
TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(100, 200));
return this.get(key, loader);
}
return null;
}