基于很久没有开灶写博客了,决定周末整理一下之前入手的 k8s,毕竟再不整理就又要忘了。
从 Docker 开始
缘何而来
Paas 由来久远,但还是免不了巨大的搭建开销。同样在软件项目中,(搭建技术栈->构建基础技术->模拟测试)整个过程的耗费时间长,资源隔离不彻底,部署代价巨大,Docker 在这些方面恰好有很大的优势。
Docker 的几个重要概念
namespace
cgroup
子系统(资源控制器),管理 cpu, iops, network, memory, device access
LXC
比较方向 | 结果 |
---|---|
性能 | LXC >> KVM >> XEN |
内存利用率 | LXC >> KVM >> XEN |
隔离程度 | XEN >> KVM >> LXC |
AUFS
共享文件系统
全生命周期开发模式
Build + Ship + Run
App 打包
Kernel + BaseImage + Self Images + Container
Daemon
用于绑定本地端口,提供 RESTful API(k8s 的基础)
Docker 基本命令
docker version
- /etc/sysconfig/docker
- /usr/lib/systemd/system/docker.service
OPTIONS=
- -H
-H=unix:///var/run/docker.sock
-H=tcp://0.0.0.0:2375
- –registry-mirror 镜像地址
- –insecure-registry 本地私有 Docker Registry 地址 (:5000)
- –selinux-enabled 是否开启 SELinux,默认开启 (=true)
- –bip 网桥 docker0 使用指定 CIDR 网络地址
- -b 已创建好的网桥
http_proxy = xx.xx.xx.xx:8080
https_proxy = xx.xx.xx.xx:8080
docker search xxx
docker pull xxx [repo:tag]
docker images
docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG]
- -d 后台执行
- -it 数据交互
- –name
- –cidfile=”” container-id输出到指定文件
- –privileged 特权模式(删除容器后目录仍然存在)
-v [本地容器] 容器目录
docker inspect [containerId] // 可以看到 Volume 信息
docker create/start/stop/pause/unpause
docker ps // 所有运行过的容器都会出现在输出中
docker run -rm // 临时性,用完后就会被 remove 掉
docker commit <container> [repo:tag] // 快速方便,但不规范,且无法自动化,因而需要使用 buildfile 语法(supervisor)
docker build -t xx/xx .
Docker 友好程序架构
利用 etcd/zookeeper 将配置从 Docker Image 中剥离
容器互联
基于 Volume 互联
- /var/lib/docker/graph 本地 image 的分层信息
- /var/lib/devicemapper/devicemapper/data Image 和 Container 的二进制数据文件
- /var/lib/devicemapper/devicemapper/metadata 相关元数据
- 单主机容器间互联 –volumes-from=[containerId]
- 跨主机共享互联
- iscsi
- nfs
- ceph
- 分布式文件系统
基于 link 的互联
- –icc=true 关闭互通
- –link=name:alias 连接指定 container(会在 /etc/hosts 中生成对应的 ip 映射)
- – iptables=true 开启防火墙(iptables-save)
基于网络的互联
docker-proxy
- 端口映射 NAT : docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8066 -container-ip 172.17.0.15 -container-port 3306
- 直接使用宿主机网络 host-only (不能启动两个同端口启动的进程)[无法负载均衡] 有限且无法重复占用 : –net=host
- 容器共用一个 ip 网络 : –net=container:mysqlserver(同 ip 使用 localhost 互访)此概念在 k8s 中有重要意义 跨主机可访问任意进程
容器网络机制
Linux 路由机制打通网络
systemctl daemon-reload # 重载所有修改过的配置文件
iptables -F; iptables -t nat -F
tshark -f icmp; tshark -i docker0 -f icmp
- 传统网络
- 双网卡独立/大二层交换 Linux Bridge
- Overlay 网络:GRE(tcp)/VXLAN(udp)
- 基于 OVS 的 Overlay 网络:GRE Tunnel
- Neutron 网络
- Libnetwork (New -> In k8s Used)方便不同 Container 之间共用网段
Linux Namespace
Namespace 间通信使用 veth pair / Linux Bridge
brctl show
docker inspect -f '{{state.pid}}' containerId
mkdir -p /var/run/netns; ln -s /proc/xx/ns/net /var/run/netns/xx
ip netns exec xxx ethtool -S eth0
OVS + Docker
Open vSwitch (Security / Monitoring / QoS / Automated Control)
ovs-vsctl add-br br0
ovs-vsctl add-port br0 gre1 --set-interface gre1 type=gre option:remote_ip=192.168.18.128
brctl addif br0 docker0
ip link set dev br0 docker0
ip link set dev br0 up
ip link set dev docker0 up
iptables -t nat -F; iptables -F
ip route add 172.17.0.0/16 dev docker0
Docker 管理工具
- Docker Machine
- Swarm
- Docker Compose
- Tutum
- Shipyard -> 基于 web
- cAdvisor -> 实时监控
Kubernetes
重要概念
Namespace
多租户资源隔离
Resource
某个 NS 下有状态可关联/可限定配额/可持久化到 etcd 的资源对象
Label
任意定义的 K-V 对,用于过滤和选择资源,与资源相关
Volumes
Pod 存储卷,可被多个容器使用
Master 节点
提供资源访问入口的管理节点
Node
Linux 工作节点(负载节点)自修复,接受 Master 管理,并启动和管理 Pod 实例
Pod
k8s 中最小任务调度单元,可在任意 Node 上修复 Pod 内共享资源(网络/Volumes)
Service
微服务容器/容器隔离/TCP/无状态/多实例/默认外部不能访问/滚动升级
Replication Controller
Pod 副本控制器,限定当前实例个数,滚动升级提供方,属于 Service 集群控制范畴
集群部署
kubectl get pods/namespace/...
kubectl cluster-info
kubectl describe pods/...
--rollback
kubectl scale # 扩容
kubectl rolling-update # 滚动升级
- 服务注册与发现 -> 不变的虚拟 ip + 端口
- 负载均衡 -> kube-proxy
- 规模部署 -> 确定实例数,系统自动调度
- 自监控,自修复
分布式网络方案
- openvswitch 灵活/对现有物理网络无要求/业界主流/性能低/复杂度高/Troubleshooting 难
- 路由技术 常规路由技术/使用传统网络技术/简单/高性能/灵活性低/与现有网络融为一体
- Flannel 结合路由机制与隧道技术(UDP 封装 -> etcd 存储子网拓扑与路由表) FLANNEL_ETCD=”http://xx.xx.xx.xx:4001”
负载均衡与网络拓扑
Service
- 单体程序:
- 先天性,难以分布式部署和扩容
- 系统性,组建缺陷导致进程崩溃
- 运维风险,系统升级/bug 修复/故障排查都存在风险
- 难以可持续发展,难以复用原有服务
- 微服务架构
- 先天分布式
- 无状态 -> 平滑扩容
- 积木式发展
Proxy 网络代理 & 负载均衡器
- 运行在每个 Node 上
- 代理每个服务的请求
- 保持会话/自动排查故障点
API
swagger-ui
ku8-eye (ku8 eye-web / ku8 eye-ansible)
现有 docker + k8s 如何自改并提交
docker ps | grep xxx
docker commit {docker id}
kubectl exec -it xxx /bin/bash
Mark
将 filename 所有文本中的 previous 替换为 new
sed -i 's/previous/new/g' filename