让我们尝试将Docker Compose迁移到Minikube + Kompose

首先

据说Kubernetes已经成为容器编排工具的事实标准已经有一段时间了。但是今年在AWS re:Invent上也宣布了Amazon EKS2的发布,这可能会让更多人开始涉足Kubernetes。

坦白说,我也是其中一员,最近开始涉足这个领域的技术并尝试了很多事情,所以今天我将总结一下。

更新纪录

    • 2020-05-09 Compose on Kubernetesについて追記

 

    2017-12-12 初稿投稿

用语解释

微型部署工具

这是一种可以在本地计算机上创建Kubernetes集群的工具。

搭建一个Kubernetes集群从零开始似乎非常困难(我从未尝试过),但使用它可以轻松进行测试。

这似乎可以在各种情况下应用。

Kompose 方便

这是一个将Docker Compose配置文件转换为适用于Kubernetes的工具。同时,还可以通过转换生成的资源集来使用类似docker-compose的接口进行控制。

在这篇文章中要做的事情。

    1. 我会准备一个基于PostgreSQL作为后端的简单Rails Web应用程序。

 

    1. 将这个Web应用程序容器化,并使用Docker Compose构建开发环境。

我将使用Kompose工具将Docker Compose配置转换为适用于Kubernetes的配置,并在Minikube上运行。

在之后的内容中,我们会假设读者对于Docker和Docker Compose有一定的了解。

请随时参考我在 https://github.com/progrhyme/compose-to-minikube 中整理的源代码和配置文件。

2020年5月9日追記:关于在Kubernetes上进行编排的问题

2018年12月,Docker公司发布了名为Compose on Kubernetes的工具。

只要使用这个工具,就可以直接通过以下命令将设置部署到Kubernetes集群,而无需将其转换为适用于Kubernetes的配置。

docker stack deploy --namespace my-app --compose-file /path/to/docker-compose.yml mystack

请注意,使用此功能需要安装 Docker Desktop 或 Docker Enterprise。
如果你有这些软件,这个方法可能更加方便。

必需品

ツール筆者環境のバージョン公式インストールガイドDocker17.05.0-cehttps://docs.docker.com/engine/installation/Docker Compose1.17.0https://docs.docker.com/compose/install/kubectlv1.8https://kubernetes.io/docs/tasks/tools/install-kubectl/Minikubev0.24.1https://github.com/kubernetes/minikube#installationKompose1.5.0http://kompose.io/installation/

由于所有的工具都支持Windows、Mac OS和Linux平台,所以您可以在任何一种环境下运行。

在这里,我们将省略每个具体的安装步骤。

我在Ubuntu 16.04上进行操作。

创建一个Rails应用程序

我們將按下列方式創建一個使用PostgreSQL的應用程式。

rails new my_app --database=postgresql

为了在后续操作中将数据库连接目标从环境变量传递,可以对 config/database.yml 进行如下编辑。

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV['DATABASE_URL'] %>

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

為了進行動作確認,將與控制器一起生成一個適當的模型。

bundle exec rails g scaffold person name:string age:integer

通过这样的方式,现在可以使用/people和/people/new等终点来尝试对数据库进行CRUD操作了。

将应用程序容器化为Docker。

为了在Docker中运行上述的Rails应用程序,我编写了以下的Dockerfile。

FROM ruby:2.4.2

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /app
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . ./

CMD bundle exec rails server -b 0.0.0.0 -p ${PORT:-3000}

你可以尝试使用下面的命令来构建Docker镜像。

docker build -t progrhyme/compose2minikube:v1 .

使用Docker Compose构建开发环境

为了让上面准备好的Rails应用程序与数据库进行互联并运行,我们将使用Docker Compose在本地机器上构建一个集群。

我已经创建了一个docker-compose.yml文件,其中包含如下配置。

version: "3"

services:
  db:
    image: postgres:9.5
    environment:
      - POSTGRES_USER=${MY_APP_DATABASE_USER}
      - POSTGRES_PASSWORD=${MY_APP_DATABASE_PASSWORD}
      - POSTGRES_DB=${MY_APP_DATABASE_NAME}
  rails:
    build:
      context: .
    ports:
      - "3000:${PORT:-3000}"
    environment:
      - DATABASE_URL=postgres://${MY_APP_DATABASE_USER}:${MY_APP_DATABASE_PASSWORD}@db:5432/${MY_APP_DATABASE_NAME}
    depends_on:
      - db

在DockerHub提供的PostgreSQL镜像中,可以通过上述环境变量来设置初始的数据库用户名、密码、数据库名。

将${MY_APP_DATABASE_USER}等变量设置为环境变量。

export MY_APP_DATABASE_USER=myapp
export MY_APP_DATABASE_PASSWORD=password
export MY_APP_DATABASE_NAME=my_app_development

在docker-compose.yml中,您可以像上面的设置一样直接在YAML中编写环境变量,从而创建一个相对简单的配置文件。

另外,如上所设定的 DATABASE_URL,Rails 容器内可以通过主机名 db 访问 db 服务。

确认动作

让我们尝试运行上面构建的集群。
您可以使用下面的命令启动db和rails容器。

docker-compose up

在 http://0.0.0.0:3000 上运行了Rails服务器,但由于未执行数据库迁移,因此访问时会出错。
您可以按照以下方式执行迁移:

docker-compose exec rails rake db:migrate

在这里,Rails 是从 Docker-compose 视角下的服务标识名。

当您再次访问,您将能够查看Rails的页面。

当您访问http://0.0.0.0:3000/people时,将显示使用scaffold生成的在Rails开发中熟悉的控制器页面。

image.png

使用Kompose在Minikube上运行应用程序。

在接下来的步骤中,我们将在Minikube上运行使用先前步骤创建的Docker Compose集群。

准备好了

请提前启动Minikube

首先,让我们提前启动Minikube。
※假设必需的工具已经安装好。

minikube start

我认为第一次可能需要花费相当长的时间来进行容器镜像的拉取等操作。一旦成功启动,您可以使用下面的命令来确认状态。

minikube status
minikube dashboard # ブラウザでダッシュボードを開く

通过执行minikube start命令,Minikube将设置为kubectl的上下文,并且您可以使用kubectl命令对集群进行操作。

在本地运行Docker注册表

Kubernetes没有构建容器镜像的功能。因此,您需要将示例应用程序的自定义镜像推送到某个注册表中,并配置从那里拉取镜像的设置。

由于这只是一个示例,所以可以将其放在DockerHub上,但在这里我们决定使用官方的Docker Registry镜像,在本地运行注册表服务器。

可以使用Docker轻松地运行注册表服务器,如下所示:

docker run -d -p 5000:5000 \
  -v ~/.dockerregistry:/var/lib/registry \
  --restart always \
  --name registry \
  registry:2

在这里,将本地机器的~/.dockerregistry目录作为持久化卷进行挂载。

把在上面构建的Docker镜像推送到此注册表中。

docker tag progrhyme/compose2minikube:v1 localhost:5000/progrhyme/compose2minikube:v1
docker push localhost:5000/progrhyme/compose2minikube:v1

将Docker Compose配置进行转换。

我們將使用 kompose convert 命令將剛才根據上述步驟創建的 docker-compose.yml 文件進行轉換。

$ cd <docker-compose.ymlがあるディレクトリ>
$ kompose convert
INFO Kubernetes file "db-service.yaml" created    
INFO Kubernetes file "rails-service.yaml" created 
INFO Kubernetes file "db-deployment.yaml" created 
INFO Kubernetes file "rails-deployment.yaml" created 

成功地更改了设置。

需要进行两个修改才能通过 `kompose up` 从本地机器访问服务。

    1. 在docker-compose.yml中,指定将容器映像推送到本地注册表。

在rails-service.yaml中,更改Service的类型。

每个的差异如下:

# docker-compose.yml
       :
       - POSTGRES_DB=${MY_APP_DATABASE_NAME}
    rails:
-     build:
-       context: .
+     image: localhost:5000/progrhyme/compose2minikube:v1
      ports:
        - "3000:${PORT:-3000}"
      environment:
       :

# rails-service.yaml
     :
     targetPort: 3000
    selector:
      io.kompose.service: rails
+   type: NodePort
  status:
    loadBalancer: {}

关于第二点,Kubernetes的Service类型默认为ClusterIP,只能从集群内部访问。
要使其从集群外部可以访问,需要将其设置为NodePort或LoadBalancer。

请确认动作

Kompose convert生成的配置文件中的资源附带了诸如 io.kompose.service 之类的键的label和selector。
Kompose使用这些label等来管理资源。

当执行kompose up命令时,将在Kubernetes集群中创建资源群。

$ kompose up
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need differe
nt kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. 

INFO Deploying application in "default" namespace 
INFO Successfully created Service: db             
INFO Successfully created Service: rails          
INFO Successfully created Deployment: db          
INFO Successfully created Deployment: rails       

Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.

已经创建了 Rails, DB 的部署和服务。

让我们使用 kubectl 命令来检查 Pod 的状态。

$ kubectl get pods
NAME                     READY     STATUS        RESTARTS   AGE
db-65644f9968-4zx5w      1/1       Running       0          5s
rails-6896549fc6-45mmw   1/1       Running       0          5s

由于新创建的DB容器是空的,所以需要再次进行DB迁移。
使用kubectl命令在rails容器中执行命令。

kubectl exec -it rails-6896549fc6-45mmw rake db:migrate

好的,实际上刚刚编辑的 rails-service.yaml 文件的更改尚未应用到集群上。
要应用这些更改,需要执行 kubectl apply 命令。

$ kubectl apply -f rails-service.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
service "rails" configured

尽管发出了警告,但已经应用了更改。

我将使用kubectl命令和minikube命令进行确认。

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
db           ClusterIP   None            <none>        55555/TCP        6m
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          1d
rails        NodePort    10.96.140.120   <none>        3000:31308/TCP   6m

$ minikube service list
|-------------|----------------------|------------------------|
|  NAMESPACE  |         NAME         |          URL           |
|-------------|----------------------|------------------------|
| default     | db                   | No node port           |
| default     | kubernetes           | No node port           |
| default     | rails                | http://127.0.0.1:31308 |
| kube-system | kube-dns             | No node port           |
| kube-system | kubernetes-dashboard | http://127.0.0.1:30000 |
|-------------|----------------------|------------------------|

使用浏览器访问 http://127.0.0.1:31308 ,可以确认Rails正在运行。
或者,您可以使用 minikube service rails 命令在浏览器中打开对应的URL。

我的感受

我认为,与Docker Compose相比,Kubernetes的配置更复杂,需要更多的先前知识。但是通过Kompose可以跳过这些步骤并创建可运行的配置,这非常方便。

我觉得使用Minikube和Kompose使得Kubernetes的开发环境变得更加方便了许多。

如果在实际环境中使用Kubernetes,那么建议按照以下方式构建开发环境。

以后想做的事情

我认为,在开发过程中,将项目目录挂载到先前介绍的docker-compose.yml中会很方便。不过,我还没有完全研究出在Kubernetes中的操作方法,我想试试看。

绑成一束

可能因为尝试了很多新的元素,所以这篇文章里有些地方可能解释不足或者不够清楚。同时,也有很多是我刚试过的事情。

如果有任何错误或其他问题,请在评论中告知。

请参考

https://kubernetes.io/ … Kubernetes公式サイト

Running Kubernetes Locally via Minikube | Kubernetes … MinikubeのGetting Startedガイド

http://kompose.io/ … Kompose公式サイト

https://docs.docker.com/ … Dockerドキュメンテーション

https://docs.docker.com/compose/ … Docker Compose

From Docker Compose to Minikube – Skillshare Writings – Medium

Skillshareでプロダクション/QA環境をKubernetesに移行したことに続いて、開発環境をDocker ComposeからMinikubeに移行した事例。

注脚

容器编排:从fleet迁移到Kubernetes | CoreOS ↩

亚马逊弹性容器服务 for Kubernetes。https://aws.amazon.com/eks/ ↩

使用Docker Compose和朋友简化Kubernetes – Docker博客 ↩

广告
将在 10 秒后关闭
bannerAds