zaki work log

作業ログやら生活ログやらなんやら

[oc / kubectl] run --commandを使って何もしないpodや一定時間後に任意のリターンコードで終了するpodをデプロイ

tail -f /dev/nullsleep,exitを使ってデバッグや動作確認用に。
run実行で作成されるworkloadsリソースについては以下も参照。

zaki-hmkc.hatenablog.com

usage

  # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command.
  kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN>
  
  # Start the nginx container using a different command and custom arguments.
  kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>

kubectl run --helpより。

runningするだけで何もしないpod

「何もしない」というと語弊があるけど、とりあえずrunning状態のpodを作る。
pod内から別podへの疎通を確認したり、runningなpodがある状態でクラスタやネームスペースの状態などを確認したり、デプロイ時のノードへのスケジューリングを確認したり。

[zaki@minikube ~]$ kubectl run running-pod --image=alpine:latest --command -- tail -f /dev/null
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/running-pod created
[zaki@minikube ~]$ kubectl get pod -l run=running-pod
NAME                           READY   STATUS    RESTARTS   AGE
running-pod-6d5c4b4975-v9h88   1/1     Running   0          11s

このpodはtail -f /dev/nullしてるだけなので、基本的にそれ以外何もせずにrunning状態を維持する。

[zaki@minikube ~]$ kubectl exec -it running-pod-6d5c4b4975-v9h88  ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 tail -f /dev/null
    8 root      0:00 ps aux

もちろんalpine:latestでなくcentos:latestdebian:latestでも良いし、OpenShiftならrhel7なども。適当なコンテナイメージを使えばOK。

OKD 4.4の場合

[zaki@okd4-manager ~]$ oc run running-pod --image=alpine:latest --command -- tail -f /dev/null
kubectl run --generator=deploymentconfig/v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deploymentconfig.apps.openshift.io/running-pod created
[zaki@okd4-manager ~]$ oc get pod 
NAME                   READY   STATUS      RESTARTS   AGE
running-pod-1-deploy   0/1     Completed   0          22s
running-pod-1-sgmbv    1/1     Running     0          14s
[zaki@okd4-manager ~]$ oc exec -it running-pod-1-sgmbv ps aux
PID   USER     TIME  COMMAND
    1 10005800  0:00 tail -f /dev/null
   11 10005800  0:00 ps aux

停止するにはDeploymentかDeploymentConfigを削除する。
(--restart=Neverで実行した場合は、podを削除する)

60秒後に実行完了するpod

tail -f /dev/nullのかわりに、sleep 60すればよい。

[zaki@minikube ~]$ kubectl run sleep-exit-pod --image=alpine:latest --command -- sleep 60
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/sleep-exit-pod created
[zaki@minikube ~]$ kubectl get pod -l run=sleep-exit-pod
NAME                              READY   STATUS    RESTARTS   AGE
sleep-exit-pod-5dd66749d5-j2bdq   1/1     Running   0          7s

60秒後

[zaki@minikube ~]$ kubectl get pod -l run=sleep-exit-pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sleep-exit-pod-5dd66749d5-j2bdq   1/1     Running   0          34s
sleep-exit-pod-5dd66749d5-j2bdq   0/1     Completed   0          64s
sleep-exit-pod-5dd66749d5-j2bdq   1/1     Running     1          68s

この通り、(Deployment/ReplicaSetリソースがあるため)podが停止するとセルフヒーリングされるため、restartされ続ける。
sleep 60の後そのまま終了したい場合は--restart=Neverを指定し、Deploymentリソースを作成せずにpod単発で動作させる。(k8s 1.17まで)

[zaki@minikube ~]$ kubectl run sleep-exit-pod --image=alpine:latest --restart=Never --command -- sleep 60
pod/sleep-exit-pod created
[zaki@minikube ~]$ kubectl get pod -l run=sleep-exit-pod -w
NAME             READY   STATUS    RESTARTS   AGE
sleep-exit-pod   1/1     Running   0          5s
sleep-exit-pod   0/1     Completed   0          64s

Completedで完了し、そのままrestartしなくなる。

OKD 4.4の場合も同様。

[zaki@okd4-manager ~]$ oc run sleep-exit-pod --image=alpine:latest --command -- sleep 60
kubectl run --generator=deploymentconfig/v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deploymentconfig.apps.openshift.io/sleep-exit-pod created
[zaki@okd4-manager ~]$
[zaki@okd4-manager ~]$ oc get pod -l run=sleep-exit-pod -w
NAME                     READY   STATUS              RESTARTS   AGE
sleep-exit-pod-1-4wqbg   0/1     ContainerCreating   0          11s
sleep-exit-pod-1-4wqbg   1/1     Running             0          11s

60sec後

[zaki@okd4-manager ~]$ oc get pod -l run=sleep-exit-pod
NAME                     READY   STATUS      RESTARTS   AGE
sleep-exit-pod-1-4wqbg   0/1     Completed   0          75s

このままだとセルフヒーリングする。(RESTARTSが1になっている)

[zaki@okd4-manager ~]$ oc get pod -l run=sleep-exit-pod -w
NAME                     READY   STATUS      RESTARTS   AGE
sleep-exit-pod-1-skj6g   0/1     Completed   0          73s
sleep-exit-pod-1-skj6g   1/1     Running     1          77s

--restart=Neverを付ければpod単発で動作する。

[zaki@okd4-manager ~]$ oc run sleep-exit-pod --image=alpine:latest --restart=Never --command -- sleep 60
pod/sleep-exit-pod created
[zaki@okd4-manager ~]$ oc get pod -l run=sleep-exit-pod
NAME                     READY   STATUS              RESTARTS   AGE
sleep-exit-pod           0/1     ContainerCreating   0          7s

60sec後

[zaki@okd4-manager ~]$ oc get pod -l run=sleep-exit-pod
NAME             READY   STATUS      RESTARTS   AGE
sleep-exit-pod   0/1     Completed   0          77s

60秒後にエラーで完了するpod

エラーと言っても、リターンコードを0以外で終わらせればよい。
要はexit 89とか。

[zaki@minikube ~]$ kubectl run error-exit-pod --image=alpine:latest --restart=Never --command -- sh -c "sleep 60; exit 89"
pod/error-exit-pod created
[zaki@minikube ~]$
[zaki@minikube ~]$ kubectl get pod -l run=error-exit-pod -w
NAME             READY   STATUS    RESTARTS   AGE
error-exit-pod   1/1     Running   0          10s
error-exit-pod   0/1     Error     0          64s

Errorで終了した。
podの状態はkubectl get pod error-exit-pod -o yaml.status.containerStatuses[].state辺りで確認する。

sh -c "..."を使わずに、そのままsleep 60; exit 89にしてしまうと、コンテナで実行されるのはsleep 60だけで、; exit 89kubectlのコマンドの後の実行になってそのままログアウトしてしまうので注意。

OKD 4.4

[zaki@okd4-manager ~]$ oc run error-exit-pod --image=alpine:latest --restart=Never --command -- sh -c "sleep 60; exit 89"
pod/error-exit-pod created
[zaki@okd4-manager ~]$ oc get pod -l run=error-exit-pod
NAME             READY   STATUS   RESTARTS   AGE
error-exit-pod   0/1     Error    0          80s

任意のLinuxコマンドを実行して終了するpod

tailsleepのかわりに、コンテナ内で実行可能なコマンドを叩いて終わるpod

[zaki@minikube ~]$ kubectl run exec-command-pod --image=alpine:latest --restart=Never --command -- ps auxww
pod/exec-command-pod created
[zaki@minikube ~]$ kubectl get pod -l run=exec-command-pod -w
NAME               READY   STATUS              RESTARTS   AGE
exec-command-pod   0/1     ContainerCreating   0          2s
exec-command-pod   0/1     Completed           0          4s

コマンドの実行時間によっては当然一瞬で終了する。
実行結果はstdoutへ出した分はkubectl logsで確認できる。

[zaki@minikube ~]$ kubectl logs exec-command-pod  
PID   USER     TIME  COMMAND
    1 root      0:00 ps auxww

ファイル入出力が必要なものであれば、NFSみたいな共有ストレージやFTPでファイル転送したり、なんか工夫してちょ。

例のpsだとパッとしないけど、例えばyes > /dev/nullを実行すれば簡単にCPU負荷をかけたりもできる。

プライベートレジストリにあるイメージの場合

--image=に指定するイメージをFQDNで指定すればOK

$ kubectl run priv-image-pod --image=gitlab-ce.example.org:25000/zaki/example/httpd:latest --restart=Never --command -- tail -f /dev/null
pod/priv-image-pod created
[zaki@minikube ~]$ kubectl get pod -l run=priv-image-pod
NAME             READY   STATUS    RESTARTS   AGE
priv-image-pod   1/1     Running   0          13s

ところで--commandって有ってもなくても動作変わらないような気がするんだけど、どこに影響してるんだろ。


ちなみにdebianイメージだと、psコマンド入ってないのね。(ubuntuなら入ってる)

Ansibleのyum_repositoryモジュールを使ってyumインストール用のリポジトリを追加する

/etc/yum.repos.d/以下の設定ファイルをAnsibleを使って作成する方法。

ドキュメント

yum_repository – Add or remove YUM repositories — Ansible Documentation

お題

zaki-hmkc.hatenablog.com

このクライアント側のyum設定

playbook

---
- hosts: localhost
  become: true
  gather_facts: false
  tasks:
  - name: "add my-repository"
    yum_repository:
      name: "my-repository"
      description: "my repository"
      file: "my-repository"
      baseurl: "http://192.168.0.21/yum-repo/"
      enabled: true
      gpgcheck: false

このplaybookを指定してansible-playbook playbook.ymlを実行する。

結果

[zaki@manager-dev ~]$ ls /etc/yum.repos.d/
CentOS-Base.repo       CentOS-Media.repo    CentOS-fasttrack.repo
CentOS-CR.repo         CentOS-Sources.repo  my-repository.repo
CentOS-Debuginfo.repo  CentOS-Vault.repo
[zaki@manager-dev ~]$ cat /etc/yum.repos.d/my-repository.repo 
[my-repository]
baseurl = http://192.168.0.21/yum-repo/
enabled = 1
gpgcheck = 0
name = my repository

(CentOS7)プライベート環境に必要なパッケージのみ提供するyumリポジトリサーバを構築する

プライベート環境で用意されているyumリポジトリサーバではインストールできないパッケージを、rpmファイル配布してインストールでなく、ローカルにyumリポジトリサーバを構築し、そのリポジトリからパッケージインストールする。

例としてjq用のyumリポジトリサーバの構築について。

リポジトリサーバ

httpサーバ

パッケージ配布にwebサーバが必要なので、なんか適当にインストールする。ここではApache(httpd)

# yum install httpd
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --reload

作業ディレクト

# cd /var/www/html/
# mkdir -p yum-repo/Packages
# cd /var/www/html/yum-repo/Packages/

rpmファイル配置

だいたいこの辺からrpmファイルをダウンロードする。
jq-1.6-1.el7.x86_64 RPM

# curl -LO https://rpmfind.net/linux/epel/7/x86_64/Packages/j/jq-1.6-1.el7.x86_64.rpm
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  166k  100  166k    0     0  66471      0  0:00:02  0:00:02 --:--:-- 66476
# file jq-1.6-1.el7.x86_64.rpm
jq-1.6-1.el7.x86_64.rpm: RPM v3.0 bin i386/x86_64 jq-1.6-1.el7

ファイル構成

# find /var/www/html/yum-repo/
/var/www/html/yum-repo/
/var/www/html/yum-repo/Packages
/var/www/html/yum-repo/Packages/jq-1.6-1.el7.x86_64.rpm

リモートからrpmファイルにGET確認

$ curl -I http://192.168.0.21/yum-repo/Packages/
HTTP/1.1 200 OK
Date: Sun, 08 Mar 2020 12:42:37 GMT
Server: Apache/2.4.6 (CentOS)
Content-Type: text/html;charset=ISO-8859-1

firewallなどで遮断されてないか確認しておく。

リポジトリ作成

配置したrpmファイルに対し、リモートからのyumに応答するためのメタデータを生成する。
コマンドはcreaterepoを使用するので、入っていなければyumインストールする。

# yum install createrepo

リポジトリデータの作成

# createrepo /var/www/html/yum-repo/
Spawning worker 0 with 1 pkgs
Spawning worker 1 with 0 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete
# ls -l /var/www/html/yum-repo/
合計 4
drwxr-xr-x. 2 root root   37  3月  8 21:41 Packages
drwxr-xr-x. 2 root root 4096  3月  8 21:43 repodata

クライアント設定

yumコマンドを実行してパッケージインストールする側の設定。

before

# yum install jq
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
パッケージ jq は利用できません。
エラー: 何もしません

jqをインストールするためのリポジトリは設定されていない。

リポジトリ追加

この辺は普通の処理。
…のはず。この辺を作成するコマンドってないのかな。

# vi /etc/yum.repos.d/my-repository.repo
[my-repository]
name=my repository
baseurl=http://192.168.0.21/yum-repo/
gpgcheck=0
enabled=1

リポジトリの設定を追加したら

# yum repolist
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
リポジトリー ID                     リポジトリー名                        状態
base/7/x86_64                       CentOS-7 - Base                       10,097
extras/7/x86_64                     CentOS-7 - Extras                        335
my-repository                       my repository                              1
updates/7/x86_64                    CentOS-7 - Updates                     1,487
repolist: 11,920

この通り、my-repositoryが追加され、パッケージが1つあることが確認できる。

# yum search jq
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
=============================== N/S matched: jq ================================
jq.x86_64 : Command-line JSON processor

  Name and summary matches only, use "search all" for everything.

searchもヒットする。

パッケージインストール

では、いよいよインストール。

# yum install jq
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
my-repository                                            | 2.9 kB     00:00     
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ jq.x86_64 0:1.6-1.el7 を インストール
--> 依存性の処理をしています: libonig.so.2()(64bit) のパッケージ: jq-1.6-1.el7.x86_64
--> 依存性解決を終了しました。
エラー: パッケージ: jq-1.6-1.el7.x86_64 (my-repository)
             要求: libonig.so.2()(64bit)
 問題を回避するために --skip-broken を用いることができます。
 これらを試行できます: rpm -Va --nofiles --nodigest

あっ…

Linux用jqのバイナリをダウンロードする場合は単体で動作するが、パッケージインストール時は鬼車が依存で必要。

oniguruma-5.9.5-3.el7.x86_64 RPM

このファイルをリポジトリに追加しよう。

パッケージファイルを追加

ファイルを追加して、リポジトリメタデータを更新すればOK

ファイルを追加

# curl -LO https://rpmfind.net/linux/epel/7/x86_64/Packages/o/oniguruma-5.9.5-3.el7.x86_64.rpm
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  128k  100  128k    0     0  51702      0  0:00:02  0:00:02 --:--:-- 51684
# ls -l
合計 300
-rw-r--r--. 1 root root 170978  3月  8 21:28 jq-1.6-1.el7.x86_64.rpm
-rw-r--r--. 1 root root 131744  3月  8 22:02 oniguruma-5.9.5-3.el7.x86_64.rpm

リポジトリデータを更新

# createrepo --update /var/www/html/yum-repo/
Spawning worker 0 with 1 pkgs
Spawning worker 1 with 0 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete

クライアント側の更新

# yum repolist 
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
リポジトリー ID                     リポジトリー名                        状態
base/7/x86_64                       CentOS-7 - Base                       10,097
extras/7/x86_64                     CentOS-7 - Extras                        335
my-repository                       my repository                              1
updates/7/x86_64                    CentOS-7 - Updates                     1,487
repolist: 11,920

キャッシュが効いているため、"my repository"の件数が1のまま。

# yum makecache

# yum clean all

を実行。

# yum repolist 
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
リポジトリー ID                     リポジトリー名                        状態
base/7/x86_64                       CentOS-7 - Base                       10,097
extras/7/x86_64                     CentOS-7 - Extras                        335
my-repository                       my repository                              2
updates/7/x86_64                    CentOS-7 - Updates                     1,487
repolist: 11,921

2件に更新された。

jqのインストール

]# yum install jq
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ty1.mirror.newmediaexpress.com
 * extras: ty1.mirror.newmediaexpress.com
 * updates: ty1.mirror.newmediaexpress.com
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ jq.x86_64 0:1.6-1.el7 を インストール
--> 依存性の処理をしています: libonig.so.2()(64bit) のパッケージ: jq-1.6-1.el7.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ oniguruma.x86_64 0:5.9.5-3.el7 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

================================================================================
 Package          アーキテクチャー
                                バージョン           リポジトリー          容量
================================================================================
インストール中:
 jq               x86_64        1.6-1.el7            my-repository        167 k
依存性関連でのインストールをします:
 oniguruma        x86_64        5.9.5-3.el7          my-repository        129 k

トランザクションの要約
================================================================================
インストール  1 パッケージ (+1 個の依存関係のパッケージ)

総ダウンロード容量: 296 k
インストール容量: 936 k
Is this ok [y/d/N]: y
Downloading packages:
(1/2): jq-1.6-1.el7.x86_64.rpm                             | 167 kB   00:00     
(2/2): oniguruma-5.9.5-3.el7.x86_64.rpm                    | 129 kB   00:00     
--------------------------------------------------------------------------------
合計                                               5.5 MB/s | 296 kB  00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : oniguruma-5.9.5-3.el7.x86_64                    1/2 
  インストール中          : jq-1.6-1.el7.x86_64                             2/2  
  検証中                 : jq-1.6-1.el7.x86_64                             1/2  
  検証中                 : oniguruma-5.9.5-3.el7.x86_64                    2/2 
インストール:
  jq.x86_64 0:1.6-1.el7

依存性関連をインストールしました:
  oniguruma.x86_64 0:5.9.5-3.el7

完了しました!
$ jq --version
jq-1.6

インストール対象のサーバがインターネットに接続できずに数も多い時や、クライアント用途のLinuxがある場合は、ファイル配布して個別にインストールよりはスマートと思う。


クライアント側のリポジトリ設定は、Ansibleで自動化できる場合はyum_repositoryモジュールを使うのが簡単。

yum_repository – Add or remove YUM repositories — Ansible Documentation

使い方はこちら

zaki-hmkc.hatenablog.com


この辺とコンボしてね

zaki-hmkc.hatenablog.com

(CentOS7) sudo実行時に/usr/local/binにパスが設定されてないのは何故

結論から書くと、sudoの実行元のユーザのPATH設定・sudoの実行先のユーザ(root)のPATH設定、どちらも関係なく、/etc/sudoersでPATHを再設定しているため。

Defaults    env_reset                                    # 環境変数をクリア

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin  # 環境変数PATHを再設定

この設定により、sudoの元ユーザ・権限変更先ユーザ関係なく、/sbin:/bin:/usr/sbin:/usr/binがPATHに設定されて実行される。

[zaki@registry ~]$ sudo /usr/bin/env | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin

そのため、例えば/usr/loca/binに置いたdocker-composeコマンドはPATH設定が無いためコマンド名のみだと実行に失敗する。

[zaki@registry ~]$ sudo docker-compose
sudo: docker-compose: コマンドが見つかりません

sudoで/usr/local/binにPATHを通すには

じゃあどうすれば/usr/local/binにPATHを通した状態でsudoできるかというと、

(A) secure_path/usr/local/binも追加する

--- /etc/sudoers.org    2019-10-25 00:23:49.000000000 +0900
+++ /etc/sudoers        2020-03-05 22:45:27.716903825 +0900
@@ -86,5 +86,5 @@
 # Defaults   env_keep += "HOME"
 
-Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
 
 ## Next comes the main part: which users can run what software on 

この変更を加えたうえで

[zaki@registry ~]$ sudo docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

動きました。

(B) sudo時にPATHを引き継ぐ

--- /etc/sudoers.org    2019-10-25 00:23:49.000000000 +0900
+++ /etc/sudoers        2020-03-05 22:50:00.429974656 +0900
@@ -86,5 +86,6 @@
 # Defaults   env_keep += "HOME"
 
-Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+#Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+Defaults    env_keep += "PATH"
 
 ## Next comes the main part: which users can run what software on 

secure_pathの設定丸ごと削除し、替わりにenv_keepというsudo時に引き継ぎたい環境変数名にPATHを追加(+=)する。

[zaki@registry ~]$ sudo docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

こちらも動きました


参考

qiita.com


Linuxのお作法としてyumaptなどディストリビューションで管理してるパッケージでインストールしたものは/usr/binに入るけど、自前でmakeしたり管理外のものは/usr/local/binに入れるようになってる。(と昔学習した)

www.atmarkit.co.jp

ので、言い方を変えれば、/usr/local以下は野良アプリが入ってるので、不用意に特権のある状態で実行しないようになっているんだなぁ、と。

(コマンドメモ)ssh経由でリモートのファイル一覧をtarする

たまに使うので備忘録

リモートの/home/zaki/work/ansibleをローカルにansible.tar.gzとして固める

[zaki@manager-dev ~]$ ls
[zaki@manager-dev ~]$ 
[zaki@manager-dev ~]$ ssh zaki@192.168.0.19 tar cz /home/zaki/work/ansible | cat - > ansible.tar.gz
zaki@192.168.0.19's password: 
tar: メンバ名から先頭の `/' を取り除きます
[zaki@manager-dev ~]$ ls
ansible.tar.gz
[zaki@manager-dev ~]$ tar tf ansible.tar.gz 
home/zaki/work/ansible/
home/zaki/work/ansible/vmware/
home/zaki/work/ansible/vmware/inventory.ini
home/zaki/work/ansible/vmware/ansible.cfg
:
:

f-を指定して、ssh zaki@192.168.0.19 tar czf - /home/zaki/work/ansible | cat - > ansible.tar.gzでも一緒

ローカルのtar.gzをリモートの/var/tmp以下へ展開する

[zaki@manager-dev ~]$ cat ansible.tar.gz | ssh 192.168.0.19 tar xz -C /var/tmp/
zaki@192.168.0.19's password: 
[zaki@manager-dev ~]$ 
[zaki@manager-dev ~]$ ssh zaki@192.168.0.19 find /var/tmp/home/
zaki@192.168.0.19's password: 
/var/tmp/home/
/var/tmp/home/zaki
/var/tmp/home/zaki/work
/var/tmp/home/zaki/work/ansible
/var/tmp/home/zaki/work/ansible/vmware
/var/tmp/home/zaki/work/ansible/vmware/inventory.ini
/var/tmp/home/zaki/work/ansible/vmware/ansible.cfg
:
:

fで標準入力(-)を指定して、cat ansible.tar.gz | ssh 192.168.0.19 tar xzf - -C /var/tmp/でも一緒 ただ、これはzが無いとエラーだった。

[zaki@manager-dev ~]$ cat ansible.tar.gz | ssh 192.168.0.19 tar x -C /var/tmp/
zaki@192.168.0.19's password: 
tar: アーカイブは圧縮されています. -z オプションを使ってください

※ 普通にファイルを指定する場合はtar xf file.tar.gzだけでよい。

[zaki@manager-dev ~]$ tar --version
tar (GNU tar) 1.26
Copyright (C) 2011 Free Software Foundation, Inc.
使用許諾 GPLv3+: GNU GPL version 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

[参考訳]
これはフリーソフトウェアです. 変更と再配布は自由です.
法律で認められる範囲で「無保証」です.

作者: John Gilmore, Jay Fenlason.

もちろんコンテナイメージをdocker load < -とかもできる。

oc runでPod単体デプロイするとoc adm drainで退避できないので注意 (作業ログ)

oc run --restart=NeverでPod単体で動作させると、oc adm drainでノードをサービスアウトさせようとしても、Podが退避されないのでその様子の実行ログ。
この記事の補足的な内容。

zaki-hmkc.hatenablog.com

環境

[zaki@okd4-manager ~]$ oc version
Client Version: 4.4.0-0.okd-2020-01-28-022517
Server Version: 4.4.0-0.okd-2020-01-28-022517
Kubernetes Version: v1.17.1

ノード構成

[zaki@okd4-manager ~]$ oc get node -o wide
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION           CONTAINER-RUNTIME
okd4-master0   Ready    master   10d   v1.17.1   172.16.0.10   <none>        Fedora CoreOS 31.20200127.20.1   5.4.13-201.fc31.x86_64   cri-o://1.17.0-rc1
okd4-master1   Ready    master   10d   v1.17.1   172.16.0.11   <none>        Fedora CoreOS 31.20200127.20.1   5.4.13-201.fc31.x86_64   cri-o://1.17.0-rc1
okd4-master2   Ready    master   10d   v1.17.1   172.16.0.12   <none>        Fedora CoreOS 31.20200127.20.1   5.4.13-201.fc31.x86_64   cri-o://1.17.0-rc1
okd4-worker0   Ready    worker   10d   v1.17.1   172.16.0.20   <none>        Fedora CoreOS 31.20200127.20.1   5.4.13-201.fc31.x86_64   cri-o://1.17.0-rc1
okd4-worker1   Ready    worker   10d   v1.17.1   172.16.0.21   <none>        Fedora CoreOS 31.20200127.20.1   5.4.13-201.fc31.x86_64   cri-o://1.17.0-rc1

Pod状態

[zaki@okd4-manager ~]$ oc get pod -o wide
NAME                                   READY   STATUS      RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
dc-run-pod-1-deploy                    0/1     Completed   0          62m   10.129.0.20   okd4-worker0   <none>           <none>
dc-run-pod-1-ht77f                     1/1     Running     0          62m   10.128.2.19   okd4-worker1   <none>           <none>
dc-run-with-svc-1-deploy               0/1     Completed   0          54m   10.129.0.22   okd4-worker0   <none>           <none>
dc-run-with-svc-1-wddbs                1/1     Running     0          53m   10.128.2.20   okd4-worker1   <none>           <none>
deploy-run-pod-56c6698fdb-dzk2g        1/1     Running     0          60m   10.129.0.21   okd4-worker0   <none>           <none>
deploy-run-with-svc-5ffbb8d9c7-h2j28   1/1     Running     0          51m   10.129.0.23   okd4-worker0   <none>           <none>
never-restart-pod                      1/1     Running     0          67m   10.128.2.18   okd4-worker1   <none>           <none>

never-restart-podが単体で動いてるPod(親リソース無し)
これがデプロイされてるノード(okd4-worker1)をdrainする。

drain

[zaki@okd4-manager ~]$ oc adm drain okd4-worker1 --ignore-daemonsets --delete-local-data 
node/okd4-worker1 cordoned
evicting pod "alertmanager-main-1"
evicting pod "downloads-cf5d8d7f4-b9bfg"
evicting pod "csi-snapshot-controller-f44f9d4b4-fvwv2"
evicting pod "alertmanager-main-0"
evicting pod "prometheus-adapter-d48bc96cc-g8nwl"
evicting pod "grafana-66d8c446bf-p75bt"
evicting pod "kube-state-metrics-84bf857f94-fpcc8"
evicting pod "telemeter-client-954595b4d-cfptr"
evicting pod "prometheus-k8s-0"
evicting pod "dc-run-pod-1-ht77f"
evicting pod "dc-run-with-svc-1-wddbs"
pod/csi-snapshot-controller-f44f9d4b4-fvwv2 evicted
pod/prometheus-k8s-0 evicted
pod/telemeter-client-954595b4d-cfptr evicted
pod/alertmanager-main-0 evicted
pod/alertmanager-main-1 evicted
pod/dc-run-pod-1-ht77f evicted
pod/downloads-cf5d8d7f4-b9bfg evicted
pod/grafana-66d8c446bf-p75bt evicted
pod/kube-state-metrics-84bf857f94-fpcc8 evicted
pod/prometheus-adapter-d48bc96cc-g8nwl evicted
pod/dc-run-with-svc-1-wddbs evicted
node/okd4-worker1 evicted
[zaki@okd4-manager ~]$ 

drainの結果

[zaki@okd4-manager ~]$ oc get pod -o wide
NAME                                   READY   STATUS      RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
dc-run-pod-1-deploy                    0/1     Completed   0          65m   10.129.0.20   okd4-worker0   <none>           <none>
dc-run-pod-1-zjslf                     1/1     Running     0          99s   10.129.0.30   okd4-worker0   <none>           <none>
dc-run-with-svc-1-deploy               0/1     Completed   0          56m   10.129.0.22   okd4-worker0   <none>           <none>
dc-run-with-svc-1-tqf44                1/1     Running     0          99s   10.129.0.26   okd4-worker0   <none>           <none>
deploy-run-pod-56c6698fdb-dzk2g        1/1     Running     0          63m   10.129.0.21   okd4-worker0   <none>           <none>
deploy-run-with-svc-5ffbb8d9c7-h2j28   1/1     Running     0          54m   10.129.0.23   okd4-worker0   <none>           <none>
never-restart-pod                      1/1     Running     0          70m   10.128.2.18   okd4-worker1   <none>           <none>

この通り、drainしてもevictされない。

--forceを付けるとと強制的にevictされるが、停止するだけで別ノードで再デプロイはされない。

[zaki@okd4-manager ~]$ oc adm uncordon okd4-worker1
node/okd4-worker1 uncordoned
[zaki@okd4-manager ~]$ oc adm drain okd4-worker1 --ignore-daemonsets --delete-local-data --force 
node/okd4-worker1 cordoned
WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: run-sample/never-restart-pod
evicting pod "alertmanager-main-0"
evicting pod "router-default-5698995cc8-b7k5f"
evicting pod "migrator-5746b7d596-vnrf8"
evicting pod "grafana-66d8c446bf-8ws9l"
evicting pod "prometheus-k8s-0"
evicting pod "never-restart-pod"
pod/alertmanager-main-0 evicted
pod/grafana-66d8c446bf-8ws9l evicted
pod/router-default-5698995cc8-b7k5f evicted
pod/prometheus-k8s-0 evicted
pod/migrator-5746b7d596-vnrf8 evicted
pod/never-restart-pod evicted
node/okd4-worker1 evicted
[zaki@okd4-manager ~]$ oc get pod -o wide
NAME                                   READY   STATUS      RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
dc-run-pod-1-deploy                    0/1     Completed   0          70m     10.129.0.20   okd4-worker0   <none>           <none>
dc-run-pod-1-zjslf                     1/1     Running     0          6m53s   10.129.0.30   okd4-worker0   <none>           <none>
dc-run-with-svc-1-deploy               0/1     Completed   0          61m     10.129.0.22   okd4-worker0   <none>           <none>
dc-run-with-svc-1-tqf44                1/1     Running     0          6m53s   10.129.0.26   okd4-worker0   <none>           <none>
deploy-run-pod-56c6698fdb-dzk2g        1/1     Running     0          68m     10.129.0.21   okd4-worker0   <none>           <none>
deploy-run-with-svc-5ffbb8d9c7-h2j28   1/1     Running     0          59m     10.129.0.23   okd4-worker0   <none>           <none>

ノードにCompletedなPodが残っている場合、drainによって消える。
また、OCPのバージョンによってはエラーになる。


k8sでも同じだと思うけど、よく考えたら自由に使えるマルチノードk8sクラスタ持ってなかった… 作るか…


ふと思ったけど、restartPolicy: Never以外の設定でPod単体で動かせたりできるのかな…?

[oc / kubectl] runでデプロイできるpodとその親リソースについて (廃止予定オプション--generatorの動作)

oc runを使ったPodのデプロイについて。

OpenShift v4では、oc runを使ってDeploymentConfigやDeploymentを作成するとDEPRECATEDの警告が表示さるようになった。(正確にはv4.1は触ったことないからわからない)
k8sバージョン1.18で無くなる模様。

github.com

予定ではpod単体のデプロイに特化するようになるらしいが、現状どう動作するかについてまとめた。
以下、OKD v4.4(k8s v1.17.1)で確認。

[zaki@okd4-manager ~]$ oc version
Client Version: 4.4.0-0.okd-2020-01-28-022517
Kubernetes Version: v1.17.1

Pod単発

現在は--restart=Neverを付けるとpod単体でデプロイされる。(将来これがデフォルトの動作になるっぽい)

[zaki@okd4-manager ~]$ oc run never-restart-pod --restart=Never --image=rhel:7.7 -- tail -f /dev/null
pod/never-restart-pod created
[zaki@okd4-manager ~]$ oc get all
NAME                    READY   STATUS              RESTARTS   AGE
pod/never-restart-pod   0/1     ContainerCreating   0          2s

DeploymentConfigで起動

OpenShiftではこれがデフォルト動作。

[zaki@okd4-manager ~]$ oc run dc-run-pod --image=rhel:7.7 -- tail -f /dev/null
kubectl run --generator=deploymentconfig/v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
[zaki@okd4-manager ~]$ oc get all -l run=dc-run-pod
NAME                     READY   STATUS    RESTARTS   AGE
pod/dc-run-pod-1-ht77f   1/1     Running   0          49s

NAME                                 DESIRED   CURRENT   READY   AGE
replicationcontroller/dc-run-pod-1   1         1         1       57s

NAME                                            REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/dc-run-pod   1          1         1         config

DeploymentConfig, ReplicationController, Podが作成される。

Deploymentで起動

--generator=deployment/apps.v1を付けるとDeploymentConfigでなくDeploymentが作成される。
kubectlの場合はこちらがデフォルト動作。

[zaki@okd4-manager ~]$ oc run deploy-run-pod --generator=deployment/apps.v1 --image=rhel:7.7 -- tail -f /dev/null
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
[zaki@okd4-manager ~]$ oc get all -l run=deploy-run-pod
NAME                                  READY   STATUS    RESTARTS   AGE
pod/deploy-run-pod-56c6698fdb-dzk2g   1/1     Running   0          42s

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-run-pod   1/1     1            1           42s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-run-pod-56c6698fdb   1         1         1       42s

Deployment, ReplicaSet, Podが作成される。


k8s(1.17)の場合

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl run k8s-run-pod --image=centos:7 -- tail -f /dev/null
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/k8s-run-pod created
$ kubectl get all -l run=k8s-run-pod
NAME                               READY   STATUS    RESTARTS   AGE
pod/k8s-run-pod-655b579894-dzlc2   1/1     Running   0          20s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/k8s-run-pod   1/1     1            1           20s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/k8s-run-pod-655b579894   1         1         1       20s

デプロイと同時にServiceリソースも作成する

--exposeと、--portで使用するポート番号を指定する。
(--portのみだとserviceは作成されない。--expose--portの指定が無ければエラーになる)

[zaki@okd4-manager ~]$ oc run dc-run-with-svc --image=rhel:7.7 --port=8080 --expose -- tail -f /dev/null 
kubectl run --generator=deploymentconfig/v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
service/dc-run-with-svc created
deploymentconfig.apps.openshift.io/dc-run-with-svc created
[zaki@okd4-manager ~]$ oc get all -l run=dc-run-with-svc
NAME                          READY   STATUS              RESTARTS   AGE
pod/dc-run-with-svc-1-wddbs   0/1     ContainerCreating   0          1s

NAME                                      DESIRED   CURRENT   READY   AGE
replicationcontroller/dc-run-with-svc-1   1         1         0       9s

NAME                                                 REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/dc-run-with-svc   1          1         1         config
[zaki@okd4-manager ~]$ oc get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
dc-run-with-svc   ClusterIP   172.30.211.158   <none>        8080/TCP   16s

dc,rc,pod,svcが作成される。

Depoyment + Service

これまでの組み合わせ。

[zaki@okd4-manager ~]$ oc run deploy-run-with-svc --image=rhel:7.7 --generator=deployment/apps.v1 --port=8080 --expose -- tail -f /dev/null
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
service/deploy-run-with-svc created
deployment.apps/deploy-run-with-svc created
[zaki@okd4-manager ~]$ oc get all -l run=deploy-run-with-svc
NAME                                       READY   STATUS    RESTARTS   AGE
pod/deploy-run-with-svc-5ffbb8d9c7-h2j28   1/1     Running   0          20s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-run-with-svc   1/1     1            1           20s

NAME                                             DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-run-with-svc-5ffbb8d9c7   1         1         1       20s
[zaki@okd4-manager ~]$ oc get svc
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
dc-run-with-svc       ClusterIP   172.30.211.158   <none>        8080/TCP   2m54s
deploy-run-with-svc   ClusterIP   172.30.202.241   <none>        8080/TCP   22s

oc run--dry-runが使えるので、実行前に--dry-run -o yamlすれば何が起きるかわかりやすいし、何ならYAMLファイルに出力してマニフェスト作成して、oc apply -fするのが何かと楽と思う。きっと。

とはいえ--generatorは近い将来(というか次のk8sリリース)に廃止されるオプションなので、大人しくoc createに移行するのが吉。


ちなみにpod単体でデプロイしてもオートヒーリングとか聞かないしデプロイされてるノードをdrainしても退避できないのでいろいろ注意(というか検証用に使おう)

zaki-hmkc.hatenablog.com