Kubernetesについての勉強のため、以下のとてもよくできたチュートリアルを実施したログ。
このチュートリアルではGCP上にKubernetesのクラスターをスクラッチ構築する。スクラッチインストールに関する公式ドキュメントは以下。
概要
作成するクラスターの特徴
- 3 Master、3 Workerノード構成
- OSはUbuntu Server 18.04
- 各k8sコンポーネントは公式のバイナリを使用し、Systemdサービスとして稼働させる
- API ServerはTLSで公開し、各k8sコンポーネントはそれぞれ毎にクライアント証明書を用意する
バージョン
やった時点でドキュメントに記載されていた各コンポーネントのバージョンは以下。
- Kubernetes 1.12.0
- containerd Container Runtime 1.2.0-rc.0
- gVisor 50c283b9f56bb7200938d9e207355f05f79f0d17
- CNI Container Networking 0.6.0
- etcd v3.3.9
- CoreDNS v1.2.2
全体の流れ
作業は14のLabに分かれており各Labではそれぞれ以下のことをする。
-
Prerequisites
- gcloudコマンドをセットアップする
-
Installing the Client Tools
- 作業用のPCに
kubectl
とcfssl
をインストールする
- 作業用のPCに
-
Provisioning Compute Resources
- GCP上にネットワークとインスタンスを作成する
-
Provisioning the CA and Generating TLS Certificates
- ルートCAを作成し、各k8sコンポーネント用の鍵と証明書を作成する
-
Generating Kubernetes Configuration Files for Authentication
- 各k8sコンポーネントが使用する
kubeconfig
を作成する
- 各k8sコンポーネントが使用する
-
Generating the Data Encryption Config and Key
- Secretを暗号化してからetcdに保存するための鍵と設定ファイルを作成する
-
Bootstrapping the etcd Cluster
- etcdクラスターを起動する
-
Bootstrapping the Kubernetes Control Plane
- Masterノードのk8sコンポーネント(
apiserver
、scheduler
、controller-manager
)を起動する
- Masterノードのk8sコンポーネント(
-
Bootstrapping the Kubernetes Worker Nodes
- Workerノードのk8sコンポーネント(
kubelet
、kube-proxy
)を起動する
- Workerノードのk8sコンポーネント(
-
Configuring kubectl for Remote Access
- 作業用PCから
kubectl
が実行できるようにする
- 作業用PCから
-
Provisioning Pod Network Routes
- GCPのルーティングルールを作成し、ノードをまたいだPod間の通信ができるようにする
-
Deploying the DNS Cluster Add-on
- CoreDNSをデプロイする
-
Smoke Test
- クラスターが機能しているかテストする
-
Cleaning Up
- 作成したGCP上のリソースを削除する
Prerequisites
このLabではgcloudコマンドをセットアップする。
Google Cloud Platform
GCPのアカウントがなければサインアップする。アカウントはあったので特に何もせず。
このチュートリアルにかかるコストは0.22ドル/1時間(5.39ドル/1日)。アカウントを新規作成した場合は300ドル分のトライアルでチュートリアルを実施できるはず。
Google Cloud Platform SDK
Install the Google Cloud SDK
Google Cloud SDKを導入する
brew cask install google-cloud-sdk
.bashrc
に以下を追加し、PATH
を通して補完を有効にする。
source '/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.bash.inc'
source '/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.bash.inc'
バージョンを確認する。
sotoiwa@Soto-no-MacBook-Air:~
$ gcloud version
Google Cloud SDK 221.0.0
bq 2.0.35
core 2018.10.12
gsutil 4.34
sotoiwa@Soto-no-MacBook-Air:~
$
Set a Default Compute Region and Zone
CLIを初期化し、デフォルトの地域とゾーンを設定する。
gcloud init
sotoiwa@Soto-no-MacBook-Air:~
$ gcloud config set compute/zone asia-northeast1-a
Updated property [compute/zone].
sotoiwa@Soto-no-MacBook-Air:~
$
sotoiwa@soto-no-air:~
$ gcloud config list
[compute]
region = asia-northeast1
zone = asia-northeast1-a
[core]
account = hogehoge@hogehoge.com
disable_usage_reporting = True
project = hogehoge
Your active configuration is: [default]
sotoiwa@soto-no-air:~
$
Running Commands in Parallel with tmux
tmux
を使うと同じコマンドを複数のウインドウに入力できるので便利らしい。tmux
はほとんど使ったことがないので以下のリンクを読む。
結局使わなかったが、同じコマンドを複数のペインに入力するために、最低限tmux
を使うには以下のようにする。
brew install tmux
- マウススクロールができるように以下を設定する
set-option -g mouse on
-
tmux
でウインドウを立ち上げる -
Ctrl+b
→"
でペインを上下に分割する - もう一度
Ctrl+b
→"
でペインをさらに上下に分割する - マウスでペインの境界をドラッグしてペインのサイズをいい感じにする
- 各ペインで各サーバーにログインする
-
Ctrl+b
→;
でsynchronize-panes
を有効化する - 戻すときは
Ctrl+b
→:
でコマンドモードに入り、set synchronize-panes off
と入力
Installing the Client Tools
このLabでは作業用のPCにkubectl
とcfssl
をインストールする。
Install CFSSL
cfssl
をインストールする。
OS X
brew install cfssl
Verification
バージョン1.2.0以上であることを確認。
sotoiwa@Soto-no-MacBook-Air:~
$ cfssl version
Version: 1.3.2
Revision: dev
Runtime: go1.10.2
sotoiwa@Soto-no-MacBook-Air:~
$
Install kubectl
kubectl
をインストールする。
OS X
brew
で入れたものが入ってたのでそのまま使う。
Verification
バージョン1.12.0以上であることを確認する。
sotoiwa@Soto-no-MacBook-Air:~
$ kubectl version --client
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-30T21:39:38Z", GoVersion:"go1.11.1", Compiler:"gc", Platform:"darwin/amd64"}
sotoiwa@soto-no-air:~
$
Provisioning Compute Resources
このLabではGCP上にネットワークとインスタンスを作成する。
Networking
最終的に以下のようなネットワークとアドレスを使用することになる。
ネットワーク/アドレス | 名前 | 説明 | 設定方法 |
---|---|---|---|
10.240.0.0/24 | 今回のVMインスタンスが配置されるサブネット | gcloudコマンド | |
10.240.0.10 | controller-0 | Masterノード#0のIP | gcloudコマンド |
10.240.0.11 | controller-1 | Masterノード#1のIP | gcloudコマンド |
10.240.0.12 | controller-2 | Masterノード#2のIP | gcloudコマンド |
10.240.0.20 | worker-0 | Wokerノード#0のIP | gcloudコマンド |
10.240.0.21 | worker-1 | Wokerノード#1のIP | gcloudコマンド |
10.240.0.22 | worker-2 | Wokerノード#2のIP | gcloudコマンド |
35.243.101.236 | apiserverの外部公開用アドレス | gcloudコマンド | |
10.200.0.0/16 | クラスター全体のCIDR | controller-managerの--cluster-cidr で指定 |
|
10.200.0.0/24 | worker-0のPodのサブネット | CNIのブリッジネットワーク設定ファイル | |
10.200.1.0/24 | worker-1のPodのサブネット | CNIのブリッジネットワーク設定ファイル | |
10.200.2.0/24 | worker-2のPodのサブネット | CNIのブリッジネットワーク設定ファイル | |
10.32.0.0/24 | Serviceで使用するアドレス範囲 | apiserver(とcontroller-manager)の--service-cluster-ip-range で指定 |
|
10.32.0.1 | kubernetes | apiserverのサービスIP | Serviceのアドレス範囲の一番目がapiserverのServiceになる |
10.32.0.10 | kube-dns | clusterDNSのアドレス | CoreDNSのマニフェストで指定 |
Virtual Private Cloud Network
VPCネットワークを作成する。
gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom
sotoiwa@soto-no-air:~
$ gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/networks/kubernetes-the-hard-way].
NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4
kubernetes-the-hard-way CUSTOM REGIONAL
Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network kubernetes-the-hard-way --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network kubernetes-the-hard-way --allow tcp:22,tcp:3389,icmp
sotoiwa@soto-no-air:~
$
作成したVPCネットワークを確認する。
sotoiwa@soto-no-air:~
$ gcloud compute networks list
NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4
default AUTO REGIONAL
kubernetes-the-hard-way CUSTOM REGIONAL
sotoiwa@soto-no-air:~
$
サブネットを作成する。
gcloud compute networks subnets create kubernetes \
--network kubernetes-the-hard-way \
--range 10.240.0.0/24
sotoiwa@soto-no-air:~
$ gcloud compute networks subnets create kubernetes \
> --network kubernetes-the-hard-way \
> --range 10.240.0.0/24
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/regions/asia-northeast1/subnetworks/kubernetes].
NAME REGION NETWORK RANGE
kubernetes asia-northeast1 kubernetes-the-hard-way 10.240.0.0/24
sotoiwa@soto-no-air:~
$
作成したサブネットを確認する。
sotoiwa@soto-no-air:~
$ gcloud compute networks subnets list --network kubernetes-the-hard-way
NAME REGION NETWORK RANGE
kubernetes asia-northeast1 kubernetes-the-hard-way 10.240.0.0/24
sotoiwa@soto-no-air:~
$
Firewall Rules
全てのプロトコルで内部通信を許可するルールを作成する
-
10.240.0.0/24
はVMインスタンスを配置したネットワーク -
10.200.0.0/16
はPodが使用するアドレス範囲(クラスター全体のCIDR)
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-internal \
--allow tcp,udp,icmp \
--network kubernetes-the-hard-way \
--source-ranges 10.240.0.0/24,10.200.0.0/16
sotoiwa@soto-no-air:~
$ gcloud compute firewall-rules create kubernetes-the-hard-way-allow-internal \
> --allow tcp,udp,icmp \
> --network kubernetes-the-hard-way \
> --source-ranges 10.240.0.0/24,10.200.0.0/16
Creating firewall...⠏Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/firewalls/kubernetes-the-hard-way-allow-internal].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
kubernetes-the-hard-way-allow-internal kubernetes-the-hard-way INGRESS 1000 tcp,udp,icmp False
sotoiwa@soto-no-air:~
$
外部からのSSH、ICMP、HTTPSを許可する。
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \
--allow tcp:22,tcp:6443,icmp \
--network kubernetes-the-hard-way \
--source-ranges 0.0.0.0/0
sotoiwa@soto-no-air:~
$ gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \
> --allow tcp:22,tcp:6443,icmp \
> --network kubernetes-the-hard-way \
> --source-ranges 0.0.0.0/0
Creating firewall...⠏Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/firewalls/kubernetes-the-hard-way-allow-external].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
kubernetes-the-hard-way-allow-external kubernetes-the-hard-way INGRESS 1000 tcp:22,tcp:6443,icmp False
sotoiwa@soto-no-air:~
$
作成したルールを確認する。
sotoiwa@soto-no-air:~
$ gcloud compute firewall-rules list --filter="network:kubernetes-the-hard-way"
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
kubernetes-the-hard-way-allow-external kubernetes-the-hard-way INGRESS 1000 tcp:22,tcp:6443,icmp False
kubernetes-the-hard-way-allow-internal kubernetes-the-hard-way INGRESS 1000 tcp,udp,icmp False
To show all fields of the firewall, please show in JSON format: --format=json
To show all fields in table format, please see the examples in --help.
sotoiwa@soto-no-air:~
$
Kubernetes Public IP Address
API Serverの外部公開用のIPアドレスを取得する。
gcloud compute addresses create kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region)
sotoiwa@soto-no-air:~
$ gcloud compute addresses create kubernetes-the-hard-way \
> --region $(gcloud config get-value compute/region)
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/regions/asia-northeast1/addresses/kubernetes-the-hard-way].
sotoiwa@soto-no-air:~
$
作成されたアドレスを確認する。
sotoiwa@soto-no-air:~
$ gcloud compute addresses list --filter="name=('kubernetes-the-hard-way')"
NAME REGION ADDRESS STATUS
kubernetes-the-hard-way asia-northeast1 35.243.101.236 RESERVED
sotoiwa@soto-no-air:~
$
Compute Instances
Ubuntu Server 18.04のVMインスタンスを作成する。各インスタンスは固定のプライベートIPを持つ。
Kubernetes Controllers
Masterノード(コントロールプレーン)の3台を作成する。
for i in 0 1 2; do
gcloud compute instances create controller-${i} \
--async \
--boot-disk-size 200GB \
--can-ip-forward \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--machine-type n1-standard-1 \
--private-network-ip 10.240.0.1${i} \
--scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
--subnet kubernetes \
--tags kubernetes-the-hard-way,controller
done
sotoiwa@soto-no-air:~
$ for i in 0 1 2; do
> gcloud compute instances create controller-${i} \
> --async \
> --boot-disk-size 200GB \
> --can-ip-forward \
> --image-family ubuntu-1804-lts \
> --image-project ubuntu-os-cloud \
> --machine-type n1-standard-1 \
> --private-network-ip 10.240.0.1${i} \
> --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
> --subnet kubernetes \
> --tags kubernetes-the-hard-way,controller
> done
Instance creation in progress for [controller-0]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541756265972-57a381a904121-5c3b74e7-36e449c1
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
Instance creation in progress for [controller-1]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541756270177-57a381ad06ae9-9ebc254c-e604d3d4
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
Instance creation in progress for [controller-2]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541756274215-57a381b0e085a-d986a783-47ccc0f6
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
sotoiwa@soto-no-air:~
$
Kubernetes Workers
Workerノードを作成する。各ノードが使用するPodネットワークのサブネットの値(pod-cidr
)をメタデータに格納しておく。クラスター全体のCIDRは後でController Managerの--cluster-cidr
パラメータで指定することになり、このチュートリアルでは10.200.0.0/16
を使う。各Workerノードはそのうちのぞれぞれ10.200.0.0/24
、10.200.1.0/24
、10.200.2.0/24
を使う。
for i in 0 1 2; do
gcloud compute instances create worker-${i} \
--async \
--boot-disk-size 200GB \
--can-ip-forward \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--machine-type n1-standard-1 \
--metadata pod-cidr=10.200.${i}.0/24 \
--private-network-ip 10.240.0.2${i} \
--scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
--subnet kubernetes \
--tags kubernetes-the-hard-way,worker
done
sotoiwa@soto-no-air:~
$ for i in 0 1 2; do
> gcloud compute instances create worker-${i} \
> --async \
> --boot-disk-size 200GB \
> --can-ip-forward \
> --image-family ubuntu-1804-lts \
> --image-project ubuntu-os-cloud \
> --machine-type n1-standard-1 \
> --metadata pod-cidr=10.200.${i}.0/24 \
> --private-network-ip 10.240.0.2${i} \
> --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
> --subnet kubernetes \
> --tags kubernetes-the-hard-way,worker
> done
Instance creation in progress for [worker-0]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541757249739-57a38553358f8-a5900c8d-449e5ada
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
Instance creation in progress for [worker-1]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541757252867-57a38556313ba-b4658130-00e19bc3
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
Instance creation in progress for [worker-2]: https://www.googleapis.com/compute/v1/projects/sotoiwa/zones/asia-northeast1-a/operations/operation-1541757256094-57a3855945131-9896d4b4-a81fd823
Use [gcloud compute operations describe URI] command to check the status of the operation(s).
sotoiwa@soto-no-air:~
$
Verification
作成されたインスタンスを確認する。
sotoiwa@soto-no-air:~
$ gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
controller-0 asia-northeast1-a n1-standard-1 10.240.0.10 35.221.104.74 RUNNING
controller-1 asia-northeast1-a n1-standard-1 10.240.0.11 35.200.119.187 RUNNING
controller-2 asia-northeast1-a n1-standard-1 10.240.0.12 35.187.211.56 RUNNING
worker-0 asia-northeast1-a n1-standard-1 10.240.0.20 35.243.75.112 RUNNING
worker-1 asia-northeast1-a n1-standard-1 10.240.0.21 35.243.106.204 RUNNING
worker-2 asia-northeast1-a n1-standard-1 10.240.0.22 35.200.35.27 RUNNING
sotoiwa@soto-no-air:~
$
Configuring SSH Access
はじめてインスタンスに接続すると、SSH鍵が作成され、プロジェクトまたはインスタンスメタデータに保存される。
controller-0
インスタンスへのSSHログインできることを確認する。
gcloud compute ssh controller-0
Provisioning a CA and Generating TLS Certificates
cfsslを使って認証局を立て、各コンポーネント用の証明書を生成する。
(参考)
https://kubernetes.io/docs/concepts/cluster-administration/certificates/
Certificate Authority
作業用PCで作業する。
ルートCAの設定ファイルのjsonを作成する。kubernetes
というプロファイルを定義し、このCAが署名する証明書の有効期限と、X509v3拡張で証明書に含まれるパブリックキーの用途を指定している。後でCAから証明書を発行するときにこの設定ファイルとプロファイルを指定する。
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
EOF
ルートCAのCSR(証明書署名要求)を作成するためのjsonを作成する。ルートCAのCNは先頭大文字のKubernetes
としている。
cat > ca-csr.json <<EOF
{
"CN": "Kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "CA",
"ST": "Oregon"
}
]
}
EOF
CA秘密鍵(ca-key.pem)とCA証明書(ca.pem)を作成する。このとき証明書署名要求(ca.csr)もできる。前半のcfssl gencert
コマンドが秘密鍵とCSRと証明書を作成していて、出力されたjsonをcfssljson
コマンドがファイルにしている。
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2018/11/11 13:17:28 [INFO] generating a new CA key and certificate from CSR
2018/11/11 13:17:28 [INFO] generate received request
2018/11/11 13:17:28 [INFO] received CSR
2018/11/11 13:17:28 [INFO] generating key: rsa-2048
2018/11/11 13:17:29 [INFO] encoded CSR
2018/11/11 13:17:29 [INFO] signed certificate with serial number 689603942501758426539296774063220033367462065061
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
鍵の内容を確認する。
openssl rsa -text -noout -in ca-key.pem
CSRの内容を確認する。
openssl req -text -noout -in ca.csr
証明書の内容を確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in ca.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
78:ca:e9:06:c9:fb:05:0c:d7:24:9e:e8:cf:9f:bd:5c:fb:ab:33:a5
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 04:12:00 2018 GMT
Not After : Nov 10 04:12:00 2023 GMT
Subject: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
Client and Server Certificates
各Kubernetesコンポーネント用のサーバー/クライアント証明書と、admin
ユーザー用のクライアント証明書を作成する。
The Admin Client Certificate
admin
ユーザーの秘密鍵と証明書を作成する。
設定ファイルを作成する。CN=admin
を指定している。
cat > admin-csr.json <<EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:masters",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
秘密鍵と証明書を作成する。
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
admin-csr.json | cfssljson -bare admin
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> admin-csr.json | cfssljson -bare admin
2018/11/11 13:37:46 [INFO] generate received request
2018/11/11 13:37:46 [INFO] received CSR
2018/11/11 13:37:46 [INFO] generating key: rsa-2048
2018/11/11 13:37:46 [INFO] encoded CSR
2018/11/11 13:37:46 [INFO] signed certificate with serial number 194040900673817816765523470049772624081356590203
2018/11/11 13:37:46 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
admin-key.pem
とadmin.csr
とadmin.pem
が作られる。
証明書を確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in admin.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
21:fd:18:4c:6d:25:82:a8:53:9c:fd:e8:4e:b0:d3:4b:21:10:0c:7b
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 04:33:00 2018 GMT
Not After : Nov 11 04:33:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=system:masters, OU=Kubernetes The Hard Way, CN=admin
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
The Kubelet Client Certificates
Kubeletのクライアント証明書を作成する。Kubeletのリクエストは特別な認可モードであるNode Authorizer
で認可する(controller-managerなどはRBAC)が、そのためにはCN=system:node:<nodeName>
とする必要がある。全てのWorkerノード用にKubeletのクライアント証明書を作成する。
また、KubeletはクライアントであるだけでなくKubelet APIを提供するサーバーでもあるため、生成時に-hostname
を指定している。これによって作成する証明書にはSubject Alternative Name
が含まれる。
for instance in worker-0 worker-1 worker-2; do
cat > ${instance}-csr.json <<EOF
{
"CN": "system:node:${instance}",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:nodes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
INTERNAL_IP=$(gcloud compute instances describe ${instance} \
--format 'value(networkInterfaces[0].networkIP)')
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
-profile=kubernetes \
${instance}-csr.json | cfssljson -bare ${instance}
done
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ for instance in worker-0 worker-1 worker-2; do
> cat > ${instance}-csr.json <<EOF
> {
> "CN": "system:node:${instance}",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "system:nodes",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
> --format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
>
> INTERNAL_IP=$(gcloud compute instances describe ${instance} \
> --format 'value(networkInterfaces[0].networkIP)')
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
> -profile=kubernetes \
> ${instance}-csr.json | cfssljson -bare ${instance}
> done
2018/11/11 13:54:09 [INFO] generate received request
2018/11/11 13:54:09 [INFO] received CSR
2018/11/11 13:54:09 [INFO] generating key: rsa-2048
2018/11/11 13:54:09 [INFO] encoded CSR
2018/11/11 13:54:09 [INFO] signed certificate with serial number 607068271717182629182608002048778592028239367009
2018/11/11 13:54:12 [INFO] generate received request
2018/11/11 13:54:12 [INFO] received CSR
2018/11/11 13:54:12 [INFO] generating key: rsa-2048
2018/11/11 13:54:12 [INFO] encoded CSR
2018/11/11 13:54:13 [INFO] signed certificate with serial number 265349660986184529136660474458334524391738562848
2018/11/11 13:54:15 [INFO] generate received request
2018/11/11 13:54:15 [INFO] received CSR
2018/11/11 13:54:15 [INFO] generating key: rsa-2048
2018/11/11 13:54:15 [INFO] encoded CSR
2018/11/11 13:54:15 [INFO] signed certificate with serial number 441273454681782563464999456585802366467077262409
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
作成されたファイルを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ ls -l worker*
-rw-r--r-- 1 sotoiwa staff 244 11 11 13:54 worker-0-csr.json
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-0-key.pem
-rw-r--r-- 1 sotoiwa staff 1119 11 11 13:54 worker-0.csr
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-0.pem
-rw-r--r-- 1 sotoiwa staff 244 11 11 13:54 worker-1-csr.json
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-1-key.pem
-rw-r--r-- 1 sotoiwa staff 1119 11 11 13:54 worker-1.csr
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-1.pem
-rw-r--r-- 1 sotoiwa staff 244 11 11 13:54 worker-2-csr.json
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-2-key.pem
-rw-r--r-- 1 sotoiwa staff 1119 11 11 13:54 worker-2.csr
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-2.pem
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
worker-0
の証明書を確認する。SANが含まれる。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in worker-0.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6a:55:e1:fd:ea:e0:e4:7a:5c:d4:cf:90:44:b5:e5:34:c4:28:8b:61
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 04:49:00 2018 GMT
Not After : Nov 11 04:49:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=system:nodes, OU=Kubernetes The Hard Way, CN=system:node:worker-0
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
X509v3 Subject Alternative Name:
DNS:worker-0, IP Address:35.243.75.112, IP Address:10.240.0.20
(省略)
The Controller Manager Client Certificate
Controller Managerの証明書はCN=system:kube-controller-manager
とする。
{
cat > kube-controller-manager-csr.json <<EOF
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:kube-controller-manager",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
>
> cat > kube-controller-manager-csr.json <<EOF
> {
> "CN": "system:kube-controller-manager",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "system:kube-controller-manager",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
>
> }
2018/11/11 14:05:17 [INFO] generate received request
2018/11/11 14:05:17 [INFO] received CSR
2018/11/11 14:05:17 [INFO] generating key: rsa-2048
2018/11/11 14:05:18 [INFO] encoded CSR
2018/11/11 14:05:18 [INFO] signed certificate with serial number 663059462179332133204598729540750202823868590760
2018/11/11 14:05:18 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in kube-controller-manager.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
74:24:9d:56:20:af:2a:3b:a1:90:4c:2a:21:1b:4b:64:9c:be:aa:a8
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 05:00:00 2018 GMT
Not After : Nov 11 05:00:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=system:kube-controller-manager, OU=Kubernetes The Hard Way, CN=system:kube-controller-manager
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
The Kube Proxy Client Certificate
Kube Proxyの証明書はCN=system:kube-proxy
とする。
{
cat > kube-proxy-csr.json <<EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:node-proxier",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare kube-proxy
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
>
> cat > kube-proxy-csr.json <<EOF
> {
> "CN": "system:kube-proxy",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "system:node-proxier",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> kube-proxy-csr.json | cfssljson -bare kube-proxy
>
> }
2018/11/11 14:13:28 [INFO] generate received request
2018/11/11 14:13:28 [INFO] received CSR
2018/11/11 14:13:28 [INFO] generating key: rsa-2048
2018/11/11 14:13:29 [INFO] encoded CSR
2018/11/11 14:13:29 [INFO] signed certificate with serial number 419734016720855630130671555622742251431767916802
2018/11/11 14:13:29 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in kube-proxy.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
49:85:86:35:c2:1e:dc:59:66:12:4d:e6:9a:65:d1:df:45:65:41:02
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 05:08:00 2018 GMT
Not After : Nov 11 05:08:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=system:node-proxier, OU=Kubernetes The Hard Way, CN=system:kube-proxy
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
The Scheduler Client Certificate
Schedulerの証明書はCN=system:kube-scheduler
とする。
{
cat > kube-scheduler-csr.json <<EOF
{
"CN": "system:kube-scheduler",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:kube-scheduler",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-scheduler-csr.json | cfssljson -bare kube-scheduler
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
>
> cat > kube-scheduler-csr.json <<EOF
> {
> "CN": "system:kube-scheduler",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "system:kube-scheduler",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> kube-scheduler-csr.json | cfssljson -bare kube-scheduler
>
> }
2018/11/11 14:17:29 [INFO] generate received request
2018/11/11 14:17:29 [INFO] received CSR
2018/11/11 14:17:29 [INFO] generating key: rsa-2048
2018/11/11 14:17:30 [INFO] encoded CSR
2018/11/11 14:17:30 [INFO] signed certificate with serial number 291023982831656432886923858896283759904092510905
2018/11/11 14:17:30 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in kube-scheduler.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
32:f9:f7:7b:6e:58:65:42:8f:4e:52:c2:e1:85:f0:81:8a:2e:da:b9
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 05:13:00 2018 GMT
Not After : Nov 11 05:13:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=system:kube-scheduler, OU=Kubernetes The Hard Way, CN=system:kube-scheduler
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
The Kubernetes API Server Certificate
API Serverはクラスター内部からはkubernetes
というServiceとしてアクセスされるのでCN=kubernetes
とする。kube-apiserver
ではない。また、外部からもアクセスできるようにするため、-hostname
オプションでSANに以下を指定する。
アドレス/ホスト名 | 説明 |
---|---|
10.32.0.1 | apiserverのServiceのIP(Serviceが使用するアドレス範囲はあとで指定するが、その1番目のアドレスになる) |
10.240.0.10,10.240.0.11,10.240.0.12 | 各Masterノードのプライベートアドレス |
${KUBERNETES_PUBLIC_ADDRESS} | 外部公開用のIPアドレス |
127.0.0.1 | ループバックアドレス |
kubernetes.default | apiserverのServiceのホスト名 |
(疑問)
kubernetes
、kubernetes.default.svc
、kubernetes.default.svc.cluster
、kubernetes.default.svc.cluster.local
もSANに含めた方がよいのでは?
{
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
cat > kubernetes-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,kubernetes.default \
-profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
>
> KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
> --region $(gcloud config get-value compute/region) \
> --format 'value(address)')
>
> cat > kubernetes-csr.json <<EOF
> {
> "CN": "kubernetes",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "Kubernetes",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,kubernetes.default \
> -profile=kubernetes \
> kubernetes-csr.json | cfssljson -bare kubernetes
>
> }
2018/11/11 14:37:02 [INFO] generate received request
2018/11/11 14:37:02 [INFO] received CSR
2018/11/11 14:37:02 [INFO] generating key: rsa-2048
2018/11/11 14:37:03 [INFO] encoded CSR
2018/11/11 14:37:03 [INFO] signed certificate with serial number 265279844700410116849351878684631182647597918003
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in kubernetes.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2e:77:8f:45:14:b3:8a:c1:0c:5a:98:57:6a:b7:a7:a1:09:66:e7:33
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 05:32:00 2018 GMT
Not After : Nov 11 05:32:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=Kubernetes The Hard Way, CN=kubernetes
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
X509v3 Subject Alternative Name:
DNS:kubernetes.default, IP Address:10.32.0.1, IP Address:10.240.0.10, IP Address:10.240.0.11, IP Address:10.240.0.12, IP Address:35.243.101.236, IP Address:127.0.0.1
(省略)
The Service Account Key Pair
Controller Managerで稼働するToken ControllerがService Account Tokenを生成するための秘密鍵を作成する。CN=service-accounts
の証明書と秘密鍵を作成する。
(参考)
Managing Service Accounts
{
cat > service-account-csr.json <<EOF
{
"CN": "service-accounts",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
service-account-csr.json | cfssljson -bare service-account
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
>
> cat > service-account-csr.json <<EOF
> {
> "CN": "service-accounts",
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "US",
> "L": "Portland",
> "O": "Kubernetes",
> "OU": "Kubernetes The Hard Way",
> "ST": "Oregon"
> }
> ]
> }
> EOF
>
> cfssl gencert \
> -ca=ca.pem \
> -ca-key=ca-key.pem \
> -config=ca-config.json \
> -profile=kubernetes \
> service-account-csr.json | cfssljson -bare service-account
>
> }
2018/11/11 14:51:48 [INFO] generate received request
2018/11/11 14:51:48 [INFO] received CSR
2018/11/11 14:51:48 [INFO] generating key: rsa-2048
2018/11/11 14:51:48 [INFO] encoded CSR
2018/11/11 14:51:48 [INFO] signed certificate with serial number 35293248960946258940722654882849406852741852896
2018/11/11 14:51:48 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ openssl x509 -text -noout -in service-account.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
06:2e:9a:a0:f0:7c:02:82:7f:2b:4e:c7:14:46:3c:5a:24:bd:ee:e0
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=CA, CN=Kubernetes
Validity
Not Before: Nov 11 05:47:00 2018 GMT
Not After : Nov 11 05:47:00 2019 GMT
Subject: C=US, ST=Oregon, L=Portland, O=Kubernetes, OU=Kubernetes The Hard Way, CN=service-accounts
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
(省略)
Distribute the Client and Server Certificates
ここまでに作成した秘密鍵・証明書は以下。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ ls -l *.pem
-rw------- 1 sotoiwa staff 1679 11 11 13:37 admin-key.pem
-rw-r--r-- 1 sotoiwa staff 1428 11 11 13:37 admin.pem
-rw------- 1 sotoiwa staff 1675 11 11 13:17 ca-key.pem
-rw-r--r-- 1 sotoiwa staff 1318 11 11 13:17 ca.pem
-rw------- 1 sotoiwa staff 1679 11 11 14:05 kube-controller-manager-key.pem
-rw-r--r-- 1 sotoiwa staff 1484 11 11 14:05 kube-controller-manager.pem
-rw------- 1 sotoiwa staff 1679 11 11 14:13 kube-proxy-key.pem
-rw-r--r-- 1 sotoiwa staff 1452 11 11 14:13 kube-proxy.pem
-rw------- 1 sotoiwa staff 1679 11 11 14:17 kube-scheduler-key.pem
-rw-r--r-- 1 sotoiwa staff 1460 11 11 14:17 kube-scheduler.pem
-rw------- 1 sotoiwa staff 1679 11 11 14:37 kubernetes-key.pem
-rw-r--r-- 1 sotoiwa staff 1521 11 11 14:37 kubernetes.pem
-rw------- 1 sotoiwa staff 1679 11 11 14:51 service-account-key.pem
-rw-r--r-- 1 sotoiwa staff 1440 11 11 14:51 service-account.pem
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-0-key.pem
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-0.pem
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-1-key.pem
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-1.pem
-rw------- 1 sotoiwa staff 1679 11 11 13:54 worker-2-key.pem
-rw-r--r-- 1 sotoiwa staff 1493 11 11 13:54 worker-2.pem
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
それぞれの秘密鍵と証明書の最終的な行き先は次の通り。PEMファイルのまま、あるいはkubeconfigの中のBase64エンコードされたデータとして配布される。
- admin-key.pem
- 作業用PC:admin.kubeconfig
- admin.pem
- 作業用PC:admin.kubeconfig
- ca-key.pem
- controller-${i}:/var/lib/kubernetes/ca-key.pem
- ca.pem
- controller-${i}:/etc/etcd/ca.pem
- controller-${i}:/var/lib/kubernetes/ca.pem
- worker-${i}:/var/lib/kubernetes/ca.pem
- worker-${i}:/var/lib/kubelet/kubeconfig
- worker-${i}:/var/lib/kube-proxy/kubeconfig
- controller-${i}:/var/lib/kubernetes/kube-controller-manager.kubeconfig
- controller-${i}:/var/lib/kubernetes/kube-scheduler.kubeconfig
- 作業用PC:admin.kubeconfig
- kube-controller-manager-key.pem
- controller-${i}:/var/lib/kubernetes/kube-controller-manager.kubeconfig
- kube-controller-manager.pem
- controller-${i}:/var/lib/kubernetes/kube-controller-manager.kubeconfig
- kube-proxy-key.pem
- worker-${i}:/var/lib/kube-proxy/kubeconfig
- kube-proxy.pem
- worker-${i}:/var/lib/kube-proxy/kubeconfig
- kube-scheduler-key.pem
- controller-${i}:/var/lib/kubernetes/kube-scheduler.kubeconfig
- kube-scheduler.pem
- controller-${i}:/var/lib/kubernetes/kube-scheduler.kubeconfig
- kubernetes-key.pem
- controller-${i}:/etc/etcd/kubernetes-key.pem
- controller-${i}:/var/lib/kubernetes/kubernetes-key.pem
- kubernetes.pem
- controller-${i}:/etc/etcd/kubernetes.pem
- controller-${i}:/var/lib/kubernetes/kubernetes.pem
- service-account-key.pem
- controller-${i}:/var/lib/kubernetes/service-account-key.pem
- service-account.pem
- controller-${i}:/var/lib/kubernetes/service-account.pem
- worker-0-key.pem
- worker-0:/var/lib/kubelet/worker-0-key.pem
- worker-0:/var/lib/kubelet/kubeconfig
- worker-0.pem
- worker-0:/var/lib/kubelet/worker-0.pem
- worker-0:/var/lib/kubelet/kubeconfig
- worker-1-key.pem
- worker-1:/var/lib/kubelet/worker-1-key.pem
- worker-1:/var/lib/kubelet/kubeconfig
- worker-1.pem
- worker-1:/var/lib/kubelet/worker-1.pem
- worker-1:/var/lib/kubelet/kubeconfig
- worker-2-key.pem
- worker-2:/var/lib/kubelet/worker-2-key.pem
- worker-2:/var/lib/kubelet/kubeconfig
- worker-2.pem
- worker-2:/var/lib/kubelet/worker-2.pem
- worker-2:/var/lib/kubelet/kubeconfig
WorkerノードにCAの証明書と各ノード(Kubelet)秘密鍵と証明書を転送する。
for instance in worker-0 worker-1 worker-2; do
gcloud compute scp ca.pem ${instance}-key.pem ${instance}.pem ${instance}:~/
done
MasterノードにCAの秘密鍵と証明書、API Serverの秘密鍵と証明書、Service Account作成用の秘密鍵と証明書をコピーする。
for instance in controller-0 controller-1 controller-2; do
gcloud compute scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
service-account-key.pem service-account.pem ${instance}:~/
done
以下のコンポーネントの証明書は次のLabでkubeconfigを作成するのに使用する。
- kube-proxy
- kube-controller-manager
- kube-scheduler
- kubelet
Generating Kubernetes Configuration Files for Authentication
このLabでは各k8sコンポーネントが使用するkubeconfigを作成する。
Client Authentication Configs
Kubernetes Public IP Address
API Serverの外部公開用のIPアドレスを確認する。
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
> --region $(gcloud config get-value compute/region) \
> --format 'value(address)')
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ echo $KUBERNETES_PUBLIC_ADDRESS
35.243.101.236
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
The kubelet Kubernetes Configuration File
Kubelet用のkubeconfigを作成する。KubeletはCN=system:node:<nodeName>
と設定されたクライアント証明書を使うことでノード認可をする。ノード認可を行うために、あとでAPI Serverは--authorization-mode=Node
として起動する。
for instance in worker-0 worker-1 worker-2; do
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \
--kubeconfig=${instance}.kubeconfig
kubectl config set-credentials system:node:${instance} \
--client-certificate=${instance}.pem \
--client-key=${instance}-key.pem \
--embed-certs=true \
--kubeconfig=${instance}.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:${instance} \
--kubeconfig=${instance}.kubeconfig
kubectl config use-context default --kubeconfig=${instance}.kubeconfig
done
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ for instance in worker-0 worker-1 worker-2; do
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \
> --kubeconfig=${instance}.kubeconfig
>
> kubectl config set-credentials system:node:${instance} \
> --client-certificate=${instance}.pem \
> --client-key=${instance}-key.pem \
> --embed-certs=true \
> --kubeconfig=${instance}.kubeconfig
>
> kubectl config set-context default \
> --cluster=kubernetes-the-hard-way \
> --user=system:node:${instance} \
> --kubeconfig=${instance}.kubeconfig
>
> kubectl config use-context default --kubeconfig=${instance}.kubeconfig
> done
Cluster "kubernetes-the-hard-way" set.
User "system:node:worker-0" set.
Context "default" created.
Switched to context "default".
Cluster "kubernetes-the-hard-way" set.
User "system:node:worker-1" set.
Context "default" created.
Switched to context "default".
Cluster "kubernetes-the-hard-way" set.
User "system:node:worker-2" set.
Context "default" created.
Switched to context "default".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ cat worker-0.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <CA証明書>
server: https://35.243.101.236:6443
name: kubernetes-the-hard-way
contexts:
- context:
cluster: kubernetes-the-hard-way
user: system:node:worker-0
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: system:node:worker-0
user:
client-certificate-data: <Kubeletのクライアント証明書>
client-key-data: <Kubeletの秘密鍵>
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
証明書や秘密鍵のデータはbase64エンコードされている。base64 -D
で戻して確認することができる。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ cat worker-0.kubeconfig | grep certificate-authority-data | awk '{print $2}' | base64 -D
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIUeMrpBsn7BQzXJJ7oz5+9XPurM6UwDQYJKoZIhvcNAQEL
BQAwaDELMAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9y
dGxhbmQxEzARBgNVBAoTCkt1YmVybmV0ZXMxCzAJBgNVBAsTAkNBMRMwEQYDVQQD
EwpLdWJlcm5ldGVzMB4XDTE4MTExMTA0MTIwMFoXDTIzMTExMDA0MTIwMFowaDEL
MAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQx
EzARBgNVBAoTCkt1YmVybmV0ZXMxCzAJBgNVBAsTAkNBMRMwEQYDVQQDEwpLdWJl
cm5ldGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1mOweOZlxEvV
HcpA2T0G0LC58yqgzAj9M27QB9FOUIFTRRYmdZ3QlGKM2TaHUwMVMBLobh3EUrp9
e6ThAh1Tc2S/NsSTbmXpVlx4kHiJKAJK6M/srLFE3r6gWDdKsMh7o0AVmylVn9M0
bQrJ0vg2gbFXNaD0aXpYVFWPlxhqeZrf7nAgx6R7Kl5US4rlZ3Pyn8UMNLBDsGWC
QFcmdFOP8aV8zIjsDwyeVwjTOIzNo8DSBnrYu+z0zDkgUKccp+HgNt/7SLW7u4Zq
d2gHjVXfIrlwzikZ69IcCCg5YdvH8A9exObCDzYgj7Pi+0bn1qa3+P2jrkcJch+0
ERMAAK8SVwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUhdE6ktI5OtKwCPAtnjGpf9tIUMQwDQYJKoZIhvcNAQELBQAD
ggEBAGoGeJdYdAYZ9frfK+KBAu5QQyYh56u6UxZfHgqJ4NNIo2sM1YYX1EP6LPKI
TnsYzDw5t+XzN1twrgCazjQjR6Hus0iv5R4eTQprL65vbaPpUSD+x8FkJ6V8X6cJ
go4xPUUp4dfq3JY27dqdFyKBPcNme6j4TCxZiCAnro8v8X7dVLbvWoSe2QxPuw05
l4j4Hk/Cwl8yCmK1GNL7q9OW3VaImTN2KbUuhQrpqN9BM3wOwdiOrW/BnodMY2QD
pwh5TEV6TDDpDSlM85jXfL2No7wQXFReZVQ0P1wEk5kLx0A5HmRK3HpqnkLXGSE6
AMekXv0nLbGEcMYlIZgluubFgPw=
-----END CERTIFICATE-----
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
The kube-proxy Kubernetes Configuration File
Kube Proxy用のkubeconfigを作成する。
{
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials system:kube-proxy \
--client-certificate=kube-proxy.pem \
--client-key=kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \
> --kubeconfig=kube-proxy.kubeconfig
>
> kubectl config set-credentials system:kube-proxy \
> --client-certificate=kube-proxy.pem \
> --client-key=kube-proxy-key.pem \
> --embed-certs=true \
> --kubeconfig=kube-proxy.kubeconfig
>
> kubectl config set-context default \
> --cluster=kubernetes-the-hard-way \
> --user=system:kube-proxy \
> --kubeconfig=kube-proxy.kubeconfig
>
> kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
> }
Cluster "kubernetes-the-hard-way" set.
User "system:kube-proxy" set.
Context "default" created.
Switched to context "default".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
The kube-controller-manager Kubernetes Configuration File
Controller Manager用のkubeconfigを作成する。接続先はAPIサーバーの外部公開用のIPアドレスではなく127.0.0.1
を指定している。3台のAPI Serverは対等でありリーダーがいるわけではないので、同居しているAPI Serverに接続するようにしているが、外部公開用のIPアドレスを使用したとしても問題ないはず。
{
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://127.0.0.1:6443 \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-credentials system:kube-controller-manager \
--client-certificate=kube-controller-manager.pem \
--client-key=kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:kube-controller-manager \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://127.0.0.1:6443 \
> --kubeconfig=kube-controller-manager.kubeconfig
>
> kubectl config set-credentials system:kube-controller-manager \
> --client-certificate=kube-controller-manager.pem \
> --client-key=kube-controller-manager-key.pem \
> --embed-certs=true \
> --kubeconfig=kube-controller-manager.kubeconfig
>
> kubectl config set-context default \
> --cluster=kubernetes-the-hard-way \
> --user=system:kube-controller-manager \
> --kubeconfig=kube-controller-manager.kubeconfig
>
> kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig
> }
Cluster "kubernetes-the-hard-way" set.
User "system:kube-controller-manager" set.
Context "default" created.
Switched to context "default".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
The kube-scheduler Kubernetes Configuration File
Scheduler用のkubeconfigを作成する。こちらも接続先はAPIサーバーの外部公開用のIPアドレスではなく127.0.0.1
を指定している。
{
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://127.0.0.1:6443 \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config set-credentials system:kube-scheduler \
--client-certificate=kube-scheduler.pem \
--client-key=kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:kube-scheduler \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://127.0.0.1:6443 \
> --kubeconfig=kube-scheduler.kubeconfig
>
> kubectl config set-credentials system:kube-scheduler \
> --client-certificate=kube-scheduler.pem \
> --client-key=kube-scheduler-key.pem \
> --embed-certs=true \
> --kubeconfig=kube-scheduler.kubeconfig
>
> kubectl config set-context default \
> --cluster=kubernetes-the-hard-way \
> --user=system:kube-scheduler \
> --kubeconfig=kube-scheduler.kubeconfig
>
> kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig
> }
Cluster "kubernetes-the-hard-way" set.
User "system:kube-scheduler" set.
Context "default" created.
Switched to context "default".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
The admin Kubernetes Configuration File
admin
ユーザー用の設定ファイルを作成する。外部公開用のIPアドレスではなく127.0.0.1
を指定しているが、Masterノードに配置してMasterノードでkubectl
を実行することを想定しているため。作業用PCで使用するkubeconfigはまたあとで作成するが、そのときはAPI Serverの外部公開用のIPアドレスを指定する。
{
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://127.0.0.1:6443 \
--kubeconfig=admin.kubeconfig
kubectl config set-credentials admin \
--client-certificate=admin.pem \
--client-key=admin-key.pem \
--embed-certs=true \
--kubeconfig=admin.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=admin \
--kubeconfig=admin.kubeconfig
kubectl config use-context default --kubeconfig=admin.kubeconfig
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://127.0.0.1:6443 \
> --kubeconfig=admin.kubeconfig
>
> kubectl config set-credentials admin \
> --client-certificate=admin.pem \
> --client-key=admin-key.pem \
> --embed-certs=true \
> --kubeconfig=admin.kubeconfig
>
> kubectl config set-context default \
> --cluster=kubernetes-the-hard-way \
> --user=admin \
> --kubeconfig=admin.kubeconfig
>
> kubectl config use-context default --kubeconfig=admin.kubeconfig
> }
Cluster "kubernetes-the-hard-way" set.
User "admin" set.
Context "default" created.
Switched to context "default".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Distribute the Kubernetes Configuration Files
作成したkubeconfigは以下。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ ls -l *.kubeconfig
-rw------- 1 sotoiwa staff 6265 11 11 16:47 admin.kubeconfig
-rw------- 1 sotoiwa staff 6391 11 11 16:37 kube-controller-manager.kubeconfig
-rw------- 1 sotoiwa staff 6326 11 11 16:17 kube-proxy.kubeconfig
-rw------- 1 sotoiwa staff 6341 11 11 16:44 kube-scheduler.kubeconfig
-rw------- 1 sotoiwa staff 6388 11 11 16:04 worker-0.kubeconfig
-rw------- 1 sotoiwa staff 6388 11 11 16:04 worker-1.kubeconfig
-rw------- 1 sotoiwa staff 6388 11 11 16:04 worker-2.kubeconfig
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Workerノードにkubelet
とkube-proxy
のkubeconfigを配布する。
for instance in worker-0 worker-1 worker-2; do
gcloud compute scp ${instance}.kubeconfig kube-proxy.kubeconfig ${instance}:~/
done
Masterノードにadmin
とkube-controller-manager
とkube-scheduler
のkubeconfigを配布する。
for instance in controller-0 controller-1 controller-2; do
gcloud compute scp admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig ${instance}:~/
done
Generating the Data Encryption Config and Key
このLabではSecretを暗号化してからetcdに保存するための鍵と設定ファイルを作成する。
(参考)
Encrypting Secret Data at Rest
The Encryption Key
暗号化キーを作成する。
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
The Encryption Config File
設定ファイルを作成する。
cat > encryption-config.yaml <<EOF
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: ${ENCRYPTION_KEY}
- identity: {}
EOF
作成したファイルをMasterノードに転送する。
for instance in controller-0 controller-1 controller-2; do
gcloud compute scp encryption-config.yaml ${instance}:~/
done
Bootstrapping the etcd Cluster
このLabではetcdクラスターを起動する。
Prerequisites
このLabでのコマンドはcontroller-0
、controller-1
、controller-2
のそれぞれのノードで実行する。ノードへのログインは以下のコマンド。
gcloud compute ssh controller-0
Running commands in parallel with tmux
(最初のLabでも記載があった内容なので省略)
Bootstrapping an etcd Cluster Member
Download and Install the etcd Binaries
etcdのバイナリをダウンロードする。バイナリのダウンロード元は以下のリリースページ。バージョンはv3.3.9をダウンロードしている。
wget -q --show-progress --https-only --timestamping \
"https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz"
ダウンロードしたファイルを展開して/usr/local/bin
ディレクトリーにインストールする。
{
tar -xvf etcd-v3.3.9-linux-amd64.tar.gz
sudo mv etcd-v3.3.9-linux-amd64/etcd* /usr/local/bin/
}
Configure the etcd Server
/etc/etcd
と/var/lib/etcd
ディレクトリーを作成して以下のファイルをコピーする。
- CA証明書
- APIサーバーの秘密鍵と証明書
{
sudo mkdir -p /etc/etcd /var/lib/etcd
sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/
}
現在のVMインスタンス自身のIPアドレスを取得して変数に入れる。
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
sotoiwa@controller-0:~$ INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
> http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
sotoiwa@controller-0:~$ echo $INTERNAL_IP
10.240.0.10
sotoiwa@controller-0:~$
Etcdメンバーはユニークな名前を持つ必要があるので、名前としてインスタンス名を使う。-s
は短い形式(最初のドットまで)のホスト名を表示するオプション。
ETCD_NAME=$(hostname -s)
sotoiwa@controller-0:~$ ETCD_NAME=$(hostname -s)
sotoiwa@controller-0:~$ echo $ETCD_NAME
controller-0
sotoiwa@controller-0:~$
Systemdサービスの定義ファイルetcd.service
を作成する。etcdの引数として指定しているものについては以下のドキュメントに解説がある。
(参考)
Operating etcd clusters for Kubernetes
cat <<EOF | sudo tee /etc/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/etcd/kubernetes.pem \\
--key-file=/etc/etcd/kubernetes-key.pem \\
--peer-cert-file=/etc/etcd/kubernetes.pem \\
--peer-key-file=/etc/etcd/kubernetes-key.pem \\
--trusted-ca-file=/etc/etcd/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
--advertise-client-urls https://${INTERNAL_IP}:2379 \\
--initial-cluster-token etcd-cluster-0 \\
--initial-cluster controller-0=https://10.240.0.10:2380,controller-1=https://10.240.0.11:2380,controller-2=https://10.240.0.12:2380 \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/etcd.service
> [Unit]
> Description=etcd
> Documentation=https://github.com/coreos
>
> [Service]
> ExecStart=/usr/local/bin/etcd \\
> --name ${ETCD_NAME} \\
> --cert-file=/etc/etcd/kubernetes.pem \\
> --key-file=/etc/etcd/kubernetes-key.pem \\
> --peer-cert-file=/etc/etcd/kubernetes.pem \\
> --peer-key-file=/etc/etcd/kubernetes-key.pem \\
> --trusted-ca-file=/etc/etcd/ca.pem \\
> --peer-trusted-ca-file=/etc/etcd/ca.pem \\
> --peer-client-cert-auth \\
> --client-cert-auth \\
> --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
> --listen-peer-urls https://${INTERNAL_IP}:2380 \\
> --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
> --advertise-client-urls https://${INTERNAL_IP}:2379 \\
> --initial-cluster-token etcd-cluster-0 \\
> --initial-cluster controller-0=https://10.240.0.10:2380,controller-1=https://10.240.0.11:2380,controller-2=https://10.240.0.12:2380 \\
> --initial-cluster-state new \\
> --data-dir=/var/lib/etcd
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \
--name controller-0 \
--cert-file=/etc/etcd/kubernetes.pem \
--key-file=/etc/etcd/kubernetes-key.pem \
--peer-cert-file=/etc/etcd/kubernetes.pem \
--peer-key-file=/etc/etcd/kubernetes-key.pem \
--trusted-ca-file=/etc/etcd/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ca.pem \
--peer-client-cert-auth \
--client-cert-auth \
--initial-advertise-peer-urls https://10.240.0.10:2380 \
--listen-peer-urls https://10.240.0.10:2380 \
--listen-client-urls https://10.240.0.10:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://10.240.0.10:2379 \
--initial-cluster-token etcd-cluster-0 \
--initial-cluster controller-0=https://10.240.0.10:2380,controller-1=https://10.240.0.11:2380,controller-2=https://10.240.0.12:2380 \
--initial-cluster-state new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@controller-0:~$
-
--cert-file
と--key-file
がサーバーとしての通信に使う証明書と秘密鍵 -
--peer-cert-file
と--peer-key-file
はetcd間の通信に使う証明書と秘密鍵 - API Server用に作成した秘密鍵や証明書をetcdでも使用している
-
--peer-client-cert-auth
、--client-cert-auth
が指定されているので、サーバーとしての通信でもetcd間の通信でもクライアント認証する
Start the etcd Server
etcdを起動する。
{
sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd
}
サービスのステータスを確認。
sudo systemctl status etcd
Verification
etcdクラスターのメンバーをリストするコマンドを実行する。
sudo ETCDCTL_API=3 etcdctl member list \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem \
--cert=/etc/etcd/kubernetes.pem \
--key=/etc/etcd/kubernetes-key.pem
sotoiwa@controller-0:~$ sudo ETCDCTL_API=3 etcdctl member list \
> --endpoints=https://127.0.0.1:2379 \
> --cacert=/etc/etcd/ca.pem \
> --cert=/etc/etcd/kubernetes.pem \
> --key=/etc/etcd/kubernetes-key.pem
3a57933972cb5131, started, controller-2, https://10.240.0.12:2380, https://10.240.0.12:2379
f98dc20bce6225a0, started, controller-0, https://10.240.0.10:2380, https://10.240.0.10:2379
ffed16798470cab5, started, controller-1, https://10.240.0.11:2380, https://10.240.0.11:2379
sotoiwa@controller-0:~$
Bootstrapping the Kubernetes Control Plane
このLabではMasterノードのk8sコンポーネント(apiserver、scheduler、controller-manager)を起動する。
Prerequisites
前のLabと同じく、このLabのコマンドは全てのMasterノードで実施する必要がある。
Running commands in parallel with tmux
(省略)
Provision the Kubernetes Control Plane
Kubenetesの構成ファイル用ディレクトリーを作成する。
sudo mkdir -p /etc/kubernetes/config
Download and Install the Kubernetes Controller Binaries
公式のバイナリをダウンロードする。この直接ダウンロードリンクにどうやってたどり着けばいいのかわからなかった。以下のリリースページからtarをダウンロードできる。tarの中にはバイナリは入っておらず、解凍してkubernetes/cluster/get-kube-binaries.sh
を実行するとダウンロードできる。バージョンはv1.12.0をダウンロードする。
wget -q --show-progress --https-only --timestamping \
"https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kube-apiserver" \
"https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kube-controller-manager" \
"https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kube-scheduler" \
"https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl"
バイナリを/usr/local/bin
ディレクトリーにインストールする。
{
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
}
確認する。
sotoiwa@controller-0:~$ ls -l /usr/local/bin/
total 493164
-rwxr-xr-x 1 sotoiwa sotoiwa 18934016 Jul 24 17:13 etcd
-rwxr-xr-x 1 sotoiwa sotoiwa 15809280 Jul 24 17:13 etcdctl
-rwxrwxr-x 1 sotoiwa sotoiwa 192766426 Sep 27 23:04 kube-apiserver
-rwxrwxr-x 1 sotoiwa sotoiwa 162936572 Sep 27 23:04 kube-controller-manager
-rwxrwxr-x 1 sotoiwa sotoiwa 57180560 Sep 27 23:04 kube-scheduler
-rwxrwxr-x 1 sotoiwa sotoiwa 57343669 Sep 27 23:04 kubectl
sotoiwa@controller-0:~$
Configure the Kubernetes API Server
/var/lib/kubernetes/
ディレクトリーを作成して以下のファイルを移動する。
- CAの秘密鍵と証明書
- API Serverの秘密鍵と証明書
- Service Account作成用の秘密鍵と証明書
- Secretの暗号化用の設定ファイル
{
sudo mkdir -p /var/lib/kubernetes/
sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
service-account-key.pem service-account.pem \
encryption-config.yaml /var/lib/kubernetes/
}
確認する。
sotoiwa@controller-2:~$ ls -l /var/lib/kubernetes/
total 28
-rw------- 1 sotoiwa sotoiwa 1675 Nov 11 06:04 ca-key.pem
-rw-r--r-- 1 sotoiwa sotoiwa 1318 Nov 11 06:04 ca.pem
-rw-r--r-- 1 sotoiwa sotoiwa 196 Nov 11 08:09 encryption-config.yaml
-rw------- 1 sotoiwa sotoiwa 1679 Nov 11 06:04 kubernetes-key.pem
-rw-r--r-- 1 sotoiwa sotoiwa 1521 Nov 11 06:04 kubernetes.pem
-rw------- 1 sotoiwa sotoiwa 1679 Nov 11 06:04 service-account-key.pem
-rw-r--r-- 1 sotoiwa sotoiwa 1440 Nov 11 06:04 service-account.pem
sotoiwa@controller-2:~$
現在のVMインスタンス自身のIPアドレスを取得して変数に入れる。
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
Systemdサービスの定義ファイルkube-apiserver.service
を作成する。引数については以下のリンク先に説明がある。
(参考)
kube-apiserver
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
--advertise-address=${INTERNAL_IP} \\
--allow-privileged=true \\
--apiserver-count=3 \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/audit.log \\
--authorization-mode=Node,RBAC \\
--bind-address=0.0.0.0 \\
--client-ca-file=/var/lib/kubernetes/ca.pem \\
--enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
--enable-swagger-ui=true \\
--etcd-cafile=/var/lib/kubernetes/ca.pem \\
--etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
--etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
--etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
--event-ttl=1h \\
--experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
--kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
--kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
--kubelet-https=true \\
--runtime-config=api/all \\
--service-account-key-file=/var/lib/kubernetes/service-account.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--service-node-port-range=30000-32767 \\
--tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
--tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
> [Unit]
> Description=Kubernetes API Server
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-apiserver \\
> --advertise-address=${INTERNAL_IP} \\
> --allow-privileged=true \\
> --apiserver-count=3 \\
> --audit-log-maxage=30 \\
> --audit-log-maxbackup=3 \\
> --audit-log-maxsize=100 \\
> --audit-log-path=/var/log/audit.log \\
> --authorization-mode=Node,RBAC \\
> --bind-address=0.0.0.0 \\
> --client-ca-file=/var/lib/kubernetes/ca.pem \\
> --enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
> --enable-swagger-ui=true \\
> --etcd-cafile=/var/lib/kubernetes/ca.pem \\
> --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
> --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
> --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
> --event-ttl=1h \\
> --experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
> --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
> --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
> --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
> --kubelet-https=true \\
> --runtime-config=api/all \\
> --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
> --service-cluster-ip-range=10.32.0.0/24 \\
> --service-node-port-range=30000-32767 \\
> --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
> --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
> --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-apiserver \
--advertise-address=10.240.0.10 \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/audit.log \
--authorization-mode=Node,RBAC \
--bind-address=0.0.0.0 \
--client-ca-file=/var/lib/kubernetes/ca.pem \
--enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--enable-swagger-ui=true \
--etcd-cafile=/var/lib/kubernetes/ca.pem \
--etcd-certfile=/var/lib/kubernetes/kubernetes.pem \
--etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \
--etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \
--event-ttl=1h \
--experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \
--kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \
--kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \
--kubelet-https=true \
--runtime-config=api/all \
--service-account-key-file=/var/lib/kubernetes/service-account.pem \
--service-cluster-ip-range=10.32.0.0/24 \
--service-node-port-range=30000-32767 \
--tls-cert-file=/var/lib/kubernetes/kubernetes.pem \
--tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@controller-0:~$
-
--authorization-mode=Node,RBAC
としており、Kubeletはノード認可する -
--etcd-***
がetcdとの接続に関する設定で使用する証明書などを指定している -
--kubelet-***
がkubeletとの接続に関する設定で使用する証明書などを指定している -
--tls-cert-file
と--tls-private-key-file
が自身がHTTPSサーバーとしてリクエストを受け付けるための設定 -
--service-cluster-ip-range=10.32.0.0/24
でServiceが使用するIPのCIDRを指定している
Configure the Kubernetes Controller Manager
Controller Managerが使用するkubeconfigを/var/lib/kubernetes/
に配置する。
sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/
Systemdサービスの定義ファイルkube-controller-manager.service
を作成する。
cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \\
--address=0.0.0.0 \\
--cluster-cidr=10.200.0.0/16 \\
--cluster-name=kubernetes \\
--cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
--cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
--leader-elect=true \\
--root-ca-file=/var/lib/kubernetes/ca.pem \\
--service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
--use-service-account-credentials=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
> [Unit]
> Description=Kubernetes Controller Manager
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-controller-manager \\
> --address=0.0.0.0 \\
> --cluster-cidr=10.200.0.0/16 \\
> --cluster-name=kubernetes \\
> --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
> --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
> --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
> --leader-elect=true \\
> --root-ca-file=/var/lib/kubernetes/ca.pem \\
> --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
> --service-cluster-ip-range=10.32.0.0/24 \\
> --use-service-account-credentials=true \\
> --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
--address=0.0.0.0 \
--cluster-cidr=10.200.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \
--cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \
--leader-elect=true \
--root-ca-file=/var/lib/kubernetes/ca.pem \
--service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \
--service-cluster-ip-range=10.32.0.0/24 \
--use-service-account-credentials=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@controller-0:~$
-
--cluster-cidr=10.200.0.0/16
でクラスターのCIDRを指定している -
--kubeconfig
でAPI Serverへの接続情報を指定している -
--service-account-private-key-file
でServiec Account Tokenの作成に使用する秘密鍵を指定している -
--service-cluster-ip-range=10.32.0.0/24
でAPI Serverと同じくServiceのCIDRを指定している -
--leader-elect=true
を設定しているので、3台のMasterノードのうちの1つがリーダーになる -
--cluster-signing-key-file
と--cluster-signing-cert-file
を指定しているのは証明書のローテーション時にController Managerが署名を行うためと思われる
Configure the Kubernetes Scheduler
Schedulerが使用するkubeconfigを/var/lib/kubernetes/
に配置する。
sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/
Schedulerの設定ファイルkube-scheduler.yaml
を作成する。
cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
apiVersion: componentconfig/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
leaderElect: true
EOF
sotoiwa@controller-0:~$ cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
> apiVersion: componentconfig/v1alpha1
> kind: KubeSchedulerConfiguration
> clientConnection:
> kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
> leaderElection:
> leaderElect: true
> EOF
apiVersion: componentconfig/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
leaderElect: true
sotoiwa@controller-0:~$
- kubeconfigをここで指定している
-
leaderElect: true
を設定しているので、3台のMasterノードのうちの1つがリーダーになる
Systemdサービスの定義ファイルkube-scheduler.service
を作成する。
(参考)
kube-scheduler
cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \\
--config=/etc/kubernetes/config/kube-scheduler.yaml \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
> [Unit]
> Description=Kubernetes Scheduler
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-scheduler \\
> --config=/etc/kubernetes/config/kube-scheduler.yaml \\
> --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-scheduler \
--config=/etc/kubernetes/config/kube-scheduler.yaml \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@controller-0:~$
- 先ほど作成した
kube-scheduler.yaml
を指定している
Start the Controller Services
サービスを有効にして起動する。
{
sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
}
サービスのステータスを確認する。
sudo systemctl status kube-apiserver kube-controller-manager kube-scheduler
Enable HTTP Health Checks
Google Network Load BalancerがAPI Serverへのリクエストを負荷分散する。API ServerはHTTPSで接続を受け付けるが、Load BalancerはHTTPしかサポートしておらずヘルスチェックが失敗してしまうため、回避策としてヘルスチェックをプロキシするnginxを動かす。nginxは80
ポートで受け取ったヘルスチェックリクエストをhttps://127.0.0.1:6443/healthz
へプロキシする。この/healthz
エンドポイントは認証が不要。
(参考)
Network Load Balancing Concepts
nginxをインストールする。
sudo apt-get install -y nginx
設定ファイルを作成。
cat > kubernetes.default.svc.cluster.local <<EOF
server {
listen 80;
server_name kubernetes.default.svc.cluster.local;
location /healthz {
proxy_pass https://127.0.0.1:6443/healthz;
proxy_ssl_trusted_certificate /var/lib/kubernetes/ca.pem;
}
}
EOF
設定ファイルを配置してサイトを有効化する。
{
sudo mv kubernetes.default.svc.cluster.local \
/etc/nginx/sites-available/kubernetes.default.svc.cluster.local
sudo ln -s /etc/nginx/sites-available/kubernetes.default.svc.cluster.local /etc/nginx/sites-enabled/
}
サービスを再起動して有効化する。
{
sudo systemctl restart nginx
sudo systemctl enable nginx
}
Verification
コンポーネントの状態を確認する。
kubectl get componentstatuses --kubeconfig admin.kubeconfig
sotoiwa@controller-0:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
sotoiwa@controller-0:~$
curlでプロキシができていることを確認する。
curl -H "Host: kubernetes.default.svc.cluster.local" -i http://127.0.0.1/healthz
sotoiwa@controller-0:~$ curl -H "Host: kubernetes.default.svc.cluster.local" -i http://127.0.0.1/healthz
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Sun, 11 Nov 2018 11:12:28 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Connection: keep-alive
oksotoiwa@controller-0:~$
RBAC for Kubelet Authorization
このセクションでは、API Serverが各WorkerノードのKubelet APIにアクセスできるようにRBACを構成する。Kubelet APIにアクセスすることで、メトリックを取得したり、ログを取得したり、Pod内でコマンドを実行したりできる。
このチュートリアルでは、Kubeletの--authorization-mode
をWebhook
に設定する。Webhookモードではkubeconfigの設定にしたがって外部に問い合わせにいくが、Kubeletは結局API Serverに問い合わせるということだと思われる。
(参考)
Authorization Overview
Webhook Mode
controller-0
で作業する。
gcloud compute ssh controller-0
system:kube-apiserver-to-kubelet
というClusterRoleを作成し、Kubelet APIへのアクセスを許可する。apiGroups
の""
はcore API groupを意味する。
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
verbs:
- "*"
EOF
sotoiwa@controller-0:~$ cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
> apiVersion: rbac.authorization.k8s.io/v1beta1
> kind: ClusterRole
> metadata:
> annotations:
> rbac.authorization.kubernetes.io/autoupdate: "true"
> labels:
> kubernetes.io/bootstrapping: rbac-defaults
> name: system:kube-apiserver-to-kubelet
> rules:
> - apiGroups:
> - ""
> resources:
> - nodes/proxy
> - nodes/stats
> - nodes/log
> - nodes/spec
> - nodes/metrics
> verbs:
> - "*"
> EOF
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created
sotoiwa@controller-0:~$
Kubeletに対して、API Serverはkubernetes
ユーザーとして--kubelet-client-certificate
で指定されたクライアント証明書を使って認証を試みるのでkubernetes
ユーザーをsystem:kube-apiserver-to-kubelet
のClusterRoleにバインドするClusterRoleBindingを作成する。
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetes
EOF
sotoiwa@controller-0:~$ cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
> apiVersion: rbac.authorization.k8s.io/v1beta1
> kind: ClusterRoleBinding
> metadata:
> name: system:kube-apiserver
> namespace: ""
> roleRef:
> apiGroup: rbac.authorization.k8s.io
> kind: ClusterRole
> name: system:kube-apiserver-to-kubelet
> subjects:
> - apiGroup: rbac.authorization.k8s.io
> kind: User
> name: kubernetes
> EOF
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created
sotoiwa@controller-0:~$
The Kubernetes Frontend Load Balancer
API Serverの前に配置される外部ロードバランサーをプロビジョニングする。
Provision a Network Load Balancer
{
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
gcloud compute http-health-checks create kubernetes \
--description "Kubernetes Health Check" \
--host "kubernetes.default.svc.cluster.local" \
--request-path "/healthz"
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \
--network kubernetes-the-hard-way \
--source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \
--allow tcp
gcloud compute target-pools create kubernetes-target-pool \
--http-health-check kubernetes
gcloud compute target-pools add-instances kubernetes-target-pool \
--instances controller-0,controller-1,controller-2
gcloud compute forwarding-rules create kubernetes-forwarding-rule \
--address ${KUBERNETES_PUBLIC_ADDRESS} \
--ports 6443 \
--region $(gcloud config get-value compute/region) \
--target-pool kubernetes-target-pool
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
gcloud compute http-health-checks create kubernetes \
--description "Kubernetes Health Check" \
--host "kubernetes.default.svc.cluster.local" \
--request-path "/healthz"
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \
--network kubernetes-the-hard-way \
--source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \
--allow tcp
gcloud compute target-pools create kubernetes-target-pool \
--http-health-check kubernetes
gcloud compute target-pools add-instances kubernetes-target-pool \
--instances controller-0,controller-1,controller-2
gcloud compute forwarding-rules create kubernetes-forwarding-rule \
--address ${KUBERNETES_PUBLIC_ADDRESS} \
--ports 6443 \
--region $(gcloud config get-value compute/region) \
--targe> KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
> --region $(gcloud config get-value compute/region) \
> --format 'value(address)')
>
> gcloud compute http-health-checks create kubernetes \
> --description "Kubernetes Health Check" \
> --host "kubernetes.default.svc.cluster.local" \
> --request-path "/healthz"
>
> gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \
> --network kubernetes-the-hard-way \
> --source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \
> --allow tcp
>
> gcloud compute target-pools create kubernetes-target-pool \
> --http-health-check kubernetes
>
> gcloud compute target-pools add-instances kubernetes-target-pool \
> --instances controller-0,controller-1,controller-2
>
> gcloud compute forwarding-rules create kubernetes-forwarding-rule \
> --address ${KUBERNETES_PUBLIC_ADDRESS} \
> --ports 6443 \
> --region $(gcloud config get-value compute/region) \
> --target-pool kubernetes-target-pool
> }
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/httpHealthChecks/kubernetes].
NAME HOST PORT REQUEST_PATH
kubernetes kubernetes.default.svc.cluster.local 80 /healthz
Creating firewall...⠏Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/firewalls/kubernetes-the-hard-way-allow-health-check].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
kubernetes-the-hard-way-allow-health-check kubernetes-the-hard-way INGRESS 1000 tcp False
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/regions/asia-northeast1/targetPools/kubernetes-target-pool].
NAME REGION SESSION_AFFINITY BACKUP HEALTH_CHECKS
kubernetes-target-pool asia-northeast1 NONE kubernetes
Updated [https://www.googleapis.com/compute/v1/projects/sotoiwa/regions/asia-northeast1/targetPools/kubernetes-target-pool].
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/regions/asia-northeast1/forwardingRules/kubernetes-forwarding-rule].
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Verification
API Server公開用の外部IPを確認する。
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
作業用PCからHTTPリクエストを投げ、Kubernetesのバージョンが取得出来ることを確認する。
curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version
{
"major": "1",
"minor": "12",
"gitVersion": "v1.12.0",
"gitCommit": "0ed33881dc4355495f623c6f22e7dd0b7632b7c0",
"gitTreeState": "clean",
"buildDate": "2018-09-27T16:55:41Z",
"goVersion": "go1.10.4",
"compiler": "gc",
"platform": "linux/amd64"
}sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Bootstrapping the Kubernetes Worker Nodes
このLabではWorkerノードのk8sコンポーネント(kubelet、kube-proxy)を起動する。
Prerequisites
このLabの作業は各Workerノードで行う。
Running commands in parallel with tmux
(省略)
Provisioning a Kubernetes Worker Node
依存パッケージをインストールする。
{
sudo apt-get update
sudo apt-get -y install socat conntrack ipset
}
Download and Install Worker Binaries
cri-tools、runcs、runc、cni-plugins、containerdのバイナリをダウンロードする。runcsは公式バイナリではなくこのチュートリアル用のもの?それぞれのリリースページは以下。
- https://github.com/kubernetes-sigs/cri-tools/releases
- https://github.com/opencontainers/runc/releases
- https://github.com/containernetworking/plugins/releases
- https://github.com/containerd/containerd/releases
kubectl、kube-proxy、kubeletは先ほどMasterノードのコンポーネントをダウンロードしたときと同じtarに入っている。
wget -q --show-progress --https-only --timestamping \
https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.12.0/crictl-v1.12.0-linux-amd64.tar.gz \
https://storage.googleapis.com/kubernetes-the-hard-way/runsc-50c283b9f56bb7200938d9e207355f05f79f0d17 \
https://github.com/opencontainers/runc/releases/download/v1.0.0-rc5/runc.amd64 \
https://github.com/containernetworking/plugins/releases/download/v0.6.0/cni-plugins-amd64-v0.6.0.tgz \
https://github.com/containerd/containerd/releases/download/v1.2.0-rc.0/containerd-1.2.0-rc.0.linux-amd64.tar.gz \
https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl \
https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kube-proxy \
https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubelet
ディレクトリーを作成する。
sudo mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
バイナリをインストールする。
-
kube-proxy
、kubelet
、runc
、runsc
、crictl
は/usr/local/bin/
へ - cniプラグインは
/opt/cni/bin/
へ -
containerd
は/bin/
へ
{
sudo mv runsc-50c283b9f56bb7200938d9e207355f05f79f0d17 runsc
sudo mv runc.amd64 runc
chmod +x kubectl kube-proxy kubelet runc runsc
sudo mv kubectl kube-proxy kubelet runc runsc /usr/local/bin/
sudo tar -xvf crictl-v1.12.0-linux-amd64.tar.gz -C /usr/local/bin/
sudo tar -xvf cni-plugins-amd64-v0.6.0.tgz -C /opt/cni/bin/
sudo tar -xvf containerd-1.2.0-rc.0.linux-amd64.tar.gz -C /
}
Configure CNI Networking
この時点ではインターフェースは以下のみ。
sotoiwa@worker-0:~$ ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc fq_codel state UP group default qlen 1000
link/ether 42:01:0a:f0:00:14 brd ff:ff:ff:ff:ff:ff promiscuity 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 10.240.0.20/32 scope global dynamic ens4
valid_lft 79565sec preferred_lft 79565sec
inet6 fe80::4001:aff:fef0:14/64 scope link
valid_lft forever preferred_lft forever
sotoiwa@worker-0:~$
インスタンスのメタデータからPodサブネットのCIDRを取得する。
POD_CIDR=$(curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/attributes/pod-cidr)
sotoiwa@worker-0:~$ POD_CIDR=$(curl -s -H "Metadata-Flavor: Google" \
> http://metadata.google.internal/computeMetadata/v1/instance/attributes/pod-cidr)
sotoiwa@worker-0:~$ echo $POD_CIDR
10.200.0.0/24
sotoiwa@worker-0:~$
ブリッジネットワークの設定ファイルを作成する。
cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
{
"cniVersion": "0.3.1",
"name": "bridge",
"type": "bridge",
"bridge": "cnio0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "${POD_CIDR}"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
> {
> "cniVersion": "0.3.1",
> "name": "bridge",
> "type": "bridge",
> "bridge": "cnio0",
> "isGateway": true,
> "ipMasq": true,
> "ipam": {
> "type": "host-local",
> "ranges": [
> [{"subnet": "${POD_CIDR}"}]
> ],
> "routes": [{"dst": "0.0.0.0/0"}]
> }
> }
> EOF
{
"cniVersion": "0.3.1",
"name": "bridge",
"type": "bridge",
"bridge": "cnio0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "10.200.0.0/24"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
sotoiwa@worker-0:~$
ループバックネットワークの設定ファイルを作成する。
cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
{
"cniVersion": "0.3.1",
"type": "loopback"
}
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
> {
> "cniVersion": "0.3.1",
> "type": "loopback"
> }
> EOF
{
"cniVersion": "0.3.1",
"type": "loopback"
}
sotoiwa@worker-0:~$
Configure containerd
containerdの設定をする。
(参考)
docker-containerd、docker-containerd-shim、 docker-containerd-ctr、docker-runc
gVisorを使ってdockerコンテナをより安全に利用する
ディレクトリーを作成する。
sudo mkdir -p /etc/containerd/
設定ファイルを作成する。untrustedなワークロードはgVisor(runsc)で実行する
cat << EOF | sudo tee /etc/containerd/config.toml
[plugins]
[plugins.cri.containerd]
snapshotter = "overlayfs"
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runc"
runtime_root = ""
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runsc"
runtime_root = "/run/containerd/runsc"
[plugins.cri.containerd.gvisor]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runsc"
runtime_root = "/run/containerd/runsc"
EOF
sotoiwa@worker-0:~$ cat << EOF | sudo tee /etc/containerd/config.toml
> [plugins]
> [plugins.cri.containerd]
> snapshotter = "overlayfs"
> [plugins.cri.containerd.default_runtime]
> runtime_type = "io.containerd.runtime.v1.linux"
> runtime_engine = "/usr/local/bin/runc"
> runtime_root = ""
> [plugins.cri.containerd.untrusted_workload_runtime]
> runtime_type = "io.containerd.runtime.v1.linux"
> runtime_engine = "/usr/local/bin/runsc"
> runtime_root = "/run/containerd/runsc"
> [plugins.cri.containerd.gvisor]
> runtime_type = "io.containerd.runtime.v1.linux"
> runtime_engine = "/usr/local/bin/runsc"
> runtime_root = "/run/containerd/runsc"
> EOF
[plugins]
[plugins.cri.containerd]
snapshotter = "overlayfs"
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runc"
runtime_root = ""
[plugins.cri.containerd.untrusted_workload_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runsc"
runtime_root = "/run/containerd/runsc"
[plugins.cri.containerd.gvisor]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runsc"
runtime_root = "/run/containerd/runsc"
sotoiwa@worker-0:~$
containerd.service
のSystemdユニットファイルを作成する。
cat <<EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /etc/systemd/system/containerd.service
> [Unit]
> Description=containerd container runtime
> Documentation=https://containerd.io
> After=network.target
>
> [Service]
> ExecStartPre=/sbin/modprobe overlay
> ExecStart=/bin/containerd
> Restart=always
> RestartSec=5
> Delegate=yes
> KillMode=process
> OOMScoreAdjust=-999
> LimitNOFILE=1048576
> LimitNPROC=infinity
> LimitCORE=infinity
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
sotoiwa@worker-0:~$
Configure the Kubelet
Kubeletが使用する秘密鍵と証明書とkubeconfingを/var/lib/kubelet/
に配置する。
{
sudo mv ${HOSTNAME}-key.pem ${HOSTNAME}.pem /var/lib/kubelet/
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
sudo mv ca.pem /var/lib/kubernetes/
}
Kubeletの設定フィルkubelet-config.yaml
を作成する。
-
clusterDNS
として10.32.0.10
を指定している -
podCIDR
を指定している - resolvConfは
systemd-resolved
環境でのループを避けるための設定
cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
- "10.32.0.10"
podCIDR: "${POD_CIDR}"
resolvConf: "/run/systemd/resolve/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/${HOSTNAME}.pem"
tlsPrivateKeyFile: "/var/lib/kubelet/${HOSTNAME}-key.pem"
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
> kind: KubeletConfiguration
> apiVersion: kubelet.config.k8s.io/v1beta1
> authentication:
> anonymous:
> enabled: false
> webhook:
> enabled: true
> x509:
> clientCAFile: "/var/lib/kubernetes/ca.pem"
> authorization:
> mode: Webhook
> clusterDomain: "cluster.local"
> clusterDNS:
> - "10.32.0.10"
> podCIDR: "${POD_CIDR}"
> resolvConf: "/run/systemd/resolve/resolv.conf"
> runtimeRequestTimeout: "15m"
> tlsCertFile: "/var/lib/kubelet/${HOSTNAME}.pem"
> tlsPrivateKeyFile: "/var/lib/kubelet/${HOSTNAME}-key.pem"
> EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
- "10.32.0.10"
podCIDR: "10.200.0.0/24"
resolvConf: "/run/systemd/resolve/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/worker-0.pem"
tlsPrivateKeyFile: "/var/lib/kubelet/worker-0-key.pem"
sotoiwa@worker-0:~$
kubelet.service
のSystemdユニットファイルを作成する。
(参考)
kubelet
cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--config=/var/lib/kubelet/kubelet-config.yaml \\
--container-runtime=remote \\
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
--image-pull-progress-deadline=2m \\
--kubeconfig=/var/lib/kubelet/kubeconfig \\
--network-plugin=cni \\
--register-node=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
> [Unit]
> Description=Kubernetes Kubelet
> Documentation=https://github.com/kubernetes/kubernetes
> After=containerd.service
> Requires=containerd.service
>
> [Service]
> ExecStart=/usr/local/bin/kubelet \\
> --config=/var/lib/kubelet/kubelet-config.yaml \\
> --container-runtime=remote \\
> --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
> --image-pull-progress-deadline=2m \\
> --kubeconfig=/var/lib/kubelet/kubeconfig \\
> --network-plugin=cni \\
> --register-node=true \\
> --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \
--config=/var/lib/kubelet/kubelet-config.yaml \
--container-runtime=remote \
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \
--image-pull-progress-deadline=2m \
--kubeconfig=/var/lib/kubelet/kubeconfig \
--network-plugin=cni \
--register-node=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@worker-0:~$
Configure the Kubernetes Proxy
Kube Proxyが使用するkubeconfigを配置する。
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
kube-proxy-config.yaml
設定ファイルを作成する。
cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml
> kind: KubeProxyConfiguration
> apiVersion: kubeproxy.config.k8s.io/v1alpha1
> clientConnection:
> kubeconfig: "/var/lib/kube-proxy/kubeconfig"
> mode: "iptables"
> clusterCIDR: "10.200.0.0/16"
> EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
sotoiwa@worker-0:~$
kube-proxy.service
のSystemdユニットファイルを作成する。
(参考)
kube-proxy
cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sotoiwa@worker-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service
> [Unit]
> Description=Kubernetes Kube Proxy
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-proxy \\
> --config=/var/lib/kube-proxy/kube-proxy-config.yaml
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sotoiwa@worker-0:~$
Start the Worker Services
サービスを起動する。
{
sudo systemctl daemon-reload
sudo systemctl enable containerd kubelet kube-proxy
sudo systemctl start containerd kubelet kube-proxy
}
サービスのステータスを確認する。
sudo systemctl status containerd kubelet kube-proxy
Verification
Masterノードでkubectlコマンドを実行する。
gcloud compute ssh controller-0 \
--command "kubectl get nodes --kubeconfig admin.kubeconfig"
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ gcloud compute ssh controller-0 \
> --command "kubectl get nodes --kubeconfig admin.kubeconfig"
NAME STATUS ROLES AGE VERSION
worker-0 Ready <none> 6m29s v1.12.0
worker-1 Ready <none> 6m22s v1.12.0
worker-2 Ready <none> 6m19s v1.12.0
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Configuring kubectl for Remote Access
このLandでは作業用PCからkubectlが実行できるようにする。
The Admin Kubernetes Configuration File
API Serverへの接続には外部公開用のIPアドレスを使用する。
{
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443
kubectl config set-credentials admin \
--client-certificate=admin.pem \
--client-key=admin-key.pem
kubectl config set-context kubernetes-the-hard-way \
--cluster=kubernetes-the-hard-way \
--user=admin
kubectl config use-context kubernetes-the-hard-way
}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ {
> KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
> --region $(gcloud config get-value compute/region) \
> --format 'value(address)')
>
> kubectl config set-cluster kubernetes-the-hard-way \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443
>
> kubectl config set-credentials admin \
> --client-certificate=admin.pem \
> --client-key=admin-key.pem
>
> kubectl config set-context kubernetes-the-hard-way \
> --cluster=kubernetes-the-hard-way \
> --user=admin
>
> kubectl config use-context kubernetes-the-hard-way
> }
Cluster "kubernetes-the-hard-way" set.
User "admin" set.
Context "kubernetes-the-hard-way" created.
Switched to context "kubernetes-the-hard-way".
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Verification
作業用PCでkubectl
コマンドが実行できることを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
worker-0 Ready <none> 9m11s v1.12.0
worker-1 Ready <none> 9m4s v1.12.0
worker-2 Ready <none> 9m1s v1.12.0
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Provisioning Pod Network Routes
このLabではGCPのルーティングルールを作成し、ノードをまたいだPod間の通信ができるようにする。
The Routing Table
インスタンスのIPとメタデータに保存したPodサブネットのCIDRを確認する。
for instance in worker-0 worker-1 worker-2; do
gcloud compute instances describe ${instance} \
--format 'value[separator=" "](networkInterfaces[0].networkIP,metadata.items[0].value)'
done
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ for instance in worker-0 worker-1 worker-2; do
> gcloud compute instances describe ${instance} \
> --format 'value[separator=" "](networkInterfaces[0].networkIP,metadata.items[0].value)'
> done
10.240.0.20 10.200.0.0/24
10.240.0.21 10.200.1.0/24
10.240.0.22 10.200.2.0/24
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Routes
ルートを定義する。各Podサブネット宛のパケットを適切なノードにルーティングする。
for i in 0 1 2; do
gcloud compute routes create kubernetes-route-10-200-${i}-0-24 \
--network kubernetes-the-hard-way \
--next-hop-address 10.240.0.2${i} \
--destination-range 10.200.${i}.0/24
done
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ for i in 0 1 2; do
> gcloud compute routes create kubernetes-route-10-200-${i}-0-24 \
> --network kubernetes-the-hard-way \
> --next-hop-address 10.240.0.2${i} \
> --destination-range 10.200.${i}.0/24
> done
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/routes/kubernetes-route-10-200-0-0-24].
NAME NETWORK DEST_RANGE NEXT_HOP PRIORITY
kubernetes-route-10-200-0-0-24 kubernetes-the-hard-way 10.200.0.0/24 10.240.0.20 1000
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/routes/kubernetes-route-10-200-1-0-24].
NAME NETWORK DEST_RANGE NEXT_HOP PRIORITY
kubernetes-route-10-200-1-0-24 kubernetes-the-hard-way 10.200.1.0/24 10.240.0.21 1000
Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/routes/kubernetes-route-10-200-2-0-24].
NAME NETWORK DEST_RANGE NEXT_HOP PRIORITY
kubernetes-route-10-200-2-0-24 kubernetes-the-hard-way 10.200.2.0/24 10.240.0.22 1000
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ gcloud compute routes list --filter "network: kubernetes-the-hard-way"
NAME NETWORK DEST_RANGE NEXT_HOP PRIORITY
default-route-9b51bcf3343f23cb kubernetes-the-hard-way 10.240.0.0/24 kubernetes-the-hard-way 1000
default-route-cb67e0e6997aee57 kubernetes-the-hard-way 0.0.0.0/0 default-internet-gateway 1000
kubernetes-route-10-200-0-0-24 kubernetes-the-hard-way 10.200.0.0/24 10.240.0.20 1000
kubernetes-route-10-200-1-0-24 kubernetes-the-hard-way 10.200.1.0/24 10.240.0.21 1000
kubernetes-route-10-200-2-0-24 kubernetes-the-hard-way 10.200.2.0/24 10.240.0.22 1000
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Deploying the DNS Cluster Add-on
このLabではCoreDNSをデプロイする。
The DNS Cluster Add-on
CoreDNSをデプロイする。
kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.extensions/coredns created
service/kube-dns created
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。Serviceが10.32.0.10
というIPであるのはマニフェストにそう書いてあるから。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get pods -l k8s-app=kube-dns -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-699f8ddd77-9p52h 1/1 Running 0 30s
coredns-699f8ddd77-pnqgg 1/1 Running 0 30s
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 4d22h
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Podが稼働したノードを確認すると、CNIプラグインによってブリッジとvethができていることが確認できる。
sotoiwa@worker-0:~$ ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc fq_codel state UP group default qlen 1000
link/ether 42:01:0a:f0:00:14 brd ff:ff:ff:ff:ff:ff promiscuity 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 10.240.0.20/32 scope global dynamic ens4
valid_lft 76914sec preferred_lft 76914sec
inet6 fe80::4001:aff:fef0:14/64 scope link
valid_lft forever preferred_lft forever
3: cnio0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0a:58:0a:c8:00:01 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge forward_delay 1500 hello_time 200 max_age 2000 ageing_time 30000 stp_state 0 priority 32768 vlan_filtering 0 vlan_protocol 802.1Q bridge_id 8000.a:58:a:c8:0:1 designated_root 8000.a:58:a:c8:0:1 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer 0.00 tcn_timer 0.00 topology_change_timer 0.00 gc_timer 105.05 vlan_default_pvid 1 vlan_stats_enabled 0 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 1 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 4 mcast_hash_max 512 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3124 mcast_stats_enabled 0 mcast_igmp_version 2 mcast_mld_version 1 nf_call_iptables 0 nf_call_ip6tables 0 nf_call_arptables 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 10.200.0.1/24 scope global cnio0
valid_lft forever preferred_lft forever
inet6 fe80::649e:f8ff:fe02:8877/64 scope link
valid_lft forever preferred_lft forever
4: veth797b7424@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master cnio0 state UP group default
link/ether 7e:7d:3a:72:7e:d0 brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 1
veth
bridge_slave state forwarding priority 32 cost 2 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8001 port_no 0x1 designated_port 32769 designated_cost 0 designated_bridge 8000.a:58:a:c8:0:1 designated_root 8000.a:58:a:c8:0:1 hold_timer 0.00 message_age_timer 0.00 forward_delay_timer 0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on neigh_suppress off group_fwd_mask 0x0 group_fwd_mask_str 0x0 vlan_tunnel off numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet6 fe80::7c7d:3aff:fe72:7ed0/64 scope link
valid_lft forever preferred_lft forever
sotoiwa@worker-0:~$
ノードのルーティングテーブルを表示すると以下のようになっている。10.200.0.0/24
は自身のノードに割り当てているpod-cidrであり、cnio0ブリッジへルーティングしている。それ以外はPVCのデフォルトゲートウェイである10.240.0.1
へルーティングしている。
sotoiwa@worker-0:~$ ip r
default via 10.240.0.1 dev ens4 proto dhcp metric 100
10.200.0.0/24 dev cnio0 proto kernel scope link src 10.200.0.1
10.240.0.1 dev ens4 proto dhcp scope link metric 100
sotoiwa@worker-0:~$
Verification
busybox
のPodを使って動作確認する。busyboxは1.28.4以下のバージョンを使わないと上手くいかないかもしれない。
(参考)
dns can't resolve kubernetes.default and/or cluster.local
Depoymentを作成してPodを起動する。
kubectl run busybox --image=busybox:1.28 --command -- sleep 3600
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl run busybox --image=busybox:1.28 --command -- sleep 3600
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/busybox created
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Pod名を変数に入れる。
POD_NAME=$(kubectl get pods -l run=busybox -o jsonpath="{.items[0].metadata.name}")
kubernetes
が名前解決できるか確認する。
kubectl exec -ti $POD_NAME -- nslookup kubernetes
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl exec -ti $POD_NAME -- nslookup kubernetes
Server: 10.32.0.10
Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.32.0.1 kubernetes.default.svc.cluster.local
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Smoke Test
このLabではクラスターが機能しているかテストする。
Data Encryption
Secretを作成する。
kubectl create secret generic kubernetes-the-hard-way \
--from-literal="mykey=mydata"
etcdからデータを取得する。
gcloud compute ssh controller-0 \
--command "sudo ETCDCTL_API=3 etcdctl get \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem \
--cert=/etc/etcd/kubernetes.pem \
--key=/etc/etcd/kubernetes-key.pem\
/registry/secrets/default/kubernetes-the-hard-way | hexdump -C"
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ gcloud compute ssh controller-0 \
> --command "sudo ETCDCTL_API=3 etcdctl get \
> --endpoints=https://127.0.0.1:2379 \
> --cacert=/etc/etcd/ca.pem \
> --cert=/etc/etcd/kubernetes.pem \
> --key=/etc/etcd/kubernetes-key.pem\
> /registry/secrets/default/kubernetes-the-hard-way | hexdump -C"
00000000 2f 72 65 67 69 73 74 72 79 2f 73 65 63 72 65 74 |/registry/secret|
00000010 73 2f 64 65 66 61 75 6c 74 2f 6b 75 62 65 72 6e |s/default/kubern|
00000020 65 74 65 73 2d 74 68 65 2d 68 61 72 64 2d 77 61 |etes-the-hard-wa|
00000030 79 0a 6b 38 73 3a 65 6e 63 3a 61 65 73 63 62 63 |y.k8s:enc:aescbc|
00000040 3a 76 31 3a 6b 65 79 31 3a b7 94 88 06 f0 45 07 |:v1:key1:.....E.|
00000050 90 c7 3c 77 8c ee d7 66 39 d6 12 fd 25 32 27 e6 |..<w...f9...%2'.|
00000060 2e ac 0d 8b f6 24 17 13 92 bf 79 64 41 a3 0c 71 |.....$....ydA..q|
00000070 5b 67 bc 2e d9 eb 82 aa 29 eb 45 c4 d4 e7 75 35 |[g......).E...u5|
00000080 81 4c 6e 81 b2 2f a6 be 2a 7e 56 33 fc 44 10 db |.Ln../..*~V3.D..|
00000090 b4 aa 76 f6 5d 2f 3d 57 e1 e1 39 ac eb 56 6b a6 |..v.]/=W..9..Vk.|
000000a0 89 18 1c 75 fb 5e a7 7a 1f 63 cd 21 46 5b 9d 82 |...u.^.z.c.!F[..|
000000b0 bc e4 30 36 72 6e 23 4a 68 62 f6 72 57 0e b4 e7 |..06rn#Jhb.rW...|
000000c0 13 4e 99 41 8f e3 0a 68 f8 dd c4 3a 33 1b f4 b7 |.N.A...h...:3...|
000000d0 bf d8 67 45 c0 ec 72 ac 99 72 df 7f 96 70 33 d1 |..gE..r..r...p3.|
000000e0 ee 2f 76 1a cf 00 55 28 6c 0a |./v...U(l.|
000000ea
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
k8s:enc:aescbc:v1:key1
となっていることを確認する。
Deployments
Deploymentを作成する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl run nginx --image=nginx
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get pods -l run=nginx
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-4pnbv 1/1 Running 0 37s
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Port Forwarding
ポートフォワーディングできることを確認する。はじめにPod名を変数に入れる。
POD_NAME=$(kubectl get pods -l run=nginx -o jsonpath="{.items[0].metadata.name}")
ポートフォワードを行う。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl port-forward $POD_NAME 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
別ターミナルでcurlコマンドを実行し、Podに転送されることを確認する。
sotoiwa@Soto-no-MacBook-Air:~
$ curl --head http://127.0.0.1:8080
HTTP/1.1 200 OK
Server: nginx/1.15.6
Date: Tue, 13 Nov 2018 16:13:16 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 06 Nov 2018 13:32:09 GMT
Connection: keep-alive
ETag: "5be197d9-264"
Accept-Ranges: bytes
sotoiwa@Soto-no-MacBook-Air:~
$
Ctrl+Cでポートフォワーディングを終了する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl port-forward $POD_NAME 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
^Csotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Logs
ログが取得出来ることを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl logs $POD_NAME
127.0.0.1 - - [13/Nov/2018:16:13:16 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.54.0" "-"
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
exec
コンテナ内でコマンドが実行できることを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl exec -ti $POD_NAME -- nginx -v
nginx version: nginx/1.15.6
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Services
NodePort Serviceを作成する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl expose deployment nginx --port 80 --type NodePort
service/nginx exposed
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
アサインされたNodePort Serviceのポート番号を変数に入れる。
NODE_PORT=$(kubectl get svc nginx \
--output=jsonpath='{range .spec.ports[0]}{.nodePort}')
worker-0の外部IPを変数に入れる。
EXTERNAL_IP=$(gcloud compute instances describe worker-0 \
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
NodePortへのアクセスを許可するFirewall Ruleを追加する。
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-nginx-service \
--allow=tcp:${NODE_PORT} \
--network kubernetes-the-hard-way
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ gcloud compute firewall-rules create kubernetes-the-hard-way-allow-nginx-service \
> --allow=tcp:${NODE_PORT} \
> --network kubernetes-the-hard-way
Creating firewall...⠏Created [https://www.googleapis.com/compute/v1/projects/sotoiwa/global/firewalls/kubernetes-the-hard-way-allow-nginx-service].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
kubernetes-the-hard-way-allow-nginx-service kubernetes-the-hard-way INGRESS 1000 tcp:31010 False
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
curlコマンドでアクセスできることを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ curl -I http://${EXTERNAL_IP}:${NODE_PORT}
HTTP/1.1 200 OK
Server: nginx/1.15.6
Date: Tue, 13 Nov 2018 16:44:51 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 06 Nov 2018 13:32:09 GMT
Connection: keep-alive
ETag: "5be197d9-264"
Accept-Ranges: bytes
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Untrusted Workloads
UntrustedなPodをデプロイする。
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: untrusted
annotations:
io.kubernetes.cri.untrusted-workload: "true"
spec:
containers:
- name: webserver
image: gcr.io/hightowerlabs/helloworld:2.0.0
EOF
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ cat <<EOF | kubectl apply -f -
> apiVersion: v1
> kind: Pod
> metadata:
> name: untrusted
> annotations:
> io.kubernetes.cri.untrusted-workload: "true"
> spec:
> containers:
> - name: webserver
> image: gcr.io/hightowerlabs/helloworld:2.0.0
> EOF
pod/untrusted created
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Verification
Podを確認する。
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
busybox-bd8fb7cbd-6t52r 1/1 Running 0 55m 10.200.1.2 worker-1 <none>
nginx-dbddb74b8-4pnbv 1/1 Running 0 40m 10.200.1.3 worker-1 <none>
untrusted 1/1 Running 0 2m13s 10.200.0.4 worker-0 <none>
sotoiwa@Soto-no-MacBook-Air:~/workspace/kubernetes-the-hard-way
$
Podが稼働しているノード名を変数に入れる。
INSTANCE_NAME=$(kubectl get pod untrusted --output=jsonpath='{.spec.nodeName}')
Podが稼働しているノードにSSHログインする。
gcloud compute ssh ${INSTANCE_NAME}
gVisorの配下で稼働しているコンテナをリストする。
sudo runsc --root /run/containerd/runsc/k8s.io list
sotoiwa@worker-0:~$ sudo runsc --root /run/containerd/runsc/k8s.io list
I1113 16:52:58.756368 15780 x:0] ***************************
I1113 16:52:58.756586 15780 x:0] Args: [runsc --root /run/containerd/runsc/k8s.io list]
I1113 16:52:58.756667 15780 x:0] Git Revision: 50c283b9f56bb7200938d9e207355f05f79f0d17
I1113 16:52:58.756751 15780 x:0] PID: 15780
I1113 16:52:58.756821 15780 x:0] UID: 0, GID: 0
I1113 16:52:58.756890 15780 x:0] Configuration:
I1113 16:52:58.756947 15780 x:0] RootDir: /run/containerd/runsc/k8s.io
I1113 16:52:58.757071 15780 x:0] Platform: ptrace
I1113 16:52:58.757210 15780 x:0] FileAccess: exclusive, overlay: false
I1113 16:52:58.757337 15780 x:0] Network: sandbox, logging: false
I1113 16:52:58.757494 15780 x:0] Strace: false, max size: 1024, syscalls: []
I1113 16:52:58.757617 15780 x:0] ***************************
ID PID STATUS BUNDLE CREATED OWNER
a835bf9486cc50f733ad547709d7da081d3188d5604ef92aba328cad748a29f5 15140 running /run/containerd/io.containerd.runtime.v1.linux/k8s.io/a835bf9486cc50f733ad547709d7da081d3188d5604ef92aba328cad748a29f5 0001-01-01T00:00:00Z
eb020a9beed26c2541f07af8bb35889297aceb4d44fe5b4903de7e63627fd0b2 15060 running /run/containerd/io.containerd.runtime.v1.linux/k8s.io/eb020a9beed26c2541f07af8bb35889297aceb4d44fe5b4903de7e63627fd0b2 0001-01-01T00:00:00Z
I1113 16:52:58.761825 15780 x:0] Exiting with status: 0
sotoiwa@worker-0:~$
untrusted
PodのIPを取得する。
POD_ID=$(sudo crictl -r unix:///var/run/containerd/containerd.sock \
pods --name untrusted -q)
untrusted
Podの中で稼働しているwebserver
コンテナのIDを取得する。
CONTAINER_ID=$(sudo crictl -r unix:///var/run/containerd/containerd.sock \
ps -p ${POD_ID} -q)
webserver
コンテナの中で稼働しているプロセスを表示する。
sudo runsc --root /run/containerd/runsc/k8s.io ps ${CONTAINER_ID}
sotoiwa@worker-0:~$ sudo runsc --root /run/containerd/runsc/k8s.io ps ${CONTAINER_ID}
I1113 16:54:30.817005 15909 x:0] ***************************
I1113 16:54:30.817191 15909 x:0] Args: [runsc --root /run/containerd/runsc/k8s.io ps a835bf9486cc50f733ad547709d7da081d3188d5604ef92aba328cad748a29f5]
I1113 16:54:30.817265 15909 x:0] Git Revision: 50c283b9f56bb7200938d9e207355f05f79f0d17
I1113 16:54:30.817344 15909 x:0] PID: 15909
I1113 16:54:30.817410 15909 x:0] UID: 0, GID: 0
I1113 16:54:30.817475 15909 x:0] Configuration:
I1113 16:54:30.817528 15909 x:0] RootDir: /run/containerd/runsc/k8s.io
I1113 16:54:30.817651 15909 x:0] Platform: ptrace
I1113 16:54:30.817837 15909 x:0] FileAccess: exclusive, overlay: false
I1113 16:54:30.817960 15909 x:0] Network: sandbox, logging: false
I1113 16:54:30.818085 15909 x:0] Strace: false, max size: 1024, syscalls: []
I1113 16:54:30.818351 15909 x:0] ***************************
UID PID PPID C STIME TIME CMD
0 1 0 0 16:49 0s app
I1113 16:54:30.820659 15909 x:0] Exiting with status: 0
sotoiwa@worker-0:~$
Cleaning Up
このLabでは作成したGCP上のリソースを削除する。
Compute Instances
インスタンスを削除する。
gcloud -q compute instances delete \
controller-0 controller-1 controller-2 \
worker-0 worker-1 worker-2
Networking
外部ロードバランサーを削除する。
{
gcloud -q compute forwarding-rules delete kubernetes-forwarding-rule \
--region $(gcloud config get-value compute/region)
gcloud -q compute target-pools delete kubernetes-target-pool
gcloud -q compute http-health-checks delete kubernetes
gcloud -q compute addresses delete kubernetes-the-hard-way
}
Filewall Ruleを削除する。
gcloud -q compute firewall-rules delete \
kubernetes-the-hard-way-allow-nginx-service \
kubernetes-the-hard-way-allow-internal \
kubernetes-the-hard-way-allow-external \
kubernetes-the-hard-way-allow-health-check
VPCネットワークを削除する。
{
gcloud -q compute routes delete \
kubernetes-route-10-200-0-0-24 \
kubernetes-route-10-200-1-0-24 \
kubernetes-route-10-200-2-0-24
gcloud -q compute networks subnets delete kubernetes
gcloud -q compute networks delete kubernetes-the-hard-way
}