Kubernetes 是 Google 团队发起并维护的基于 Docker 的开源容器集群管理系统,它不只支持常见的云平台,并且支持内部数据中心。它的目标是管理跨多个主机的容器,提供基本的部署,维护以及运用伸缩,主要实现语言为 Go 语言。前端
最初,Google 开发了一个叫 Borg 的系统(如今命令为 Omega)来调度如此庞大数量的容器和工做负载。在积累了这么多年的经验后,Google 决定重写这个容器管理系统,并将其贡献到开源社区,让全世界都能受益。它就是 Kubernetes。node
建于 Docker 之上的 Kubernetes 能够构建一个容器的调度服务,其目的是让用户透过 Kubernetes 集群来进行云端容器集群的管理,而无需用户进行复杂的设置工做。它是当前最流行的容器编排引擎。nginx
安装 Kubernetes 须要安装git
kubeadm
: 用来初始化集群的指令。kubelet
: 在集群中的每一个节点上用来启动 pod 和 container 等。kubectl
: 是 Kubernetes 命令行工具,用来与集群通讯的命令行工具。咱们可使用 minikube 来快速安装开发和学习环境。github
安装好 minikube
能够执行以下命令建立虚拟机web
$ minikube start
# --vm-driver hyperv \
# --hyperv-virtual-switch PVS \
--image-mirror-country cn \
--registry-mirror https://dockerhub.azk8s.cn \
--v 7 \
--alsologtostderr
复制代码
若是是 windows 10 可使用 hyperv, 须要设置
--vm-driver
和--hyperv-virtual-switch
参数,须要使用管理员权限。sql
$ minikube status # 安装完成后,查看一下状态
$ kubectl cluster-info # 查看一下集群信息
$ minikube dashboard # 开启 Kubernetes web UI 控制台
复制代码
还可使用在线的 play with k8s。docker
或者去 官网交互教程。windows
建立一个集群须要使用到 kubeadm
,它会生成证书,配置文件,安装附加组键,如 kube-proxy
和 kube-dns
。几乎全部的 Kubernetes
组件自己也运行在 Pod
里。后端
Kubernetes 中咱们不直接管理容器,而是 Pod
。它是最小工做单元。
一个 Pod
是一个或一组运行很是紧密的容器, Pod
中的全部容器使用同一个网络 namespace
,即相同的 IP
地址和 Port
空间。它们能够直接用 localhost
通讯。一样的,这些容器能够共享存储,当 Kubernetes
挂载 volume
到 Pod
,本质上是将 volume
挂载到 Pod
中的每个容器。
Pod
有 Pending
,Running
,Succeeded
,Failed
和 Unknown
这几个阶段。
咱们通常不本身建立 Pod
, 而是建立 Deployment
。
Kubernetes 集群中主机分为 master
和 node
。
Master
是 Cluster
的大脑,它负责管理集群,主要职责是调度,决定将应用放在哪里运行。一个主机能够同时拥有 Master
和 Node
两种身份。
Master
上运行着
API Server 提供 HTTP/HTTPS RESTful API。API Server 是 Kubernetes Cluster 的前端接口,各类客户端工具(CLI 或 UI)以及 Kubernetes 其余组件能够经过它管理 Cluster 的各类资源。
Controller Manager
负责管理 Cluster
各类资源,保证资源处于预期的状态。Controller Manager
由多种 controller
组成,包括 replication controller
、endpoints controller
、namespace controller
、serviceaccounts controller
等。不一样的 controller
管理不一样的资源。
etcd 负责保存 Kubernetes Cluster 的配置信息和各类资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。
Pod 网络让 Kubernetes Cluster 中 Pod 可以相互通讯。
Node
的职责是运行容器应用。Node
由 Master
管理,Node
负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。
每一个工做节点都有一个 Kubelet
,它是管理 节点 并与 Kubernetes Master
节点进行通讯的代理。节点 上还应具备处理容器操做的工做,例如 Docker
或 rkt
。一个 Kubernetes
工做集群至少有三个节点。
Node
上运行的 Kubernetes 组件有
kubelet
是 Node
的 agent
,当 Scheduler
肯定在某个 Node
上运行 Pod
后,会将 Pod
的具体配置信息(image、volume 等)发送给该节点的 kubelet
,kubelet
根据这些信息建立和运行容器,并向 Master
报告运行状态。
每一个 Node 都会运行 kube-proxy 服务,它负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。若是有多个副本,kube-proxy 会实现负载均衡。
Pod 网络让 Kubernetes Cluster 中 Pod 可以相互通讯。
Kubernetes
一般不会直接建立 Pod
,而是经过 Controller
来管理 Pod
的。Controller
中定义了 Pod
的部署特性,好比有几个副本,在什么样的 Node
上运行等。Kubernetes
中有多种 Controller
。
Deployment
能够管理 Pod
的多个副本。Deployment
负责建立和更新应用程序实例。建立 Deployment
后, Kubernetes master
会将 Deployment
建立的应用程序实例调度到集群中的各个节点。
实现了 Pod
的多副本管理。使用 Deployment
时会自动建立 ReplicaSet
,也就是说 Deployment
是经过 ReplicaSet
来管理 Pod
的多个副本,咱们一般不须要直接使用 ReplicaSet
。
用于每一个 Node
最多只运行一个 Pod
副本的场景。好比运行每台机器上运行一个监测系统。
可以保证 Pod
的每一个副本在整个生命周期中名称是不变的。而其余 Controller
不提供这个功能,当某个 Pod
发生故障须要删除并从新启动时,Pod
的名称会发生变化。同时 StatefuleSet
会保证副本按照固定的顺序启动、更新或者删除。
用于运行结束就删除的应用。而其余 Controller
中的 Pod
一般是长期持续运行。
Pod
在 Kubernetes
中是不稳定的,它可能被销毁并从新建立,或者从新放置到了不一样的 Node
,它们的 IP 可能就不相同,因此为了让应用稳定的访问到 Pod
咱们就须要使用到 Service
。
Kubernetes
中的服务是一个抽象对象,它定义了一组逻辑的 Pods
和一个访问它们的策略。服务让互相依赖的 Pod 之间的耦合松动。
咱们部署了 Deployment
外界要访问咱们的应用,或者 Pod
到 Pod
之间的访问,就要用到 Service
。
Service
有本身的 IP 和端口,Service
为 Pod
提供了负载均衡。
它有几个子类型
(默认) - 在集群中的内部IP上公开服务。此类型使服务只能从集群中访问。
使用NAT在群集中每一个选定的节点的同一端口上显示该服务。使用 :
能够从群集外部访问服务。创建 ClusterIP 的超集。它相似于 docker run
中的 -p
参数。
在当前云中建立外部负载平衡器(若是支持),并为服务分配固定的外部IP。创建 NodePort
的超集。
用任意名称显示该服务,本过程经过使用该名称返回 CNAME 记录达成。无须使用代理。这种类型须要 v1.7 或更高版本的 kube-dns.
若是有多个用户或项目组使用同一个 Kubernetes Cluster
,可使用 Namespace
。
Namespace
能够将一个物理的 Cluster
逻辑上划分红多个虚拟 Cluster
,每一个 Cluster
就是一个 Namespace
。不一样 Namespace
里的资源是彻底隔离的。
默认会建立两个 Namespace
default
建立资源时若是不指定,将被放到这个 Namespace 中。kube-system
Kubernetes 本身建立的系统资源将放到这个 Namespace 中。Taint
是设置到节点上相似于标签,它分为三个部分 键=值:效果
,它好像在描述这个节点有这些污点,Pod
要会根据本身的 Toleration
(容忍)来判断本身要不要运行在这个节点。
Taint
和 toleration
相互配合,能够用来避免 pod
被分配到不合适的节点上。每一个节点上均可以应用一个或多个 taint
,这表示对于那些不能容忍这些 taint
的 p
od,是不会被该节点接受的。
$ kubectl taint nodes node1 key=value:NoSchedule
# 给节点 node1 设置 taint
$ kubectl taint nodes node1 key=value:NoSchedule-
# 后面加个减号能够删除这个 taint
复制代码
taint
一共有三种效果 NoSchedule
PreferNoSchedule
和 NoExecute
。
node
上有一个 pod
不能容忍的 NoSchedule
的 taint
,则 Kubernetes 不会将 pod 分配到该节点。node
上有一个 pod
不能容忍的 PreferNoSchedule
的 taint
,则 Kubernetes 会尝试将 pod
分配到该节点。node
上有一个 pod
不能容忍的 NoExecute
的 taint
,则 Kubernetes 不会将 pod
分配到该节点,和 NoSchedule
不一样若是 pod
已经在节点上运行它会将 pod
从该节点驱逐。Pod
能够经过配置文件它的 toleration
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
# operator 是 Equal,须要 键 值 效果彻底匹配
- key: "key2"
operator: "Exists"
effect: "NoSchedule"
# 若是 operator 是 Exists 则不能指定 value
- operator: "Exists"
# 表示这个 toleration 能容忍任意 taint
tolerations:
- key: "key3"
operator: "Exists"
# key 要匹配,效果任意
- key: "key4"
operator: "Equal"
value: "value4"
effect: "NoExecute"
tolerationSeconds: 3600
# tolerationSeconds 表明 node 设置了上面的 taint,
# Pod 还能够在上面运行 `tolerationSeconds` 秒,若是不设置则能够一直运行
复制代码
新版本的 Kubernetes 能够自动给 node 设置 taint
,如 node.kubernetes.io/not-ready
出于安全考虑,默认配置下 Kubernetes 不会将 Pod 调度到 Master 节点。若是但愿将 master 也看成 Node 使用,能够执行。
$ kubectl taint node node1 node-role.kubernetes.io/master-
# 去除
$ kubectl taint node k8s-master node-role.kubernetes.io/master='':NoSchedule
# 恢复
复制代码
$ kubectl describe node node1
# 咱们能够经过 kubectl describe 查看节点的 taint
复制代码
咱们如今使用 Kubernetes 建立一个小应用。
咱们在 deployment
中运行 4 个 Pod
副本,使用 NodePort
类型的 service
暴露咱们的 deployment
,让外部能够访问到。
可使用本地的 minikube
或 Kubernetes 交互教程中的虚拟机。
$ kubectl run es --image=elasticsearch:2 --port=9200
# kubectl run 有点相似 docker run 它会建立并运行指定类型的镜像
# 它也支持 `--rm` `--env` `--command` `--restart` 等这些参数
# 上面咱们建立一个 Deployment,Deployment 会建立 ReplicaSet
# 由 ReplicaSet 建立 Pod
# `--image` 用来指定镜像
# `--port` 是容器须要暴露的端口
# `--replicas` 参数为建立多少个副本,默认是 1
复制代码
$ kubectl get deploy
# deploy 也能够写成 deployments
NAME READY UP-TO-DATE AVAILABLE AGE
es 1/1 1 1 30s
$ kubectl get po
# po 也能够写成 pods
NAME READY STATUS RESTARTS AGE
es-6994df7bf8-cchzb 1/1 Running 0 51s
复制代码
kubectl get
可让咱们获取集群的各类资源信息,好比kubectl get nodes
获取集群节点信息,kubectl get namespaces
来获取命令空间信息。
咱们如今启动了一个 deployment
它里面有一个运行着 elasticsearch
容器的 pod
。可是咱们如今还不能访问到它,想要访问到它咱们须要 service
的帮助。
$ kubectl expose deploy es --port=9200 --target-port=9200 --type=NodePort
service/es exposed
# kubectl expose 将资源暴露成新的 service
# 上面咱们将名为 es 的 deployment 资源暴露出来
# `--type` 将类型设置为 NodePort
# `--port` 指定服务的端口,其余 deplyment 能够经过这个端口访问到咱们 es deplyment
# `--target-port` 目标端口 service 会将流量导入到这个端口
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
es NodePort 10.99.113.186 <none> 9200:32687/TCP 11s
# 能够看到咱们的服务被随机映射到了 32687 端口
$ curl `hostname -i`:32687
{
"name" : "Firelord",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "-QGqxWm3RTCrCv0wDAQJ9A",
"version" : {
"number" : "2.4.6",
"build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
"build_timestamp" : "2017-07-18T12:17:44Z",
"build_snapshot" : false,
"lucene_version" : "5.5.4"
},
"tagline" : "You Know, for Search"
}
# 如今咱们就能够访问到 es deployment 了
复制代码
如今想把咱们的 pod 增长 4 个,就须要用到 kubectl scale
命令。
$ kubectl scale --replicas=4 deployment/es
deployment.extensions/es scaled
# kubectl scale 用来伸缩
# Deployment, ReplicaSet, Replication Controller, 或 StatefulSet 的大小
# 咱们这里将 es 应用建立 4 个副本
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
es 4/4 4 4 3m49s
$ kubectl get po
NAME READY STATUS RESTARTS AGE
es-6994df7bf8-brhfw 1/1 Running 0 3m59s
es-6994df7bf8-bvmkk 1/1 Running 0 19s
es-6994df7bf8-ffv7c 1/1 Running 0 19s
es-6994df7bf8-z4kkf 1/1 Running 0 19s
$ curl `hostname -i`:32687
{
"name" : "Claudette St. Croix"
}
$ curl `hostname -i`:32687
{
"name" : "Firelord"
}
# 请求会被负载均衡到 4 个节点中的一个
复制代码
咱们还能够滚动更新
$ kubectl set image dployment/es es=elasticsearch:5
# 滚动跟新 elasticsearch:2 到 elasticsearch:5
# kubectl set 能够用来配置更新资源,它有多个子命令如 `image` `env` 等
# 上面命令咱们将 es deployment 的 es 容器的镜像更新到 elasticsearch:5
$ kubectl describe pod es
# kubectl describe 用来查看资源详情相似于 docker inspect
# kubectl describe 类型 前缀
Containers:
es:
Image: elasticsearch:5 # 镜像如今已是版本 5 了
Port: 9200/TCP
Host Port: 0/TCP
State: Running
复制代码
还能够撤销回去
$ kubectl rollout undo deployment/es
# kubectl rollout 用来管理回滚
# kubectl rollout undo 回滚到以前的版本
# `--to-revision=0` 回滚版本 默认 0(上一个版本)
$ kubectl describe po es
Containers:
es:
Image: elasticsearch:2 # 变回版本 2 了
Port: 9200/TCP
Host Port: 0/TCP
State: Running
复制代码
咱们除了使用 命令式 来建立资源,还可使用 yaml
配置文件。不一样于 docker-compose,Kubernetes 中一个配置文件只建立一个对象。使用配置文件咱们建立或更新资源只用 kubectl apply
这一个命令就能够了。
咱们如今使用配置文件建立一个 drupal 网站。
首先新建一个 k8s
目录,而后再里面建立一个 drupal-deploy.yml
文件
apiVersion: apps/v1
Kind: Deployment # 要建立对象的类型
metadata: # 元数据
name: drupal-deployment # 对象名称
namespace: default # 命名空间,默认 default
labels: # 标签
app: drupal-deployment
spec: # 配置
replicas: 1 # 指望的副本,默认 1
minReadySeconds: 0 # 应用准备时间,默认 0
selector: # 选择要管理的 Pod
matchLabels: # 须要与 Pod 的 label 匹配
app: drupal-pod
template: # pod 的配置
metadata: # pod 的元数据
labels: # 标签
app: drupal-pod
spec: # 配置
containers: # Pod 中的容器
- name: drupal # 名称
image: drupal # 镜像
imagePullPolicy: IfNotPresent
# IfNotPresent(默认)Always 或 Never
ports: # 暴露的端口
- containerPort: 80
protocol: TCP
# TCP(默认), UDP, 或 SCTP
tolerations: # Pod 容忍
- key: key
operator: Exists
restartPolicy: Always # Pod 重启规则
# Always(默认), OnFailure, 或 Never
复制代码
apiVersion
是 api 的版本,它控制能建立什么样的对象,好比咱们要建立一个 Deployment
对应的 apiVersion
是 apps/v1
,因此通常咱们通常根据 Kind
去选择 apiVersion
。能够在 API Reference 查看更多信息。
$ kubectl api-versions # 查看当前 kubernetes 支持的 api 版本
复制代码
API 版本号分为 3 种:
Alpha 测试版本
多是有缺陷的和随时被删除,默认状况是关闭的。Beta 测试版本
已经测试过,支持的功能不会删除,细节可能发生变化,默认开启。稳定版本
版本名称是 vX
,其中 X
是整数。imagePullPolicy
定义了镜像拉取的规则,默认是 IfNotPresent
,就是有本地缓存就用本地缓存,没有就去远程拉取,若是镜像名后的标签是:latest
则默认为 Always
。老是会去远程拉取。
Pod
是不稳定的它能够被建立,也能够被销毁,每一个 Pod
都会获取它本身的 IP
地址,当它被动态地建立和销毁,可能获取到不一样的 IP
,为了咱们能够稳定的访问到 Pod
就须要使用到 Service
。
有了 Service
咱们就无需关系后端 Pod
,Service
会把请求代理到合适的 Pod
。
默认的 Service
是 ClusterIP
(虚拟IP),ClusterIP
服务只可以在集群内部能够访问,没法被外部直接访问。
kube-proxy
负责为 ExternalName
之外的类型的服务实现一种形式的虚拟IP
如今咱们再建立一个 drupal-cluster-ip.yml
apiVersion: v1
kind: Service
metadata:
name: drupal-cluster-ip
spec:
type: ClusterIP
# ClusterIP(默认), ExternalName, NodePort, 或 LoadBalancer
sessionAffinity: None
# None(默认) 或 ClientIP
# 若是想让同一个客户端的请求链接到同一个 Pod 能够设置为 ClientIP
selector: # 经过标签选择 Pods
app: drupal-pod
ports:
- port: 80
# Service 的 port
targetPort: 80
# 目标(pod)的 port
protocol: TCP
# TCP(默认), UDP 或 SCTP
name: http
# 名称,当有多个端口时必填
复制代码
而后咱们建立 postgres-cluster-ip.yml
apiVersion: v1
kind: Service
metadata:
name: postgres-cluster-ip
spec:
selector:
app: postgres-pod
ports:
- port: 5432
targetPort: 5432
复制代码
当运行在 Pod
中的容器崩溃,重启时,容器中保存在磁盘上的数据都会被清空,在 Docker
中咱们使用 Volume
来解决这个问题。
在 Kubernetes
中也有 Volume
当容器重启时,Volume
中的数据不会被清除,并且 Pod
中的容器能够共享 Volume
。可是 Kubernetes Volume
也有生命周期,当 Pod
不存在时,Kubernetes Volume
也会不存在,可是使用如 awsElasticBlockStore
这种类型的 Volume
,删除 Pod
时不会删除 Volume
中的数据只是卸载数据卷。
Kubernetes Volume
支持很是多的类型,如 azureDisk
configMap
secret
等等。
emptyDir
类型是一个空的文件夹,当 Pod
被建立时,它也被建立,当 Pod
被删除时,它里面的数据将被永久删除。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts: # 挂在到容器中的位置
- mountPath: /cache
name: cache-volume
volumes: # 定义数据卷
- name: cache-volume # 数据卷名称
emptyDir:
medium: Memory
# 空字符串(默认) 或 Memory
# 该存储介质的是什么空字符串表明节点默认的媒介
sizeLimit: 1Gi # 数据卷大小,默认未定义
复制代码
hostPath
类型将节点中的目录挂在到容器中。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
# 节点中的路径
type: DirectoryOrCreate # 是目录,当不存在时自动建立
# 默认空字符串,表明挂载 hostPath 以前不会执行任何检查
# File, Directory, FileOrCreate, DirectoryOrCreate 等等
复制代码
Persistent Volumes
(PV)是群集中的一块存储,它生命周期独立于任何 pod
。
Persistent Volume Claim
(PVC)是用户对存储的请求,PVC
消耗 PV
资源,PVC
能够要求特定的大小和访问模式的存储。
咱们使用 PVC
来请求不一样大小的 PV
,集群管理员会根据请求找到符合的 PV
,若是不存在则会建立符合要求的 PV
。
咱们的应用的 postgres
使用 PV
,建立一个 db-pvc.yml
。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pvc
spec:
accessModes: # 访问模式
- ReadWriteOnce
volumeMode: Filesystem # 默认 Filesystem
resources:
requests:
storage: 1Gi # 请求的存储大小
storageClassName: standard # 选择属于这个类的 PV
# 特定类的 `PV` 只能绑定到请求该类的 `PVC`
selector:
matchLabels:
release: stable # 选择特定标签的 PV
复制代码
一共有三中访问模式
ReadWriteOnce
被一个节点挂载读写ReadOnlyMany
– 被多个节点挂载可读ReadWriteMany
– 被多个节点挂载读写咱们也能够手动建立一个 PersistentVolume
,配置它的 persistentVolumeReclaimPolicy
它的值 Delete
或 Retain
,也就是当咱们删除 PVC
时,PV
的中的数据是所有删除仍是保留。
而后再建立 postgres-deploy.yml
文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment
spec:
selector:
matchLabels:
app: postgres-pod
template:
metadata:
labels:
app: postgres-pod
spec:
volumes:
- name: postgres-volume
persistentVolumeClaim:
claimName: db-pvc
containers:
- name: postgres
image: postgres
env: # 设置容器的环境变量
- name: POSTGRES_PASSWORD
value: password
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-volume
mountPath: /var/lib/postgresql/data
subPath: postgres
# Volume 中的子目录
# 防止将 Volume 中其余文件也挂载进来
复制代码
Ingress
能够将集群外部的 HTTP
和 HTTPS
路由到集群中的服务。
要想 ingress
生效,必须有一个 ingress controller
知足它。
咱们使用 ingress-nginx 这个 ingress controller
,咱们可使用以下命令安装它。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
复制代码
若是使用 minikube 能够执行
minikube addons enable ingress
复制代码
也可使用 Helm 安装(Kubernetes 包管理器,功能强大)。
helm install stable/nginx-ingress --name my-nginx
复制代码
如今来建立 ingress-service.yml
文件。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations: # 和资源一块儿存储的键值对,它至关于一个额外的配置
kubernetes.io/ingress.class: nginx
# 表示咱们使用 ingress-nginx
nginx.ingress.kubernetes.io/rewrite-target: /
# 将 url 前缀重写为 /,如 /api/ 将会变成 /
spec:
rules:
- http:
paths:
- path: / # 该路径的 url 所有代理到咱们的 drupal-cluster-ip
backend:
serviceName: drupal-cluster-ip
servicePort: 80
复制代码
好了如今咱们就能够建立应用了。
$ kubectl apply -f k8s
复制代码
kubectl apply
来应用配置文件,-f
后面能够是文件,文件夹 或 url。
咱们可使用命令查看建立状态
$ kubectl get svc # 查看 services
$ kubectl get deploy 查看 deployments
$ kubectl get po # 查看 pods
$ kubectl get pv # 查看 Persistent Volumes
$ kubectl get pvc # 查看 Persistent Volume Claim
复制代码
发现所有建立成功后咱们就能够去浏览器访问咱们的应用了。
$ minikube ip # 获取虚拟机 ip,输入到浏览器中
复制代码
当咱们打开咱们的浏览器这个地址,会发现会跳转到 https
链接,而后浏览器报不安全的错误,咱们要点高级继续访问咱们的网站才能浏览咱们的应用。
由于咱们 ingress 默认是 https
的,咱们能够看见证书是一个假证书。
咱们可使用 cert manager 来自动配置和管理 TLS 证书。
能够看到咱们的 Host 能够直接填写 postgres service 的名称。
kubeadm
部署时会默认安装 kube-dns
组件,kube-dns
是一个 DNS
服务器。每当有新的 Service
被建立,kube-dns
会添加该 Service
的 DNS
记录。Cluster
中的 Pod
能够经过 <SERVICE_NAME>.<NAMESPACE_NAME>
访问 Service
。
因此咱们以能够经过 postgres-cluster-ip.default
访问,default
命名空间能够省略,咱们就能够写成 postgres-cluster-ip
。
Kubernetes 中可使用 label
来控制 Pod
运行的节点。
$ kubectl label pods foo unhealthy=true
# 给节点 foo 设置 label unhealthy=true
$ kubectl get node --show-labels
# 查看节点的 label
$ kubectl label --overwrite pods foo status=unhealthy
# 修改 node foo 的label
$ kubectl label pods --all status=unhealthy
# 给全部这个 namespace 中的节点添加指定 label
$ kubectl label pods foo bar-
# 后面加 - 号能够删除节点上的 label
复制代码
给节点设置了 label 后,咱们就可使用配置文件中的 nodeSelector
来指定
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
nodeSelector: # 选择要运行的节点
env: test
复制代码
若是咱们如今把节点的这个标签删除了,会发现 Pod 还运行在这个节点,不会从新部署。
Secret
对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。将这些信息放在 secret
中比放在 pod
的定义或者 docker
镜像中来讲更加安全和灵活。
Secret
会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret
会以 Volume
的形式被 mount
到 Pod
,容器可经过文件的方式使用 Secret
中的敏感数据。
咱们能够经过文件来建立 Secret
$ kubectl create secret generic my-secret \
--from-file=./username.txt \
--from-file=./password.txt
复制代码
也能够经过 yaml
文件建立
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data: # 每一项必须是 base64 编码
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
复制代码
kubectl create -f ./secret.yaml # 建立 secret
复制代码
而后咱们就能够在 Pod
中使用它
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: mysecret
items: # 可选,自定义访问的 secret
- key: password
path: a/pass
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: /etc/secret # 挂载的目录
复制代码
如今咱们就能够经过 /etc/secret/username
和 /etc/secret/a/pass
访问咱们的 Secret 了。
咱们还能够经过环境变量访问咱们的 Secret。
apiVersion: v1
metadata:
name: secret-test-pod
spec:
containers:
- name: ssh-test-container
image: mySshImage
env:
- name: SECRET
valueFrom:
secretKeyRef:
name: mysecret
key: username
复制代码
ConfigMap
能够用来保存应用配置信息,ConfigMap
和 Secret
很是相似,主要的不一样是数据以明文的形式存放。
$ kubectl create configmap myconfigmap \
--from-file=./config1 \
--from-file=./config2
复制代码
经过文件建立 configMap
。每一个文件内容对应一个信息条目。
咱们也可使用 yaml
文件。
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
data:
game.properties: | # | 表示保留换行符 enemies: aliens
lives: 3
enemies.cheat: true
enemies.cheat.level: noGoodRotten
secret.code.passphrase: UUDDLRLRBABAS
secret.code.allowed: true
secret.code.lives: 30
--- # 文件的开头,能够将多个配置写入一个文件中
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
复制代码
和 secret
同样也能够经过环境变量来使用,只是将 secretKeyRef
换为 configMapKeyRef
。
除了上面介绍的 kubernetes dashboard,还有不少监控工具。