Kubernetes 入门练习

版权声明:版权归博主所有,转载请带上本文链接!联系方式:[email protected] https://blog.csdn.net/isea533/article/details/86771615

Kubernetes 最新版本安装过程和注意事项 中,我已经配置好了 Kubernetes 的基础环境,接下来要按照 Kubernetes 权威指南 书中的内容简单做个练习。

Kubernetes 使用的 v1.13.3 版本,在实际操作时发现和书上 v1.6.3 版本的命令没太大区别,但是由于例子中使用的 mysql 没有指定版本,因此,不管 Kubernetes 版本如何,跟着书上第一章的入门操作时,会遇到各种各样的问题,错误的根源在 mysql 版本,但是根据错误信息解决问题的过程中,往往让人跑偏。

我自己为了方便管理,直接在 / 创建了 /k8s/chapter01 目录。由于我也是正在入门,对概念性的东西以及配置参数理解不深,所以本文只是能让你完成某些功能,并不能让你知道为什么这么做,如果想要了解,可以找一些资料学习。

如果你正好也买了《Kubernetes 权威指南》这本书,先按照 Kubernetes 最新版本安装过程和注意事项 配置好环境,然后再配合本文看第 1 章 Kubernetes 入门,你可以避免很多坑,会让你学的更顺利。

这些坑没必要自己踩一遍,我认为这是写书的人没有考虑周全导致的,是书的问题。

1. 配置 MySQL 服务

1.1 配置 MySQL ReplicationController

创建 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:5.6.43
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

如果你从来没接触过 yaml 格式,要切记,所有属性名的冒号后面必须有一个空格,必须形如:name:_mysql下划线代表空格,不要真的输入一个下划线),而不能是 name:mysql

本文中的配置和书上的区别在 image: mysql:5.6.43,这里指定了一个 5.6 的最新版本,不用 5.7 和最新的 8 是因为驱动或者密码机制有很多不同的地方,基本上指定这个版本后,就没有了。

1.2 下载用到的镜像

既然用到了 mysql:5.6.43,建议先通过 docker 下载下来,执行 docker pull mysql:5.6.43

1.3 根据配置创建 Pod

只需要执行命令 kubectl create -f mysql-rc.yaml 即可。

如果出错想要删除,可以执行: kubectl delete -f mysql-rc.yaml

启动后,通过 kubectl get pods 查看状态。

1.4 配置 MySQL 服务

创建 mysql-svc.yaml 配置文件,写入以下内容:

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: NodePort
  ports:
  - port: 3306
    nodePort: 30002
  selector:
    app: mysql

为了方便外网连接数据库查看数据库问题,这里参考书上对 tomcat 的配置,增加了 NodePort,这样配置后,外网能通过 30002 端口访问 MySQL 数据库。

1.5 启动 MySQL 服务

只需要执行命令 kubectl create -f mysql-svc.yaml(删除和前面方式一样,改成 delete 即可)。

然后通过 kubectl get svc 查看服务状态。

此时你也可以通过 Navicat 等数据库管理工具连接到 MySQL 数据库查看。

2. 配置 Tomcat 服务

和前面一样的套路,这里不在细分。
创建 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: kubeguide/tomcat-app:v1
        ports:
        - containerPort: 8080

这里用到了 kubeguide/tomcat-app:v1 镜像,通过 docker 下载即可。

特别注意,上面配置中有个 replicas: 2,因此通过该配置创建 Pod 时,会出现两个不同的 Pod。

执行命令 kubectl create -f myweb-rc.yaml 创建 Pod,只需要执行一次,但是会出现两个 Pod,例如我这里的输出如下:

[root@k8s-master chapter01]# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
mysql-wjmlk   1/1     Running   0          41m
myweb-j94ws   1/1     Running   0          26m
myweb-vvlkg   1/1     Running   0          26m

接下来创建对应的服务,文件为 myweb-svc.yaml,内容如下:

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

这里对外公开了 30001 端口。执行命令启动服务 kubectl create -f myweb-svc.yaml,此时所有的服务如下:

[root@k8s-master chapter01]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          156m
mysql        NodePort    10.100.172.159   <none>        3306:30002/TCP   42m
myweb        NodePort    10.105.77.133    <none>        8080:30001/TCP   28m

此时访问 http://K8s主机IP:30001/demo/ 即可查看效果。

3. 其他

如何连上 docker 容器?

执行 docker ps 查看当前运行的容器(部分)列表如下:

[root@k8s-master chapter01]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS               NAMES
db1fafff0e93        a29e200a18e9           "catalina.sh run"        31 minutes ago      Up 31 minutes                           k8s_myweb_myweb-vvlkg_default_00f1ad16-2ae7-11e9-8861-000c293fb758_0
01a31ce5551e        a29e200a18e9           "catalina.sh run"        31 minutes ago      Up 31 minutes                           k8s_myweb_myweb-j94ws_default_00f2305e-2ae7-11e9-8861-000c293fb758_0
51a678ae4a2e        k8s.gcr.io/pause:3.1   "/pause"                 31 minutes ago      Up 31 minutes                           k8s_POD_myweb-j94ws_default_00f2305e-2ae7-11e9-8861-000c293fb758_0
74397325fb22        k8s.gcr.io/pause:3.1   "/pause"                 31 minutes ago      Up 31 minutes                           k8s_POD_myweb-vvlkg_default_00f1ad16-2ae7-11e9-8861-000c293fb758_0
15042ef46260        96e41ac53eac           "docker-entrypoint.s…"   45 minutes ago      Up 45 minutes                           k8s_mysql_mysql-wjmlk_default_04017175-2ae5-11e9-8861-000c293fb758_0
31fda404c387        k8s.gcr.io/pause:3.1   "/pause"                 45 minutes ago      Up 45 minutes                           k8s_POD_mysql-wjmlk_default_04017175-2ae5-11e9-8861-000c293fb758_0

复制想要连接的容器 ID,例如第一个的 Tomcat 容器 db1fafff0e93,执行下面命令:

docker exec -it db1fafff0e93 /bin/bash

然后就进入了容器中,此时命令行显示如下:

root@myweb-vvlkg:/usr/local/tomcat# 

通过 cd webapps/demo/ 进入 web 项目的目录,可以看看 index.jsp 的内容,执行 cat index.jsp 输出如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HPE University Docker&Kubernetes Learning</title>
</head>
<body  align="center">

	<%   
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...");

      conn = java.sql.DriverManager.getConnection("jdbc:mysql://"+ip+":"+port+"?useUnicode=true&characterEncoding=UTF-8", "root","123456");
      
      stmt = conn.createStatement();
      String sql = "show databases like 'HPE_APP'";
      rs =stmt.executeQuery(sql);
    if(!rs.next())
    {
      sql = "CREATE DATABASE HPE_APP DEFAULT CHARSET utf8 COLLATE utf8_general_ci";
      stmt.executeUpdate(sql);
      System.out.println("Database created successfully...");
      sql = "CREATE TABLE HPE_APP.T_USERS (ID INT NOT NULL AUTO_INCREMENT ,   USER_NAME VARCHAR(100),   LEVEL VARCHAR(20), PRIMARY KEY ( ID ))";
      stmt.executeUpdate(sql);
       System.out.println("table created successfully...");
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('me','100')";
      stmt.executeUpdate(sql);
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('our team','100')";
      stmt.executeUpdate(sql);
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('HPE','100')";
      stmt.executeUpdate(sql);
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('teacher','100')";
      stmt.executeUpdate(sql);
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('docker','100')";
      stmt.executeUpdate(sql);
      sql="insert into HPE_APP.T_USERS(USER_NAME,LEVEL) values('google','100')";
      stmt.executeUpdate(sql);
       System.out.println("demo records inserted successfully...");
      }
      %>
      <h2>Congratulations!!</h2>
     <br></br>
	 <input type="button" value="Add..." onclick="location.href='input.html'" >
	     <br></br>
      <TABLE align="center"  border="1" width="600px">
   <TR>
      <TD>Name</TD>
      <TD>Level(Score)</TD>
   </TR>

      <%
      rs = stmt.executeQuery("SELECT * FROM  HPE_APP.T_USERS order by id desc");

    while(rs.next()) {
    System.out.println("find record");
%>
 <TR>
      <TD><%= rs.getString("USER_NAME") %></TD>
      <TD><%= rs.getString("LEVEL") %></TD>
   </TR>
<%   
    }
    %>
  </TABLE>
    <% 
      
   }catch(Exception se){
   se.printStackTrace();
   %>
   
  <h3> Error:<%= se %></h3>
   <%
   }finally{
      //finally block used to close resources
      try{
         if(stmt!=null)
            stmt.close();
      }catch(Exception se2){
      }// nothing we can do
      try{
         if(conn!=null)
            conn.close();
      }catch(Exception se){
         se.printStackTrace();
      }//end finally try
   }//end try
   
   System.out.println("Goodbye!");
   %>  
</body>
</html>

可以看到两个关键的环境变量:MYSQL_SERVICE_HOSTMYSQL_SERVICE_PORT,控制台执行命令查看:

root@myweb-vvlkg:/usr/local/tomcat/webapps/demo# echo $MYSQL_SERVICE_HOST
10.100.172.159

这里的 IP 和上面执行 kubectl get svc 时 mysql 对应的虚拟 IP 相同。

执行 export 看看所有的环境变量,输出如下:

root@myweb-vvlkg:/usr/local/tomcat/webapps/demo# export
declare -x CATALINA_HOME="/usr/local/tomcat"
declare -x HOME="/root"
declare -x HOSTNAME="myweb-vvlkg"
declare -x JAVA_DEBIAN_VERSION="7u101-2.6.6-1~deb8u1"
declare -x JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64/jre"
declare -x JAVA_VERSION="7u101"
declare -x KUBERNETES_PORT="tcp://10.96.0.1:443"
declare -x KUBERNETES_PORT_443_TCP="tcp://10.96.0.1:443"
declare -x KUBERNETES_PORT_443_TCP_ADDR="10.96.0.1"
declare -x KUBERNETES_PORT_443_TCP_PORT="443"
declare -x KUBERNETES_PORT_443_TCP_PROTO="tcp"
declare -x KUBERNETES_SERVICE_HOST="10.96.0.1"
declare -x KUBERNETES_SERVICE_PORT="443"
declare -x KUBERNETES_SERVICE_PORT_HTTPS="443"
declare -x LANG="C.UTF-8"
declare -x MYSQL_PORT="tcp://10.100.172.159:3306"
declare -x MYSQL_PORT_3306_TCP="tcp://10.100.172.159:3306"
declare -x MYSQL_PORT_3306_TCP_ADDR="10.100.172.159"
declare -x MYSQL_PORT_3306_TCP_PORT="3306"
declare -x MYSQL_PORT_3306_TCP_PROTO="tcp"
declare -x MYSQL_SERVICE_HOST="10.100.172.159"
declare -x MYSQL_SERVICE_PORT="3306"
declare -x OLDPWD="/usr/local/tomcat"
declare -x OPENSSL_VERSION="1.0.2h-1"
declare -x PATH="/usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/usr/local/tomcat/webapps/demo"
declare -x SHLVL="1"
declare -x TERM="xterm"
declare -x TOMCAT_MAJOR="8"
declare -x TOMCAT_TGZ_URL="https://www.apache.org/dist/tomcat/tomcat-8/v8.0.35/bin/apache-tomcat-8.0.35.tar.gz"
declare -x TOMCAT_VERSION="8.0.35"

4. 总结

入门只是一个很简单的例子,但是因为书中没有指定 mysql 的版本,你会遇到各种各样的问题,细节很重要,有一点点的不认真,都可能要付出百倍的时间来解决,所以希望本文能节省大家的时间,让大家能避免类似的错误。

猜你喜欢

转载自blog.csdn.net/isea533/article/details/86771615