容器化技术(No.2) -- Kubernetes 基础

前言

今天的分享主要有以下几个目标:

  • 了解什么是 Kubernetes, 架构组成及核心概念
  • 可以通过 kubeadm 独立搭建完整的集群
  • 尝试使用 kubectl 命令操作集群
  • 学习使用 YAML 编排简单任务

Docker 回顾

  • 什么是 Docker?
- 打包代码及其所有依赖项的软件的标准单元, 本质上是宿主机上的一个进程;
- 通过 namespace 实现了资源隔离, 通过 cgroups 实现了资源限制, 通过 copy-on-write 机制实现了高效的文件操作
- 与虚拟机相比, Docker 启动速度更快, 性能接近原生 (虚拟机损失 5% 左右), 资源使用更少

容器化技术(No.1) – Docker 基础

  • 思考:
  • 什么是 Kubernetes
  • 为什么要用 Kubernetes
  • Kubernetes 架构组成
  • Kubernetes 基本概念

Kubernetes

  • Kubernetes 是 Google 在 2014 年开源的一个容器集群管理系统, 简称 K8S.
  • Kubernetes 用于容器化应用程序的部署, 扩展和管理, 目标是让部署容器化应用简单高效.

官方网站:http://www.kubernetes.io

技术架构及核心概念

技术架构

Kubernetes-Arch.png

Master

  • kube-apiserver

Kubernetes API, 集群的统一入口, 通过 api server 控制着这些资源的访问权限,通过使用暴露给外部用户REST API接口执行对Kubernetes资源的CRUD操作, 处理后再提交给 Etcd 存储.

  • kube-controller-manager

处理集群中常规后台任务, 一个资源对应一个控制器, 而ControllerManager就是负责管理这些控制器的.

  • kube-scheduler

根据调度算法为新创建的Pod选择一个Node节点, 可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上.

  • etcd

分布式键值存储系统.用于保存集群状态数据, 比如Pod、Service等对象信息.

Worker

  • kubelet

kubelet是Master在Node节点上的Agent, 管理本机运行容器的生命周期, 比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作.kubelet将每个Pod转换成一组容器.

  • kube-proxy

在Node节点上实现Pod网络代理, 维护网络规则和四层负载均衡工作. 主要作用就是负责 service 的实.

  • docker

容器引擎, 运行容器.

核心概念

Pod

  • 最小部署单元
  • 一组容器的集合
  • 一个Pod中的容器共享网络命名空间
  • Pod是短暂的

Controllers

  • Deployment : 无状态应用部署
  • StatefulSet: 有状态应用部署
  • DaemonSet : 确保所有 Node 运行相同的 Pod
  • Job : 一次性任务
  • Cronjob : 定时任务

控制器是更高级层次对象, 用于部署和管理 Pod.

Service

  • 防止 Pod 失联
  • 定义一组 Pod 的访问策略

Label

  • 标签, 附加到某个资源上, 用于关联对象、查询和筛选

Namespaces

  • 命名空间, 将对象逻辑上隔离

基础实践

部署方式

官方提供三种部署方式:

  • minikube

Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,仅用于尝试Kubernetes或日常开发的用户使用。
部署地址:https://kubernetes.io/docs/setup/minikube

  • kubeadm

Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。
部署地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm

  • 二进制

推荐,从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
下载地址:https://github.com/kubernetes/kubernetes/releases

部署集群

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.

这个工具能通过两条指令完成一个kubernetes集群的部署:

# 创建一个 Master 节点
$ kubeadm init

# 将一个 Node 节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口 >
安装要求

在开始之前, 部署Kubernetes集群机器需要满足以下几个条件:

  • 一台或多台机器, 操作系统 CentOS7.x-86_x64
  • 硬件配置:>=2GB mem, >=2 core, >=30GB disk
  • 集群中所有机器之间网络互通
  • 可以访问外网, 需要拉取镜像
  • 禁止swap分区
准备环境
角色IP
k8s-master192.168.0.10
k8s-node1192.168.0.11
k8s-node2192.168.0.12
#关闭防火墙
$ systemctl stop firewalld
$ systemctl disable firewalld

#关闭selinux
$ sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
$ setenforce 0  # 临时

#关闭swap
$ swapoff -a  # 临时
$ vim /etc/fstab  # 永久

#设置主机名
$ hostnamectl set-hostname <hostname>

#在master添加hosts
$ cat >> /etc/hosts << EOF
192.168.0.1 k8s-master
192.168.0.2 k8s-node1
192.168.0.3 k8s-node2
EOF

#将桥接的IPv4流量传递到iptables的链
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system  # 生效

#时间同步
$ yum install ntpdate -y
$ ntpdate -u cn.ntp.org.cn
所有节点安装Docker/kubeadm/kubelet

Kubernetes 默认 CRI(容器运行时)为 Docker, 因此先安装 Docker.

1、 安装Docker

$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum install -y docker-ce-18.09.9-3.el7 
$ systemctl enable docker && systemctl start docker
$ docker --version
# cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

2、 添加阿里云 YUM 软件源

$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

3、 安装 kubeadm, kubelet 和 kubectl
由于版本更新频繁, 这里指定版本号部署:

$ yum install -y kubelet-1.16.2 kubeadm-1.16.2 kubectl-1.16.2
$ systemctl enable kubelet
部署 Kubernetes Master

在192.168.0.10(Master)执行.

$ kubeadm init \
  --apiserver-advertise-address=192.168.0.10 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.16.2 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

kubeadm 到底做了什么? 稍后说明.

由于默认拉取镜像地址k8s.gcr.io国内无法访问, 这里指定阿里云镜像仓库地址.

使用kubectl工具:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get nodes
安装Pod网络插件(CNI)
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

确保能够访问到quay.io这个registery.

加入Kubernetes Node

在192.168.0.11/12(Worker)执行.

向集群添加新节点, 执行在kubeadm init输出的kubeadm join命令:

$ kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c \
    --discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9

默认token有效期为24小时, 超时就需要重新创建token, 操作如下:

# Master 节点执行
$ kubeadm token create
i1ofj9.ujm6xpc7sx4tmt1c
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9
# Worker 上执行
$ kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c --discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9

也可以通过如下命令直接获取

$ kubeadm token create --print-join-command

官方文档: https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join

测试kubernetes集群

在Kubernetes集群中创建一个pod, 验证是否正常运行:

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

访问地址:http://NodeIP:Port

部署 Dashboard
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

默认Dashboard只能集群内部访问, 修改Service为NodePort类型, 暴露到外部:

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

访问地址:http://NodeIP:Port

创建service account并绑定默认cluster-admin管理员集群角色:

kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

使用输出的token登录Dashboard.

kubeadm init 到底做了些什么
[root@Ali-irvin ~]# kubeadm init \
>   --apiserver-advertise-address=192.168.0.10 \
>   --image-repository registry.aliyuncs.com/google_containers \
>   --kubernetes-version v1.16.2 \
>   --service-cidr=10.96.0.0/12 \
>   --pod-network-cidr=10.244.0.0/16
[init] Using Kubernetes version: v1.16.
# 1. 环境检查
[preflight] Running pre-flight checks       
	[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
# 2. 下载镜像
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
# 3. 为 kubelet 创建配置文件并启动
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Activating the kubelet service
# 4. 为apiserver、etcd生成https证书
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [ali-irvin kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.10]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [ali-irvin localhost] and IPs [192.168.0.10 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [ali-irvin localhost] and IPs [192.168.0.10 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
# 5. 生成连接apiserver的kubeconfig文件
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
# 6. 容器启动 master 组件
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 18.002987 seconds
# 7. 将涉及的配置文件存储到 configmap
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.16" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
# 8. 设置 master 节点不可调度 Pod
[mark-control-plane] Marking the node ali-irvin as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node ali-irvin as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
# 9. 启用 bootstrap 自动为 kubelet 颁发证书
[bootstrap-token] Using token: i1ofj9.ujm6xpc7sx4tmt1c
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
# 10. 安装插件:CoreDNS、kube-proxy
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.0.10:6443 --token i1ofj9.ujm6xpc7sx4tmt1c \
    --discovery-token-ca-cert-hash sha256:7ce38ff560c14aa85e2ae1736c081019b9890c78aee86cd75c4ff1ef311d6aa9
[root@Ali-irvin ~]#
1、检查系统环境是否满足,例如swap是否关闭、配置是否满足
2、下载所需镜像,kubeadm config images pull
3、为 kubelet 创建配置文件并启动
4、为 apiserver、etcd 生成 https 证书(/etc/kubernetes/pki/)
5、生成连接 apiserver 的 kubeconfig 文件
6、容器启动 master 组件
7、将涉及的配置文件存储到 configmap
8、设置 master 节点不可调度 Pod
9、启用 bootstrap 自动为 kubelet 颁发证书
10、安装插件:CoreDNS、kube-proxy
常见问题

1. 证书问题

问题: 仅火狐浏览器可访问 Dashboard

原因: 官方提供的自签证书有问题(有效时间)

解决方案:

  1. 删除默认的secret
  2. 用自签证书创建新的secret
  3. 修改 dashboard.yaml 文件

2. token 失效

$ kubeadm token create --print-join-command

3. 环境清理

$ kubeadm reset
命令行操作

kubectl --help 查看帮助信息

kubectl create --help 查看 create 命令帮助信息

命令描述
create通过文件名或标准输入创建资源
expose将一个资源公开为一个新的Service
run在集群中运行一个特定的镜像
set在对象上设置特定的功能
get显示一个或多个资源
explain文档参考资料
edit使用默认的编辑器编辑一个资源.
delete通过文件名、标准输入、资源名称或标签选择器来删除资源.
rollout管理资源的发布
rolling-update对给定的复制控制器滚动更新
scale扩容或缩容Pod数量, Deployment、ReplicaSet、RC或Job
autoscale创建一个自动选择扩容或缩容并设置Pod数量
certificate修改证书资源
cluster-info显示集群信息
top显示资源(CPU/Memory/Storage)使用.需要Heapster运行
cordon标记节点不可调度
uncordon标记节点可调度
drain驱逐节点上的应用, 准备下线维护
taint修改节点taint标记
describe显示特定资源或资源组的详细信息
logs在一个Pod中打印一个容器日志.如果Pod只有一个容器, 容器名称是可选的
attach附加到一个运行的容器
exec执行命令到容器
port-forward转发一个或多个本地端口到一个pod
proxy运行一个proxy到Kubernetes API server
cp拷贝文件或目录到容器中
auth检查授权
apply通过文件名或标准输入对资源应用配置
patch使用补丁修改、更新资源的字段
replace通过文件名或标准输入替换一个资源
convert不同的API版本之间转换配置文件
label更新资源上的标签
annotate更新资源上的注释
completion用于实现kubectl工具自动补全
api-versions打印受支持的API版本
config修改kubeconfig文件(用于访问API, 比如配置认证信息)
help所有命令帮助
plugin运行一个命令行插件
version打印客户端和服务版本信息

使用kubectl管理应用生命周期

# 创建
$ kubectl create deployment web --image=java 
$ kubectl get deploy,pods

# 发布
$ kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web
$ kubectl get service

# 升级
$ kubectl set image deployment/web nginx=nginx:1.15
$ kubectl rollout status deployment/nginx-deployment  # 查看升级状态

# 回滚
$ kubectl rollout history deployment/web  # 查看发布记录
$ kubectl rollout undo deployment/web   # 回滚最新版本
$ kubectl rollout undo deployment/web --revision=2  # 回滚指定版本

# 删除
$ kubectl delete deploy/web
$ kubectl delete svc/web

常用选项

-f, --filename=[]: 文件名、目录、或者URL创建资源
-o, --output='': json|yaml|name|wide   所有查看的资源都可以用
-l, --selector='': 根据标签过滤内容,支持运算符 '=', '==','!='.(示例 -l key1=value1,key2=value2)
资源编排
编写YAML注意事项

YAML 是一种简洁的非标记语言.

语法格式:

  • 缩进表示层级关系
  • 不支持制表符“tab”缩进, 使用空格缩进
  • 通常开头缩进 2 个空格
  • 字符后缩进 1 个空格, 如冒号、逗号等
  • “—” 表示YAML格式, 一个文件的开始
  • “#”注释
YAML内容解析

YAML 编排文件内容大致分为两部分:

# 控制器相关定义
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLables:
      app: nginx
# 被控制对象定义
    template:
      metadata:
        lables:
          app: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:latest
          ports:
          - containerPort:80

控制器定义:定义控制器属性
被控制对象:Pod 模板, 定义容器属性

具体字段意义:

apiVersionAPI版本
kind资源类型
metadata资源元数据
spec资源规格
replicas副本数量
selector标签选择器
templatePod模板
metadataPod元数据
specPod规格
containers容器配置
编写 YAML

熟能生巧, 多写. 另外可通过如下方式快速生成, 基于实际场景修改.

  • run 命令生成部署模板

    kubectl create deployment nginx --image=nginx:1.14 -o yaml --dry-run> my-deploy.yaml

  • get 命令将已有部署的应用yaml导出

    kubectl get my-deploy/nginx -o=yaml --export > my-deploy.yaml

  • 通过 explain 查看更详细的帮助文档获得

    kubectl explain pods.spec.containers

总结

Kubernetes 基础

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值