Foreverly

メモ帳

kubeadmでHA構成のetcdクラスタ構築

最新手順はこちら

Kubeadmは、コントロールプレーンノード上のkubeletによって管理される静的ポッドで単一メンバーのetcdクラスタをデフォルトで実行する。 etcdクラスターに含まれるメンバーは1つだけで、メンバーが使用不可になっても持続できないため、これはHA設定ではない。 このタスクでは、kubeadmを使用してkubernetesクラスタを設定するときに外部etcdとして使用できる3つのメンバからなる高可用性etcdクラスタを作成する手順をみていく。

始める前に

  • ポート2379および2380を介して互いに通信できる3つのホスト。(今回はこれらをデフォルトポートと想定。kubeadmの設定ファイルで設定可能)
  • 各ホストにはdocker、kubelet、およびkubeadmがインストールされている必要がある。
  • ホスト間でファイルをコピーするためのssh, scpなどが可能であること。

クラスタを設定

一般的な方法は、1つのノードですべての証明書を生成し、必要なファイルだけを他のノードに配布すること。

※kubeadmには、以下に説明する証明書を生成するために必要なすべての暗号化機構が含まれているので他の暗号化ツールは必要ない

  1. etcのサービスマネージャになるようにkubeletを設定

etcdが最初に作成されたので、kubeadm提供のkubeletユニットファイルよりも高い優先順位を持つ新しいユニットファイルを作成することによって サービスの優先順位を上書きする必要がある。

cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true
Restart=always
EOF

systemctl daemon-reload
systemctl restart kubelet
  1. kubeadm用の設定ファイルを作成

以下のスクリプトを使用して、etcdメンバーが実行されるホストごとに1つのkubeadm構成ファイルを生成する。

# Update HOST0, HOST1, and HOST2 with the IPs or resolvable names of your hosts
export HOST0=10.64.20.1
export HOST1=10.64.20.2
export HOST2=10.64.20.3

# Create temp directories to store files that will end up on other hosts.
mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/

ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2})
NAMES=("infra0" "infra1" "infra2")

for i in "${!ETCDHOSTS[@]}"; do
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
apiVersion: "kubeadm.k8s.io/v1beta1"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380,${NAMES[2]}=https://${ETCDHOSTS[2]}:2380
            initial-cluster-state: new
            name: ${NAME}
            listen-peer-urls: https://${HOST}:2380
            listen-client-urls: https://${HOST}:2379
            advertise-client-urls: https://${HOST}:2379
            initial-advertise-peer-urls: https://${HOST}:2380
EOF
done
  1. 認証局を生成する

すでにCAを持っているなら、 crtkey ファイルを /etc/kubernetes/pki/etcd/ca.crt/etc/kubernetes/pki/etcd/ca.key にコピーするだけがアクションです これらのファイルをコピーしたら、次の手順「各メンバーの証明書を作成する」に進む。ない場合は作成する。

  1. 各メンバーの証明書を作成する
kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST2}/
# cleanup non-reusable certificates
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST1}/
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# No need to move the certs because they are for HOST0

# clean up certs that should not be copied off this host
find /tmp/${HOST2} -name ca.key -type f -delete
find /tmp/${HOST1} -name ca.key -type f -delete
  1. 証明書とkubeadm設定をコピーする

証明書が生成されたので、今度はそれらをそれぞれのホストに移動する必要がある。

 USER=hogeuser
 HOST=${HOST1}
 scp -r /tmp/${HOST}/* ${USER}@${HOST}:
 ssh ${USER}@${HOST}
 USER@HOST $ sudo -Es
 root@HOST $ chown -R root:root pki
 root@HOST $ mv pki /etc/kubernetes/
  1. 必要なファイルがすべて存在することを確認。

$HOST0 に必要なファイルの完全なリストは以下。

/tmp/${HOST0}
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── ca.key
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

$HOST1

$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

$HOST2

$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key
  1. 静的ポッドマニフェストを作成

証明書と設定が整ったので、次にマニフェストを作成。 各ホストで、kubeadmコマンドを実行してetcdの静的マニフェストを生成する。

root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml
root@HOST1 $ kubeadm init phase etcd local --config=/home/ubuntu/kubeadmcfg.yaml
root@HOST2 $ kubeadm init phase etcd local --config=/home/ubuntu/kubeadmcfg.yaml
  1. オプション:クラスターの正常性を確認
docker run --rm -it \
--net host \
-v /etc/kubernetes:/etc/kubernetes quay.io/coreos/etcd:${ETCD_TAG} etcdctl \
--cert-file /etc/kubernetes/pki/etcd/peer.crt \
--key-file /etc/kubernetes/pki/etcd/peer.key \
--ca-file /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://${HOST0}:2379 cluster-health
...
cluster is healthy

${ETCD_TAG} :あなたのetcd画像のバージョンタグを設定。例えばv3.2.24。 ${HOST0} :テストしているホストのIPアドレスを設定。

Creating multi master cluster with kubeadm(ver1.13以下)

document

https://kubernetes.io/docs/setup/independent/install-kubeadm/ https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ kubeadmのトラブルシューティング

始める前に

  1. 以下のいずれかを実行している1台以上のマシンを用意
  2. Ubuntu 16.04+
  3. CentOS 7
  4. マシンごとに2 GB以上のRAM(それ以下にすると、アプリケーション用のスペースが狭まる)
  5. 2 CPU以上
  6. クラスタ内のすべてのマシン間の完全なネットワーク接続(パブリックまたはプライベートネットワークは問題なし)
  7. ノードごとに固有のホスト名、MACアドレス、およびproduct_uuid。
  8. マシンでは特定のポートを開けとく
  9. スワップ無効(kubeletを正しく動作させるためにスワップを無効にする。)

今回の構成

ホスト名 役割
haproxy01 ロードバランサー(HAProxy)
master-node01 MasterNode
master-node02 MasterNode
master-node03 MasterNode
worker-node01 WorkerNode
worker-node02 WorkerNode
worker-node03 WorkerNode

クライアントに必要なもの

cfsslとkubectlをインストールする

HAProxyロードバランサーのインストール

3つのKubernetesマスターノードを配置するので、 トラフィックを分散させるためにそれらの前にHAPRoxyロードバランサーを配置する必要がある。

  1. LBにするサーバにSSHで接続します。
  2. OS update
  3. $ sudo yum update -y
  4. HAProxyをインストール
  5. $ sudo yum install haproxy
  6. 3つのKubernetesマスターノード間でトラフィックを負荷分散するようにHAProxyを設定。
$ sudo vim /etc/haproxy/haproxy.cfg
global
...
default
...
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend kubernetes
    bind 10.64.21.35:6443
    option tcplog
    mode tcp
    default_backend kubernetes-master-nodes
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
    balance     roundrobin
    server      static 127.0.0.1:4331 check

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-master-nodes
    mode tcp
    balance     roundrobin
    option tcp-check
    server  master-node01 10.64.20.01:6443 check
    server  master-node02 10.64.20.02:6443 check
    server  master-node03 10.64.20.03 :6443 check
  1. HAProxyを再起動。

$ sudo systemctl restart haproxy

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

systemctl enable kubelet && systemctl start kubelet

以下は各kubeノードで実行

sudo visudo で一般ユーザにroot権限を付与 sudo yum -y install vim

Dockerのインストール

最新の手順はこちら

$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum -y install docker-ce-18.06.1.ce-3.el7
$ sudo systemctl start docker & sudo systemctl enable docker

kubeadmのインストール

最新の手順はこちら

まず事前準備として、全ノードで Docker、CLI 等の関連パッケージのインストールと、 クラスタ内で利用するオーバーレイネットワーク用にカーネルパラメータを変更しておきます。

# 必要な依存パッケージのインストール
$ sudo yum -y update
# リポジトリの登録と更新
$ sudo su -
$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF

# SELinux disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# Kubernetes 関連パッケージのインストール
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

systemctl enable --now kubelet
# オーバーレイネットワーク用にカーネルパラメータを変更 
# RHEL / CentOS 7の一部のユーザーは、iptablesがバイパスされているために
# トラフィックが誤ってルーティングされるという問題を報告しています。
# あなたのnet.bridge.bridge-nf-call-iptables設定で1に設定されていることを確認する必要がある
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

kubeadmを使ったHAクラスタの作成

最新の手順はこちら

TLS証明書を生成する

これらの手順は、cfsslツールをインストールした場所に応じて、 LinuxデスクトップまたはHAProxyマシン上にあれば実行できる。

認証局を作成する

  1. 認証局設定ファイルを作成します。
$ vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
  1. 認証局署名要求設定ファイルを作成します。
$ vim ca-csr.json
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
  {
    "C": "IE",
    "L": "Cork",
    "O": "Kubernetes",
    "OU": "CA",
    "ST": "Cork Co."
  }
 ]
}
  1. 認証局証明書と秘密鍵を生成します。
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
  1. ca-key.pemとca.pemが生成されたことを確認します。
$ ls -la

Etcdクラスター用の証明書を作成する

  1. 証明書署名要求設定ファイルを作成します。
$ vim kubernetes-csr.json
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
  {
    "C": "IE",
    "L": "Cork",
    "O": "Kubernetes",
    "OU": "Kubernetes",
    "ST": "Cork Co."
  }
 ]
}
  1. 証明書と秘密鍵を生成します。
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=10.64.20.1,10.64.20.2,10.64.20.3,10.64.21.35,127.0.0.1,kubernetes.default \
-profile=kubernetes kubernetes-csr.json | \
cfssljson -bare kubernetes
  1. kubernetes-key.pemファイルとkubernetes.pemファイルが生成されたことを確認

ls -la

  1. 証明書を各ノードにコピー
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.1~
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.2:~
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.3:~
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.4:~
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.5:~
$ scp ca.pem kubernetes.pem kubernetes-key.pem hogeuser@10.64.20.6:~

最初のコントロールプレーンノードの手順

  1. 最初のコントロールプレーンノードで、次の設定ファイルを作成 kubeadm-config.yaml

  2. kubernetesVersion 使用するKubernetesバージョンに設定する必要があります。この例では stable を使用。

  3. controlPlaneEndpoint ロードバランサのアドレスまたはDNSとポートを一致させる必要があり。
  4. kubeadm、kubelet、kubectl およびKubernetesのバージョンを一致させることがお勧め。
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
  certSANs:
  - "10.64.21.35"
controlPlaneEndpoint: "10.64.21.35:6443"
  1. ノードがクリーンな状態にあることを確認
sudo kubeadm init --config=kubeadm-config.yaml

次のようなものが見えるはず

To start using your cluster, you need to run the following as a regular user:

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

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

kubeadm join 10.64.21.35:6443 --token c6c3id.bba2b5hih8ka9jx3 --discovery-token-ca-cert-hash sha256:b078841bd826050e1461341835ffc5a5b0cf2e32365a33794eb77512ca0c016a
  1. この出力をテキストファイルにコピーし。後で他のコントロールプレーンノードをクラスタに参加させるために必要になる。
  2. Weave CNIプラグインを適用
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

kubectl を kubelet に利用可能にするために以下のコマンドを実行しておくこと

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

実行しない場合は次のようになる。

# kubectl get pod --all-namespaces
    Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
  1. 次のように入力して、コンポーネントのPodを見始める。
kubectl get pod -n kube-system -w
  1. 最初のノードの初期化が完了した後にのみ、新しいコントロールプレーンノードを結合させる。

次の例でCONTROL_PLANE_IPSは、他のコントロールプレーンノードのIPアドレスに置き換えます。

USER=hogeuser
CONTROL_PLANE_IPS="10.64.20.190 10.64.20.186"
for host in ${CONTROL_PLANE_IPS}; do
    scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:
    scp /etc/kubernetes/pki/ca.key "${USER}"@$host:
    scp /etc/kubernetes/pki/sa.key "${USER}"@$host:
    scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:
    scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:
    scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:
    scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt
    scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key
    scp /etc/kubernetes/admin.conf "${USER}"@$host:
done

注意:上記のリストの証明書だけをコピーしてください。kubeadmは、参加しているコントロールプレーンインスタンスに必要なSANを使用して、残りの証明書を生成します。すべての証明書を誤ってコピーした場合、必要なSANが不足しているために追加のノードを作成できない可能性があります。

残りのコントロールプレーンノードの手順

ノード一つずつ、クラスタに組み込んでから次のノードに進むこと

  1. 前の手順で作成したファイルを scp を使用した場所に移動させる
USER=hogeuser
sudo mkdir -p /etc/kubernetes/pki/etcd
sudo mv /home/${USER}/ca.crt /etc/kubernetes/pki/
sudo mv /home/${USER}/ca.key /etc/kubernetes/pki/
sudo mv /home/${USER}/sa.pub /etc/kubernetes/pki/
sudo mv /home/${USER}/sa.key /etc/kubernetes/pki/
sudo mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
sudo mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
sudo mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
sudo mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
sudo mv /home/${USER}/admin.conf /etc/kubernetes/admin.conf
  1. 最初のノードで以前に渡されたjoinコマンドを使用して、このノードで起動( kubeadm init )します。これは次のようになります。
sudo kubeadm join 10.64.21.35:6443 --token c6c3id.bba2b5hih8ka9jx3 --discovery-token-ca-cert-hash sha256:b078841bd826050e1461341835ffc5a5b0cf2e32365a33794eb77512ca0c016a --experimental-control-plane

--experimental-control-plane フラグの追加に注意してください。このフラグは、このコントロールプレーンノードをクラスタに参加させることを自動化します。

コントロールプレーンノードをクラスタ追加失敗時は kubeadm reset して kubeadm init する。

  1. 次のように入力して、コンポーネントのポッドを見始めます。
kubectl get pod -n kube-system -w
  1. 残りのコントロールプレーンノードに対してこれらの手順を繰り返します。

workerノードのクラスタ組み込み

さきほどの kubeadm join のコマンドを --experimental-control-planeをつけないで 実行。 1台ずつpodが組み込まれて完了したことを確認してから実行していくこと。

unshareコマンドでLinuxのNamespaceに入門

Namespaceはコンテナで使われている技術の一つで、コンテナを理解深めるために知っておくとよいので調べてみた。 どんな使われ方をしているかというと、 例えばPID namespaceはPIDの number spaceを隔離する。 これは同じホスト上で実行されている2つのプロセスが同じPIDを持つことができるということになる。

namespaceがなくて隔離されてないとコンテナAがコンテナB、C、Dなどに filesystemのunmountやホスト名の変更、NWインターフェースの削除など できたりしてしまうので、必ず他のコンテナのプロセスがみれないようにする。

Namespace

Kernel/OSのリソースで、物理リソースは制限しない(cgroupsでする)が、 以下の項目についてNamespaceを分離する。 namespaceを分離した環境では、許可されたリソースしか見えなくなるので コンテナ内の要素だけ見えるように制限できる。

  • Mount Namespace(ファイルシステムのマウントポイントを分離: Namespace 内の mount / umount が他の Namespace に影響を与えないようにする)
  • UTS Namespace(ホスト名,ドメイン名の分離)
  • PID Namespace(PID 空間の分離、新しい PID Namespace では PID 1 から始まる)
  • IPC Namespace(セマフォ、MQ、共有メモリなどのプロセス間通信の分離)
  • User Namespace(UID、GID Namespaceの分離)
  • Network Namespace(インターフェース、ルーティングテーブル、ソケットなど)
  • cgroup Namespace(cgroupのルートディレクトリを分離)

cgroups

cpuやmemory、ディスクなどの物理リソース制限は cgroupsと呼ばれるカーネル機能で計測されアクセス制限される。 cgroupsではタスクをグループ化したり、そのグループ内のタスクに対して 以下のような物理リソースを制限できる。使用量やアクセスを制限する。

  • CPU
  • メモリ
  • ブロックデバイス(mmap可能なストレージとほぼ同義)
  • ネットワーク
  • /dev以下のデバイスファイル

unshareコマンドでNamespaceについて確認

unshare コマンドはparentから unshared されている namespaceを使用してプログラムを実行できるらしい。 unshare が新しいnamespace でどんなプログラムでも走らせることができるということ。実際にUTS Namespaceを例に unshareコマンドの動きを確認してみる。

    $ unshare -h
    
    Usage:
     unshare [options] <program> [<argument>...]
    
    Run a program with some namespaces unshared from the parent.
    
    オプション:
     -m, --mount               unshare mounts namespace
     -u, --uts                 unshare UTS namespace (hostname etc)
     -i, --ipc                 unshare System V IPC namespace
     -n, --net                 unshare network namespace
     -p, --pid                 unshare pid namespace
     -U, --user                unshare user namespace
     -f, --fork                fork before launching <program>
         --mount-proc[=<dir>]  mount proc filesystem first (implies --mount)
     -r, --map-root-user       map current user to root (implies --user)
         --propagation <slave|shared|private|unchanged>
                               modify mount propagation in mount namespace
     -s, --setgroups allow|deny  control the setgroups syscall in user namespaces
    
     -h, --help     display this help and exit
     -V, --version  output version information and exit
    
    For more details see unshare(1).

UTS Namespaceは名前空間ごとにホスト名やドメイン名を独自に持つことができる。 以下で UTS Namespace を unshare コマンドで操作してみる。

unshare -u /bin/shUTS名前空間を指定してunshare実行している これでホスト名、ドメイン名が分離されたので、 もとのホスト名は test-ozawa-dev01.amb-infra-dev.incvb.io だが、 unshare で切り替え後、 my-new-hostname に変更している。

もちろんこのホスト名は新たな namespace だけで有効なので、 unshareで起動したシェルを終了すると、ホスト名はもとに戻る。

    $ sudo su       # root userになる
    # uname -n   # 現在のhostnameを確認
    test01
    # unshare -u /bin/sh  # 新しいUTS namespaceでshellを作成
    sh-4.2# hostname my-new-hostname                 # hostnameを設定
    sh-4.2# uname -n                                 # 新しいhostnameを確認
    my-new-hostname
    sh-4.2# exit                        # 新しいUTS namespaceから出る
    exit
    # uname -n   # 元のhostnameが変更されていないことを確認
    test01

2018年読んだ本

2018年の読書メーター
読んだ本の数:15
読んだページ数:4818
ナイス数:70

アシュリーの戦争 -米軍特殊部隊を最前線で支えた、知られざる「女性部隊」の記録アシュリーの戦争 -米軍特殊部隊を最前線で支えた、知られざる「女性部隊」の記録感想
15時間ほどで読めた。CST(文化支援部隊)という女性メンバーだけの特殊部隊を追ったノンフィクション。CSTの役割はアフガニスタンでの戦闘でアフガニスタン人の女性や子供たちから情報を聞き出すことが彼女たちの任務で地上戦の最前線でレンジャーの任務を支えていました。主人公のアシュリーが英雄視されているようで、プロパガンダ的作品と感じとってしまいました。2016年にアメリカの女性兵士も地上戦闘に参加することが法的に認められたのも、このCSTがあってのことのようで米軍にとっても大きな影響を与えた部隊だと思います。
読了日:12月30日 著者:ゲイル・スマク・レモン
シベリアの掟シベリアの掟感想
15時間ほどで読めた。かなりの力作だけど面白かった。筆者の幼少期の自伝的小説。これはntddkさんが面白いとツイートしていたので読んだ。この本については多くは語るのは不要だと思いますので、この本についての感想は本の中で語られているシベリアの掟の引用で締めくくる。『私たちシベリアの民は、子供の頃から「言葉にフィルターをかける」、すなわちたとえ故意でなくとも決して過ちを犯さないよう、口から出る言葉に気をつけることを教えられてきた。シベリアの掟によれば、「一度口から飛び去った言葉は二度と戻ってこない」からだ。』
読了日:12月30日 著者:ニコライ・リリン
五色の虹 満州建国大学卒業生たちの戦後五色の虹 満州建国大学卒業生たちの戦後感想
8時間ほどで読めた。日本が満州国を建国した時の理念である五族協和満州国を引っ張っていくリーダーを育成するための学校である満州建国大学についての話。日・漢・朝・満・蒙から集められた超エリートの卒業生たちを取材することで少ない資料の中、どんな学校だったのか、どんなことを考えて授業を受けたのか、戦後どうなったのか話をきいて浮き彫りになっていく建国大学。日本の敗戦とともにエリートだった学生たちが不遇の待遇を受けていたりと、国がその優秀な人材を生かさず中には忙殺する亡国もあったりと、貴重な歴史的資料のような一冊。
読了日:12月30日 著者:三浦 英之
悪童日記 (ハヤカワepi文庫)悪童日記 (ハヤカワepi文庫)感想
5時間ほどで読めた。薄い小説だけどrebuild.fmで紹介されていたように凄まじい本。打ちのめされるような本。双子の男の子の日記の体でストーリーが進んでいきます。男の子たちの行動原理みたいなものが読み取れてるので、その行動が加速するにつれてページを捲るスピードも上がっていきました。全部で第3部らしいのですが、素晴らしい作品のようですのでほかも読んでみたいです。子供だから視点は狭いようで、大人とは別の視点を持ち戦争下の描写が書かれています。筆者の幼少期の体験を双子の男の子を通して追体験するような感覚です。
読了日:12月30日 著者:アゴタ クリストフ
UNIXという考え方―その設計思想と哲学UNIXという考え方―その設計思想と哲学感想
20時間ぐらいで読めたと思う。途中何年も積んだりしたので、正確な時間がわかないけど、薄いけど一気に読めるような文章ではないので読むのが大変だった。名著ということでとりあえず読んでみたのが良くないのか、あんまり理解できなかった。これだけみんな名著と思って読まれているのにUNIXという考え方で実装していないのは何故だと思うぐらい複雑だったり謎の処理つけたりしているので気をつけたいですね。Linuxコマンドは強力でそれを使うスクリプトも強力ですね。こんな内容の現代の本が読みたいのでオススメあったら教えて下さい。
読了日:11月30日 著者:Mike Gancarz
スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)スラスラ読める JavaScript ふりがなプログラミング (ふりがなプログラミングシリーズ)感想
6時間ほどで読めた。タイトルの通りスラスラ読めました。ES6でJavaScriptを説明していますので、これからJavaScriptを勉強したい人や、プログラミングを覚えたい人が読む最初の一冊には良いと思いました。ふりがなが全てに振ってあるので、これがどんな意味なのかを、おまじないなどでごまかしていないので納得して読み進めることができると思います。監修も及川卓也さんなので内容も安心して読むことができました。次のステップはどう進めていけばいいのかは書いてないので、どうステップを進めるかが難しいと思いました。
読了日:08月20日 著者:リブロワークス
Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本Linuxサーバーセキュリティ徹底入門 オープンソースによるサーバー防衛の基本感想
8時間ほどで読めました。CentOS6で内容は少し古いですが、現在動いているシステムを運用している人は読んでおくとよいと思いました。LinuxのOS全般とApacheやメールなどの設定でセキュアな設定について細かく書かれており、わかりやすく書かれています。どのような運用が望ましいのかなども自分で調べるには難しいですが、このような本が増えてほしいと思いました。MySQLなどのDBやPHPなどについては記載ありませんが、それらはどのような本を読めばいいかなどの動線があればよいなと思います。おすすめの一冊です。
読了日:08月16日 著者:中島 能和
インフラエンジニアの教科書2 スキルアップに効く技術と知識インフラエンジニアの教科書2 スキルアップに効く技術と知識感想
10時間ほどで読めた。インフラエンジニア教科書とのことなのでインフラエンジニアとして読んでみた。1は立ち読みしたことありますが、個人的には2の方が読んでいて面白かったです。オペレーションシステムの基礎知識をわりと実用的なレベルで紹介されていて、インフラエンジニアになった人のまさに教科書的な存在だと思います。個人的にはなるほどUnixなどで、手で動かしてから読んでから読んだ方が理解が深まると思います。OSの動作の理屈をいきなり本を読んで理解できる人は頭がいいと思うので、普通の人は手を動かすといいと思います。
読了日:07月31日 著者:佐野 裕
絵で見てわかるOS/ストレージ/ネットワーク~データベースはこう使っている (DB Magazine Selection)絵で見てわかるOS/ストレージ/ネットワーク~データベースはこう使っている (DB Magazine Selection)感想
読むのに30時間ぐらいかかったと思う。新人の時(6年前)から何度も途中で諦めたりした本。OSやストレージ、DBMS、ネットーワークとシステム周り全般のボトルネックがどこか、リソースをどう使っているのかなどをコマンド実行レイヤ、絵を通して詳細に解説してくれている。個人的には詳解システムパフォーマンスの前に読んでおくと良いのではないかと思った。内容はオンプレミスのシステム前提で少し古いので、今のクラウド時代での内容に即した内容ではどうなるか気になるし、どんな本がそれにあたるのか気になる。このような本読みたい。
読了日:07月31日 著者:小田 圭二
オブジェクト指向でなぜつくるのか 第2版オブジェクト指向でなぜつくるのか 第2版感想
15時間ほどで読めた。Pythonでクラスをどういう時に書くべきなのか、オブジェクト指向でプログラミングするとはどういうことなのかよくわかっていないのでオブジェクト指向とは何なのかじっくり調べたいと思って読みました。この本は1冊まるまる書いているので説明が豊富でわかりやすかったです。Pythonの入門本とかだと犬とか人間とかを例にしたりして解説するのが余計に混乱させられていたのでオブジェクト指向の歴史と意義やクラス(カプセル化)・継承・ポリモーフィズムがどう意味なのかわかりやすく説明してありよかったです。
読了日:07月31日 著者:平澤 章
アカマイ―知られざるインターネットの巨人 (角川EPUB選書)アカマイ―知られざるインターネットの巨人 (角川EPUB選書)感想
6時間ほどで読めた。インターネットのトラフィックがどう流れているのか、CDNのアカマイがどういう成り立ちでできたのか。どのようにサービスを成り立たせているのか、どのような仕組みなのかなどをわかりやすく説明されているので読んでいて楽しかったです。CDNを利用すればオリジンサーバへの負荷分散にもなり、ユーザも高速にアクセスができ本当に良いものです。ネットワークの基本のようなものと併せて本書を読むことでインターネットの大枠を掴むことができるのではないでしょうか。誰にでも読むことができるので、オススメの一冊です。
読了日:06月21日 著者:小川 晃通
MySQL徹底入門 第3版 ~5.5新機能対応~MySQL徹底入門 第3版 ~5.5新機能対応~感想
10時間ほどで読めた。4年ほど積んでいましたが、そろそろMySQLに入門したい気持ちになり読みました。内容としては設定から運用までわかりやすくまとめっていて良いと思います。内容も5.5なのでそこまで古くはないので今読んでも参考になりました。昨今MySQL8がリリースされましたが、ほとんどの運用されているMySQLのバージョンはおいくつでしょうか?そうですね。おわかりのように、この本の内容は古くはないのです。次は実践ハイパフォーマンスMySQLをよんでMySQLの内部にもう少し踏み込んでいきたいと思います。
読了日:05月30日 著者:遠藤 俊裕,坂井 恵,館山 聖司,鶴長 鎮一,とみた まさひろ,班石 悦夫,松信 嘉範
忘れられた巨人忘れられた巨人感想
40時間ぐらいかけて読んだ。カズオ・イシグロは初めて読みます。牧歌的なファンタジー小説という印象で、THE・ビッグオーのような世界観です。記憶を奪う霧のせいで過去が曖昧な老夫婦がある日息子の存在を思い出して、どこに住んでいるかも顔も思い出せない息子に会いに行こうと行くあてのない旅を初めます。舞台はイングランドで時代はアーサー王伝説なので、この物語には騎士王伝説の知識があるとより楽しめるのかもしれません。読んでいて、ついさっきの記憶も危うい人達の会話を延々と読むことになるので、かなりの混乱が起こりました。
読了日:05月02日 著者:カズオ イシグロ
データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]感想
8時間ほどで読めた。EFKで可視化したい人向けの本。 td-agentとElasticStackはバージョンが上がってしまったので、この本の内容は古いが、十分参考になる内容です。Qiitaぐらいしか日本語での情報がないEFKの可視化について上手くまとまっています。また、運用Tipsについても詳しく書かれていますので、運用や監視の勘所やチューニングの勘所についても参考になります。これからEFKで可視化をしたいと思っている人にはお勧めの一冊です。データ分析基盤の本で代表的な一冊になると思います。おすすめです。
読了日:04月22日 著者:鈴木 健太,吉田 健太郎,大谷 純,道井 俊介
Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版感想
6時間ほどで読めた。AWSでWEB/DB構成をインスタンス1台ずつたてて、Wordpressを構築するLessonとなっています。新改訂版でコンソールが日本語対応となっているので、わかりやすくなっています。一部コンソール表示は変わっていましたが。他にもネットワークの説明、VPNやサブネットなどAWS特有の説明もされているのでAWSはじめに読む本には良いと思います。TCP/IP周りの説明もされていますので、サーバやネットワークの勉強がしたい人にもおすすめです。内容は薄いのでサクサクすすめてよいと思います。
読了日:01月11日 著者:玉川憲,片山暁雄,今井雄太,大澤文孝

読書メーター

Kubernetes Application Update

303-app-updateの内容

Kubernetes Application Update

今回では、Kubernetesクラスタにデプロイされたアプリケーションを使用して更新する方法について説明しデプロイします。 また、アプリケーションのCanary Deploymentについても見ていきます。

Deploymentは、Podを管理するためのレプリカセットを作成します。 レプリカセット内のレプリカの数は、アプリケーションの要求に合わせて拡大縮小できます。 Deploymentを使用してdeployされたアプリケーションを更新するには、 Deploymentの構成を更新する必要があります。

この変更により、新しいレプリカセットが作成されます。 これは、以前のレプリカセットが縮小されている間にスケールアップされます。 これにより、アプリケーションのダウンタイムが発生しません。

kubectl rolling-update コマンドが ありますが、レプリカセットにのみ適用されます。 このコマンドからの更新は、クライアント側で行われました。 更新がサーバー側にあるので、Deploymentを使用してrolling-updateを行うことを強くお勧めします。

我々のユースケースでは、アプリケーションは最初に画像を使用します arungupta/app-upgrade:v1 。 次に、イメージを使用するようにDeploymentが更新されます arungupta/app-upgrade:v2 。 v1イメージは "Hello World!"を出力します。 v2イメージは「Howdy World!」を印刷します。 これらのイメージのソースコードimagesディレクトリにあります。

前提条件

この章の演習を行うには、Kubernetesクラスタ構成を展開する必要があります。 EKSベースのKubernetesクラスタを作成するには、AWS CLIを使用します。 EKSを使用せずにKubernetesクラスタを作成する場合は、代わりにkopsを使用できます。 この章の設定ファイルはすべてapp-updateディレクトリにあります。 この章のコマンドを実行する前に、そのディレクトリに移動してください。 Cloud9で作業している場合は、次のコマンドを実行します。

cd ~/environment/aws-workshop-for-kubernetes/03-path-application-development/303-app-update/

rolling-update

新しいリビジョンへのアップデート

アプリケーションを更新するには、既存のすべてのポッドを、別のバージョンのイメージを使用する新しいポッドに置き換える必要があります。 .spec.strategy デプロイメント設定で、古いポッドを新しいポッドに置き換えるための戦略を定義することができます。 このキーには次の2つの値があります。

  1. Recreate
  2. RollingUpdate (デフォルト)

この2つのデプロイ戦略を見てみましょう。

strategy を再作成する

既存のPodはすべて、新しいものが作成される前に強制終了されます。 設定ファイルは以下のようになります

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-recreate
spec:
  replicas: 5
  selector:
    matchLabels:
      name: app-recreate
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        name: app-recreate
    spec:
      containers:
      - name: app-recreate
        image: arungupta/app-upgrade:v1
        ports:
        - containerPort: 8080
  1. deploymentを作成
$ kubectl create -f templates/app-recreate.yaml --record
deployment "app-recreate" created

--recordこのdeploymentを開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。

  1. deploymentsの履歴を取得
$ kubectl rollout history deployment/app-recreate
deployments "app-recreate"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-recreate.yaml --record=true
  1. サービスを公開する
$ kubectl expose deployment/app-recreate --port=80 --target-port=8080 --name=app-recreate --type=LoadBalancer
service "app-recreate" exposed
  1. サービスの詳細を取得する
$ kubectl describe svc/app-recreate
Name:                     app-recreate
Namespace:                default
Labels:                   name=app-recreate
Annotations:              <none>
Selector:                 name=app-recreate
Type:                     LoadBalancer
IP:                       100.65.43.233
LoadBalancer Ingress:     af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30158/TCP
Endpoints:                100.96.1.14:80,100.96.2.13:80,100.96.3.13:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  CreatingLoadBalancer  24s   service-controller  Creating load balancer
  Normal  CreatedLoadBalancer   23s   service-controller  Created load balancer
  1. serviceにアクセス
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com
Hello World!
  1. 別の端末では、Podの状態を確認
$ kubectl get -w pods
app-v1-recreate-486400321-4rwzb   1/1       Running   0          9m
app-v1-recreate-486400321-fqh5l   1/1       Running   0          9m
app-v1-recreate-486400321-jm02h   1/1       Running   0          9m
app-v1-recreate-486400321-rl79n   1/1       Running   0          9m
app-v1-recreate-486400321-z89nm   1/1       Running   0          9m
  1. deploymentのイメージを更新します。
$ kubectl set image deployment/app-recreate app-recreate=arungupta/app-upgrade:v2
deployment "app-recreate" image updated
  1. Podのステータスが更新されます。すべてのPodが最初に終了し、新しいPodが作成されたことを示します。
$ kubectl get -w pods
NAME                              READY     STATUS    RESTARTS   AGE
app-v1-recreate-486400321-4rwzb   1/1       Running   0          9m
app-v1-recreate-486400321-fqh5l   1/1       Running   0          9m
app-v1-recreate-486400321-jm02h   1/1       Running   0          9m
app-v1-recreate-486400321-rl79n   1/1       Running   0          9m
app-v1-recreate-486400321-z89nm   1/1       Running   0          9m
app-v1-recreate-486400321-rl79n   1/1       Terminating   0         10m
app-v1-recreate-486400321-jm02h   1/1       Terminating   0         10m
app-v1-recreate-486400321-fqh5l   1/1       Terminating   0         10m
app-v1-recreate-486400321-z89nm   1/1       Terminating   0         10m
app-v1-recreate-486400321-4rwzb   1/1       Terminating   0         10m
app-v1-recreate-486400321-rl79n   0/1       Terminating   0         10m
app-v1-recreate-486400321-4rwzb   0/1       Terminating   0         10m
app-v1-recreate-486400321-fqh5l   0/1       Terminating   0         10m
app-v1-recreate-486400321-z89nm   0/1       Terminating   0         10m
app-v1-recreate-486400321-jm02h   0/1       Terminating   0         10m
app-v1-recreate-486400321-fqh5l   0/1       Terminating   0         10m
app-v1-recreate-486400321-fqh5l   0/1       Terminating   0         10m
app-v1-recreate-486400321-z89nm   0/1       Terminating   0         10m
app-v1-recreate-486400321-z89nm   0/1       Terminating   0         10m
app-v1-recreate-486400321-rl79n   0/1       Terminating   0         10m
app-v1-recreate-486400321-rl79n   0/1       Terminating   0         10m
app-v1-recreate-486400321-jm02h   0/1       Terminating   0         10m
app-v1-recreate-486400321-jm02h   0/1       Terminating   0         10m
app-v1-recreate-486400321-4rwzb   0/1       Terminating   0         10m
app-v1-recreate-486400321-4rwzb   0/1       Terminating   0         10m
app-v1-recreate-2362379170-fp3j2   0/1       Pending   0         0s
app-v1-recreate-2362379170-xxqqw   0/1       Pending   0         0s
app-v1-recreate-2362379170-hkpt7   0/1       Pending   0         0s
app-v1-recreate-2362379170-jzh5d   0/1       Pending   0         0s
app-v1-recreate-2362379170-k26sf   0/1       Pending   0         0s
app-v1-recreate-2362379170-xxqqw   0/1       Pending   0         0s
app-v1-recreate-2362379170-fp3j2   0/1       Pending   0         0s
app-v1-recreate-2362379170-hkpt7   0/1       Pending   0         0s
app-v1-recreate-2362379170-jzh5d   0/1       Pending   0         0s
app-v1-recreate-2362379170-k26sf   0/1       Pending   0         0s
app-v1-recreate-2362379170-xxqqw   0/1       ContainerCreating   0         0s
app-v1-recreate-2362379170-fp3j2   0/1       ContainerCreating   0         1s
app-v1-recreate-2362379170-hkpt7   0/1       ContainerCreating   0         1s
app-v1-recreate-2362379170-jzh5d   0/1       ContainerCreating   0         1s
app-v1-recreate-2362379170-k26sf   0/1       ContainerCreating   0         1s
app-v1-recreate-2362379170-fp3j2   1/1       Running   0         3s
app-v1-recreate-2362379170-k26sf   1/1       Running   0         3s
app-v1-recreate-2362379170-xxqqw   1/1       Running   0         3s
app-v1-recreate-2362379170-hkpt7   1/1       Running   0         4s
app-v1-recreate-2362379170-jzh5d   1/1       Running   0         4s

出力は、すべてのPodが最初に終了した後、新しいPodが作成されたことを示します。

  1. deploymentsの履歴を手に入れる
$ kubectl rollout history deployment/app-recreate
deployments "app-recreate"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-recreate.yaml --record=true
2         kubectl set image deployment/app-recreate app-recreate=arungupta/app-upgrade:v2
  1. 再度アプリケーションにアクセスする
$ curl http://af2dc1f99bda211e791f402037f18a54-1616925381.eu-central-1.elb.amazonaws.com
Howdy World!

出力にv2は、使用されているイメージのバージョンが表示されるようになりました。

Rolling update戦略

Podはローリングアップデートの方法で更新されます。 Rolling updateの実行方法を定義するには、次の2つのオプションのプロパティを使用できます。

  1. .spec.strategy.rollingUpdate.maxSurge 必要な数のポッドに作成できるポッドの最大数を指定します。値には、絶対数またはパーセンテージを使用できます。デフォルト値は25%です。
  2. .spec.strategy.rollingUpdate.maxUnavailable 更新処理中に使用できないポッドの最大数を指定します。

設定ファイルは以下のようになります

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-rolling
spec:
  replicas: 5
  selector:
    matchLabels:
      name: app-rolling
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: app-rolling
    spec:
      containers:
      - name: app-rolling
        image: arungupta/app-upgrade:v1
        ports:
        - containerPort: 8080

この場合、最大数のポッド上に1つ以上のポッドを作成することができ、更新プロセス中には1つのポッドしか利用できなくなります。

  1. deploymentを作成
$ kubectl create -f templates/app-rolling.yaml --record
deployment "app-rolling" created

再度、--recordこの展開を開始するコマンドが確実に記録されます。 これは、アプリケーションがいくつかの更新を経て、バージョンとコマンドを関連付ける必要がある場合に便利です。

  1. デプロイの履歴を取得する
$ kubectl rollout history deployment/app-rolling
deployments "app-rolling"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-rolling.yaml --record=true
  1. サービスを公開する
$ kubectl expose deployment/app-rolling --port=80 --target-port=8080 --name=app-rolling --type=LoadBalancer
service "app-rolling" exposed
  1. サービスの詳細を取得する
$ kubectl describe svc/app-rolling
Name:                     app-rolling
Namespace:                default
Labels:                   name=app-rolling
Annotations:              <none>
Selector:                 name=app-rolling
Type:                     LoadBalancer
IP:                       100.71.164.130
LoadBalancer Ingress:     abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31521/TCP
Endpoints:                100.96.1.16:80,100.96.2.15:80,100.96.3.15:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  CreatingLoadBalancer  1m    service-controller  Creating load balancer
  Normal  CreatedLoadBalancer   1m    service-controller  Created load balancer
  1. サービスへアクセス
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com
Hello World!

出力はv1、イメージのバージョンが使用されていることを示します。

  1. 別の端末では、Podの状態を確認します。
$ kubectl get -w pods
NAME                           READY     STATUS    RESTARTS   AGE
app-rolling-1683885671-d7vpf   1/1       Running   0          2m
app-rolling-1683885671-dt31h   1/1       Running   0          2m
app-rolling-1683885671-k8xn9   1/1       Running   0          2m
app-rolling-1683885671-sdjk3   1/1       Running   0          2m
app-rolling-1683885671-x1npp   1/1       Running   0          2m
  1. deploymentのイメージを更新します。
$ kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2
deployment "app-rolling" image updated
  1. Podのステータスが更新されます。
$ kubectl get -w pods
NAME                           READY     STATUS    RESTARTS   AGE
app-rolling-1683885671-d7vpf   1/1       Running   0          2m
app-rolling-1683885671-dt31h   1/1       Running   0          2m
app-rolling-1683885671-k8xn9   1/1       Running   0          2m
app-rolling-1683885671-sdjk3   1/1       Running   0          2m
app-rolling-1683885671-x1npp   1/1       Running   0          2m
app-rolling-4154020364-ddn16   0/1       Pending   0         0s
app-rolling-4154020364-ddn16   0/1       Pending   0         1s
app-rolling-4154020364-ddn16   0/1       ContainerCreating   0         1s
app-rolling-1683885671-sdjk3   1/1       Terminating   0         5m
app-rolling-4154020364-j0nnk   0/1       Pending   0         1s
app-rolling-4154020364-j0nnk   0/1       Pending   0         1s
app-rolling-4154020364-j0nnk   0/1       ContainerCreating   0         1s
app-rolling-1683885671-sdjk3   0/1       Terminating   0         5m
app-rolling-4154020364-ddn16   1/1       Running   0         2s
app-rolling-1683885671-dt31h   1/1       Terminating   0         5m
app-rolling-4154020364-j0nnk   1/1       Running   0         3s
app-rolling-4154020364-wlvfz   0/1       Pending   0         1s
app-rolling-4154020364-wlvfz   0/1       Pending   0         1s
app-rolling-1683885671-x1npp   1/1       Terminating   0         5m
app-rolling-4154020364-wlvfz   0/1       ContainerCreating   0         1s
app-rolling-4154020364-qr1lz   0/1       Pending   0         1s
app-rolling-4154020364-qr1lz   0/1       Pending   0         1s
app-rolling-1683885671-dt31h   0/1       Terminating   0         5m
app-rolling-4154020364-qr1lz   0/1       ContainerCreating   0         1s
app-rolling-1683885671-x1npp   0/1       Terminating   0         5m
app-rolling-4154020364-wlvfz   1/1       Running   0         2s
app-rolling-1683885671-d7vpf   1/1       Terminating   0         5m
app-rolling-4154020364-vlb4b   0/1       Pending   0         2s
app-rolling-4154020364-vlb4b   0/1       Pending   0         2s
app-rolling-4154020364-vlb4b   0/1       ContainerCreating   0         2s
app-rolling-1683885671-d7vpf   0/1       Terminating   0         5m
app-rolling-1683885671-x1npp   0/1       Terminating   0         5m
app-rolling-1683885671-x1npp   0/1       Terminating   0         5m
app-rolling-4154020364-qr1lz   1/1       Running   0         3s
app-rolling-1683885671-k8xn9   1/1       Terminating   0         5m
app-rolling-1683885671-k8xn9   0/1       Terminating   0         5m
app-rolling-4154020364-vlb4b   1/1       Running   0         2s

出力は、新しいPodが作成された後、古いPodが作成された後、新しいPodが作成されたことを示します。

  1. デプロイの履歴を取得する
$ kubectl rollout history deployment/app-rolling
deployments "app-rolling"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-rolling.yaml --record=true
2         kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2
  1. アプリケーションに再度アクセスする
$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com
Howdy World!

出力にv2は、使用されているイメージのバージョンが表示されるようになりました。

以前のリビジョンへのロールバック

上記で説明したように、Deploymentをどのように展開したかの詳細は、 kubectl rollout history コマンドを使用して取得できます。 ロールバックするには、Deploymentの完全な履歴を取得できます。

$ kubectl rollout history deployment/app-rolling
deployments "app-rolling"
REVISION  CHANGE-CAUSE
1         kubectl create --filename=templates/app-rolling.yaml --record=true
2         kubectl set image deployment/app-rolling app-rolling=arungupta/app-upgrade:v2

次のコマンドを使用して以前のバージョンにロールバックします。

$ kubectl rollout undo deployment/app-rolling --to-revision=1
deployment "app-rolling" rolled back

サービスに再度アクセスしてください

$ curl http://abe27b4c7bdaa11e791f402037f18a54-647142678.eu-central-1.elb.amazonaws.com
Hello World!

出力はv1、イメージのバージョンが現在使用されていることを示します。

リソースの削除

kubectl delete deployment/app-recreate svc/app-recreate deployment/app-rolling svc/app-rolling

Canary deployment

Canaryデプロイメントを使用すると、少数のユーザーに変更を徐々に反映させることで、すべてのユーザーに展開する前に、新しいバージョンのアプリケーションを本番環境に展開することができます。 Kubernetesでこれを達成するにはいくつかの方法があります。

  1. Service、DeploymentおよびLabelの使用
  2. 入力コントローラの使用
  3. DNSコントローラの使用
  4. IstioまたはLinkerdの使用

今回はService、DeploymentおよびLabelの方法を見ていきます

Deployment, ServiceとLabels

異なるバージョンのイメージを使用した2つのデプロイメントが使用されます。 どちらの配置も同じポッドラベルを持ちますが、少なくとも1つのラベルが異なります。 一般的なポッドラベルは、サービスのセレクタとして表示されます。 レプリカの数を調整するために、異なるポッドラベルが使用されます。 新しいバージョンのDeploymentの1つのレプリカが古いバージョンとともにリリースされます。 しばらくの間エラーが検出されない場合、新しいバージョンのレプリカの数がスケールアップされ、古いバージョンのレプリカの数が縮小されます。 最終的に、古いバージョンは削除されます。

Deploymentとサービス定義

v1展開のバージョンを見てみましょう

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v1
spec:
  replicas: 2
  selector:
    matchLabels:
      name: app
      version: v1
  template:
    metadata:
      labels:
        name: app
        version: v1
    spec:
      containers:
      - name: app
        image: arungupta/app-upgrade:v1
        ports:
        - containerPort: 8080

それは arungupta/app-upgrade:v1 イメージを使用します。 それは2つのラベル name: appversion: v1 v2展開のバージョンを見てみましょう

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v2
spec:
  replicas: 2
  selector:
    matchLabels:
      name: app
      version: v2
  template:
    metadata:
      labels:
        name: app
        version: v2
    spec:
      containers:
      - name: app
        image: arungupta/app-upgrade:v2
        ports:
        - containerPort: 8080

それは別のイメージ arungupta/app-upgrade:v2 を使用します。 これには、Deploymentのバージョン v1 と一致する1つのラベル name: app があります。 これは、他のラベル v2 と似ていますが、異なる値 version: v2 を使用しています。 このラベルを使用するv1と、Deploymentの v1 バージョンをオーバーライドすることなく、このDeploymentを独自に拡張できます。

最後に、これらのデプロイメントを使用するサービス定義を見てみましょう。

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    name: app
  ports:
  - name: app
    port: 80
  type: LoadBalancer

サービスは、アプリケーションの両方のバージョンに共通のラベルを使用します。これにより、両方のデプロイメントのポッドをサービスの一部にすることができます。

確認しましょう。

Canary Deploymentを作成

  1. Deploymentのv1バージョンをデプロイする
$ kubectl apply -f templates/app-v1.yaml
deployment "app-v1" created
  1. Deploymentのv2バージョンをデプロイする
$ kubectl apply -f templates/app-v2.yaml
deployment "app-v2" created

3. サービスをデプロイする

$ kubectl apply -f templates/app-service.yaml
service "app-service" created
  1. このサービスのPod listを確認してください
$ kubectl get pods -l name=app
NAME                      READY     STATUS    RESTARTS   AGE
app-v1-3101668686-4mhcj   1/1       Running   0          2m
app-v1-3101668686-ncbfv   1/1       Running   0          2m
app-v2-2627414310-89j1v   1/1       Running   0          2m
app-v2-2627414310-bgg1t   1/1       Running   0          2m

templates/app-service.yamlのサービス定義で指定されているポッドのみを選択するように、クエリーのname=appラベルを明示的に指定していることに注意してください。 v1バージョンからは2つのポッド、 v2バージョンからは2つのポッドがあります。 このサービスにアクセスすると、v1バージョンから50%、2vバージョンから50%の応答が得られます。

Canary Deploymentをスケール

v1バージョンとv2バージョンから含まれるポッドの数は、2つのデプロイメントを使用して個別に拡張できます。

  1. v2 deployment のレプリカ数を増やす
$ kubectl scale deploy/app-v2 --replicas=4
deployment "app-v2" scaled
  1. サービスの一部であるポッドを確認してください
$ kubectl get pods -l name=app
NAME                      READY     STATUS    RESTARTS   AGE
app-v1-3101668686-4mhcj   1/1       Running   0          6m
app-v1-3101668686-ncbfv   1/1       Running   0          6m
app-v2-2627414310-89j1v   1/1       Running   0          6m
app-v2-2627414310-8jpzd   1/1       Running   0          7s
app-v2-2627414310-b17v8   1/1       Running   0          7s
app-v2-2627414310-bgg1t   1/1       Running   0          6m

現在、4つのポッドはアプリケーションのバージョンv2から来ており、2つのポッドはアプリケーションのバージョンv1から来ていることがわかります。 したがって、ユーザーからのトラフィックの3分の2が新しいアプリケーションから提供されるようになります。

  1. v1バージョンのレプリカ数を0に減らす
$ kubectl scale deploy/app-v1 --replicas=0
deployment "app-v1" scaled
  1. サービスの一部であるPodを確認してください
$ kubectl get pods -l name=app
NAME                      READY     STATUS    RESTARTS   AGE
app-v2-2627414310-89j1v   1/1       Running   0          8m
app-v2-2627414310-8jpzd   1/1       Running   0          1m
app-v2-2627414310-b17v8   1/1       Running   0          1m
app-v2-2627414310-bgg1t   1/1       Running   0          8m

現在、すべてのポッドがDeploymentのv2バージョンを提供しています。

Canary Deploymentを削除する

上記で作成したすべてのリソースを削除するには、このコマンドを実行します。

$ kubectl delete svc/app-service deployment/app-v1 deployment/app-v2

Ingress Controller (まだ未実装)

デプロイメントとサービスを使用してトラフィックの適切なパーセンテージを達成するには、必要な数のポッドをスピンアップする必要があります。 たとえば、バージョンにv1ポッドのレプリカが4つある場合などです。 次に、バージョンに5%のトラフィックを向けるためにv2、1ポッドのv2バージョンのレプリカには16個のv1バージョンのレプリカがさらに必要になります。 これはリソースの最適な使用ではありません。 この問題を解決するには、Kubernetes Ingressによる重み付けトラフィックの切り替えが使用できます。

Zalandoによると Kubernetes Ingress Controller for AWSKubernetesIngressコントローラ

$ kubectl apply -f templates/ingress-controller.yaml
deployment "app-ingress-controller" created

Service Discovery for Microservices with Kubernetes

302-app-discovery

Service Discovery for Microservices with Kubernetes

ハードコードされたIPアドレスを使用するのではなく、 アプリケーション内のさまざまなマイクロサービスがサービス検出を使用してインフラストラクチャ内で互いにどのように位置付けられるかの例を示す。

前提条件

3つのマスターノードと5つのワーカーノードを持つクラスタを使用

アプリケーションアーキテクチャ

サンプルアプリケーションでは、次の3つのサービスを使用

  1. webapp :Webアプリケーションのマイクロサービスは greetername のマイクロサービスを使用して人のために挨拶を生成します。
  2. greeter :マイクロサービスは greet 、URLの名前/値のキーペアに基づいて挨拶を返します。
  3. nameid URLの名前/値のキーペアに基づいて人の名前を返すマイクロサービス。

これらのサービスは、Dockerイメージとして構築され、Kubernetesに配備されています。すべてのサービスはNode.jsアプリケーションとしてビルドされています。 サービスのソースコードhttps://github.com/arun-gupta/container-service-discovery/tree/master/services にあります。

これらの webapp サービスは namegreeter サービスと通信するに、以下の環境変数でサービスを構成する必要があります。 NAME_SERVICE_HOSTGREETER_SERVICE_HOST環境変数は、そのラベルではなく、ポッドまたはホストのIPアドレスなどの静的参照することによって、これらのサービスを参照してください。 その利点は 存在している name および/または greeter ポッドがもはや操作可能でなくなった場合、それが依存するサービスを継続して実行するために十分なリソースがクラスタにある場合、 webapp サービスは機能し続けます。

  1. NAME_SERVICE_HOST
  2. NAME_SERVICE_PORT
  3. NAME_SERVICE_PATH
  4. GREETER_SERVICE_HOST
  5. GREETER_SERVICE_PORT
  6. GREETER_SERVICE_PATH

3つの異なるサービスを持つ設定ファイルは、app.yml で定義されています。 webappサービスのレプリカセットには、次の環境変数があります。

spec:
  containers:
  - name: webapp-pod
    image: arungupta/webapp-service:latest
    env:
    - name: NAME_SERVICE_HOST
      value: name-service
    - name: NAME_SERVICE_PORT
      value: "8080"
    - name: NAME_SERVICE_PATH
      value: /
    - name: GREETER_SERVICE_HOST
      value: greeter-service
    - name: GREETER_SERVICE_PORT
      value: "8080"
    - name: GREETER_SERVICE_PATH
      value: /

環境変数は、アプリケーション構成で定義されているように、nameおよびgreeterサービスを指しています。 webapp サービス用のイングレスロードバランサは、次のフラグメントを使用して作成されます。

spec:
  selector:
    app: webapp-pod
  ports:
    - name: web
      port: 80
  type: LoadBalancer

全体として、サービスは次のように互いに通信します。

[Ingress LB (ELB)] → [WEBAPP] → /name-service → Name ↓ → /greeter-service → Greeter

アプリケーションのデプロイ

  1. アプリケーションをデプロイする

    $ kubectl create -f templates/app.yml service "name-service" created replicaset.extensions "name-rs" created service "greeter-service" created replicaset.extensions "greeter-rs" created service "webapp-service" created replicaset.extensions "webapp-rs" created

  2. サービスのリストを取得

$ kubectl get svc
NAME              CLUSTER-IP       EXTERNAL-IP        PORT(S)        AGE
greeter-service   100.64.44.23     <none>             8080/TCP       13s
kubernetes        100.64.0.1       <none>             443/TCP        23m
name-service      100.66.113.58    <none>             8080/TCP       13s
webapp-service    100.71.126.195   a5427e1288472...   80:31234/TCP   12s
  1. サービスの詳細情報を取得
$ kubectl describe svc/webapp-service
Name:           webapp-service
Namespace:      default
Labels:         <none>
Annotations:        <none>
Selector:       app=webapp-pod
Type:           LoadBalancer
IP:         100.71.126.195
LoadBalancer Ingress:   a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com
Port:           web 80/TCP
NodePort:       web 31234/TCP
Endpoints:      100.96.2.12:80
Session Affinity:   None
Events:
  FirstSeen LastSeen    Count   From            SubObjectPath   Type        Reason          Message
  --------- --------    -----   ----            -------------   --------    ------          -------
  30s       30s     1   service-controller          Normal      CreatingLoadBalancer    Creating load balancer
  29s       29s     1   service-controller          Normal      CreatedLoadBalancer Created load balancer

ロードバランサーがリクエストを受け入れるまで3分ほど待つ

アプリケーションへアクセス

ブラウザやcurlでアプリケーションにアクセスする

http://<host>
http://<host>?greet=ho
http://<host>?id=1
http://<host>?greet=ho&id=1

<host> はロードバランサのアドレスの入力値

$ kubectl get svc/webapp-service -o jsonpath={.status.loadBalancer.ingress[0].hostname}
a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com

アプリケーション削除

$ kubectl delete -f templates/app.yml

k8sクラスタのアップグレード

203-cluster-upgrades

Kubernetesクラスタのアップグレード

AWS上のKubernetesクラスタのアップグレードは、kopsで簡単にできます。 今回Kubernetesクラスターを2つの方法でアップグレードする方法を試します。

インプレースアップグレード

Kopsを使用すると、インプレースを使用してクラスタをアップグレードすることは簡単です。 バージョン1.6.10のKubernetesクラスタをセットアップし、kopsを使用して1.7.2への自動ローリングアップグレードを実行します。

クラスタを作成

次のようにKubernetes 1.6.10バージョンクラスタを作成します。

kops create cluster \
  --name example.cluster.k8s.local \
  --master-count 3 \
  --node-count 5 \
  --zones $AWS_AVAILABILITY_ZONES \
  --kubernetes-version=1.6.10 \
  --yes

マルチAZ配備のクラスタにより、クラスタのアップグレード中にポッドやサービスがダウンタイムを起こさないことが保証されます。

クラスタを検証

$ kops validate cluster --name example.cluster.k8s.local
Validating cluster example.cluster.k8s.local

INSTANCE GROUPS
NAME      ROLE  MACHINETYPE MIN MAX SUBNETS
master-eu-central-1a  Master  m3.medium 1 1 eu-central-1a
master-eu-central-1b  Master  m3.medium 1 1 eu-central-1b
master-eu-central-1c  Master  c4.large  1 1 eu-central-1c
nodes     Node  t2.medium 5 5 eu-central-1a,eu-central-1b,eu-central-1c

NODE STATUS
NAME            ROLE  READY
ip-172-20-112-170.eu-central-1.compute.internal master  True
ip-172-20-117-204.eu-central-1.compute.internal node  True
ip-172-20-54-176.eu-central-1.compute.internal  master  True
ip-172-20-55-115.eu-central-1.compute.internal  node  True
ip-172-20-63-241.eu-central-1.compute.internal  node  True
ip-172-20-71-25.eu-central-1.compute.internal master  True
ip-172-20-91-30.eu-central-1.compute.internal node  True
ip-172-20-93-220.eu-central-1.compute.internal  node  True

Your cluster example.cluster.k8s.local is ready

クラスタ内の異なるノードのバージョンを確認します。

$ kubectl get nodes
NAME                                              STATUS    ROLES     AGE       VERSION
ip-172-20-112-170.eu-central-1.compute.internal   Ready     master    7m        v1.6.10
ip-172-20-117-204.eu-central-1.compute.internal   Ready     node      6m        v1.6.10
ip-172-20-54-176.eu-central-1.compute.internal    Ready     master    7m        v1.6.10
ip-172-20-55-115.eu-central-1.compute.internal    Ready     node      6m        v1.6.10
ip-172-20-63-241.eu-central-1.compute.internal    Ready     node      6m        v1.6.10
ip-172-20-71-25.eu-central-1.compute.internal     Ready     master    7m        v1.6.10
ip-172-20-91-30.eu-central-1.compute.internal     Ready     node      6m        v1.6.10
ip-172-20-93-220.eu-central-1.compute.internal    Ready     node      6m        v1.6.10

クラスタ内の各ノードがバージョン1.6.10であることを示しています。

クラスタ構成の編集

1.6.10の既存のクラスタを1.7.4にアップグレードしましょう。クラスタ構成を編集します。

kops edit cluster example.cluster.k8s.local

これにより、クラスタ構成がテキストエディタで開きます。 kubernetesVersion ターゲットバージョン(この場合は1.7.4)にキーを設定し、設定ファイルを保存します。

以前の値:

kubernetesVersion: 1.6.10

以下に変更されます:

kubernetesVersion: 1.7.4

変更を保存してエディタを終了します。Kubernetesクラスタは設定を再読み込みする必要があります。 これは、次のコマンドを使用して、クラスタのローリング・アップデートを強制することで実行できます。

このプロセスには30〜45分かかることがあります。その時間中に更新なしでクラスタを離れることをお勧めします。

$ kops update cluster example.cluster.k8s.local
I1028 18:18:59.671912   10844 apply_cluster.go:420] Gossip DNS: skipping DNS validation
I1028 18:18:59.699729   10844 executor.go:91] Tasks: 0 done / 81 total; 36 can run
I1028 18:19:00.824806   10844 executor.go:91] Tasks: 36 done / 81 total; 15 can run
I1028 18:19:01.601875   10844 executor.go:91] Tasks: 51 done / 81 total; 22 can run
I1028 18:19:03.340103   10844 executor.go:91] Tasks: 73 done / 81 total; 5 can run
I1028 18:19:04.153174   10844 executor.go:91] Tasks: 78 done / 81 total; 3 can run
I1028 18:19:04.575327   10844 executor.go:91] Tasks: 81 done / 81 total; 0 can run
Will modify resources:
  LaunchConfiguration/master-eu-central-1a.masters.cluster.k8s.local
    UserData
                          ...
                            cat > kube_env.yaml << __EOF_KUBE_ENV
                            Assets:
                          + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet
                          - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet
                          + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl
                          - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl
                            - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
                            - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz
                          ...


  LaunchConfiguration/master-eu-central-1b.masters.cluster.k8s.local
    UserData
                          ...
                            cat > kube_env.yaml << __EOF_KUBE_ENV
                            Assets:
                          + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet
                          - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet
                          + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl
                          - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl
                            - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
                            - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz
                          ...


  LaunchConfiguration/master-eu-central-1c.masters.cluster.k8s.local
    UserData
                          ...
                            cat > kube_env.yaml << __EOF_KUBE_ENV
                            Assets:
                          + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet
                          - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet
                          + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl
                          - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl
                            - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
                            - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz
                          ...


  LaunchConfiguration/nodes.cluster.k8s.local
    UserData
                          ...
                            cat > kube_env.yaml << __EOF_KUBE_ENV
                            Assets:
                          + - 7bf3fda43bb8d0a55622ca68dcbfaf3cc7f2dddc@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubelet
                          - - a9258e4d2c7d7ed48a7bf2e3c77a798fa51a6787@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubelet
                          + - 819010a7a028b165f5e6df37b1bb7713ff6d070f@https://storage.googleapis.com/kubernetes-release/release/v1.7.4/bin/linux/amd64/kubectl
                          - - 0afe23fb48276ad8c6385430962cd237367b22f7@https://storage.googleapis.com/kubernetes-release/release/v1.6.10/bin/linux/amd64/kubectl
                            - 1d9788b0f5420e1a219aad2cb8681823fc515e7c@https://storage.googleapis.com/kubernetes-release/network-plugins/cni-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
                            - c18ca557507c662e3a072c3475da9bd1bc8a503b@https://kubeupv2.s3.amazonaws.com/kops/1.7.1/linux/amd64/utils.tar.gz
                          ...


  LoadBalancer/api.cluster.k8s.local
    Lifecycle              <nil> -> Sync

  LoadBalancerAttachment/api-master-eu-central-1a
    Lifecycle              <nil> -> Sync

  LoadBalancerAttachment/api-master-eu-central-1b
    Lifecycle              <nil> -> Sync

  LoadBalancerAttachment/api-master-eu-central-1c
    Lifecycle              <nil> -> Sync

Must specify --yes to apply changes

次のコマンドを使用して変更を適用します。

kops update cluster example.cluster.k8s.local --yes

出力します

$ kops update cluster example.cluster.k8s.local --yes
I1028 18:22:53.558475   10876 apply_cluster.go:420] Gossip DNS: skipping DNS validation
I1028 18:22:54.487232   10876 executor.go:91] Tasks: 0 done / 81 total; 36 can run
I1028 18:22:55.750674   10876 executor.go:91] Tasks: 36 done / 81 total; 15 can run
I1028 18:22:56.640322   10876 executor.go:91] Tasks: 51 done / 81 total; 22 can run
I1028 18:22:59.756888   10876 executor.go:91] Tasks: 73 done / 81 total; 5 can run
I1028 18:23:01.154703   10876 executor.go:91] Tasks: 78 done / 81 total; 3 can run
I1028 18:23:01.890273   10876 executor.go:91] Tasks: 81 done / 81 total; 0 can run
I1028 18:23:02.196422   10876 update_cluster.go:247] Exporting kubecfg for cluster
kops has set your kubectl context to example.cluster.k8s.local

Cluster changes have been applied to the cloud.

Changes may require instances to restart: kops rolling-update cluster

クラスタのアップグレード

次のコマンドを使用して、いずれかのノードで再起動が必要かどうかを判断します。

kops rolling-update cluster example.cluster.k8s.local

このコマンドは、次のように出力します。

NAME                  STATUS      NEEDUPDATE  READY MIN MAX NODES
master-eu-central-1a  NeedsUpdate 1           0     1   1   1
master-eu-central-1b  NeedsUpdate 1           0     1   1   1
master-eu-central-1c  NeedsUpdate 1           0     1   1   1
nodes                 NeedsUpdate 5           0     5   5   5

Must specify --yes to rolling-update.

このSTATUS列には、マスターノードとワーカーノードの両方を更新する必要があることが示されています。 次のコマンドを使用してローリングアップデートを実行します。

kops rolling-update cluster example.cluster.k8s.local --yeskops rolling-update cluster example.cluster.k8s.loc

このコマンドの出力が表示されます。

NAME                  STATUS      NEEDUPDATE  READY MIN MAX NODES
master-eu-central-1a  NeedsUpdate 1           0     1   1   1
master-eu-central-1b  NeedsUpdate 1           0     1   1   1
master-eu-central-1c  NeedsUpdate 1           0     1   1   1
nodes                 NeedsUpdate 5           0     5   5   5
I1028 18:26:37.124152   10908 instancegroups.go:350] Stopping instance "i-0c729296553079aab", node "ip-172-20-54-176.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1a.masters.cluster.k8s.local".
I1028 18:31:37.439446   10908 instancegroups.go:350] Stopping instance "i-002976b15a2968b34", node "ip-172-20-71-25.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1b.masters.cluster.k8s.local".
I1028 18:36:38.700513   10908 instancegroups.go:350] Stopping instance "i-0d4bd1a9668fab3e1", node "ip-172-20-112-170.eu-central-1.compute.internal", in AWS ASG "master-eu-central-1c.masters.cluster.k8s.local".
I1028 18:41:39.938149   10908 instancegroups.go:350] Stopping instance "i-0048aa89472a2c225", node "ip-172-20-93-220.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local".
I1028 18:43:41.019527   10908 instancegroups.go:350] Stopping instance "i-03787fa7fa77b9348", node "ip-172-20-117-204.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local".
I1028 19:14:50.288739   10908 instancegroups.go:350] Stopping instance "i-084c653bad3b17071", node "ip-172-20-55-115.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local".
I1028 19:16:51.339991   10908 instancegroups.go:350] Stopping instance "i-08da4ee3253afa479", node "ip-172-20-63-241.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local".
I1028 19:18:52.368412   10908 instancegroups.go:350] Stopping instance "i-0a7975621a65a1997", node "ip-172-20-91-30.eu-central-1.compute.internal", in AWS ASG "nodes.cluster.k8s.local".
I1028 19:20:53.743998   10908 rollingupdate.go:174] Rolling update completed!

クラスタを再度検証します。

$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local

Validating cluster example.cluster.k8s.local

INSTANCE GROUPS
NAME      ROLE  MACHINETYPE MIN MAX SUBNETS
master-eu-central-1a  Master  m3.medium 1 1 eu-central-1a
master-eu-central-1b  Master  m3.medium 1 1 eu-central-1b
master-eu-central-1c  Master  c4.large  1 1 eu-central-1c
nodes     Node  t2.medium 5 5 eu-central-1a,eu-central-1b,eu-central-1c

NODE STATUS
NAME            ROLE  READY
ip-172-20-101-20.eu-central-1.compute.internal  master  True
ip-172-20-106-93.eu-central-1.compute.internal  node  True
ip-172-20-109-10.eu-central-1.compute.internal  node  True
ip-172-20-41-77.eu-central-1.compute.internal node  True
ip-172-20-44-33.eu-central-1.compute.internal master  True
ip-172-20-75-132.eu-central-1.compute.internal  node  True
ip-172-20-85-128.eu-central-1.compute.internal  master  True
ip-172-20-93-108.eu-central-1.compute.internal  node  True

Your cluster example.cluster.k8s.local is ready

クラスタからノードのリストを取得

$ kubectl get nodes
NAME                                             STATUS    ROLES     AGE       VERSION
ip-172-20-101-20.eu-central-1.compute.internal   Ready     master    42m       v1.7.4
ip-172-20-106-93.eu-central-1.compute.internal   Ready     node      36m       v1.7.4
ip-172-20-109-10.eu-central-1.compute.internal   Ready     node      37m       v1.7.4
ip-172-20-41-77.eu-central-1.compute.internal    Ready     node      3m        v1.7.4
ip-172-20-44-33.eu-central-1.compute.internal    Ready     master    51m       v1.7.4
ip-172-20-75-132.eu-central-1.compute.internal   Ready     node      5m        v1.7.4
ip-172-20-85-128.eu-central-1.compute.internal   Ready     master    46m       v1.7.4
ip-172-20-93-108.eu-central-1.compute.internal   Ready     node      44s       v1.7.4

Blue/green Upgrade

Blue/green メソッドを使用してクラスターをアップグレードすることは、本質的にはより控えめであると考えられ、アプリケーションの高可用性を考慮します。 2つのk8sクラスタを設定します.1つは1.6.10バージョン、もう1つは1.7.2で、ポッドの展開とサービスは新しいクラスタに移行します。