例子来源于《Kubernetes实践指南》一书。问题依然没有解决,求助大神。

测试环境

  • Centos 7.0
  • docker 1.13.1
  • kubectl v1.5.2
  • etcd 3.2.18

    都是通过yum安装,防火墙已关闭。

入坑问题

浏览器输入:http://ip:30001/demo/

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.

相关资源rc、pod、service、ep都创建成功,但是myweb的pods无法访问到mysql提供的数据库服务。

# kubectl get all
NAME DESIRED CURRENT READY AGE
rc/mysql 1 1 1 4h
rc/myweb 1 1 1 2h NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes 10.254.0.1 <none> 443/TCP 5d
svc/mysql 10.254.67.31 <none> 3306/TCP 4h
svc/myweb 10.254.62.177 <nodes> 8080:30001/TCP 2h NAME READY STATUS RESTARTS AGE
po/mysql-vc9x6 1/1 Running 0 4h
po/myweb-6k7s3 1/1 Running 0 2h
# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.1.171:6443 5d
mysql 172.17.0.4:3306 4h
myweb 172.17.0.2:8080 2h

定义文件

mysql-rc.yaml

apiVersion : v1
kind : ReplicationController
metadata :
name : mysql
spec :
replicas : 1
selector :
app : mysql
template :
metadata :
labels :
app : mysql
spec :
containers :
- name : mysql
image : mysql
ports :
- containerPort : 3306
env :
- name : MYSQL_ROOT_PASSWORD
value : "123456"

mysql-svc.yaml

apiVersion : v1
kind : Service
metadata :
name : mysql
spec :
ports :
- port : 3306
selector :
app : mysql

myweb-rc.yaml

apiVersion : v1
kind : ReplicationController
metadata :
name : myweb
spec :
replicas : 1
selector :
app : myweb
template :
metadata :
labels :
app : myweb
spec :
containers :
- name : myweb
image : tomcat-app:v1
ports :
- containerPort : 8080
env :
- name : MYSQL_SERVICE_HOST
value : 'mysql'
- name : MYSQL_SERVICE_PORT
value : '3306'

myweb-svc.yaml

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

启动方式是顺序执行kubectl create -f yaml

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

启动后即前面提到的问题。

查看源代码

既然无法建立连接,那先看下是如何建立连接的。登录到myweb的docker容器里面,查看index.jsp文件,主要内容如下:

java.sql.Connection conn=null;
java.lang.String strConn;
java.sql.Statement stmt=null;
java.sql.ResultSet rs=null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
try{
Class.forName("com.mysql.jdbc.Driver");
String ip=System.getenv("MYSQL_SERVICE_HOST");
String port=System.getenv("MYSQL_SERVICE_PORT");
ip=(ip==null)?"localhost":ip;
port=(port==null)?"3306":port;
System.out.println("Connecting to database..."); System.out.println("jdbc:mysql://"+ip+":"+port+"?useUnicode=true&characterEncoding=UTF-8");
conn = java.sql.DriverManager.getConnection("jdbc:mysql://"+ip+":"+port+"?useUnicode=true&characterEncoding=UTF-8", "root","123456"); stmt = conn.createStatement();
}catch(Exception ex){
...
}

就是用jsp创建了一个连接,连接的地址通过ENV方式注入。即在myweb-rc.yaml中配置的MYSQL_SERVICE_HOST和MYSQL_SERVICE_PORT环境变量指定。

既然指定名称为mysql无法解决,那换成mysql容器的IP是否可行呢?

更新配置

通过kubectl get ep 可以看到mysql暴露出的服务接口,那就用这个Ip试试。

修改myweb-rc.yaml:

        env :
- name : MYSQL_SERVICE_HOST
value : '172.17.0.4'

然后重新部署pod。但是结果还是一样。

网上看来的

网上有个说法说把 MYSQL_SERVICE_HOST 去掉不配置。但是从源码看,不配置的默认值是localhost,显然不能具备3306的端口服务。

网络谜团

通过docker登录到容器内,互相ping网络都是通的。

mysql:/# ping 172.17.0.4
PING 172.17.0.4 (172.17.0.4): 56 data bytes
64 bytes from 172.17.0.4: icmp_seq=0 ttl=64 time=0.155 ms
64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.139 ms
--- 172.17.0.4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.139/0.147/0.155/0.000 ms myweb:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.062 ms
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.062/0.075/0.089/0.016 ms

很显然网络是互通,但不知为何无法通过端口访问。

clusterIP

除了ep暴露的端口服务外,还有一个ClusterIP存在,是否可以通过ClusterIP访问呢。

# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes 10.254.0.1 <none> 443/TCP 5d
svc/mysql 10.254.67.31 <none> 3306/TCP 4h
svc/myweb 10.254.62.177 <nodes> 8080:30001/TCP 2h

发现ping ClusterIP全部都不通。至此不明白了。

三个IP

Kubernetes中管理主要有三种类型的IP:Pod IP 、Cluster IP 和 外部IP。

Pod IP

Kubernetes的最小部署单元是Pod。利用Flannel作为不同HOST之间容器互通技术时,由Flannel和etcd维护了一张节点间的路由表。Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:0.8.0的容器,容器内部与外部的通信经由此容器代理,该容器的IP也可以称为Pod IP。

Cluster IP

Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但Service Cluster IP就不一样了,没有网络设备为这个地址负责。它是由kube-proxy使用Iptables规则重新定向到其本地端口,再均衡到后端Pod的。

外部IP

Service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个Service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。

结论

依然不懂为什么会出现链接失败的情况,网络ping通的情况下,无法访问,这个坑填不上

怀疑方向:应该是配置层面的问题,可能是k8s的,也可能是docker的。

k8s踩坑记第2篇--3个IP折磨人的故事的更多相关文章

  1. k8s踩坑记第1篇--rc无法创建

    六一快乐!!! 什么是k8s,我不想解释,百度资料有很多,本系列只踩坑,不科普. 问题描述: 做Hello World的例子,结果get pods一直显示没有资源? 应用配置代码: apiVersio ...

  2. k8s踩坑记 - kubeadm join 之 token 失效

    抛砖引玉 环境 centos 7 amd64 两台 kubernetes 1.10 伴随着k8s1.10版本的发布,前天先在一台机器上搭建了k8s单机版集群,即既是master,也是node,按照经验 ...

  3. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  4. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  5. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  6. djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记

    情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...

  7. Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记

    前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...

  8. k8s采坑记 - 解决二进制安装环境下证书过期问题

    前言 上一篇k8s采坑记 - 证书过期之kubeadm重新生成证书阐述了如何使用kubeadm解决k8s证书过期问题. 本篇阐述使用二进制安装的kubernetes环境,如何升级过期证书? k8s配置 ...

  9. centos 7( linux )下搭建elasticsearch踩坑记

    原文:https://blog.csdn.net/an88411980/article/details/83150380 概述    公司最近在做全文检索的项目,发现elasticsearch踩了不少 ...

随机推荐

  1. 为什么说Java中只有值传递----说服自己

    在开始深入讲解之前,有必要纠正一下大家以前的那些错误看法了.如果你有以下想法,那么你有必要好好阅读本文. 错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递.如果是个引用,就 ...

  2. 自定义ClassLoader

    自定义classloader MapleClassLoader package com.maple; import java.io.*; public class MapleClassLoader e ...

  3. iPhone X进入DFU模式

    下面把iphoneX进dfu模式的方法分享给大家.在开机状态下,按一下音量加键后松开,然后按一下音量减键后松开,接着按住电源键,屏幕完全熄灭后,松开电源键,接着同时按住电源键和音量减,保持5秒左右,再 ...

  4. ES6新特性1:let和const

    本文摘自ECMAScript6入门,转载请注明出处. 一.let 1. ES6增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a ...

  5. P1569 [USACO11FEB]属牛的抗议

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row and numbered 1..N. The cow ...

  6. 五种典型开发周期模型(瀑布、V、原型化、螺旋、迭代)

    五种典型开发周期模型(瀑布.V.原型化.螺旋.迭代) 总结一下经常可以见到的系统开发周期模型.    在过去的几年里,可以很奇葩的碰到类似于“创业项目库”这种需求非常明确,工作量十分可控,对质量要求比 ...

  7. 设计一个分布式RPC框架

    0 前言 提前先祝大家春节快乐!好了,先简单聊聊. 我从事的是大数据开发相关的工作,主要负责的是大数据计算这块的内容.最近Hive集群跑任务总是会出现Thrift连接HS2相关问题,研究了解了下内部原 ...

  8. 一份可以落地靠谱iOS开发规范

    列出来的都是个人觉得在团队合作,代码阅读,代码维护中比较重要的一些点,没有什么空格 间距华而不实的东西在里面.涉及 命名规范.编码规范.代码管理规范 命名规范 项目名都遵循大驼峰命名.例如:MSMob ...

  9. vue实现两重列表集合,点击显示,点击隐藏的折叠效果,(默认显示集合最新一条数据,点击展开,显示集合所有数据)

    效果图: 默认显示最新一条数据: 点击显示所有数据: 代码: 说明:这里主要是 这块用来控制显示或者隐藏 根据当前点击的  这个方法里传递的index 对应  isShow 数组里的index  ,对 ...

  10. HDFS源码文件过大,IDEA打开失败解决方法

    问题现象:hadoop 3.1.0源码文件ClientNamenodeProtocolProtos大小4M+,IDEA打开时加载失败,ClientNamenodeProtocolPB报错找不到类. - ...