5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CentOS 7 に pyenv を用いて最新バージョンの Python をインストールする

Last updated at Posted at 2023-07-11

はじめに

サーバーのPythonのアップグレードに挑戦しました。かなり時間を取られたので、備忘録としてここにまとめます。

環境

  • CentOS 7
  • python3.6とpython2.7が予め入っている

1. pyenvのインストール

$ pyenv versions

以下のように出力されれば、インストールされていないことになります。バージョンが表示される場合は、インストールされているので読み飛ばしてください。

bash: pyenv: command not found...

pyenvのインストールは以下の記事を参考にしました。手順をまとめておきます。

1-1. pyenvの使用に必要となるパッケージのインストール

$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git libffi-devel

1-2.ホームディレクトリ下にpyenvのリポジトリをクローンする

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

1-3. .bash_profileにpyenvのパスを追加

$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

1-4. pyenvのバージョンを確認

$ pyenv --version

pyenv 1.2.2-6-g694b551

2. pythonのインストール (失敗)

入手できる最新のpythonのバージョンを確認。

$ pyenv install --list

3.11.3を選びました。

$ pyenv install 3.11.3

とすれば問題なくpython3.11.3がインストールできるはずですが

ModuleNotFoundError: No module named '_ssl'
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

とエラーが出てきてしまいました。どうやら、_sslというモジュールが無いというエラーのようです。
実際、以下のように打ち込み、インストールされているpythonのバージョンを確認してみても、3.11.3は出てきません。

$ pyenv versions

調べてみると、たくさん記事が出てきました。

なるほど。python3.10.x以降はopen-sslのバージョンが1.1.1以上でないとダメらしいです。open-sslとはchatGPTによると以下のようなものだそうです。

OpenSSLは、オープンソースの暗号ライブラリとツールキットです。データの暗号化、復号化、署名、証明書の作成、プロトコルの実装など、さまざまな暗号化関連の機能を提供します。

では、今入っているopen-sslのバージョンを確認してみます。

$ openssl version

OpenSSL 1.0.2k-fips 26 Jan 2017

確かにバージョンは1.0.2です。ではアップグレードを試みましょう。

3. opensslのアップグレード

まず試したのは以下のスクリプトです。

sudo yum install openssl11-devel --allowerasing

Command line error: no such option: --allowerasing

怒られました。

次に試したのは以下のコマンドです。

sudo yum install openssl11-devel

0 packages excluded due to repository protections
No package openssl11-devel available.

また怒られました。

よく見ると、以下のように書いてあります。

This system is not registered with an entitlement server. You can use subscription-manager to register.

なるほど、エンタイトルメントサーバーじゃないからダメ。みたいな話でしょうか。調べてみたら以下のような記事が出てきました。

/etc/yum/pluginconf.d/subscription-manager.confの中身にある、enabledの値を1から0に書き換えたらいいんですね。こちらの方が、もし万が一のことがあったときに書き直せばいいのでsudo subscription-manager registerとするよりも心理的にやりやすいです。
ということで、

$ vi /etc/yum/pluginconf.d/subscription-manager.conf

としてenabled=0に書き換えました。

登録を済ませた?ところで再び実行です。
openssl11もその開発用パッケージopenssl11-develもまとめてインストールします。

sudo yum install openssl11 openssl11-devel

No package openssl11 available.
No package openssl11-devel available.

ダメでした。
仕方ないのでソースコードから直接インストールする方法がないか調べてみたところ、以下の記事が見つかりました。

良さそうなので早速試してみることに。

3-1. 必要なパッケージのインストール

最初にインストールしたパッケージと一部被ってますが、気にせずインストールしました。

$ sudo yum install -y zlib-devel perl-core make gcc

3-2. opensslのダウンロード

次に、ソースコードをおいてあるサイトから、tar.gzファイルをダウンロード。

$ sudo curl https://www.openssl.org/source/openssl-1.1.1.tar.gz -o /usr/local/src/openssl-1.1.1.tar.gz

3-3. opensslのインストール

そしてOpenSSLのインストールです。

$ cd /usr/local/src
$ sudo tar xvzf openssl-1.1.1.tar.gz
$ cd openssl-1.1.1/
$ sudo ./config --prefix=/usr/local/openssl-1.1.1 shared zlib
$ sudo make depend
$ sudo make
$ sudo make test
$ sudo make install

インストールされたかを確認しましょう。以下のようになればOKです。

$ sudo ls -l /usr/local/openssl-1.1.1
total 0
drwxr-xr-x 2 root root  37 Jul 11 13:57 bin
drwxr-xr-x 3 root root  21 Jul 11 13:57 include
drwxr-xr-x 4 root root 159 Jul 11 13:57 lib
drwxr-xr-x 4 root root  28 Jul 11 13:58 share
drwxr-xr-x 5 root root 140 Jul 11 13:57 ssl

3-4. opensslのライブラリ群を追加する

どうやら、ライブラリの追加という操作が必要なようです。
以下のサイトを参考にしました。

$ vi /etc/ld.so.conf.d/openssl-1.1.1.conf

として、

/usr/local/openssl-1.1.1/lib

と書き込みました。

3-5. キャッシュファイルの更新

$ sudo ldconfig

3-6. ライブラリが追加されたことを確認

$ sudo ldconfig -p | grep libssl

これで、

libssl.so.1.1 (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so.1.1
libssl.so (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so

が追加されていれば(あれば)OKです。

3-7. 動作確認

以下のコマンドで問題なくインストールされていることがわかります。

$ sudo /usr/local/openssl-1.1.1/bin/openssl ciphers -v TLSv1.3
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD

さて、これで最新のOpenSSLがインストールできたので、自信をもってpyenv installができますね。

pyenvの実行再び

$ pyenv install 3.11.3

ModuleNotFoundError: No module named '_ssl'
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

ダメでした。
OpenSSLは問題なくインストールできたはず。インストールできてるよね?ってことで調べてみる。

$ openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

できてない。いやでも間違いなくサーバーの何処かにちゃんとしたOpenSSLはおいてあるはず。ということは従来のバージョンと競合してるかもしれない。ログアウトして再度ログインしても問題は解決しない。さっきインストールしたOpenSSLは/usr/local/openssl-1.1.1/bin/opensslにある。
ということで絶対パスで確認してみる。

$ /usr/local/openssl-1.1.1/bin/openssl version
OpenSSL 1.1.1  11 Sep 2018

ビンゴ。絶対パスで指定してあげればちゃんと機能するってことは、正しくインストールはできたけど、opensslとコマンドを打つときに従来のopensslがまず読み込まれるようになっているということでしょう。これは従来のopensslがおいてあるPATHよりも前に、/usr/local/openssl-1.1.1/bin/opensslをPATHとして指定すれば解決しそう。

ということで、

$ vi .bashrc

として、

export PATH="/usr/local/openssl-1.1.1/bin/:$PATH"

とすれば良いんじゃないだろうか。

source ~/.bashrc

として変更を反映させて、

$ openssl version
OpenSSL 1.1.1  11 Sep 2018

うまくいきました。これでようやくpyenvが使えそうです。

$  pyenv install 3.11.3

ModuleNotFoundError: No module named '_ssl'
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

ダメでした。
調べてみたところ、opensslが標準の場所とは違うところにインストールされたせいで、pythonのビルドがうまく行かないそう(以下の記事参考)。そこで、OpenSSLのヘッダ・ライブラリを見つけられるように、PYTHON_CONFIGURE_OPTSという環境変数にOpenSSLの場所を代入する必要があるみたいです。

上記の記事とはインストール場所が違うので、そこだけ書き換えた以下のコマンドを実行します。

$ echo 'export PYTHON_CONFIGURE_OPTS="--with-openssl=/usr/local/openssl-1.1.1"' >> ~/.bashrc

達成

流石に次はうまくいくだろうと思い、再度pyenvを実行します。

$ pyenv install 3.11.3

Downloading Python-3.11.3.tar.xz...
-> https://www.python.org/ftp/python/3.11.3/Python-3.11.3.tar.xz
Installing Python-3.11.3...
Installed Python-3.11.3 to /root/.pyenv/versions/3.11.3

できました。
ようやくpython3.11.3がインストールできました。

以下のコマンドで、インストールができているか念のため確認します。アスタリスクの付いているものが現在の環境です。

$ pyenv versions

デフォルトで使用されるpythonを3.11.3にするために、

$ pyenv global 3.11.3

と実行して、

$ python -V
Python 3.11.3

と表示されればインストール終了です。

おまけ(一般ユーザーにも変化を適用する)

以下のように普段Pythonが使われているディレクトリに、新しくインストールしたPythonのシンボリックリンクを作成しました。

sudo ln -s $(pyenv which python) /usr/bin/python3.11

これで、
python3.11というコマンドによって、誰でもpython3.11.3を使うことが可能になりました。

結論

従来のPythonも残しつつ、新しいPythonも使えるようになりました。

追記:rootでやる必要はなかった

パッケージの保管場所など色々と面倒だったので、よく確認してみたら、上記のpyenvのインストールやpyenvの実行は別に一般ユーザーでもできることでした。なので、それぞれがpyenvをインストールしてopen-sslの問題をクリアして、好きなバージョンのpythonをインストールし管理する方がいい気がしました。
ですので、rootにインストールした新しいpyenvは

pyenb uninstall 3.11.3

として消しました。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?