ksaitoの日記

日々試したことの覚え書き

kubeにdockerhubの認証情報を安全に保管する

Kubernetesで認証が必要なdocker registoryを操作するためにdocker registoryの認証情報を安全に保管する方法を検討しました。

kubernetesでdocker registoryの認証情報を設定する方法は、下記の2つがあります。

  1. kubernetes.io/basic-authbase64エンコードしたユーザ名とパスワードをsecretに設定
  2. kubernetes.io/dockerconfigjsonにローカル環境で認証済みの情報をsecretに設定

kubernetes.io/basic-authに設定する方法

kubernetes.io/basic-authに設定する場合には、下記のようなmanifestを準備します。

apiVersion: v1
kind: Secret
metadata:
  name: docker-hub-auth
  annotations:
    build.knative.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
data:
  username: # Use 'echo -n "username" | base64' to generate this string
  password: # Use 'echo -n "password" | base64' to generate this string

username:password:base64エンコードしたユーザ名、パスワードを設定してkubectl apply -f docker-hub-auth.yamlで認証情報を設定できます。

この方法では、ユーザ名、パスワードはbase64エンコードされているだけなので安全ではなく、gitにpushすることはできません。

kubernetes.io/dockerconfigjsonに設定する方法

docker loginコマンドでdocker registoryにログインすると$HOME/.docker/config.jsonに認証情報が記録されます。この情報をsecretに設定するには、下記のコマンドを実行します。

kubectl create secret generic docker-hub-auth --from-file=.dockerconfigjson=$HOME/.docker/config.json --type=kubernetes.io/dockerconfigjson

docker loginと、この手順をセットでスクリプトにすることで、安全に認証情報をkubernetesに設定することができます。

認証情報の使い方

下記のserviceaccountをデプロイします。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: docker-hub
secrets:
- name: docker-hub-auth

下記のmanifestでknative buildでビルドしたイメージをdockerhubにpushすることができます。

apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
  name: docker-build
spec:
  serviceAccountName: docker-hub
  source:
    git:
      url: https://github.com/<gitアカウント>/<gitリポジトリ>.git
      revision: master
  steps:
  - name: build-and-push
    image: gcr.io/kaniko-project/executor:v0.1.0
    args:
    - --dockerfile=/workspace/Dockerfile
    - --destination=<dockerhubユーザ>/<コンテナ名>

考察

dockerの認証情報は、ローカル環境で人手でログインした$HOME/.docker/config.jsonをsecretのkubernetes.io/dockerconfigjsonに設定するのが良さそうです。

$HOME/.docker/config.jsonには、複数のdocker registoryの認証情報が記録されています。設定時には、このファイルを一時的に退避して操作する必要があります。

従って、下記の点について留意する必要があります。

  • 設定するときに$HOME/.docker/config.jsonを退避する
  • ログイン先を間違えない

参考

knative.dev

k8sのREST API

k8sREST APIにアクセスしてみました。

環境は、k3sを使っています。

defaultネームスペースのserviceaccountのトークンを取得してREST APIにアクセスします。 k3sは、Basic認証なのでエラーになりました。

$ TOKEN=$(kubectl describe secrets $(kubectl get secrets | grep default | awk '{print $1}') | grep -E '^token' | awk '{print $2}')
$ URL=$(kubectl config view | grep server | awk '{print $2}')
$ curl $URL/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
$

Basic認証でアクセスします。

$ USER=$(grep username ~/.kube/config | awk '{print $2}')
$ PWD=$(grep password ~/.kube/config | awk '{print $2}')
$ URL=$(kubectl config view | grep server | awk '{print $2}')
$ curl -s -u $USER:$PWD $URL/api/v1/namespaces/default/pods --insecure | head
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "3242"
  },
  "items": [
    {
      "metadata": {
(23) Failed writing body

kubectl proxyを使えば、認証方式に依存せずにREST APIにアクセスできます。

$ kubectl proxy --port=8080 &
[1] 94999
Starting to serve on 127.0.0.1:8080
$ curl -s http://localhost:8080/api/v1/namespaces/default/pods | head
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "3270"
  },
  "items": [
    {
      "metadata": {
(23) Failed writing body

git configで複数のユーザを切り替える

これまでの方法

gitで複数のユーザを切り替えるのにgit config --localを使って設定していました。

この方法は、切り替え忘れはないのですが、新規にリポジトリをcloneする毎にgit configを実行する必要がありました。

includeIfを使う方法

ghq~/.gitconfigincludeIfを使えば、初期設定以外何もしなくてもリポジトリ毎にuser.emailやuser.mailを切り替えて使うことができます。

ghqを使うと~/.ghq/gitサーバ名/ユーザ名/リポジトリ名にcloneされます。

includeIfを使って~/.ghq/gitサーバ名/単位で、user.emailやuser.nameを設定します。

例えば、下記のように~/.gitconfigに下記のように設定することで~/.ghq/bitbucket.org/mycompany/以下にcloneされたリポジトリは、~/.gitconfig-mycompanyの設定をイングルードしてくれます。

git config --globalでメインで使うメールアドレスを設定し、特定のディレクトリだけは、別のメールアドレスを設定することが可能になります。

$ tail -2 ~/.gitconfig
[includeIf "gitdir:~/.ghq/bitbucket.org/mycompany/"]
        path =~/.gitconfig-mycompany
$ cat ~/.gitconfig-mycompany
[user]
        email = me@mycompany

CodeBuildのローカル実行

CodeBuildのローカル実行がうまく動きませんでした。

AWS CodeBuild がローカルのテストとデバッグをサポート

手順に従ってビルドコンテナをビルドして、ヘルパーシェルをダウンロードして、実行してみると下記のエラーがでます。

$ ./codebuild_build.sh -i aws/codebuild/ruby:2.5.1 -a tmp
Build Command:

docker run -it -v /var/run/docker.sock:/var/run/docker.sock -e "IMAGE_NAME=aws/codebuild/ruby:2.5.1" -e "ARTIFACTS=/home/user/aws/aws-codebuild-docker-images/ubuntu/docker/17.09.0/tmp" -e "SOURCE=/home/user/aws/aws-codebuild-docker-images/ubuntu/docker/17.09.0" amazon/aws-codebuild-local:latest

Removing agentresources_build_1 ... done
Removing agentresources_agent_1 ... done
Removing network agentresources_default
Removing volume agentresources_user_volume
Removing volume agentresources_source_volume
Creating network "agentresources_default" with the default driver
Creating volume "agentresources_user_volume" with local driver
Creating volume "agentresources_source_volume" with local driver
Creating agentresources_agent_1 ... 
Creating agentresources_agent_1 ... done
Creating agentresources_build_1 ... 
Creating agentresources_build_1 ... done
Attaching to agentresources_agent_1, agentresources_build_1
agentresources_agent_1 exited with code 0
Stopping agentresources_build_1 ... done
Aborting on container exit...
$

カレントのソースコードをzipに固める

AWSのCodeシリーズは、S3のバケットにzipで固めたソースをアップロードが基本のようです。

カレントディレクトリのソース一式をsrc.zipにします。

zip -r src.zip . -x .git/\* -x \*~

VPCエンドポイントの性能

S3のVPCエンドポイントとNAT Gateway経由の性能差です。

1つ目がVPCエンドポイント経由で0.664ms、NAT Gateway経由が3.097msと圧倒的にVPCエンドポイントが早かった。

[ec2-user@ip-10-0-10-188 ~]$ sudo  tcptraceroute s3.ap-northeast-1.amazonaws.com 443
traceroute to s3.ap-northeast-1.amazonaws.com (52.219.68.120), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  s3-ap-northeast-1.amazonaws.com (52.219.68.120) <syn,ack>  0.660 ms  0.667 ms  0.664 ms
[ec2-user@ip-10-0-10-188 ~]$ sudo  tcptraceroute s3.ap-northeast-1.amazonaws.com 443
traceroute to s3.ap-northeast-1.amazonaws.com (52.219.0.60), 30 hops max, 60 byte packets
 1  ip-10-0-1-132.ap-northeast-1.compute.internal (10.0.1.132)  0.421 ms  0.401 ms  0.398 ms
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  52.219.0.60 (52.219.0.60) <syn,ack>  3.357 ms  3.068 ms  3.097 ms
[ec2-user@ip-10-0-10-188 ~]$