16boke - 一路博客

1、K8S初体验--单机部署kubernetes

一、安装

操作系统选择centos7。

(1)关闭Centos自带的防火墙服务:

systemctl disable firewalld

systemctl stop firewalld

(2)安装etcd和kubernetes(会自动安装Docker软件)

yum install -y etcd kubernetes

(3)安装好后修改配置文件

1、Docker配置文件为/etc/sysconfig/docker,其中OPTIONS的内容修改为:

OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'

2、Kubernetes apiserver配置文件为/etc/kubernetes/apiserver,把--admission_control参数中的ServiceAccount删除,修改后的KUBE_ADMISSION_CONTROL为:

# default admission control policies

KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

(4)按顺序启动所有服务:

systemctl start etcd

systemctl start docker

systemctl start kube-apiserver

systemctl start kube-controller-manager

systemctl start kube-scheduler

systemctl start kubelet

systemctl start kube-proxy

至此,一个单机版的kubernetes集群环境就安装好了。

二、启动mysql服务

1、首先为mysql服务创建一个RC定义文件: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

       ports:

       - containerPort: 3306

       env:

       - name: MYSQL_ROOT_PASSWORD

         value: "123456"

2、发布到k8s集群中

我们在master节点执行命令:

kubectl create -f mysql-rc.yaml

会提示:replicationcontroller "mysql" created

3、查看创建的RC

[root@centos7 ~]# kubectl get rc

NAME      DESIRED   CURRENT   READY     AGE

mysql     1         1         1         19m

4、查看pod的创建

[root@centos7 ~]# kubectl get pod

NAME          READY     STATUS    RESTARTS   AGE

mysql-4ts86   1/1       Running   0          19m

可以看到一个名为mysql-xxxxx的pod实例,这是k8s根据mysql这个RC的定义自动创建的pod,由于pod的调度和创建需要一定时间,所以刚开始看到的状态是Pending,当pod成功创建完成后,状态最终会被更新为Running。

三、启动myweb服务

1、创建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: kubeguide/tomcat-app:v1

       ports:

       - containerPort: 8080

       env:

       - name: MYSQL_SERVICE_HOST

         value: 'mysql'

       - name: MYSQL_SERVICE_PORT

         value: '3306'

kubectl create -f myweb-rc.yaml

2、创建myweb-svc.yaml

apiVersion: v1

kind: Service

metadata:

 name: myweb

spec:

 type: NodePort

 ports:

 - port: 8080

   nodePort: 30001

   targetPort: 8080

 selector:

   app: myweb

kubectl create -f myweb-svc.yaml

四、打开iptables的外网访问

iptables -P FORWARD ACCEPT

五、创建RC服务出现的问题

执行kubectl get pod时会看到状态一直是“ContainerCreating”,是什么原因呢?

可以使用kubectl describe pod mysql命令,看到输出结果为:

......

failed to "StartContainer" for "POD" with ImagePullBackOff: "Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest\""

17m 10s 7 {kubelet 127.0.0.1} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request. details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)"

查看/etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt路径发现是一个链接文件,但是我本地没有/etc/rhsm/ca/redhat-uep.pem怎么办。

方法一:

先下载一个试试:

yum -y install *rhsm*

安装完成后,重新创建mysql RC:

kubectl delete -f mysql-rc.yaml 

kubectl create -f mysql-rc.yaml 

如果发现rc的状态还是ContainerCreating,说明还是不成功。

方法二:

安装完成后,执行一下docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest

如果依然报错,可参考下面的方案:

# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm

# rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pem

这两个命令会生成/etc/rhsm/ca/redhat-uep.pem文件.

顺得的话会得到下面的结果。

docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest

删除原来创建的rc

kubectl delete -f mysql-rc.yaml

重新创建

方法三:

执行下面命令,手动下载pause镜像:

docker pull docker.io/kubernetes/pause

docker tag docker.io/kubernetes/pause gcr.io/google_containers/pause-amd64:3.0

docker rmi -f docker.io/kubernetes/pause

然后再重新创建mysql-rc

kubectl delete -f mysql-rc.yaml 

kubectl create -f mysql-rc.yaml

隔几十秒后发现rc和pod的状态已经变成Running了。

六、测试

访问http://hostIP:30001/demo

出现的问题:

1、无法访问,提示超时

如果需要外网访问暴露的30001端口,需要先开启iptables的访问,执行:

iptables -P FORWARD ACCEPT

2、可以访问,但是页面报错:

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.

同时查看myweb服务的后台:

[root@centos7 ~]# kubectl get pod

NAME          READY     STATUS    RESTARTS   AGE

mysql-1qx17   1/1       Running   2          6m

myweb-p97bb   1/1       Running   2          1h

使用这个命令查看myweb服务的后台输出:kubectl logf -f myweb-p97bb

会看到报错信息:

Caused by: java.net.UnknownHostException: mysql: Name or service not known

at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)

at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:922)

at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1316)

at java.net.InetAddress.getAllByName0(InetAddress.java:1269)

at java.net.InetAddress.getAllByName(InetAddress.java:1185)

at java.net.InetAddress.getAllByName(InetAddress.java:1119)

at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:191)

at com.mysql.jdbc.MysqlIO.(MysqlIO.java:298)

说明无法访问主机名为mysql,是因为kubernetes未配置dns,下面给出一种解决办法:

先查看服务的endpoint如下:

[root@centos7 ~]# kubectl get ep

NAME         ENDPOINTS             AGE

kubernetes   192.168.13.128:6443   1h

mysql        172.17.0.2:3306       6m

myweb        172.17.0.3:8080       42m

然后进入myweb-p97bb的pod,手动添加一条hosts记录,主机名为mysql,ip为172.17.0.2

[root@centos7 ~]# kubectl exec -it myweb-p97bb /bin/bash

root@myweb-p97bb:/usr/local/tomcat# echo "172.17.0.2    mysql">>/etc/hosts

3、再次请求页面报mysql的getConnection异常

原因是因为按照《kubernetes权威指南》书上的例子来实验,创建mysql-rc.yaml的时候没有指明mysql镜像的版本号,默认下载的latest,此时mysql的版本为8.XX,导致jdbc驱动不符,所以报错。

解决办法是修改mysql-rc.yaml文件,指定mysql的镜像版本为5.6,下面给出最新的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

       ports:

       - containerPort: 3306

       env:

       - name: MYSQL_ROOT_PASSWORD

         value: "123456"

再次请求应该就可以看到成功页面了