【Kubernetes】

【k8s学习】在minikube上布署MongoDB和Mongo

2022-06-20  本文已影响0人  伊丽莎白2015

【本文目标】
在minikube上部署MongoDB和Mongo-express,MongoDB作为内部项目(internal service),Mongo-express会连接到Mongo服务上,Mongo-express会对外暴露。

注:本文用到的yaml配置文件有大神在git上已经上传了,可以直接使用,github地址:https://github.com/Einsteinish/mongo-mongoexpress-minikube

【前置文章】

【运行环境 】

1. 架构

用到的Component:

架构:
架构

可以看到:

运行环境

运行在minikube上,并且集群中没有部署项目:


image.png

2. MongoDB部署

2.1 MongoDB docker hub

首先我们想要运行的是MongoDB最新版,docker hub地址:https://hub.docker.com/_/mongo
下拉页面,可以看到默认的Port是:27017

image.png

其次是查看环境变量,可以看到我们需要定义MongoDB的username和password,变量名称为:MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD

image.png
2.2 定义Secret

我们在定义的时候,不会直接把username和password在mongodb-deployment.yaml中hardcode,因为mongodb-deployment.yaml通常会checkin到Git repository,如果直接写那么所有人都能看到,这样不安全。所以我们会使用Kubernetes的Secret组件,这样用户名和密码就存在Kubernetes中,而不是Git repository中。

基于以上原因,我们先定义Secret组件,配置文件叫:mongodb-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: mongodb-secret
type: Opaque
data:
  mongo-root-username: dXNlcm5hbWU=
  mongo-root-password: cGFzc3dvcmQ=

我们可以用命令先把想要的明文加密成密文后,再放到上述的data中。

image.png

通过mongodb-secret.yaml先创建出Secret组件:

kubectl apply -f mongodb-secret.yaml

可以看到Secret组件创建成功: image.png
2.3 开始定义mongodb-deployment.yaml文件

在Deployment文件中会引用到2.2中定义的Secret。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mondodb-deployment
  labels:
    app: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-password
通过配置文件创建deployment: image.png 可以看到mongo-db的Pod运行起来了: image.png
2.4 定义MongoDB的internal service:

我们接着上述的Deployment定义,把MongoDB service也放在同一个文件中,用---分割开(上述mongo-deployment.yaml改名为mongodb.yaml):

---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  selector:
    app: mongodb
  ports:
  - protocol: TCP
    port: 27017
    targetPort: 27017

通过mongodb.yaml创建Service,可以看到它会先提示Deployment没有改动,然后再提示Service创建了。


image.png 查看Service,这里的Port指的是上述定义的port(即Service自己对外暴露的端口),不是targetPort: image.png

查看Pod和Service具体信息,可以看到Service的Endpoint信息,指向的IP是Pod的IP:


image.png
【总结】至此,MongoDB相关的组件都创建好了:

3. MongoDB-express部署

3.1 MongoDB-express docker hub

MongoDB-express docker hub地址:https://hub.docker.com/_/mongo-express

可以下拉查看基础信息,默认的port为: image.png 部署MongoDB-express需要的信息: image.png
3.2 定义ConfigMap

上述三个变量(MongoDB地址,用户名和密码),其中用户名和密码我们可以从Secret组件中读取(查看2.2章),剩下来的MongoDB地址,没有必要加密,但为什么不放在mongodb-express.yaml中是因为,可能MongoDB以后换地址了,那么作为读取他的mongodb-express项目,不想要重新打包并部署,所以我们使用组件ConfigMap来定义MongoDB地址。

新建配置mongodb-configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-configmap
data:
  database_url: mongodb-service
创建ConfigMap组件: image.png 查看ConfigMap: image.png
3.3 定义MongoDB-express Deployment:

新建mongodb-express.yaml文件,用来定义Deployment和Service,首先是Deployment,可以看到定义了Pod中的容器的containerPort为8081,三个变量其中用户名和密码从Secret组件中读取(valueFrom定义的是secretKeyRef),而server信息,是从ConfigMap组件中读取(valueFrom定义的是configMapKeyRef。)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo-express
  labels:
    app: mongo-express
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo-express
  template:
    metadata:
      labels:
        app: mongo-express
    spec:
      containers:
      - name: mongo-express
        image: mongo-express
        ports:
        - containerPort: 8081
        env:
        - name: ME_CONFIG_MONGODB_ADMINUSERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-username
        - name: ME_CONFIG_MONGODB_ADMINPASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-password
        - name: ME_CONFIG_MONGODB_SERVER
          valueFrom:
            configMapKeyRef:
              name: mongodb-configmap
              key: database_url
创建Deployment: image.png 可以看到mongodb-express的Pod运行了: image.png
3.4 定义MongoDB-express的external service

我们在上述的mongodb-express.yaml中追加Service组件的定义,用---分隔,这里和上述定义mongodb的internal service略有不同的是,我们在mongodb-express中需要定义external service,以便外部的客户可以通过浏览器访问express dashboard页面。所以我们在spec中需要额外定义service的type为LoadBalancer,表示给这个service一个外部的IP以便可以接收外部的请求。

注:内部的internal service没有定义type,不定义type的时候,默认为ClusterIP,也是load balanced,即如果有两个mongodb的Pod,我们访问mongo-service,那么也会做负载均衡跳到两个Pod中的一个。

所以type定义为LoadBlancer是在负载均衡的基础上再做了暴露Service IP的作用。

另外,除了Service自身的端口port,以及需要转发的Pod中的container的端口targetPort外,我们还需要定义第三种端口,即nodePort,这个端口表示的意思是给外部IP地址访问时用的端口,一般来说范围在30000~32767之间。在例子中,我们定义为30000:

---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-express-service
spec:
  selector:
    app: mongodb-express
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 8081
      targetPort: 8081
      nodePort: 30000
创建Service: image.png

查看Service:

如上述所说,在minikube的external-ip中,显示的是<pending>,表示还没有分配外部IP,所以我们需要手动分配:
这个命令表示给service mongo-express-service分配一个public的IP地址,这个是minikube only的,所以你看到的是minikube的命令,而不是kubectl:

minikube service mongo-express-service

3.5 MacOS,vm-driver=docker,对外暴露有点问题
我的系统是MacOS,然后minikube选择的虚拟driver是docker,在service expose的过程中出现了一些问题,发现命令停在了以下状态并且无法正确expose: image.png

网上看了一圈说是MacOS上的minikube用docker作虚拟driver的时候,network会有点问题,参考:https://github.com/kubernetes/minikube/issues/11193,解决办法是可以安装https://github.com/yuzhaopeng/minikube-mac-network,中文文档有:https://zhuanlan.zhihu.com/p/446915171,(这个解决办法我没有试过)。

**但我觉得太麻烦了,直接改个虚拟driver,用hyperkit代替docker。

3.6 安装新的vm-driver:hyperkit

hyperkit是轻量级虚拟化工具包。先安装hyperkit:**

brew install hyperkit

安装完毕: image.png

启动minikube,这次使用的是vm-driver=hyperkit,而不是docker:

minikube start --vm-driver=hyperkit

3.7 使用hyperkit作为vm-driver后,再次启动,并对外暴露服务

启动好了之后,再重新kubectl apply -f <filename>上面的文件,本文用到的文件有大神在git上已经上传了,可以直接使用,git地址:https://github.com/Einsteinish/mongo-mongoexpress-minikube

在组件(secret, configmap, deployment, pod, replicaset, service)都创建好了之后,再次使用minikube的命令进行对外暴露:

minikube service mongo-express-service --url

返回:http://192.168.64.4:30000

使用minikube service命令查看所有的服务:

minikube service list

image.png 使用浏览器打开: image.png

4. 测试

在mongo-express UI页面上新增一个database: image.png

这个请求:首先会跳到Mongo Express External Service --> 然后再转发到Mongo Express Pod上 --> 再通过Pod上的url转到Mongo DB Internal Serivce --> 再转发到Mongo DB Pod


参考:
https://www.youtube.com/watch?v=X48VuDVv0do
https://www.bogotobogo.com/DevOps/Docker/Docker_Kubernetes_MongoDB_MongoExpress.php
https://github.com/Einsteinish/mongo-mongoexpress-minikube

上一篇下一篇

猜你喜欢

热点阅读