使用K8s的ConfigMap服务

前言

我在前两篇文章里,介绍如何搭建Dashboard以及K8s的架构和实现原理,这篇文章,我么尝试使用ConfigMap创建Redis服务。

创建Redis服务

由于当前集群的安装的版本与官方的不一致,按照官方最新的教程来实现的话,可能会出现异常问题。在这里,我们尝试用kubectl的1.12版本来使用ConfigMap创建Redis服务。

首先创建configmap目录,存放我们的配置文件。

mkdir configmap
cat <<EOF >>./redis-config
maxmemory 2mb
maxmemory-policy allkeys-lru
EOF

在这里,我们定义redis的两个配置选项:最大内存容量为2MB,超过容量的策略为,首先尝试删除最近使用较少的(LRU)键,以便为添加的新数据腾出空间。

创建ConfigMap,名称为example-redis-config,配置文件为configmap/redis-config。

kubectl create configmap example-redis-config --from-file=configmap/redis-config

检查创建的configmap配置文件

kubectl get configmap example-redis-config -o yaml

apiVersion: v1
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru
kind: ConfigMap
metadata:
  creationTimestamp: 2019-07-14T06:16:30Z
  name: example-redis-config
  namespace: default
  resourceVersion: "2565685803"
  selfLink: /api/v1/namespaces/default/configmaps/example-redis-config
  uid: eb5f8b0d-a5fe-11e9-b0be-32a10a974892

新建redis-pod.yaml配置文件

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis:5.0.4
    command:
      - redis-server
      - "/redis-master/redis.conf"
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf

创建pod

kubectl create -f configmap/redis-pod.yaml
pod/redis created

检查创建的pods

kuberctl get pods
NAME    READY   STATUS    RESTARTS   AGE
redis   1/1     Running   0          21s

验证创建的服务

kubectl exec -it redis redis-cli
127.0.0.1:6379> CONFIG get maxmemory
1) "maxmemory"
2) "2097152"
127.0.0.1:6379> CONFIG get maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
127.0.0.1:6379>

常用命令

比如创建服务kubectl create configmap命令,其中是要分配给ConfigMap的名称,是从中提取数据的目录,文件或文字值。

kubectl create configmap <map-name> <data-source>

参考链接

  1. Configuring Redis using a ConfigMap
  2. 使用ConfigMap来配置Redis

搭建k8s的Dashboard服务

前言

这篇文章记录下自己搭建一个Kubernetes Dashboard的过程。

什么是Kubernetes Dashboard

Kubernetes Dashboard是一套基于Web的通用UI,可以允许用户对集群中运行的应用进行管理以及故障修复,还可以管理集群本身。安装完k8s后,大部分操作都是基于kubectl命令来操作的,使用Kubernetes Dashboard可以更方便的管理集群。

怎么搭建Kubernetes Dashboard

搭建Kubernetes Dashboard 大致需要以下几个步骤:

  1. 生成Https证书
  2. 创建认证Token
  3. 部署服务
  4. 获取认证Token
  5. 访问登录

生成Https证书

mkdir certs
openssl req -nodes -newkey rsa:2048 -keyout certs/dashboard.key -out certs/dashboard.csr -subj "/C=/ST=/L=/O=/OU=/CN=kubernetes-dashboard"
openssl x509 -req -sha256 -days 10000 -in certs/dashboard.csr -signkey certs/dashboard.key -out certs/dashboard.crt

第一行命令openssl req 创建新的PKCS#10格式证书请求和新私钥。其中dashboard.key是私钥,dashboard.csr是证书请求。所谓的CSR就是Certificate Signing Request。

第二行命令,openssl x509 对上面生成的csr,用dashboard.key私钥自签名,生成dashboard.crt。所谓的CRT就是certificate的缩写,即证书。

创建认证Token

官方wiki里,推荐使用https的链接来访问Dashboard。默认情况下会生成自签名证书并将其存储在内存中。如果要自定义证书,就需要按照下面的命令操作。自定义证书必须存储在命名 空间kubernetes-dashboard-certskube-system命名的机密中。假设你有dashboard.crtdashboard.key文件存储在$HOME/certs目录下,你应该用这些文件的内容创建Token,该命令如下:

kubectl create secret generic kubernetes-dashboard-certs --from-file=$HOME/certs -n kube-system

部署服务

根据kubernetes-dashboard-lb.yaml 文件来部署服务,详细配置文件如下:

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1beta2
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - name: kubernetes-dashboard
        image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          - --auto-generate-certificates
          # Uncomment the following line to manually specify Kubernetes API server Host
          # If not specified, Dashboard will attempt to auto discover the API server and connect
          # to it. Uncomment only if the default does not work.
          # - --apiserver-host=http://my-address:port
        volumeMounts:
        - name: kubernetes-dashboard-certs
          mountPath: /certs
          # Create on-disk volume to store exec logs
        - mountPath: /tmp
          name: tmp-volume
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: kubernetes-dashboard-certs
        secret:
          secretName: kubernetes-dashboard-certs
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
  annotations:
    service.kubernetes.io/qcloud-loadbalancer-clusterid: cls-xxxxxx
    service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-8uouk8f0
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: LoadBalancer
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

这个配置文件主要定义创建账户,绑定对应的角色以及如何部署该服务:

  1. 服务账户 Dashboard Service Account
  2. 账户角色的绑定 Dashboard Role & Role Binding
  3. 服务的部署 Dashboard Deployment

部署的命令如下:

CLUSTER_ID=$(cat /etc/kubernetes/config | grep KUBE_CLUSTER | awk -F '"' '{print $2}')
sed -i "154s/cls-[a-z0-9]*/${CLUSTER_ID}/" kubernetes-dashboard-lb.yaml
kubectl create -f kubernetes-dashboard-lb.yaml

这一行命令是这样运行的:

  1. 从/etc/kubernetes/config的配置文件,获取KUBE_CLUSTER变量值,使用awk流编辑器,以双引号作为字段分隔符,获取第二列的值保存到临时变量CLUSTER_ID
  2. 使用sed 编辑替换第154行的cls-后面字符为当前获取到CLUSTER_ID变量值。
  3. kubectl 对该配置文件进行部署。

获取认证Token

通过以下命令,检查部署服务的状态,即name为Kubernetes-dashboard开头的服务status为Running。

kubectl get pod -n kube-system

这一行命令是这样获取资源信息的:

  1. kubectl get 列举应用实例的信息
  2. -n 参数指定namespace 为kube-system

按照以下配置文件admin-role.yaml进行部署:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile

执行部署命令:

kubectl create -f admin-role.yaml

获取认证Token:

kubectl -n kube-system describe secret admin-token

这一行命令,从命名空间kube-system获取描述信息,复制记录token: 后的字符串,方便后面登录Dashboard。

访问登录

执行以下命令获取访问地址:

kubectl get service kubernetes-dashboard -n kube-system

从EXTERNAL-IP获取到对外可访问的ip地址,输入浏览器https://ip即可访问。访问成功后,选择Token登录即可。这样我们就成功部署了Kubernetes Dashboard服务了。

总结

这篇文章介绍如何搭建Kubernetes Dashboard服务,这仅仅是学习Kubernetes的第一步,使用Kubernetes Dashboard服务可以更好的管理你的集群。K8s的架构设计可能要复杂得多,一篇文章可能还无法窥见全貌,希望通过搭建Dashboard服务可以更好的了解学习K8s服务。

K8s必知必会

前言

Kubernetes是用于自动部署,扩展和容器花应用程序的开源系统,简单的来讲就是容器集群调度平台,可以自动化应用容器的部署、扩展和操作,提供以容器为中心的基础架构。

使用 Kubernetes, 您可以快速高效地响应客户需求:

  • 快速、可预测地部署您的应用程序
  • 拥有即时扩展应用程序的能力
  • 不影响现有业务的情况下,无缝地发布新功能
  • 优化硬件资源,降低成本

应用场景

我们先看下k8s的官方对应用场景的定义。

Kubernetes是Google基于Borg开源的容器编排调度引擎,作为CNCF(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动地达到和维持在这个状态。Kubernetes作为云原生应用的基石,相当于一个云操作系统,其重要性不言而喻。

这些定义是什么鬼?为什么每个字我都认识,但就不明白是啥意思?

来,我们先理解下什么是云?这里的云,肯定不是天上飘的那种,我们说的云,其实就是云服务。我还是先去翻翻维基百科吧。云的定义是这样子的:

云计算(英语:cloud computing),是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需求提供给计算机各种终端和其他设备。

所谓的云就是,以互联网的方式提供服务器端的计算服务。在云上,你可以运行很多自定义的服务,而不需要关心基础设施的细节,简单的来讲,你不需要自己购买维护服务器硬件了,因为你可以买云提供商已经部署的服务器,直接用就可以了。

那么问题来了,虽然不需要管理维护服务器硬件了,但我们运行部署的自定义服务,还是得自己维护吧。这时候,K8s就站出来说,它可以帮你管理运行的应用,不管你的应用啥时候挂了,还是需要扩容,它都可以帮你搞定。只要你描述了整个集群的架构是怎么样的,定义你的服务最终状态,K8s都可以很好管理和维护服务的状态。那K8s到底是怎么做到的呢?

组成部分

K8s的主要组成部分有3个,分别为:Master、Node、Pods。

Master

负责集群内所有pods的状态,负载均衡等,主要组件有Ectd、Controller Manager、API Server、Scheduler等。

  1. 采用Etcd键值对服务,保存了整个集群的状态。
  2. Controller Manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
  3. API Server提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
  4. Scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上

Node

这些Node和我们经常遇到的节点,其实就是一回事。这些都是真实的物理机器,连接了网络,有CPU计算能力。主要组成有:

  1. kubelet负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理

  2. Container runtime负责镜像管理以及Pod和容器的真正运行(CRI)

  3. kube-proxy负责为Service提供cluster内部的服务发现和负载均衡

再往下走,就涉及到主机的操作系统OS,底层硬件了。

Pods

这是整个架构中的精华部分。

对节点抽象出来的一层,节点的操作系统,硬件部分可能会有不同的差异,通过在Docker+Kubelet+kuebe-proxy的基础上抽象出一个集装箱层,类似与编程中对业务逻辑的抽象,也就是Pod.

这一层关注的是标准化,提供集装箱Pod的格式给到业务,至于里面的应用,只要符合Pod的标准,都可以正常运行起来,并且还是支持自动部署,自动恢复,负载均衡等。

关键点

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构。

分类 实现 备注
核心层 Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
服务层 部署服务(无状态应用、有状态应用、批处理任务、集群应用等)
路由服务(服务发现、DNS解析等)
Service Mesh服务(部分位于应用层)
管理服务:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)、Service Mesh(部分位于管理层)
接口服务:kubectl命令行工具、客户端SDK以及集群联邦
应用层 也就是可以运行的生态系统服务
Kubernetes外部:日志、监控、配置管理、CI/CD、Workflow、FaaS、OTS应用、ChatOps、GitOps、SecOps等
Kubernetes内部:CRICNICSI、镜像仓库、Cloud Provider、集群自身的配置和管理等

总结

文章中,我们了解到云的定义,K8s的应用场景,以及K8s的常用组件,下面,我们尝试搭建K8s组件Dashborad,方便管理集群。

参考链接

  1. Kubernetes架构