前言
今天的分享主要有以下几个目标:
- 了解什么是 Kubernetes, 架构组成及核心概念
- 可以通过 kubeadm 独立搭建完整的集群
- 尝试使用 kubectl 命令操作集群
- 学习使用 YAML 编排简单任务
Docker 回顾
- 什么是 Docker?
- 打包代码及其所有依赖项的软件的标准单元, 本质上是宿主机上的一个进程;
- 通过 namespace 实现了资源隔离, 通过 cgroups 实现了资源限制, 通过 copy-on-write 机制实现了高效的文件操作
- 与虚拟机相比, Docker 启动速度更快, 性能接近原生 (虚拟机损失 5% 左右), 资源使用更少
- 思考:
- 什么是 Kubernetes
- 为什么要用 Kubernetes
- Kubernetes 架构组成
- Kubernetes 基本概念
Kubernetes
- Kubernetes 是 Google 在 2014 年开源的一个容器集群管理系统, 简称 K8S.
- Kubernetes 用于容器化应用程序的部署, 扩展和管理, 目标是让部署容器化应用简单高效.
技术架构及核心概念
技术架构
Kubernetes-Arch.pngMaster
- 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-master | 192.168.0.10 |
k8s-node1 | 192.168.0.11 |
k8s-node2 | 192.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
原因: 官方提供的字签证书有问题(有效时间)
解决方案:
- 删除默认的secret
- 用自签证书创建新的secret
- 修改 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 模板, 定义容器属性
具体字段意义:
apiVersion | API版本 |
---|---|
kind | 资源类型 |
metadata | 资源元数据 |
spec | 资源规格 |
replicas | 副本数量 |
selector | 标签选择器 |
template | Pod模板 |
metadata | Pod元数据 |
spec | Pod规格 |
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
网友评论