• OBS与git的联动应用

    总览

    本文章主要将分为两部分:

    • 利用Source Services(下称源服务)直接获取git源码并编译成包
    • 利用webhook 使源服务在git仓库push时触发,从而实现OBS始终跟进git仓库最新版本源码的效果

    # 此文章的全部步骤使用OBS参考服务器完成,使用其他服务器时可能出现工具不全的情况

    利用源服务直接获取git源码并编译成包

    Source Services 相关

    Source Services 是用于以可靠方式验证,生成或修改源的工具。它们被设计为最小的工具,并且可以按照经典UNIX设计的强大思想进行组合。

    源服务就像是系统中的函数, 我们可以通过运行脚本调用它。而脚本就是Package中的_service文件。

    参考链接: openSUSE Wiki OBS官网文档

    创建使用源服务的Package

    1. 将源服务工具添加到环境中:

      osc meta prj -e [project名]

      在对应<repository>下添加对应环境的工具库:

       <repository name="Fedora_30">
           <path project="openSUSE:Tools" repository="Fedora_30"/>
           <path project="Fedora:30" repository="standard"/>
           <arch>x86_64</arch>
       </repository>
      

      或者使用网页版的方式:

      点击Home Project -> Repositories。

      点击对应环境下方的绿色加号。

      环境标签

      在Project栏填入“openSUSE:Tools”,并在Repositories栏中选择对应环境。

      添加

      点击Accept按钮保存。

    2. 通过命令行工具或者网页新建一个空的Package

      空Package

    3. 进入Package目录并创建_service:

      • 网页端点击“Add file” ,在“File URL:”中填入git链接并保存。
      • 命令行则在Package目录中新建_service文件并上传之服务器。
    4. 准备编辑_service文件

    编辑_service文件

    最基础的_service文件将会如下所示:

    	<services>
    	  <service name="obs_scm">
    	    <param name="scm">git</param>
    	    <param name="url">git://github.com/cs2c-fu/hi.git</param>
    	  </service>
    	  <service name="tar" mode="buildtime"/>
    	  <service name="recompress" mode="buildtime">
    	    <param name="compression">xz</param>
    	    <param name="file">*.tar</param>
    	  </service>
    	  <service name="set_version" mode="buildtime"/>
    	</services>
    

    最外层为<services>标记,在<services>内则为一个个<service>函数,而<param>则为<service>函数的参数。

    为了实现“利用源服务直接获取git源码并编译成包”这个目标,

    我们的_service应该类似于这样:

    <services>
    
      <service name="obs_scm">
        <param name="scm">git</param>
        <param name="filename">helloworld</param>
        <param name="url">git://github.com/cs2c-fu/hi.git</param>
        <param name="versionprefix">VERSION.git</param>
      </service>
    
      <service name="tar" mode="buildtime"/>
    
      <service name="extract_file">
        <param name="archive">*.*</param>
        <param name="files">*/*.spec */*.patch</param>
      </service>
    
      <service name="recompress" mode="buildtime">
        <param name="compression">xz</param>
        <param name="file">*.tar</param>
      </service>
    
      <service name="set_version" mode="buildtime"/>
    
    </services>
    

    下面将对所需的服务逐一进行介绍:

    第一个服务:obs_scm

    obs_scm 会将链接 url 中的仓库下载下来并打包为 obscpio、obsinfo 文件,文件包命名格式为:

    [Name]-[Version].[commit_timestamp].obscpio

    其中,[commit_timestamp]为 commit 十六进制时间戳。

    可选参数:

    • filename 定义打包后文件的 Name,默认为git仓库名。
    • versionprefix 定以打包后文件的 Version 格式,默认为当前十进制时间戳。

    第二个服务:tar

    tar 会将 obs_scm 保存的 obscpio 文件转化为 tar 包文件。

    原本OBS统一使用 tar_scm 来完成 obs_scmtar 的任务,但 tar_scm 在空间利用率上表现不佳,故现在推荐使用 obs_scmtar 来完成下载tar包的任务。

    # 详见:链接

    第三个服务:extract_file

    extract_file 可以从tar包中提取文件, 具体需要提取什么文件取决于git仓库中的文件格式。

    一般来说我们可以将打包需要的内容分为四大类:

    • 源码 : 参与编译过程的文件
    • spec文件 : 指导如何打包的规范文件
    • patch文件 : 修改源码的差异文件
    • 源文件 : 不参与编译但需要打包的文件

    对于git仓库来说,一般会将所有文件放到仓库的根目录。

    git仓库

    此时我们需要将spec文件、patch文件、源文件提取出来, 源码则留在tar包中等待之后的服务将其压缩打包。

    对于OBS仓库来说,为了方便OBS系统使用,人们已经对源码进行压缩打包。

    OBS仓库

    此时我们需要将所有文件提取出来并省略之后的压缩打包环节。

    参数:

    • archive 定义提取来源文件格式
    • files 定义提取文件类型 注意:存在一个顶层目录,其名称未知,因此文件名应以 “*/” 开头

    第四个服务:recompress

    recompress 会对指定文件进行压缩

    参数:

    • compression 压缩格式,可选:none、gz、bz2、xz
    • file 压缩内容

    第五个服务:set_version

    会将spec文件中的Version替换为obs_scm时的

    [Version].[commit_timestamp]

    spec文件中可以以

    helloworld-%{version}.tar.xz

    格式定位源码包。

    等待编译完成

    由于使用源服务获取源码,所以编译时需要额外过程与时间。

    service运行中

    当状态显示为 blocked 时, 表明源服务正在运行。当源服务运行完毕时会正常开始打包过程。

    我的参考案例:链接

    利用 webhook 使源服务在git仓库push时触发

    obs可以创建令牌(token),当令牌被触发时,OBS会运行源服务。

    将网址与令牌添加到git仓库的webhook列表中,就可以在git仓库中实现触发源服务,进而更新OBS中的包版本。

    具体步骤:

    创建专属包的OBS Token(OBS令牌):

    osc token --create <PROJECT> <PACKAGE>
    

    命令将生成仅对Project/Package生效的token。

    • 使用命令 osc token 可以查看当前生效的令牌列表。

    • 使用命令osc token --delete <TOKEN> 可以删除令牌

    打开git仓库网址(以github为例):

    git仓库页

    打开仓库 -> Setting -> Webhooks

    Webhook页

    点击左上方的 Add webhook。

    新建Webhook

    在 Payload URL中以:

    https://<服务器域名>/trigger/webhook?id=<令牌ID>

    为格式填入。

    在 Secret 中填入令牌秘匙,按需求选择trigger类型, 保证Webhook为Active状态。

    之后点击 Add webhook 即成功实现。

    可尝试触发trigger以验证成果。

  • openSUSE15.1系统字符界面下配置网络

    常用命令

    routel: 类似红帽系中的route命令。

    ip a: 类似红帽系中的ifconfig命令。

    service network [start,restart,stop,statu]: opensuse15.1中对网络开始、重启、结束、查询状态的命令

    配置网络

    进入网络配置目录:cd /etc/sysconfig/network/

    编辑默认配置文件:vi ifcfg-eth0

    至如下状态:

    BOOTPROTO=static 		<- 联网模式
    BROADCAST=''
    ETHTOOL_OPTIONS=''
    IPADDR=10.1.30.124		<- IP地址
    MTU=''
    NAME=''
    NETMASK=255.255.255.0	<- 子网掩码
    NETWORK=''
    REMOTE_IPADDR=''
    STARTMODE='auto'		<- 是否自动开启(auto就可以)
    DHCLIENT_SET_DEFAULT_ROUTE='yes'
    

    创建文件/etc/sysconfig/network/routes (这文件默认没有): vi routes

    写入默认网关:

    default [网关ip]
    

    打开网络配置文件:vi config

    NETCONFIG_DNS_STATIC_SERVERS 项后添加DNS地址(以空格做间隔)

    例:

    NETCONFIG_DNS_STATIC_SERVERS="4.4.4.4 8.8.8.8"
    

    重启网络:service network restart

    查看网卡状态:ip a

    确认eth0网卡ip、掩码配置正确

    ip a

    查看路由状态:routel

    确认默认网关配置正确

    routel

    查看/etc/resolv.confvi /etc/resolv.conf

    确认网关配置正确

    resolv.conf

    然后就可以开心的ping www.baidu.com了 :-P

  • Docker Compose初探

    简介

    Docker Compose是docker提供的一个命令行工具,用于定义和运行多容器的应用程序。通过Compose,您可以使用YML文件来配置应用程序需要的所有服务,通过单一命令,就可以根据YML文件配置,创建并启动所有服务。

    对于研发、测试、环境配置,还有CI工作流来说,Compose都是一个不错的工具,更多应用示例请参考: Common use cases

    Compose使用的三个步骤:

    • 使用Dockerfile定义应用程序的环境。

    • 使用docker-compose.yml定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

    • 最后执行docker-compose up命令来启动并运行整个应用程序。

    一个简单的docker-compose.yml配置案例如下:

    version: '2'
    
    services:
      web:
        build: .
        ports:
         - "5000:5000"
        volumes:
         - .:/code
      redis:
        image: redis
    

    详细的docker-compose.yml配置的编写规则请参考:Compose file reference

    Compose通过以下一些命令来管理应用程序的整个生命周期:

    • 启动、停止、重新构建服务

    • 查看正在运行的服务状态

    • 流式处理正在运行的服务的日志输出

    • 对服务运行一次性命令

    安装配置

    安装Docker Compose前,请先确认以下依赖包是否安装: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。

    在Linux操作系统下,从Github上下载它的二进制包来使用,目前最新版本的下载地址:https://github.com/docker/compose/releases

    通过以下命令下载Docker Compose当前的稳定版本:

    curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    

    若想安装其他版本,可直接替换以上命令中版本号1.25.4即可

    将可执行权限应用于二进制文件:

    chmod +x /usr/local/bin/docker-compose
    

    创建软连接:

    ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    

    测试是否安装成功:

    [root@localhost ~]# docker-compose --version
    docker-compose version 1.25.4, build 8d51620a
    

    首次执行docker-compose –version遇到如下错误:

    [root@localhost ~]# docker-compose --version
    [2513] Error loading Python lib '/tmp/_MEIc8S5bO/libpython3.7m.so.1.0': dlopen: libcrypt.so.1: cannot open shared object file: No such file or directory
    

    原因:libcrypt.so.1文件或目录不存在,未安装相关的软件包。

    解决办法:通过dnf whatprovides查找相关文件所属的软件包,安装即可

    [root@localhost ~]# dnf whatprovides '*/libcrypt.so.1'
    上次元数据过期检查:0:28:41 前,执行于 2020年02月25日 星期二 09时34分16秒。
    libxcrypt-compat-4.4.12-1.fc30.i686 : Compatibility library providing legacy API functions
    仓库        :updates
    匹配来源:
    文件名    :/lib/libcrypt.so.1
    
    libxcrypt-compat-4.4.12-1.fc30.x86_64 : Compatibility library providing legacy API functions
    仓库        :updates
    匹配来源:
    文件名    :/lib64/libcrypt.so.1
    
    glibc-arm-linux-gnu-2.27-4.fc29.x86_64 : Cross Compiled GNU C Library targeted at arm-linux-gnu
    仓库        :fedora
    匹配来源:
    文件名    :/usr/arm-linux-gnu/sys-root/lib/libcrypt.so.1
    
    libxcrypt-compat-4.4.4-2.fc30.i686 : Compatibility library providing legacy API functions
    仓库        :fedora
    匹配来源:
    文件名    :/lib/libcrypt.so.1
    
    libxcrypt-compat-4.4.4-2.fc30.x86_64 : Compatibility library providing legacy API functions
    仓库        :fedora
    匹配来源:
    文件名    :/lib64/libcrypt.so.1
    [root@localhost ~]# dnf install libxcrypt-compat
    上次元数据过期检查:0:29:23 前,执行于 2020年02月25日 星期二 09时34分16秒。
    依赖关系解决。
    ===========================================================================================================================================
     Package                               Architecture                Version                              Repository                    Size
    ===========================================================================================================================================
    安装:
     libxcrypt-compat                      x86_64                      4.4.12-1.fc30                        updates                       95 k
    升级:
     libxcrypt                             x86_64                      4.4.12-1.fc30                        updates                      122 k
     libxcrypt-devel                       x86_64                      4.4.12-1.fc30                        updates                       35 k
    
    事务概要
    ===========================================================================================================================================
    安装  1 软件包
    升级  2 软件包
    
    总下载:252 k
    确定吗?[y/N]: y
    下载软件包:
    (1/3): libxcrypt-devel-4.4.12-1.fc30.x86_64.rpm                                                            253 kB/s |  35 kB     00:00
    (2/3): libxcrypt-compat-4.4.12-1.fc30.x86_64.rpm                                                           455 kB/s |  95 kB     00:00
    (3/3): libxcrypt-4.4.12-1.fc30.x86_64.rpm                                                                  433 kB/s | 122 kB     00:00
    -------------------------------------------------------------------------------------------------------------------------------------------
    总计                                                                                                        84 kB/s | 252 kB     00:02
    运行事务检查
    事务检查成功。
    运行事务测试
    事务测试成功。
    运行事务
      准备中  :                                                                                                                            1/1
      升级    : libxcrypt-4.4.12-1.fc30.x86_64                                                                                             1/5
      安装    : libxcrypt-compat-4.4.12-1.fc30.x86_64                                                                                      2/5
      升级    : libxcrypt-devel-4.4.12-1.fc30.x86_64                                                                                       3/5
      清理    : libxcrypt-devel-4.4.4-2.fc30.x86_64                                                                                        4/5
      清理    : libxcrypt-4.4.4-2.fc30.x86_64                                                                                              5/5
      运行脚本: libxcrypt-4.4.4-2.fc30.x86_64                                                                                              5/5
      验证    : libxcrypt-compat-4.4.12-1.fc30.x86_64                                                                                      1/5
      验证    : libxcrypt-4.4.12-1.fc30.x86_64                                                                                             2/5
      验证    : libxcrypt-4.4.4-2.fc30.x86_64                                                                                              3/5
      验证    : libxcrypt-devel-4.4.12-1.fc30.x86_64                                                                                       4/5
      验证    : libxcrypt-devel-4.4.4-2.fc30.x86_64                                                                                        5/5
    
    已升级:
      libxcrypt-4.4.12-1.fc30.x86_64                                    libxcrypt-devel-4.4.12-1.fc30.x86_64
    
    已安装:
      libxcrypt-compat-4.4.12-1.fc30.x86_64
    
    完毕!
    

    应用实例

    使用Docker compose前,请确保Docker以及Docker Compose已经正确安装。

    1. Step 1: 准备应用程序
      • 创建项目目录
       mkdir composetest
       cd composetest
      
      • 在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
       import time
      
       import redis
       from flask import Flask
      
       app = Flask(__name__)
       cache = redis.Redis(host='redis', port=6379)
      
      
       def get_hit_count():
           retries = 5
           while True:
               try:
                   return cache.incr('hits')
               except redis.exceptions.ConnectionError as exc:
                   if retries == 0:
                       raise exc
                   retries -= 1
                   time.sleep(0.5)
      
      
       @app.route('/')
       def hello():
           count = get_hit_count()
           return 'Hello World! I have been seen {} times.\n'.format(count)
      
      

      在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379

      在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:

       flask
       redis
      
    2. Step 2: 创建Dockerfile Dockerfile文件用于构建Docker镜像,这个镜像中包含应用程序需要的Python环境以及相关的依赖。 创建Dockerfile文件,内容如下:

       FROM python:3.7-alpine
       WORKDIR /code
       ENV FLASK_APP app.py
       ENV FLASK_RUN_HOST 0.0.0.0
       RUN apk add --no-cache gcc musl-dev linux-headers
       COPY requirements.txt requirements.txt
       RUN pip install -r requirements.txt
       COPY . .
       CMD ["flask", "run"]
      

      Dockerfile文件注释如下:

      • 使用Python 3.7镜像作为应用程序的基础镜像
      • 设置工作目录:/code
      • 设置flask命令使用的环境变量
      • 安装gcc用于编译
      • 拷贝requirements.txt文件
      • 通过requirements.txt文件安装python相关的依赖项
      • 拷贝项目当前目录到镜像的工作目录
      • 容器提供默认的执行命令为:flask run

      Dockerfile更多相关内容,请移步:

    3. Step 3: 通过Compose配置文件定义应用程序的服务 在项目目录下,创建docker-compose.yml,其内容如下:

       version: '3'
       services:
         web:
           build: .
           ports:
             - "5000:5000"
         redis:
           image: "redis:alpine"
      

      该Compose文件定义了两个服务:web 和 redis。

      • Web service:该web服务使用通过Dockerfile构建的镜像。它将容器和主机绑定到暴露的端口5000。此示例服务使用Flask Web服务器的默认端口5000
      • Redis service:该redis服务使用Docker Hub中的公共Redis映像
    4. Step 4: 使用Compose命令构建和运行应用程序 通过docker-compose up命令启动应用程序:

       [root@localhost composetest]# docker-compose up
       Creating network "composetest_default" with the default driver
       Building web
       Step 1/9 : FROM python:3.7-alpine
       3.7-alpine: Pulling from library/python
       c9b1b535fdd9: Pull complete
       2cc5ad85d9ab: Pull complete
       53a2fca3c2ea: Pull complete
       30fce49de8b1: Pull complete
       ca406aaf66e0: Pull complete
       Digest: sha256:4e91ff3eed8bdd013178b6d8e55f656b394aeea42945f04389e4af5462e7cb6d
       Status: Downloaded newer image for python:3.7-alpine
       ---> a5d195bb2a63
       Step 2/9 : WORKDIR /code
       ---> Running in 383b9c047bc0
       Removing intermediate container 383b9c047bc0
       ---> b1d1aa7fb542
       Step 3/9 : ENV FLASK_APP app.py
       ---> Running in 7c15e2ac5605
       Removing intermediate container 7c15e2ac5605
       ---> eff98003a302
       Step 4/9 : ENV FLASK_RUN_HOST 0.0.0.0
       ---> Running in 5a27ed3f6c64
       Removing intermediate container 5a27ed3f6c64
       ---> be6f583a0052
       Step 5/9 : RUN apk add --no-cache gcc musl-dev linux-headers
       ---> Running in 7cbe2a06a6ff
       fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
       fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
       (1/12) Installing libgcc (9.2.0-r3)
       (2/12) Installing libstdc++ (9.2.0-r3)
       (3/12) Installing binutils (2.33.1-r0)
       (4/12) Installing gmp (6.1.2-r1)
       (5/12) Installing isl (0.18-r0)
       (6/12) Installing libgomp (9.2.0-r3)
       (7/12) Installing libatomic (9.2.0-r3)
       (8/12) Installing mpfr4 (4.0.2-r1)
       (9/12) Installing mpc1 (1.1.0-r1)
       (10/12) Installing gcc (9.2.0-r3)
       (11/12) Installing linux-headers (4.19.36-r0)
       (12/12) Installing musl-dev (1.1.24-r0)
       Executing busybox-1.31.1-r9.trigger
       OK: 131 MiB in 47 packages
       Removing intermediate container 7cbe2a06a6ff
       ---> 8954c4530c9e
       Step 6/9 : COPY requirements.txt requirements.txt
       ---> 8ca0e7e75f7d
       Step 7/9 : RUN pip install -r requirements.txt
       ---> Running in a13015b04175
       Collecting flask
         Downloading Flask-1.1.1-py2.py3-none-any.whl (94 kB)
       Collecting redis
         Downloading redis-3.4.1-py2.py3-none-any.whl (71 kB)
       Collecting click>=5.1
         Downloading Click-7.0-py2.py3-none-any.whl (81 kB)
       Collecting Werkzeug>=0.15
         Downloading Werkzeug-1.0.0-py2.py3-none-any.whl (298 kB)
       Collecting Jinja2>=2.10.1
         Downloading Jinja2-2.11.1-py2.py3-none-any.whl (126 kB)
       Collecting itsdangerous>=0.24
         Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
       Collecting MarkupSafe>=0.23
         Downloading MarkupSafe-1.1.1.tar.gz (19 kB)
       Building wheels for collected packages: MarkupSafe
         Building wheel for MarkupSafe (setup.py): started
         Building wheel for MarkupSafe (setup.py): finished with status 'done'
         Created wheel for MarkupSafe: filename=MarkupSafe-1.1.1-cp37-cp37m-linux_x86_64.whl size=32609 sha256=a4fabd314ab107e7c0d3fde9b41c3dc8a4ea39f9a2f31261e04a67f7815c0357
         Stored in directory: /root/.cache/pip/wheels/b9/d9/ae/63bf9056b0a22b13ade9f6b9e08187c1bb71c47ef21a8c9924
       Successfully built MarkupSafe
       Installing collected packages: click, Werkzeug, MarkupSafe, Jinja2, itsdangerous, flask, redis
       Successfully installed Jinja2-2.11.1 MarkupSafe-1.1.1 Werkzeug-1.0.0 click-7.0 flask-1.1.1 itsdangerous-1.1.0 redis-3.4.1
       Removing intermediate container a13015b04175
       ---> 1f7ad3ce85c3
       Step 8/9 : COPY . .
       ---> 93aa9e4318b7
       Step 9/9 : CMD ["flask", "run"]
       ---> Running in 13ba37d94b83
       Removing intermediate container 13ba37d94b83
       ---> ea3066cef40e
       Successfully built ea3066cef40e
       Successfully tagged composetest_web:latest
       WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use 'docker-compose build' or 'docker-compose up --build'.
       Pulling redis (redis:alpine)...
       alpine: Pulling from library/redis
       c9b1b535fdd9: Already exists
       8dd5e7a0ba4a: Pull complete
       e20c1cdf5aef: Pull complete
       f06a0c1e566e: Pull complete
       230b5c8df708: Pull complete
       0cb9ac88f5bf: Pull complete
       Digest: sha256:cb9783b1c39bb34f8d6572406139ab325c4fac0b28aaa25d5350495637bb2f76
       Status: Downloaded newer image for redis:alpine
       Creating composetest_web_1   ... done
       Creating composetest_redis_1 ... done
       Attaching to composetest_redis_1, composetest_web_1
       redis_1  | 1:C 25 Feb 2020 03:34:13.765 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
       redis_1  | 1:C 25 Feb 2020 03:34:13.765 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
       redis_1  | 1:C 25 Feb 2020 03:34:13.765 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
       redis_1  | 1:M 25 Feb 2020 03:34:13.776 * Running mode=standalone, port=6379.
       redis_1  | 1:M 25 Feb 2020 03:34:13.776 # Server initialized
       redis_1  | 1:M 25 Feb 2020 03:34:13.776 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
       redis_1  | 1:M 25 Feb 2020 03:34:13.776 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
       redis_1  | 1:M 25 Feb 2020 03:34:13.778 * Ready to accept connections
       web_1    |  * Serving Flask app "app.py"
       web_1    |  * Environment: production
       web_1    |    WARNING: This is a development server. Do not use it in a production deployment.
       web_1    |    Use a production WSGI server instead.
       web_1    |  * Debug mode: off
       web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
      

      在本例中,Compose从公共Docker仓库中拉取Redis镜像,在构建镜像时,直接将程序代码静态的拷贝到镜像中,并启动了定义的应用程序服务。

      在浏览器中输入:http://localhost:5000/ 即可看到运行应用程序: app运行

      刷新页面,页面内容如下:

       Hello World! I have been seen 2 times.
      

      如果你想在后台执行该服务可以加上 -d 参数:

       docker-compose up -d
      

      切换终端,通过docker image可查看本地的镜像:

       [root@localhost ~]# docker image list
       REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
       composetest_web     latest              ea3066cef40e        43 minutes ago      222MB
       python              3.7-alpine          a5d195bb2a63        2 weeks ago         97.8MB
       redis               alpine              b68707e68547        5 weeks ago         29.8MB
      

      停止应用程序,有两种方式:

      • 切换终端,通过 docker-compose down 命令停止服务
      • 在服务运行终端,通过 CTRL+C 停止服务服务

    参考文档

  • Docker与Podman的对比分析

    它们是啥

    Docker

    Docker是一个开源的应用容器引擎,属于Linux容器的一种封装,Docker提供简单易用的容器使用接口,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上。容器是完全使用沙箱机制,相互之间不会有任何接口。

    Podman

    Podman是一个无守护进程的容器引擎,用于在Linux系统上开发、管理和运行任何符合 OCI(Open Container Initiative)规范的容器和容器镜像。它可以在root权限下运行,也可以在没有root权限的情况下运行。

    Podman提供的功能与Docker相似,大部分命令与Docker兼容,可以通过设置 alias docker=podman 将命令统一。

    有啥不一样

    1. Docker需要在系统上运行一个守护进程docker daemon,而Podman没有守护进程。Docker需要使用root用户创建容器,而Podman可以在没有root权限的情况下运行

      Docker在Linux上作为守护进程运行,会产生一定的开销,并且还需要任何想创建容器的用户具有root访问权限,一旦授权,就可能存在安全风险。Podman的无守护进程架构就相对的更加灵活和安全。

    2. 容器的启动方式不同:

      Docker CLI命令通过gRPC API跟Docker Engine交互,通知engine需要创建一个container,然后Docker Engine会调用OCI container runtime(runc)来启动一个container。这就代表container的进程不是Docker CLI的子进程,而是Docker Engine的子进程。 Podman没有Daemon,它是直接跟OCI containner runtime(runc)进行交互来创建container的,所以container 的进程直接就是podman的子进程。

      相比较来说Podman这种交互模式就展现出了一些优势:

      • 系统管理员可以知道某个容器进程到底是谁启动的;
      • 如果利用cgroup对podman做一些限制,那么所有创建的容器都会被限制;
      • 如果将podman命令放入systemd单元文件中,容器进程可以通过podman返回通知,表明服务已准备好接收任务;
      • 可以将连接的socket从systemd传递到podman,并传递到容器进程以便使用它们
    3. 容器自动重启的实现不同

      Docker因为有docker daemon,因此docker启动的容器支持–restart策略 Podman没有守护进程,也就不能通过守护进程去实现自动重启容器的功能。若在k8s中,可以通过设置pod重启策略来实现;若在操作系统中,系统通常是以Systemd作为守护进程管理工具,因此可以使用Systemd来实现开机重启容器。

    安装与配置

    下面以Fedora 30安装为例,介绍Docker与Podman的安装配置流程。

    Docker的安装

    1. 添加Docker源

    [root@localhost ~]# dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
    添加仓库自:https://download.docker.com/linux/fedora/docker-ce.repo
    [root@localhost ~]# cat /etc/yum.repos.d/docker-ce.repo
    [docker-ce-stable]
    name=Docker CE Stable - $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/$basearch/stable
    enabled=1
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-stable-debuginfo]
    name=Docker CE Stable - Debuginfo $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/debug-$basearch/stable
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-stable-source]
    name=Docker CE Stable - Sources
    baseurl=https://download.docker.com/linux/fedora/$releasever/source/stable
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-edge]
    name=Docker CE Edge - $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/$basearch/edge
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-edge-debuginfo]
    name=Docker CE Edge - Debuginfo $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/debug-$basearch/edge
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-edge-source]
    name=Docker CE Edge - Sources
    baseurl=https://download.docker.com/linux/fedora/$releasever/source/edge
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-test]
    name=Docker CE Test - $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/$basearch/test
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-test-debuginfo]
    name=Docker CE Test - Debuginfo $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/debug-$basearch/test
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-test-source]
    name=Docker CE Test - Sources
    baseurl=https://download.docker.com/linux/fedora/$releasever/source/test
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-nightly]
    name=Docker CE Nightly - $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/$basearch/nightly
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-nightly-debuginfo]
    name=Docker CE Nightly - Debuginfo $basearch
    baseurl=https://download.docker.com/linux/fedora/$releasever/debug-$basearch/nightly
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    
    [docker-ce-nightly-source]
    name=Docker CE Nightly - Sources
    baseurl=https://download.docker.com/linux/fedora/$releasever/source/nightly
    enabled=0
    gpgcheck=1
    gpgkey=https://download.docker.com/linux/fedora/gpg
    

    2. 安装Docker-CE

    [root@localhost ~]# dnf install docker-ce
    上次元数据过期检查:0:07:02 前,执行于 2020年02月19日 星期三 04时22分53秒。
    依赖关系解决。
    ======================================================================================
     Package              Arch      Version                     Repository           Size
    ======================================================================================
    安装:
     docker-ce            x86_64    3:19.03.6-3.fc30            docker-ce-stable     24 M
    安装依赖关系:
     containerd.io        x86_64    1.2.10-3.2.fc30             docker-ce-stable     23 M
     docker-ce-cli        x86_64    1:19.03.6-3.fc30            docker-ce-stable     39 M
     container-selinux    noarch    2:2.95-1.gite3ebc68.fc30    fedora               46 k
     libcgroup            x86_64    0.41-21.fc30                fedora               61 k
    
    事务概要
    ======================================================================================
    安装  5 软件包
    
    总下载:87 M
    安装大小:363 M
    确定吗?[y/N]: y
    下载软件包:
    (1/5): containerd.io-1.2.10-3.2.fc30.x86_64.rpm       2.3 MB/s |  23 MB     00:10
    (2/5): container-selinux-2.95-1.gite3ebc68.fc30.noarc 107 kB/s |  46 kB     00:00
    (3/5): libcgroup-0.41-21.fc30.x86_64.rpm              592 kB/s |  61 kB     00:00
    (4/5): docker-ce-cli-19.03.6-3.fc30.x86_64.rpm                    1.6 MB/s |  39 MB     00:24
    (5/5): docker-ce-19.03.6-3.fc30.x86_64.rpm                        958 kB/s |  24 MB     00:25
    --------------------------------------------------------------------------------------------------
    总计                                                              3.2 MB/s |  87 MB     00:26
    警告:/var/cache/dnf/docker-ce-stable-75f6791067d84a00/packages/containerd.io-1.2.10-3.2.fc30.x86_64.rpm: 头V4 RSA/SHA512 Signature, 密钥 ID 621e9f35: NOKEY
    Docker CE Stable                                                  1.0 kB/s | 1.6 kB     00:01
    导入 GPG 公钥 0x621E9F35:
     Userid: "Docker Release (CE rpm) <docker@docker.com>"
     指纹: 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
     来自: https://download.docker.com/linux/fedora/gpg
    确定吗?[y/N]: y
    导入公钥成功
    运行事务检查
    事务检查成功。
    运行事务测试
    事务测试成功。
    运行事务
      准备中  :                                                                                   1/1
      安装    : container-selinux-2:2.95-1.gite3ebc68.fc30.noarch                                 1/5
      运行脚本: container-selinux-2:2.95-1.gite3ebc68.fc30.noarch                                 1/5
      安装    : containerd.io-1.2.10-3.2.fc30.x86_64                                                                                                                                                  2/5
      运行脚本: containerd.io-1.2.10-3.2.fc30.x86_64                                                                                                                                                  2/5
      运行脚本: libcgroup-0.41-21.fc30.x86_64                                                                                                                                                         3/5
      安装    : libcgroup-0.41-21.fc30.x86_64                                                                                                                                                         3/5
      安装    : docker-ce-cli-1:19.03.6-3.fc30.x86_64                                                                                                                                                 4/5
      运行脚本: docker-ce-cli-1:19.03.6-3.fc30.x86_64                                                                                                                                                 4/5
      安装    : docker-ce-3:19.03.6-3.fc30.x86_64                                                                                                                                                     5/5
      运行脚本: docker-ce-3:19.03.6-3.fc30.x86_64                                                                                                                                                     5/5
      验证    : containerd.io-1.2.10-3.2.fc30.x86_64                                                                                                                                                  1/5
      验证    : docker-ce-3:19.03.6-3.fc30.x86_64                                                                                                                                                     2/5
      验证    : docker-ce-cli-1:19.03.6-3.fc30.x86_64                                                                                                                                                 3/5
      验证    : container-selinux-2:2.95-1.gite3ebc68.fc30.noarch                                                                                                                                     4/5
      验证    : libcgroup-0.41-21.fc30.x86_64                                                                                                                                                         5/5
    
    已安装:
      docker-ce-3:19.03.6-3.fc30.x86_64  containerd.io-1.2.10-3.2.fc30.x86_64  docker-ce-cli-1:19.03.6-3.fc30.x86_64  container-selinux-2:2.95-1.gite3ebc68.fc30.noarch  libcgroup-0.41-21.fc30.x86_64
    
    完毕!
    

    Docker安装完成,可通过以下方式检测安装:

    [root@localhost ~]# docker version
    Client: Docker Engine - Community
     Version:           19.03.6
     API version:       1.40
     Go version:        go1.12.16
     Git commit:        369ce74
     Built:             Thu Feb 13 01:28:18 2020
     OS/Arch:           linux/amd64
     Experimental:      false
    
    Server: Docker Engine - Community
     Engine:
      Version:          19.03.6
      API version:      1.40 (minimum version 1.12)
      Go version:       go1.12.16
      Git commit:       369ce74
      Built:            Thu Feb 13 01:26:53 2020
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.2.10
      GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
     runc:
      Version:          1.0.0-rc8+dev
      GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
     docker-init:
      Version:          0.18.0
      GitCommit:        fec3683
    [root@localhost ~]#
    

    3. 启动Docker服务

    启动Docker服务

    sudo systemctl start docker
    

    允许Dcoker服务在系统启动时运行

    sudo systemctl enable docker
    

    Docker只允许root和docker用户组中的用户才能使用。基于安全原因,通常不会使用root账户。在docker-ce安装完毕后,Linux系统中会自动创建好docker用户组,可将当前用户添加到docker用户组之中即可。

    sudo usermod -aG docker $(whoami)
    

    4. 配置Docker国内镜像源

    创建/etc/docker/daemon.json文件并写入源地址:

    • Docker中国区官方镜像:https://registry.docker-cn.com
    • 网易:http://hub-mirror.c.163.com
    • ustc:https://docker.mirrors.ustc.edu.cn
    • 中国科技大学:https://docker.mirrors.ustc.edu.cn
    • 阿里云容器服务:https://cr.console.aliyun.com/
    sudo tee /etc/docker/daemon.json  << EOF
    {
      "registry-mirrors": ["https://registry.docker-cn.com"]
    }
    EOF
    

    注意:必须确保daemon.json文件内容为json格式

    Podman的安装

    [root@localhost ~]# dnf install podman
    上次元数据过期检查:0:33:44 前,执行于 2020年02月19日 星期三 06时55分03秒。
    依赖关系解决。
    ======================================================================================================================================================================================================
     Package                                                    Architecture                          Version                                                Repository                              Size
    ======================================================================================================================================================================================================
    安装:
     podman                                                     x86_64                                2:1.7.0-3.fc30                                         updates                                 13 M
    升级:
     libseccomp                                                 x86_64                                2.4.2-2.fc30                                           updates                                 65 k
    安装依赖关系:
     conmon                                                     x86_64                                2:2.0.10-2.fc30                                        updates                                 36 k
     containernetworking-plugins                                x86_64                                0.8.5-1.fc30                                           updates                                 20 M
     containers-common                                          x86_64                                1:0.1.40-2.fc30                                        updates                                 46 k
     fuse3-libs                                                 x86_64                                3.6.2-1.fc30                                           updates                                 88 k
     fuse3                                                      x86_64                                3.4.2-3.fc30                                           fedora                                  45 k
    安装弱的依赖:
     fuse-overlayfs                                             x86_64                                0.7.5-2.fc30                                           updates                                 62 k
     libvarlink-util                                            x86_64                                18-1.fc30                                              updates                                 47 k
     slirp4netns                                                x86_64                                0.4.0-4.git19d199a.fc30                                updates                                 85 k
    
    事务概要
    ======================================================================================================================================================================================================
    安装  9 软件包
    升级  1 软件包
    
    总下载:33 M
    确定吗?[y/N]: y
    下载软件包:
    (1/10): containers-common-0.1.40-2.fc30.x86_64.rpm                                                                                                                     79 kB/s |  46 kB     00:00
    (2/10): conmon-2.0.10-2.fc30.x86_64.rpm                                                                                                                                50 kB/s |  36 kB     00:00
    (3/10): fuse-overlayfs-0.7.5-2.fc30.x86_64.rpm                                                                                                                         75 kB/s |  62 kB     00:00
    (4/10): fuse3-libs-3.6.2-1.fc30.x86_64.rpm                                                                                                                             60 kB/s |  88 kB     00:01
    (5/10): libvarlink-util-18-1.fc30.x86_64.rpm                                                                                                                           31 kB/s |  47 kB     00:01
    (6/10): slirp4netns-0.4.0-4.git19d199a.fc30.x86_64.rpm                                                                                                                 60 kB/s |  85 kB     00:01
    (7/10): fuse3-3.4.2-3.fc30.x86_64.rpm                                                                                                                                  26 kB/s |  45 kB     00:01
    (8/10): libseccomp-2.4.2-2.fc30.x86_64.rpm                                                                                                                             56 kB/s |  65 kB     00:01
    (9/10): podman-1.7.0-3.fc30.x86_64.rpm                                                                                                                                 52 kB/s |  13 MB     04:12
    (10/10): containernetworking-plugins-0.8.5-1.fc30.x86_64.rpm                                                                                                           52 kB/s |  20 MB     06:31
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    总计                                                                                                                                                                   86 kB/s |  33 MB     06:34
    运行事务检查
    事务检查成功。
    运行事务测试
    事务测试成功。
    运行事务
      准备中  :                                                                                                                                                                                       1/1
      安装    : fuse3-libs-3.6.2-1.fc30.x86_64                                                                                                                                                       1/11
      安装    : fuse3-3.4.2-3.fc30.x86_64                                                                                                                                                            2/11
      安装    : fuse-overlayfs-0.7.5-2.fc30.x86_64                                                                                                                                                   3/11
      运行脚本: fuse-overlayfs-0.7.5-2.fc30.x86_64                                                                                                                                                   3/11
      升级    : libseccomp-2.4.2-2.fc30.x86_64                                                                                                                                                       4/11
      安装    : slirp4netns-0.4.0-4.git19d199a.fc30.x86_64                                                                                                                                           5/11
      安装    : libvarlink-util-18-1.fc30.x86_64                                                                                                                                                     6/11
      安装    : containers-common-1:0.1.40-2.fc30.x86_64                                                                                                                                             7/11
      安装    : containernetworking-plugins-0.8.5-1.fc30.x86_64                                                                                                                                      8/11
      安装    : conmon-2:2.0.10-2.fc30.x86_64                                                                                                                                                        9/11
      安装    : podman-2:1.7.0-3.fc30.x86_64                                                                                                                                                        10/11
      清理    : libseccomp-2.4.0-0.fc30.x86_64                                                                                                                                                      11/11
      运行脚本: libseccomp-2.4.0-0.fc30.x86_64                                                                                                                                                      11/11
      验证    : conmon-2:2.0.10-2.fc30.x86_64                                                                                                                                                        1/11
      验证    : containernetworking-plugins-0.8.5-1.fc30.x86_64                                                                                                                                      2/11
      验证    : containers-common-1:0.1.40-2.fc30.x86_64                                                                                                                                             3/11
      验证    : fuse-overlayfs-0.7.5-2.fc30.x86_64                                                                                                                                                   4/11
      验证    : fuse3-libs-3.6.2-1.fc30.x86_64                                                                                                                                                       5/11
      验证    : libvarlink-util-18-1.fc30.x86_64                                                                                                                                                     6/11
      验证    : podman-2:1.7.0-3.fc30.x86_64                                                                                                                                                         7/11
      验证    : slirp4netns-0.4.0-4.git19d199a.fc30.x86_64                                                                                                                                           8/11
      验证    : fuse3-3.4.2-3.fc30.x86_64                                                                                                                                                            9/11
      验证    : libseccomp-2.4.2-2.fc30.x86_64                                                                                                                                                      10/11
      验证    : libseccomp-2.4.0-0.fc30.x86_64                                                                                                                                                      11/11
    
    已升级:
      libseccomp-2.4.2-2.fc30.x86_64
    
    已安装:
      podman-2:1.7.0-3.fc30.x86_64                    fuse-overlayfs-0.7.5-2.fc30.x86_64       libvarlink-util-18-1.fc30.x86_64 slirp4netns-0.4.0-4.git19d199a.fc30.x86_64 conmon-2:2.0.10-2.fc30.x86_64
      containernetworking-plugins-0.8.5-1.fc30.x86_64 containers-common-1:0.1.40-2.fc30.x86_64 fuse3-libs-3.6.2-1.fc30.x86_64   fuse3-3.4.2-3.fc30.x86_64
    
    完毕!
    

    验证:

    通过podman version查看版本信息

    [root@localhost ~]# podman version
    Version:            1.7.0
    RemoteAPI Version:  1
    Go Version:         go1.12.14
    OS/Arch:            linux/amd64
    

    通过podman info查看相关环境信息

    [root@localhost ~]# podman info
    host:
      BuildahVersion: 1.12.0
      CgroupVersion: v1
      Conmon:
        package: conmon-2.0.10-2.fc30.x86_64
        path: /usr/bin/conmon
        version: 'conmon version 2.0.10, commit: 35d9b09d9d2791c7167091a9f25792535a380967'
      Distribution:
        distribution: fedora
        version: "30"
      MemFree: 308760576
      MemTotal: 4123508736
      OCIRuntime:
        name: runc
        package: containerd.io-1.2.10-3.2.fc30.x86_64
        path: /usr/bin/runc
        version: |-
          runc version 1.0.0-rc8+dev
          commit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
          spec: 1.0.1-dev
      SwapFree: 3047591936
      SwapTotal: 3057643520
      arch: amd64
      cpus: 1
      eventlogger: journald
      hostname: localhost
      kernel: 5.4.18-100.fc30.x86_64
      os: linux
      rootless: false
      uptime: 13h 36m 0.97s (Approximately 0.54 days)
    registries:
      search:
      - docker.io
      - registry.fedoraproject.org
      - quay.io
      - registry.access.redhat.com
      - registry.centos.org
    store:
      ConfigFile: /etc/containers/storage.conf
      ContainerStore:
        number: 0
      GraphDriverName: overlay
      GraphOptions:
        overlay.mountopt: nodev,metacopy=on
      GraphRoot: /var/lib/containers/storage
      GraphStatus:
        Backing Filesystem: extfs
        Native Overlay Diff: "false"
        Supports d_type: "true"
        Using metacopy: "true"
      ImageStore:
        number: 0
      RunRoot: /var/run/containers/storage
      VolumePath: /var/lib/containers/storage/volumes
    

    参考文档

  • OBS使用简介

    OBS是什么

    OBS是Open Build Service 的简写(官方网址:https://openbuildservice.org/),

    原本是作为发行版openSUSE专用的rpm打包的平台, 后续扩展为面向多发行版、多架构、多格式的打包发布平台。

    OBS 系统结构。图自论文《集群模式操作系统软件包生成系统的研究与实现》

    与koji的不同

    • 管理范围

      与koji只管理包(包括源码包与二进制包)仓库不同, OBS同时管理着源码与包两个仓库。

      koji是从一个包编译完成后开始接手,他根据包的NVR(Name-Version-Release)确定包的位置, 在编译验证后入库保存。而OBS是从源码阶段开始管理,他拥有自己的包版本标记与changelog日记。

      OBS可以像git一样保存源码的历史版本,对源码进行分支管理。并生成各版本的二进制包与源码包。

      换句话说, OBS可以同时实现koji和git的功能(但注意,OBS接受源码的格式与git普遍的保存格式并不相同,所以OBS无法完全取代git的作用)。

    • 适用格式

      OBS可以生成rpm、Debian、Arch等格式的包。而koji只适用于rpm格式。

    OBS使用

    安装osc(OBS的命令行程序):

    打开网址:https://download.opensuse.org/repositories/openSUSE:/Tools/

    选择自己的系统版本,添加软件源到自身包管理器中。

    例:  
        fc30 将文件`http://download.opensuse.org/repositories/openSUSE:/Tools/Fedora_30/openSUSE:Tools.repo`另存到/etc/yum.repo.d/中(需要root权限)。
    

    安装osc

    dnf install osc

    注册OBS网页账号:

    打开网址:https://build.opensuse.org/

    点击右上角“Sign Up”,注册自己喜欢的帐号。

    注册完成后,重新回到上面网址。点击右上角的“Login”,用新账户登录。

    系统会在注册时自动创建一个以“home:用户名”为格式命名的Home Project。

    创建本地目录

    创建obs工作目录: mkdir ~/obs

    进入obs工作目录: cd ~/obs

    将远程obs库同步到本地: osc checkout home:用户名

    输入网页用户名与密码

    登陆OBS

    第一次登陆时会询问本地密码保存方式,三种方式分别是:

    1. 明文保存
    2. 加密保存
    3. 不保存(需要每次输入)

    三种密码保存方式

    推荐选择2

    同步结束后可以看到当前目录下有以Project名命名的文件夹。

    配置Project:

    两种方法:网页操作、命令行操作

    • 网页操作:

      在obs主页点击右上角

      主页右上角

      依次进入 Home Project -> Repositories -> Add from a Distribution 。

      Add from a Distribution页

      在此界面选择编包时使用的基础发行版环境。

      在选择后后退至Repositories界面,可以看到如下图所示的环境:

      环境标签

      • 第一个为编辑按钮, 可以选择当前发行版编译架构
      • 第二个为添加按钮, 可在发行版标准环境上额外添加单独的包(例如其他私人编译的依赖包)
      • 第三个为下载, 点击后转到当前环境的仓库
      • 第四个为删除
    • 命令行操作:

      执行命令: osc meta prj -e [project名] 会看到如下文本。

      meta配置

      其中,

      • repository标签为仓库标签, 可添加此项添加编译时的基础环境
      • Path标签为可用包路径标签, 需手动添加发行版包路径。如需要额外依赖, 也可以单独添加。
      • Arch标签为编译架构, 可同时添加多个。

      例:

          <repository name="Fedora_30_standard">
            <path project="Fedora:30" repository="standard"/>
            <path project="Fedora:29" repository="standard"/>    //此为额外添加依赖
            <arch>i586</arch>
            <arch>x86_64</arch>    //此为多架构选项
          </repository>
      

    新建包:

    进入Project目录: cd [project名]

    新建Package: osc mkpac [package名]

    进入Package目录并将下载源码以【tar包、所有patch、spec文件、其他source文件】格式放置:

    目录格式

    向新创建的package中添加以上文件: osc add *

    osc add

    将更改上传至服务器: osc commit

    commit介绍

    在这里可以注明本次上传的简短介绍,用“:wq”保存并退出

    之后就可以在网页上等待编译并查看结果了。

    查看包状态与下载包

    你可以在Project与Package主页右侧看到当前编译状态

    编译状态

    • finished 表示在某个系统平台执行编译链接、安装检查的过程结束
    • succeeded 状态为编译成功,
    • failed 为编译失败,你可以点击以查看日志

    你可以点击 编译平台 -> “Go to download repository” 到达编译仓库,

    在仓库你可以获得此Project的repo源与所有编译成功的package。

    更新包

    进入project文件夹: cd [project名]

    更新本地代码为最新代码: osc up

    进入package目录,使用 osc add 命令将新文件添加到package,修改spec文件后使用osc commit命令上传新版本。

  • gRPC调研: 基于HTTP2的gRPC框架实现

    gRPC简介

    gRPC是由Google主导开发、可以在任何环境中运行的开源高性能RPC(远程过程调用)框架,基于HTTP2和Protobuf实现。gRPC是跨语言的RPC框架,采用了IDL来描述数据类型和接口,使用编译器编译出特定语言的代码从而实现跨语言的RPC。

    • 简单的服务定义
      使用Protobuf,功能强大的二进制序列化工具集和语言定义服务
    • 快速启动并扩展
      只需一行即可安装运行和开发环境,并通过该框架每秒可扩展至数百万个RPC
    • 跨语言和平台工作
      自动以多语言多平台为服务生成惯用的客户端和服务器stubs
    • 双向流和集成身份验证
      基于HTTP2实现双向流传输和完全集成的身份验证

      gRPC是Cloud Native Computing基金会的孵化项目

    什么是RPC?

    假设有两台服务器A、B,应用a部署在A服务器上,想要调用B服务器上应用b提供的函数/方法,由于不在同一个内存空间,不能直接调用,此时需要网络来表达调用的语义和传达调用的数据。可用于多台机器组成的集群上部署应用。

    RPC的解决问题的过程如下:

    • 在客户端和服务器之间建立TCP连接,所有调用时交换的数据都在连接里传输。多个远程过程调用共享同一个连接。
    • 解决寻址问题。服务器A上的应用a如何告知底层的RPC框架连接到服务器B(通过主机或IP地址)以及特定的端口,方法的名称等,这样才能完成调用。比如,基于Web服务协议栈的RPC,需要提供endpoint URI;如果RMI(Remote Method Invocation,远程方法调用)的话,还需要一个RMI Registry来注册服务的地址。
    • 当服务器A上的应用a发起RPC时,方法的参数值序列化为二进制的形式,基于底层网络协议,如TCP,通过寻址和传输传递到服务器B。
    • 服务器B收到请求后,对参数进行反序列化,恢复为内存中的表达方式,找到对应的方法(寻址的一部分)进行本地调用,得到返回值。
    • 返回值序列化后发送回服务器A上的应用a,接收后,经历反序列化+恢复,传递给服务器A上的应用。

    可以理解为,RPC就是从一台机器(Client)上通过传参的方式调用另一台机器(Server)上的一个方法(统称为服务)并得到返回的结果。RPC会隐藏底层的通讯细节,即不需要直接处理Socket或HTTP通讯,它是一个请求响应模型:客户端发起请求,服务器返回响应,这是一种类似HTTP的工作方式,在形式上类似调用本地方法,只不过依靠网络可以调用远程的方法。
    RPC框架的出现让调用者不必关心底层细节,处理了数据序列化、反序列化、连接管理、收发线程、超时处理等问题,是一种优秀的微服务架构。

    gRPC如何在HTTP2上传输

    gRPC请求&响应流程

    gRPC在HTTP2的基础上定义了request和response的规范。
    以下是gRPC请求&响应消息流中消息原子的一般顺序:

    • 请求 -> 请求报头*界定的消息(Length-Prefixed-Message)及EOS

      长度前缀法适用于二进制协议,HTTP协议的Content-Length头信息用来标记消息体的长度,也可以视为是长度前缀法的一种应用。

    gRPC的请求报头直接使用HTTP2头部,在HEADERS+CONTINUATION帧中传递。
    举例说明:单独调用HTTP2帧序列

    HEADERS (flags = END_HEADERS)
    :method = POST
    :scheme = http
    :path = /google.pubsub.v2.PublisherService/CreateTopic
    :authority = pubsub.googleapis.com
    grpc-timeout = 1S
    content-type = application/grpc+proto
    grpc-encoding = gzip
    authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v
    
    DATA (flags = END_STREAM)
    <Length-Prefixed Message>
    
    • 响应 -> (响应报头*界定消息尾部)/仅尾部
      每个响应报头&尾部在单个HTTP2 HEADERS帧块(frame block)中传递。
      对于响应,流的结束是通过最后接收到的带有尾部的HEADERS帧上存在的END_STREAM标志来指示。
      举例说明:单独调用HTTP2帧序列
    HEADERS (flags = END_HEADERS)
    :status = 200
    grpc-encoding = gzip
    content-type = application/grpc+proto
    
    DATA
    <Length-Prefixed Message>
    
    HEADERS (flags = END_STREAM, END_HEADERS)
    grpc-status = 0 # OK
    trace-proto-bin = jher831yy13JHy3hc
    

    HTTP2传输映射

    • 流识别
      所有GRPC调用都需要指定一个内部ID。 在此方案中,我们将使用HTTP2流ID作为调用标识符。注意:这些ID与打开的HTTP2会话相关,并且在处理给定的多个HTTP2会话进程中不是唯一的,也不能用作GUID。
    • 数据帧
      数据帧边界与长度前缀消息边界没有任何关系,实现中不应对数据对齐方式进行任何假设。
    • 错误
      在RPC应用程序或运行时错误时,状态和状态消息将在尾部中传递。
    • 安全
      HTTP2要求使用TLS 1.2或更高版本,对部署中允许的密码有额外约束,以避免已知安全问题,还有需要SNI支持的情况。
    • GOAWAY帧
      由于Stream ID不可被重复使用,如果一条连接上的ID分配完毕,客户端会新建一条连接,服务器则发送给客户端一个GOAWAY帧以指示它们将不再接受关联连接上的任何新流。该帧包含服务器上次成功接受的流的ID。客户应将在最后一个成功接受的流之后发起的任何流视为“不可用”,然后在其他地方重试该调用。客户端可以自由地继续使用已经接受的流,直到它们完成或连接终止。服务器应在终止连接之前发送GOAWAY,通知客户端服务器已接受并正在执行哪些工作。
    • PING帧
      客户端和服务器都可以发送PING帧,对方必须通过准确地回显它们收到的内容来响应。这用于断言该连接仍然有效,并提供一种估算端到端延迟的方法。 如果服务器启动的PING在运行时预期的期限内未收到响应,则服务器上所有未完成的呼叫将以CANCELED状态关闭。 客户端启动的PING过期将导致所有呼叫以UNAVAILABLE状态关闭。
    • 连接失败
      如果客户端上发生可检测到的连接失败,则所有调用将以UNAVAILABLE状态关闭。对于服务器,已开放的调用将以“已取消”状态关闭。

      总结:HTTP2是如何在gRPC中发挥优势的?

      我们可以通过令HTTP2的优势与其在gRPC中的实现一一对应来总结这个问题:

    • 二进制成帧和压缩
      RPC框架中,传参的值是二进制格式的,HTTP2采用二进制格式传输数据,对机器更为友好,使得HTTP2协议在发送和接收方面都是紧凑而高效的。
    • 单个TCP连接和多路复用
      根据帧首部的流标识,可以重新组装多个乱序发送的帧,使得在单个连接可以承载任意数量的双向数据流。HTTP2是标准协议,其流式传输特性完全适合gRPC的要求,因此无需重新设计即可利用。在单个TCP连接上多路复用同时消除了行头阻塞。
    • 服务器推送
      HTTP2可以让服务器预测并提前推送给客户端需要的资源。此外,gRPC可以智能地选择向哪个后端发送流量。(库功能,而不是有线协议功能)。这意味着可以将请求发送到负载最少的后端服务器,而无需使用代理。
    • Protobuf

      序列化用Protobuf,通信用HTTP2

    gRPC 的 service 接口是基于 protobuf 定义的,我们可以非常方便的将 service 与 HTTP/2 关联起来,在HTTP2之上带来额外的优势。格式如下:

    Path : /Service-Name/{method name}  
    Service-Name : ?( {proto package name} "." ) {service name}  
    Message-Type : {fully qualified proto message name}  
    Content-Type : "application/grpc+proto"  
    

    HTTP2的这些优点为gRPC的高性能提供了保障,而gRPC也为通过HTTP2进行流传输提供了广泛的支持(无串流、服务器到客户端流、客户端到服务器流、双向流),在延迟和网络吞吐量方面的表现都很优秀(特别是比起传统的REST+HTTP1),更适用于分布式部署。这些特性使得gRPC在移动设备上表现尤为出色,更省电、节省空间占用。
    当然,gRPC也有其劣势:由于gRPC大量使用HTTP2功能,没有浏览器能提供Web请求所需的控制级别来支持gRPC客户端,比如不允许调用者使用HTTP的要求,或提供对基础HTTP帧的访问(Chrome会崩溃的)。gRPC-Web是gRPC团队的另一项技术,可以在浏览器中提供优先的gRPC。gRPC-Web由两部分组成,一个支持所有现代浏览器的JavaScript客户端,以及服务器上的一个gRPC-Web代理。gRPC-Web客户端调用代理,代理将根据gRPC请求转发到gRPC服务器。gRPC-Web并非支持所有gRPC的功能。不支持客户端和双向流,并且对服务器流的支持有限。
    由于gRPC消息使用Protobuf编码。尽管Protobuf可以高效地发送和接收,但其二进制格式不是人类可读的。Protobuf要求在.proto文件中指定的消息接口描述才能正确反序列化。需要额外的工具来分析网上的Protobuf有效载荷并手动撰写请求。为了解决这个问题,存在诸如服务器反射和gRPC命令行工具之类的功能来辅助二进制Protobuf消息。此外,protobuf消息支持与JSON之间的转换。内置的JSON转换提供了一种在调试时将Protobuf消息与人类可读格式之间相互转换的有效方法。

    gRPC相关项目

    gRPC该存储库包含在共享C核心库src / core之上编写的以多种语言实现的gRPC库的源代码,并欢迎对其代码库做出贡献。 在大多数语言中,gRPC运行时是作为软件包提供的。不同语言的gRPC库处于发展状态,正在寻求贡献:

    Language Source Repo
    Java grpc-java
    Go grpc-go
    Language Source
    Shared C [core library] src/core
    C++ src/cpp
    Ruby src/ruby
    Python src/python
    PHP src/php
    C#(core library based) src/csharp

    ref

    谁能用通俗的语言解释一下什么是 RPC 框架?
    RPC简介及框架选择
    gRPC学习笔记
    grpc.io
    gRPC over HTTP2
    无所不能的RPC消息协议是如何设计的?
    深入了解 gRPC:协议
    Is gRPC(HTTP/2) faster than REST with HTTP/2?
    开源中国翻译:gRPC官方文档中文版
    Compare gRPC services with HTTP APIs

  • Prometheus简介和框架

    本文翻译自Prometheus官网,介绍了Prometheus系统构架和基础搭建。

    简介

    Prometheus是一套开源的系统监控警报工具包,初始建立在Soundclouds,作为紧随Kubernetes之后第二个托管项目,于2016年正式加入Cloud Native Computing Foundation。

    特性

    • 一个多维度的数据模型,时间序列通过Metric名和键值对来区分。
    • 灵活的查询语句PromQL:可以通过多个Metrics进行维度性的操作如乘法,加法,连接等
    • 不依赖于分布式储存:Prometheus server是一个单服务器节点
    • 使用pull模式采集时间序列数据
    • 通过中间网关(intermediary gateway)支持推送时间序列
    • 通过服务发现或者静态配置去获取监控的 targets。
    • 有多种可视化图形界面

    组件及构成

    architecture

    • Prometheus Server: 用于收集和存储时间序列数据。
    • Client Library:客户端库,检测应用代码。
    • Push Gateway: 支持短期的 jobs。
    • Exporters: 用于暴露已有的第三方服务的 metrics 给 Prometheus,例如 HAProxy, StatsD, Graphite等。
    • Alertmanager:处理从Prometheus server接受到的Alert,进行处理后发出警报。
    • 及其他可选项

    大致工作流程

    1. 由Prometheuss server从被配置好的jobs中 拉取拉取Metrics。
    2. Prometheus server 在本地存储收集到的 metrics,并运行已定义好的 alert.rules以便聚合或记录新的实践序列或者推送警报。
    3. Grafana 或其他 API 使用者可用于可视化收集的数据。

    初始化配置

    下载

    从平台下载最新发布的Prometheus,然后解压缩

    tar xvfz prometheus-*.tar.gz
        cd prometheus-*
    

    Prometheus server是一个single binary文件(Windows中是prometheus.exe),可以使用–help flag去运行和查找帮助

       ./prometheus --help
        usage: prometheus [<flags>]
        The Prometheus monitoring server
        . . .
    

    在启动Prometheus之前需要先完成配置

    配置

    Prometheus使用YAML配置,初始化下载中包含一个叫做prometheus.yml的配置文件,可以从这里开始。

    global:
      scrape_interval:     15s
      evaluation_interval: 15s
    
    rule_files:
      # - "first.rules"
      # - "second.rules"
    
    scrape_configs:
      - job_name: prometheus
        static_configs:
          - targets: ['localhost:9090']
    

    示例中代码主要分成3部分:global, rule_files, 和scrape_configd。

    global 用来管理Prometheus server的通用配置。有两种呈现,分别是记录scrape频率的scrape_interval,例子里是15s。第二个是评估Rules的频率,Prometheus使用rules创建新的时间序列或生成警报。

    rule_files指定用户希望Prometheus server加载的Rules的位置,目前示例中为空。

    scrape_configs 管理Prometheus 监控的资源。在默认配置中,job名为 Prometheus,它scrape(拉取) Prometheus server公开的时间序列数据。这个Job包含一个单个静态的target,Localhost在port 9090。 metrics一般存在路径/metrict,所以默认配置URL地址为: http://localhost:9090/metrics

    更多配置信息可查看这个网页: https://prometheus.io/docs/prometheus/latest/configuration/configuration/ ###启动Prometheus 启动修改过配置文件的通过更改config.file地址

     ./prometheus --config.file=prometheus.yml
    

    启动成功后就可以通过打开 http://localhost:9090 查看相关状态页了,可能需要30s的时间去收集信息。 打开 http://localhost:9090/metrics 可以浏览metrics终端。

    Ref

    1. Prometheus Overview
    2. ibm.com developerworks
    3. Prometheus 安装与配置
    4. Prometheus 系统监控方案
  • git使用指南

    git指南

    本文基于个人git使用经验总结而成,可供初学者上手参考,欢迎补充与指正! 下载安装config以及添加ssh等请自行搜索完成。

    git仓库

    本地 fork 上游
    local origin upstream
    基于本地仓库修改代码 自己fork的仓库,拥有修改权限,可以push本地代码 源仓库,一般没有修改权限,所以无法直接push;拥有最新版本的代码

    本地仓库初始化相关命令

    需求分析:

    我要开始为开源社区做贡献了!

    git初始化命令

    新建本地目录,在该目录下进行如下操作:

    已有项目远程仓库

    1. 下载代码
      git clone origin_ssh_url
    2. 添加与之关联的上游仓库(名字可以随意,建议命名为upstream)
      git remote add upstream upstream_ssh_url
      ok,到这里就把github里的项目挪到本地了,下一步是开发前的准备——更新/新建分支。

    本地项目尚未上传

    1. 初始化本地git仓库
      git init
    2. 添加与之关联的fork仓库(名字可以随意,建议命名为origin)
      git remote add origin origin_ssh_url
    3. 确认关联仓库
      git remote -v

    更新本地代码

    需求分析:

    1. upstream仓库有更新,而自己fork的origin仓库和本地代码不会自动与之同步。
    2. 其他原因导致本地代码落后于upstream(或origin,极特殊情况)的代码

    实际上,origin/master是不需要单独更新的,因为只要将local/master更新至upstream/master,就可以在本地master的基础上新建本地分支,基于最新代码进行修改。修改完成后再push至origin上。

    git更新本地代码命令

    1. 拉取上游代码
      git fetch upstream git fetch upstream
    2. 同步本地分支 local/master -> upstream/master
      git rebase upstream/master
      git rebase upstream/master
    3. 此时使用git status查看状态
      git status
      会发现本地代码已经同步了上游的代码,领先了origin的代码,此时已经可以开始开发了。如果你非要让origin也同步: git push origin master
      接下来就可以进行开发了~

    分支

    需求分析:

    1. 需要开发多个独立的功能,并以pr的方式逐一提交。
    2. 需要保留master上的代码。

    注:

    分支同样分为本地(local)分支、origin分支、upstream分支。
    一般在本地,与上游代码同步后,基于local/master新建本地分支,该分支中的代码继承master,且在该分支上的改动不会影响local/master中的代码。
    建议开发时,尽量将不同分支上开发无互相依赖的不同功能,如在branch A上开发A功能,切换到branch B上开发B功能……
    分支之间互不影响,但仍然要注意是否有依赖,否则会在合并时出现冲突。尽量使各功能的开发独立。

    开发新功能时请记得切换回到master再新建分支!!

    git分支常用命令

    git checkout branch_name 切换至branch_name分支
    git checkout -b new_branch 新建并切换至new_branch分支
    git branch -a 查看所有分支(标记的为所在分支)
    git branch -D branch_name 删除本地的branch_name分支(请不要直接在该分支上做这种过河拆桥的事情),该操作不会影响远程仓库的分支
    git push origin :branch_namegit push origin --delete branch_name 删除远程分支——fork仓库的branch_name分支

    提交本地代码

    需求分析:

    1. 保存,防止电脑突然歇菜
    2. 暂存,以便之后放弃修改回退到该状态
    3. 开发完成,准备回馈上游社区

    git提交命令

    本地代码的提交分为三步:推到暂存区、添加提交内容描述、推到origin仓库的新分支上

    1. 建议先确认下修改内容,是不是在正确的分支上,因为如果搞错了,这里没有新修改的内容,是推不上去的
      git status
    2. 将本地修改推到暂存区
      git add -A-A的意思是全部)

      有许多网上教程在这一步写的是git add .,但该命令仅提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件;git add -u表示将已跟踪文件中的修改和删除的文件添加到暂存区,不包括新增加的文件;-A则包括以上两种功能
      git add -i可以查看所有被所有修改过或已删除文件但没有提交的文件
      git add [<path>]可以指定添加文件或目录至暂存区

    3. 添加提交描述,这个commit会显示在仓库首页,即最近一次修改,请用简洁正常语句撰写,之前的所有commit也都会保留在github的仓库里,这样比较好看版本修改内容
      git commit -m "simple normal words"
    4. 推送至origin仓库新分支,建议跟本地分支同名
      git push origin new_branch
      然后就可以打开github网页,自己的仓库首页就会提醒你是否根据这个branch创建pr。

    合并多个提交commit

    需求分析:

    在修改代码的过程中,我们在本地与origin仓库间可能存在着多次提交(commit),建议最终提交pr时,合并所有commit,保证该pr内仅包含一次提交。
    尽管可以经由审查人员直接在merge时合并所有提交,但仍期望在pr中有着干净的提交记录,规范的pr可以反映出提交者的专业性。
    以下命令同样适用于在已提交pr的情况下继续修改该分支代码,pr会自动与分支代码同步,通过使用git commit --amendgit push --force强制推送来保证只有一次commit记录

    git合并多个提交命令

    • 查看log
      git log
      gitlog
      这里会出现很多个commit,找到你需要合并的commit,比如将最新一个(HEAD所指)commit和第二个合并为一次提交,复制作为父亲的提交后面那一串 c47e54a3c35b6cec9f5fd2be0fc3905785df6df0之类的
    • 重置提交状态到父提交时,之后会在这个基础上提交一次新的、合并了所有需要合并的提交的提交
      git reset xxxxx
    • 重新推到暂存区
      git add -A
    • 对提交内容描述进行修改
      git commit --amend
      会进入文本编辑,修改描述,之后的commit就只有这次描述了,合并的commit里的旧描述可以注释掉
      amend
    • push到origin
      git push -f origin xxx
      -f的作用是强制推送到orign,因为前面在本地合并commit之后,对应的远程分支中的commit并没有变化,git会认为远程分支的提交领先于本地分支
      -f
      强制推送之后即可合并远程分支上的commit
      刷新github看看commit记录

    代码版本回退、合并

    需求分析:

    1. 开发进行中,远程代码已更新,需要同步
    2. 放弃本地修改

    git同步与合并命令

    • 先拉取upstream
      git fetch upstream
    • 需要版本回退,用upstream/master更新本地代码
      git rebase upstream/master
    • 或者需要合并本地代码和上游代码
      git merge upstream/master
      可能会遇到各种冲突,根据git提示来就行,直接打开vscode也会给你标出冲突的地方,选择就行

      git rebasegit merge要好,想要更好的提交树,使用rebase操作会更好一点。这样可以线性的看到每一次提交,并且没有增加提交节点。
      merge操作遇到冲突的时候,当前merge就不能继续进行了。手动修改冲突内容后,add提交修改,再commit就可以了。
      rebase操作的话,会中断rebase,同时会提示去解决冲突。解决冲突后,将修改add后执行git rebase –continue继续操作,或者git rebase –skip忽略冲突。

    放弃本地修改

    这里分三种修改阶段:

    1. 本地修改还没有使用git add命令提交至暂存区,使用:
      git checkout -- filepathname
      如果需要放弃所有的文件修改,可以使用git checkout .
    2. 本地修改已经由git add缓存:
      git reset HEAD filepathname重置,放弃指定文件的缓存,同样如果需要放弃所有缓存可以使用git reset HEAD .命令 此时本地修改还未完全消失,而是回到1.的状态,后续操作同上
    3. 已经用git commit提交了代码:
      git reset --hard HEAD^回退至上一次commit的状态
      git reset --hard commitid回退至任意commit状态(使用git log来查看git的commit历史,确定需要的commitID)

    本地新建文件并没有加入到git的管理系统中,对于git来说是未知的(untracked files),如果放弃该文件,需要手动删除或使用: git clean -fd -n查看确认需要删除的文件
    git clean -fd即可删除,其中-f表示文件-d表示目录。如果需要删除.gitignore中的文件,再加上-x;如果git submodule中也有需要删除的文件,加上-f变成git clean -dff
    简单来说,删除git未跟踪文件可以这样执行:git clean -f

    需要注意,在开发过程中,本地有可能自动生成.classpath等编译文件,这些在提交之前都需要用git clean -f清除

    修改pr

    直接修改对应的本地分支再git push --force origin xxx到origin对应分支就行了,pr会自动跟着branch的commit变

    总结

    综上,一套完整的开发、提交pr流程一般为:

    1. 新建本地目录,后续操作都需要在这个目录下进行
    2. 第一种情况:
      如果不存在远程仓库,即为还未上传的本地项目,在该目录下,git init初始化本地git仓库,这个命令用一次就行了,之后基于该仓库的操作请勿再使用init命令,人生没有重来,本地仓库也是
      git remote add origin ssh_url ssh_url是复制自己的仓库的ssh,将本地仓库关联该远程仓库
      git remote -v查看关联的仓库
      第二种情况:
      Github上已有项目远程仓库
      git clone ssh_url将代码下载下来,建议使用fork的origin仓库
      git remote add upstream ssh_url关联上游仓库
      git remote -v查看关联的仓库
      git fetch upstream+git rebase upstream/master开发之前一定要确保本地代码与上游同步,是最新的
    3. git checkout -b feature-A基于local/master,新建本地分支,开发功能A
    4. 开发ing……
    5. 开发完成后,git status看看修改的文件是不是那几个,确认后git add -A把所有的文件(代码)加入暂存区(或者git add [<path>]将指定文件或目录加入暂存区)
    6. git commit -m "the changes"添加一次提交,”“内填写本次提交概述
    7. git push origin branch_name将刚才加入暂存区的文件(代码)和提交内容推到origin的branch_name分支中
    8. 在github网页上,将origin/branch_name分支以pr形式提交给上游仓库
    9. 如若需要进行下一个功能的开发,记得切换回master分支,再新建本地feature-B分支进行B功能的开发

    注意!

    为国争光,禁用pull,从我做起。

    git pull是一个非常强硬的命令,它会忽略一切细节并且可以把git fetchgit mergegit rebase等等的活儿都干了,中间没有出于安全考虑的确认
    该命令还会将合并结果记录在新提交中,包含两个父提交的名称以及来自用户的描述更改的日志消息
    虽然简单,但请勿使用git pull

    流程链接

    贡献流程

  • grpc调研:HTTP2简介

    HTTP2 简介

    基于Google引入的支持多路复用的SPDY(speedy)协议,IETF的HTTP工作组于2015年提出了HTTP2。

    1. 引入了服务器推送概念,其中服务器预计客户端将需要的资源,并在客户端发出请求之前将其推送,内置的安全机制必须授权服务器预先推送资源。 客户端保留拒绝服务器推送的权限;客户端将推送的资源保存在缓存中,可以跨不同页面重用这些缓存的资源,还可以限制同时多路复用的推送流的数量。 服务器推送 HTTP2授权
    2. 引入了多路复用概念,通过单个TCP连接完成交错请求和响应,且没有队首阻塞。功能的实现基于“二进制分帧”的特性。
    3. 是一种二进制协议,二进制成帧层将消息划分为多个帧,这些帧根据其类型(数据或报头)进行分离。 此功能在安全性,压缩和多路复用方面大大提高了效率。
      二进制协议
    4. 安全性能方面,HTTP2使用HPACK标头压缩算法,该算法可抵御像CRIME这样的攻击,并使用静态霍夫曼编码。

      HTTP2与HTTP1的区别

    5. 线端阻塞:HTTP1限制为每个TCP连接仅处理一个未完成的请求,如果有多个请求,则浏览器需要并行使用多个TCP连接,将导致拥塞,同时垄断网络资源,降低其他用户的网络性能。HTTP2采用多路复用,所有的通信都在一个TCP连接上完成,实现了真正的并行传输。
    6. 流优先级:http1底层TCP连接的无效使用导致资源优先级低下,随着Web应用程序在复杂性、功能和范围方面的增长而导致性能指数级下降。http2每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回客户端。无需应用不必要的优化。 流优先级
    7. 安全:HTTP1.1中使用了摘要身份验证。http2中改进了新TLS功能的实现,使得新应用协议具有更好的安全性能设计。
    8. 报头压缩:在HTTP1.x中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500~800字节的负荷。HTTP2默认使用UPACK压缩,既避免了重复报头的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩报头,减少发送包的数量从而降低延迟。 HTTP2 HPACK 压缩
    9. 协议格式: HTTP1采用文本格式。HTTP2则是二进制协议。使用HTTP2实现的浏览器会将相同的文本命令转换为二进制命令,然后再通过网络进行传输。 二进制协议 HTTP/1.x vs. HTTP/2 – The Difference Between the Two Protocols Explained提供了一份更为详细的表格来对比HTTP1和HTTP2。

      总结

      HTTP2是二进制协议,支持多路复用,报头压缩,资源优先级和更智能的数据包流管理。可以减少延迟,并加快网页上的内容下载。

      备注

      • 多路复用
    10. 所有的HTTP2通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。
    11. 每个数据流以消息的形式发送,消息由多帧组成,帧可以乱序发送,接受方根据帧头部的流标识符(stream id)重新组装,归属到各自的请求中。
    12. 多路复用可能导致关键请求阻塞。但在HTTP2中,每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回客户端,数据流还可以依赖其他的子数据流。
      • TLS(Transport Layer Security,安全传输层协议) 位于会话层,主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,主要有以下增强内容:
    13. TLS 使用“消息认证代码的密钥散列法”(HMAC)更安全的MAC算法。
    14. TLS提供更多的特定和附加警报,还对何时应该发送某些警报进行记录。
    15. 增强的伪随机功能,TLS对于安全性的改进。
  • Fedora30 物理断电后重启问题

    Fedora30 物理断电后重启问题

    Fedora30 物理重启 后,停留在

    generating /run/initramfs/rdsosreport.txt
    

    进入journalctl查看log,发现报错:

    Failed to start File System Check on /dev/mapper/fedora-root.
    

    另有提醒fsck failed,说明是文件系统的问题,且修复失败。

    解决办法

    fsck /dev/mapper/fedora-root
    

    重启即可。注意根据具体报错修改指令(fedora-root)。

    • 注:重启后发现点击图标进入文件系统会崩溃,不知是否与文件系统未完全修复有关。其他启动正常。
  • oVirt 架构预览

    本文翻译自 oVirt 官网文章:oVirt Arch,介绍了 oVirt 的系统架构图。

  • 什么情况下在 Go 中使用 <基础类型指针>

    本文将介绍我在写 oVirt Go SDK 时,struct 内属性定义为指针。

  • 关于 REST API URI 设计规则的讨论

    本文是阅读7 Rules for REST API URI Design后,结合自己的经验,就《如何设计优秀的 REST API URI》做的个人讨论。