前回は、Tanzu Kubernetes Cluster に接続して、Pod を単独で起動してみました。
前回の投稿はこちら。
vSphere with Kubernetes ラボ環境構築。Part-14: Tanzu Kubernetes Cluster への接続 / Pod 起動編
しかし、Kubernetes で Pod を起動する場合には、
Deployment や StatefulSet といったリソースを利用することが一般的だと思うので、今回は Deployment リソースから Pod を作成してみます。
なお、今回の一連の手順では Kubernetes の Namespace を省略しており、「default」Namespace 作業対象にしています。
Deployment 作成を試す。(PSP エラーになるパターン)
まず、ほぼデフォルト状態の Tanzu Kubernetes Cluster に、Deployment を作成してみます。
ただし、Tanzu Kubernetes Cluster ではアドミッション コントロールと呼ばれる機能が有効化されており、
この時点での Pod 作成は失敗してしまいます。
前回の投稿でも実施したように、kubectl で Tanzu Kubernetes Cluster にログインして、
Context を切り替えておきます。
$ kubectl vsphere login --insecure-skip-tls-verify --server lab-wcp-01.go-lab.jp --tanzu-kubernetes-cluster-namespace lab-ns-02 --tanzu-kubernetes-cluster-name tkg-cluster-01
$ kubectl config use-context tkg-cluster-01
Nginx コンテナの Pod を、Deployment から起動する YAML ファイル(nginx-deploy.yml · GitHub)を用意します。
$ cat nginx-deploy.yml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: tkc-demo
spec:
replicas: 2
selector:
matchLabels:
app: tkc-demo
template:
metadata:
labels:
app: tkc-demo
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
protocol: TCP
Deployment を作成します。
$ kubectl apply -f nginx-deploy.yml
deployment.apps/tkc-demo created
Deployment では、Deployment → ReplicaSet → Pod といった順でリソースが作成されますが、
待っても Pod が起動されません。
$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 198.48.0.1 <none> 443/TCP 17d
service/supervisor ClusterIP None <none> 6443/TCP 17d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tkc-demo 0/2 0 0 61s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tkc-demo-659dff8bd 2 0 0 61s
これは、ReplicaSet を作成する時点で PodSecurityPolicy(pod security policy)に関係するエラーが発生しています。
$ kubectl describe replicasets tkc-demo-659dff8bd
Name: tkc-demo-659dff8bd
Namespace: default
Selector: app=tkc-demo,pod-template-hash=659dff8bd
Labels: app=tkc-demo
pod-template-hash=659dff8bd
Annotations: deployment.kubernetes.io/desired-replicas: 2
deployment.kubernetes.io/max-replicas: 3
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/tkc-demo
Replicas: 0 current / 2 desired
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=tkc-demo
pod-template-hash=659dff8bd
Containers:
nginx-container:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
ReplicaFailure True FailedCreate
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreate 39s (x15 over 2m1s) replicaset-controller Error creating: pods "tkc-demo-659dff8bd-" is forbidden: unable to validate against any pod security policy: []
エラーになった Deployment は、ひとまず削除しておきます。
$ kubectl delete -f nginx-deploy.yml
deployment.apps "tkc-demo" deleted
それでは、PodSecurityPolicy を使用してみます。
ドキュメントは下記のあたりです。
Tanzu Kubernetesクラスタでのポッド セキュリティ ポリシーの使用
PodSecurityPolicy(PSP)の確認。
それでは、Deployment から Pod が起動できるように、
PodSecurityPolicy(PSP)と Kubernetes のサービスアカウント(ServiceAccount)をひもづける RoleBindig を作成しておきます。
Tanzu Kubernetes Cluster には、デフォルトで PSP が2つ用意されており、
vmware-system-privileged と vmware-system-restricted が作成されています。
$ kubectl get podsecuritypolicies
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
vmware-system-privileged true * RunAsAny RunAsAny RunAsAny RunAsAny false *
vmware-system-restricted false RunAsAny MustRunAsNonRoot MustRunAs MustRunAs false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
今回は root ユーザとして Pod を起動できる vmware-system-privileged を指定します。
ちなみに、もう一つの vmware-system-restricted が指定されている状態で root で Pod 起動しようとすると、
Pod のイベントとして、下記のようなエラーが発生します。
Error: container has runAsNonRoot and image will run as root
RoleBinding の作成。
PSP を指定した RoleBinding を作成します。
下記のような YAML ファイル(tkc-rb-privileged.yml · GitHub)を用意しておきます。
- RoleBinding の名前は rb-vmware-system-privileged を指定。
- roleRef には、ClusterRole「psp:vmware-system-privileged」を指定。
- subjects には system:serviceaccounts Group(すべてのサービスアカウントが含まれる)を指定。
$ cat tkc-rb-privileged.yml
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rb-vmware-system-privileged
roleRef:
kind: ClusterRole
name: psp:vmware-system-privileged
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
roleRef で指定している ClusterRole「psp:vmware-system-privileged」では、
resourceNames に PSP「vmware-system-privileged」が指定されています。
この ClusterRole も、デフォルトで作成されているものです。
$ kubectl get clusterrole psp:vmware-system-privileged -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2020-07-30T03:36:50Z"
name: psp:vmware-system-privileged
resourceVersion: "480"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/psp%3Avmware-system-privileged
uid: 391f6160-44c8-4bcc-b776-184b17dce8d6
rules:
- apiGroups:
- policy
resourceNames:
- vmware-system-privileged
resources:
- podsecuritypolicies
verbs:
- use
それでは、RoleBindig を作成します。
$ kubectl apply -f tkc-rb-privileged.yml
rolebinding.rbac.authorization.k8s.io/rb-vmware-system-privileged created
Deployment 作成を試す。(リトライ)
あらためて、Deployment を作成します。
$ kubectl apply -f nginx-deploy.yml
deployment.apps/tkc-demo created
今度は、Deployment から Pod が起動されました。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/tkc-demo-6b459d8b8d-8hfbb 1/1 Running 0 10s
pod/tkc-demo-6b459d8b8d-q7cq5 1/1 Running 0 10s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 198.48.0.1 <none> 443/TCP 17d
service/supervisor ClusterIP None <none> 6443/TCP 17d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tkc-demo 2/2 2 2 11s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tkc-demo-6b459d8b8d 2 2 2 11s
これで、アドミッション コントロールなしの Kubernetes クラスタと同様にワークロード展開できるはずです。
また、今回は RoleBindig を作成しましたが、デモ環境などであれば
ClusterRoleBinding でクラスタ全体の設定にしてもよいと思います。
以上、vSphere with Kubernetes と Tanzu Kubernetes Cluster のラボ環境構築でした。