2019年11月

Kubernetes 是一款生产级的开源系统,用于容器化应用程序的自动部署、扩展和管理。本文关于使用 Kubernetes 来管理容器。

“容器”已成为最新的流行语之一。但是,这个词到底意味着什么呢?说起“容器”,人们通常会把它和 Docker 联系起来,Docker 是一个被定义为软件的标准化单元容器。该容器将软件和运行软件所需的环境封装到一个易于交付的单元中。

容器是一个软件的标准单元,用它来打包代码及其所有依赖项,这样应用程序就可以从一个计算环境到另一个计算环境快速可靠地运行。容器通过创建类似于 ISO 镜像的方式来实现此目的。容器镜像是一个轻量级的、独立的、可执行的软件包,其中包含运行应用程序所需的所有信息,包括代码、运行时、系统工具、系统库和设置。

容器镜像在运行时变成容器,对于 Docker 容器,镜像在 Docker 引擎上运行时变成容器。容器将软件与环境隔离开来,确保不同环境下的实例,都可以正常运行。

什么是容器管理?

容器管理是组织、添加或替换大量软件容器的过程。容器管理使用软件来自动化创建、部署和扩展容器。这一过程就需要容器编排,容器编排是一个自动对基于容器的应用程序进行部署、管理、扩展、联网和提供可用性的工具。

Kubernetes

Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,它有助于配置和自动化。它最初由 Google 开发,拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、技术支持和工具得到广泛应用。

Google 在 2014 年开源了 Kubernetes 项目。Kubernetes 建立在 Google 十五年大规模运行生产工作负载的经验基础上,并结合了社区中最好的想法和实践以及声明式句法的使用。

下面列出了与Kubernetes生态系统相关的一些常用术语。

Pod:Pod 是 Kubernetes 应用程序的基本执行单元,是你创建或部署的 Kubernetes 对象模型中的最小和最简单的单元。Pod 代表在 Kubernetes 集群上运行的进程。

Pod 将运行中的容器、存储、网络 IP(唯一)和控制容器应如何运行的命令封装起来。它代表 Kubernetes 生态系统内的单个部署单元,代表一个应用程序的单个实例,该程序可能包含一个或多个紧密耦合并共享资源的容器。

Kubernetes 集群中的 Pod 有两种主要的使用方式。第一种是运行单个容器。即“一个容器一个 Pod”,这种方式是最常见的。第二种是运行多个需要一起工作的容器。

Pod 可能封装一个由紧密关联且需要共享资源的多个同位容器组成的应用程序。

副本集 ReplicaSet :副本集的目的是维护在任何给定时间运行的一组稳定的副本容器集。 副本集包含有关一个特定 Pod 应该运行多少个副本的信息。为了创建多个 Pod 以匹配副本集条件,Kubernetes 使用 Pod 模板。副本集与其 Pod 的链接是通过后者的 metas.ownerReferences 字段实现,该字段指定哪个资源拥有当前对象。

服务 Services :服务是一种抽象,用来公开一组 Pod 功能。使用 Kubernetes,你无需修改应用程序即可使用陌生服务发现机制。Kubernetes 给 Pod 提供了其自己的 IP 地址和一组 Pod 的单个 DNS 名称,并且可以在它们之间负载平衡。

服务解决的一个主要问题是 Web 应用程序前端和后端的集成。由于 Kubernetes 将幕后的 IP 地址提供给 Pod,因此当 Pod 被杀死并复活时,IP 地址会更改。这给给定的后端 IP 地址连接到相应的前端 IP 地址带来一个大问题。服务通过在 Pod 上提供抽象来解决此问题,类似于负载均衡器。

Volumes : Kubernetes 卷具有明确的生命周期,与围绕它的 Pod 相同。 因此,卷超过了 Pod 中运行的任何容器的寿命,并且在容器重新启动后保留了数据。当然,当 Pod 不存在时,该卷也将不再存在。也许比这更重要的是 Kubernetes 支持多种类型的卷,并且 Pod 可以同时使用任意数量的卷。

卷的核心只是一个目录,其中可能包含一些数据,Pod 中的容器可以访问该目录。该目录是如何产生的,它后端基于什么存储介质,其中的数据内容是什么,这些都由使用的特定卷类型来决定的。

为什么选择 Kubernetes?

容器是捆绑和运行应用程序的好方法。在生产环境中,你需要管理运行应用程序的容器,并确保没有停机时间。例如,如果一个容器发生故障,则需要启动另一个容器。如果由系统自动实现这一操作,岂不是更好? Kubernetes 就是来解决这个问题的!Kubernetes 提供了一个框架来弹性运行分布式系统。该框架负责扩展需求、故障转移、部署模式等。例如,Kubernetes 可以轻松管理系统的金丝雀部署。

Kubernetes 为用户提供了:

  1. 服务发现和负载平衡
  2. 存储编排
  3. 自动退出和回退
  4. 自动打包
  5. 自我修复
  6. 秘密配置管理

Kubernetes 可以做什么?

在本文中,我们将会看到一些从头构建 Web 应用程序时如何使用 Kubernetes 的代码示例。我们将在 Python 中使用 Flask 创建一个简单的后端服务器。

对于那些想从头开始构建 Web 应用程序的人,有一些前提条件,即:

  1. 对 Docker、Docker 容器和 Docker 镜像的基本了解。可以访问这里快速了解。
  2. 系统中应该安装 Docker。
  3. 系统中应该安装 Kubernetes,有关如何在本地计算机上安装的说明,请访问这里

现在,创建一个目录,如下代码片段所示:

mkdir flask-kubernetes/app && cd flask-kubernetes/app

接下来,在 flask-kubernetes/app 目录中,创建一个名为 main.py 的文件,如下面的代码片段所示:

touch main.py

在新创建的 main.py 文件中,粘贴下面代码:

from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello from Kubernetes!"
 
if __name__ == "__main__":
    app.run(host='0.0.0.0')

使用下面命令在本地安装 Flask:

pip install Flask==0.10.1

Flask 安装后,执行下面的命令:

python app.py

应该在本地 5000 端口运行 Flask 服务器,这是 Flask 应用程序的默认端口,并且你可以在 http://localhost:5000 上看到输出 “Hello from Kubernetes!”。服务器在本地运行之后,我们创建一个供 Kubernetes 使用的 Docker 镜像。创建一个名为 Dockerfile 的文件,并将以下代码片段粘贴到其中:

FROM python:3.7
 
RUN mkdir /app
WORKDIR /app
ADD . /app/
RUN pip install -r requirements.txt
 
EXPOSE 5000
CMD ["python", "/app/main.py"]

Dockerfile 文件的说明如下:

  1. Docker 将从 DockerHub 获取 Python 3.7 镜像。
  2. 将在镜像中创建一个应用程序目录。
  3. 它将一个 /app 目录设置为工作目录。
  4. 将内容从主机中的应用程序目录复制到镜像应用程序目录。
  5. 发布端口 5000。
  6. 最后,它运行命令,启动 Flask 服务器。

接下来,我们将使用以下命令创建 Docker 镜像:

docker build -f Dockerfile -t flask-kubernetes:latest .

创建 Docker 镜像后,我们可以使用以下命令在本地运行该镜像进行测试:

docker run -p 5001:5000 flask-kubernetes

通过运行容器在本地完成测试之后,我们需要在 Kubernetes 中部署它。我们将首先使用 kubectl 命令验证 Kubernetes 是否正在运行。如果没有报错,则说明它正在工作。如果有报错,请参考该信息

接下来,我们创建一个部署文件。这是一个 Yaml 文件,其中包含有关 Kubernetes 的说明,该说明涉及如何以声明性的方式创建 Pod 和服务。因为我们有 Flask Web 应用程序,我们将创建一个 deployment.yaml 文件,并在其中包含 Pod 和服务声明。

创建一个名为 deployment.yaml 的文件并向其中添加以下内容,然后保存:

apiVersion: v1
kind: Service
metadata:
  name: flask-kubernetes -service
spec:
  selector:
    app: flask-kubernetes
  ports:
  - protocol: "TCP"
    port: 6000
    targetPort: 5000
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-kubernetes
spec:
  replicas: 4
  template:
    metadata:
      labels:
        app: flask-kubernetes
    spec:
      containers:
      - name: flask-kubernetes
        image: flask-kubernetes:latest
        imagePullPolicy: Never
        ports:
          - containerPort: 5000

使用以下命令将 yaml 文件发送到 Kubernetes:

kubectl apply -f deployment.yaml

如果执行以下命令,你会看到 Pod 正在运行:

kubectl get pods

现在,导航至 http://localhost:6000,你应该会看到 “Hello from Kubernetes!”消息。成功了! 该应用程序现在正在 Kubernetes 中运行!

Kubernetes 做不了什么?

Kubernetes 不是一个传统的,包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 运行在容器级别而非硬件级别,因此它提供了 PaaS 产品共有的一些普遍适用功能,如部署、扩展、负载平衡、日志记录和监控。Kubernetes 为开发人员平台提供了构建块,但在重要的地方保留了用户的选择和灵活性。

  • Kubernetes 不限制所支持的应用程序的类型。如果应用程序可以在容器中运行,那么它应该可以在 Kubernetes 上更好地运行。
  • 它不部署和构建源代码。
  • 它不决定日志记录、监视或警报解决方案。
  • 它不提供或不要求配置语言/系统。它提供了一个声明式的 API 供所有人使用。
  • 它不提供或不采用任何全面的机器配置、维护、管理或自我修复系统。

via: https://opensourceforu.com/2019/11/demystifying-kubernetes/

作者:Abhinav Nath Gupta 选题:lujun9972 译者:Morisun029 校对:wxy

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

VirtualBox 是一款自由开源的虚拟化工具,它允许技术人员同时运行多个不同风格的虚拟机(VM)。它通常用于运行桌面(Linux 和 Windows),当人们尝试探索新的 Linux 发行版的功能或希望在 VM 中安装 OpenStack、Ansible 和 Puppet 等软件时,它会非常方便,在这种情况下,我们可以使用 VirtualBox 启动 VM。

VirtualBox 被分类为 2 类虚拟机管理程序,这意味着它需要一个现有的操作系统,在上面安装 VirtualBox 软件。VirtualBox 提供功能来创建本机网络或 NAT 网络。在本文中,我们将演示如何在 CentOS 8 和 RHEL 8 系统上安装最新版本的 VirtualBox 6.0,并演示如何安装 VirtualBox 扩展。

在 CentOS 8 / RHEL 8 上安装 VirtualBox 6.0 的安装步骤

步骤 1: 启用 VirtualBox 和 EPEL 仓库

登录到你的 CentOS 8 或 RHEL 8 系统并打开终端,执行以下命令并启用 VirtualBox 和 EPEL 包仓库:

[root@linuxtechi ~]# dnf config-manager --add-repo=https://download.virtualbox.org/virtualbox/rpm/el/virtualbox.repo

使用以下 rpm 命令导入 Oracle VirtualBox 公钥:

[root@linuxtechi ~]# rpm --import https://www.virtualbox.org/download/oracle_vbox.asc

使用以下 dnf 命令启用 EPEL 仓库:

[root@linuxtechi ~]# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y

步骤 2: 安装 VirtualBox 构建工具和依赖项

运行以下命令来安装所有 VirtualBox 构建工具和依赖项:

[root@linuxtechi ~]# dnf install binutils kernel-devel kernel-headers libgomp make patch gcc glibc-headers glibc-devel dkms -y

成功安装上面的依赖项和构建工具后,使用 dnf 命令继续安装 VirtualBox。

步骤 3: 在 CentOS 8 / RHEL 8 上安装 VirtualBox 6.0

如果希望在安装之前列出 VirtualBox 的可用版本,请执行以下 dnf 命令:

[root@linuxtechi ~]# dnf search virtualbox
Last metadata expiration check: 0:14:36 ago on Sun 17 Nov 2019 04:13:16 AM GMT.
=============== Summary & Name Matched: virtualbox =====================
VirtualBox-5.2.x86_64 : Oracle VM VirtualBox
VirtualBox-6.0.x86_64 : Oracle VM VirtualBox
[root@linuxtechi ~]#

让我们使用以下 dnf 命令安装最新版本的 VirtualBox 6.0:

[root@linuxtechi ~]# dnf install VirtualBox-6.0 -y

如果有本地用户希望将 usb 设备连接到 VirtualBox VM,那么他/她应该是 vboxusers 组的一员,请使用下面的 usermod 命令将本地用户添加到 vboxusers 组。

[root@linuxtechi ~]# usermod -aG vboxusers pkumar

步骤 4: 访问 CentOS 8 / RHEL 8 上的 VirtualBox

有两种方法可以访问 VirtualBox,在命令行输入 virtualbox 然后回车:

[root@linuxtechi ~]# virtualbox

在桌面环境中,在搜索框中搜索 “VirtualBox”。

Access-VirtualBox-CentOS8

单击 VirtualBox 图标:

VirtualBox-CentOS8

这确认 VirtualBox 6.0 已成功安装,让我们安装它的扩展包。

步骤 5: 安装 VirtualBox 6.0 扩展包

顾名思义,VirtualBox 扩展包用于扩展 VirtualBox 的功能。它添加了以下功能:

  • USB 2.0 和 USB 3.0 支持
  • 虚拟 RDP(VRDP)
  • 磁盘镜像加密
  • Intel PXE 启动
  • 主机网络摄像头

使用下面的 wget 命令下载 Virtualbox 扩展包到下载文件夹中:

[root@linuxtechi ~]$ cd Downloads/
[root@linuxtechi Downloads]$ wget https://download.virtualbox.org/virtualbox/6.0.14/Oracle_VM_VirtualBox_Extension_Pack-6.0.14.vbox-extpack

下载后,打开 VirtualBox 并依次点击 “File -> Preferences -> Extension”,然后点击 “+” 号图标添加下载的扩展包:

Install-VirtualBox-Extension-Pack-CentOS8

单击 “Install” 开始安装扩展包:

Accept-VirtualBox-Extension-Pack-License-CentOS8

单击 “I Agree” 接受 VirtualBox 扩展包许可证。

成功安装 VirtualBox 扩展包后,我们将看到下面的页面,单击 “OK” 并开始使用 VirtualBox。

VirtualBox-Extension-Pack-Install-Message-CentOS8

本文就是这些了,我希望这些步骤可以帮助你在 CentOS 8 和 RHEL 8 系统上安装 VirtualBox 6.0。请分享你的宝贵的反馈和意见。


via: https://www.linuxtechi.com/install-virtualbox-6-centos-8-rhel-8/

作者:Pradeep Kumar 选题:lujun9972 译者:geekpi 校对:wxy

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

最好将文档作为开发过程的一部分。Sphinx 加上 Tox,让文档可以轻松书写,并且外观漂亮。

 title=

Python 代码可以在源码中包含文档。这种方式默认依靠 docstring,它以三引号格式定义。虽然文档的价值是很大的,但是没有充足的文档的代码还是很常见。让我们演练一个场景,了解出色的文档的强大功能。

经历了太多在白板技术面试上要求你实现斐波那契数列,你已经受够了。你回家用 Python 写了一个可重用的斐波那契计算器,使用浮点技巧来实现 O(1) 复杂度。

代码很简单:

# fib.py
import math

_SQRT_5 = math.sqrt(5)
_PHI = (1 + _SQRT_5) / 2

def approx_fib(n):
    return round(_PHI**(n+1) / _SQRT_5)

(该斐波那契数列是四舍五入到最接近的整数的几何序列,这是我最喜欢的鲜为人知的数学事实之一。)

作为一个好人,你可以将代码开源,并将它放在 PyPI 上。setup.py 文件很简单:

import setuptools

setuptools.setup(
    name='fib',
    version='2019.1.0',
    description='Fibonacci',
    py_modules=["fib"],
)

但是,没有文档的代码是没有用的。因此,你可以向函数添加 docstring。我最喜欢的 docstring 样式之一是 “Google” 样式。标记很轻量,当它放在源代码中时很好。

def approx_fib(n):
    """
    Approximate Fibonacci sequence

    Args:
        n (int): The place in Fibonacci sequence to approximate

    Returns:
        float: The approximate value in Fibonacci sequence
    """
    # ...

但是函数的文档只是成功的一半。普通文档对于情境化代码用法很重要。在这种情况下,情景是恼人的技术面试。

有一种添加更多文档的方式,专业 Python 人的方式通常是在 docs/ 添加 rst 文件( reStructuredText 的缩写)。因此 docs/index.rst 文件最终看起来像这样:

Fibonacci
=========

Are you annoyed at tech interviewers asking you to implement
the Fibonacci sequence?
Do you want to have some fun with them?
A simple
:code:`pip install fib`
is all it takes to tell them to,
um,
fib off.

.. automodule:: fib
   :members:

我们完成了,对吧?我们已经将文本放在了文件中。人们应该会看的。

使 Python 文档更漂亮

为了使你的文档看起来更漂亮,你可以利用 Sphinx,它旨在制作漂亮的 Python 文档。这三个 Sphinx 扩展特别有用:

  • sphinx.ext.autodoc:从模块内部获取文档
  • sphinx.ext.napoleon:支持 Google 样式的 docstring
  • sphinx.ext.viewcode:将 ReStructured Text 源码与生成的文档打包在一起

为了告诉 Sphinx 该生成什么以及如何生成,我们在 docs/conf.py 中配置一个辅助文件:

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
    'sphinx.ext.viewcode',
]
# 该入口点的名称,没有 .rst 扩展名。
# 惯例该名称是 index
master_doc = "index"
# 这些值全部用在生成的文档当中。
# 通常,发布(release)与版本(version)是一样的,
# 但是有时候我们会有带有 rc 标签的发布。
project = "Fib"
copyright = "2019, Moshe Zadka"
author = "Moshe Zadka"
version = release = "2019.1.0"

此文件使我们可以使用所需的所有元数据来发布代码,并注意扩展名(上面的注释说明了方式)。最后,要确保生成我们想要的文档,请使用 Tox 管理虚拟环境以确保我们顺利生成文档:

[tox]
# 默认情况下,`.tox` 是该目录。
# 将其放在非点文件中可以从
# 文件管理器或浏览器的
# 打开对话框中打开生成的文档,
# 这些对话框有时会隐藏点文件。
toxworkdir = {toxinidir}/build/tox

[testenv:docs]
# 从 `docs` 目录内运行 `sphinx`,
# 以确保它不会拾取任何可能进入顶层目录下的
# 虚拟环境或 `build/` 目录下的其他工件的杂散文件。
changedir = docs
# 唯一的依赖关系是 `sphinx`。
# 如果我们使用的是单独打包的扩展程序,
# 我们将在此处指定它们。
# 更好的做法是指定特定版本的 sphinx。
deps =
    sphinx
# 这是用于生成 HTML 的 `sphinx` 命令。
# 在其他情况下,我们可能想生成 PDF 或电子书。
commands =
    sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
# 我们使用 Python 3.7。
# Tox 有时会根据 testenv 的名称尝试自动检测它,
# 但是 `docs` 没有给出有用的线索,因此我们必须明确它。
basepython = python3.7

现在,无论何时运行 Tox,它都会为你的 Python 代码生成漂亮的文档。

在 Python 中写文档很好

作为 Python 开发人员,我们可以使用的工具链很棒。我们可以从 docstring 开始,添加 .rst 文件,然后添加 Sphinx 和 Tox 来为用户美化结果。

你对好的文档有何评价?你还有其他喜欢的方式么?请在评论中分享它们!


via: https://opensource.com/article/19/11/document-python-sphinx

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

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

Linux 的 date 命令提供了很多显示日期和时间的选项,要比你想的还要多。这是一些有用的选择。

在 Linux 系统上,date 命令非常简单。你键入 date,日期和时间将以一种有用的方式显示。它包括星期几、日期、时间和时区:

$ date
Tue 26 Nov 2019 11:45:11 AM EST

只要你的系统配置正确,你就会看到日期和当前时间以及时区。

但是,该命令还提供了许多选项来以不同方式显示日期和时间信息。例如,如果要显示日期以便进行排序,则可能需要使用如下命令:

$ date "+%Y-%m-%d"
2019-11-26

在这种情况下,年、月和日按该顺序排列。请注意,我们使用大写字母 Y 来获得四位数的年份。如果我们使用小写的 y,则只会看到两位数字的年份(例如 19)。不要让这种做法使你错误地联想到如果 %m 给你一个数字月份,%M 可能会给你月份的名称。不,%M 将给你分钟数。要以缩写名称格式获得月份,你要使用 %b,而对于完全拼写的月份,则要使用 %B

$ date "+%b %B"
Nov November

或者,你可能希望以这种常用格式显示日期:

$ date "+%D"
11/26/19

如果你需要四位数的年份,则可以执行以下操作:

$ date "+%x"
11/26/2019

下面是一个可能有用的示例。假设你需要创建一个每日报告并在文件名中包含日期,则可以使用以下命令来创建文件(可能用在脚本中):

$ touch Report-`date "+%Y-%m-%d"`

当你列出你的报告时,它们将按日期顺序或反向日期顺序(如果你添加 -r)列出。

$ ls -r Report*
Report-2019-11-26
Report-2019-11-25
Report-2019-11-22
Report-2019-11-21
Report-2019-11-20

你还可以在日期字符串中添加其他详细信息。可用的各种选项多得令人惊讶。你可以使用 date "+%q" 来显示你所在的一年中的哪个季度,或使用类似以下命令来显示两个月前的日期:

$ date --date="2 months ago"
Thu 26 Sep 2019 09:02:43 AM EDT

是否想知道下周四的日期?你可以使用类似 date --date="next thu" 的命令,但是要理解,对于Linux,下个周四意味着今天之后的周四。如果今天是星期三,那就是明天,而不是下周的星期四。但是,你可以像下面的第二个命令一样指定下周的星期四。

$ date --date="next thu"
Thu 28 Nov 2019 12:00:00 AM EST
$ date --date="next week thu"
Thu 05 Dec 2019 12:00:00 AM EST

date 命令的手册页列出了其所有选项。该列表多得令人难以置信,但是你可能会发现一些日期/时间显示选项非常适合你。以下是一些你可能会发现有趣的东西。

世界标准时间(UTC):

$ date -u
Tue 26 Nov 2019 01:13:59 PM UTC

自 1970 年 1 月 1 日以来的秒数(与 Linux 系统上日期的存储方式有关):

$ date +%s
1574774137

以下是 date 命令选项的完整列表。正如我所说,它比我们大多数人想象的要广泛得多。

  • %% 显示字母 %
  • %a 本地语言环境的缩写星期名称(例如,日 / Sun)
  • %A 本地语言环境的完整星期名称(例如,星期日 / Sunday)
  • %b 本地语言环境的缩写月份名称(例如 一 / Jan)
  • %B 本地语言环境的完整月份名称(例如,一月 / January)
  • %c 本地语言环境的日期和时间(例如 2005年3月3日 星期四 23:05:25 / Thu Mar 3 23:05:25 2005)
  • %C 世纪;类似于 %Y,但省略了后两位数字(例如,20)
  • %d 月份的天(例如,01)
  • %D 日期;与 %m/%d/%y 相同
  • %e 月份的天,填充前缀空格;与 %_d 相同
  • %F 完整日期;与 %Y-%m-%d 相同
  • %g ISO 周号的年份的后两位数字(请参见 %G
  • %G ISO 周号的年份(请参阅 %V);通常仅配合 %V 使用
  • %h%b 相同
  • %H 24 小时制的小时(00..23)
  • %I 12 小时制的小时(01..12)
  • %j 一年的天(001..366)
  • %k 24 小时制的小时,填充前缀空格( 0..23);与 %_H 相同
  • %l 12 小时制的小时,填充前缀空格( 1..12);与 %_I 相同
  • %m 月份(01..12)
  • %M 分钟(00..59)
  • %n 换行符
  • %N 纳秒(000000000..999999999)
  • %p 本地语言环境中等同于 AM 或 PM 的字符串;如果未知,则为空白
  • %P%p,但使用小写
  • %q 季度(1..4)
  • %r 本地语言环境的 12 小时制时间(例如,晚上 11:11:04 / 11:11:04 PM)
  • %R 24 小时制的小时和分钟;与 %H:%M 相同
  • %s 自 1970-01-01 00:00:00 UTC 以来的秒数
  • %S 秒(00..60)
  • %t 制表符
  • %T 时间;与 %H:%M:%S 相同
  • %u 星期(1..7);1 是星期一
  • %U 年的周号,以星期日为一周的第一天,从 00 开始(00..53)
  • %V ISO 周号,以星期一为一周的第一天,从 01 开始(01..53)
  • %w 星期(0..6);0 是星期日
  • %W 年的周号,星期一为一周的第一天,从 00 开始(00..53)
  • %x 本地语言环境的日期表示形式(例如,1999年12月31日 / 12/31/99)
  • %X 本地语言环境的时间表示形式(例如,23:13:48)
  • %y 年的最后两位数字(00..99)
  • %Y 年份
  • %z +hhmm 格式的数字时区(例如,-0400)
  • %:z +hh:mm 格式的数字时区(例如,-04:00)
  • %::z +hh:mm:ss 格式的数字时区(例如,-04:00:00)
  • %:::z 数字时区,: 指明精度(例如,-04, +05:30)
  • %Z 字母时区缩写(例如,EDT)

via: https://www.networkworld.com/article/3481602/displaying-dates-and-times-your-way-with-linux.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:wxy 校对:校对者ID

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

如果你才刚开始学习 Java 编程,这里有七个你需要知道的基础知识。

Java 是一个多功能的编程语言,在某种程度上,它用在几乎所有可能涉及计算机的行业了里。Java 的最大优势是,它运行在一个 Java 虚拟机(JVM)中,这是一个翻译 Java 代码为与操作系统兼容的字节码的层。只要有 JVM 存在于你的操作系统上 —— 不管这个操作系统是在一个服务器(或“无服务器”,也是同样的)、桌面电脑、笔记本电脑、移动设备,或嵌入式设备 —— 那么,Java 应用程序就可以运行在它上面。

这使得 Java 成为程序员和用户的一种流行语言。程序员知道,他们只需要写一个软件版本就能最终得到一个可以运行在任何平台上的应用程序;用户知道,应用程序可以运行在他们的计算机上,而不用管他们使用的是什么样的操作系统。

很多语言和框架是跨平台的,但是没有实现同样的抽象层。使用 Java,你针对的是 JVM,而不是操作系统。对于程序员,当面对一些编程难题时,这是阻力最小的线路,但是它仅在当你知道如何编程 Java 时有用。如果你刚开始学习 Java 编程,这里有你需要知道的七个基础的提示。

但是,首先,如果你不确定是否你安装了 Java ,你可以在一个终端(例如 BashPowerShell)中找出来,通过运行:

$ java --version
openjdk 12.0.2 2019-07-16
OpenJDK Runtime Environment 19.3 (build 12.0.2+9)
OpenJDK 64-Bit Server VM 19.3 (build 12.0.2+9, mixed mode, sharing)

如果你得到一个错误,或未返回任何东西,那么你应该安装 Java 开发套件(JDK)来开始 Java 开发。或者,安装一个 Java 运行时环境(JRE),如果你只是需要来运行 Java 应用程序。

1、Java 软件包

在 Java 语言中,相关的类被分组到一个软件包中。当你下载 JDK 时所获得的 Java 基础库将被分组到以 javajavax 开头的软件包中。软件包提供一种类似于计算机上的文件夹的功能:它们为相关的元素提供结构和定义(以编程术语说,命名空间)。额外的软件包可以从独立开发者、开源项目和商业供应商获得,就像可以为任何编程语言获得库一样。

当你写一个 Java 程序时,你应该在你的代码是顶部声明一个软件包名称。如果你只是编写一个简单的应用程序来入门 Java,你的软件包名称可以简单地用你的项目名称。如果你正在使用一个 Java 集成开发环境,如 Eclipse,当你启动一个新的项目时,它为你生成一个合乎情理的软件包名称。

package helloworld;

/**
 * @author seth
 * An application written in Java.
 */

除此之外,你可以通过查找它相对于你的项目整体的路径来确定你的软件包名称。例如,如果你正在写一组类来帮助游戏开发,并且该集合被称为 jgamer,那么你可能在其中有一些唯一的类。

package jgamer.avatar;

/**
 * @author seth
 * An imaginary game library.
 */

你的软件包的顶层是 jgamer,并且在其内部中每个软件包都是一个独立的派生物,例如 jgamer.avatarjgamer.score 等等。在你的文件系统里,其目录结构反映了这一点,jgamer 是包含文件 avatar.javascore.java 的顶级目录。

2、Java 导入

作为一名通晓多种语言的程序员,最大的乐趣是找出是否用 includeimportuserequire,或一些其它术语来引入你不管使用何种编程语言编写的库。在 Java 中,顺便说一句,当导入你的代码的需要的库时,使用 import 关键字。

package helloworld;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * @author seth
 * A GUI hello world.
 */

导入是基于该环境的 Java 路径。如果 Java 不知道 Java 库存储在系统上的何处,那么,就不能成功导入。只要一个库被存储在系统的 Java 路径中,那么导入能够成功,并且库能够被用于构建和运行一个 Java 应用程序。

如果一个库并不在 Java 路径中(因为,例如,你正在写你自己的库),那么该库可以与你的应用程序绑定在一起(协议许可),以便导入可以按预期地工作。

3、Java 类

Java 类使用关键字 public class 声明,以及一个唯一的对应于它的文件名的类名。例如,在项目 helloworld 中的一个文件 Hello.java 中:

package helloworld;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * @author seth
 * A GUI hello world.
 */

public class Hello {
        // this is an empty class
}

你可以在一个类内部声明变量和函数。在 Java 中,在一个类中的变量被称为字段

4、Java 方法

Java 的方法本质上是对象中的函数。基于预期返回的数据类型(例如 voidintfloat 等等),它们被定义为 public(意味着它们可以被任何其它类访问)或 private(限制它们的使用)。

    public void helloPrompt(ActionEvent event) {
        String salutation = "Hello %s";
 
        string helloMessage = "World";
        message = String.format(salutation, helloMessage);
        JOptionPane.showMessageDialog(this, message);
    }
 
    private int someNumber (x) {
        return x*2;
    }

当直接调用一个方法时,以其类和方法名称来引用。例如,Hello.someNumber 指向在 Hello 类中的 someNumber 方法。

5、static

Java 中的 static 关键字使代码中的成员可以独立于包含其的对象而被访问。

在面向对象编程中,你编写的代码用作“对象”的模板,这些对象在应用程序运行时产生。例如,你不需要编写一个具体的窗口,而是编写基于 Java 中的窗口类的窗口实例(并由你的代码修改)。由于在应用程序生成它的实例之前,你编写的所有代码都不会“存在”,因此在创建它们所依赖的对象之前,大多数方法和变量(甚至是嵌套类)都无法使用。

然而,有时,在对象被通过应用程序创建前,你需要访问或使用其中的数据。(例如,除非事先知道球是红色时,应用程序无法生成一个红色的球)。对于这些情况,请使用 static 关键字。

6、try 和 catch

Java 擅长捕捉错误,但是,只有你告诉它遇到错误时该做什么,它才能优雅地恢复。在 Java 中,尝试执行一个动作的级联层次结构以 try 开头,出现错误时回落到 catch,并以 finally 结束。如果 try 子句失败,则将调用 catch,最后,不管结果如何,总是由 finally 来执行一些合理的动作。这里是一个示例:

try {
        cmd = parser.parse(opt, args); 
       
        if(cmd.hasOption("help")) {
                HelpFormatter helper = new HelpFormatter();
                helper.printHelp("Hello <options>", opt);
                System.exit(0);
                }
        else {
                if(cmd.hasOption("shell") || cmd.hasOption("s")) {
                String target = cmd.getOptionValue("tgt");
                } // else
        } // fi
} catch (ParseException err) {
        System.out.println(err);
        System.exit(1);
        } //catch
        finally {
                new Hello().helloWorld(opt);
        } //finally
} //try

这是一个健壮的系统,它试图避免无法挽回的错误,或者,至少,为你提供让用户提交有用的反馈的选项。经常使用它,你的用户将会感谢你!

7、运行 Java 应用程序

Java 文件,通常以 .java 结尾,理论上说,可以使用 java 命令运行。然而,如果一个应用程序很复杂,运行一个单个文件是否会产生有意义的结果是另外一个问题。

来直接运行一个 .java 文件:

$ java ./Hello.java

通常,Java 应用程序以 Java 存档(JAR)文件的形式分发,以 .jar 结尾。一个 JAR 文件包含一个清单文件(可以指定主类、项目结构的一些元数据),以及运行应用程序所需的所有代码部分。

要运行一个 JAR 文件,你可以双击它的图标(取决于你的操作系统设置),你也可以从终端中启动它:

$ java -jar ./Hello.jar

适合所有人的 Java

Java 是一种强大的语言,由于有了 OpenJDK 项目及其它的努力,它是一种开放式规范,允许像 IcedTeaDalvikKotlin 项目的茁壮成长。学习 Java 是一种准备在各种行业中工作的好方法,而且,使用 Java 的理由很多


via: https://opensource.com/article/19/10/java-basics

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

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

你是否曾经想过如何备份和还原 Ubuntu 或 Debian 系统?Timeshift 是一款自由开源工具,可让你创建文件系统的增量快照。你可以使用 RSYNC 或 BTRFS 两种方式创建快照。

让我们深入研究并安装 Timeshift。在本教程,我们将安装在 Ubuntu 18.04 LTS 系统上。

在 Ubuntu / Debian Linux 上安装 TimeShift

TimeShift 尚未正式托管在 Ubuntu 和 Debian 仓库中。考虑到这一点,我们将运行以下命令来添加 PPA:

# add-apt-repository -y ppa:teejee2008/ppa

Add timeshift repository

接下来,使用以下命令更新系统软件包:

# apt update

成功更新系统后,使用以下 apt 命令安装 Timeshift:

# apt install timeshift

apt install timeshift

准备备份存储设备

最佳实践要求我们将系统快照保存在系统硬盘之外的单独的存储卷上。对于本指南,我们将使用 16GB 闪存作为第二个驱动器,并在该驱动器上保存快照。

# lsblk | grep sdb

lsblk sdb ubuntu

为了将闪存用作快照的备份位置,我们需要在设备上创建一个分区表。运行以下命令:

# parted /dev/sdb  mklabel gpt
# parted /dev/sdb  mkpart primary 0% 100%
# mkfs.ext4  /dev/sdb1

create partition table on drive ubuntu

在 USB 闪存上创建分区表后,我们可以开始创建文件系统的快照!

使用 Timeshift 创建快照

要启动 Timeshift,使用应用程序菜单搜索 “Timeshift”。

Access timeshift

单击 Timeshift 图标,系统将提示你输入管理员密码。提供密码,然后单击验证。

Authentication required

接下来,选择你喜欢的快照类型。

Select rsync option

点击 “Next”。选择快照的目标驱动器。在这里,我的位置是标记为 /dev/sdb 的外部 USB 驱动器。

Select snapshot location

接下来,定义快照级别。级别是指创建快照的时间间隔。你可以选择每月、每周、每天或每小时的快照级别。

Select snapshot levels

点击 “Finish”。

在下一个窗口中,单击 “Create” 按钮开始创建快照。此后,系统将开始创建快照。

Create snapshot

最后,你的快照将显示如下:

Snapshot created

从快照还原 Ubuntu / Debian

创建系统快照后,现在让我们看看如何从同一快照还原系统。在同一个 Timeshift 中,单击快照,然后单击 “Restore” 按钮,如图所示。

Restore snapshot

接下来,将提示你选择目标设备。保留默认选择,然后点击 “Next”。

Select target device

恢复过程开始之前,Timeshift 将会试运行。

Comparing files dry run

在下一个窗口中,点击 “Next” 按钮确认显示的操作。

Confirm actions

如图所示,你会看到警告和免责声明。点击 “Next” 初始化恢复过程。

此后,将开始还原过程,最后,系统之后将重新启动到快照定义的早期版本。

Restoring snapshot

总结

如你所见,使用 TimeShift 从快照还原系统非常容易。在备份系统文件时,它非常方便,并允许你在系统故障时进行恢复。因此,不要害怕修改系统或弄乱系统。TimeShift 使你能够返回到一切运行平稳的时间点。


via: https://www.linuxtechi.com/timeshift-backup-restore-ubuntu-linux/

作者:James Kiarie 选题:lujun9972 译者:geekpi 校对:wxy

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