计算机系统应用教程网站

网站首页 > 技术文章 正文

k8s 的原理以及基本使用

btikc 2024-09-04 03:09:30 技术文章 9 ℃ 0 评论

k8s 的原理以及基本使用:

k8s 原理:

kubernetes API server 作为集群的核心,负责集群各功能之间的通信, 集群内的各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据的时候

通过API Server 提供的 REST 接口(get put post watch) 来实现。

场景一: node节点的 kubelet --------> apiserver

node上的 kubelet 进程每隔一个时间周期,就会调用一次API Server接口报告自身状态,API Server接受这些信息后,将节点状态更新到etcd中

kubelet也通过API Server的 WATCH接口监听pod信息,如果监控到新的pod副本被调度绑定到本节点,则执行pod对应的容器的创建和启动,如果

如果监听到pod对象被删除,则删除本节点对应的pod容器。

场景二: master kube-controller-manager --------> apiserver

kube-controller-manager 中的node controller 模块通过 API Server提供的Watch接口,实时监控node的状态信息

controller-manager 作为集群内部的管理控制中心,负责集群内的node,pod副本, 命名空间namespace, 服务账号,资源定额等的管理,当某个node 宕机,

controller manager 就会及时防线故障并自动修复。

k8s网络

使用weave网络:

etcd 中注册的对象内容。
[root@docker1 ~]# etcdctl ls /registry
/registry/controllers
/registry/daemonsets
/registry/namespaces
/registry/ranges
/registry/replicasets
/registry/serviceaccounts
/registry/ingress
/registry/clusterrolebindings
/registry/secrets
/registry/services
/registry/certificatesigningrequests
/registry/configmaps
/registry/clusterroles
/registry/deployments
/registry/events
/registry/minions
/registry/pods
API server: 提供了HTTP Rest接口,可以对所有资源进行增 删 改 查,是整个集群的入口
controller Mananter: 所有资源对象的自动化控制中心
scheduler: 负责资源调度。
kubelet,负责pod的创建 启停,与master 节点密切协作,实现集群管理的功能
kube-proxy: 实现service的通信与负载均衡机制

DaemonSet

DaemonSet能够让所有(或者一些特定)的Node节点运行同一个pod。当节点加入到kubernetes集群中,pod会被(DaemonSet)调度到该节点上运行,当节点从kubernetes集群中被移除,被(DaemonSet)调度的pod会被移除,如果删除DaemonSet,所有跟这个DaemonSet相关的pods都会被删除。

在使用kubernetes来运行应用时,很多时候我们需要在一个区域(zone)或者所有Node上运行同一个守护进程(pod),例如如下场景:

每个Node上运行一个分布式存储的守护进程,例如glusterd,ceph

运行日志采集器在每个Node上,例如fluentd,logstash

运行监控的采集端在每个Node,例如prometheus node exporter,collectd等

在简单的情况下,一个DaemonSet可以覆盖所有的Node,来实现Only-One-Pod-Per-Node这种情形;在有的情况下,我们对不同的计算几点进行着色,或者把kubernetes的集群节点分为多个zone,DaemonSet也可以在每个zone上实现Only-One-Pod-Per-Node。

什么是Deployment

Kubernetes Deployment提供了官方的用于更新Pod和Replica Set(下一代的Replication Controller)的方法,您可以在Deployment对象中只描述您所期望的理想状态(预期的运行状态),Deployment控制器为您将现在的实际状态转换成您期望的状态,例如,您想将所有的webapp:v1.0.9升级成webapp:v1.1.0,您只需创建一个Deployment,Kubernetes会按照Deployment自动进行升级。现在,您可以通过Deployment来创建新的资源(pod,rs,rc),替换已经存在的资源等。

Deployment集成了上线部署、滚动升级、创建副本、暂停上线任务,恢复上线任务,回滚到以前某一版本(成功/稳定)的Deployment等功能,在某种程度上,Deployment可以帮我们实现无人值守的上线,大大降低我们的上线过程的复杂沟通、操作风险。

Deployment的使用场景

下面是Deployment的典型用例:

  • 使用Deployment来启动(上线/部署)一个Pod或者ReplicaSet
  • 检查一个Deployment是否成功执行
  • 更新Deployment来重新创建相应的Pods(例如,需要使用一个新的Image)
  • 如果现有的Deployment不稳定,那么回滚到一个早期的稳定的Deployment版本
  • 暂停或者恢复一个Deployment

kind: 定义的对象: Replicationcontroller, ReplicaSet Deployment 区别

Replicationcontroller 的升级版是 ReplicaSet , ReplicaSet支持基于集合的 Label selector, 而RC只支持基于等式的 Lable select

Deployment其实就是内部调用 ReplicaSet.

DaemonSet 根据标签指定pod 在那个服务器上运行,需要与nodeselect 公用。

configMap 设置环境变量

server定义的selector 与 Deployment 中的 template 的 lables 对应:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
containers:
- name: tomcat
image: docker.cinyi.com:443/tomcat
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
ports:
- port: 11111 # cluster IP 的端口
targetPort: 8080 # container容器的端口
selector:
tier: frontend
-

外部系统访问service 问题

kubernetes 中三种IP 包括:

1. NodeIP node节点的IP地址
2. PodIP pod的IP地址
3. clusterIP service的IP地址
nodeIP 是kubernetes集群中每个节点的物理网卡的IP地址, client 访问kubernetes集群使用的IP地址
Pod ip地址 是更具创建的网络类型,网桥分配的IP地址,
clusterIP 是一个虚拟的IP, cluster ip 仅作用于kubernetes service 这个对象, 是由kubernetes管理和分配ip地址,源于cluster ip地址池
[root@kubernetes nginx]# vim /etc/kubernetes/apiserver
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
cluster IP 无法ping通, 因为没有一个 实体网络对象 响应
cluster ip 只能结合 service port 组成一个具体的通信接口,单独的cluster IP不具备tcp/ip通信基础,
如果 pod 对外访问,需要在servcie 中 指定 type 为 NodePort
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
containers:
- name: tomcat
image: docker.cinyi.com:443/tomcat
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
type: NodePort
ports:
- port: 11111
targetPort: 8080
nodePort: 30001
selector:
tier: frontend
root@kubernetes nginx]# kubectl describe service tomcat-server
Name: tomcat-server
Namespace: default
Labels: <none>
Selector: tier=frontend
Type: NodePort
IP: 10.254.222.139 #cluster IP 的地址
Port: <unset> 11111/TCP #cluster IP 的端口
NodePort: <unset> 30001/TCP # nodeport 的端口
Endpoints: 10.0.223.3:8080,10.0.224.2:8080,10.0.225.2:8080 #容器的服务端口
Session Affinity: None
No events.
访问node IP + node port ,可以访问页面
nodeport 并没有完全解决外部访问service 的问题, 比如负载均衡问题,如果有10 pod 节点, 如果是用谷歌的GCE公有云,那么可以把 service type=NodePort 修改为 LoadBalancer.

2 通过设置pod(daemonset) hostNetwork=true, 将pod中所有容器的端口号直接映射到物理机上, 设置hostNetwork=true的时候需要注意,如果不指定hostport,默认hostport 等于containerport, 如果指定了hostPort, 则hostPort 必须等于containerPort的值。

deployment创建部署:

[root@docker ~]# cat test_deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: my-nginx
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: nginx
 spec:
 containers:
 - name: nginx
 image: docker.cinyi.com:443/senyint/im-web
 ports:
 - containerPort: 80

ReplicationController创建部署:

apiVersion: v1
kind: ReplicationController
metadata:
 name: im-web
 namespace: test
spec:
 replicas: 3
 template:
 metadata:
 labels:
 name: im-web
 spec:
 volumes:
 - name: workdir
 hostPath:
 path: "/data/log/im-web"
 containers:
 - name: im-web
 image: docker.cinyi.com:443/senyint/im-web:latest
 ports:
 - containerPort: 80
 volumeMounts:
 - name: workdir
 mountPath: /data/tomcat/logs
扩容副本
[root@docker1 ~]# kubectl scale rc im-web --namespace=test --replicas=5
滚动升级
[root@docker1 ~]# kubectl rolling-update im-web --image=docker.cinyi.com:443/senyint/im-web:2017-03-21_10_12
api
/api/v1/namespaces/test/replicationcontrollers/im-web

kubernetes volume(存储卷)

volume 是pod中能够被多个容器访问的共享目录, volume 定义在pod上,然后被一个pod里的多个容器挂载到具体的文件目录下,其实volume与pod的声明周期相同,与容器的生命周期无关系,

kubernetes 支持多种类型的volume,如:glusterfs ceph等分布式文件系统

1.emptyDir:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: tomcat-deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: tomcat-deployment
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: tomcat
 tier: frontend
 spec:
 volumes:
 - name: workdir
 emptyDir: {}
 containers:
 - name: tomcat
 image: docker.cinyi.com:443/tomcat
 ports:
 - containerPort: 80
 volumeMounts:
 - name: workdir
 mountPath: /opt
---
apiVersion: v1
kind: Service
metadata:
 name: tomcat-server
spec:
 type: NodePort
 ports:
 - port: 11111
 targetPort: 8080
 nodePort: 30001
 selector:
 tier: frontend
emptyDir volume是在pod 分配到node是创建的,初始内容为空,并且无需指定宿主机上的对应的目录文件,当pod从node上移除时,emptydir中的数据也会永久被删除,目前emptyDir无法控制介质种类
emptpdir 的一些用途如下:
1. 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保修
2. 长时间任务的中间过程checkpoint 的临时保存目录
3. 一个容器需要从另一个容器中获取数据的目录。
2. hostPath 为在pod上挂载宿主机上的文件或者目录,
volumes:
- name: "storage"
 hostPath:
 path: "/data"
-------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: tomcat-deployment
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: tomcat
 tier: frontend
 spec:
 volumes:
 - name: workdir
 hostPath:
 path: "/data"
 containers:
 - name: tomcat
 image: docker.cinyi.com:443/tomcat
 ports:
 - containerPort: 80
 volumeMounts:
 - name: workdir
 mountPath: /opt #把宿主机/data目录挂载到容器的/opt目录下
---
apiVersion: v1
kind: Service
metadata:
 name: tomcat-server
spec:
 type: NodePort
 ports:
 - port: 11111
 targetPort: 8080
 nodePort: 30001
 selector:
 tier: frontend 

3. gcePersistentDisk google云盘

4.awsEasticblockStore 亚马逊云盘

5 nfs, 使用nfs网络文件服务器提供的共享目录存储数据时,需要部署一个nfs server,定义nfs类型volume 如:

 volumeMounts:
 - name: workdir
 nfs:
 server: nfs-server
 path: "/"

6. 其他类型的volume

iscsi: 使用iscsi存储设备上的目录挂载到pod上。
flock: 使用flocker来管理存储卷
glusterfs: 使用glusterfs分布式文件系统
等等.....

Namespace 命名空间:

Namespace 在很多情况下用于多租户的资源隔离,Namespace通过将集群内部的资源对象“分配”到不通的Namespace中, 形成逻辑上的分组的不同项目,小组或者 用户组,便于不同的分组在共享使用这个集群的资源的同时还能被分别管理。
kubernetes集群在启动后,会创建一个 default 的 namespace,
[root@kubernetes nginx]# kubectl get namespace
NAME STATUS AGE
default Active 7d
kube-system Active 7d
如果不特别指明namespace,则用户创建的 pod rc service 都将被系统创建到defalut中
#创建fengjian20170221 的命名空间
apiVersion: v1
kind: Namespace
metadata:
 name: fengjian20170221
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: tomcat-deployment
 namespace: fengjian20170221
spec:
 replicas: 3
 template:
 metadata:
 labels:
 app: tomcat
 tier: frontend
 spec:
 volumes:
 - name: workdir
 hostPath:
 path: "/data"
 containers:
 - name: tomcat
 image: docker.cinyi.com:443/tomcat
 ports:
 - containerPort: 80
 volumeMounts:
 - name: workdir
 mountPath: /opt
---
apiVersion: v1
kind: Service
metadata:
 name: tomcat-server
spec:
 type: NodePort
 ports:
 - port: 11111
 targetPort: 8080
 nodePort: 30001
 selector:
 tier: frontend
[root@kubernetes nginx]# kubectl get namespace
NAME        STATUS      AGE
default      Active      7d
fengjian20170221 Active      2m
kube-system    Active      7d
 
[root@kubernetes nginx]# kubectl get pods --namespace=fengjian20170221
NAME                  READY STATUS    RESTARTS AGE
tomcat-deployment-2750437860-4no2f 1/1    Running    0    5m
tomcat-deployment-2750437860-mmk4b 1/1    Running    0    5m
tomcat-deployment-2750437860-yb8u2 1/1    Running    0    5m

guestbook 示例:

3个php, 1个redis主 ,2 个redis从:

[root@kubernetes guestbook]# vim redis-master.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: redis-master
spec:
 replicas: 1
 template:
 metadata:
 labels:
 app: redis-master
 spec:
 containers:
 - name: redis-master
 image: docker.cinyi.com:443/kubeguide/redis-master
 ports:
 - containerPort: 6379
 env:
 - name: hostname
 value: fengjian
---
apiVersion: v1
kind: Service
metadata:
 name: redis-master
spec:
 ports:
 - port: 6379
 targetPort: 6379
 selector:
 app: redis-master
#########################
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: redis-slave
spec:
 replicas: 2
 template:
 metadata:
 labels:
 app: redis-slave
 spec:
 containers:
 - name: redis-slave
 image: docker.cinyi.com:443/kubeguide/guestbook-redis-slave
 ports:
 - containerPort: 6379
 env:
 - name: GET_HOSTS_FROM
 value: env
---
apiVersion: v1
kind: Service
metadata:
 name: redis-slave
spec:
 ports:
 - port: 6379
 targetPort: 6379
 selector:
 app: redis-slave
############################
[root@kubernetes guestbook]# vim frontend-php.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: frontend-server
spec:
 replicas: 2
 template:
 metadata:
 labels:
 app: frontend-server
 spec:
 containers:
 - name: frontend-server
 image: docker.cinyi.com:443/kubeguide/guestbook-php-frontend
 ports:
 - containerPort: 80
 env:
 - name: GET_HOSTS_FROM
 value: env
---
apiVersion: v1
kind: Service
metadata:
 name: frontend-server
spec:
 type: NodePort
 ports:
 - port: 80
 targetPort: 80
 nodePort: 30001
 selector:
 app: frontend-server
[root@kubernetes guestbook]# kubectl create -f redis-master.yaml -f redis-slave.yaml -f frontend-php.yaml
[root@kubernetes guestbook]# kubectl get service

访问 nodeIP+端口, 可以访问出程序页面,

Pod 声明周期和重启策略:

状态        描述
Pending      API server 已经创建该Pod,但pod 内还有一个或多个容器的镜像还有创建,包括正在下载镜像的过程
Running      pod内的所有容器均已创建,且至少有一个容器处于运行状态,正在启动状态或正在重启状态。
Successed     Pod内所有容器均成功执行退出,且不会重启
Failed       Pod内所有容器均已退出,但至少一个容器退出为失败状态
Unknown      由于某种原因无法获取该pod的状态,可能由于网络问题

Pod重启策略(restartpolicy) 应用于pod内的所有容器,并且仅在pod所处的node上由kubelet进行判断和重启操作:

pod 的重启策略包括always、 onfailure 、 Never, 默认为always.
always: 懂容器失效时,有kubulet自动重启该容器
onfailure: 当容器终止运行且退出码不为0,有kubulet 自动重启容器
never: 不论容器运行状态如何,kubelet都不会重启该容器。

Pod扩容和缩容

在生产环境中,经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或工作负载降低减少服务实例的场景,可以使用 RC 的 scale机制操作

[root@kubernetes guestbook]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-server-3958566729-0fwym 1/1 Running 0 2h
frontend-server-3958566729-dw937 1/1 Running 0 2h
redis-master-1081272834-nyjra 1/1 Running 0 2h
redis-slave-3198086074-0ijyl 1/1 Running 0 2h
redis-slave-3198086074-6vwya 1/1 Running 0 2h
[root@kubernetes guestbook]# kubectl scale deployment frontend-server --replicas=1 #replicas 副本数变成1个
deployment "frontend-server" scaled
[root@kubernetes guestbook]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-server-3958566729-0fwym 1/1 Running 0 2h
redis-master-1081272834-nyjra 1/1 Running 0 2h
redis-slave-3198086074-0ijyl 1/1 Running 0 2h
redis-slave-3198086074-6vwya 1/1 Running 0 2h

静态pod

是由kubelet进行管理的,仅存在于特定的node上的pod, 他们不能功过API server进行管理,无法于ReplicationController,Deployment或者DaemonSet关联

kebelet守护进程监控它,并在崩溃时重启它。 静态pod 总是绑定到一个kubulet守护程序上,并且总是运行在同一个节点上。

创建静态pod的两种方式:

1. 配置文件 ,2.http

(1)、创建一个yaml文件,并且放置到一个文件夹中/etc/kubelet.d/
[root@docker225 kubelet.d]# mkdir /etc/kubelet.d/
[root@docker225 kubelet.d]# cat static-web.yaml
apiVersion: v1
kind: Pod
metadata:
 name: static-web
 labels:
 role: myrole
spec:
 containers:
 - name: web
 image: nginx
 ports:
 - name: web
 containerPort: 80
 protocol: TCP
(2) 修改 /etc/kubernetes/kubelet 配置文件,最后一行添加 静态pod的yaml文件的路径。
KUBELET_ARGS="--pod-manifest-path=/etc/kubelet.d/"
(3)重启kulelet 服务
systemctl restart kubelet.service
 (4) 删除静态pod, yaml文件去掉后,会自动删除
 mv static-web.yaml /root/static-web.xml

configmap

许多应用程序需要通过配置文件,命令行参数和环境变量的组合进行配置。这些配置工件应该与映像内容解耦,以便保持容器化应用程序可移植。ConfigMap API资源提供了使用配置数据注入容器的机制,同时保持容器与Kubernetes无关

应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离,这样可以使得应用程序被更好的复用,通过不同的配置也能实现更灵活的功能,将应用打包为镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,

在大规模容器集群的环境中,对多个容器进行不同的配置将变得非常负责, kubernetes提供了一种统一的集群配置管理方案

configmap 供容器使用的典型方案如下:

1. 生成为容器内的环境变量

2. 设置容器启动命令的启动参数

3. 以volume的形式挂载为容器内部的文件或者目录

4: 注意必须先创建 configMap, 然后pod 才能创建,如果已经创建的pod,升级,环境变量无法找到,

一定要做好提前规划。

生成为容器内的环境变量
[root@kubernetes configmap]# cat cm-appenv.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: testenv
 namespace: test
data:
 mysql_server: 192.168.20.131
 redis_server: 192.168.20.116
 mongo_server: 192.168.20.116
 
支持所有的kind类型:如下: china.yaml
apiVersion: v1
kind: Service
metadata:
 name: china
 labels:
 app: china
spec:
 ports:
 - port: 80
 selector:
 app: china
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: china
 namespace: test
spec:
 replicas: 1
 template:
 metadata:
 labels:
 app: china
 spec:
 containers:
 - name: china
 image: docker.cinyi.com:443/senyint/im-web
 ports:
 - containerPort: 80
 env:
 - name: mysql_server
 valueFrom:
 configMapKeyRef:
 name: testenv
 key: mysql_server
 - name: redis_server
 valueFrom:
 configMapKeyRef:
 name: testenv
 key: redis_server
 - name: mongo_server
 valueFrom:
 configMapKeyRef:
 name: testenv
 key: mongo_server
[root@kubernetes configmap]# kubectl create -f cm-appenv.yaml -f china.yaml
[root@kubernetes configmap]# kubectl get pods --all-namespaces -o wide
登陆到pod中,查看env环境变量
  [root@kubernetes configmap]# kubectl exec -it china-3221241881-rlr8w --namespace=test bash
  [root@china-3221241881-rlr8w /]# env | grep -i server
  
  redis_server=192.168.20.116
  mysql_server=192.168.20.131
  mongo_server=192.168.20.116
  mysql-server=192.168.20.131

configmap使用 volumeMount模式:

apiVersion: v1
kind: ConfigMap
metadata:
 name: special-config
 namespace: default
data:
 special.how: very
 special.type: charm
---
apiVersion: v1
kind: Pod
metadata:
 name: dapi-test-pod
spec:
 containers:
 - name: test-container
 image: docker.cinyi.com:443/busybox
 command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
 volumeMounts:
 - name: config-volume
 mountPath: /etc/config
 volumes:
 - name: config-volume
 configMap:
 name: special-config
 restartPolicy: Never

DNS服务

为了能够通过服务的名字在集群内部进行服务的相互访问,需要创建一个虚拟的dns服务来完成服务名到clusterIP的解析:

kubernetes 提供的虚拟dns服务器名为skydns,是由4个组件组成
1. etc: dns存储
2. kube2sky: 将kubernetes master 中的service 注册到etcd
3. skydns 提供dns域名解析服务
4. healthz: 提供对skydns服务的健康检查功能

创建skydns的yaml文件

apiVersion: v1
kind: ReplicationController
metadata:
 name: kube-dns-v8
 namespace: kube-system
 labels:
 k8s-app: kube-dns
 version: v8
 kubernetes.io/cluster-service: "true"
spec:
 replicas: 1
 selector:
 k8s-app: kube-dns
 version: v8
 template:
 metadata:
 labels:
 k8s-app: kube-dns
 version: v8
 kubernetes.io/cluster-service: "true"
 spec:
 containers:
 - name: etcd
 #image: gcr.io/google_containers/etcd:2.0.9
 image: index.tenxcloud.com/google_containers/etcd:2.0.9
 resources:
 limits:
 cpu: 100m
 memory: 50Mi
 command:
 - /usr/local/bin/etcd
 - -data-dir
 - /var/etcd/data
 - -listen-client-urls
 - http://127.0.0.1:2379,http://127.0.0.1:4001
 - -advertise-client-urls
 - http://127.0.0.1:2379,http://127.0.0.1:4001
 - -initial-cluster-token
 - skydns-etcd
 volumeMounts:
 - name: etcd-storage
 mountPath: /var/etcd/data
 - name: kube2sky
 #image: gcr.io/google_containers/kube2sky:1.11
 image: index.tenxcloud.com/google_containers/kube2sky:1.11
 resources:
 limits:
 cpu: 100m
 memory: 50Mi
 args:
 # command = "/kube2sky"
 - -domain=cinyi.com
 - -kube_master_url=http://192.168.20.226:8080
 - name: skydns
 #image: gcr.io/google_containers/skydns:2015-03-11-001
 image: index.tenxcloud.com/google_containers/skydns:2015-03-11-001
 #image: index.tenxcloud.com/google_containers/skydns:2015-10-13-8c72f8c
 resources:
 limits:
 cpu: 100m
 memory: 50Mi
 args:
 # command = "/skydns"
 - -machines=http://localhost:4001
 - -addr=0.0.0.0:53
 - -domain=cinyi.com
 ports:
 - containerPort: 53
 name: dns
 protocol: UDP
 - containerPort: 53
 name: dns-tcp
 protocol: TCP
 volumes:
 - name: etcd-storage
 emptyDir: {}
 dnsPolicy: Default # Don't use cluster DNS.
---
apiVersion: v1
kind: Service
metadata:
 name: kube-dns
 namespace: kube-system
 labels:
 k8s-app: kube-dns
 kubernetes.io/cluster-service: "true"
 kubernetes.io/name: "KubeDNS"
spec:
 selector:
 k8s-app: kube-dns
 clusterIP: 10.254.0.2 
 ports:
 - name: dns
 port: 53
 protocol: UDP
 - name: dns-tcp
 port: 53
 protocol: TCP
2. 修改每台node 上的 kubelet启动参数
[root@docker223 ~]# cat /etc/kubernetes/kubelet 
###
# kubernetes kubelet (minion) config
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"
# The port for the info server to serve on
# KUBELET_PORT="--port=10250"
# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=192.168.20.223"
# location of the api-server
KUBELET_API_SERVER="--api-servers=http://192.168.20.226:8080"
# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=docker.cinyi.com:443/rhel7/pod-infrastructure:latest"
#KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
# Add your own!
KUBELET_ARGS="--pod-manifest-path=/etc/kubelet.d/ --cluster_dns=10.254.0.2 --cluster_domain=cinyi.com"


DNS工作原理解析:

1. kube2sky通过调用kubernetes master 的API 获取集群中所有service的信息,并且持续监控新的service 的生成,然后写入etcd中
查看etcd中存储的service 信息
[root@kubernetes nginx]# kubectl exec kube-dns-v8-98n35 -c etcd --namespace=kube-system etcdctl ls /skydns/com/cinyi
/skydns/com/cinyi/default
/skydns/com/cinyi/svc
/skydns/com/cinyi/kube-system
查看tomcat1 服务对应的键值:
[root@kubernetes nginx]# kubectl exec kube-dns-v8-98n35 -c etcd --namespace=kube-system etcdctl get /skydns/com/cinyi/default/tomcat1
{"host":"10.254.100.145","priority":10,"weight":10,"ttl":30,"targetstrip":0}

2. kubelet启动参数设置了(--cluster_dns),kubelet会在每个创建的pod中设置dns解析配置 /etc/resolv.conf

[root@docker223 ~]# docker exec -it 2ff /bin/bash
[root@my-nginx-335071150-a8mak nginx-1.11.2]# cat /etc/resolv.conf
search default.svc.cinyi.com svc.cinyi.com cinyi.com
nameserver 10.254.0.2
nameserver 114.114.114.114
options ndots:5

3.应用程序能够通过网站域名进行访问

[root@my-nginx-335071150-a8mak nginx-1.11.2]# nslookup tomcat1
Server: 10.254.0.2
Address: 10.254.0.2#53
Name: tomcat1.default.svc.cinyi.com
Address: 10.254.100.145

例子:查看所有的service 服务:

进入到 pod容器中后 ping kubernetes-dashboard.kube-system 的server,不同,但是可以解析到IP地址

使用telnet kubernetes-dashboard.kube-system 80端口,是通的,

结论:service 通过内部IP(虚IP),可以进行通信,但是不能ping通。

遇到的问题:

1. ingress 如果使用不同namespace,需要使用2个yaml文件

2. 配置一个nginx pod,hostNetwork=true的情况下,进入pod中 dns无法解析到其他services,所以直接采用nginx反向代理service方式行不通。 可以是使用问题6的方式,暴露service的nodePort端口。

3. 容器的hosts: 在dockerfile中,使用add host /etc/,命令,容器启动后,host还是被覆盖

4. 使用configMap,设置环境变量方式,但是一定要提前规划好,当pod已经创建,再修改configmap文件, 添加环境变量 , 启动的pod,环境变量不启用,需要删除pod,重新创建。

5. deployment 与 ReplicationController api不同,升级方法不同

6. DaemoSet类型 实现高可用,需要删除 replicas 参数, 并且设置nodeSelector,只是label, 最后,在node上引用label,kubectl label node docker role=master

7. 所有操作都是用API,与jenkins结合使用。

8. k8s 1.5.3以后 skydns 已经取消, 新的 Kubernetes DNS pod拥有3个容器 kubedns,dnsmasq和一个名为healthz的健康检查。kubedns进程监视Kubernetes主服务和端点的更改,并维护内存中查找结构来服务DNS请求。dnsmasq容器添加DNS缓存以提高性能。healthz容器在执行双重健康检查(对于dnsmasq和kubedns)时提供单个健康检查端点。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表