首次使用 Kubernetes(Minikube) Pod 进行协作和数据持久化

总结

继上次“在初次使用kubernetes(Minikube)的Windows环境进行教程+α之后”,我尝试了应用服务器Pod和数据库服务器Pod的协作,并以备忘录形式记录下我所理解的内容。

当执行minikube命令时,请以管理员权限执行。

执行环境

    • Windows 10 pro

 

    • Minikube v0.28.0

 

    Docker Version 18.06.1-ce-win73 (19507)

立即开始操作指南

获取示例应用程序

请使用一个简单的示例应用程序,从Node.js应用程序中获取Redis数据并进行显示,因此请将源代码克隆到本地。

为了方便在本地进行预先操作确认,我们还准备了docker-compose。请根据需要灵活使用。

const http = require('http');
const redis = require('redis');
let redis_host = 'redis';
let redis_port = 6379;

// k8s環境の場合は、redisの接続先とポートは環境変数から取得
if (process.env.MODE && process.env.MODE == 'k8s') {
    redis_host = process.env.SAMPLE_REDIS_SERVICE_HOST;
    redis_port = process.env.SAMPLE_REDIS_SERVICE_PORT;
}
const client = redis.createClient({
    host: redis_host,
    port: redis_port
});

// 表示用の変数をredisに保存する
client.set('sample', 'hello world');
client.set('sample2', 'hello Qiita');

// 表示用の変数
let redis_val = '';
client.get('sample', function (err, data) {
    redis_val += '<li>' + data + '</li>';
});
client.get('sample2', function (err, data) {
    redis_val += '<li>' + data + '</li>';
});

const handleRequest = function (request, response) {
    console.log('Received request for URL: ' + request.url);
    response.writeHead(200);
    response.end('<h1>redis value:</h1><ul>' + redis_val + '</ul>');
};

// echo env
const envs = process.env;
console.log(envs);

const www = http.createServer(handleRequest);
www.listen(3000);

2. 更改Docker客户端的连接目标

请预先将Docker客户端的目标更改为Minikube,与上次一样。

> minikube docker-env --shell powershell | Invoke-Expression

> docker images

# kubernetes関連のイメージが表示されればOK

3. 形象构建

在Minikube上构建示例应用程序的Docker镜像。

> docker build -t sample-app:v1 --no-cache ./app

4. 部署

将其部署到Minikube上。

> kubectl apply -f ./deployment_k8s_sample_app.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-redis
  labels:
    app: sample-redis
    type: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-redis
      type: db
  template:
    metadata:
      labels:
        app: sample-redis
        type: db
    spec:
      containers:
      - name: sample-redis
        image: redis:4
        ports:
        - containerPort: 6379
        # redis-volumeボリュームとredisのデータ領域の/data
        volumeMounts:
        - mountPath: /data
          name: redis-volume
      # データ永続化するためのボリューム
      volumes:
      - name: redis-volume
        # ボリュームの種別はhostPath
        hostPath:
          path: /home/docker/redis-data
          # ディレクトリがなければ作る
          type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
  name: sample-redis
  labels:
    app: sample-redis
    type: db
spec:
  type: LoadBalancer
  selector:
    app: sample-redis
    type: db
  ports:
  - port: 6379
    targetPort: 6379
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  labels:
    app: sample-app
    type: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
      type: app
  template:
    metadata:
      labels:
        app: sample-app
        type: app
    spec:
      containers:
      - name: sample-app
        image: sample-app:v1
        ports:
        - containerPort: 3000
        # k8s環境用で稼働しているかどうかの環境変数
        env:
        - name: MODE
          value: k8s
---
apiVersion: v1
kind: Service
metadata:
  name: sample-app
  labels:
    app: sample-app
    type: app
spec:
  type: LoadBalancer
  selector:
    app: sample-app
    type: app
  ports:
  - port: 3000

确认

确认Pod

> kubectl get po

NAME                            READY     STATUS    RESTARTS   AGE
sample-app-694d9bf49f-66b7b     1/1       Running   0          37m
sample-redis-55c5b46859-n7pnt   1/1       Running   0          42m

确认服务 (Confirmation of service)

> kubectl get svc

NAME           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP      10.96.0.1        <none>        443/TCP          20d
sample-app     LoadBalancer   10.101.237.112   <pending>     3000:32482/TCP   43m
sample-redis   LoadBalancer   10.111.4.116     <pending>     6379:32400/TCP   43m

确认应用程序

> minikube service sample-app

只要在浏览器中显示以下内容,就可以了。

redis value:

hello world
hello Qiita

解释

可以通过获取与Docker相同的DB Pod(redis)连接信息环境变量来实现。但是,必须将其作为服务公开。通过使用服务,可以实现流量负载均衡、服务发现以及在集群内使用DNS。因此,从环境变量中获取应用程序的redis连接目标。

服务器.js


// k8s環境の場合は、redisの接続先とポートは環境変数から取得
// MODEはDeploymentで環境変数として設定しています
if (process.env.MODE && process.env.MODE == 'k8s') {
    redis_host = process.env.SAMPLE_REDIS_SERVICE_HOST;
    redis_port = process.env.SAMPLE_REDIS_SERVICE_PORT;
}

我们来检查一下环境变量吧。

kubectl logs sample-app-694d9bf49f-66b7b

{ KUBERNETES_SERVICE_PORT: '443',
  KUBERNETES_PORT: 'tcp://10.96.0.1:443',
  SAMPLE_APP_PORT_3000_TCP_ADDR: '10.97.74.141',
  NODE_VERSION: '6.9.2',
  HOSTNAME: 'sample-app-565db6587d-xtblr',
  MODE: 'k8s',
  SAMPLE_APP_PORT_3000_TCP_PORT: '3000',
  SAMPLE_APP_PORT_3000_TCP_PROTO: 'tcp',
  HOME: '/root',
  SAMPLE_REDIS_SERVICE_HOST: '10.103.205.192',
  SAMPLE_APP_PORT_3000_TCP: 'tcp://10.97.74.141:3000',
  SAMPLE_APP_SERVICE_HOST: '10.97.74.141',
  SAMPLE_REDIS_PORT: 'tcp://10.103.205.192:6379',
  SAMPLE_REDIS_SERVICE_PORT: '6379',
  SAMPLE_REDIS_PORT_6379_TCP_ADDR: '10.103.205.192',
  KUBERNETES_PORT_443_TCP_ADDR: '10.96.0.1',
  PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
  SAMPLE_REDIS_PORT_6379_TCP_PORT: '6379',
  KUBERNETES_PORT_443_TCP_PORT: '443',
  SAMPLE_REDIS_PORT_6379_TCP_PROTO: 'tcp',
  SAMPLE_APP_PORT: 'tcp://10.97.74.141:3000',
  SAMPLE_APP_SERVICE_PORT: '3000',
  NPM_CONFIG_LOGLEVEL: 'info',
  KUBERNETES_PORT_443_TCP_PROTO: 'tcp',
  SAMPLE_REDIS_PORT_6379_TCP: 'tcp://10.103.205.192:6379',
  KUBERNETES_PORT_443_TCP: 'tcp://10.96.0.1:443',
  KUBERNETES_SERVICE_PORT_HTTPS: '443',
  KUBERNETES_SERVICE_HOST: '10.96.0.1',
  PWD: '/' }

数据的持久化

为了持久化数据,我们将卷定义为hostPath。hostPath可以将任何节点上的路径作为卷使用。如果只是一个单节点的Minikube环境,那么这没有问题,但是在多节点配置的情况下,我们必须考虑数据的一致性,因此需要使用其他类型的卷。

以下是数据持久化验证步骤的内容。

1. 部署、服务的删除

为了确认数据是否持久化,我们将先进行一次删除操作。

> kubectl delete -f ./deployment_k8s_sample_app.yml

修改server.js文件

我会将代码中保存值到Redis的部分注释掉。


// 表示用の変数をredisに保存する
// client.set('sample', 'hello world');
// client.set('sample2', 'hello Qiita');

3. 重塑形象

标签使用v2进行构建。

> docker build -t sample-app:v2 --no-cache ./app

编辑deployment_k8s_sample_app.yml文件。

将部署的图像更改为v2版本。

~中略~
      containers:
      - name: sample-app
        image: sample-app:v2
~中略~

5. 部署再次完成

> kubectl apply -f ./deployment_k8s_sample_app.yml

deployment.apps "sample-redis" created
service "sample-redis" created
deployment.apps "sample-app" created
service "sample-app" created

动作验证

可以通过前述的方式确认数值


> minikube service sample-app

广告
将在 10 秒后关闭
bannerAds