2021年4月

学习 Bash 读取和写入数据的不同方式,以及何时使用每种方法。

 title=

当你使用 Bash 编写脚本时,有时你需要从一个文件中读取数据或向一个文件写入数据。有时文件可能包含配置选项,而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言处理这个任务的方式都有些不同,本文将演示如何使用 Bash 和其他 POSIX shell 处理数据文件。

安装 Bash

如果你在使用 Linux,你可能已经有了 Bash。如果没有,你可以在你的软件仓库里找到它。

在 macOS 上,你可以使用默认终端,Bash 或 Zsh,这取决于你运行的 macOS 版本。

在 Windows 上,有几种方法可以体验 Bash,包括微软官方支持的 Windows Subsystem for Linux(WSL)。

安装 Bash 后,打开你最喜欢的文本编辑器并准备开始。

使用 Bash 读取文件

除了是 shell 之外,Bash 还是一种脚本语言。有几种方法可以从 Bash 中读取数据。你可以创建一种数据流并解析输出, 或者你可以将数据加载到内存中。这两种方法都是有效的获取信息的方法,但每种方法都有相当具体的用例。

在 Bash 中援引文件

当你在 Bash 中 “ 援引 source ” 一个文件时,你会让 Bash 读取文件的内容,期望它包含有效的数据,Bash 可以将这些数据放入它建立的数据模型中。你不会想要从旧文件中援引数据,但你可以使用这种方法来读取配置文件和函数。

(LCTT 译注:在 Bash 中,可以通过 source. 命令来将一个文件读入,这个行为称为 “sourcing”,英文原意为“一次性(试)采购”、“寻找供应商”、“获得”等,考虑到 Bash 的语境和发音,我建议可以翻译为“援引”,或有不当,供大家讨论参考 —— wxy)

例如,创建一个名为 example.sh 的文件,并输入以下内容:

#!/bin/sh

greet opensource.com

echo "The meaning of life is $var"

运行这段代码,看见失败了:

$ bash ./example.sh
./example.sh: line 3: greet: command not found
The meaning of life is

Bash 没有一个叫 greet 的命令,所以无法执行那一行,也没有一个叫 var 的变量记录,所以文件没有意义。为了解决这个问题,建立一个名为 include.sh 的文件:

greet() {
    echo "Hello ${1}"
}

var=42

修改你的 example.sh 脚本,加入一个 source 命令:

#!/bin/sh

source include.sh

greet opensource.com

echo "The meaning of life is $var"

运行脚本,可以看到工作了:

$ bash ./example.sh
Hello opensource.com
The meaning of life is 42

greet 命令被带入你的 shell 环境,因为它被定义在 include.sh 文件中,它甚至可以识别参数(本例中的 opensource.com)。变量 var 也被设置和导入。

在 Bash 中解析文件

另一种让数据“进入” Bash 的方法是将其解析为数据流。有很多方法可以做到这一点. 你可以使用 grepcat 或任何可以获取数据并管道输出到标准输出的命令。另外,你可以使用 Bash 内置的东西:重定向。重定向本身并不是很有用,所以在这个例子中,我也使用内置的 echo 命令来打印重定向的结果:

#!/bin/sh

echo $( < include.sh )

将其保存为 stream.sh 并运行它来查看结果:

$ bash ./stream.sh
greet() { echo "Hello ${1}" } var=42
$

对于 include.sh 文件中的每一行,Bash 都会将该行打印(或 echo)到你的终端。先用管道把它传送到一个合适的解析器是用 Bash 读取数据的常用方法。例如, 假设 include.sh 是一个配置文件, 它的键和值对用一个等号(=)分开. 你可以用 awk 甚至 cut 来获取值:

#!/bin/sh

myVar=`grep var include.sh | cut -d'=' -f2`

echo $myVar

试着运行这个脚本:

$ bash ./stream.sh
42

用 Bash 将数据写入文件

无论你是要存储用户用你的应用创建的数据,还是仅仅是关于用户在应用中做了什么的元数据(例如,游戏保存或最近播放的歌曲),都有很多很好的理由来存储数据供以后使用。在 Bash 中,你可以使用常见的 shell 重定向将数据保存到文件中。

例如, 要创建一个包含输出的新文件, 使用一个重定向符号:

#!/bin/sh

TZ=UTC
date > date.txt

运行脚本几次:

$ bash ./date.sh
$ cat date.txt
Tue Feb 23 22:25:06 UTC 2021
$ bash ./date.sh
$ cat date.txt
Tue Feb 23 22:25:12 UTC 2021

要追加数据,使用两个重定向符号:

#!/bin/sh

TZ=UTC
date >> date.txt

运行脚本几次:

$ bash ./date.sh
$ bash ./date.sh
$ bash ./date.sh
$ cat date.txt
Tue Feb 23 22:25:12 UTC 2021
Tue Feb 23 22:25:17 UTC 2021
Tue Feb 23 22:25:19 UTC 2021
Tue Feb 23 22:25:22 UTC 2021

Bash 轻松编程

Bash 的优势在于简单易学,因为只需要一些基本的概念,你就可以构建复杂的程序。完整的文档请参考 GNU.org 上的 优秀的 Bash 文档


via: https://opensource.com/article/21/3/input-output-bash

作者:Seth Kenlon 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这要从一次咨询的失误说起:政府组织 A 让政府组织 B 开发一个 Web 应用程序。政府机构 B 把部分工作外包给某个人。后来,项目的托管和维护被外包给一家私人公司 C。C 公司发现,之前外包的人(已经离开很久了)构建了一个自定义的 Docker 镜像,并将其成为系统构建的依赖项,但这个人没有提交原始的 Dockerfile。C 公司有合同义务管理这个 Docker 镜像,可是他们他们没有源代码。C 公司偶尔叫我进去做各种工作,所以处理一些关于这个神秘 Docker 镜像的事情就成了我的工作。

幸运的是,Docker 镜像的格式比想象的透明多了。虽然还需要做一些侦查工作,但只要解剖一个镜像文件,就能发现很多东西。例如,这里有一个 Prettier 代码格式化 的镜像可供快速浏览。

首先,让 Docker 守护进程 daemon 拉取镜像,然后将镜像提取到文件中:

docker pull tmknom/prettier:2.0.5
docker save tmknom/prettier:2.0.5 > prettier.tar

是的,该文件只是一个典型 tarball 格式的归档文件:

$ tar xvf prettier.tar
6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/
6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/VERSION
6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/json
6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar
88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json
a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/
a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/VERSION
a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/json
a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar
d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/
d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/VERSION
d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/json
d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar
manifest.json
repositories

如你所见,Docker 在命名时经常使用 哈希 hash 。我们看看 manifest.json。它是以难以阅读的压缩 JSON 写的,不过 JSON 瑞士军刀 jq 可以很好地打印 JSON:

$ jq . manifest.json
[
  {
    "Config": "88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json",
    "RepoTags": [
      "tmknom/prettier:2.0.5"
    ],
    "Layers": [
      "a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar",
      "d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar",
      "6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar"
    ]
  }
]

请注意,这三个 Layer 对应三个以哈希命名的目录。我们以后再看。现在,让我们看看 Config 键指向的 JSON 文件。它有点长,所以我只在这里转储第一部分:

$ jq . 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json | head -n 20
{
  "architecture": "amd64",
  "config": {
    "Hostname": "",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "--help"
    ],
    "ArgsEscaped": true,
    "Image": "sha256:93e72874b338c1e0734025e1d8ebe259d4f16265dc2840f88c4c754e1c01ba0a",

最重要的是 history 列表,它列出了镜像中的每一层。Docker 镜像由这些层堆叠而成。Dockerfile 中几乎每条命令都会变成一个层,描述该命令对镜像所做的更改。如果你执行 RUN script.sh 命令创建了 really_big_file,然后用 RUN rm really_big_file 命令删除文件,Docker 镜像实际生成两层:一个包含 really_big_file,一个包含 .wh.really_big_file 记录来删除它。整个镜像文件大小不变。这就是为什么你会经常看到像 RUN script.sh && rm really_big_file 这样的 Dockerfile 命令链接在一起——它保障所有更改都合并到一层中。

以下是该 Docker 镜像中记录的所有层。注意,大多数层不改变文件系统镜像,并且 empty_layer 标记为 true。以下只有三个层是非空的,与我们之前描述的相符。

$ jq .history 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json
[
  {
    "created": "2020-04-24T01:05:03.608058404Z",
    "created_by": "/bin/sh -c #(nop) ADD file:b91adb67b670d3a6ff9463e48b7def903ed516be66fc4282d22c53e41512be49 in / "
  },
  {
    "created": "2020-04-24T01:05:03.92860976Z",
    "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:06.617130538Z",
    "created_by": "/bin/sh -c #(nop)  ARG BUILD_DATE",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:07.020521808Z",
    "created_by": "/bin/sh -c #(nop)  ARG VCS_REF",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:07.36915054Z",
    "created_by": "/bin/sh -c #(nop)  ARG VERSION",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:07.708820086Z",
    "created_by": "/bin/sh -c #(nop)  ARG REPO_NAME",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:08.06429638Z",
    "created_by": "/bin/sh -c #(nop)  LABEL org.label-schema.vendor=tmknom org.label-schema.name=tmknom/prettier org.label-schema.description=Prettier is an opinionated code formatter. org.label-schema.build-date=2020-04-29T06:34:01Z org
.label-schema.version=2.0.5 org.label-schema.vcs-ref=35d2587 org.label-schema.vcs-url=https://github.com/tmknom/prettier org.label-schema.usage=https://github.com/tmknom/prettier/blob/master/README.md#usage org.label-schema.docker.cmd=do
cker run --rm -v $PWD:/work tmknom/prettier --parser=markdown --write '**/*.md' org.label-schema.schema-version=1.0",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:08.511269907Z",
    "created_by": "/bin/sh -c #(nop)  ARG NODEJS_VERSION=12.15.0-r1",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:08.775876657Z",
    "created_by": "/bin/sh -c #(nop)  ARG PRETTIER_VERSION",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:26.399622951Z",
    "created_by": "|6 BUILD_DATE=2020-04-29T06:34:01Z NODEJS_VERSION=12.15.0-r1 PRETTIER_VERSION=2.0.5 REPO_NAME=tmknom/prettier VCS_REF=35d2587 VERSION=2.0.5 /bin/sh -c set -x &&     apk add --no-cache nodejs=${NODEJS_VERSION} nodejs-np
m=${NODEJS_VERSION} &&     npm install -g prettier@${PRETTIER_VERSION} &&     npm cache clean --force &&     apk del nodejs-npm"
  },
  {
    "created": "2020-04-29T06:34:26.764034848Z",
    "created_by": "/bin/sh -c #(nop) WORKDIR /work"
  },
  {
    "created": "2020-04-29T06:34:27.092671047Z",
    "created_by": "/bin/sh -c #(nop)  ENTRYPOINT [\"/usr/bin/prettier\"]",
    "empty_layer": true
  },
  {
    "created": "2020-04-29T06:34:27.406606712Z",
    "created_by": "/bin/sh -c #(nop)  CMD [\"--help\"]",
    "empty_layer": true
  }
]

太棒了!所有的命令都在 created_by 字段中,我们几乎可以用这些命令重建 Dockerfile。但不是完全可以。最上面的 ADD 命令实际上没有给我们需要添加的文件。COPY 命令也没有全部信息。我们还失去了 FROM 语句,因为它们扩展成了从基础 Docker 镜像继承的所有层。

我们可以通过查看 时间戳 timestamp ,按 Dockerfile 对层进行分组。大多数层的时间戳相差不到一分钟,代表每一层构建所需的时间。但是前两层是 2020-04-24,其余的是 2020-04-29。这是因为前两层来自一个基础 Docker 镜像。理想情况下,我们可以找出一个 FROM 命令来获得这个镜像,这样我们就有了一个可维护的 Dockerfile。

manifest.json 展示第一个非空层是 a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar。让我们看看它:

$ cd a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/
$ tar tf layer.tf | head
bin/
bin/arch
bin/ash
bin/base64
bin/bbconfig
bin/busybox
bin/cat
bin/chgrp
bin/chmod
bin/chown

看起来它可能是一个 操作系统 operating system 基础镜像,这也是你期望从典型 Dockerfile 中看到的。Tarball 中有 488 个条目,如果你浏览一下,就会发现一些有趣的条目:

...
dev/
etc/
etc/alpine-release
etc/apk/
etc/apk/arch
etc/apk/keys/
etc/apk/keys/[email protected]
etc/apk/keys/[email protected]
etc/apk/keys/[email protected]
etc/apk/protected_paths.d/
etc/apk/repositories
etc/apk/world
etc/conf.d/
...

果不其然,这是一个 Alpine 镜像,如果你注意到其他层使用 apk 命令安装软件包,你可能已经猜到了。让我们解压 tarball 看看:

$ mkdir files
$ cd files
$ tar xf ../layer.tar
$ ls
bin  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
$ cat etc/alpine-release
3.11.6

如果你拉取、解压 alpine:3.11.6,你会发现里面有一个非空层,layer.tar 与 Prettier 镜像基础层中的 layer.tar 是一样的。

出于兴趣,另外两个非空层是什么?第二层是包含 Prettier 安装包的主层。它有 528 个条目,包含 Prettier、一堆依赖项和证书更新:

...
usr/lib/libuv.so.1
usr/lib/libuv.so.1.0.0
usr/lib/node_modules/
usr/lib/node_modules/prettier/
usr/lib/node_modules/prettier/LICENSE
usr/lib/node_modules/prettier/README.md
usr/lib/node_modules/prettier/bin-prettier.js
usr/lib/node_modules/prettier/doc.js
usr/lib/node_modules/prettier/index.js
usr/lib/node_modules/prettier/package.json
usr/lib/node_modules/prettier/parser-angular.js
usr/lib/node_modules/prettier/parser-babel.js
usr/lib/node_modules/prettier/parser-flow.js
usr/lib/node_modules/prettier/parser-glimmer.js
usr/lib/node_modules/prettier/parser-graphql.js
usr/lib/node_modules/prettier/parser-html.js
usr/lib/node_modules/prettier/parser-markdown.js
usr/lib/node_modules/prettier/parser-postcss.js
usr/lib/node_modules/prettier/parser-typescript.js
usr/lib/node_modules/prettier/parser-yaml.js
usr/lib/node_modules/prettier/standalone.js
usr/lib/node_modules/prettier/third-party.js
usr/local/
usr/local/share/
usr/local/share/ca-certificates/
usr/sbin/
usr/sbin/update-ca-certificates
usr/share/
usr/share/ca-certificates/
usr/share/ca-certificates/mozilla/
usr/share/ca-certificates/mozilla/ACCVRAIZ1.crt
usr/share/ca-certificates/mozilla/AC_RAIZ_FNMT-RCM.crt
usr/share/ca-certificates/mozilla/Actalis_Authentication_Root_CA.crt
...

第三层由 WORKDIR /work 命令创建,它只包含一个条目:

$ tar tf 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar
work/

原始 Dockerfile 在 Prettier 的 git 仓库中


via: https://theartofmachinery.com/2021/03/18/reverse_engineering_a_docker_image.html

作者:Simon Arneaud 选题:lujun9972 译者:DCOLIVERSUN 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

华为称 HMS 已成为全球第三大移动应用生态,有 230 万开发者

2020 年初,华为在海外市场正式发布了 HMS(华为移动服务),用来代替谷歌 GMS。3 月 31 日下午,华为举行了线上发布会,华为公司轮值董事长胡厚崑表示:“2020 年 HMS 已经成为全球第三大移动应用生态,2020 年年底全球注册开发者 230 万,其中国外 30 万,扩展应用超过 12 万个。”华为此前曾公布,截至去年 12 月,HMS 已经在 170 个国家和地区覆盖 5 亿月活用户。

此外,华为还表示鸿蒙 OS 目前已吸引到超过 20 家硬件厂商、280 家应用厂商共同参与生态建设。

Google 从 Android 设备上收集的遥测数据二十倍于苹果

有专家研究了 iOS 和 Android 设备向苹果和 Google 服务器发送的遥测数据。该研究发现即使用户选择退出遥测,iOS 和 Android 仍然会发送遥测数据。当新的 SIM 卡插入到设备中,相关信息会立即与苹果和 Google 共享。设备上预装的应用被发现在未启动或使用前就会连接苹果和 Google 服务器。

研发发现 Google 收集的数据二十倍于苹果。开机 10 分钟内,Pixel 手机向 Google 发送了 1MB 数据,而 iPhone 发送了 42KB;在闲置状态下,Pixel 手机每 12 小时向 Google 发送 1MB 数据,相比之下 iPhone 只向苹果发送 52KB 数据。

这智能手机简直就是一个手机厂商的一个个遥测终端啊。

SCO 继任者 Xinuos 继续对 IBM、红帽发起版权、反垄断诉讼

十年前以 UnXis 的名义围绕 SCO 集团资产组建的 Xinuos,当时表示对继续 SCO 长期以来对 Linux 的诉讼不感兴趣,但是如今又开始起诉 IBM 和红帽涉嫌违反版权和反垄断法。

这家公司在诉状中称,IBM 窃取了 UnixWare 和 OpenServer 代码,并利用所窃取的财产构建和销售与 AIX、z/OS大型机等 Xinuos 本身竞争的产品,并与红帽公司合谋瓜分市场后,随后收购了红帽公司。

SCO 集团在 2003 年也提出了类似的知识产权诉求。它认为,SCO 集团拥有 AT&T 的 Unix 和 UnixWare 操作系统源代码的权利,Linux 2.4.x 和 2.5.x 是 Unix 的未经授权的衍生物,IBM 发布 Linux 代码违反了其合同义务。

这可真是不死不休啊,哦不,连 SCO 公司都没有了也不休。

通过使用 Ansible 自动执行可重复的日常任务,提高工作效率并避免错误。

 title=

如果你讨厌执行重复性的任务,那么我有一个提议给你,去学习 Ansible!

Ansible 是一个工具,它可以帮助你更轻松、更快速地完成日常任务,这样你就可以更有效地利用时间,比如学习重要的新技术。对于系统管理员来说,它是一个很好的工具,因为它可以帮助你实现标准化,并在日常活动中进行协作,包括:

  1. 安装、配置和调配服务器和应用程序;
  2. 定期更新和升级系统;
  3. 监测、减轻和排除问题。

通常,许多这些基本的日常任务都需要手动步骤,而根据个人的技能的不同,可能会造成不一致并导致配置发生漂移。这在小规模的实施中可能是可以接受的,因为你管理一台服务器,并且知道自己在做什么。但当你管理数百或数千台服务器时会发生什么?

如果不小心,这些手动的、可重复的任务可能会因为人为的错误而造成延误和问题,而这些错误可能会影响你及你的组织的声誉。

这就是自动化的价值所在。而 Ansible 是自动化这些可重复的日常任务的完美工具。

自动化的一些原因是:

  1. 你想要一个一致和稳定的环境。
  2. 你想要促进标准化。
  3. 你希望减少停机时间,减少严重事故案例,以便可以享受生活。
  4. 你想喝杯啤酒,而不是排除故障问题!

本文提供了一些系统管理员可以使用 Ansible 自动化的日常任务的例子。我把本文中的剧本和角色放到了 GitHub 上的 系统管理员任务仓库 中,以方便你使用它们。

这些剧本的结构是这样的(我的注释前面有 ==>)。

[root@homebase 6_sysadmin_tasks]# tree -L 2
.
├── ansible.cfg ==> 负责控制 Ansible 行为的配置文件
├── ansible.log
├── inventory
│   ├── group_vars
│   ├── hosts  ==> 包含我的目标服务器列表的清单文件
│   └── host_vars
├── LICENSE
├── playbooks  ==> 包含我们将在本文中使用的剧本的目录
│   ├── c_logs.yml
│   ├── c_stats.yml
│   ├── c_uptime.yml
│   ├── inventory
│   ├── r_cron.yml
│   ├── r_install.yml
│   └── r_script.yml
├── README.md
├── roles    ==> 包含我们将在本文中使用的角色的目录
│   ├── check_logs
│   ├── check_stats
│   ├── check_uptime
│   ├── install_cron
│   ├── install_tool
│   └── run_scr
└── templates ==> 包含 jinja 模板的目录
    ├── cron_output.txt.j2
    ├── sar.txt.j2
    └── scr_output.txt.j2

清单类似这样的:

[root@homebase 6_sysadmin_tasks]# cat inventory/hosts
[rhel8]
master ansible_ssh_host=192.168.1.12
workernode1 ansible_ssh_host=192.168.1.15

[rhel8:vars]
ansible_user=ansible ==> 请用你的 ansible 用户名更新它

这里有五个你可以用 Ansible 自动完成的日常系统管理任务。

1、检查服务器的正常运行时间

你需要确保你的服务器一直处于正常运行状态。机构会拥有企业监控工具来监控服务器和应用程序的正常运行时间,但自动监控工具时常会出现故障,你需要登录进去验证一台服务器的状态。手动验证每台服务器的正常运行时间需要花费大量的时间。你的服务器越多,你需要花费的时间就越长。但如果有了自动化,这种验证可以在几分钟内完成。

使用 check\_uptime 角色和 c_uptime.yml 剧本:

[root@homebase 6_sysadmin_tasks]# ansible-playbook -i inventory/hosts  playbooks/c_uptime.yml -k
SSH password:
PLAY [Check Uptime for Servers] ****************************************************************************************************************************************
TASK [check_uptime : Capture timestamp] *************************************************************************************************
.
截断...
.
PLAY RECAP *************************************************************************************************************************************************************
master                     : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
workernode1                : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
[root@homebase 6_sysadmin_tasks]#

剧本的输出是这样的:

[root@homebase 6_sysadmin_tasks]# cat /var/tmp/uptime-master-20210221004417.txt
-----------------------------------------------------
 Uptime for  master
-----------------------------------------------------
 00:44:17 up 44 min,  2 users,  load average: 0.01, 0.09, 0.09
-----------------------------------------------------
[root@homebase 6_sysadmin_tasks]# cat /var/tmp/uptime-workernode1-20210221184525.txt
-----------------------------------------------------
 Uptime for  workernode1
-----------------------------------------------------
 18:45:26 up 44 min,  2 users,  load average: 0.01, 0.01, 0.00
-----------------------------------------------------

使用 Ansible,你可以用较少的努力以人类可读的格式获得多个服务器的状态,Jinja 模板 允许你根据自己的需要调整输出。通过更多的自动化,你可以按计划运行,并通过电子邮件发送输出,以达到报告的目的。

2、配置额外的 cron 作业

你需要根据基础设施和应用需求定期更新服务器的计划作业。这似乎是一项微不足道的工作,但必须正确且持续地完成。想象一下,如果你对数百台生产服务器进行手动操作,这需要花费多少时间。如果做错了,就会影响生产应用程序,如果计划的作业重叠,就会导致应用程序停机或影响服务器性能。

使用 install\_cron 角色和 r_cron.yml 剧本:

[root@homebase 6_sysadmin_tasks]# ansible-playbook -i inventory/hosts playbooks/r_cron.yml -k
SSH password:
PLAY [Install additional cron jobs for root] ***************************************************************************************************************************
.
截断...
.
PLAY RECAP *************************************************************************************************************************************************************
master                     : ok=10   changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
workernode1                : ok=10   changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

验证剧本的结果:

[root@homebase 6_sysadmin_tasks]# ansible -i inventory/hosts all -m shell -a "crontab -l" -k
SSH password:
master | CHANGED | rc=0 >>
1 2 3 4 5 /usr/bin/ls /tmp
#Ansible: Iotop Monitoring
0 5,2 * * * /usr/sbin/iotop -b -n 1 >> /var/tmp/iotop.log 2>> /var/tmp/iotop.err
workernode1 | CHANGED | rc=0 >>
1 2 3 4 5 /usr/bin/ls /tmp
#Ansible: Iotop Monitoring
0 5,2 * * * /usr/sbin/iotop -b -n 1 >> /var/tmp/iotop.log 2>> /var/tmp/iotop.err

使用 Ansible,你可以以快速和一致的方式更新所有服务器上的 crontab 条目。你还可以使用一个简单的点对点 Ansible 命令来报告更新后的 crontab 的状态,以验证最近应用的变化。

3、收集服务器统计和 sars

在常规的故障排除过程中,为了诊断服务器性能或应用程序问题,你需要收集 系统活动报告 system activity reports (sars)和服务器统计。在大多数情况下,服务器日志包含非常重要的信息,开发人员或运维团队需要这些信息来帮助解决影响整个环境的具体问题。

安全团队在进行调查时非常特别,大多数时候,他们希望查看多个服务器的日志。你需要找到一种简单的方法来收集这些文档。如果你能把收集任务委托给他们就更好了。

通过 check\_stats 角色和 c_stats.yml 剧本来完成这个任务:

$ ansible-playbook -i inventory/hosts  playbooks/c_stats.yml

PLAY [Check Stats/sar for Servers] ***********************************************************************************************************************************

TASK [check_stats : Get current date time] ***************************************************************************************************************************
changed: [master]
changed: [workernode1]
.
截断...
.
PLAY RECAP ***********************************************************************************************************************************************************
master                     : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
workernode1                : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

输出看起来像这样:

$ cat /tmp/sar-workernode1-20210221214056.txt
-----------------------------------------------------
 sar output for workernode1
-----------------------------------------------------
Linux 4.18.0-193.el8.x86_64 (node1)     21/02/21        _x86_64_        (2 CPU)
21:39:30     LINUX RESTART      (2 CPU)
-----------------------------------------------------

4、收集服务器日志

除了收集服务器统计和 sars 信息,你还需要不时地收集日志,尤其是当你需要帮助调查问题时。

通过 check\_logs 角色和 r_cron.yml 剧本来实现:

$ ansible-playbook -i inventory/hosts  playbooks/c_logs.yml -k
SSH password:

PLAY [Check Logs for Servers] ****************************************************************************************************************************************
.
截断...
.
TASK [check_logs : Capture Timestamp] ********************************************************************************************************************************
changed: [master]
changed: [workernode1]
PLAY RECAP ***********************************************************************************************************************************************************
master                     : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
workernode1                : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

为了确认输出,打开转储位置生成的文件。日志应该是这样的:

$ cat /tmp/logs-workernode1-20210221214758.txt | more
-----------------------------------------------------
 Logs gathered: /var/log/messages for workernode1
-----------------------------------------------------

Feb 21 18:00:27 node1 kernel: Command line: BOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-193.el8.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto resume=/dev/mapper/rhel
-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet
Feb 21 18:00:27 node1 kernel: Disabled fast string operations
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
Feb 21 18:00:27 node1 kernel: x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
Feb 21 18:00:27 node1 kernel: x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
Feb 21 18:00:27 node1 kernel: x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'compacted' format.

5、安装或删除软件包和软件

你需要能够持续快速地在系统上安装和更新软件和软件包。缩短安装或更新软件包和软件所需的时间,可以避免服务器和应用程序不必要的停机时间。

通过 install\_tool 角色和 r_install.yml 剧本来实现这一点:

$ ansible-playbook -i inventory/hosts playbooks/r_install.yml -k
SSH password:
PLAY [Install additional tools/packages] ***********************************************************************************

TASK [install_tool : Install specified tools in the role vars] *************************************************************
ok: [master] => (item=iotop)
ok: [workernode1] => (item=iotop)
ok: [workernode1] => (item=traceroute)
ok: [master] => (item=traceroute)

PLAY RECAP *****************************************************************************************************************
master                     : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
workernode1                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

这个例子安装了在 vars 文件中定义的两个特定包和版本。使用 Ansible 自动化,你可以比手动安装更快地安装多个软件包或软件。你也可以使用 vars 文件来定义你要安装的软件包的版本。

$ cat roles/install_tool/vars/main.yml
---
# vars file for install_tool
ins_action: absent
package_list:
  - iotop-0.6-16.el8.noarch
  - traceroute

拥抱自动化

要成为一名有效率的系统管理员,你需要接受自动化来鼓励团队内部的标准化和协作。Ansible 使你能够在更少的时间内做更多的事情,这样你就可以将时间花在更令人兴奋的项目上,而不是做重复的任务,如管理你的事件和问题管理流程。

有了更多的空闲时间,你可以学习更多的知识,让自己可以迎接下一个职业机会的到来。


via: https://opensource.com/article/21/3/ansible-sysadmin

作者:Mike Calizo 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

有多实惠?低于 1000 美元。

 title=

3D 打印机从 20 世纪 80 年代就已经出现了,但是由于 RepRap 项目的出现,它们直到获得开源才受到人们的关注。RepRap 意即 自我复制快速原型机 self-replicating rapid prototyper ,它是一种基本上可以自己打印的 3D 打印机。它的开源计划2004 年 发布之后,导致 3D 打印机的成本从几十万美金降到了几百美金。

这些开源的桌面工具一直局限于 ABS 等低性能、低温热塑性塑料(如乐高积木)。市场上有几款高温打印机,但其高昂的成本(几万到几十万美元)使大多数人无法获得。直到最近,它们才参与了很多竞争,因为它们被一项专利 (US6722872B1) 锁定,该专利于 2021 年 2 月 27 日到期

随着这个路障的消除,我们即将看到高温、低成本、熔融纤维 3D 打印机的爆发。

价格低到什么程度?低于 1000 美元如何。

在疫情最严重的时候,我的团队赶紧发布了一个 开源高温 3D 打印机 的设计,用于制造可高温消毒的个人防护装备(PPE)。该项目的想法是让人们能够 用高温材料打印 PPE(如口罩),并将它放入家用烤箱进行消毒。我们称我们的设备为 Cerberus,它具有以下特点:

  1. 可达到 200℃ 的加热床
  2. 可达到 500℃ 的热源
  3. 带有 1kW 加热器核心的隔离式加热室。
  4. 主电源(交流电源)电压室和床身加热,以便快速启动。

你可以用现成的零件来构建这个项目,其中一些零件你可以打印,价格不到 1000 美元。它可以成功打印聚醚酮酮 (PEKK) 和聚醚酰亚胺(PEI,以商品名 Ultem 出售)。这两种材料都比现在低成本打印机能打印的任何材料强得多。

 title=

这款高温 3D 打印机的设计是有三个头,但我们发布的时候只有一个头。Cerberus 是以希腊神话中的三头冥界看门狗命名的。通常情况下,我们不会发布只有一个头的打印机,但疫情改变了我们的优先级。开源社区团结起来,帮助解决早期的供应不足,许多桌面 3D 打印机都在产出有用的产品,以帮助保护人们免受 COVID 的侵害。

那另外两个头呢?

其他两个头是为了高温熔融颗粒制造(例如,这个开源的 3D打印机 的高温版本)并铺设金属线(像在 这个设计 中),以建立一个开源的热交换器。Cerberus 打印机的其他功能可能是一个自动喷嘴清洁器和在高温下打印连续纤维的方法。另外,你还可以在转台上安装任何你喜欢的东西来制造高端产品。

把一个盒子放在 3D 打印机周围,而把电子元件留在外面的 专利 到期,为高温家用 3D 打印机铺平了道路,这将使这些设备以合理的成本从单纯的玩具变为工业工具。

已经有公司在 RepRap 传统的基础上,将这些低成本系统推向市场(例如,1250 美元的 Creality3D CR-5 Pro 3D 打印机可以达到 300℃)。Creality 销售最受欢迎的桌面 3D 打印机,并开源了部分设计。

然而,要打印超高端工程聚合物,这些打印机需要达到 350℃ 以上。开源计划已经可以帮助桌面 3D 打印机制造商开始与垄断公司竞争,这些公司由于躲在专利背后,已经阻碍了 3D 打印 20 年。期待低成本、高温桌面 3D 打印机的竞争将真正升温!


via: https://opensource.com/article/21/3/desktop-3d-printer

作者:Joshua Pearce 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出