Kubernetes集群的学习笔记(1)
Kubernetes基础知识及笔记。
概念定义容器的出现以及容器编排引擎出现的原因。
容器编排工具容器最早的模型时LXC+Linux Namespace。容器的出现导致了我们需要对容器进行管理,单机的管理不能满足业务的需要,于是快速衍生出了多种不同的容器编排工具。Docker提供的工具:
docker compose
docker swarm
docker machine
IDC的操作系统:
mesos(资源分配工具), marathron(面向容器编排的框架)
Google的工具:
Kubernetes
当一个产品可以占据35%以上的份额就已属于自然垄断。k8s现在已经处于垄断地位。透过容器所产生的衍生概念有: DevOps, MicroServices, BlockChain.开发模式的开发:瀑布模型,进化到了敏捷开发,精益开发,到现在的DevOps.发布线上的做法:蓝绿部署,灰度部署,金丝雀(canary)DevOps几个简单的名词解释:
CI: 持续集成 - 持续集成通俗一些就是快速提交代码,快速变更需求,快速合并代码。
CD: 持续部署 - 持续部署是指在代码提交变更之后,快速进行部署及测试;传统的代码在提交后需要运维人员手动部署,持续部署其实就是缩短的部署所需要的步骤和周期,尽可能将部署操作交由自动化完成。
CD: 持续交付 - 让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以发布的状态。
有时候,持续交付也与持续部署混淆。持续部署意味着所有的变更都会被自动部署到生产环境中。持续交付意味着所有的变更都可以被部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。
云原生的概念Native Cloud Application To Wikipedia.
A native cloud application (NCA) is a type of computer software that natively utilizes services and infrastructure from cloud computing providers.
例如:当容器中的nginx需要变更项目文件的时候,容器的环境已经决定了不太容易对项目的变更,早期的程序设计使用配置文件进行定义。因此,最好的办法是可以通过传递宿主机环境变量的方式对镜像进行设置,当项目有变更的时候直接通过读取环境变量的方式对容器内项目的数据进行配置和更改。基于这种思路设计出来的容器或者软件,叫做云原生应用(Native Cloud Application)。
K8s的前世k8s本来开始是Google内部的Brog系统,Google在Docker被发现了之后,快速的使用Go语言重写了Brog系统,借鉴了Brog的逻辑和设计,所有的代码进行了全面的重构。
Kubernetes项目的Github页面
K8s的特点
自动装箱
自我修复
水平扩展
服务发现与负载均衡
自动发布和回滚
密钥的配置和管理 – 将配置定义在k8s的对象中,通过k8s在容器启动的时候自动传递环境变量到容器中。
存储编排 – 可自动创建存储卷供容器需要的自动管理及使用
批量处理执行
K8s的工作流程及逻辑
Kubernetes组合多台主机的资源,整合成资源池,并统一对外提供计算、存储等能力的集群。k8s的集群是Master\Node模型,具有角色分类,需要部署master节点及node节点。master节点一般有三个,node节点理论上可以无限增加。
k8s的简要工作流程: 收到请求后,Master节点上的Scheduler用来收集所有Node上的可用资源信息,并通过API Server告知资源充足的Node启动相关的容器;Node收到请求会查找需要的镜像,如果本地不存在从Docker Registery上面拉取相应的镜像进行所请求容器的启动。
k8s可将 Master节点 + Node节点 + Registery节点 同时托管在k8s自身的环境中,也就是直接托管在docker虚拟化层上,因此我们可以通过kubeadm等相关的工具将所有的组件使用容器的方式进行管理和调度。
Master上的主要组件及服务
API Server # 负责提供对外的及对内的服务接口
Scheduler # 选出适合部署容器的node节点,两级筛选:选出所有可以使用的node,在所有合规的node上进行最优选择,选择取决于调度算法。
Controller-Manager # 检测容器的状态,如果出现异常或不符合定义的状态,就向API申请重新部署相关容器。
Node上的主要服务及组件
Kube-Proxy
容器引擎,docker
Kubelet
Flannel
逻辑组件:PodNode上可以运行及调度逻辑单元pod,pod是k8s的一个逻辑概念,真实运行起来的还是Container,只是k8s为了方便管理,将一个或多个Container封装了成了逻辑上的Pod,打上了相应的标签,使得可以通过Seletor对不同的Pod进行分类管理和选择。Pod是模拟了传统的虚拟机模式(相同主机上的Pod可以使用宿主机的lo进行网络通信),使得可以构建精细的模型。
一个pod中可以有多个容器,共享底层名称空间net,UTS,IPC,另外三个互相隔离user,mnt,pid.
Sidecar的概念一般来讲,一个Pod只放入一个容器,如果我们需要放置多个容器,一般为一个主要的一个辅助的,辅助的叫做 sidecar.例如主程序运行在一个容器中,收集日志的程序放在sidecar中。
Pod的标签选择Pod已经被附加了一些元数据,创建完成的Pod可以通过标签的数值直接识别Pod的类别。k8s使用标签选择器selector来过滤符合条件的资源。所有的对象都可以通过标签选择器进行选择。
Pod的不完全分类
自主式pod # 自行控制自己的生命周期
控制器管理的pod # 通过管理器可管理生命周期的pod
k8s使用的pod的控制器
ReplicationController - 最早提供的组件,支持滚动更新和回滚,最早只有一个。现在已经不再使用。
ReplicaSet - 新的工具替代了原始的控制器,但是不直接使用,直接使用的是Deployment来管理无状态的pod。
StatefulSet - 对有状态的Pod进行管理。
DaemonSet - 控制容器的进程为守护进程的控制器,每个Node上都会运行一个,无法指定副本的数量。一般用于信息和日志的收集。
Job, Cronjob - 作业管理, 周期性作业管理。
HPA - HorizontalPodAutoscaler
服务发现的概念为了能快速管理新启动的pod,在pod和用户之间添加了逻辑的中间层,pod启动后需要在service中注册自己的信息,客户端需要相关的服务的时候从service取得相关的信息,完成服务的管理。service是逻辑组件,通过iptables的DNAT来实现相关的service的功能。
其实服务发现相当于消息中间件,有Pods(生产者)来注册,有用户(消费者)来消费,只是不会被消费掉。
Kube-proxy的作用一旦发现了service的改变,反映到Iptables上,同时向API Server报告。
Kubernetes的安装部署通过kubeadm工具进行安装及部署,部署的过程其实不复杂,只是镜像的拉取麻烦了一些,记录了一些简单的步骤和问题。安装的时候启动了三个虚拟机,一台虚拟机作为Master节点,其他的两台作为Node节点,所有的机器都需要关闭firewalld,k8s会默认托管iptables的相关规则。安装采用k8s自托管的方式,结构如下,列出了在每个节点上必须运行的服务和容器:
master
Node1
Node2
Kubelet
Kubelet
Kubelet
Pause
Pause
Pause
Flannel
Flannel
Flannel
Kube-Proxy
Kube-Proxy
Kube-Proxy
API Server
Schedular
Controller-manager
Coredns
etcd
机器的信息如下:
IP-ADDRESS
HOSTNAME
ROLES
192.168.229.144
master.docker
master
192.168.229.145
node1.docker
node
192.168.229.146
node2.docker
node
安装基础环境这里记录一下所有机器都需要安装的环境及软件。
编辑hostname vim /etc/hostname
关闭firewalld systemctl mask firewalld
关闭selinux sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
关闭Swap分区, 注释掉swap的相关行,或者在安装的时候默认不分区即可。 vim /etc/fstab
配置docker-ce,kubernetes相关软件源,从阿里云直接配置到本地的机器上。 # kubernetes部分
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# docker -ce部分
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
同步镜像仓库,从docker-ce源安装docker-ce/docker-cli/containerd;其实可以关闭gpgcheck,并将其他同步失败的源关闭即可,我自己只是为了做学习用途,关闭了fedora的update源,总是同步失败耽误我的时间。 dnf makecache -y && \
dnf install -y docker-ce docker-cli containerd && \
systemctl start docker && \
systemctl enable docker
从kubernetes源安装kubeadm\kubectl\kubernetes-cni\kubelet四个组件。 dnf install - y kubeadm kubectl kubelet kubernetes-cni && \
systemctl start kubelet && \
systemctl enable kubelet
四个组件的用途分别是:
kubeadm 用来进行所有节点的部署及初始化。
kubectl 集群的cli接口。
kubelet 每个Node节点都会启动kubelet进程,用来处理Master节点下发到本节点的任务,管理Pod和其中的容器。kubelet会在API Server上注册节点信息,定期向Mast ...
面试记录
这个月还是发生了不少事情了,面试,换房子,真快。
面试题
有一个字符串s=“kjdfdsfevsdf”,使用python单独输出每个字符并在后面加上”th”.
s = "asdfaurhgauh"
for i in s:
print(i+'th')
数据库问题,增删改查。基本上都没答上来。select语句对数据库内容Where做一个筛选。
提取b.txt中的所有域名,awk我写的grep。
grep -E -o "www.[[:alpha:]]*.com" ./b.txt | sort | uniq -c | sort -nr
awk -F / '{print $3}' b.txt | sort | uniq -c | sort -nr
我写的这个唯一个不好的地方就是不能匹配数字的部分,如果域名有数字就提取不出了。其实中间如果全部用正则也可以,但是正则会特别的长。
nginx的反向代理配置文件是不是能看懂,考了一个upstream模块,考了一个weight的分配,考了一个 proxy_pass模块的调用。
描述Raid0 , 1 ,5的区别,但是没让说raid10。
描述如果你有多的资源如何搭建高可用和高并发,这种题目其实还挺无聊的,高并发靠负载均衡分流,四层转发七层代理。高可用靠的冗余和故障的快速切换。没什么特别的架构,web服务也就是keepalived + lvs。硬件的话F5直接搞,虽然我没见过,但是也听说过。
容器问了一个私有的register,不记得叫什么名字,但是我知道Docker官方有文档。软件名称是Harbor
k8s没什么可说了,昨天晚上听了一堆的k8s的理论,一个集群简单而要三个网络,要不是设计思路清晰,网络就已经是一锅粥了。软件的架构真的是越来越复杂了,现在的网络里面不是桥桥桥,就是NAT转换。
查看Linux系统CPU,MEM,NET-IO,DISK-IO的命令。top | htop | free -m | iostat -a
ext4如果分区超过2T如何操作。这题估计本来是问Ext3文件系统的,改的。Ext4随便分了已经。
如何理解top命令中的load average的含义 这个问题本来是聊到了服务器性能的观察,我说到了top命令查看系统的当前状况,所以后续有了这个问题,其实在系统中,这三个数值的计算方式是通过CPU进程队列的长度来进行计算的,具体的数值及计算公式网上有很多,等我不记得了我在去找资料吧,这种东西已经是死知识了,到处都是。 我说说我的理解,这三个数值其实是system load average,是系统的负载状态,其实是描述了系统的压力变化趋势,计算的CPU参数主要是Running Process & uninterreptable Process , 其实就是正在运行和不可中断运行的进程,这些是CPU的工作量。还有一个衡量的参数实际上是IO,IO的指标也会体现在三个不同时间点的计算中。 如何查看或者分析是我一直理解的不透彻的点,记录一下。单项指标的观察不足以解决系统的问题,需要搭配其他的工具进行分析才可以。 看三个参数的变化趋势,1,5,15三个时间点:
如果1分钟高,但是后面两个都低,说明系统当前的状态是压力高的,但是是暂时的。
如果是三个数值都高,可以说明可能是系统的性能不足或者有问题需要解决。
如果1分钟的数值低,但是15分钟的数值高,说明系统的压力会慢慢平稳下来,不会持续太久。
ps命令的使用
ps aux
To see every process on the system using BSD syntax USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 186736 10160 ? Ss 09:32 0:03 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:32 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 09:32 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 09:32 0:00 [rcu_par_gp]
root 6 0.0 0.0 0 0 ? I< 09:32 0:00 [kworker/0:0H-kblockd]
root 8 0.0 0.0 0 0 ? I< 09:32 0:00 [mm_percpu_wq]
root 9 0.0 0.0 0 0 ? S 09:32 0:00 [ksoftirqd/0]
root 10 0.0 0.0 0 0 ? I 09:32 0:00 [rcu_preempt]
root 11 0.0 0.0 0 0 ? I 09:32 0:00 [rcu_sched]
root 12 0.0 0.0 0 0 ? I 09:32 0:00 [rcu_bh]
ps axjf / ps -ejH
To print a process tree PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 555 555 555 ? -1 Ssl 0 0:00 /usr/bin/gdm
555 585 555 555 ? -1 Sl 0 0:00 \_ gdm-session-worker [pam/gdm-launch-environment]
585 789 789 789 tty1 789 Ssl+ 120 0:00 | \_ /usr/lib/gdm-x-session gnome-session --autostart /usr/share/gdm/g
789 791 789 789 tty1 789 Sl+ 120 0:01 | \_ /usr/lib/Xorg vt1 -displayfd 3 -auth /run/user/120/gdm/Xautho
791 848 789 789 tty1 789 S+ 0 0:00 | | \_ xf86-video-intel-backlight-helper intel_backlight
789 939 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gnome-session-binary --autostart /usr/share/gdm/gree
939 970 789 789 tty1 789 Sl+ 120 0:04 | \_ /usr/bin/gnome-shell
970 1032 1032 789 tty1 789 Sl 120 0:00 | | \_ ibus-daemon --xim --panel disable
1032 1035 1032 789 tty1 789 Sl 120 0:00 | | \_ /usr/lib/ibus/ibus-dconf
1032 1200 1032 789 tty1 789 Sl 120 0:00 | | \_ /usr/lib/ibus/ibus-engine-simple
939 1086 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-rfkill
939 1088 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-smartcard
939 1089 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-clipboard
939 1090 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-xsettings
939 1091 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-housekeeping
939 1092 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-mouse
939 1093 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-power
939 1094 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-screensaver-proxy
939 1095 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-sound
939 1099 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/lib/gsd-color
939 1101 789 789 tty1 789 Sl+ 120 0:00 | \_ /usr/ ...
Nginx反向代理笔记
Nginx的反向代理笔记。
Nginx程序的主要功能
load configuration
launch workers
non-stop upgrade
可以使用epoll单进程响应多个用户请求,如果是BSD可以使用kevent时间驱动模式响应。磁盘一侧使用的是高级IO中的sendfile机制,AIO异步IO,以及内存映射机制来完成硬盘IO的高级特性。
Nginx官方文档及参数说明在这里: nginx documentation
SNAT && DNAT主要是工作在三层/四层的协议SNAT主要的功能是隐藏客户端,DNAT对服务器接受并转发请求。NAT功能无法触及7层协议的上面三层,所以无权控制上面的数据包内容,所以NAT不能对应用层的内容作出更改及缓存。只能对网络的内容及数据包进行直接的转发以及控制。
正向代理 && 反向代理正向代理是通过代理服务器对客户端发出的请求进行全部修改及转发;反向代理是通过代理服务器对发送到服务器的请求进行全部修改及转发;由于代理的服务器可以控制判定URL的资源内容,因此可以对站点进行动静分离处理。如果这个功能可以工作在应用层叫做代理,如果工作类似SNAT上的叫做正向代理,工作类似DNAT就叫做反向代理。
Nginx反向代理服务器
面向客户端:该方向支持两种协议: http/https
面向服务端:该方向支持HTTP/FastCGI/memcache协议Nginx需要支持相关的协议需要有相关协议的对应模块原理以及流程: 从远程服务器取得数据进行nginx服务器本地的缓存,然后响应给客户端.可修改或具有修改意义的报文有两种:第一种是发到后面处理服务器的报文;第二种是发给客户端的响应报文。
Nginx的代理模块
ngx_http_proxy_module – Nginx的反向代理模块官方说明:Module ngx_http_proxy_module 添加新的反向代理服务配置文件: vim /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name [SERVER_FQDN]
location / {
proxy_pass http://[IP_ADDR:PORT]
# 字段后加上/表示将location后的目录映射为后端服务器的目录;
# 例如:如果是location /test,那么在反向代理不加/的时候,访问的是后端真实的/test目录;
# 如果加上/,访问到的是后端服务器的根目录;
# 当使用了正则表达式进行了匹配的时候后面不能添加/符号;
}
location ~* \.{jpg|jpeg|png}$ {
proxy_pass http://[IP_ADDR:PORT];
# 正则表达模式下部分在代理服务器的地址后面加上/;
}
}
proxy_pass [RealServerAddress];# 设置反向代理服务器的地址; proxy_set_header [field] [value]; # 设定传递到后端服务器的请求报文首部的值; proxy_set_header – Nginx的设定代理头文件参数模块的官方说明:proxy_set_header
proxy_set_header X-Real-IP $remote_addr;
在设定字段后,更改后端真实服务器的日志记录的值,即可记录所有的真正的客户端IP;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_headers_module # 设定发给客户端的响应报文的地址的值; Module ngx_http_headers_module – Nginx的客户端响应报文模块官方说明: Module ngx_http_headers_module
add_header X_Via $server_addr;` # 显示后端服务器的真实地址;
Linux启动流程简述
记录Linux启动流程。
Linux启动的简要流程Linux-MBR启动流程POST – GRUB(Bootloader-MBR) – Kernel – init
详细描述及说明
在触发开机通电之后,计算机读取BIOS中CMOS芯片的已经写好的程序进行主板设备的通电自检.
在自检完成后将读取硬盘上的前512个字节,通过前面的446个字节载入grub的bootloader及硬盘相关驱动.
同时引导grub进入stage1.5,stage1.5指向了定义在boot分区下的grub.cfg,及相关的grub图形文件.
grub的stage2进行了grub的菜单展示及内核选择的界面.
通过grub的引导,计算机挂载内核,识别的根文件系统.
启动init进程,通过SysV管理其他进程的启动及执行.
Grub 内核参数grub的菜单里面有几个参数, 这几个参数是用来控制内核行为的.AWS ec2 的串行端口是通过这个东西控制的, 如果不添加这个参数, 串口就是黑的.
linux /boot/vmlinuz-linux-zen root=UUID=7a1c634b-4d44-4136-87b1-6232d31b7c3b rw console=ttyS0 earlyprintk=serial,ttyS0,keep transparent_hugepage=never
初始化 Serial Console.console=ttyS0
设置初始化端口的选项.
Append “,keep” to not disable it when the real console takes over.earlyprintk=serial,ttyS0,keep
关闭透明巨页.transparent_hugepage=never
vim笔记
vim的常用的命令速记。
可在~/.vimrc中进行vim的的默认配置,echo ‘:set nu’ > ~/.vimrc即可设置vim默认显示行号。30分钟正则表达式入门教程
Vim一种模式化的编辑器,具有多种不同的模式。
编辑模式,命令模式
插入模式
末行模式 内置的命令行接口
vim +12 test.sh
vim +/PATTERN test.sh 打开自动定位到匹配模式的第一个结果的行首。
vim + test.sh 直接出现在文件末尾
切换模式的说明i – 直接在当前光标的位置输入a – 在光标字符的后面输入o – 在光标下面直接新建一行,开始输入I – 在光标所在行的行首输入O – 在光标所在的上面直接新建一行,开始输入A – 在光所所在行的行尾输入
编辑模式到末行模式 使用符号 ::10,100d:set nu:set nonu:s/dhcp/static/g
关闭文件: 编辑模式下 连续ZZ,表示保存退出 :q 表示直接退出,类似的常用还有 :wq :wq! :q! :w! :w :x 保存退出 :w [PATHTOFILE]
光标调整:字符间hjkl 左 下 上 右 10l 右侧10个字符w 下一个单词的词首b 前一个单词的词首e 下一个单词的词尾
行首行尾^ 调至行首第一个非空白字符0 调至行首$ 调至行尾
HIJK 行间G 直接到最后一行句间段间
1.2. 设置vim的个性化设置设置自动显示行号,设置VIM自动将tab转化为4个空格
:set nu
:set tabstop=4
:set softtabstop=4
:set shiftwidth=4
:set expandtab
3. 已经编辑的文件进行tab空格转换:
TAB替换为空格::set ts=4
:set expandtab
:%retab!
空格替换为TAB::set ts=4
:set noexpandtab
:%retab!
4. Vim的个性化配置及插件
自动换行
set wrap
输入命令时自动提示补完
set showcmd
显示行号
set nu
显示当前行号及关联前后行号
set relativenumber
语法高亮
syntax on
光标所在的行高亮
set cursorline
前后滚动时保留最前和最后的5行
set scrolloff=5
Ansible笔记-2
这份笔记介绍的是Ansible playbook的格式及相关的内容。
Ansible笔记Ansible PlaybookYAML
YAML(/ˈjæməl/,尾音类似 camel ) 是“YAML不是一种标记语言”的外语缩写(见前方参考资料原文内容);但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。它是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。数据结构可以用类似大纲的缩排方式呈现,结构通过缩进来表示,连续的项目通过减号“-”来表示,map结构里面的key/value对用冒号“:”来分隔。YAML文件一般的文件名为.yaml 或 .yml,文本结构举例如下:
house:
family:
name: Doe
parents:
- John
- Jane
children:
- Paul
- Mark
- Simone
address:
number: 34
street: Main Street
city: Nowheretown
zipcode: 12345
Ansible Playbook的关键字内容与命令的内容基本一致,有如下的几个关键字:
- hosts 用来指定控制主机的范围,注意短横线后空格接字符
remote_user 用来指定使用的用户
tasks 可在字段下方缩进指定需要执行的任务,注意缩进
- name 用来定义任务的名称或描述,注意短横线后空格接字符
yum: name=httpd state=latest 定义使用的模块功能:后面跟操作参数
tags: 对任务进行标记,可通过命令调用标记执行或排除某些任务
when: 判断,满足when后面的条件才执行任务
notify: 触发handler的标志
handlers: 定义触发任务的内容
- name: 任务的名称,注意短横线后空格接字符
service: name=httpd state=restarted 定义使用的模块:后面跟操作参数
Ansible Playbook示例先看一个已经写好的playbook,针对写好的来解释playbook如何书写。
--- # 默认的开头
- hosts: all # 先定义控制的范围,all表示所有主机,分组可定义在/etc/ansible/hosts文件中;
remote_user: root # 定义执行下面操作的用户,控制权限
tasks: # tasks字段负责定义任务
# 如果是Redhat系,执行安装httpd
- name: install httpd CentOS
yum:
name: httpd
state: latest
tags: install_httpd
when: ansible_os_family == "RedHat"
# 如果是Debain系,执行安装apache
- name: install httpd Ubuntu
apt:
name: apache
state: latest
when: ansible_os_family == "Ubuntu"
tags: install_httpd
# 执行网站主页的替换,如果变更触发handler字段定义的重启服务任务
- name: set the homepage
copy:
src: ./index.html
dest: /var/www/html/index.html
notify:
- restart_the_service
# 执行启动服务
- name: start httpd
service:
name: httpd
service: started
# 执行清空防火墙
- name: empty firewalld
shell: iptables -F
# 移除apache软件包
- name: remove httpd
yum:
name: httpd
state: absent
tags: remove_httpd
# 删除预设的apache网站文件
- name: clean stuff
file:
name: /var/www/html/
state: absent
tags: clean_stuff
# handler触发后需要执行的任务
handlers:
# 重启httpd服务
- name: restart_the_service
service:
name: httpd
state: restarted
Ansible Playbook执行命令使用格式:
ansible-playbook [options] playbook.yml [playbook2 ...]
命令作用:
Runs Ansible playbooks, executing the defined tasks on the targeted hosts.
# 运行ansible的playbook,在目标主机上执行已经定义好的任务。
命令示例:
[root@Hayden ~]$ ansible-playbook --syntax-check install_httpd.yaml
# 对playbook进行语法检查
[root@Hayden ~]$ ansible-playbook -C install_httpd.yaml
# 对playbook进行运行测试,不改变结果,仅仅进行测试
[root@Hayden ~]$ ansible-playbook install_httpd.yaml
# 对playbook进行运行,并生成运行的结果
[root@Hayden ~]$ ansible-playbook -t "install_httpd" install-httpd.yaml
# 只运行具有“install_httpd”标签的任务
[root@Hayden ~]$ ansible-playbook --skip-tags "install_httpd" install-httpd.yaml
# 跳过install_httpd标签的任务
[root@Hayden ~]$ ansible-playbook --skip-tags "install_httpd clean_stuff" install-httpd.yaml
# 跳过多个标签的任务示例
默认文件位置sudo pacman -Ql ansible | grep hosts 查看hosts文件的范例文件所在目录,其他文件操作类似.
如果有不明白的命令可通过ansible-doc命令直接查看内置的说明文件,针对模块的ansible-doc -l 为列出所有可用模块
Ansible笔记-1
Ansible的学习笔记。Ansible管理方式是资源在目标主机上,定义所期望的目标状态的方式;每一个操作必须是幂等的(可重复操作但结果不变的)。ansible采用ssh链接所管理的服务器,因此具有agentless的优势。
Ansible的安装Ansible在Redhat的仓库中就有二进制包,直接dnf或yum安装就可以了。
[root@localhost Liarlee]$ yum install -y Ansible
Ansible的配置文件Ansible的配置文件常用的有:
/etc/ansible/ansible.cfg Ansible的配置文件
/etc/ansible/hosts Ansible允许控制的主机列表,可在hosts文件中对服务器进行分组
Ansible的组件
ansible
ansible-playbook
ansible-doc
Ansible的配置和使用Ansible命令模式
ansible [HOST_PARTTEN] -m [MODUELS] -a “[ARGS]” -f [Forks] -C -u [USERNAME] -c [CONNTECTION]
基于密钥认证ansibleansible支持使用ssh用户命名密码的认证方式,也支持使用ssh密钥认证的方式进行链接。ssh密钥的方式可以保证安全性,同时免去输入密码的麻烦。
生成ansible的密钥 [root@localhost Liarlee]$ ssh-keygen -t rsa -P ""
复制ansible的公钥到需要连接控制的host上 [root@localhost Liarlee]$ ssh-copy-id -i ~/.ssh/id-rsa.pub root@[host1-IP]
[root@localhost Liarlee]$ ssh-copy-id -i ~/.ssh/id-rsa.pub root@[host2-IP]
在ansible的hosts文件中记录需要控制的主机名或者IP [root@localhost Liarlee]$ echo "[host1-IP]" >> /etc/ansible/hosts
[root@localhost Liarlee]$ echo "[host2-IP]" >> /etc/ansible/hosts
使用ansible进行控制测试 [root@localhost Liarlee]$ ansible all -m ping # 进行连通测试
[root@localhost Liarlee]$ ansible all -m ping --list-hosts # 列举所有受影响的主机,但是不执行操作
[root@localhost Liarlee]$ ansible all -m ping -C # 进行测试,但是不对控制的主机作更改
Ansible使用示例Ansible默认将所有的操作通过模块的方式定义,这里列举了一些常用的模块:
Ansible管理查询命令使用ansible-doc命令来进行模块的文档查看, /var/log/messages 中会记录操作日志。
[root@localhost Liarlee]$ ansible-doc -l # 列举所有当前可用的模块和简单说明
[root@localhost Liarlee]$ ansible-doc -s [MODULES_NAME] # 查看指定模块的使用方法和说明
User模块设定主机的用户状态,对用户进行创建删除,更改信息以及参数。
# 设置所有主机创建用户user,设置内容有uid,groups,shell
[root@localhost Liarlee]$ ansible all -m user -a "name=user1 uid=3000 state=present groups=testgrp shell=/bin/zsh"
Group模块设置主机的组状态,对组状态进行编辑。
# 控制所有主机创建组testgrp,设置内容有gid,非系统组
[root@localhost Liarlee]$ ansible all -m group -a "gid=3000 name=testgrp state=present system=no"
# 控制所有主机删除testgrp
[root@localhost Liarlee]$ ansible all -m group -a "gid=3000 name=testgrp state=absent"
Copy模块从本地复制内容到控制的所有主机,指定源地址和目的地址。
# 复制本地/etc/fstab到所有主机的/tmp/fstab.ansible,同时设置权限为755
[root@localhost Liarlee]$ ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=755"
# 通过键盘输入的文本内容传输到目的文件中,文件可不存在,可同时设置文件的属主属组
[root@localhost Liarlee]$ ansible all -m copy -a "content='hello,world\n' dest=/tmp/test.txt owner=liarlee group=liarlee"
# 递归复制目录及其子文件到所有主机的/tmp/下
[root@localhost Liarlee]$ ansible all -m copy -a "src=/etc/httpd dest=/tmp/"
# 复制目录下的所有文件到所有主机的/tmp/下,不创建对应的目录
[root@localhost Liarlee]$ ansible all -m copy -a "src=/etc/httpd/ dest=/tmp/"
# 在所有主机的目录下新建一个空文件
[root@localhost Liarlee]$ ansible all -m copy -a "content='' dest=/tmp/testfile"
Fetch模块可从远程主机复制文件到本地。
# 从某个主机复制文件到本地目录,文件不存在退出
[root@localhost Liarlee]$ ansible [HOST1] -m fetch -a "src=/etc/fstab dest=/tmp/fstab.host1 fail-on-missing=yes"
Command模块command模块不调用shell去解析命令,仅仅读取第一个命令进行简单执行,因此不支持管道传递参数。
# 在所有主机上执行ifconfig
[root@localhost Liarlee]$ ansible all -m command -a "ifconfig"
Shell模块使用shell执行传递的命令,支持管道传递参数
# 执行shell命令修改用户的密码
[root@localhost Liarlee]$ ansible all -m shell -a "echo PASSWORD | passwd --stdin user1"
File模块用于设定文件的状态以及属性
# 在所有主机上建立目录
[root@localhost Liarlee]$ ansible all -m file -a "path=/tmp/testdir state=directory"
# 在所有主机上对文件建立符号链接
[root@localhost Liarlee]$ ansible all -m file -a "src=/tmp/testfile path=/tmp/testfile.link state=link"
# 在所有主机上设置文件或目录的权限
[root@localhost Liarlee]$ ansible all -m file -a "path=/tmp/testfile mode=0755"
Cron模块用于设置计划任务
# 设置每三分钟运行一次同步时间的脚本
[root@localhost Liarlee]$ ansible all -m cron -a "miniute=*/3 name=synctime job='usr/sbin/update 172.16.0.1 &> /dev/null'state=present"
# 删除设置的计划任务
[root@localhost Liarlee]$ ansible all -m cron -a "miniute=*/3 name=synctime job='usr/sbin/update 172.16.0.1 &> /dev/null'state=absent"
Yum模块用于调用yum进行软件包的安装卸载等,定义主机安装软件包的状态
# 在所有主机安装nginx
[root@localhost Liarlee]$ ansible all -m yum -a "name=nginx state=install"
Service模块用于定义管理目标主机的服务状态
# 在所有的主机上启动nginx服务
[root@localhost Liarlee]$ ansible all -m service -a "name=nginx state=startd"
# 在所有的主机上设置nginx开机启动
[root@localhost Liarlee]$ ansible all -m service -a "name=nginx enabled"
# 在所有主机上停止nginx服务
[root@localhost Liarlee]$ ansible all -m service -a "name=nginx state=stoppd"
# 在所有的主机上重载nginx的配置文件
[root@localhost Liarlee]$ ansible all -m service -a "name=nginx state=reloaded"
# 在所有主机上重启nginx服务
[root@localhost Liarlee]$ ansible all -m service -a "name=nginx state=restarted"
Scripts模块用于在所有主机上执行设置好的脚本
# 在所有的主机上执行test.sh
[root@localhost Liarlee]$ ansible all -m scripts -a "/tmp/test.sh"
KVM中windows7虚拟机时间问题
在KVM虚拟机中,安装Windows7的虚拟机,安装完成启动的时候发现虚拟机的时间与外部时间的速度不一致。记录问题的原因及解决方法。
解决方式查看虚拟机的配置文件观察运行的效果类似于GBA模拟器的加速设定,动画速度变快了,windows7的系统时间也被加速了。 首先怀疑的是虚拟机的运行速度是不是被加速了,没有相关的设置。其次是查看配置文件中时间的相关定义,发现我的配置文件中,时间的定义是这样的:
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
怀疑这几个timer是有问题的,一般来说配置文件中只有简单的 clock offset=’localtime’ 的字段其实就够用了。在删除了第一个timer之后,系统的时间和运行速度就正常了。
在fedora-wiki找到的说明页面Libvirt_Managed_Timers页面链接在字段中‘rtc’并不是主要的问题,主要问题是后面的tickpolicy=’catchcup’。fedora wiki给出的答案是catchup–Deliver at a higher rate to catch up.所以这就是为什么删除了这个timer之后系统正常的原因。
IO重定向笔记
输出重定向部分的复习笔记
标准输入输出文件描述符的概念可以通过命令查看以及绑定文件描述符FD。
liarlee@hayden-pc ~
> $ ll /proc/$$/fd
总用量 0
dr-x------ 2 liarlee liarlee 0 6月 24 20:22 .
dr-xr-xr-x 9 liarlee liarlee 0 6月 24 20:22 ..
lrwx------ 1 liarlee liarlee 64 6月 24 20:22 0 -> /dev/pts/0
lrwx------ 1 liarlee liarlee 64 6月 24 20:22 1 -> /dev/pts/0
lrwx------ 1 liarlee liarlee 64 6月 24 20:22 10 -> /dev/pts/0
lrwx------ 1 liarlee liarlee 64 6月 24 20:22 2 -> /dev/pts/0
Linux提供的I/O设备Linux系统提供的IO设备,共有三种:
STDIN - 0 默认键盘输入
STDOUT - 1 默认输出信息到终端
STDERR - 2 默认输出错误信息到终端
Linux输入输出重定向重定向说明STDOUT和STDERR可以被重定向到文件中,STDIN可通过读取文件实现输入重定向,重定向命令的基本格式如下:
[CMD] [lOPERATION_SYMBOL] [FILENAME]
命令 操作符号 文件名
操作符号包括:
> 把STDOUT重定向到文件
2> 把STDERR重定向到文件
&> 把所有结果输出重定向到文件
>> 在原有文件内容的基础上进行追加
< 标准输入的重定向
例子那么会有如下的操作:
> $ ls 1> /tmp/echo.stdout
# 正确的命令结果输出到文件中
> $ ls 2> /tmp/echo.stderr
# 命令执行的错误结果输出到文件中
> $ ls /error /usr 2>&1 >/tmp/right.test
# 将错误信息重定向输出到屏幕显示,正确的信息输出到文件
# 通俗的讲是-- 将STDERR(2)重定向为STDOUT(1)输出到屏幕上,
# 命令的其他结果输出到文件中
> $ ls /error /usr >true 2>false
# 将正确的信息输出到true中,把错误的信息输出到false中
> $ ls /error /usr >all 2>&1
# 先将标准输出重定向到文件all中,在将错误信息追加到标准输出中
# 命令结果等于ls /error /usr &>all
> $ ls /error /usr &> /dev/null
# 静默执行命令,不显示结果,不输出到终端
> $ ls /error /usr 2>&1 >/dev/null
# 错误的信息显示在终端上,其他信息不显示
# 某些命令可以使用管道将STDIN输入重定向作为命令的值
echo [PASSWD] | passwd --stdin [username] &> /dev/null
# 更改某个用户的用户名和密码
pyautogui自动脚本
最近一个游戏非常的上头, 实在是肝不动了,自己写了个脚本帮我点点点。
Pyautogui 库Pyautogui 项目Pyautogui CheatSheet
简单记录了一下使用到的方法。
pyautogui.position() # 获取鼠标位置
pyautogui.locateOnScreen() # 对屏幕截图,获取图片文件所对应的屏幕坐标
pyautogui.click() # 模拟鼠标点击
pyautogui.doubleclick() # 模拟鼠标双击
pyautogui.moveTo() # 移动到屏幕坐标位置
pyautogui.moveRel() # 移动固定的坐标距离
pyautogui.dragRel() # 按住鼠标拖拽
code#!/usr/bin/python
# -*- coding:UTF-8 -*-
import pyautogui
import time
import os
def MOTIONMOUSE(lines):
if lines < 9:
# 检测是否有书本或食物
results_food = pyautogui.locateOnScreen('./food.png', grayscale=True) # 检测食物图片是否存在
print('- 食物检测结果:', results_food)
results_book = pyautogui.locateOnScreen('./book.png', grayscale=True) # 检测书籍图片是否存在
print('- 书本检测结果:', results_book)
pyautogui.click(1900, 60, duration=0.1) # 点击换线
if results_book is not None:
pyautogui.click(1700, 325) # 点击学习
pyautogui.click(1600, 645) # 点击确定
elif results_food is not None:
pyautogui.click(1700, 325) # 点击食用
else:
pass
pyautogui.moveTo(1700, 60, duration=0.1) # 移动到对应一线的位置
pyautogui.moveRel(0, 65 * lines, duration=0.1) # 移动到对应的线路位置
time.sleep(1)
pyautogui.click() # 触发一次点击
else:
pyautogui.click(1900, 60, duration=0.3) #
# 检测是否有书本或食物
results_food = pyautogui.locateOnScreen('./food.png', grayscale=True)
print('- 食物检测结果:', results_food)
results_book = pyautogui.locateOnScreen('./book.png', grayscale=True)
print('- 书本检测结果:', results_book)
if results_book is not None:
pyautogui.click(1700, 325)
pyautogui.click(1600, 645)
elif results_food is not None:
pyautogui.click(1700, 325)
else:
pass
for t in range(0, lines-8):
pyautogui.moveTo(1700, 90, duration=0.1)
pyautogui.dragRel(0, -65, duration=0.3)
if t < 14:
time.sleep(3)
else:
pass
pyautogui.click(1700, 480, duration=0.1)
# starting .....
Count = 0
replace_times = 0
Energy = input('please input value of energy: ') # 输入体力
All_lines = input('please input the number of lines: ') # 输入所有线路的数字
for turns in range(1, 999):
print('** 这是第 ' + str(turns) + ' 轮采集。')
for line in range (1, int(All_lines) + 1):
print('* 这是第 ' + str(line) + ' 条线路。')
clock = time.strftime('%H:%M:%S', time.localtime(time.time()))
print('* 开始时间 = ' + clock + ' ')
MOTIONMOUSE(int(line))
time.sleep(2)
pyautogui.click(1600, 770, duration=1.5)
pyautogui.moveTo(1310, 800)
#检测是否有树木
results_click = pyautogui.locateOnScreen('./level4_usable.png', grayscale=True) # 计算斧子在不在
print('- 斧子检测结果:', results_click)
results_replace = pyautogui.locateOnScreen('./level4_replace.png', grayscale=True) # 计算可替换的斧子在不在
print('- 更换检测结果:', results_replace)
# 判断是否有物品
if results_click is not None: # 判断是否有按键,有等待,没有按键换线;
print('* 第 ' + str(Count) + ' 次采集。')
Count = Count +1
energy = int(Energy) - 15
elif results_replace is not None: # 判断是否有可更换的斧子
pyautogui.click(1510, 720, duration=0.2)
pyautogui.click(1310, 880, duration=0.2)
Count = Count + 1
replace_times = replace_times + 1
print('这是第 ' + str(Count) + ' 次采集。')
print('这是第 ' + str(replace_times) + ' 次换斧子。')
energy = int(Energy) - 15
time.sleep(4)
else:
print('-- 采集物或斧子未存在,跳过。')
pass # 啥也没有,跳过
print('Starting Waiting for Refresh:')
time.sleep(200)