😎

SPIREのQuickstart for Kubernetesためす

2021/08/21に公開

Quickstart for Kubernetesを試してみたのでその時のメモを残す。
このガイドでは、KubernetesクラスタでSPIRE ServerとSPIRE Agentを実行し、SPIREにアクセスできるようにワークロードコンテナを設定する方法について解説されている。

Obtain the Required Files

以下のコマンドを実行し、クイックスタートに必要なファイルを取得する。

$ git clone https://github.com/spiffe/spire-tutorials.git
$ cd spire-tutorials/k8s/quickstart/

Configure Kubernetes Namespace for SPIRE Components

SPIRE ServerおよびSPIRE AgentがデプロイされるNamespaceを構成する。
以下のコマンドを実行してNamespaceを作成する。

$ kubectl apply -f spire-namespace.yaml
namespace/spire created

以下のコマンドを実行してspire Namespaceが表示されることを確認する。

$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   32h
kube-node-lease   Active   32h
kube-public       Active   32h
kube-system       Active   32h
spire             Active   32h

Configure SPIRE Server

Create Server Bundle Configmap, Role & ClusterRoleBinding

SPIRE Serverが機能するためには、SPIRE Agentに証明書を提供する必要がある。この証明書は、SPIRE Agentが接続を確立する際にSPIRE Serverが身元を確認するために使用される。
SPIRE AgentとSPIRE Serverが同じクラスタに存在している場合、SPIREは定期的に証明書を自動生成し、証明書の内容をConfigMapに更新するようにすることができる。そのためには、SPIRE Serverはspire NamespaceのConfigMapオブジェクトを取得したり、パッチを当てたりする機能が必要になる。
SPIRE ServerがConfigMapお読み書きできるようにするには、KubernetesのRBACに適切な権限を与えるClusterRoleを作成し、そのClusterRoleBindingを、サービスアカウントに関連づける必要がある。
以下のコマンドを実行して、SPIRE ServerのServiceAccount、ConfigMap、RoleBindingを作成する。

$ kubectl apply \
    -f server-account.yaml \
    -f spire-bundle-configmap.yaml \
    -f server-cluster-role.yaml
serviceaccount/spire-server created
configmap/spire-bundle created
clusterrole.rbac.authorization.k8s.io/spire-server-trust-role created
clusterrolebinding.rbac.authorization.k8s.io/spire-server-trust-role-binding created

Create Server Configmap

SPIRE Serverはserver-configmap.yamlで指定されたKubernetesのConfigmapで設定される。このConfigmapには、/run/spire/data/run/spire/configといったディレクトリが指定される。これらのボリュームは、コンテナのデプロイ時に配置される。
以下のコマンドを実行し、ConfigmapとStatefulsetをデプロイする。

$ kubectl apply \
    -f server-configmap.yaml \
    -f server-statefulset.yaml \
    -f server-service.yaml
configmap/spire-server created
statefulset.apps/spire-server created
service/spire-server created

これにより、spire Namespaceにspire-serverというStatefulSetが作成され、spire-server Podが起動する。

$ kubectl get statefulset --namespace spire
NAME           READY   AGE
spire-server   1/1     6m25s

$ kubectl get pods --namespace spire
NAME             READY   STATUS              RESTARTS   AGE
spire-server-0   0/1     ContainerCreating   0          22s

$ kubectl get services --namespace spire
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
spire-server   NodePort   10.100.74.158   <none>        8081:30400/TCP   8m42s

Configure and deploy the SPIRE Agent

SPIRE AgentがWorkload Attestationを実行するためのkubelet APIへの読み取りを許可するには、Kubernetes RBACに適切な権限を付与するService AccountとCluster Roleを作成し、そのClusterRoleBindingをService Accountに関連づける必要がある。

$ kubectl apply \
    -f agent-account.yaml \
    -f agent-cluster-role.yaml
serviceaccount/spire-agent created
clusterrole.rbac.authorization.k8s.io/spire-agent-cluster-role created
clusterrolebinding.rbac.authorization.k8s.io/spire-agent-cluster-role-binding created

agent-configmap.yamlでSPIRE AgentのConfigmapを作成し、各Kubernetes Worker Nodeで各Agentのインスタンを1つずつ実行するDaemonSetとしてAgentを展開する。

$ kubectl apply \
    -f agent-configmap.yaml \
    -f agent-daemonset.yaml
configmap/spire-agent created
daemonset.apps/spire-agent created

これにより、spire Namespaceにspire agentというDaemonSetが作成され、spire-serverと共にspire-agent Podが起動する。

$ kubectl get daemonset --namespace spire
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
spire-agent   1         1         1       1            1           <none>          108s

$ kubectl get pods --namespace spire
NAME                READY   STATUS    RESTARTS   AGE
spire-agent-bxh6n   1/1     Running   0          3m8s
spire-server-0      1/1     Running   0          16m

DaemonSetとして、ノード数と同じ数のspire-agent Podが表示される。

Register Workloads

SPIREがWorkloadの認証を行えるようにするためには、WorkloadをSPIRE Serverに登録する必要がある。これにより、Workloadをどのように識別するか、どのSPIFFE IDを与えるかをSPIREに伝えることができる。

  1. Nodeに割り当てるSPIFFE IDを指定し、Nodeの新規登録エントリを作成する。
$  kubectl exec -n spire spire-server-0 -- \
    /opt/spire/bin/spire-server entry create \
    -spiffeID spiffe://example.org/ns/spire/sa/spire-agent \
    -selector k8s_sat:cluster:demo-cluster \
    -selector k8s_sat:agent_ns:spire \
    -selector k8s_sat:agent_sa:spire-agent \
    -node
Entry ID         : cee5d6e5-1667-4be3-8c78-7c61e3d95fdd
SPIFFE ID        : spiffe://example.org/ns/spire/sa/spire-agent
Parent ID        : spiffe://example.org/spire/server
Revision         : 0
TTL              : default
Selector         : k8s_sat:agent_ns:spire
Selector         : k8s_sat:agent_sa:spire-agent
Selector         : k8s_sat:cluster:demo-cluster

  1. ワークロードに割り当てるSPIFFE IDを指定して、ワークロードの新登録エントリを作成する。
$ kubectl exec -n spire spire-server-0 -- \
    /opt/spire/bin/spire-server entry create \
    -spiffeID spiffe://example.org/ns/default/sa/default \
    -parentID spiffe://example.org/ns/spire/sa/spire-agent \
    -selector k8s:ns:default \
    -selector k8s:sa:default
Entry ID         : 59bda4d3-a1fd-4ba5-b5a5-71a07b92370b
SPIFFE ID        : spiffe://example.org/ns/default/sa/default
Parent ID        : spiffe://example.org/ns/spire/sa/spire-agent
Revision         : 0
TTL              : default
Selector         : k8s:ns:default
Selector         : k8s:sa:default

Configure a Workload Container to Access SPIRE

WorkloadコンテナがSPIREにアクセスするように設定する。具体的には、Workload API UNIXドメインソケットにアクセスするようにWorkloadコンテナを設定する。
client-deploymentファイルはServerとAgentに使用されるspire-k8s Dockerイメージを使用してno-opコンテナを構成する。

  1. deploymentファイルを適用する。
$ kubectl apply -f client-deployment.yaml
deployment.apps/client created
  1. 実行中のPodへのシェル接続を開始する。
$ kubectl exec -it $(kubectl get pods -o=jsonpath='{.items[0].metadata.name}' \
   -l app=client)  -- /bin/sh
/opt/spire #
  1. 接続後、コンテナがソケットに接続できることを確認する。
/opt/spire #  /opt/spire/bin/spire-agent api fetch -socketPath /run/spire/sockets/agent.sock
Received 1 svid after 100.376685ms

SPIFFE ID:		spiffe://example.org/ns/default/sa/default
SVID Valid After:	2021-06-10 16:37:29 +0000 UTC
SVID Valid Until:	2021-06-10 17:37:39 +0000 UTC
CA #1 Valid After:	2021-06-10 16:19:14 +0000 UTC
CA #1 Valid Until:	2021-06-11 16:19:24 +0000 UTC

/opt/spire #

Tear Down All Components

  1. Workloadコンテナを削除する。
$ kubectl delete deployment client
deployment.apps "client" deleted
  1. すべてのAgent、ServerおよびDeploymentと設定を削除する。
$ kubectl delete namespace spire
namespace "spire" deleted
  1. ClusterRoleおよびClusterRoleBinding設定を削除する。
$ kubectl delete clusterrole spire-server-trust-role spire-agent-cluster-role
clusterrole.rbac.authorization.k8s.io "spire-server-trust-role" deleted
clusterrole.rbac.authorization.k8s.io "spire-agent-cluster-role" deleted

$ kubectl delete clusterrolebinding spire-server-trust-role-binding spire-agent-cluster-role-binding
clusterrolebinding.rbac.authorization.k8s.io "spire-server-trust-role-binding" deleted
clusterrolebinding.rbac.authorization.k8s.io "spire-agent-cluster-role-binding" deleted

References

GitHubで編集を提案

Discussion