k8s の検証を行う際にマニュフェスト(YAML)を作らずに Pod や Deployment、Service を作る方法を知っておくと良さそうだと思ったのでメモしておく。(あとは CKD/CKAD 取得を目指す場合にも知っておくと良さそう)
具体的には以下のコマンドについて説明する
- kubectl run
- kubectl create
- kubectl scale
- kubectl expose
環境
- AWS 環境を利用(EKS)
- k8s は v1.14.9
-
k
をkubectl
の alias として指定(``)
参考記事
kubectl run/create/expose のススメ
Pod をサクッと作りたい(kubectl run コマンド)
kubectl run
コマンドにより可能。
作成できるリソースとしてkubectl runの generator
のページを見ると以下がリンクされている。
ここに Pod
はないが、generator
のデフォルトが run-pod/v1
であり、以下のように指定することで作成出来る
$kubectl run nginx --image=nginx --generator=run-pod/v1
pod/nginx created
$ k get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 5s
なお、デフォルトなので設定しなくても良いのではと思ったが、指定しないと以下のようになり、Pod ではなく、Deployment が作成される模様
$kubectl run nginx --image=nginx
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created
kubectl run --help
を見ると Create and run a particular image, possibly replicated
と書いてあるので、なるべく Pod 単独では起動させないようしたいという感じな気がする。
後述するが kubectl create
で Deploymnet 及び Pod などの作成は可能であるが、指定出来るオプションが少なかったので検証という意味では kubectl run
を覚えておいたほうが良い気がする。
また、いつも --generator=run-pod/v1
オプションの run-pod/v1
を忘れてしまっていたのだが、--restart=Never
オプションを付与すれば Pod のマニュフェストファイル作成となるのでこちらの方が楽(こちらは --help
に記載がある)
作った Pod の設定を変更したい
kubectl edit
すればできる(本当はファイルを作ってや立ったほうが良い)
例えば以下で Pod の設定を変更できる
$k edit pod nginx
YAML ファイルを作りたい
--dry-run -o yaml
を指定する事で作ることができる
先程の例でやってみる
$kubectl run nginx --image=nginx --generator=run-pod/v1 --dry-run -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
こんな感じで出来る。
なのでこれをリダイレクトさせてファイルを作ればいい。
# テンプレートを作成
$kubectl run nginx --image=nginx --generator=run-pod/v1 --dry-run -o yaml > nginx.yaml
# 編集
$vi nginx.yaml
# apply
$ kubectl apply -f nginx.yaml
pod/nginx created
$ k get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9s
コンテナで任意のコマンドを実行したい
「Pod から nslookup を実行したい」などのようなワンライナーの確認をしたい時は以下のようにする。
$kubectl run -i busybox --image=busybox --generator=run-pod/v1 --rm --restart=Never --command -- nslookup google.co.jp
If you don't see a command prompt, try pressing enter.
Server: 10.100.0.10
Address: 10.100.0.10:53
Non-authoritative answer:
Name: google.co.jp
Address: 2404:6800:4004:81d::2003
*** Can't find google.co.jp: No answer
pod "busybox" deleted
関係するオプションなどは以下
-
-i
オプションを指定してフォアグラウンドで実行 -
--rm
オプションを指定してコンテナが終了したら Pod も削除する -
--restart=Never
オプションを指定して失敗した場合でもリスタートさせないようにする(デフォルトは Always になっている) -
--command -- <cmd> <arg1> ... <argN>
という書式のオプションでコマンド及び引数を指定
こんな感じで指定することも良くする
kubectl run sleep-pod --image=busybox:1.28 -- /bin/sh -c "sleep 4800"
コンテナ内で shell を起動したい
コンテナでワンライナーではない確認をしたい場合に shell を起動したいということがある。
上記については以下のようにすれば良い
$kubectl run -i --tty busybox --image=busybox --generator=run-pod/v1 --rm -- sh
If you don't see a command prompt, try pressing enter.
/ # exit
Session ended, resume using 'kubectl attach busybox -c busybox -i -t' command when the pod is running
pod "busybox" deleted
なお、kubectl Cheat Sheet のコマンドの通りだと shell の起動はできるがメッセージが出たり、あとで deployment の削除も必要で面倒。
# kubectl Cheat Sheet の通りのコマンド.exit コマンドで shell は終了している
$ kubectl run -i --tty busybox --image=busybox -- sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # ls
bin dev etc home proc root sys tmp usr var
/ # exit
Session ended, resume using 'kubectl attach busybox-c8f8564d4-thjfg -c busybox -i -t' command when the pod is running
# deployment が残っているので削除が必要
$ k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
busybox 1/1 1 1 80s
$k delete
deployments busybox
deployment.extensions "busybox" deleted
最初に示したコマンドと比較すると 最初のコマンドでは --generator
オプションを指定する事で Pod の起動であることを指定して deployment の作成を防ぎ、--rm
オプションを指定することで shell が終了したタイミングで Pod も削除するようにしている。
その他例が見たい
kubectl run --help
コマンドでいくつかサンプルが見えたのでこれを見ておくと良いだろう。
指定可能なオプションの確認もこちらの参照が有効。
kubectl Cheat Sheetにもいくつかのサンプルあり。
少しだけ抜粋
kubectl run -i --tty busybox --image=busybox -- sh # Run pod as interactive shell
kubectl run nginx --image=nginx --restart=Never -n
mynamespace # Run pod nginx in a specific namespace
kubectl run nginx --image=nginx --restart=Never # Run pod nginx and write its spec into a file called pod.yaml
--dry-run -o yaml > pod.yaml
Pod 以外のリソースをサクッと作りたい(kubectl create )
kubectl create
コマンドを使う。
具体的に作れるリソース郡は以下に記載あり。
clusterrole Create a ClusterRole.
clusterrolebinding Create a ClusterRoleBinding for a particular ClusterRole.
configmap Create a configmap from a local file, directory or literal value.
cronjob Create a cronjob with the specified name.
deployment Create a deployment with the specified name.
job Create a job with the specified name.
namespace Create a namespace with the specified name.
poddisruptionbudget Create a pod disruption budget with the specified name.
priorityclass Create a priorityclass with the specified name.
quota Create a quota with the specified name.
role Create a role with single rule.
rolebinding Create a RoleBinding for a particular Role or ClusterRole.
secret Create a secret using specified subcommand.
service Create a service using specified subcommand.
serviceaccount Create a service account with the specified name.
なお、service
については後述する kubectl expose
コマンドを使うほうが指定出来るオプションも多い。
試しに deployment を作ってみる。
$kubectl create deployment nginx --image=nginx
$k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 6s
こんな感じで作れる。
kubectl run
コマンドと同様にテンプレートの雛形を作る事も可能。
その時は同じように --dry-run -o yaml
オプションを付与する。
$k create deployment nginx --dry-run --image nginx -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
あとはこれをリダイレクトさせればファイルとして作成出来る。
なお、--help
オプションで指定可能な詳細が分かるが、kubectl runコマンドと比較すると指定可能なオプションが全然ない。
$k create deployment --help
Create a deployment with the specified name.
Aliases:
deployment, deploy
Examples:
# Create a new deployment named my-dep that runs the busybox image.
kubectl create deployment my-dep --image=busybox
Options:
--allow-missing-template-keys=true: If true, ignore any errors in
templates when a field or map key is missing in the template. Only applies to
golang and jsonpath output formats.
--dry-run=false: If true, only print the object that would be sent,
without sending it.
--generator='': The name of the API generator to use.
--image=[]: Image name to run.
-o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
--save-config=false: If true, the configuration of current object will be
saved in its annotation. Otherwise, the annotation will be unchanged. This flag
is useful when you want to perform kubectl apply on this object in the future.
--template='': Template string or path to template file to use when
-o=go-template, -o=go-template-file. The template format is golang templates
[http://golang.org/pkg/text/template/#pkg-overview].
--validate=true: If true, use a schema to validate the input before
sending it
Usage:
kubectl create deployment NAME --image=image [--dry-run] [options]
Use "kubectl options" for a list of global command-line options (applies to all
commands).
細かい指定をする場合の検証(env や limit など)の場合には kubectl run
を使うほうが良さそう。
ServiceAccount/Role/RoleBinding の検証時に kubectl create
コマンドが役にたった。
以下が検証時のページ
ServiceAccount を作成し、Pod から kubectl get pods
をやってみた時のメモ
ReplicaSet のスケールイン・スケールアウトをさくっと確認したい(kubectl scale コマンド)
ReplicaSet の数を変えてスケールイン・スケールアウトの際のテストをする時には kubectl scale
コマンドが便利。
実際にやってみる
# deploymnet を作って ReplicaSet を作る
$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
# デフォルトでは Pod 数は1
$k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 31s
# kubectl scale コマンドで数を変える
$k scale deployment nginx --replicas=5
deployment.extensions/nginx scaled
# Pod 数が5になっている
$ k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 5/5 5 5 2m53s
# 同じようにスケールインさせる
$k scale deployment nginx --replicas=1
deployment.extensions/nginx scaled
$k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 3m51s
Service を作って Pod へのアクセスをサクッと確認したい(kubectl expose コマンド)
Service を使ってアプリケーションを公開できるが、kubectl expose
コマンドを使うことでこちらも可能。
--type
オプションを使うことでいくつかのサービスが作成できる。
- ClusterIP->クラスター内の内部 IP で Service を公開する。Service はクラスター内からのみ到達可能
- NodePort-> NAT を使用して、クラスター内の選択された各ノードの同じポートに Service を公開する。:を使用してクラスターの外部から Service にアクセスできるようにする
- LoadBalancer->現在のクラウドに外部ロードバランサを作成し(サポートされている場合)、Serviceに固定の外部IPを割り当てる
今回は上記3種類で確認する。
ClusterIP
以下の記事を参考にやってみる
Amazon EKS クラスターで実行されている Kubernetes Services を公開するにはどうすればよいですか?
ClusterIP のため、確認は同じクラスターの Pod からアクセスしてみる。
# Pod を作成
$kubectl run nginx --replicas=2 --labels='app=nginx' --image=nginx --port=80
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created
# Pod が Running であることと IP を確認
$kubectl get pods -l 'app=nginx' -o wide | awk {'print $1" " $3 " " $6'} | column -t
NAME STATUS IP
nginx-56db997f77-vvbjp Running 192.168.69.238
nginx-56db997f77-wm5ql Running 192.168.42.52
# kubectl expose コマンドで ClusterIP のサービスを作成。deployment の nginx を指定してこちらを公開するようにしている
$kubectl expose deployment nginx --type=ClusterIP --name=nginx-service
service/nginx-service exposed
# サービスの情報を確認。アクセスするための IP は Pod の IP とは異なる
$ k get service nginx-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.100.223.112 <none> 80/TCP 13s
$k describe service nginx-service
Name: nginx-service
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP: 10.100.223.112
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 192.168.42.52:80,192.168.69.238:80
Session Affinity: None
Events: <none>
# 以下でアクセス出来てレスポンスが返却される
$kubectl run -i testpod --image=centos:6 --generator=run-pod/v1 --restart=Never --rm --command -- curl -s http://nginx-service
# <service-name>.<namespace>.svc.cluster.local によって名前解決出来る。IP の IP アドレスが返却される
$kubectl run -i testpod --image=centos:6 --generator=run-pod/v1 --restart=Never --rm --command -- dig +short nginx-service.default.svc.cluster.local
10.100.223.112
pod "testpod" deleted
NodePort
以下の記事を参考にやってみる
Serviceを利用したクラスター内のアプリケーションへのアクセス
Amazon EKS クラスターで実行されている Kubernetes Services を公開するにはどうすればよいですか?
NodePort を使ってアプリケーションを外部からアクセス出来ることを確認する。
# hello world アプリをデプロイする。これによって deployment が作成される
$kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/hello-world created
$k get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
hello-world 2/2 2 2 26s
# NodePort のサービスを kubectl expose コマンドで作成する
$kubectl expose deployment hello-world --type=NodePort --name=example-service
service/example-service exposed
# service の情報を確認。以下の場合、NodePort では TCP 32425 ポートでアクセスする
$ kubectl describe services example-service
Name: example-service
Namespace: default
Labels: run=load-balancer-example
Annotations: <none>
Selector: run=load-balancer-example
Type: NodePort
IP: 10.100.88.21
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 32425/TCP
Endpoints: 192.168.57.115:8080,192.168.71.173:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
# ノードの PublicIP を確認する
$kubectl get nodes -o wide | awk {'print $1" " $2 " " $7'} | column -t
NAME STATUS EXTERNAL-IP
ip-192-168-48-33.ap-northeast-1.compute.internal Ready 52.192.84.154
ip-192-168-74-169.ap-northeast-1.compute.internal Ready 54.250.97.77
# <PublicIP>:<NodePort>でアクセスしてみる
$curl http://52.192.84.154:32425
Hello Kubernetes!
なお、curl
を実行するクライアントから Node のポートまでの接続は可能である必要があるので注意(上記例であればクライアントから TCP 32425 番ポートでの接続が可能である前提)
例えば AWS であればセキュリティグループのインバウンドルールが許可されている必要がある。
LoadBalancer
以下の記事を参考にやってみる
クラスター内のアプリケーションにアクセスするために外部IPアドレスを公開する
Amazon EKS クラスターで実行されている Kubernetes Services を公開するにはどうすればよいですか?
LodBalancer を使う場合、外部ロードバランサが使われるが、今回の環境は AWS 環境のため、ELB が作成され、こちらを経由してのアクセスの確認をしてみる。
# hello world アプリをデプロイ
$kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
# 外部公開のために LoadBalancer タイプのサービスを作成
$kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
# サービスの情報を確認
$kubectl get services my-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.100.79.155 a8731078a9e2111ea80d80aafc37fdac-244
533548.ap-northeast-1.elb.amazonaws.com 8080:31474/TCP 38s
$kubectl describe services my-service
Name: my-service
Namespace: default
Labels: run=load-balancer-example
Annotations: <none>
Selector: run=load-balancer-example
Type: LoadBalancer
IP: 10.100.79.155
LoadBalancer Ingress: a8731078a9e2111ea80d80aafc37fdac-244533548.ap-northeast-1.elb.amazonaws.com
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31474/TCP
Endpoints: 192.168.42.52:8080,192.168.81.79:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 88s service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 84s service-controller Ensured load balancer
# <LoadBalancerIngress>:<Port> でアクセス
$curl http://a8731078a9e2111ea80d80aafc37fdac-244533548.ap-northeast-1.elb.amazonaws.com:8080
Hello Kubernetes!
OK.
上記例の場合、AWS 環境のため ELB が作成され、ELB を経由してアクセスしている。