一、Kubernetes基础知识
1、在Kubernete中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征
2、什么是Pod对象
3、什么是Node
4、什么是Pause容器和业务容器
5、Kubernete的集群管理
6、RC(Replication Controller),为Kubernetes提供了自动扩容功能的支持。在一个RC定义文件中会包括以下3个信息:
RC运行机制:
二、环境准备
以下实验均是使用CentOS7.4 Minimual版本系统完成。
1、关闭系统防火墙
systemctl disable firewalld
systemctl stop firewalld
2、安装etcd和Kubernetes软件
yum -y install etcd kubernetes
3、按顺序启动所有的服务
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
一个单机版的kubernete就安装完成了。
4、创建和启动一个MySQL服务
(1)定义一个RC文件:mysql-rc.yaml
apiVersion: v1
kind: ReplicationController #类型为副本控制器RC
metadata:
name: mysql #RC的名称,全局唯一
spec:
replicas: 1 #POD副本期待数量
selector:
app: mysql #符合目标的Pod拥有此标签
template: #根据此模板创建Pod的副本
metadata:
labels:
app: mysql #Pod副本拥有的标签,对应RC的Selector
spec:
containers: #Pod内容器的定义部分
- name: mysql #容器的名称
image: mysql.io/mysql:latest #容器对应的Docker Image
ports:
- containerPort: 3306 #容器应用监听的端口号
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
在Master节点执行创建命令:
# kubectl create -f mysql-rc.yaml
replicationcontroller "mysql" created
查看刚刚创建的RC:
# kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 0 0 26s
查看Pod的创建情况:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
注:在创建Pod实例的过程视宿主机性能差异,有时需要待一会。如果立即查看,会像上面显示的样子,还不会立即有结果。
(2)故障排除1
在等了一会儿后发现仍然查看不到正确的创建Pod的结果,于是查看相关日志tail -200 /var/log/messages,看到下面报错信息。
Feb 18 02:09:53 gqtest kube-controller-manager: I0218 02:09:53.543524 1230 event.go:217] Event(api.ObjectReference{Kind:"ReplicationController", Namespace:"default", Name:"mysql", UID:"8ace1e3a-140d-11e8-961e-0800275f8277", APIVersion:"v1", ResourceVersion:"15425", FieldPath:""}): type: 'Warning' reason: 'FailedCreate' Error creating: No API token found for service account "default", retry after the token is automatically created and added to the service account
属于K8S服务间接口调用授权问题,可以通过以下方法解决:
vi /etc/kubernetes/apiserver
# default admission control policies
# KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"
再查看Pod创建结果:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 0/1 ContainerCreating 0 27s
(3)故障排除2
又是等待了好一会儿,一直停滞在ContainerCreating的状态,继续查看日志或者使用以下方法查看Pod创建信息:
# kubectl describe pod mysql
Name: mysql-mn49n
Namespace: default
Node: 127.0.0.1/127.0.0.1
Start Time: Sun, 18 Feb 2018 02:17:26 +0800
Labels: app=mysql
Status: Pending
IP:
Controllers: ReplicationController/mysql
Containers:
mysql:
Container ID:
Image: docker.io/mysql:latest
Image ID:
Port: 3306/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Volume Mounts:
Environment Variables:
MYSQL_ROOT_PASSWORD: 123456
Conditions:
Type Status
Initialized True
Ready False
PodScheduled True
No volumes.
QoS Class: BestEffort
Tolerations:
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
4m 4m 1 {default-scheduler } Normal Scheduled Successfully assigned mysql-mn49n to 127.0.0.1
4m 1m 5 {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)"
4m 3s 16 {kubelet 127.0.0.1} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ImagePullBackOff: "Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest\""
从上面信息中看到,是因为系统中缺少一个文件:/etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt
查看这个文件:
# ls -l /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt
lrwxrwxrwx. 1 root root 27 Feb 17 21:39 /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt -> /etc/rhsm/ca/redhat-uep.pem
可以继续看到上面缺少的是一个符号链接指向的物理文件:/etc/rhsm/ca/redhat-uep.pem
找了一些简单的资料,显示rhsm是redhat用于管理服务注册管理的一个软件包,虽然我们使用的开源CentOS系统,用不到这个文件,但显然K8S对此有依赖。
因此,也安装一个该工具包。
# yum search rhsm
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.shu.edu.cn
* epel: mirrors.ustc.edu.cn
* extras: mirror.bit.edu.cn
* updates: mirror.bit.edu.cn
======================================================================== N/S matched: rhsm ========================================================================
python-rhsm.x86_64 : A Python library to communicate with a Red Hat Unified Entitlement Platform
python-rhsm-certificates.x86_64 : Certificates required to communicate with a Red Hat Unified Entitlement Platform
# yum -y install rhsm
再次查看Pod创建结果,看到创建了一个名为mysql-mn49n的容器,显示状态已经变为了Running:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 13m
查看产生了哪些新的docker容器:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5d627846fe docker.io/mysql:latest "docker-entrypoint.sh" About a minute ago Up About a minute k8s_mysql.162321c7_mysql-mn49n_default_cee70dc4-140e-11e8-9692-0800275f8277_a8673105
1ab87e554d8a registry.access.redhat.com/rhel7/pod-infrastructure:latest "/usr/bin/pod" About a minute ago Up About a minute k8s_POD.1d520ba5_mysql-mn49n_default_cee70dc4-140e-11e8-9692-0800275f8277_896ea006
注:共新建了两个docker容器,其中后面那个显然是K8S用于Pod内部网络和其他基础功能管理使用的一个容器。
(4)为上面的创建服务创建一个与之关联的K8s Service的定义文件
apiVersion: v1
kind: Service #类型为k8s Service
metadata:
name: mysql #该Service的全局唯一名称
spec:
ports:
- port: 3306 #Service提供服务的端口号
selector: #Service对应的Pod拥有这里定义的标签
app: mysql
执行创建命令:
[root@gqtest ~]# kubectl create -f mysql-svc.yaml
service "mysql" created
[root@gqtest ~]# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 443/TCP 4h
mysql 10.254.20.191 3306/TCP 11s
[root@gqtest ~]#
可以看到,mysql服务已经被分配了一个10.154.20.191的cluster ip地址。
这是一个虚地址,k8s集群中其他Pod就可以通过Service的Cluster IP+端口号3306来连接这个mysql服务了。
5、启动Tomcat应用
再创建一个tomcat应用,来访问上一步创建的mysql服务,提供一个简单的web功能。
(1)首先创建tomcat服务使用的RC文件
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2 #在这里选择配置成了2个副本
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: docker.io/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
查看结果:
[root@gqtest ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 41m
myweb-k6fp0 0/1 ContainerCreating 0 2m
myweb-m9nv9 0/1 ContainerCreating 0 2m
[root@gqtest ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 42m
myweb-k6fp0 1/1 Running 0 3m
myweb-m9nv9 1/1 Running 0 3m
(2)继续创建对应的Service
需要特别注意的是,在该Service文件中用到了type=NodePort和nodePort=30001这两个重要属性。
表明此Service开启了NodePort方式的外网访问模式。
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
[root@gqtest ~]# kubectl create -f myweb-svc.yaml
service "myweb" created
[root@gqtest ~]# kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 443/TCP 4h
mysql 10.254.20.191 3306/TCP 19m
myweb 10.254.89.4 8080:30001/TCP 1m
(3)测试下tomcat和mysql两个服务是否可以正确得互相连通并提供web服务
(4)查看一下此时系统中有哪些docker容器、哪些Pods
参考:《Kubernetes权威指南——从Docker到Kubernetes实践全接触》第1章。