x**3な人生

基本的にはメモ

zathura on MacOSX

homebrewでzathuraとzathura-pdf-popplerを入れた後、PDFが開けずにpluginが見つからないというエラーが出るので何でかなと思ってたけど、自分でシンボリックリンク張らなければいけなかったんですね。。。

error: could not open plugin directory: /opt/homebrew/Cellar/zathura/0.5.2/lib/zathura
error: Found no plugins. Please install at least one plugin.
error: Could not determine file type.

zathura-pdf-popplerをインストールする際にわざわざ教えてくれていたのに気づいていませんでした。

zathura-pdf-poppler
      To enable this plugin you will need to link it in place.
      First create the plugin directory if it does not exist yet:
        $ mkdir -p $(brew --prefix zathura)/lib/zathura
      Then link the .dylib to the directory:
        $ ln -s $(brew --prefix zathura-pdf-poppler)/libpdf-poppler.dylib $(brew --prefix zathura)/lib/zathura/libpdf-poppler.dylib

kubernetesを再セットアップしたときのメモ

はじめに

ここで構築した環境をresetして再度initしたときのメモ。 verdigrisbrain.hatenablog.com

内容

master

まずメモリのswapを無効にしておく。

$ sudo swapoff -a

flannelのインターフェースが残っているとpodを起動したときにreadyにならなくなるため、ここのやり方に従ってあらかじめ消しておく。 https://stackoverflow.com/questions/46276796/kubernetes-cannot-cleanup-flannel なおifconfigではなくipを使う場合は、ip link deleteに置き換える。あと自分の環境にはcni0は無かったのでflannel.1だけ削除したが、 特に問題なく再起動できた。

kubeadmからresetとinitを実行する。

$ sudo kubeadm reset
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

このコマンドを実行後、後でslaveで実行するためのコマンドが表示されるのでメモしておく。

kubeadm join [IP addr]:6443 --token [token] \
    --discovery-token-ca-cert-hash [hash]

忘れずにコンフィグを$HOME/.kubeにコピーする。

$ sudo cp -f /etc/kubernetes/admin.conf .kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

最後にflannelをデプロイしてノード間で通信できるようにする。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

slave

masterと同じくflannelのインターフェースを削除してkubeadm resetした後、先程のkubeadm join ...を実行する。

以上

複数のtagsファイルをvimで読み込む

他に良いやり方があるような気もするが、とりあえずメモ。

複数のプロジェクトにまたがってtagジャンプしたい時がある。例えば外部のライブラリの挙動を詳しく確認したいときなど。 ここでは便宜上、myprojectとsome_libという2つのプロジェクトが同じディレクトリの配下にあるという前提にする。

まずそれぞれのプロジェクトでtagsファイルを作成する。

$ (cd myproject; ctags -R)
$ (cd some_lib; ctags -R)

両方のプロジェクトに新しくtagsファイルが生成される。

$ tree
.
├── myproject
│   ├── tags
│   ├── src/
│   │   └── main.c
├── some_lib
│   ├── tags
....

次にmyprojectへ移動してvimソースコードを開く。このとき既にmyproject/tagsは読み込まれているが、some_lib/tagsは読み込まれていない。よってsome_libにある関数などにジャンプすることはできない。 そこで以下のようにvim:set tagsを使ってこのtagsファイルを追加する。

:set tags+=../some_lib/tags

すると両方のプロジェクトに渡ってtagジャンプすることができるようになる。

以上

vagrantのcentos/7でDPDKをインストールする

はじめに

vagarntのcentos/7イメージを使ってDPDKとそのアプリケーションをインストールするときにはまったメモ。 それぞれのパッケージのバージョンはあとで書く。

結論としては、シンボリックリンクの作り方がマズくてコンパイルが途中でこけていたことが原因。

$ cd /lib/modules/3.10.0-957.5.1.el7.x86_64/
$ ll
total 3240
lrwxrwxrwx.  1 root root     42 Feb 28 20:51 build -> /usr/src/kernels/3.10.0-957.5.1.el7.x86_64
....

(環境に依存するが)buildが赤色で表示され、本来はこれが青色で無ければいけない。

対処

シンボリックリンクを削除して作成し直す。

$ sudo rm build
$ sudo ln -s /usr/src/kernels/3.10.0-957.10.1.el7.x86_64 build
$ ll
total 3240
lrwxrwxrwx.  1 root root     43 Apr  2 19:34 build -> /usr/src/kernels/3.10.0-957.10.1.el7.x86_64
....

以上

Ubuntu18.04でKubernetesのクラスタを組んだときのメモ

TL;DR

基本的にはここの通りに従えば良いです。

linuxconfig.org

環境

ノードは3台(masterが1台、slaveが2台)、すべてVMなどは用いずホスト上に構築します。

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
...

$ docker -v
Docker version 18.09.2, build 6247962

2019/3/21時点でkubernetesはdocker 18.06で動作することを期待するため、後ほどセットアップのときに警告が出力されますが おそらく問題はないと思います。

インストールする前に、すべてのノードでホスト名が設定されていることを確認してください。 もし設定がまだであれば、hostnamectlコマンドを用いてそれぞれのノードで任意のホスト名を設定します。

$ sudo hostnamectl set-hostname HOSTNAME

インストール

すべてのノードにおいて次のインストール手順を行います。

(1) dockerのインストール

$ sudo apt install docker.io
$ sudo systemctl enable docker  # 再起動したときにdockerも起動するよう設定

(2) kubernetesのインストール

最初にgoogleのサイトにあるapt-keyを用いてリポジトリを追加します。 なおxenial(16.04)用のリポジトリのようですが、まだbionicのものがないためこれを用います。 今のところこれで正常に動作しているようです。

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

次にapt installによりkubectlkubeadmおよびkubeletをインストールします。 以下のようにkubeadmだけを指定すれば他もまとめてインストールされます。

$ sudo apt install kubeadm

メモリのswapを無効にしていないのであれば、kubernetesを起動する前にオフにしておきます。 -a--allの省略版です。

$ sudo swapoff -a

kubernetesの起動

(1) Masterノード

masterノードから起動を行います。まずmasterノードでkubeadm initを初期化し、 次にそれぞれのslaveノードでkubeadm joinを実行してクラスタに参加させます。

複数ノード間でコンテナ間通信を行うためにflannelを利用するため、--pod-network-cidrでCIDRを指定します。 指定するアドレス帯は 参考サイト と同じく10.244.0.0/16に設定します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

もし起動に失敗した場合、エラーの内容に応じて対処を行い再度起動を試みます。 例えばswapoff -aを忘れていたりすると起動に失敗します。 なお再起動の前にkubeadm resetでクリアする必要があります。

# 起動に失敗した場合はresetしてからinit
$ sudo kubeadm reset
...
$ sudo kubeadm init

kubeadm initが成功すると、セットアップの実行ログとともに設定方法のインストラクションが表示されますので これに従います。

まずkubectlコマンドでkubernetesを操作できるようにconfigを用意します。 /etc/kubernetes/admin.confkubeadm initの実行後に生成されるconfigファイルです。

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

この設定が完了すると、kubectl applyでpodをデプロイしたりすることができるようになります。

またインストラクションの最後に、次のようなslaveノードをクラスタに参加させるための方法が表示されます。 後ほどslaveノードでこれを実行する必要があるため、シェルスクリプトとして保存するなどしておきます。

#!/bin/sh

$ sudo kubeadm join IPADDR:PORT --token TOKEN --discovery-token-ca-cert-hash HASH

(2) Flannel podのデプロイ

続いてmasterノードからflannel podをデプロイしてslaveノードとの通信ができるようにします。

$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
$ kubectl apply -f kube-flannel.yml

代わりにURLを直接指定することもできます。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

flannelがデプロイされたことを確認します。

$ kubectl get pods --all-namespaces
...

(3) Slaveノード

インストールが完了していれば、あとは先ほどのインストラクションに従ってkubeadmからkubernetesを起動するだけです。

# on slave node
$ sudo kubeadm join IPADDR:PORT --token TOKEN --discovery-token-ca-cert-hash HASH

slaveノードがクラスタに参加したかどうかはmasterノードからkubectlで確認出来ます。

# on master node
$ kubectl get nodes
NAME        STATUS      ROLES       AGE      VERSION
master      Ready       master      10m      v1.13.4
slave1      Ready       <none>      3m       v1.13.4
slave2      Ready       <none>      2m       v1.13.4

サービスのデプロイ

最後に参考サイトの 例に従いnginxをデプロイしてみます。

$ kubectl run --image=nginx nginx-server --port=80 --env="DOMAIN=cluster"
$ kubectl expose deployment nginx-server --port=80 --name=nginx-http

デプロイが成功すると、kubectl get servicesもしくはkubectl get svcにより nginx-httpと言う名前のサービスがデプロイされている ことが確認できます。

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   39h
nginx-http   ClusterIP   10.99.125.225   <none>        80/TCP    37h

またkubectl scaleによりpodのレプリカの数を変更することも出来ます。 まずdeploymentとレプリカ数を確認します。

$ kubectl get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   1/1     1            1           38h

nginx-serverというdeploymentがレプリカ数1で配置されていることが分かります。 READYがレプリカの状態を示しています。

次にkubectl scaleによりレプリカ数を2に変更します。対象のdeploymentは deployments/nginx-serverのように指定します。

$ kubectl scale deployments/nginx-server --replicas=2
$ kc get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   1/2     2            1           38h

変更後すぐは2つ目のレプリカが用意されていないためREADY1/2となっていますが、 しばらくするとこれが2/2となり2つのレプリカが配置されたことが分かります。

$ kc get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   2/2     2            1           38h

以上

Cryptography_HAS_SSL_ST

はじめに

Ubuntu16.04でovsをコンパイルしようとしてmakeではまったので、場当たり的に対処したときのメモ。

pythonのOpenSSLの中でCryptography_HAS_SSL_STが定義されていないためAttributeErrorでこける。 Ubuntuが古いので、libraryも古かったというのが原因の模様。

本当は python - Pip Error : 'module' object has no attribute 'Cryptography_HAS_SSL_ST' - Stack Overflow にあるようにパッケージマネージャーで綺麗に入れ直した方がよいはず。

環境など

  • Ubuntu 16.04
  • python2.7
  • openvswitch-2.10.1

ovsはgithubからcloneしたので正しくは以下のコミット時点。

commit b1331295eaada5bc0e3bcd7e3b964003af3273d6
Author: Ilya Maximets <i.maximets@samsung.com>
Date:   Tue Dec 11 17:34:17 2018 +0300

    cirrus: Add Cirrus CI integration for FreeBSD build

内容

このへんの手順をみてmakeまで進めると、OpenSSLのところでエラーが出る。

Open vSwitch on Linux, FreeBSD and NetBSD — Open vSwitch 2.10.90 documentation

...
  File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 194, in <module>
    if _lib.Cryptography_HAS_SSL_ST:
AttributeError: 'module' object has no attribute 'Cryptography_HAS_SSL_ST'

replでimportしても確かにエラーになる。

>>> import OpenSSL
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 194, in <module>
    if _lib.Cryptography_HAS_SSL_ST:
AttributeError: 'module' object has no attribute 'Cryptography_HAS_SSL_ST'

SSL.pyの内容を見ると、_utilというモジュールの中で_lib.Cryptography_HAS_SSL_STが定義されていることを期待している。

from OpenSSL._util import (
    UNSPECIFIED as _UNSPECIFIED,
    exception_from_error_queue as _exception_from_error_queue,
    ffi as _ffi,
    lib as _lib,
...

# 194行目
if _lib.Cryptography_HAS_SSL_ST:
    SSL_ST_INIT = _lib.SSL_ST_INIT
    SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
    SSL_ST_OK = _lib.SSL_ST_OK
    SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
    __all__.extend([
        'SSL_ST_INIT',
        'SSL_ST_BEFORE',
        'SSL_ST_OK',
        'SSL_ST_RENEGOTIATE',
    ])

確かに_util.pyというのがある。

$ ls /usr/local/lib/python2.7/dist-packages/OpenSSL/
SSL.py   __init__.py   _util.py   crypto.py   debug.py   rand.py   tsafe.py   version.py
SSL.pyc  __init__.pyc  _util.pyc  crypto.pyc  debug.pyc  rand.pyc  tsafe.pyc  version.pyc

ので開いてみると最初の方でBinding.liblibとして参照させている。

# 6行目
from cryptography.hazmat.bindings.openssl.binding import Binding


binding = Binding()
binding.init_static_locks()
ffi = binding.ffi
lib = binding.lib

cryptographyというのは

GitHub - pyca/cryptography: cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.

のことみたいで、ソースコードの中身を見ると確かにCryptography_HAS_SSL_STが定義されている。具体的にはBinding()のクラスメソッドから_conditional.pyCONDITIONAL_NAMESを参照していて、Cryptography_HAS_SSL_STの実体は単にリストを返すメソッドであることが分かる。

# cryptography/src/cryptography/hazmat/bindings/openssl/binding.py

from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES
...

class Binding(object):
    """
    OpenSSL API wrapper.
    """
    lib = None
    ffi = ffi
...

    @classmethod
    def _ensure_ffi_initialized(cls):
        with cls._init_lock:
            if not cls._lib_loaded:
                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
...
# cryptography/src/cryptography/hazmat/bindings/openssl/_conditional.py

CONDITIONAL_NAMES = {
    "Cryptography_HAS_EC2M": cryptography_has_ec2m,
    "Cryptography_HAS_EC_1_0_2": cryptography_has_ec_1_0_2,
   ...
   "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st,
   ...
}
...

def cryptography_has_ssl_st():
    return [
        "SSL_ST_BEFORE",
        "SSL_ST_OK",
        "SSL_ST_INIT",
        "SSL_ST_RENEGOTIATE",
    ]

とりあえずここまで分かってある程度満足したのと、ovsでSSLあたりの機能を使う予定は無いので、_util.pyの最初に無理矢理lib.Cryptography_HAS_SSL_STの定義を書くことでコンパイル終了。そのあと消したのでovsからこの辺を使うときはエラーになるはず。

# _util.py

binding = Binding()
binding.init_static_locks()
ffi = binding.ffi
lib = binding.lib

# これ
lib.Cryptography_HAS_SSL_ST = False

以上