Kubenews #29
2021-08-20
Encrypt your Kubernetes Secrets with Mozilla SOPS (click here to source)
Kubernetes Secretsは、base64で暗号化されていて、簡単に複合化できてしまう。 そのソリューションとして、Mozilla SOPSがある。
・特徴
以下のようなSolutionと連携が可能
この記事では、Azureに関しての例が書かれており、Azure Service Principal (SP) を使うことを推奨しています。
- Provision an Azure Service Principal (SP)
# create a service principal az ad sp create-for-rbac -n sp-sops-keyvault -o json # { # "appId": "00000000-0000-0000-000000000000", # "displayName": "http://sp-sops-keyvault", # "name": "http://sp-sops-keyvault", # "password": "00000000-0000-0000-000000000000", # "tenant": "<your_tenant_identifier> # } export AZURE_CLIENT_ID=<appId> export AZURE_CLIENT_SECRET=<password> export AZURE_TENANT_ID=<tenant>
- Provisioning an Azure Key Vault instance
# create a new Resource Group az group create -n rg-sops-sample -l germanywestcentral # create a Key Vault instance az keyvault create -n kv-sops-sample \ -g rg-sops-sample \ -l germanywestcentral # create an access policy for the SP az keyvault set-policy -n kv-sops-sample \ -g rg-sops-sample \ --spn $AZURE_CLIENT_ID \ --key-permissions encrypt decrypt
- Create a key in Azure Key Vault for encryption & decryption
# create an key for encryption / decryption az keyvault key create -n sops-sample-key \ --vault-name kv-sops-sample \ --ops encrypt decrypt \ --protection software # read and store key identifier export KEY_ID=$(az keyvault key show -n sops-sample-key \ --vault-name kv-sops-sample \ --query key.kid -o tsv)
- Install Mozilla SOPS
# download sops cli for macOS curl -O -L -C - https://github.com/mozilla/sops/releases/download/v3.7.1/sops-v3.7.1.darwin # move and rename the cli to /usr/bin sudo mv sops-v3.7.1.darwin /usr/bin/sops # make it executable sudo chmod +x /usr/bin/sops
- Encrypt Kubernetes Secrets
まず、Sercretを作成します。
# create the Kubernetes secret kubectl create secret generic demo \ --from-literal mysecret=secret_value \ -o yaml \ --dry-run=client > secret.encoded.yml # print the contents of secret.encoded.yml cat secret.encoded.yml # apiVersion: v1 # data: # mysecret: c2VjcmV0X3ZhbHVl # kind: Secret # metadata: # creationTimestamp: null # name: demo
sopsコマンドを用いて、暗号化します。
# encrypt secret.encoded.yml using SOPS sops --encrypt --encrypted-regex '^(data|stringData)$' \ --azure-kv $KEY_ID secret.encoded.yml > secret.encrypted.yml # print the contents of secret.encrypted.yml cat secret.encrypted.yml # apiVersion: v1 # data: # mysecret: ENC[AES256_GCM,data:gz/WAjWte3bCnNm6e+G4ow==,iv:VB4pAv833tDdD4n76h4CqEZNpGdwA3V1QGWp7PK/Jfc=,tag:CcUy3rti4XcWArmHANVS8Q==,type:str] # kind: Secret # metadata: # creationTimestamp: null # name: demo # sops: # kms: [] # gcp_kms: [] # azure_kv: # - vault_url: https://kv-sops-sample.vault.azure.net # name: sops-sample-key # version: ee44c0c0cc9e4620aa4f4c86c4942047 # created_at: "2021-08-02T20:55:40Z" # enc: EjszDACgiDP8rW3wzs-7fAmFzlAhCq0-R9YlA9cuPcq78EXEeNTC8OnlSdXQAGdGrgE9oylu1HKZa4RB9GxzzVDav8uNVPp67NPmC4-teeA5iRE4jqlp1An6sG6CpkZGcAmKWpfj_DEWecqrNGWSLTA2hI_HKwG5xNkFh9Myik6732W-XL65IFqgepcFrNIzeHetznO0j1iISNXqMeJjeCnZ6Qq0jcXUMIfQnXjAllKfjSukiT3A3GlWxP0j50Z328t-JHi5RowYHT-hC8FDOdR_U95sqnFd27RgEXmbDIU6IGvP3vmCiZJz4YQCPXaGhySvFY6qCEoCbCSC4RaoWw # hc_vault: [] # age: [] # lastmodified: "2021-08-02T20:55:41Z" # mac: ENC[AES256_GCM,data:AmKRnzoImfIzPa3JBcuxUKRrse5uZwJGukpLj1wxed3R7lsUN+QAV1+WkfNyeMoW5C3ek7j20Xpbvzi+MgP8zcQOwWSwA79Svgz3hKMn9eTRTfgU+4jYezIIHCwkv61MTN8RGW5AhOInYP8oRPW3zKD+SbBO/Jeu7SC+/oVn07I=,iv:S4Th+0quL84lhJtA/lugEv+iLc+WhWEYPSlXGWKhd/M=,tag:CUGg8+UM7gNSzfjJx1Ua1w==,type:str] # pgp: [] # encrypted_regex: ^(data|stringData)$ # version: 3.7.1 # delete encoded version of the secret rm secret.encoded.yml # add encrypted secret to source control and commit it git add secret.encrypted.yml git commit -m 'chore: add encrypted secret'
- Decrypt Kubernetes Secrets for deployment
sopsコマンドを用いて複合化ができます。
# decrypt and deploy the secret sops --decrypt secret.encrypted.yml | kubectl apply -f -
- Deploy an echo server to Kubernetes
いつものSecret同様、Pod等から参照が可能です。
apiVersion: v1 kind: Pod metadata: name: echo labels: app: echo spec: containers: - image: thorstenhans/env-via-http:0.0.1 name: main ports: - containerPort: 5000 protocol: TCP envFrom: - secretRef: name: demo optional: true resources: requests: cpu: 50m memory: 32Mi limits: cpu: 100m memory: 48Mi
Implementing traffic policies in Kubernetes (click here to source)
Kumaを使用したKubernetesのトラフィックポリシーの設計について
2つのバックエンドサービスは外部ネットワークから分離した状態で、ある1つのサービスからの通信を許可したい場合、以下のようなポリシーを適用できる。
cat <<EOF | kumactl apply -f - type: TrafficPermission name: api-to-backends mesh: default sources: - match: service: 'publicAPI' destinations: - match: service: 'backend1' - match: service: 'backend2' EOF
How to Run HAProxy with Docker (click here to source)
Dockerの実行によるパフォーマンスへの影響
Dockerを使用すると、ホストへのブリッジネットワークを作成することで、コンテナー内で実行されているサービスにアクセスできます。
よって、コンテナのローカルネットワークとホストのブリッジネットワーク間でネットワークアドレス変換(NAT)をするため、遅延が発生します。
前に引用した同じIBMの調査では、DockerのNATによって、クライアントからの100バイトの要求とアプリケーションからの200バイトの応答のレイテンシーが約35 µsから70 µsに倍増されたらしい。
非常に低いレイテンシが必要な場合は、Dockerのホストネットワーク機能の使用に切り替えることで、コンテナはホストと同じネットワークを共有できるため、NATの必要性がなくなります。
Dockerを実行する際のセキュリティに関する考慮事項
HAProxyは、80や443などの制限されたTCPポートにバインドする必要があるため、rootアクセスが必要です。
ただし、起動が完了すると、root権限が削除され、非特権ユーザーとして実行されます。
DockerでHAProxyを実行する
3つのアプリケーションを動かします。
$ sudo docker network create --driver=bridge mynetwork $ sudo docker run -d \ --name web1 --net mynetwork jmalloc/echo-server:latest $ sudo docker run -d \ --name web2 --net mynetwork jmalloc/echo-server:latest $ sudo docker run -d \ --name web3 --net mynetwork jmalloc/echo-server:latest $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 98216bb8c5ff jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web3 ae6accc111d9 jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web2 554fafbc2b3b jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web1
HAProxyロードバランサーを介してこれらのコンテナーにトラフィックを中継できるよう、現在のディレクトリにhaproxy.cfgという名前のファイルを作成し、それに以下を追加します。
global stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners log stdout format raw local0 info defaults mode http timeout client 10s timeout connect 5s timeout server 10s timeout http-request 10s log global frontend stats bind *:8404 stats enable stats uri / stats refresh 10s frontend myfrontend bind :80 default_backend webservers backend webservers server s1 web1:8080 check server s2 web2:8080 check server s3 web3:8080 check
最初のフロントエンドはポート8404でリッスンし、HAProxy Statsダッシュボードを有効にします。このダッシュボードには、ロードバランサーに関するライブ統計が表示されます。
もう一方のフロントエンドはポート80でリッスンし、Webサーバーのバックエンドにリストされている3つのWebアプリケーションの1つに要求をディスパッチします。
以下のコマンドで、HAProxyを作成します。
$ sudo docker run -d \ --name haproxy \ --net mynetwork \ -v $(pwd):/usr/local/etc/haproxy:ro \ -p 80:80 \ -p 8404:8404 \ haproxytech/haproxy-alpine:2.4
Kubernetes CI/CD with Tekton and ArgoCD (click here to source)
TektonとArgoCDを使用してKubernetesでCI / CDプロセスを構成する方法が書かれています。
AWS App MeshとIstioの比較 (click here to source)
AWSが提供するサービスメッシュのマネージドサービスであるApp MeshとIstioの比較について書かれています。
比較項目としてはいかがあります。
OPA GatekeeperによるKubernetesセキュリティの歩き方 (click here to source)
以下のような、運用をしていく中でこういったことに注意したなどの事例を基に説明されている。
ConstraintとConstraintTemplateを何も考えずにクラスタに適用してしまうと、意図していないリソースまでも影響を受ける可能性があります。 enforcementAction: dryrunを使用し、一定期間様子を見ながら適用することをおすすめします