SPIREのQuickstart for Kubernetesためす
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に伝えることができる。
- 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
- ワークロードに割り当てる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コンテナを構成する。
- deploymentファイルを適用する。
$ kubectl apply -f client-deployment.yaml
deployment.apps/client created
- 実行中のPodへのシェル接続を開始する。
$ kubectl exec -it $(kubectl get pods -o=jsonpath='{.items[0].metadata.name}' \
-l app=client) -- /bin/sh
/opt/spire #
- 接続後、コンテナがソケットに接続できることを確認する。
/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
- Workloadコンテナを削除する。
$ kubectl delete deployment client
deployment.apps "client" deleted
- すべてのAgent、ServerおよびDeploymentと設定を削除する。
$ kubectl delete namespace spire
namespace "spire" deleted
- 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
Discussion