Kubernetes 零基础入门

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 k8sdocker

或者去 官网交互教程windows

概念

建立一个集群须要使用到 kubeadm,它会生成证书,配置文件,安装附加组键,如 kube-proxykube-dns。几乎全部的 Kubernetes 组件自己也运行在 Pod 里。后端

Pod

Kubernetes 中咱们不直接管理容器,而是 Pod。它是最小工做单元。

一个 Pod 是一个或一组运行很是紧密的容器, Pod 中的全部容器使用同一个网络 namespace,即相同的 IP 地址和 Port 空间。它们能够直接用 localhost 通讯。一样的,这些容器能够共享存储,当 Kubernetes 挂载 volumePod,本质上是将 volume 挂载到 Pod 中的每个容器。

PodPendingRunningSucceededFailedUnknown 这几个阶段。

咱们通常不本身建立 Pod, 而是建立 Deployment

Master

Kubernetes 集群中主机分为 masternode

MasterCluster 的大脑,它负责管理集群,主要职责是调度,决定将应用放在哪里运行。一个主机能够同时拥有 MasterNode 两种身份。

Master 上运行着

kube-apiserver

API Server 提供 HTTP/HTTPS RESTful API。API Server 是 Kubernetes Cluster 的前端接口,各类客户端工具(CLI 或 UI)以及 Kubernetes 其余组件能够经过它管理 Cluster 的各类资源。

kube-controller-manager

Controller Manager 负责管理 Cluster 各类资源,保证资源处于预期的状态。Controller Manager 由多种 controller 组成,包括 replication controllerendpoints controllernamespace controllerserviceaccounts controller 等。不一样的 controller 管理不一样的资源。

etcd

etcd 负责保存 Kubernetes Cluster 的配置信息和各类资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。

Pod 网络

Pod 网络让 Kubernetes Cluster 中 Pod 可以相互通讯。

Node

Node 的职责是运行容器应用。NodeMaster 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。

每一个工做节点都有一个 Kubelet,它是管理 节点 并与 Kubernetes Master 节点进行通讯的代理。节点 上还应具备处理容器操做的工做,例如 Dockerrkt。一个 Kubernetes 工做集群至少有三个节点。

Node 上运行的 Kubernetes 组件有

kubelet

kubeletNodeagent,当 Scheduler 肯定在某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image、volume 等)发送给该节点的 kubeletkubelet 根据这些信息建立和运行容器,并向 Master 报告运行状态。

kube-proxy

每一个 Node 都会运行 kube-proxy 服务,它负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。若是有多个副本,kube-proxy 会实现负载均衡。

Pod 网络

Pod 网络让 Kubernetes Cluster 中 Pod 可以相互通讯。

Controller

Kubernetes 一般不会直接建立 Pod,而是经过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,好比有几个副本,在什么样的 Node 上运行等。Kubernetes 中有多种 Controller

Deployment

Deployment 能够管理 Pod 的多个副本。Deployment 负责建立和更新应用程序实例。建立 Deployment 后, Kubernetes master 会将 Deployment 建立的应用程序实例调度到集群中的各个节点。

ReplicaSet

实现了 Pod 的多副本管理。使用 Deployment 时会自动建立 ReplicaSet,也就是说 Deployment 是经过 ReplicaSet 来管理 Pod 的多个副本,咱们一般不须要直接使用 ReplicaSet

DaemonSet

用于每一个 Node 最多只运行一个 Pod 副本的场景。好比运行每台机器上运行一个监测系统。

StatefuleSet

可以保证 Pod 的每一个副本在整个生命周期中名称是不变的。而其余 Controller 不提供这个功能,当某个 Pod 发生故障须要删除并从新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。

Job

用于运行结束就删除的应用。而其余 Controller 中的 Pod 一般是长期持续运行。

Service

PodKubernetes 中是不稳定的,它可能被销毁并从新建立,或者从新放置到了不一样的 Node,它们的 IP 可能就不相同,因此为了让应用稳定的访问到 Pod 咱们就须要使用到 Service

Kubernetes 中的服务是一个抽象对象,它定义了一组逻辑的 Pods 和一个访问它们的策略。服务让互相依赖的 Pod 之间的耦合松动。

咱们部署了 Deployment 外界要访问咱们的应用,或者 PodPod 之间的访问,就要用到 Service

Service 有本身的 IP 和端口,ServicePod 提供了负载均衡。

它有几个子类型

ClusterIP

(默认) - 在集群中的内部IP上公开服务。此类型使服务只能从集群中访问。

NodePort

使用NAT在群集中每一个选定的节点的同一端口上显示该服务。使用 :能够从群集外部访问服务。创建 ClusterIP 的超集。它相似于 docker run 中的 -p 参数。

LoadBalancer

在当前云中建立外部负载平衡器(若是支持),并为服务分配固定的外部IP。创建 NodePort 的超集。

ExternalName

用任意名称显示该服务,本过程经过使用该名称返回 CNAME 记录达成。无须使用代理。这种类型须要 v1.7 或更高版本的 kube-dns.

Namespace

若是有多个用户或项目组使用同一个 Kubernetes Cluster,可使用 Namespace

Namespace 能够将一个物理的 Cluster 逻辑上划分红多个虚拟 Cluster,每一个 Cluster 就是一个 Namespace。不一样 Namespace 里的资源是彻底隔离的。

默认会建立两个 Namespace

  • default 建立资源时若是不指定,将被放到这个 Namespace 中。
  • kube-system Kubernetes 本身建立的系统资源将放到这个 Namespace 中。

Taint 和 Toleration

Taint 是设置到节点上相似于标签,它分为三个部分 键=值:效果,它好像在描述这个节点有这些污点,Pod 要会根据本身的 Toleration(容忍)来判断本身要不要运行在这个节点。

Tainttoleration 相互配合,能够用来避免 pod 被分配到不合适的节点上。每一个节点上均可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taintpod,是不会被该节点接受的。

$ kubectl taint nodes node1 key=value:NoSchedule
# 给节点 node1 设置 taint
$ kubectl taint nodes node1 key=value:NoSchedule-
# 后面加个减号能够删除这个 taint
复制代码

效果

taint 一共有三种效果 NoSchedule PreferNoScheduleNoExecute

  • 若是 node 上有一个 pod 不能容忍的 NoScheduletaint,则 Kubernetes 不会将 pod 分配到该节点。
  • 若是 node 上有一个 pod 不能容忍的 PreferNoScheduletaint,则 Kubernetes 会尝试pod 分配到该节点。
  • 若是 node 上有一个 pod 不能容忍的 NoExecutetaint,则 Kubernetes 不会将 pod 分配到该节点,和 NoSchedule 不一样若是 pod 已经在节点上运行它会将 pod 从该节点驱逐。

tolerations

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 对应的 apiVersionapps/v1,因此通常咱们通常根据 Kind 去选择 apiVersion。能够在 API Reference 查看更多信息。

$ kubectl api-versions # 查看当前 kubernetes 支持的 api 版本
复制代码

API 版本号分为 3 种:

  • Alpha 测试版本 多是有缺陷的和随时被删除,默认状况是关闭的。
  • Beta 测试版本 已经测试过,支持的功能不会删除,细节可能发生变化,默认开启。
  • 稳定版本 版本名称是 vX,其中 X 是整数。

imagePullPolicy 定义了镜像拉取的规则,默认是 IfNotPresent,就是有本地缓存就用本地缓存,没有就去远程拉取,若是镜像名后的标签是:latest 则默认为 Always。老是会去远程拉取。

Service

Pod 是不稳定的它能够被建立,也能够被销毁,每一个 Pod 都会获取它本身的 IP 地址,当它被动态地建立和销毁,可能获取到不一样的 IP,为了咱们能够稳定的访问到 Pod 就须要使用到 Service

有了 Service 咱们就无需关系后端 PodService 会把请求代理到合适的 Pod

默认的 ServiceClusterIP(虚拟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
复制代码

Volumes

当运行在 Pod 中的容器崩溃,重启时,容器中保存在磁盘上的数据都会被清空,在 Docker 中咱们使用 Volume 来解决这个问题。

Kubernetes 中也有 Volume 当容器重启时,Volume 中的数据不会被清除,并且 Pod 中的容器能够共享 Volume。可是 Kubernetes Volume 也有生命周期,当 Pod 不存在时,Kubernetes Volume 也会不存在,可是使用如 awsElasticBlockStore 这种类型的 Volume,删除 Pod 时不会删除 Volume 中的数据只是卸载数据卷。

Kubernetes Volume 支持很是多的类型,如 azureDisk configMap secret 等等。

emptyDir

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

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

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 它的值 DeleteRetain ,也就是当咱们删除 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

Ingress 能够将集群外部的 HTTPHTTPS 路由到集群中的服务。

要想 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 证书。

DNS

能够看到咱们的 Host 能够直接填写 postgres service 的名称。

kubeadm 部署时会默认安装 kube-dns 组件,kube-dns 是一个 DNS 服务器。每当有新的 Service 被建立,kube-dns 会添加该 ServiceDNS 记录。Cluster 中的 Pod 能够经过 <SERVICE_NAME>.<NAMESPACE_NAME> 访问 Service

因此咱们以能够经过 postgres-cluster-ip.default 访问,default 命名空间能够省略,咱们就能够写成 postgres-cluster-ip

控制 Pod 运行的 Node

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

Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。将这些信息放在 secret 中比放在 pod 的定义或者 docker 镜像中来讲更加安全和灵活。

Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mountPod,容器可经过文件的方式使用 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 能够用来保存应用配置信息,ConfigMapSecret 很是相似,主要的不一样是数据以明文的形式存放。

$ 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,还有不少监控工具。

  • Prometheus Operator 是 CoreOS 开发的基于 Prometheus 的 Kubernetes 监控方案,也多是目前功能最全面的开源方案

更多

Docker 零基础入门

Docker Compose 零基础入门

Docker Swarm 零基础入门

相关文章
相关标签/搜索