kubernetes 一些基本的概念

时间:2023-03-09 08:41:08
kubernetes 一些基本的概念

k8s 原理

kubernetes 一些基本的概念

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 就会及时防线故障并自动修复。

kubernetes 一些基本的概念

kubernetes 一些基本的概念

kubernetes 一些基本的概念

k8s网络

使用weave网络

kubernetes 一些基本的概念

kubernetes 一些基本的概念

kubernetes 一些基本的概念

kubernetes 一些基本的概念

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:
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
containers:
- name: tomcat
image: docker.cinyi.com:/tomcat
ports:
- containerPort:
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
ports:
- port: # cluster IP 的端口
targetPort: 8080 # container容器的端口
selector:
tier: frontend

外部系统访问service 问题

kubernetes 中三种IP 包括

. NodeIP   node节点的IP地址
. PodIP pod的IP地址
. 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的值。

kubernetes 一些基本的概念

deployment创建部署

[root@docker ~]# cat  test_deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas:
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.cinyi.com:443/senyint/im-web
ports:
- containerPort:
1. 创建
[root@docker ~]# kubectl create -f /root/test_deployment.yaml 2. 查看状态
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
my-nginx         3 0 0 0 1s DESIRED 期望的副本数
CURRENT 当前副本数
UP-TO-DATA 最新副本数
AVALLABLE 可用副本数 3. 更新部署(镜像升级)
(1)把image镜像从 docker.cinyi.com:443/senyint/nginx 升级到 docker.cinyi.com:443/senyint/im-web
[root@docker ~]# kubectl set image deployment/my-nginx nginx=docker.cinyi.com:443/senyint/im-web kubernetes 一些基本的概念
(2) 直接使用edit 修改
[root@docker ~]# kubectl edit deployment/my-nginx 4.扩展副本数
[root@docker ~] kubect scale deployment my-nginx --replicas=10 5.api
 /apis/extensions/v1beta1/namespaces/default/deployments/my-nginx

ReplicationController创建部署

apiVersion: v1
kind: ReplicationController
metadata:
name: im-web
namespace: test
spec:
replicas:
template:
metadata:
labels:
name: im-web
spec:
volumes:
- name: workdir
hostPath:
path: "/data/log/im-web"
containers:
- name: im-web
image: docker.cinyi.com:/senyint/im-web:latest
ports:
- containerPort:
volumeMounts:
- name: workdir
mountPath: /data/tomcat/logs
扩容副本
[root@docker1 ~]# kubectl scale rc im-web --namespace=test --replicas= 滚动升级
[root@docker1 ~]# kubectl rolling-update im-web --image=docker.cinyi.com:/senyint/im-web:--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:
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
volumes:
- name: workdir
emptyDir: {}
containers:
- name: tomcat
image: docker.cinyi.com:/tomcat
ports:
- containerPort:
volumeMounts:
- name: workdir
mountPath: /opt
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
type: NodePort
ports:
- port:
targetPort:
nodePort:
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:
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
volumes:
- name: workdir
hostPath:
path: "/data"
containers:
- name: tomcat
image: docker.cinyi.com:/tomcat
ports:
- containerPort:
volumeMounts:
- name: workdir
mountPath: /opt #把宿主机/data目录挂载到容器的/opt目录下
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
type: NodePort
ports:
- port:
targetPort:
nodePort:
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:
template:
metadata:
labels:
app: tomcat
tier: frontend
spec:
volumes:
- name: workdir
hostPath:
path: "/data"
containers:
- name: tomcat
image: docker.cinyi.com:/tomcat
ports:
- containerPort:
volumeMounts:
- name: workdir
mountPath: /opt
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-server
spec:
type: NodePort
ports:
- port:
targetPort:
nodePort:
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 示例:

kubernetes 一些基本的概念

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

[root@kubernetes guestbook]# vim redis-master.yaml 

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis-master
spec:
replicas:
template:
metadata:
labels:
app: redis-master
spec:
containers:
- name: redis-master
image: docker.cinyi.com:/kubeguide/redis-master
ports:
- containerPort:
env:
- name: hostname
value: fengjian
---
apiVersion: v1
kind: Service
metadata:
name: redis-master
spec:
ports:
- port:
targetPort:
selector:
app: redis-master ######################### apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis-slave
spec:
replicas:
template:
metadata:
labels:
app: redis-slave
spec:
containers:
- name: redis-slave
image: docker.cinyi.com:/kubeguide/guestbook-redis-slave
ports:
- containerPort:
env:
- name: GET_HOSTS_FROM
value: env
---
apiVersion: v1
kind: Service
metadata:
name: redis-slave
spec:
ports:
- port:
targetPort:
selector:
app: redis-slave ############################ [root@kubernetes guestbook]# vim frontend-php.yaml apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend-server
spec:
replicas:
template:
metadata:
labels:
app: frontend-server
spec:
containers:
- name: frontend-server
image: docker.cinyi.com:/kubeguide/guestbook-php-frontend
ports:
- containerPort:
env:
- name: GET_HOSTS_FROM
value: env
---
apiVersion: v1
kind: Service
metadata:
name: frontend-server
spec:
type: NodePort
ports:
- port:
targetPort:
nodePort:
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

kubernetes 一些基本的概念

访问 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--0fwym / Running 2h
frontend-server--dw937 / Running 2h
redis-master--nyjra / Running 2h
redis-slave--0ijyl / Running 2h
redis-slave--6vwya / Running 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--0fwym / Running 2h
redis-master--nyjra / Running 2h
redis-slave--0ijyl / Running 2h
redis-slave--6vwya / Running 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:
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:/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个组件组成
. etc: dns存储
. kube2sky: 将kubernetes master 中的service 注册到etcd
. skydns 提供dns域名解析服务
. 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:
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.
image: index.tenxcloud.com/google_containers/etcd:2.0.
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:---
image: index.tenxcloud.com/google_containers/skydns:---
#image: index.tenxcloud.com/google_containers/skydns:---8c72f8c
resources:
limits:
cpu: 100m
memory: 50Mi
args:
# command = "/skydns"
- -machines=http://localhost:4001
- -addr=0.0.0.0:
- -domain=cinyi.com
ports:
- containerPort:
name: dns
protocol: UDP
- containerPort:
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:
protocol: UDP
- name: dns-tcp
port:
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--a8mak nginx-1.11.]# nslookup tomcat1
Server: 10.254.0.2
Address: 10.254.0.2# Name: tomcat1.default.svc.cinyi.com
Address: 10.254.100.145

例子:查看所有的service 服务

kubernetes 一些基本的概念

kubernetes 一些基本的概念

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

kubernetes 一些基本的概念

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

kubernetes 一些基本的概念

结论: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)时提供单个健康检查端点。