Rootop 服务器运维与web架构

2019-04-17
发表者 Venus
while read line语句中ssh远程执行命令,只运行了一次。已关闭评论

while read line语句中ssh远程执行命令,只运行了一次。

while read line语句中ssh远程执行命令,只运行了一次。
目的:批量修改主机信息。

有一个host.txt文件,记录服务器ip,已经配置好秘钥登陆。如:

[root@m ~]# cat host.txt
192.168.10.71
192.168.10.72
192.168.10.73

现在想批量修改主机名,比如idc-001、idc-002 …,后面3位是数字
# 通过 expr 表达式实现shell中进行数学运算
# 通过 printf 格式化字符串,不足3位用0补全

# 先拼接出来主机名,再进一步添加修改功能

[root@m ~]# cat b
#!/bin/bash
str="idc-"
n=1
while read ip
do

 host_num=`printf "%03d" $n`
 hostname=$str$host_num
 echo $ip $hostname
 n=`expr $n + 1`

done < host.txt

# 执行结果没问题

[root@m ~]# sh b
192.168.10.71 idc-001
192.168.10.72 idc-002
192.168.10.73 idc-003

# 下一步就要通过ssh登陆实现修改主机名

[root@m ~]# cat b
#!/bin/bash
str="idc-"
n=1
while read ip
do

 host_num=`printf "%03d" $n`
 hostname=$str$host_num
 echo $ip $hostname
 ssh -o "StrictHostKeyChecking no" root@$ip "echo $hostname > /etc/hostname && hostname $hostname"
 n=`expr $n + 1`

done < host.txt

# 运行

[root@m ~]# sh b
192.168.10.71 idc-001
[root@m ~]# 

就执行了一行,退出了。去看71这台机器是修改成功了,但是72、73仍旧没变化。怀疑问题出在ssh上。

原因:
ssh中有个参数为 -n 通过man看到解释:

 
Redirects stdin from /dev/null (actually, prevents reading from stdin).  This must be used when ssh is run in the background.  A common trick is to
use this to run X11 programs on a remote machine.  For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the
X11 connection will be automatically forwarded over an encrypted channel.  The ssh program will be put in the background.  (This does not work if
ssh needs to ask for a password or passphrase; see also the -f option.)

即ssh从stdin中读取了while read line的内容,导致while语句没有输入了,就执行完了。
-n的作用就是阻止ssh读取标准输入,为了验证这个结论,修改下host.txt文件,并且把ssh要执行的命令去掉。

[root@m ~]# cat b
#!/bin/bash
str="idc-"
n=1
while read ip
do

 host_num=`printf "%03d" $n`
 hostname=$str$host_num
 echo $ip $hostname
 ssh -o "StrictHostKeyChecking no" root@$ip # 去掉了后面的命令
 n=`expr $n + 1`

done < host.txt
[root@m ~]# cat host.txt 最后两行为两条系统命令
192.168.10.71
uname -r
date

# 执行

[root@m ~]# sh b
192.168.10.71 idc-001
Pseudo-terminal will not be allocated because stdin is not a terminal.
3.10.0-514.el7.x86_64
Wed Apr 17 16:44:58 CST 2019

可以看到内核版本和日期,说明ssh从标准输入读取了内容做为命令执行了,导致while标准输入为空,最后退出。

# 修改后正确姿势,添加-n参数

#!/bin/bash
str="idc-"
n=1
while read ip
do

 host_num=`printf "%03d" $n`
 hostname=$str$host_num
 echo $ip $hostname
 ssh -n -o "StrictHostKeyChecking no" root@$ip "hostname $hostname && echo $hostname > /etc/hostname"
 n=`expr $n + 1`

done < host.txt

# 执行结果

[root@m ~]# sh b
192.168.10.71 idc-001
192.168.10.72 idc-002
192.168.10.73 idc-003

再去看72、73两台机器正确修改了。

2019-04-11
发表者 Venus
nginx中resolver参数配置解释已关闭评论

nginx中resolver参数配置解释

之前有个测试环境配置 proxy_pass 时直接指定域名是可以用的,比如

location / {
    proxy_pass http://dev.abc.com:10068;
}

遇到一个问题是:
反向代理的地址是通过花生壳动态dns实现的。
dev.abc.com通过cname解析到花生壳之类的动态dns给分配的域名上,如果路由器因为断电或者掉线之类的原因重新拨号后ip发生变化,此处nginx就无法反向代理了,必须重启一次nginx才行。

今天遇到一个问题就是通过 set 设置变量,然后 proxy_pass 调用变量实现反向代理(目的是减少配置复杂度),比如:

set $skyneturl "http://dev.abc.com:10077"; # 注意set好像不支持变量名中带下划线或其它特殊字符

location /applyrecord/aladinnApplyrecord { 
    proxy_pass $skyneturl;
}

重启nginx后发现报502错误,也就是连不上后端服务器。
看nginx日志发现错误提示:

2019/04/11 10:34:04 [error] 17241#0: *4334742 no resolver defined to resolve dev.abc.com ...

说没有定义 resolver命令 来解析域名,查了一下发现需要配置resolver参数。

官网文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver

Syntax:	resolver address ... [valid=time] [ipv6=on|off];
Default:	—
Context:	http, server, location

Configures name servers used to resolve names of upstream servers into addresses, for example:

意思是需要配置dns地址用来解析upstream中的域名(用域名替代ip地址,后来经过测试upstream中配置域名只会在nginx启动时解析一次,然后就一直用这个ip,无法使用resolver实现每次解析)

添加resolver配置参数:

resolver 202.102.134.68 114.114.114.114 valid=5 ipv6=off;
set $skyneturl "http://dev.abc.com:10077";
location /applyrecord/aladinnApplyrecord { 
    proxy_pass $skyneturl;
}

重启nginx后访问成功。

过程回顾:

无意间查资料发现 proxy_pass 后面跟域名的话并不是每次请求都会解析出这个域名的ip(这也验证了必须重启nginx才能解决),所以就会导致路由ip变化时造成服务无法访问。
解决这个问题的话,就可以用 set 设置一个变量,通过 resolver 实现每次访问都重新解析出ip地址。
这里还有一个问题,发现通过set和resolver设置域名解析时,重启路由器测试访问时,还是无法解析出新地址,通过tcpdump抓包没有发现有请求dns解析。
后来注意到还有个 valid 参数需要配置,这个参数用来控制缓存时间的,默认时间取决于dns记录的ttl值,比如我用windows搭建的dns解析默认是3600秒,也就是一小时。
通过修改valid参数,这里设置为5秒后,再次抓包发现每隔5秒后访问虚拟主机的时候就会产生一次dns解析。

这样才解决动态dns解析访问问题。

 

2019-04-10
发表者 Venus
fluentd收集docker日志已关闭评论

fluentd收集docker日志

1、安装fluentd docker版:

docker run \
-dit \
--name fluentd \
--hostname fluentd \
-p 24224:24224/udp \
-p 24224:24224 \
-v /fluentd/log:/fluentd/log \
docker.io/fluent/fluentd

这样fluentd日志就挂载到宿主机的/fluentd/log目录下。

2、创建服务,指定fluentd信息

docker service create \
--replicas 6 \
-dt \
--name ping \
--network onet \
--log-driver=fluentd \
--log-opt=fluentd-address=192.168.10.80:24224 \
--log-opt=tag=TagOfPingService \
--log-opt=fluentd-async-connect \
--with-registry-auth \
hub.xxx.com/test/java8:0402 \
ping www.baidu.com

注意事项:
1、docker service create 创建服务,指定镜像为私库路径,提示 没有这个镜像。 解决方法如下:

一)、管理节点及工作节点需要登录私库 docker login -u xxx -p xxx repoAddr 认证信息保存在 cat /root/.docker/config.json 中
二)、docker service create 添加参数 –with-registry-auth 进行私库验证
以上两步就可以拉取私库镜像了。

2、如果fluentd服务挂掉,新建的服务容器无法启动。
会提示starting container failed: failed to initialize logging driver: dial tcp 192.168.10.80:24224: connect: connection refused错误。
如果是容器已启动,fluentd挂掉会继续运行。

2019-04-10
发表者 Venus
docker版fluentd修改时区已关闭评论

docker版fluentd修改时区

发现docker容器发过来的日志记录文件中时区是错误的,差八个小时,可以确定是时区的问题。
进入容器验证时区设置

[root@localhost log]# docker exec -it fluentd /bin/sh
/ # date
Wed Apr 10 05:06:07 UTC 2019
/ # cd /usr/share/lo^C
/ # cp /usr/share/  # 发现没有zoneinfo目录
apk/              ca-certificates/  man/              misc/             terminfo/

# 查看系统版本

~ # cat /etc/issue 
Welcome to Alpine Linux 3.8
Kernel \r on an \m (\l)

系统为Alpine linux,这里需要用apk这个包管理器安装tzdata这个包

~ # apk add -U tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2018f-r0)
Executing busybox-1.28.4-r2.trigger
OK: 29 MiB in 28 packages
~ # cp /usr/share/zoneinfo/
Africa/       Atlantic/     Canada/       EST5EDT       Factory       GMT-0         Iceland       Japan         MST7MDT       PRC           ROC           US/           Zulu          zone1970.tab
America/      Australia/    Chile/        Egypt         GB            GMT0          Indian/       Kwajalein     Mexico/       PST8PDT       ROK           UTC           iso3166.tab
Antarctica/   Brazil/       Cuba          Eire          GB-Eire       Greenwich     Iran          Libya         NZ            Pacific/      Singapore     Universal     posixrules
Arctic/       CET           EET           Etc/          GMT           HST           Israel        MET           NZ-CHAT       Poland        Turkey        W-SU          right/
Asia/         CST6CDT       EST           Europe/       GMT+0         Hongkong      Jamaica       MST           Navajo        Portugal      UCT           WET           zone.tab
~ # cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
~ # date
Wed Apr 10 13:13:57 CST 2019

重启fluentd容器解决。

2019-04-02
发表者 Venus
docker私库harbor配置已关闭评论

docker私库harbor配置

harbor介绍(复制来的):

Harbor是VMware公司开源了企业级Registry项目, 其的目标是帮助用户迅速搭建一个企业级的Docker registry服务。它以Docker公司开源的registry为基础,额外提供了如下功能:
基于角色的访问控制(Role Based Access Control)
基于策略的镜像复制(Policy based image replication)
镜像的漏洞扫描(Vulnerability Scanning)
AD/LDAP集成(LDAP/AD support)
镜像的删除和空间清理(Image deletion & garbage collection)
友好的管理UI(Graphical user portal)
审计日志(Audit logging)
RESTful API
部署简单(Easy deployment)

项目地址:https://github.com/goharbor/harbor
从release里下载Harbor online installer在线安装版。
目前最新版下载地址为:https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-online-installer-v1.7.4.tgz

1、先安装docker及docker-compose(harbor部署脚本通过服务编排实现),过程略。
# 解压 harbor

[root@localhost ~]# tar zxvf harbor-online-installer-v1.7.4.tgz

# 编辑 harbor.cfg 只修改下面几行即可

[root@localhost harbor]# vi harbor.cfg
hostname = hub.xxx.com  # 绑定自己的域名,便于docker pull \ push的时候输入地址。
ui_url_protocol = https # 启用https协议,否则docker在pull的时候会提示http不安全需要https(要么每个docker机器手动加入信任,嫌弃麻烦)。
ssl_cert = /data/cert/214290856400784.pem  # ssl公钥,这里直接用阿里云颁发的免费域名证书(原先配置文件里是crt文件,pem也可以)
ssl_cert_key = /data/cert/214290856400784.key # ssl私钥,这俩证书服务编排的时候会加载到容器的nginx中。
secretkey_path = /data  # 秘钥路径
harbor_admin_password = 111111  # web界面登陆admin用户的密码

# 创建秘钥目录,把阿里云的证书文件放进去

[root@localhost harbor]# mkdir -p /data/cert
[root@localhost harbor]# ll /data/cert/
total 8
-rw-r--r-- 1 root root 1678 Apr  2 09:53 214290856400784.key
-rw-r--r-- 1 root root 3662 Apr  2 09:53 214290856400784.pem

# 开始服务编排

[root@localhost harbor]# sh install.sh
成功后会显示
----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at https://hub.xxx.com. 
For more details, please visit https://github.com/goharbor/harbor .

访问 https://hub.xxx.com 默认用户名 admin,密码上面设置的。

左上侧有个项目菜单,新建项目 可以用来区分不同的项目所用到的镜像,便于分类管理。
我这里新建了一个test项目(注意不要公开,否则任何人知道地址后都可以拉取了),测试上传镜像。

# 给本地镜像打标签并push到私库

[root@localhost ~]# docker tag 45d8d2f74278 hub.xxx.com/test/java8:0402 # 这个地方注意加上test(等于项目是一个目录) 0402是标记TAG,今天的日期便于区分
[root@localhost ~]# docker images
REPOSITORY                                  TAG                 IMAGE ID            CREATED             SIZE
docker.io/registry                          latest              f32a97de94e1        3 weeks ago         25.8 MB
docker.io/goharbor/redis-photon             v1.7.4              611d1ead0a28        4 weeks ago         99.7 MB
docker.io/goharbor/harbor-registryctl       v1.7.4              723aed7bbf8d        4 weeks ago         102 MB
docker.io/goharbor/registry-photon          v2.6.2-v1.7.4       f4743bd7b0d9        4 weeks ago         86.7 MB
docker.io/goharbor/nginx-photon             v1.7.4              dda34e6afafe        4 weeks ago         35.9 MB
docker.io/goharbor/harbor-log               v1.7.4              bf4916eef530        4 weeks ago         81.4 MB
docker.io/goharbor/harbor-jobservice        v1.7.4              1b6a0445ae9c        4 weeks ago         84.1 MB
docker.io/goharbor/harbor-core              v1.7.4              e603b8750d26        4 weeks ago         95.6 MB
docker.io/goharbor/harbor-portal            v1.7.4              2ca1d845cafa        4 weeks ago         40.6 MB
docker.io/goharbor/harbor-adminserver       v1.7.4              5706c65d65dc        4 weeks ago         72.3 MB
docker.io/goharbor/harbor-db                v1.7.4              08d163f732f3        4 weeks ago         136 MB
hub.xxx.com/java8                           0402                45d8d2f74278        5 months ago        1.21 GB
hub.xxx.com/java8                           latest              45d8d2f74278        5 months ago        1.21 GB
hub.xxx.com/test/java8                      0402                45d8d2f74278        5 months ago        1.21 GB

# 登陆私库测试推送

[root@localhost harbor]# docker login -u admin -p 111111 hub.xxx.com
Login Succeeded
[root@localhost ~]# docker push hub.xxx.com/test/java8:0402
The push refers to a repository [hub.xxx.com/test/java8]
5f70bf18a086: Pushed 
bba5ae3ca8bd: Pushed 
28a4db706758: Pushed 
8215ed96e346: Pushed 
6831dc86bfcf: Pushed 
4cdc463b402d: Pushed 
0402: digest: sha256:318cce2a9d4dfccf96c74ac1f6a146406950d961dd96da6b5cc187e034ca29c4 size: 3641

刚开始还挺纠结这个作者名字从哪里来的,后来一想是当时用dockerfile构建镜像时配置文件里MAINTAINER这个参数控制的。这个镜像还是2018年在docker1.7.1版本下做的。

# 退出登陆,测试未登录状态下能否拉取私库镜像

[root@localhost harbor]# docker logout hub.xxx.com
Removing login credentials for hub.xxx.com
[root@localhost harbor]# docker pull hub.xxx.com/test/java8:0402
Trying to pull repository hub.xxx.com/test/java8 ... 
repository hub.xxx.com/test/java8 not found: does not exist or no pull access

提示镜像不存在或没有拉取权限。

系统管理 里面的功能暂未研究。