原理介绍:
docker是完整的一套容器管理系统
容器是什么:
容器是用来装东西的,Linux里面的容器时用来装应用的
容器就是将软件打包成标准化单元,以用于开发,交付和部署
容器技术已经成为应用程序封装和交付核心技术
容器技术核心有内核几个技术组成:
Cgroups资源管理control groups
Selinux 安全
NameSpace 命名空间
linux的namespace命名空间:
unshare --help 查看主机名名命空间帮助
unshare -u /bin/bash //后面可用dacker管理
hostname 新主机名
bash
六大隔离
UTS主机名命名空间隔断:
NETWORK 通过网桥通信像虚拟的交换机
MOUNT 类似文件系统文件隔离
USER 用户隔离
PID 进程隔离只在区域隔离
IPC 跟进程绑在一起的给进程发信号隔离
docker优缺点:
优点相比于传统的·虚拟技术,容器更加简洁高效
传统虚拟机需要给每个vm安装操作系统
容器使用的共享公共库和程序
缺点:
容器的隔离性没有虚拟化强,共用linux内核,安全性有缺陷
docker的特点:与传统的虚拟化的对比
即是优势也是缺点没有操作系统只有一个docker进程共享宿主的操作系统只有应用,虚拟化主机有自己操作系统
安装部署:21主机(2cpu)需访问外网 22主机(2cpu)需访问外网 安装源服务器100主机
docker安装必须64位操作系统至少rhel6.5以上版本推荐rhel7,关闭防火墙
关闭防火墙firewalld和iptables 最终使用的是netfilter
100主机配置yum源:docker软件包位于光盘rhel7-extras.iso中
在物理机的httpd目录下创建文件交extras
mkdir /var/www/html/extras
把光盘挂载到创建的目录下
mount -t iso9660 -o ro,loop /iso/RHEL7-extras.iso /var/www/html/extras
vim /etc/fstab
/iso/Centos-7.5-1804.iso /var/www/html/centos-1804 iso9660 ro.loop 0 0
配置docker21主机22主机客户机的yum源 /etc/yum.repos.d/local.repo
[extras]
name=centos-$releaserver-extras
baseurl=http://192.168.1.100/extras
enabled=1
gpgcheck=0
yum repolist
yum -y install docker
开启路由转发 /etc/sysctl.conf //通过虚拟网桥通讯需要打开路由转发
net.ipv4.ip_forward=1
启动服务后会看到docker设备
systemctl enable docker
systemctl start docker
sysctl -p
解决软件bug版本大于1.12时会设置forward的默认规则被设置为drop
iptables -nL forward
修改vim /lib/systemd/system/docker.service 在EXecReload=/bin/kill行前添加
ExecStartPost=/sbin/iptables -P FORWARD ACCEPT
:wq
systemctl daemon-reload 重载配置
systemctl restart docker
systemctl status docker
ifconfig docker 0 //验证是否成功安装docker
yum remove firewalld-* //卸载防火墙
获取镜像镜像,容器,仓库 docker三大概念
镜像是启动容器的核心,封装容器的应用,在docker中容器时基于镜像启动的,类似模板,创建多个容器,有互不干扰文件层
镜像采用分层设计
使用cow技术 写时复制
官方镜像仓库:https://hub.docker.com
docker images 查看本机镜像:
docker search 镜像名关键字 //查找镜像
docker pull 镜像名称:标签 //下载镜像
docker pull docker.io/busybox
镜像的备份与恢复
备份镜像(导出镜像)
docker images 查看镜像名称和标签
docker save 镜像名称:标签 -o 备份文件名(tar格式)
docker save docker.io/busybox:latest -o busybox.tar
scp busybox.tar root@ip:/root/
恢复镜像(导出镜像)
docker load -i 备份文件名称
docker load -i busybox.tar
创建容器:
lftp http://ip/文件目录 //下载文件tar
mget 文件名 //下载到本机
下载导入本机centos.tar,nginx.tar,redis.tar,ubuntu.tar到docker,创建centos容器,busybox容器,nginx容器
docker load -i centos.tar|nginx.tar
运行容器
docker run -参数 镜像名称:镜像标签 启动命令
查看run的参数 run包括创建启动进入
docker help run
man docker-run
run 参数: -i 交互式, -t 终端, -d 后台运行容器的服务, --name 容器名字默认数字
docker run -it docker.io/centos:latest /bin/bash(容器内命令)
docker run -it docker.io/busybox.latest /bin/sh(容器内命令)
ps -ef 查看容器进程
ifconfig //需要装包先配置yum
yum -y install net-tools vim iproute psmisc bash-completion //容器内装
镜像管理删除镜像:
docker rmi 镜像名称:镜像标签 //必需先删除容器
上传下载镜像
docker pull 镜像名称:镜像标签
docker push 镜像名称:镜像标签
查看镜像制作历史
docker history 镜像名称:镜像标签
查看镜像的信息
docker inspect 镜像名称:镜像标签 //可以查看Cmd启动命令,环境变量PATH
cat /lib/systemd/system/httpd.service //查看服务的启动命令
镜像的新名称和标签
docker tag 镜像名称:镜像标签 新镜像名称:新的标签 //一个名称加标签等于镜像id
docker tag image的id(镜像id) 新镜像名称:新的标签
容器管理启动容器:
docker run -参数 镜像名称:镜像标签 启动命令
查看容器
docker ps [-a 所有容器id] [-q 只显示容器id]
docker ps -aq 仅仅显示所有的容器id
删除容器
docker rm 容器id //先停止容器,再删
前一个命令的结果作为后面命令的参数
docker rm $(docker ps -aq) //删全部容器
容器管理命令启动,停止,重启
docker start 容器id
docker stop 容器id
docker restart 容器id
查看容器进程
docker top 容器id //查看某个程序在某个容器运行
查看容器信息:
docker inspect 容器id //容器的详细信息ip地址,网关
连接容器启动进程
pstree -p
echo $$ //查看当前进程号
docker attach 容器id //连接的是上帝进程,exit退出就是,容器关闭;进入服务容器按ctrl p q保持服务容器退出终端,服务还在,查看报错信息attach连接上帝进程
连接容器,启动新进程,进入启动容器
docker exec -it 容器id 启动命令 //进入容器管理包括服务的容器
自定义镜像(含自做服务的应用包)使用镜像启动容器,在该容器基础上修改另存为一个新镜像
docker run -it docker.io/centos:latest /bin/bash
配置yum源,安装软件
yum install net-tools iproute psmisc vim bash-completion
yum clean all //清除缓存再打包更小
docker commit 容器id 新镜像名称:新镜像标签(myos:latest)
docker history myos:latest
使用docker run -it 验证新的镜像
Dockerfile语法注意大小写
FROM:基础镜像
RUN:制作镜像时执行的命令,可以有多个
ADD:复制文件到镜像,自动解压
COPY:复制文件到镜像,不解压
MAINTAINER:镜像创建者信息
EXPOSE:开发的端口
ENV:设置变量
WORKDIR:定义容器默认工作目录
CMD:容器启动时执行的命令,仅可以有一条cmd命令用中括号和双引号包含,命令参数用逗号隔开["ls","-l"]
创建文件编写Dockerfile 注意大小写
RROM docker.io/centos:latest
RUN rm -rf /etc/yum.repos.d/*.repo
COPY local.repo /etc/yum.repos.d/local.repo
RUN yum -y install net-tools iproute psmisc vim bash-completion tree && yum clean all
创建与Dockerfile同级目录的local.repo
[loacl_repo]
name=centos-$releasever-base
baserurl="http://192.168.1.100/centos-1804"
enabled=1
gpgcheck=0
:wq
docker build -t newos:latest(新名) . (点表示当前路径下Dockerfile)
docker images
docker run -it newos:latest
Dockerfile入门创建服务镜像
Dockerfile创建apache服务案例
FROM myos:latest
MAINTAINER Jacob redhat@163.com
RUN yum -y install httpd
ENV LANG=C
WORKDIR /var/www/html/
ADD index.html /var/www/html/
EXPOSE 80 443
CMD ["/usr/sbin/httpd","-DFOREGROUND"] //命令用中括号和双引号包含,命令参数用逗号隔开["ls","-l"]
:wq
pstree -p //查看进程
cat /lib/systemd/system/httpd.service //可以查看apache启动命令,对CMD编写,命令
创建服务镜像
docker build -t myos:httpd .
运行容器验证服务
docker run -itd myos:httpd
docker inspect 容器id //查看ip
curl http://ip验证结果
docker 进阶制作一个nginx+php的服务镜像
依赖包多,配置复杂,需要编译,多服务怎么启动等问题怎么解决
制作思路:
在虚拟机中手工安装所有服务yum+编译
解决方案:记录所有程序运行的依赖包
验证配置,打包安装路径
解决方案:把编译好的软件包直接放入容器内
多服务
解决方案:启动脚本
开始制作:
history -c
history -w //清楚历史命令
yum install -y pcre-devel openssl-devel gcc make php php-fpm pcre openssl
tar zxf nginx-1.12.2.tar.gz
cd nginx-1.12.2/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
make && make install
修改配置conf/nginx.conf //开启php
cat /lib/systemd/system/php-fpm.service //查看启动命令默认前台运行/usr/sbin/php-fpm --help --daemonize //后台运行or 加 &
--------------------
yum -y install bzip2
tar -cjf nginx.tar.bz2 /usr/local/nginx
scp nginx.tar.bz2 root@ip./
创建Dockerfileroot@ip
FROM myos:latest
RUN yum install -y pcre openssl php php-fpm && useradd nginx
ADD nginx.tar.bz2 /usr/local/
ADD run.sh /etc/init.d/run.sh
EXPOSE 80
CMD ["/etc/init.d/run.sh"]
:wq
vim run.sh
#!/bin/bash
/usr/sbin/php-fpm --nodaemonize &
/usr/local/nginx/sbin/nginx -g "daemon off;"
:wq
docker build -t myos:nginx .(点)
chmod 755 run.sh
docker run -itd myos:nginx
docker exec -it elosid
ss -ntlp
ifconfig //查看ip
curl http://ip/xx.php
私有仓库(镜像)搭建私有仓库在192.168.1.100上搭建私有仓库
安装私有仓库服务端先配置yum
yum -y install docker-distribution
启动私有仓库,并设置开机启动
systemctl start docker-distribution
systemctl enable docker-distribution
仓库配置文件计及数据存储路径
/etc/docker-distribution/registry/config.yml
/var/lib/registry
默认端口5000
curl http://仓库ip:5000/v2 // 访问仓库返回大括号
使用私有仓库在安装docker主机操作
docker[12]主机修改配置文件/etc/sysconfig/docker
允许非加密方式访问仓库 vim /etc/sysconfig/docker
INSECURE_REGISTRY='--insecure-registry 仓库ip:5000'
docker仓库地址
ADD_REGISTRY="--add-registry 仓库ip:5000'
重启docker服务
systemctl restart docker
上传镜像
为镜像创建标签:
docker tag 镜像:标签 私有仓库ip:5000/镜像:标签
docker tag busybox:latest 仓库ip:5000/busybox:latest
上传镜像
docker push 私有镜像ip:5000/镜像:标签
docker push 192.168.1.100/busybox:latest
使用使用仓库
docker run -it 192.168.1.100/busybox:latest
查看仓库中的镜像名称标签
curl http://仓库ip:5000/v2/_catalog
查看某一仓库的标签个数
curl http://仓库ip:5000/v2/镜像名称/tags/list
私有仓库数据存储目录:
/var/lib/registry //查找镜像删除
外部存储卷卷的用途:docker容器不保持任何数据是一个进程容器丢失数据
重要数据请使用外部卷存储数据持久化
容器可以挂载真实机目录或共享存储为卷
主机卷的映射
将真实机的目录挂载到容器中提供持久化存储
目录不存在就自动创建
目录存在就直接覆盖掉
多个容器可以映射通一个目录来达到数据共享的目的
启动容器时,使用-v参数映射卷
docker run -it -v 真实目录:容器内目录 docker.io/centos:lates
多主机共享目录
在多台docker主机的情况下我们也可以使用共享存储作为docker
的卷服务,可以实现多主机之间多容器的共享卷服务
例如:
使用nfs共享卷
客户端挂载nfs共享,并最终映射到容器中
共享存储卷服务 192.168.1.100
安装nfs
yum -y install nfs-utils //都需要安装nfs-utils
mkdir /var/webroot //共享文件夹
chmod 777 /var/webroot //修改权限
vim /etc/exports
/var/webroot *(rw)
:wq
systemctl start nfs
挂载共享把卷映射到容器中
showmount -e 192.168.1.100 //查看共享
mount 挂载共享
mount -t nfs -o rw 192.168.1.100:/var/webroot /mnt
运行容器时,使用-v选项映射到容器
服务器创建nfs共享目录,权限为rw
客户端挂载共享,并将共享映射到容器中
kube-node1 启动nginx
docker run -itd -v /mnt:/usr/local/nginx/html myos:nginx
kube-node2 启动apache
docker run -itd -v /mnt:/var/www/html myos:httpd
nginx和apache同一目录
再/mnt创建文件会映射到容器中和nfs共享到远程容器中
发布docker服务默认容器可以访问外网
但外部网络的主机不可以访问容器内的资源
解决这个问题的最佳方式是端口绑定
容器可以与宿主机的端口进行绑定
从而把宿主机变成对应的服务
使用-p参数把容器端口和宿主机端口绑定
-p 宿主机端口:容器端口
例如把宿主机变程httpd
docker run -itd -p 80:80 docker.io/myos:httpd
例如把宿主机变成nginx
docker run -itd -p 80:80 -v /mnt:/var/www/html docker.io/nginx:latest
docker run -itd -p 80:80 docker.io/nginx:latest
云平台部署与管理kubernetes集群管理工具
kubernetes的名字来自希腊语,意思是领航员,创造者谷歌,并不是一件全新的发明,他是谷歌10多年大规模容器管理技术borg的开源版本2014年宣布开源.
k8s是容器集群管理系统,是一个开源平台,可以实现容器集群的自动化部署,自动扩缩容,维护等功能
有大量跨主机的容器需要管理
快速部署应用
快速扩展应用
无缝对接新的应用功能
节省资源,优化硬件资源的使用
k8s核心角色
master管理者
APIserver:整个系统对外接口,供客户端和其他组件调用,相当于营业厅
scheduler 负责对集群内部的资源进行调度,相当于调度室
controller manager 负责管理控制器,相当于大总管
etcd 是一个键值存储仓库,存储集群的状态
node计算节点
docker容器管理
kubelet 主要负责监视指派到它所在的pod最小单元,包括创建,修改,监控,删除等
kube-proxy 主要负责为pod对象提供代理
其他pod服务
image镜像仓库
部署配置
kube-master 20 管理节点
kube-node1 21 计算节点
kube-node2 22 计算节点
kube-node3 23 计算节点
repo 100 yum安装源,私有仓库
分布式键值存储服务etcd的定义
etcd开源项目,他的目标是构建一个高可用的分布式键值数据库
基于go语言实现,在分布式系统中各种服务配置信息的管理分享,
服务的发现式一个很基本同时也是很重要的问题。
100主机部署远程yum仓库
mkdir -p /var/www/html/localrepo
cp -a k8s /var/www/html/localrepo/ //拷贝软件包k8s很多的安装包在里面
createrepo .(点) //在k8s同级目录下创建索引文件
客户端yum配置k8s
管理节点20:
vim /etc/repos.d/local.repo
[k8s]
name=k8s
baseurl=http://192.168.1.100/localrepo
enabled=1
gpgcheck=0
:wq
拷贝给计算节点全部都要
rsync -av local.repo 21ip:/etc/yum.repos.d/local.repo
在管理主机20上安装etcd kube-master上不需要装docker
yum install -y etcd
etcd的配置文件位于/etc/etcd/etcd.conf
修改6:ETCD_LINENT_URLS="http://0.0.0.0:2379"
启动服务
systemctl enable etcd
systemctl start etcd
etcdctl 是etcd命令行客户端
set设置键值对
get读取键值对
update更改键值对
mk创建新的键值对,rm删除键值对
mkdir 创建目录,rmdir 删除目录
ls 显示目录和键值对
etcdctl ls / //查看
etcdctl mkdir /abc
etcdctl ls /
etcdctl rmdir /abc
etcdctl ls /
创建配置
etcdctl mk /atomic.io/network/config '{"NETWORK":"10.254.0.0/16","Backend":{"TYPE":"vxlan"}}'
etcdctl get /atomic.io/network/config
网络配置flannelflannel实质上是一种覆盖网络也就是将tcp数据包装在另外一种网络里进行
路由转发和通信,目前已经支持udp,vxlan,aws vpc gce
使用flannel目标
不同主机内的容器实现互联互通
flannel 安装配置
使用rpm方式安装(所有机器都需安装)
yum install flannel
修改配置文件/etc/sysconfig/flannel 在4行
FLANNEL_ETCP_ENDPOINTS="http://etcd服务器的地址:2370"
FLANNEL_ETCP_PREFIX="/atomic.io/network"
启动服务flannel服务必须在docker服务之前启动
systemctl enable flannel
systemctl stop docker //先停止docker,要先启动flannel
systemctl start flanner docker
node计算节点启用容器:ping ip //查看容器间是否通信
安装部署kube-master 20主机master组件提供集群的控制对集群进行全局决策
检测和相应集群事件
master主要由api-server ,kube-scheduler,kube-controller-manager和etcd等服务组成
kube-master采用yum方式安装
yum install kubernetes-master kubernetes-client
yum list kubernetes-* //是1.10版本,不是1.5版本
全局配置文件/etc/kubernetes/config
KUBE_MASTER="--master=http://192.168.1.20:8080"
:wq
vim /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
KUBE_ETCD_SERVERS="--etcd-server=http://192.168.1.20:2379"
找到ServiceAccount,删掉
systemctl enable kube-apiserver kube-controller-manager kube-scheduler
systemctl start kube-apiserver kube-controller-manager kube-scheduler
kubectl get cs //检查是否正常
kubectl get node
安装部署kube-node,21,22,23一样配置kube-node计算节点
真是运行容器节点
计算节点,该组件在水平扩展在多个节点上运行
维护运行的pod并提供kubernets运行环境
kube-node由kubelet,kube-proxy和docker组成
kube-node采用yum方式安装
yum install kubernetes-node
kube-node全局配置文件/etc/kubernetes/config
KUBE_MASTER="--master=http://192.168.1.20:8080"
:wq
vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_HOSTNAME="--hostname-override=本机名称"
KUBELET_ARGS="--cgroup-driver=systemd --fail-swap-on=false
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig
--pod-infra-container-image=192.168.1.100:5000/pod-infrastructure:latest"
:wq
kubelet.kubeconfig文件kubelet.kubeconfig是kubelet的配置文件的一部分
它是通过命令生成的
kubectl config set-cluster local --server="http://192.168.1.20:8080"
kubectl config set-context --cluster="local" local
kubectl config set current-context local
kubectl config view
vim /etc/kubernetes/kubelet.kubeconfig 默认没有
apiVersion: v1
clusters:
- cluster:
server: http://192.168.1.20:8080
name: local
contexts:
- context:
cluster: local
user: ""
name: local
current-context: local
kind: Config
preferences: {}
users: []
更新pod镜像,并上传到私有仓库
下载pod-infrastructure.tar 导入镜像
docker load -i pod-infrastructure.tar
docker tag pod-infrastructure:latest 192.168.1.100:5000/pod-infrastructure:latest //上传到仓库
docker push 192.168.1.100:5000/pod-infrastructure:latest
注意保证kubelet的配置文件中的pod地址和我们私有仓库中的地址完全一致
systemctl enable kubelet kube-proxy
systemctl start kubelet kube-proxy
vim /etc/hosts //配置主机名ip
安装部署kube-dashboardpod是kubernetes调度的基本单元
一个pod包含1个或多个容器
这些容器使用相同的网络命名空间和端口号
pod是一个服务的多个进程的聚合单位
pod作为一个独立的部署单位,支持横向扩展和复制
pod镜像是官方制作的pod-infrastructure.tar
在docker中导入镜像,并上传到私有仓库
docker load -i pod-infrastructure.tar
docker images
docker tag pod-infrastructure:latest 192.168.1.100:5000/pod-infrastructure:latest
docker push 192.168.1.100:5000/pod-infrastructure:latest
管理页面
kubernetes-dashboard.tar 是kubernetes的web管理面板
kubernetes-dashboard 镜像导入到docker并上传到私有仓库
vim kube-dashboard.yaml
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: 192.168.1.100:5000/kubernetes-dashboard-amd64:v1.8.3 #私有仓库镜像地址
ports:
- containerPort: 9090
protocol: TCP
args:
- --apiserver-host=http://192.168.1.20:8080 #修改为Master的IP
volumeMounts:
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- 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
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort
ports:
- port: 80
targetPort: 9090
nodePort: 30090
selector:
k8s-app: kubernetes-dashboard
--------------------------------------------------------------------------------------------------------------------------------
kubectl apply -f kube-dashboard.yaml
http://任意节点:30090端口
kubectl命令kubectl 是用于控制kubernetes集群的命令行工具
kubectl [command][TYPE][NAME][flags]语法格式
command:子命令,如create get describe delete
type 资源类型,可以表示为单数,复数或缩写形式
name:资源的名称,如果省略,则显示所有资源的详细信息
flags:指定可选标志,或附近的参数
例子
kubectl get //查询资源
kubectl get node 查询节点状态
kubectl get pod 查询pod容器资源
kubectl get deployment 查看资源名称
kubectl get replicaset 查看资源仅次deploment下
kubectl run 创建容器
在前台创建容器
kubectl run 资源(deploy)名称 -i -t --image=镜像名称:标签
kubectl run xx -i -t --image=192.168.1.20:5000/myos:latest //创建容器
ctrl+p+q 键 退出,服务还在运行
exit //关闭容器,但是kubernetes集群会自动开启容器
kubectl get deployment
kubectl get pod
kubectl get pod -o wide //查看在那个节点创建
进入容器使用exec
kubectl exec -it 容器id 执行的命令
查看资源详细信息排错
kubectl describe 资源类型 资源名称
kubectl describe deployment //查看namexx
kubectl describe deployment xx //查看资源详细信息
kubectl describe pod //查看namexx
kubectl describe pod xx //查看容器详细信息
查看终端输出console的输出信息attach logs等效
kubectl attach podnamexx -c deploment资源名 -i -t
kubectl logs podnamexx //没有进入终端,输出信息
删除资源
kubectl get pod -o wide
kubeclt delete pod podnamexx //删除pod
kubectl get pod -o wide //删除后会自动重建
kubectl delete deployment xx //删除资源,容器自动消失
kubectl 服务管理使用run命令启动服务
kubectl run 资源名称 -r 副本数量 --image=镜像名称:标签
kubectl run web -r 2 --image=192.168.1.100/myos:httpd
kubectl get deployment
kubectl get pod -o wide
会变化的pod资源
当发现某个pod不能使用的时候rs会在其他机器上在创建一个相同的pod,及其对应的容器
service服务
会变化的pod给我们访问带来了非常多的不便
service 就是解决这一个问题方法
service 会创建一个cluster ip ,这个地址对应的资源地址,且不会改变
service 会在多个服务上实现负载均衡的访问效果
service 通过port nodePort targetPort 将访问的请求最终映射到
pod的容器内部服务上
service的三种端口
port:service 暴露在cluster ip 上的端口,是提供给集群内部客户访问service的入口,提供集群内部服务访问使用
nodePort:是提供给集群外部客户访问service入口的一种方式了,
是提供给集群外部客户访问service的入口
targetPort 是pod上容器服务器监听的端口,从port或nodePort
上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器,从而达到访问pod容器内服务的目的。
使用service访问web资源
kubectl expose 资源类型 资源名称 --port=服务端口 --target-port=容器端口 --name=service的名字
kubectl expose deployment web --port=80 --target-port=80 --name=
http-service
kubectl get service
kubectl get service http-service -o wide //查看服务cluster-ip
yaml资源文件资源对象文件一般由用户根据需求编写
我们也可以查询一个资源对象文件
kubectl get 资源对象 资源名称 -o 格式
格式包含json yaml wide(格式)
kubectl get deployment web -o yaml
如何使用资源对象文件创建容器,能定义
kubectl (apply|create|delete) -f 资源文件
apply升级更新资源对象
create创建资源对象
delete删除资源对象
例子:创建myos的对象文件
---
apiVersion: extensions/v1beta1 #当前格式的版本
kind: Deployment #当前创建资源的类型,当前是Deployment
metedata: #当前资源的元数据
name: web #当前资源的名字是元数据必须的项
spec: #是当前Deployment的规格说明
replicas: 3 #指当前创建的副本数量默认不填值为1
template: #定义pod的模板
metadata: #当前pod的元数据
labels: #至少一个labels标签,可以任意创建一个key:value
app: web
spec: #当前pod的规格说明
containers: #容器
- name: web #是容器的名字容器名字是必须填写的
image: 192.168.1.100:5000/myos:httpd #镜像地址
stdin: true #交互式输入相当于-i参数
tty: true #打开终端相当与-t 参数
--- #服务资源
apiVersion: v1 #当前格式的版本
kind: Service #创建资源类型
metadata: #当前资源的元数据
name: web-service #资源名称
namespace: default #资源的区域
spec: #规格说明
clusterIP: 10.264.254.110 #资源ip 可以留空使用dns
ports: #端口
- port: 80 #服务端口
targetPort: 80 #容器端口
nodePort: #发布的节点端口
protocol: TCP #协议
selector: #标签选择器
add: web #后端服务资源
type: ClusterIP #资源类型
---------------------------------------------------
diff http.yaml web-service.yaml //比较文件
configmap是在pod中映射文件的一种方式在日常工作中经常要修改各种配置文件的参数,数据库的地址,
用户名,密码等,这些操作在容器内非常麻烦,pod在重启或者迁徙的时候
到初始的状态,使用configmap就可以解决这样的问题
定义configmap
获取httpd.conf 并做出相应的修改
创建configmap
kubectl create configmap 名称 from-file=文件路径
kubectl exec -it 容器id /bin/bash
scp /etc/htttpd/conf/http.conf root@ip:/root/
vim /root/httpd.conf //修改端口80为8080
kubectl create configmap my-httpd --from-file=/root/httpd.conf
kubectl get configmap //查看映射my-httpd
kubectl describe configmap my-httpd -o wide //查看详细信息
kubectl get configmap my-httpd -o yaml //yaml格式
创建web容器,使用configmap
configmap默认映射的是目录
如果目标目录存在就覆盖
如果目标目录不存在就创建出来
...
volumeMounts:
- mountPath:/var/webroot #目标路径定义映射文件夹目录
name: site-data #引用configmap定义名字
volumes:
- name: site-data
emptyDir: {} #文件名
如何映射一个文件
....
volumeMounts:
- mountPath: /etc/httpd/conf/httpd.conf #映射完全路径单文件路径
name: my-httpd #引用的configmap定义的名字
subPath: httpd.conf #目标文件名定义单文件
volumes:
- name: my-httpd
configMap:
name:my-httpd #这个是kubectl create configmap my-httpd
items:
- key: httpd.conf
path: httpd.conf
定义两个案例映射目录和文件
---
apiVersion: extensions/v1beta1 #当前格式的版本
kind: Deployment #当前创建资源的类型, 当前类型是Deployment
metadata: #当前资源的元数据
name: web-test #当前资源的名字 是元数据必须的项
spec: #是当前Deployment的规格说明
replicas: 1 #指当前创建的副本数量 默认不填 默认值就为‘1’
template: #定义pod的模板
metadata: #当前pod的元数据
labels: #至少顶一个labels标签,可任意创建一个 key:value
app: web-test
spec: #当前pod的规格说明
containers: #容器
- name: web-test #是容器的名字容器名字是必须填写的
image: 192.168.1.100:5000/myos:httpd #镜像 镜像的名字和版本
stdin: ture #ports:
tty: true #- containerPort: 8080 #声明容器端口号
volumeMounts:
- mountPath: /var/webroot #目标路径
name: site-data #引用卷映射定义
- mountPath: /etc/httpd/conf/httpd.conf #映射完全路径
name: my-configmap #引用卷映射定义
subPath: httpd.conf #目标文件名
volumes:
- name: site-data
emptyDir: {}
- name: my-configmap #定义卷资源名称跟上面的mouthpath下的name同
configMap:
name: my-httpd #引用的 configmap 配置名定义的名称
items:
- key: httpd.conf
path: httpd.conf
kubectl create -f web.yaml
curl -m 2 https://clusterip:8080
kube-dns服务发现kube-dns插件提供了service的概念可以通过vip访问pod提供服务,但是在使用的时候还有一个问题怎么知道某个应用的vip ? 比如我们有两个应用,一个web,一个db,每个应用使用rc进行管理,并通过service暴露出端口提供服务,web需要连接到db应用,我们只知道db应用的名称,但是并不知道它的vip地址,这时候最好的方式通过dns来查询了,kube-dns就是为了解决这一问题而出现的,在k8s中dns不是一个独立的系统服务而是作为插件来安装的
镜像导入私有仓库
kube-dns需要使用3个镜像,分别是kube-dns-amd64,kube-dnsmasq,kube-sidecar-amd64
docker load -i *.tar //简写
dokcer tag kube-*:1.14.10 192.168.1.100:5000/kube-*:1.14.10
docker push 192.168.1.100:5000/kube-*:1.14.10
curl http://192.168.1.100:5000/v2/_catalog
修改配置文件
kube-dns.yaml配置文件
clusterIP:集群服务的ip地址,必须与kubelet配置相同
domain:为解析的父域名
vim kube-dns.yaml
33 clusterIP:10.254.254.253
98 image:192.168.1.100:5000/k8s-dns-kube-dns-amd64:1.14.10
128 - --domain=tedu.local.
131 - --kube-master-url=http://192.168.1.20:8080 #api-server地址
150 image:192.168.1.100:5000/k8s-dns-dnsmasq-nanny-amd64:1.14.10
170 - --server=/tedu.local./127.0.0.1#10053
189 image:192.168.1.100:5000/k8s-dns-sidecar-amd64:1.14.10
202 - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.tedu.local.,5,SRV
202 - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.tedu.local.,5,SRV
# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR ConDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Should keep target in cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml
# in sync with this file.
# __MACHINE_GENERATED_WARNING__
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.254.254.253
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-dns
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
spec:
# replicas: not specified here:
# 1. In order to make Addon Manager do not reconcile this replicas parameter.
# 2. Default is 1.
# 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
strategy:
rollingUpdate:
maxSurge: 10%
maxUnavailable: 0
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
spec:
priorityClassName: system-cluster-critical
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
volumes:
- name: kube-dns-config
configMap:
name: kube-dns
optional: true
containers:
- name: kubedns
image: k8s-dns-kube-dns-amd64:1.14.10
resources:
# TODO: Set memory limits when we've profiled the container for large
# clusters, then set request = limit to keep this container in
# guaranteed class. Currently, this container falls into the
# "burstable" category so the kubelet doesn't backoff from restarting it.
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
livenessProbe:
httpGet:
path: /healthcheck/kubedns
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /readiness
port: 8081
scheme: HTTP
# we poll on pod startup for the Kubernetes master service and
# only setup the /readiness HTTP server once that's available.
initialDelaySeconds: 3
timeoutSeconds: 5
args:
- --domain=tedu.local.
- --dns-port=10053
- --config-dir=/kube-dns-config
- --kube-master-url=http://192.168.1.20:8080
- --v=2
env:
- name: PROMETHEUS_PORT
value: "10055"
ports:
- containerPort: 10053
name: dns-local
protocol: UDP
- containerPort: 10053
name: dns-tcp-local
protocol: TCP
- containerPort: 10055
name: metrics
protocol: TCP
volumeMounts:
- name: kube-dns-config
mountPath: /kube-dns-config
- name: dnsmasq
image: k8s-dns-dnsmasq-nanny-amd64:1.14.10
livenessProbe:
httpGet:
path: /healthcheck/dnsmasq
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- -v=2
- -logtostderr
- -configDir=/etc/k8s/dns/dnsmasq-nanny
- -restartDnsmasq=true
- --
- -k
- --cache-size=1000
- --no-negcache
- --log-facility=-
- --server=/tedu.local./127.0.0.1#10053
- --server=/in-addr.arpa/127.0.0.1#10053
- --server=/ip6.arpa/127.0.0.1#10053
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
# see: https://github.com/kubernetes/kubernetes/issues/29055 for details
resources:
requests:
cpu: 150m
memory: 20Mi
volumeMounts:
- name: kube-dns-config
mountPath: /etc/k8s/dns/dnsmasq-nanny
- name: sidecar
image: k8s-dns-sidecar-amd64:1.14.10
livenessProbe:
httpGet:
path: /metrics
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- --v=2
- --logtostderr
- --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.tedu.local.,5,SRV
- --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.tedu.local.,5,SRV
ports:
- containerPort: 10054
name: metrics
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
dnsPolicy: Default # Don't use cluster DNS.
serviceAccountName: kube-dns
curl http://192.168.1.100:5000/v2/k8s-dns-dnsmasq-nanny-amd64/tags/list //查看标签
kubectl create -f kube-dns.yaml
node节点 kublet需要指定dns的ip
修改所有node节点/etc/kubernetes/kubelet 在kubeconfig=/etc/kube...行未加
--cluster-dns=10.254.254.253 --cluster-domain=tedu.local." 注意点表示根域例baidu.com.
重启kubelet服务
systemctl restart kubelet
主机master:
kubectl delete -f web-service.yaml
kubectl delete -f web.yaml
kubectl create -f kube-dns.yaml //域名
kubectl get deployment //找不到web-dns,在不同区域3个区域default,kube-public,kube-system
kubectl -n kube-system get deployment|pod
kube-dns在集群中非常重要,它提供了域名解析和服务发现的重要功能,
一般在配置k8s集群中都会配置,镜像导入,配置文件修改,kebulet配置文件
创建容器进入:ping web-service(创建服务的域名)
kubectl get service -o wide //查看服务名称
ingress发布服务集群外服务管理通过kubectl构建的服务已经可以在集群内部运转起来了
但集群外还无法访问集群内部的服务
有些时候,有些服务我们无法放入集群内部,这时候我们就需要集群内部和集群外部服务能够实现互访
对外提供服务:nodePort //产生端口供外部访问
对外提供服务:Ingress
nodePort发布服务
kubectl expose 资源类型 资源名称 --type=NodePort --port=80 --target-port=80 --name=服务名称
kubectl expose deployment web --type=NodePort --port=80 --target-port=80 --target-port=80 --name=web-service
kubectl get service web-service -o wide //查看端口,随机的端口,供外部访问
Ingress介绍
lngress公开了从集群外部到集群内services路由
可以将ingress配置为提供服务外部可访问url,负载均衡流量
ingress控制器通常由负载均衡器实现
必须具有ingress控制器才能满足ingress的要求,仅创建资源无效
ingress安装配置
ingress导入镜像槽私有仓库
控制器:nginx-ingress-controller.tar
默认后端服务:backend.tar
curl http://192.168.1.100:5000/v2/_catalog //查看镜像仓库
docker load -i nginx-ingress-controller.tar
docker load -i backend.tar
docker push nginx-ingress-controller:0.19.0 192.168.1.100:5000/nginx-ingress-controller:0.19.0
docker push defaultbackend;1.4 192.168.1.100:5000/defaultbackend;1.4
vim mandatory.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: default-http-backend
template:
metadata:
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissible as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: defaultbackend:1.4
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: ingress-nginx
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
ports:
- port: 80
targetPort: 8080
selector:
app.kubernetes.io/name: default-http-backend
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "-"
# Here: "-"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
serviceAccountName: nginx-ingress-serviceaccount
hostNetwork: true
dnsPolicy: "ClusterFirstWithHostNet"
containers:
- name: nginx-ingress-controller
image: nginx-ingress-controller:0.19.0
args:
- /nginx-ingress-controller
- --apiserver-host=http://192.168.1.20:8080
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --annotations-prefix=nginx.ingress.kubernetes.io
- --report-node-internal-ip-address
#- --publish-service=$(POD_NAMESPACE)/ingress-nginx
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
34行 image:192.168.1.100:5000/defaultbackend:1.4
295行 image:192.168.1.100:500/nginx-ingress-controller:0.19.0
298:- --apiserver-host=http://192.168.1.20:8080
kubectl create -f mandatory.yaml
kubectl -n ingress-nginx get service //查看service, ingress-nginx
kubectl -n ingress-nginx pod -o wide //需要时间启动,输出显示ip是多少
需要指定发布服务:
调用ingress映射集群内web-service服务基于端口服务
kubectl create -f ingress-test.yam
kubectl get ingress //查看发布服务
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: web-service #后端服务定义可以定义web-nginx服务
servicePort: 80
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-app
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: apache.tedu.local
http:
paths:
- path: /
backend:
serviceName: web-apache
servicePort: 80
- host: nginx.tedu.local
http:
paths:
- path: /
backend:
serviceName: web-nginx
servicePort: 80
ingress基于域名发布服务例子如上。



