「Container」カテゴリーアーカイブ

MicroK8sにOperator Lifecycle Manager(OLM) をインストールしてみる

今日はMicroK8sにOperatorインストールを試みました。MicroK8sはMicroK8sをMacOSにインストールしてみるでインストール済みですので、よろしければご参照ください。

  • はじめに
  • kubectlのインストール
  • OLMのインストール
    • system:auth-delegatorの作成
    • extension-apiserver-authentication-readerの作成
    • OLMのインストール
  • Operatorのインストール

はじめに


OLMは以下のコマンドでインストールできますが、MicroK8sのコマンドはmicrok8s.kubectlなのでスクリプト実行が失敗します。従って、kubectlコマンドをインストールしてからOLMをインストールします。(スクリプトのkubectlコマンドをmicrok8s.kubectlコマンドに変更するでも構いません。)

ubuntu@microk8s-vm:~$ curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/0.15.1/install.sh | bash -s 0.15.1

kubectlのインストール


kubectlコマンドをインストールします。

ubuntu@microk8s-vm:~$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 41.9M  100 41.9M    0     0  1006k      0  0:00:42  0:00:42 --:--:-- 1016k
ubuntu@microk8s-vm:~$ chmod +x ./kubectl
ubuntu@microk8s-vm:~$ sudo mv ./kubectl /usr/local/bin/kubectl

以下のコマンドでMicroK8sのconfigを確認し、~/.kube/configにコピーします。

ubuntu@microk8s-vm:~$ microk8s.kubectl config view

上記の対応だけだと以下のエラーが発生するので、clusters.cluster.insecure-skip-tls-verify: trueを追加します。

Unable to connect to the server: x509: certificate signed by unknown authority

最終的な~/.kube/configは以下の通りです。

apiVersion: v1
clusters:
- cluster:
    insecure-skip-tls-verify: true
    server: https://127.0.0.1:16443
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
  user:
    password: パスワード(インストール時に割り当てられています。)
    username: admin

OLMのインストール


以下のコマンドでインストールします。

ubuntu@microk8s-vm:~$ curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/0.15.1/install.sh | bash -s 0.15.1

しかし、CSVのpackageserverのインストールが失敗します。一応Podは作成されるのですが、TerminateとContainerCreatingを永遠に繰り返します。

CSV "packageserver" failed to reach phase succeeded

eventを確認すると、以下のエラーが確認できました。

35m         Warning   APIServiceResourceIssue            clusterserviceversion/packageserver     clusterrole.rbac.authorization.k8s.io "system:auth-delegator" not found
3m30s       Warning   APIServiceResourceIssue            clusterserviceversion/packageserver     role.rbac.authorization.k8s.io "extension-apiserver-authentication-reader" not found

どうやらKubernetesにデフォルトで設定されるroleがMicroK8sでは設定されていないようですので、system:auth-delegatorとextension-apiserver-authentication-readerを作成します。

system:auth-delegatorの作成


以下のyamlを使って、clusterroleであるsystem:auth-delegatorを作成します。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:rbac.authorization.kubernetes.io/autoupdate: {}
        f:labels:
          .: {}
          f:kubernetes.io/bootstrapping: {}
      f:rules: {}
    manager: kube-apiserver
    operation: Update
  name: system:auth-delegator
rules:
- apiGroups:
  - authentication.k8s.io
  resources:
  - tokenreviews
  verbs:
  - create
- apiGroups:
  - authorization.k8s.io
  resources:
  - subjectaccessreviews
  verbs:
  - create

extension-apiserver-authentication-readerの作成


以下のyamlを使って、system:auth-delegator roleを作成します。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  annotations:
    openshift.io/reconcile-protect: "false"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: extension-apiserver-authentication-reader
  namespace: kube-system
rules:
- apiGroups:
  - ""
  attributeRestrictions: null
  resourceNames:
  - extension-apiserver-authentication
  resources:
  - configmaps
  verbs:
  - get

OLMのインストール


以下のコマンドでリトライすると、エラーなくインストールが完了しました。PodがTerminateとCreatingを繰り返すということも無くなりました。

ubuntu@microk8s-vm:~$ curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/0.15.1/install.sh | bash -s 0.15.1
customresourcedefinition.apiextensions.k8s.io/catalogsources.operators.coreos.com created
customresourcedefinition.apiextensions.k8s.io/clusterserviceversions.operators.coreos.com created
customresourcedefinition.apiextensions.k8s.io/installplans.operators.coreos.com created
customresourcedefinition.apiextensions.k8s.io/operatorgroups.operators.coreos.com created
customresourcedefinition.apiextensions.k8s.io/subscriptions.operators.coreos.com created
namespace/olm created
namespace/operators created
serviceaccount/olm-operator-serviceaccount created
clusterrole.rbac.authorization.k8s.io/system:controller:operator-lifecycle-manager unchanged
clusterrolebinding.rbac.authorization.k8s.io/olm-operator-binding-olm unchanged
deployment.apps/olm-operator created
deployment.apps/catalog-operator created
clusterrole.rbac.authorization.k8s.io/aggregate-olm-edit unchanged
clusterrole.rbac.authorization.k8s.io/aggregate-olm-view unchanged
operatorgroup.operators.coreos.com/global-operators created
operatorgroup.operators.coreos.com/olm-operators created
clusterserviceversion.operators.coreos.com/packageserver created
catalogsource.operators.coreos.com/operatorhubio-catalog created
Waiting for deployment "olm-operator" rollout to finish: 0 of 1 updated replicas are available...
deployment "olm-operator" successfully rolled out
Waiting for deployment "catalog-operator" rollout to finish: 0 of 1 updated replicas are available...
deployment "catalog-operator" successfully rolled out
Package server phase: Installing
Package server phase: Succeeded
deployment "packageserver" successfully rolled out

Operatorのインストール


せっかくOLMをインストールしたので、試しにOperatorHubからGrafana Operatorをインストールしてみます。

ubuntu@microk8s-vm:~$ kubectl create -f https://operatorhub.io/install/grafana-operator.yaml
namespace/my-grafana-operator created
operatorgroup.operators.coreos.com/operatorgroup created
subscription.operators.coreos.com/my-grafana-operator created
ubuntu@microk8s-vm:~$ kubectl get csv -n my-grafana-operator
NAME                      DISPLAY            VERSION   REPLACES   PHASE
grafana-operator.v3.2.0   Grafana Operator   3.2.0                Installing

少し待つと、インストールが完了しました。

ubuntu@microk8s-vm:~$ kubectl get csv -n my-grafana-operator
NAME                      DISPLAY            VERSION   REPLACES   PHASE
grafana-operator.v3.2.0   Grafana Operator   3.2.0                Succeeded

本当はこの後Grafanaリソースを作成しますが、OLMが動いていることが確認できたので、今日はここまでとします。

以上です。

Operatorsを調査してみる

今日はOperatorsを調査しましたのでメモしました。

  • Operatorsとは
    • Operator Frameworkとは
      • Operator Lifecycle Managerとは
      • Operator SDKとは
      • Operator Meteringとは

Operatorsとは


Operatorsは、KubernetesアプリケーションをKubernetes APIやkubectlコマンドによってパッケージ化・デプロイ・管理する方法です。Kubernetesが提供していないリソースを自分で作成し、それをKubernetes APIやkubectlで操作することによってKubernetesアプリケーションを管理します。

参考元)https://coreos.com/operators/

運用のナレッジをソフトウェアに落とし込むことによって、運用の自動化を促進するだけでなく、他のユーザーと共有できることを目的としています。その象徴として、OperatorHubはKubernetes Communityで共有されたOperatorがアップロードされており、誰でも利用することができます。

参考元)https://www.redhat.com/en/blog/introducing-operator-framework-building-apps-kubernetes

Operator Frameworkとは


Operator Frameworkとは、OperatorのOSSツールキットです。Operator Frameworkには、以下の三つが備わっています。

  • Operator Lifecycle Manager
  • Operator SDK
  • Operator Metering

Operator Lifecycle Managerとは


Operator Lifecycle Managerとは、Operatorにおけるインストール・アップデート・管理などのライフサイクルを管理する機能を提供します。具体的には以下の機能があります。

  • Over-the-Air Updates and Catalogs・・・インストールして最新に保つためのカタログの概念で、メンテナーはアップデートパスをきめ細かくオーサリングできます。
  • Dependency Model・・・プラットフォームや他Operatorとの依存関係を表現します。
  • Discoverability・・・インストール可能なOperatorを検知し、管理者に表示します。
  • Cluster Stability・・・同じAPIを利用するOperator同士の衝突を防ぎ、クラスターの安定性を保ちます。
  • Declarative UI controls・・・コマンドラインがAPIであるため、GUIを使ってOperatorとの対話に豊富なインタフェースを付け加えることが可能です。

参考元)https://github.com/operator-framework/operator-lifecycle-manager/

Operator SDKとは


Operator SDKは、Kubernetes APIの知識が無くてもOperatorが開発できるようにするため、以下を提供しています。

  • より直感的に操作ロジックを作成するための高レベルAPIおよび抽象化
  • 新しいプロジェクトを素早くブートストラップするためのコード生成ツール
  • 一般的なオペレーターの使用例をカバーする拡張機能

SDKは、Golang、Ansible、Helmを利用することができます。

参考元)https://sdk.operatorframework.io/docs/

Operator Meteringとは


Operator Meteringとは、Kubernetesの使用量を観測しレポートする機能を提供します。CPUやメモリをレポートするだけでなく、AWSなどのCloudと連携することによってIaaSコストもレポートすることができるようになります。

参考元)https://www.redhat.com/en/blog/introducing-operator-framework-building-apps-kubernetes

ArgoRolloutsとIstioを連携したカナリアデプロイ

MicroK8sにArgoCDをインストールするでMicroK8sにArgoCDをインストールしたので機能を試しています。その一貫として、今日はItioとRolloutsを連携してカナリアデプロイメントを試します。

  • 事前準備
    • Itioをインストールする
    • Argo Rolloutsをインストールする
  • yamlを作成する
    • Rolloutを作成する
    • Gatewayを作成する
    • VirtualServiceを作成する
    • Serviceを作成する
  • デプロイする
    • Githubに登録する
    • ArgoCDのApplicationを作成する
    • GithubとArgoCDを同期する
  •  カナリアデプロイをする
    • Rolloutを編集する
    • GithubとArgoCDを同期する
    • カナリアデプロイを確認する

事前準備


Itioをインストールする


MicroK8sのIstioを有効化して、Istioをインストールします。インストールは以下の記事で実施しているので、今回はスキップします。

MicroK8sでIstioによるABテストを試してみる(1/2)

Argo Rolloutsをインストールする


カナリアデプロイをするにはRolloutというリソースが必要になるので、以下のURLを参考にそのArgo Rolloutsをインストールします。

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/

ArgoCDによるBlueGreenデプロイを試すでインストール済みなので、今回はスキップします。

yamlを作成する


以下のURLを参考に、IstioとArgo Rolloutsのyamlを作成します。

https://argoproj.github.io/argo-rollouts/features/traffic-management/istio/

Rolloutを作成する


IstioのSubsetでバージョン毎に流量制御を行うで作成したhelloaアプリケーションのv1/v2を利用して、カナリアデプロイ用のRolloutを作成します。

以下のyamlを使って、レプリカ数 4個のhelloa:v1アプリケーションを実行するhelloa-istio-canaryを作成します。helloa-istio-canaryは、アプリケーションアップデート時に25%分(1個)だけ新しいバージョンをデプロイし、30秒間canary-svcを経由してアクセスを受け付けます。30秒経過すると、新しいバージョンのアプリケーションを100%分(4個)デプロイし、stable-svcを経由してアクセスを受け付けます。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: helloa-istio-canary
  namespace: istio-app
spec:
  replicas: 4
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: helloa
  template:
    metadata:
      labels:
        app: helloa
    spec:
      containers:
      - name: helloa
        image: localhost:32147/helloa:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    canary:
      steps:
      - setWeight: 25
      - pause:
          duration: 30s
      canaryService: canary-svc
      stableService: stable-svc
      trafficRouting:
        istio:
           virtualService:
            name: rollout-vsvc
            routes:
            - primary

Serviceを作成する


helloa-istio-canaryで指定したServiceを作成します。以下のyamlで、helloaをポート8080で公開するcanary-svcとstable-svcを作成します。

kind: Service
apiVersion: v1
metadata:
  name: canary-svc
  namespace: istio-app
spec:
  selector:
    app: helloa
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
---
kind: Service
apiVersion: v1
metadata:
  name: stable-svc
  namespace: istio-app
spec:
  selector:
    app: helloa
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080

Gatewayを作成する


外部からの通信を受け付けるために、IstioのGatewayを作成します。以下のyamlは、デフォルトのGatewayに対する80番ポートを全て受け付けるGatewayです。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: helloa-gateway
  namespace: istio-app
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

VirtualServiceを作成する


以下のyamlを使って、canary-svcとstable-svcに通信を割り振るrollout-vsvcを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: rollout-vsvc
  namespace: istio-app
spec:
  hosts:
  - "*"
  gateways:
  - helloa-gateway
  http:
    - name: primary
      route:
        - destination:
            host: stable-svc
          weight: 100
        - destination:
            host: canary-svc
          weight: 0

デプロイする


Githubに登録する


上記で作成したyamlをGitHubに登録し、その後以下のコマンドでArgoCDにGitHubを登録します。

$ argocd repo add https://github.com/[user名]/[レポジトリ名] --username [user名]

ArgoCDのApplicationを作成する


以下のコマンドで、登録したGitレポジトリを使ってApplicationを作成します。デプロイ先のnamespaceはIstioインジェクション済みであることに注意してください。インジェクション方法は、MicroK8sでIstioによるABテストを試してみる(2/2)で紹介しています。

$ argocd app create istio-canary --repo [レポジトリURL] --path [ディレクトリ] --dest-namespace [Injection済みnamespace] --dest-server [ClusterURL]

GithubとArgoCDを同期する


以下のコマンドで、ApplicationをGitHubと同期してyamlからデプロイします。

$ argocd app sync istio-canary

作成が完了すると、以下の図のようになります。

カナリアデプロイをする


Rolloutを編集する


helloa-istio-canaryのイメージタグをv1からv2に変更し、再度GitHubに登録します。

image: localhost:32147/helloa:v2

GithubとArgoCDを同期する


再度以下のコマンドでGitHubと同期して変更を反映します。

$ argocd app sync istio-canary

カナリアデプロイを確認する


GUIで確認すると、以下のように25%分をデプロイしていることがわかります。(以下の画像は、一世代前のPodが削除される直前です。)

通信経路を確認すると、stable-svcに75%(1世代前のPod)、canary-svcに25%(新規Pod)通信を割り振っていることがわかります。(以下の画像は、一世代前のPodが削除される直前です。)

30秒後、以下のように新規Podが100%になります。

最終的には以下の画面になります。一世代前のReplicaSetが残っていることが確認できます。

以上です!

ArgoCDのCanary Deploymentを試す

MicroK8sにArgoCDをインストールするでMicroK8sにArgoCDをインストールしたので機能を試しています。その一貫として、今日はCanary Deployment(カナリアデプロイメント)を試したいと思います。

  • Argo Rolloutsをインストールする
  • Rolloutを作成する
    • カナリアデプロイ用のRolloutを作成する
    • Serviceを作成する
  • カナリアデプロイを実行する

Argo Rolloutsをインストールする


カナリアデプロイをするにはRolloutというリソースが必要になるので、以下のURLを参考にそのArgo Rolloutsをインストールします。

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/

ArgoCDによるBlueGreenデプロイを試すでインストール済みなので、今回はスキップします。

Rolloutを作成する


以下の記事を参考に、カナリアデプロイ用のRolloutを作成します。

https://argoproj.github.io/argo-rollouts/features/canary/

カナリアリリース用のRolloutを作成する


IstioのSubsetでバージョン毎に流量制御を行うで作成したhelloaアプリケーションのv1/v2を利用して、カナリアリリース用のRolloutを作成します。

以下のyamlを使って、レプリカ数 4個のhelloa:v1アプリケーションを実行するhelloa-canaryを作成します。helloa-canaryは、アプリケーションアップデート時に25%分だけ新しいバージョンをデプロイし、その10秒後に50%になるようデプロイします。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: helloa-canary
spec:
  replicas: 4
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: helloa
  template:
    metadata:
      labels:
        app: helloa
    spec:
      containers:
      - name: helloa
        image: localhost:32147/helloa:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    canary:
      steps:
      - setWeight: 25
      - pause:
          duration: 10 # 10 seconds
      - setWeight: 50
      - pause: {} # pause indefinitely

spec.strategy.canaryブロックでカナリアデプロイの設定が行えます。詳細なオプションについては、以下のURLを参照してください。

https://argoproj.github.io/argo-rollouts/features/canary/

作成すると、以下のようにPodとReplicaSetが作成されます。

ubuntu@microk8s-vm:~$ microk8s.kubectl create -f rollout.yaml 
rollout.argoproj.io/helloa-canary created
ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
helloa-canary-5d86bb8b54   4         4         4       23s
ubuntu@microk8s-vm:~$ microk8s.kubectl get pods 
NAME                             READY   STATUS    RESTARTS   AGE
helloa-canary-5d86bb8b54-2djjc   1/1     Running   0          7s
helloa-canary-5d86bb8b54-hr8kf   1/1     Running   0          7s
helloa-canary-5d86bb8b54-nzdcl   1/1     Running   0          7s
helloa-canary-5d86bb8b54-spzcb   1/1     Running   0          7s

Serviceを作成する


上記で作成したhelloaを公開するため、NodePort 32000ポートで公開するcanary Serviceを作成します。

kind: Service
apiVersion: v1
metadata:
  name: canary
spec:
  selector:
    app: helloa
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    nodePort: 32000

上記のyamlファイルを使い、以下のコマンドでcanary Serviceを作成します。

ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl create -f service.yaml 
service/canary created
ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl get svc canary
NAME     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
canary   NodePort   10.152.183.151   <none>        8080:32000/TCP   9s

httpリクエストを送ると、以下の結果が返ってきます。

$ curl 192.168.64.2:32000
Hello A

カナリアデプロイを実行する


helloaのタグをv2にして、カナリアデプロイを実行します。

以下のコマンドで、helloaのタグをv1からv2に変更します。

ubuntu@microk8s-vm:~/argocd/canary$ microk8s.kubectl patch rollout helloa-canary --type merge -p '{"spec": {"template": {"spec": {"containers": [{"name":"helloa","image":"localhost:32147/helloa:v2"}]}}}}'
rollout.argoproj.io/helloa-canary patched

若干のタイムラグはあるのですが、以下のコマンドでデプロイ状況を確認しました。最初は3割v2に割り振られ、その10秒後に5割v2に割り振られているので、指定した割合と近しい値が出ていることを確認できました。

$ while true; do  date "+TIME: %H:%M:%S"; curl 192.168.64.2:32000; sleep 1; done
TIME: 20:54:19←setWeight 25%
Hello A
TIME: 20:54:20
Hello A v2
TIME: 20:54:21
Hello A
TIME: 20:54:22
Hello A
TIME: 20:54:23
Hello A
TIME: 20:54:24
Hello A
TIME: 20:54:25
Hello A v2
TIME: 20:54:26
Hello A
TIME: 20:54:27
Hello A
TIME: 20:54:28
Hello A v2
TIME: 20:54:29←setWeight 50%
Hello A
TIME: 20:54:30
Hello A
TIME: 20:54:31
Hello A
TIME: 20:54:32
Hello A v2
TIME: 20:54:33
Hello A v2
TIME: 20:54:34
Hello A v2
TIME: 20:54:35
Hello A
TIME: 20:54:36
Hello A
TIME: 20:54:37
Hello A v2
TIME: 20:54:38
Hello A v2

Podの状況を確認すると、指定した通りv1, v2のPodが2個ずつデプロイされて止まっていました。

ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
helloa-canary-5695f95f6b   2         2         2       80s
helloa-canary-5d86bb8b54   2         2         2       15m
ubuntu@microk8s-vm:~$ microk8s.kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
helloa-canary-5695f95f6b-9mlh9   1/1     Running   0          76s
helloa-canary-5695f95f6b-9ppnk   1/1     Running   0          64s
helloa-canary-5d86bb8b54-hr8kf   1/1     Running   0          15m
helloa-canary-5d86bb8b54-spzcb   1/1     Running   0          15m

以上です。

ArgoCDによるBlueGreenデプロイを試す

MicroK8sにArgoCDをインストールするでArgoCDをインストールしたので機能を試しています。その一貫として、今日はBlueGreenデプロイを試したいと思います。

  • Argo Rolloutsをインストールする
  • Rolloutを作成する
    • BlueGreenデプロイ用のRolloutを作成する
    • Serviceを作成する
  • デプロイする
    • v1をデプロイする
    • v2をデプロイする
    • BlueGreenデプロイをする

Argo Rolloutsをインストールする


BlueGreenデプロイをするにはRolloutというリソースが必要になるので、以下のURLを参考にそのArgo Rolloutsをインストールします。

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/

今回は以下のコマンドでArgo Rolloutをインストールしました。

ubuntu@microk8s-vm:~$ microk8s.kubectl create namespace argo-rollouts
namespace/argo-rollouts created
ubuntu@microk8s-vm:~$ microk8s.kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io created
serviceaccount/argo-rollouts created
role.rbac.authorization.k8s.io/argo-rollouts-role created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-clusterrole created
rolebinding.rbac.authorization.k8s.io/argo-rollouts-role-binding created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts-clusterrolebinding created
service/argo-rollouts-metrics created
deployment.apps/argo-rollouts created
ubuntu@microk8s-vm:~$ 
ubuntu@microk8s-vm:~$ microk8s.kubectl get pods -n argo-rollouts
NAME                             READY   STATUS    RESTARTS   AGE
argo-rollouts-7c5dbbd46d-4sf6s   1/1     Running   0          43s

Rolloutを作成する


以下の記事を参考に、BlueGreenデプロイ用のRolloutを作成します。

https://argoproj.github.io/argo-rollouts/features/bluegreen/

BlueGreenデプロイ用のRolloutを作成する


BlueGreenデプロイ用のRolloutを作成します。IstioのSubsetでバージョン毎に流量制御を行うで作成したhelloaアプリケーションのv1/v2を利用します。

以下のyamlを使って、Service名active-svc/preview-svcに対してBlueGreenデプロイを行うhelloa-bluegreenを作成します。初回はhelloa:v1がactive-svcによって割り振られ、v2をデプロイするとhelloa:v2がpreview-svcによって割り振られます。autoPromotionEnabled: falseにしているので、手動で昇格するとhelloa:v2がactive-svcによって割り振られるようになります。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: helloa-bluegreen
spec:
  replicas: 2
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: helloa
  template:
    metadata:
      labels:
        app: helloa
    spec:
      containers:
      - name: helloa
        image: localhost:32147/helloa:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
  strategy:
    blueGreen: 
      activeService: active-svc
      previewService: preview-svc
      autoPromotionEnabled: false

strategy内のオプションについては、以下をご参照ください。

https://argoproj.github.io/argo-rollouts/features/bluegreen/

Serviceを作成する


helloa-bluegreenで指定したactive-svc/preview-svcを作成します。

NodePortでポート32000がactive-svc、同じくNodePortでポート32001がpreview-svcとするyamlを使います。

kind: Service
apiVersion: v1
metadata:
  name: active-svc
spec:
  selector:
    app: helloa
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    nodePort: 32000
---
kind: Service
apiVersion: v1
metadata:
  name: preview-svc
spec:
  selector:
    app: helloa
  type: NodePort
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    nodePort: 32001

作成すると以下の結果になります。

ubuntu@microk8s-vm:~$ microk8s.kubectl create -f service.yaml 
service/active-svc created
service/preview-svc created
ubuntu@microk8s-vm:~$ microk8s.kubectl get svc
NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
active-svc         NodePort    10.152.183.171   <none>        8080:32000/TCP   12s
preview-svc        NodePort    10.152.183.159   <none>        8080:32001/TCP   12s

デプロイする


v1をデプロイする


以下のコマンドでRolloutを作成し、v1をデプロイします。

ubuntu@microk8s-vm:~$ microk8s.kubectl create -f rollout.yaml 
rollout.argoproj.io/helloa-bluegreen created

デプロイが完了すると、二つあるレプリカセットのうち片方だけにPodが作成されます。

ubuntu@microk8s-vm:~$ microk8s.kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
helloa-bluegreen-5d86bb8b54-hs7tb   1/1     Running   0          26s
helloa-bluegreen-5d86bb8b54-pbnqx   1/1     Running   0          26s
ubuntu@microk8s-vm:~/argocd/bluegreen$ microk8s.kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
helloa-bluegreen-5d86bb8b54   2         2         2       11s
helloa-bluegreen-6d7dc44886   0         0         0       58s

確認すると以下の結果になります。192.168.64.2はmultipass-vmのIPアドレスです。

$ curl http://192.168.64.2:32000
Hello A

v2をデプロイする


以下のコマンドを使ってhelloa-bluegreenのimageタグをv2にしてデプロイします。

ubuntu@microk8s-vm:~$ microk8s.kubectl patch rollout helloa-bluegreen --type merge -p '{"spec": {"template": {"spec": {"containers": [{"name":"helloa","image":"localhost:32147/helloa:v2"}]}}}}'
rollout.argoproj.io/helloa-bluegreen patched

以下のようにPodが作成されていることがわかります。Deploymentのローリングアップデートと異なる点は、v1とv2が同時に稼働していて、任意のタイミングで切り替えることができる点です。これによって、本番適用前に手動でテストを行うことができます。

ubuntu@microk8s-vm:~$ microk8s.kubectl get pods 
NAME                                READY   STATUS    RESTARTS   AGE
helloa-bluegreen-5695f95f6b-nkcw4   1/1     Running   0          12s
helloa-bluegreen-5695f95f6b-p8jw2   1/1     Running   0          12s
helloa-bluegreen-5d86bb8b54-hs7tb   1/1     Running   0          18m
helloa-bluegreen-5d86bb8b54-pbnqx   1/1     Running   0          18m
ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
helloa-bluegreen-5695f95f6b   2         2         2       28s
helloa-bluegreen-5d86bb8b54   2         2         2       18m
helloa-bluegreen-6d7dc44886   0         0         0       19m

httpリクエストを行うと以下の結果になります。

$ curl http://192.168.64.2:32000
Hello A
$ curl http://192.168.64.2:32001
Hello A v2

BlueGreenデプロイをする


以下のコマンドを使うことで、preview-svcに配下のv2をactive-svc配下に昇格することができます。

ubuntu@microk8s-vm:~$ microk8s.kubectl argo rollouts resume helloa-bluegreen

実行したところ、以下のエラーが出ました。

Error: unknown command "argo" for "kubectl"
Run 'kubectl --help' for usage.

当たり前ですが、kubectl pluginを入れなければならないようでした。以下のURLを参考にインストールします。

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/

再度実行すると、以下のエラーが出てしまいました。

ubuntu@microk8s-vm:~$ microk8s.kubectl argo rollouts resume helloa-bluegreen
exec format error

結果解消することができなかったので、仕方なく手動でautoPromotionEnabledをtrueにして昇格を行いました。

ubuntu@microk8s-vm:~$ microk8s.kubectl patch rollout helloa-bluegreen --type merge -p '{"spec": {"strategy": {"blueGreen": {"autoPromotionEnabled": true}}}}'

昇格が完了すると、v1が消えていました。

ubuntu@microk8s-vm:~$ microk8s.kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
helloa-bluegreen-5695f95f6b-nkcw4   1/1     Running   0          48m
helloa-bluegreen-5695f95f6b-p8jw2   1/1     Running   0          48m
ubuntu@microk8s-vm:~$ microk8s.kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
helloa-bluegreen-5695f95f6b   2         2         2       81m
helloa-bluegreen-5d86bb8b54   0         0         0       99m
helloa-bluegreen-6d7dc44886   0         0         0       100m

以下のコマンドでサービスが切り替わっていることも確認できました。

$ curl http://192.168.64.2:32000
Hello A v2

以上です。

ArgoCDのCLIを使ってみる

MicroK8sにArgoCDをインストールするでArgoCDをインストールしましたが、これまでGUIだけ使っていたので、以下のURLを参考にCLIで操作してみます。

https://argoproj.github.io/argo-cd/getting_started/

  • ArgoCD CLIをMacOSにインストールする
  • CLIでログインする
  • コマンドを実行する

ArgoCD CLIをMacOSにインストールする


以下のコマンドでArgoCD CLIをインストールします。

brew tap argoproj/tap
brew install argoproj/tap/argocd

CLIでログインする


argued loginコマンドを利用してCLIでログインします。

ログイン先のURLは、ArgoCDの公開Serviceを指定します。今回は、MicroK8sにArgoCDをインストールするで公開argocd-server ServiceをNodePortに設定したので、[MicroK8sのURL]:[argocd-server Serviceの公開Port]を指定します。パスワードは、argocd-serverのPod名になります。

公式サイトでは、ServiceタイプをLoadBalancerに変更したポートフォワードに設定しています。

$ argocd login 192.168.64.2:30001
WARNING: server certificate had error: x509: cannot validate certificate for 192.168.64.2 because it doesn't contain any IP SANs. Proceed insecurely (y/n)? y
Username: admin
Password: 
'admin' logged in successfully
Context '192.168.64.2:30001' updated

コマンドを実行する


操作を確認します。

まずは登録したApplicationを以下のコマンドで確認してみます。

$ argocd app get test
Name:               test
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://192.168.64.2:30001/applications/test
Repo:               https://github.com/username/argocd
Target:             master
Path:               test
SyncWindow:         Sync Allowed
Sync Policy:        Automated
Sync Status:        Synced to master (ab089cb)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME  STATUS  HEALTH   HOOK  MESSAGE
       Service     default    test  Synced  Healthy        service/test unchanged
apps   Deployment  default    test  Synced  Healthy        deployment.apps/test configured

ArgoCDのApplicationをCLIで作成します。以下のコマンドは、自身のargocd GitHubレポジトリにおけるtestフォルダ内マニフェストファイルから、MicroK8s上のdefault namespaceにデプロイします。

$ argocd app create cli-test --repo https://github.com/username/argocd --path test --dest-namespace default --dest-server https://kubernetes.default.svc
application 'cli-test' created
$ argocd app get cli-test
Name:               cli-test
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://192.168.64.2:30001/applications/cli-test
Repo:               https://github.com/username/argocd.git
Target:             
Path:               test
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from  (ab089cb)
Health Status:      Healthy

CONDITION              MESSAGE                                                   LAST TRANSITION
SharedResourceWarning  Deployment/test is part of a different application: test  2020-06-17 22:53:41 +0900 JST
SharedResourceWarning  Service/test is part of a different application: test     2020-06-17 22:53:43 +0900 JST


GROUP  KIND        NAMESPACE  NAME  STATUS     HEALTH   HOOK  MESSAGE
       Service     default    test  OutOfSync  Healthy        
apps   Deployment  default    test  OutOfSync  Healthy        

GUIで見ても作成されていることがわかります。

手動でGitHubと同期する場合は$ argocd app sync [Application名]を実行します。上記で作成したApplicationの同期を行う場合は、以下のコマンドを実行します。

$ argocd app sync cli-test
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
2020-06-17T23:12:24+09:00            Service     default                  test  OutOfSync  Missing              
2020-06-17T23:12:24+09:00   apps  Deployment     default                  test  OutOfSync  Missing              
2020-06-17T23:12:25+09:00            Service     default                  test    Synced  Healthy              
2020-06-17T23:12:25+09:00            Service     default                  test    Synced   Healthy              service/test created
2020-06-17T23:12:25+09:00   apps  Deployment     default                  test  OutOfSync  Missing              deployment.apps/test created
2020-06-17T23:12:25+09:00   apps  Deployment     default                  test    Synced  Progressing              deployment.apps/test created

Name:               cli-test
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://192.168.64.2:30001/applications/cli-test
Repo:               https://github.com/username/argocd
Target:             
Path:               test
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        Synced to  (ab089cb)
Health Status:      Healthy

Operation:          Sync
Sync Revision:      ab089cb2e0c000d50cc90451811afc0aa2205ff4
Phase:              Succeeded
Start:              2020-06-17 23:12:24 +0900 JST
Finished:           2020-06-17 23:12:25 +0900 JST
Duration:           1s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME  STATUS  HEALTH   HOOK  MESSAGE
       Service     default    test  Synced  Healthy        service/test created
apps   Deployment  default    test  Synced  Healthy        deployment.apps/test created

syncコマンド実行後、マニフェストファイルからコンテナアプリケーションがデプロイされていることがわかります。

$ microk8s kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
registry                1/1     Running   5          5d
test-579889db56-plzgx   1/1     Running   0          6s

今日は以上です。CLIが利用できるので、より一層幅が広がりそうです。

GitHubで承認されたyamlからArgoCDで自動デプロイする

ArgoCDの初歩 GitHub上のyamlからアプリケーションをデプロイするでArgoCDの機能が試せたので、GitHub上で承認されたyamlをKubernetes上のマニフェストに自動反映してみます。

今回は実際の運用を考えて、登場人物をArgoCD担当者、アプリ開発者、アプリ責任者に分けてみました。ArgoCD担当者はCI/CDチームを想定していて、開発者とは別に開発環境を整えるチームを想定しています。アプリ開発者とアプリ責任者は同じチームで、開発者は変更を加えたら責任者に承認を取得する必要があります。

  • ArgoCD Applicationを作成する(ArgoCD担当者)
  • yamlを編集する(アプリ開発者)
    • ブランチを作成する
    • yamlを編集してpushする
    • プルリクエストを作成する
  • プルリクエストを承認する(アプリ責任者)
  • デプロイを確認する

ArgoCD Applicationを作成する(ArgoCD担当者)


開発者がyamlを編集する前に、対象レポジトリのブランチに変更があれば自動でKubernetes上のマニフェストに反映する設定を行います。以下の記事で作成した、test Applicationの「SYNC POLICY」を「Automation」に設定します。

ArgoCDの初歩 GitHub上のyamlからアプリケーションをデプロイする

test Applicationを選択し、「APP DETAILS」から「ENABLE AUTO SAVE」をクリックします。

yamlを編集する(アプリ開発者)


開発者がyamlを変更し、プルリクエストを作成します。

yamlファイルは、ArgoCDの初歩 GitHub上のyamlからアプリケーションをデプロイするで作成したtest-deployment.yamlを対象とし、HELLO_ENVという環境変数をdeploymentに追加します。

ブランチを作成する


以下のコマンドでdev-branchブランチを作成し、そのブランチに切り替えます。

$ git branch
* master
$ git checkout -b dev-branch
Switched to a new branch 'dev-branch'
$ git branch
* dev-branch
  master
$ git push origin dev-branch

yamlを編集してpushする


以下のようにtest-deployment.yamlを編集し、環境変数HELLO_ENV="Hello Env"を追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
  labels:
    app: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: test 
        image: localhost:32147/helloa:latest
        ports:
        - containerPort: 8080
        env:
        - name: HELLO_ENV
          value: "Hello Env v2"

ちなみに、変更前は当然ながらHELLO_ENVが存在しないので、以下のようになります。

ubuntu@microk8s-vm:~$ microk8s.kubectl exec -it test-6d7d668d8c-xbzfq -- env  |  grep HELLO_ENV

ubuntu@microk8s-vm:~$

以下のコマンドで、dev-branchに変更ファイルを登録します。

$ git add -A
$ git commit -m "add HELLO_ENV env to deployment"
$ git push --set-upstream origin dev-branch

プルリクエストを作成する


以下のコマンドで、dev-branchで行った変更をmasterにも反映するプルリクエストを作成します。今回は自分で作成して自分で承認することになりますが、本来であれば承認できるユーザーを予め設定します。

$ git pull-request

プルリクエストを承認する(アプリ責任者)


アプリ開発者が作成したプルリクエストをアプリ責任者が確認し、承認します。

アプリ責任者がGitにログインすると、以下のように承認待ちのプルリクエストが確認できます。

プルリクエストを開き、中身を確認後、「Merge pull request」→「Confirm merge」をクリックします。

以上で承認処理が完了です。本番運用で導入するなら、Slackやメールを使って、承認者にプルリクエストが通知される仕組みを導入すべきだと思います。

デプロイを確認する


自動でデプロイされることを確認します。

プルリクエストの承認が完了し、少し待っていると、Podのローリングアップデートが行われました。

ubuntu@microk8s-vm:~$ microk8s.kubectl get pods
NAME                    READY   STATUS        RESTARTS   AGE
registry                1/1     Running       4          3d22h
test-64df8695f6-96qhf   1/1     Running       0          13s
test-6d7d668d8c-xbzfq   0/1     Terminating   1          24h

以下のコマンドを実行すると、正しく環境変数が登録されていることがわかります。

ubuntu@microk8s-vm:~$ microk8s.kubectl exec -it test-64df8695f6-96qhf -- env  |  grep HELLO_ENV
HELLO_ENV=Hello Env
ubuntu@microk8s-vm:~$

ArgoCDから見ても、同期が完了してyamlが反映されたことがわかります。

yamlファイルを反映するコマンドを実行しなくても、反映されることがわかりました。GitOpsの片鱗を見た気がします。今回やった内容は実運用でも大分使えると思います。

以上です!

ArgoCDの初歩 GitHub上のyamlからアプリケーションをデプロイする

以下の記事でArgoCDをMicroK8sにインストールしました。今日はArgoCDの初歩とういことで、GitHubのyamlからアプリケーションをデプロイしてみたいと思います。

MicroK8sにArgoCDをインストールする

  • yamlを作成する
    • Deployment用yamlを作成する
    • Service用yamlを作成する
    • yamlをGitHubに登録する
  • ArgoCDの設定を行う
    • GitHubレポジトリをArgoCDに登録する
    • ArgoCD Applicationを作成する
  • ArgoCDとGitHubを同期する

yamlを作成する


ArgoCDが同期するyamlファイルを作成します。

今回用意するのは、アプリケーションデプロイ用のDeploymentと公開用のServiceです。

Deployment用yamlを作成する


アプリケーションをデプロイ・管理するためのyamlを作成します。

以下は、MicroK8sでアプリケーションを動かすでMicroK8s上のdocker registryに登録したhelloaイメージをレプリカ数1でデプロイするDeploymentです。helloaイメージは、httpリクエストを受け付けると”Hello A”を表示するgolangベースのコンテナアプリケーションイメージです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
  labels:
    app: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: test 
        image: localhost:32147/helloa:latest
        ports:
        - containerPort: 8080

Service用yamlを作成する


アプリケーションを公開するためのyamlを作成します。

以下は、test DeploymentのPodをポート32000をNodePortで公開するServiceのyamlです。

apiVersion: v1
kind: Service
metadata:
  name: test
  labels:
    app: test
    service: test
spec:
  ports:
  - port: 8080
    nodePort: 32000
    name: http
  selector:
    app: test
  type: NodePort

yamlをGitHubに登録する


上記で作成したyamlをargocdリポジトリのtestディレクトリに登録します。

$ tree argocd/
argocd/
├── README.md
└── test
    ├── test-deployment.yaml
    └── test-service.yaml
$ git add -A
$ git commit -m "First commit for ArgoCD test"
$ git push

ArgoCDの設定を行う


GitHubレポジトリをArgoCDに登録する


以下の記事で紹介したレポジトリ登録手順を参考に、上記で作成したargocdレポジトリをArgoCDに登録します。認証情報の設定を行うもので、次のApplication作成の時にレポジトリを選択できます。

MicroK8sにArgoCDをインストールする

ArgoCD Applicationを作成する


GitHubと同期してMicroK8s上にアプリケーションをデプロイするApplicationを作成します。

ログイン後、Applicationが未作成だと以下の画面になるので「CREATE APPLICATION」をクリックします。

必要な項目を入力します。それぞれの項目は以下の通りのです。

  • Application Name・・・ArgoCD内のApplication名。Application単位でGitHubと同期を行いデプロイされる。
  • Project・・・ArgoCD内のProject名。ApplicationをProject単位で管理できる。
  • SYNC POLICY・・・同期方法の設定。「Manual」か「Automation」が設定できる。
  • SYNC OPTIONS・・・デプロイする時にマニフェストの中身を検証する。
  • Repository URL・・・GitレポジトリのURL。ArgoCDに登録したURLが利用できる。
  • Revision・・・Gitのブランチ。
  • Path・・・レポジトリ内のパス。
  • Cluster・・・デプロイ先のクラスター。登録したクラスターをデプロイ先に選択できる。デフォルトでは、ArgoCDがインストールされたクラスターが選択できる。
  • Namespace・・・デプロイ先のnamespace。デプロイ先クラスターのnamespaceを選択できる
  • TOOL・・・同期するマニフェストファイルの形式を選択できる。以下の場合は「Directory」を選択していて、YAML/JSON/Jsonnetの形式で同期する。詳細はこちら
  • DIRECTORY RECURSE・・・ディレクトリ内の全階層におけるマニフェストファイルを全て同期する。
  • TOP-LEVEL ARGUMENTS・・・Jsonnetで扱われる、構成情報全体を関数として提供するもの。
  • EXTERNAL VARIABLES・・・Jsonnetで扱われる、コンフィグまたはファイルのどこからでもアクセスできる外部変数。

以上の項目を入力して、「Create」ボタンをクリックすると、以下のようにApplicationが作成されます。

ArgoCDとGitHubを同期する


上記で作成したApplicationの「Sync」ボタンをクリックし、「SYNCHRONIZE」ボタンをクリックすると同期が始まります。

同期に成功すると、以下のようにグリーンカラーになり、「Healthy」ステータスになります。

MicroK8s上で確認すると、以下のようにDeploymentとServiceが作成されていることがわかります。

ubuntu@microk8s-vm:~$ microk8s.kubectl get deployment test
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
test   1/1     1            1           31s
ubuntu@microk8s-vm:~$ microk8s.kubectl get svc test
NAME   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
test   NodePort   10.152.183.49   <none>        8080:32000/TCP   37s
ubuntu@microk8s-vm:~$ curl localhost:32000
Hello A

 

以上です!応用していくとかなり使えそうなツールですね。

引用


Argoのアイコン

https://github.com/cncf/artwork/blob/master/projects/argo/icon/color/argo-icon-color.png

GitHubのアイコン

https://github.com/logos

MicroK8sにArgoCDをインストールする

ArgoCDについて勉強したいと思っていたので、まずは使える環境を用意したいと思います。

  • ArgoCDとは
  • Kubernetes環境を用意する
  • ArgoCDをインストールする
  • GitHubレポジトリを登録する

ArgoCDとは


ArgoCDの定義は、公式サイトで以下の記述があります。

Argo CDは、Kubernetes用の宣言型GitOps継続的デリバリーツールです。
引用元:ArgoCD公式サイト

GitOpsという言葉は、Cloud Native Computing Foundationのカンファレンスで紹介された開発手法です。コマンドラインツールを用いず、Gitにpushした変更をKubernetesのリソースに反映することで、開発の自動化、オペミスの削減、プルリクエストの承認によるガバナンス強化などのメリットをもたらします。

ArgoCDは、GitOpsを実現するのに必要な機能を提供するツールで、以下の内容を補います。

アプリケーションの定義、構成、および環境は、宣言的でバージョン管理されている必要があります。アプリケーションのデプロイメントとライフサイクル管理は、自動化され、監査可能で、理解しやすいものでなければなりません。
引用元:ArgoCD公式サイト

Kubernetes環境を用意する


Kubernetes環境にはMicroK8s for MacOSを利用します。

MicroK8sの公式サイトは以下のURLです。

https://microk8s.io

MicroK8sはのインストールは以下の記事でインストール済みです。

MicroK8sをMacOSにインストールしてみる

ArgoCDをインストールする


公式サイトを参考に、ArgoCDをMicroK8s上にインストールします。

ArgoCD用のnamespaceを作成します。

ubuntu@microk8s-vm:~$ microk8s.kubectl create namespace argocd
namespace/argocd created

以下のコマンドで、ArgoCDに必要なリソースを作成します。

ubuntu@microk8s-vm:~$ microk8s.kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-secret created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server-metrics created
service/argocd-server created
deployment.apps/argocd-application-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created

Podが全てRunningになっていることが確認できれば、インストール完了です。

ubuntu@microk8s-vm:~$ microk8s.kubectl get pods -n argocd -w
NAME                                             READY   STATUS    RESTARTS   AGE
argocd-application-controller-5cfb8d686c-fzkzk   1/1     Running   0          5m15s
argocd-dex-server-5cf8dd69f5-qc4j2               1/1     Running   0          5m14s
argocd-redis-6d7f9df848-cmmg5                    1/1     Running   0          5m14s
argocd-repo-server-56b75988dc-9vkk8              1/1     Running   0          5m14s
argocd-server-6766455855-w6tx8                   1/1     Running   0          5m14s

Argoにアクセスする必要があるので、ServiceのタイプをClusterIPからNodePortに変更します。以下のコマンドでエディタを開き、spec.typeをNodePortに編集して保存します。

ubuntu@microk8s-vm:~$ microk8s.kubectl get svc argocd-server -n argocd 
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
argocd-server           ClusterIP   10.152.183.4     <none>        80/TCP,443/TCP               24m
ubuntu@microk8s-vm:~$ microk8s.kubectl edit svc argocd-server -n argocd
service/argocd-server edited
ubuntu@microk8s-vm:~$ microk8s.kubectl get svc argocd-server -n argocd 
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
argocd-server           NodePort    10.152.183.4     <none>        80:31946/TCP,443:30001/TCP   29m

上記の場合、https://[multipass-vmのIP]:30001でアクセスすると以下の画面になります。初期ユーザーID/パスワードは、admin/[ArgoCDのpod名]でした。

GitHubレポジトリを登録する


試しに一つArgoCDにGitHubを登録してみます。

ログイン後、「設定」タブから「Repositories」をクリックします。

「CONNECT REPO USING HTTP」をクリックします。

「Type」をgitにして、「Repository URL」「Username(optional)」「Password(optional)」を入力し、「CONNECT」をクリックします。

同期が完了すると以下のように登録されます。

以上です。今日はインストールだけにして、明日以降また色々と試してみたいと思います。

Istio使ってURLパス単位でリクエスト処理を分けてみる

Istioを使ってURLパス単位で、コンテナアプリケーションを割り振ってみます。

  • コンテナアプリケーションを作成する
    • ソースコードを作成する
    • helloaコンテナイメージを作成する
    • hellobコンテナイメージを作成する
  • コンテナアプリケーションを実行する
  • Istioの設定をする
    • Gatewayを作成する
    • VirtualServiceを作成する
  • 設定を確認する

コンテナアプリケーションを作成する


Istioの割り振り先コンテナアプリケーションを作成します。

今回作成するのは、httpリクエストをポート8080で受け付けると以下の振る舞いを行うアプリケーションです。

    • / ・・・”Hello A” or “Hello B”を表示する
    • /hello ・・・”Hello A” or “Hello B”を表示する

ソースコードを作成する


コンテナアプリケーションで使うソースコードをgolangで作成します。

main.goを以下に示します。マックスハンドラを使って、URL毎に使うhtmlファイルを分けています。

package main

import (
    "log"
    "net/http"
    "html/template"
    "fmt"
)

func main() {
    //index関数をルートディレクトリに指定
    http.HandleFunc("/", index)
    //hello関数をルートディレクトリに指定
    http.HandleFunc("/hello", hello)
    //サーバー起動
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe:", nil)
    }
}

func index(writer http.ResponseWriter, r *http.Request) {
  generateHTML(writer, "index")
}

func hello(writer http.ResponseWriter, r *http.Request) {
  generateHTML(writer, "hello")
}

func generateHTML(writer http.ResponseWriter, filenames ...string) {
    var files []string
    for _, file := range filenames {
        files = append(files, fmt.Sprintf("templates/%s.html", file))
    }

    templates := template.Must(template.ParseFiles(files...))
  templates.Execute(writer, nil)
}

main.goを実行するコンテナをビルドするためのDockerfileを以下に示します。

FROM golang:latest

# コンテナ作業ディレクトリの変更
WORKDIR /go/src/web
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
RUN go build -o web
# ウェブアプリケーション実行コマンドの実行
CMD ["./web"]

ディレクトリ構造は以下の通りです。index.htmlとhello.htmlはhelloa, hellobアプリケーション毎に作成します。

$ tree .
.
├── Dockerfile
└── src
    ├── main.go
    └── templates
        ├── hello.html
        └── index.html

helloaコンテナイメージを作成する


httpリクエストを受け付けると”Hello A”を表示するhelloaコンテナイメージを作成します。

以下のコマンドを使って、”Hello A”を表示するindex.htmlとhello.htmlを作成します。

$ echo "Hello A" > index.html
$ echo "Hello A" > hello.html

以下のコマンドでコンテナイメージをビルドして、docker registryに登録します。このdocker registryはMicroK8s上にコンテナとして動いています。docker registryの起動方法は、MicroK8sでアプリケーションを動かすを参考にしてください。

$ docker build -t helloa:latest .
$ docker tag helloa 192.168.64.2:32147/helloa
$ docker push 192.168.64.2:32147/helloa

hellobコンテナイメージを作成する


httpリクエストを受け付けると”Hello B”を表示するhelloaコンテナイメージを作成します。

以下のコマンドを使って、”Hello B”を表示するindex.htmlとhello.htmlを作成します。

$ echo "Hello B" > templates/index.html 
$ echo "Hello B" > templates/hello.html

以下のコマンドでコンテナイメージをビルドして、docker registryに登録します。

$ docker build -t hellob:latest .
$ docker tag hellob 192.168.64.2:32147/hellob
$ docker push 192.168.64.2:32147/hellob

コンテナアプリケーションを実行する


作成したコンテナイメージからコンテナアプリケーションを実行します。

以下のコマンドを使って、Injection済みのnamespaceにhelloaとhellobを実行し、サービスを公開します。Injectionの方法は、Microk8sでIstioによるABテストを試してみる(1/2)を参照してください。

ubuntu@microk8s-vm:~$ microk8s.kubectl run helloa --image=localhost:32147/helloa:latest --port=8080 -n istio-app
pod/helloa created
ubuntu@microk8s-vm:~$ microk8s.kubectl run hellob --image=localhost:32147/hellob:latest --port=8080 -n istio-app
pod/hellob created
ubuntu@microk8s-vm:~$ microk8s.kubectl expose pod helloa --port=8080 -n istio-app
service/helloa exposed
ubuntu@microk8s-vm:~$ microk8s.kubectl expose pod hellob --port=8080 -n istio-app
service/hellob exposed

Istioの設定をする


Gatewayを作成する


全てのホスト名をポート80で受け付けるIstioのGatewayを作成します。

yamlファイルを以下に示します。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: hello-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

以下のコマンドでgatewayリソースを作成します。

ubuntu@microk8s-vm:~$ microk8s.kubectl apply -f gateway.yaml -n istio-app

VirtualServiceを作成する


/helloのリクエストはhellobに、それ以外はhelloaに割り振るVirtualServiceを作成します。

VirtualService全体のyamlファイルを以下に示します。match.uri.prefixを使うことでURL毎に割り振り先を変更できます。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-switch-url-route
spec:
  hosts:
  - "*"
  gateways:
  - hello-gateway
  http:
  - match:
    - uri:
        prefix: /hello
    route:
    - destination:
        host: hellob
        port:
          number: 8080
  - route:
    - destination:
        host: helloa
        port:
          number: 8080

設定を確認する


以下のcurlコマンドを利用して確認すると、正しくルーティングされていることがわかります。192.168.64.2:31380はIstio Ingressgatewayの公開Serviceで、[multipass-vmのIP]:[NodePort]です。IngressgatewayをNodePortにする方法は、MicroK8sでIstioによるABテストを試してみる(2/2)を参照してください。

$ curl -s http://192.168.64.2:31380/
Hello A
$ curl -s http://192.168.64.2:31380/hello
Hello B

 

以上です。ページなどモジュール単位で分けるようなシステムには使えそうですね!