前面已经讲过docker、kubernetes以及私有镜像仓库的部署,本篇以一个完全使用docker构建web应用(tomcat+mysql)的完整示例进行探讨。


实验环境:

本篇的实验需要在kubernetes&docker系列01~03三篇的成果上继续,请自行查阅。

此外,本次部署测试与之前单独部署tomcat不一样,因为需要测试使用tomcat连接mysql数据库,所以需要有一个能够访问数据库的web,所以首先需要pull一个带有连接数据库测试页web的tomcat镜像,kubeguide/tomcat-app:v1这个仓库的tomcat镜像包含该测试程序

另外实验之前记得将前面创建的docker先删除了,避免影响测试。


1、镜像仓库主机(10.1.30.34)

pull拉取tomcat镜像

docker pull kubeguide/tomcat-app:v1

tag为tomcat镜像重新打标签

docker tag docker.io/kubeguide/tomcat-app:v1 registry:5000/kubeguide/tomcat-app:v1

push打标签后的tomcat镜像到私有仓库

docker push registry:5000/kubeguide/tomcat-app:v1

pull拉取mysql镜像

docker mysql:5.7

tag为mysql镜像重新打标签

docker tag docker.io/library/mysql:5.7 registry:5000/mysql:5.7

push打标签后的mysql镜像到私有仓库

docker push registry:5000/mysql:5.7


2、创建yaml文件(Master主机10.1.30.34)

创建tomcat的rc.yaml文件

vi myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 2
  selector:
    app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
        - name: myweb
          image: registry:5000/kubeguide/tomcat-app:v1
          ports:
          - containerPort: 8080
          env:
            - name: MYSQL_SERVICE_HOST
              value: 'mysql'
            - name: MYSQL_SERVICE_PORT
              value: '3306'

#注意image:需要改为私有仓库打标签后的镜像,replicas:2表示2个同时创建2个docker实例。

创建tomcat的svc.yaml文件

vi myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: myweb
spec:
  type: NodePort
  ports:
    - port: 8080
      name: myweb-svc
      nodePort: 30001
  selector:
    app: myweb

创建mysql的rc.yaml文件

vi mysql-rc.sql
apiVersion: v1
kind: ReplicationController # kind 指明此资源对象的类型
metadata:
  name: mysql # 元数据 - 此资源对象的名称,全局唯一
spec:
  replicas: 2 # Pod 副本期待的数量
  selector: 
    app: mysql # label 标签,选择有此 label 的 Pod
  template: # 定义创建 Pod 实例的模板 
    metadata: 
      labels:
        app: mysql # Pod 的 label,对应上面 rc 的 selector
    spec:
      containers: # 定义 Pod 中的容器
        - name: mysql # 容器名称
          image: registry:5000/mysql:5.7 # 使用的 docker image
          ports:
          - containerPort: 3306 # 容器暴露的端口号
          env:  # 注入到容器内的环境变量
          - name: MYSQL_ROOT_PASSWORD
            value: '123456'

创建mysql的rc.yaml文件

vi mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: NodePort
  ports: 
    - port: 3306
  selector:
    app: mysql

3、创建docker实例

kubectl apply -f mysql-rc.yaml
kubectl apply -f mysql-svc.yaml
kubectl apply -f myweb-rc.yaml
kubectl apply -f myweb-svc.yaml

直接访问Node测试

http://10.1.30.35:30001/或者http://10.1.30.36:30001/,发现tomcat能正常访问。

但是如果访问http://10.1.30.36:30001/demo,会报错误。正面tomcat是没有问题的,但是tomcat与mysql通信有问题。

Error:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 
The last packet sent successfully to the server was 0 milliseconds ago. 
The driver has not received any packets from the server.

因此计划进入容器内查看情况

kubectl exec -it myweb-c8r09 -- /bin/bash

#myweb-c8r09可以通过 kubectl get pod查看,改为想要进入的POD的名称。

然后发现时DNS解析的问题,myweb-c8r09写好的代码指向mysql,但是根本找不到mysql的DNS解析记录,手动添加一下。

先在Master上查看各个pod的IP地址。

kubectl get pod -o wide

然后进入myweb-c8r09容器,手动往hosts文件添加解析记录

echo "173.16.48.3 mysql" >> /etc/hosts

然后重新刷新http://10.1.30.36:30001/demo,发现访问正常了。

查询了一下,k8s好像内部这个网络还需要添加个DNS服务什么的,这个等待后面有机会再研究。