赞
踩
Docker 是一个开源项目, 诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0协议, 项目代码在 GitHub 上进行维护。Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容( LXC)等技术。在 LXC 的基础上 Docker 进行了进一步的封装, 让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。
1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。
2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。
3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。
作为一种新兴的虚拟化方式, Docker 跟传统的虚拟化方式相比具有众多的优势。首先, Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而 Docker 只需要启动 10 个隔离的应用即可。具体说来, Docker 在如下几个方面具有较大的优势:
对开发和运维( devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后, 运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、 测试、部署的时间。
Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
镜像,从认识上简单的来说,就是面向对象中的类,相当于一个模板。从本质上来说,镜像相当于一个文件系统。Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器,从认识上来说,就是类创建的实例,就是依据镜像这个模板创建出来的实体。容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器( Registry)混为一谈,并不严格区分。 实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签( tag)。仓库分为公开仓库( Public)和私有仓库( Private) 两种形式。
最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool 等,可以提供大陆用户更稳定快速的访问。
当然,用户也可以在本地网络内创建一个私有仓库。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
yum install docker
systemctl enable docker
systemctl start docker
apt-get update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”
apt-get update
apt-cache madison docker-ce
#安装指定版
#apt-get install docker-ce=17.12.0ce-0ubuntu
#安装最新版
apt-get install docker-ce
systemctl enable docker
systemctl start docker
docker info
docker version
docker search
docker pull 拉取镜像
docker run 运行容器
eg: docker run –it centos:latest /bin/bash
-i 表示启动一个可交互的容器
-t 表示让docker分配一个伪终端并绑定到容器的标准输入上,
Centos:latest 表示我们要运行得镜像
/bin/bash 表示我们启动容器的时候要运行得命令
docker images 列出所有镜像
docker ps 查看在运行得容器 docler ps –a 查看所有容器
docker stop/start/restart 容器停止启动重启
docker rmi 删除镜像
docker rm 删除容器
docker tag标记本地镜像,将其归入某一仓库
环境:俩个装有docker的centos7.5的虚拟机
虚拟机一:192.168.2.117 docker私有仓库服务器
虚拟机二 : 192.168.2.29 运行docker服务的服务器
docker pull registry
mkdir –p /usr/local/registry
docker run -d -p 5000:5000 --name docker-registry -v /usr/local/registry:/tmp/registry registry
-d 表示后台模式运行
-p 5000:5000 表示将容器的5000端口映射到宿主机的5000端口
–name 表示为当前容器指定名称
-v 表示将宿主机的/usr/local/registry 挂载到容器/tmp/resgistry
容器正常启动,对外提供服务通过5000端口映射到docker-registry的5000端口;
执行命令curl http://127.0.0.1:5000/v2/_catalog,收到的响应如下,是个json对象,其中repositories对应的值是空的json数组,表示目前仓库里还没有镜像:
{“repositories”:[]}
注释:正常情况下,应用服务器推送镜像到仓库用的是https,而我们通过命令行来推送用的是普通的http,所以需要修改docker的启动参数,使之允许以http协议工作
所以我们需要修改/etc/sysconfig/docker文件:
vim /etc/sysconfig/docker
OPTIONS=’–selinux-enabled --log-driver=journald --insecure-registry 192.168.95.130:5000’
systemctl daemon-reload
systemctl restart docker
然后启动registry
Docker start docker.io/registry
接着下载一个nginx镜像
Docker pull nginx
Docker images
如上图所示,这个镜像的ID是7042885a156a,所以我们执行以下命令,给这个镜像添加一个带有私有仓库IP的TAG,这样后面才能成功推送到私有仓库:
docker tag 7042885a156a 192.168.2.117:5000/nginx
再执行docker images查看镜像的信息,如下图,出现了一个新的镜像
Docker push 192.168.2.117:5000/nginx
查看私有仓库
curl http://192.168.2.117:5000/v2/_catalog
{“repositories”:[“nginx”]}
现在私有仓库搭建好,并且仓库里有一个nginx镜像
现在我们去另外一台服务器上使用这个私有仓库并下载该镜像.
首先还是修改配置文件/etc/sysconfig/docker
然后重启docker加载配置文件
Docker pull 192.168.2.117:5000/nginx
查看镜像
接着运行容器
Docker run –d -p 8080:80 --name nginx -v /feng/nginx/html/:/usr/share/nginx/html/ 192.168.2.117:5000/nginx
介绍:Dockerfile 是一个由一堆命令+参数构成的脚本,使用 docker build 即可执行脚本构建镜像,自动的去做一些事,主要用于进行持续集成
<1>FROM:
1.FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令。至于image则可以是任何合理存在的image镜像。
2.FROM 一定是首个非注释指令 Dockerfile。
3.FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。
4.如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。
<2>MAINTAINER:这里是用于指定镜像制作者的信息。
<3>RUN:用来修改镜像的命令,常用来安装库、程序以及配置程序。一条RUN指令执行完毕后,会在当前镜像上创建一个新的镜像层,接下来对的指令会在新的镜像上继续执行。
<4>ENV:
1.ENV指令可以用于为docker容器设置环境变量
2.ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run --env =来修改环境变量。
<5>WORKDIR: 为接下来执行的指令指定一个新的工作目录,这个目录可以使绝对目录,也可以是相对目录
<6>COPY:COPY 将文件从路径 复制添加到容器内部路径 。
必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url, 是目标容器中的绝对路径。
<7>ADD:
ADD 将文件从路径 复制添加到容器内部路径 。
向新镜像中添加文件,这个文件可以是一个主机文件,也可以是一个网络文件,也可以使一个文件夹。
第一个参数:源文件(夹),如果是相对路径,它必须是相对于Dockerfile所在目录的相对路径。如果是URL,会先下载下来,再添加到镜像里去。
第二个参数:目标路径。如果源文件是主机上zip或者tar形式的压缩文件,Docker会先解压缩,然后将文件添加到镜像的指定位置。如果源文件是一个通过URL指定的网络压缩文件,则不会解压。
<8>VOLUME:创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
<9>EXPOSE : 用来指明容器内进程对外开放的端口,多个端口之间使用空格隔开。
<10>CMD:用来设置启动容器时默认运行的命令
Dockerfile构建nginx
首先建立一个自己的目录
mkdir /feng
在里面放入nginx的tar包以及写好的Dockerfile 如下所示
Cat Dockerfile:
From docker.io/centos
MAINTAINER nginx fengyuhang
ENV PATH /usr/local/nginx/sbin:${PATH}
RUN useradd -M -s /sbin/nologin nginx
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
ADD nginx-1.14.2.tar.gz /usr/src/
WORKDIR /usr/src/nginx-1.14.2
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module && make && make install
EXPOSE 80
CMD [“nginx”,”-g”,”deamon off;”]
然后开始构建镜像
Docker built -t nginxfeng(指定容器名字)
接着运行nginx镜像
docker run -d -p 81:80 --name test -v /feng/index.html:/usr/local/nginx/html/index.html nginxfeng
curl 127.0.0.1:81
可以看到访问nginx 返回的是我们制定的index.html 内容 说明nginx启动成功。
Kubernetes是一个完备的分布式系统支撑平台。Kubernetes具有完备的集群管理能力,包括多层次的安全防护和准入机制/多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复功能、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时kubernetes提供了完善的管理工具,这些工具覆盖了包括开发、测试部署、运维监控在内的各个环节;因此kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。
Kubernetes 里的Master指的是集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都发给它,它负责具体的执行过程,我们后面执行的所有命令基本上都是在Master节点上运行的。如果Master宕机或不可用,那么集群内容器的管理都将失效master节点上运行一些关键进程:
1)k8s API server(kube-apiserver),提供了HTTP Rest接口的关键服务进程,是所有资源的增删改查的唯一入口,也是集群集群控制的入口进程。kubectl的命令会调用到api server,来实现资源的增删查改。
2)kube-controller-manager,k8s所有资源对象的自动化控制中心。
3)kube-scheduler,pod调度进程。
4)另外往往还启动了一个etcd服务,因为k8s里所有资源对象的数据全部是保存在etcd中的,etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现。
除了Master,集群中其他机器被称为Node节点,每个Node都会被Master分配一些工作负载docker容器,当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上去。
每个Node节点上都运行着以下一组关键进程:
1)kubelet:负责Pod对应容器的创建、停止等任务,同时与Master节点密切协作,实现集群管理的基本功能
2)kube-proxy:实现Kubernetes Service的通信与负载均衡机制的重要组件。
3)Docker Engine(Docker):Docker引擎,负责本机的容器创建和管理工作。
查看当前nodes:kubectl get nodes
然后通过下面命令查看某个node的详细信息:kubectl describe node <node_name>
在集群管理方面,Kubernets将集群中的机器划分为一个Master节点和一群工作节点(Node),其中,在Master节点上运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性收缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程,这些服务进程负责Pod创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡
Pod是kubernetes最重要也最基本的概念,如图所示是Pod的组成示意图,我们看到每个Pod都有一个特殊的被称为“根容器”的Pause容器对应的镜像属于Kubernetes的平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。
每个pod由一个根容器的pause容器,其他是业务容器。
k8s为每个pod分配了唯一的IP地址,一个pod里的多个容器共享pod IP。
pod其实有两种类型:普通的pod和静态pod,后者比较特殊,它并不存放在etcd存储中,而是存放在某个具体的Node上的一个具体文件中,并且只在此Node上启动运行。而普通的pod一旦被创建,就会被放入etcd中存储。随后被master调度到某个具体的Node上并进行绑定,随后该pod被对应的Node上的kubelet进程实例化成一组相关的docker容器并启动起来。
每个pod都可以对其使用的服务器上的计算资源设置限额,当前可以设置限额的源有CPU和memory两种。其中CPU的资源单位为CPU的数量。
一般而言,一个CPU的配额已经算是相当大的一个资源配额,所以在k8s中,通常以千分之一的CPU配额为最小单位,以m来表示,通常一个容器的CPU配额为100-300m,即占用0.1-0.3个CPU。这个配额是个绝对值,不是占比。
在k8s中,一个计算资源进行配额限定需要设定两个参数:
requests,资源的最小申请量,系统必须满足要求
一个label是一个key=value的键值组合,然后可以通过label selector(标签选择器)查询和筛选拥有某些label的资源对象。
(Label 相当于我们熟悉的标签,给某个资源对象定义一个Label,就相当于给它打了一个标签,随后可以通过Label Selector 标签选择器 查询和筛选有某些Label的资源对象。Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制)。
label的重要使用场景:
kube-controller进程通过资源对象RC上定义的label selector来筛选要监控的pod的数量,从而实现全自动控制流程。
kube-proxy进程通过service的label selector来选择对应的pod,自动建立起每个service到对应pod的请求转发路由表。从而实现service的智能负载均衡机制。
当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实力的数量刚好等于此RC的期望值,如果有过多的Pod副本在运行,系统就会停掉一些Pod,否则系统就会再自动创建一些Pod。 可以说,通过RC,Kubernetes实现了用户应用集群的高可用性,并大大减少了传统IT需要手动的工作
RC定义了如下
1.Pod期待的副本数(replicas)
2.用于筛选目标Pod的Label Seletcor(标签选择器)
3.当Pod的副本小于预期(replicas)时,用于创建新Pod的Pod模板(template)
删除RC并不会影响通过该RC已创建号的Pod。为了删除所有Pod,可以设置replicas的值为0,然后更新该RC。另外,kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod
通过手动执行kubectl scale命令,可以通过RC实现pod扩容。
HPA,pod横向自动扩容,实现原理是通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地挑战目标pod的副本数。
有两种方式作为pod负载的度量指标。
<1>CPU utilization percentage
<2>应用程序自定义的度量指标,比如服务在每秒内的相应的请求数。
CPU utilization percentage是一个算术平均值,目标pod所有副本自身的CPU利用率的平均值。一个Pod自身的CPU利用率是该Pod当前CPU使用量除以它的Pod request的值。比如当我们定义一个Pod的pod request为0.4,而当前pod的cpu使用量为0.2,则使用率为50%。如此可以得出一个平均值,如果某一个时刻CPU utilization percentage超过80%,则表示当前副本数不够,需要进行扩容.
Service是Kubernetes里最核心的资源对象之一,Service定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实力。 Service与其后端Pod副本集群之间则是通过Label Selector来实现"无缝对接"。而RC的作用实际上是保证Service 的服务能力和服务质量处于预期的标准
每个pod会被分配一个独立的IP地址,也就是每个pod都提供一个独立的endpoint(IP+port)以被访问,那多个pod如何被客户端访问呢,k8s通过运行在每个Node上的kube-proxy进程,负责将对service的请求转发到后端某个pod实例上,也就实现了类似负载均衡器的功能,至于具体转发到哪个pod,则由负载均衡器的算法所决定。并且service不是共用一个负载均衡器的IP地址,而是每一个service分配了一个全局唯一的虚拟IP,这样每个服务就变成了具有唯一IP的通信节点,服务调用也就变成了最为基础的TCP通信问题。
pod的Endpoint地址会随着Pod的销毁和重新创建而发生改变,因为新的Pod地址与之前的旧的Pod不同。而Service一旦被创建,Kubernetes就会自动为它分配一个可用的Cluster IP,而且在Service的整个声明周期内,它的Cluster IP不会发生改变。所以只要将Service的name与Service的Cluster IP地址做一个DNS域名映射即可解决问题。
k8s的服务发现机制:每个service都有一个唯一的cluster IP以及唯一的名字,而名字是由开发者自己定义的,部署的时候也没必要改变,所以完全可以固定在配置中,接下来的问题 就是如何通过service的名字找到对应的cluster IP。
外部系统访问service的问题:
k8s中有三种IP:
a,Node IP:node节点的IP地址
b,Pod IP:pod的IP地址
c,cluster IP:service IP
首先,Node IP是k8s集群中每个节点的物理网卡的IP地址,这是一个真实存在的物理网络,所有属于这个网络的服务器之间都能直接通信,不管属不属于k8s集群。这也表明了k8s集群之外的节点访问k8s集群之内的某个节点后者TCP/IP服务的时候,必须要通过Node IP通信。
其次,pod IP是每个Pod的IP地址,它是根据docker网桥的IP地址段进行分配的,通常是一个虚拟的二层网络,因此不同pod之间的通信就是通过Pod IP所在的虚拟二层网络进行通信的。而真实的TCP/IP流量则是通过Node IP所在的物理网卡流出的。
Cluster IP,它是一个虚拟IP,但更像是一个伪造的IP网络
(1)Cluster IP仅仅作用于Kubernetes Service对象,并由Kubernetes管理和分配IP地址(来源于Cluster IP地址池)
(2)Cluster IP无法被Ping,因为没有一个"实体网络对象"来响应
(3)在Kubernetes集群内,Node IP、Pod IP、Cluster IP之间的通信,采用的是Kubernetes自己设计的特殊路由规则
Volume是pod中能够被多个容器访问的共同目录。也就是被定义在pod上,然后被一个pod中的多个容器挂载到具体的文件目录下,其次,volume与pod生命周期相同,但与容器生命周期不相关,当容器终止或重启,volume中的数据也不会丢失
大多数情况下用于实现多租户的资源隔离,namespace通过将集群内部的资源对象分配到不同的namespace中,形成逻辑上分组的不同项目、小组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。
namespace的定义很简单,如下所示的yaml定义了名为development的namespace
apiVersion: v1
kind: Namespace
metadata:
name: development
一旦创建了Namespace,我们在创建资源对象时就可以指定这个资源对象属于哪个namespace,比如下面,定义了名为busybox的Pod,放入development这个namespace里:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: development
kubectl get
kubectl get命令用来获取资源信息列表,可用来查看pod是否健康,当前的运行状态,重启了几次,生命周期等,是最常用的命令之一
kubectl get pod
获取pod资源列表,默认获取default命名空间
kubectl get pod -n kube-system
获取kube-system命名空间的pod资源列表
kubectl get pod --all-namespaces
获取所有命名空间的pod资源列表
kubectl get pod -n kube-system kube-apiserver-k8s-01
获取kube-system命名空间中指定的pod:kube-apiserver-k8s-01的信息
当查看某个具体的pod时,必须指明该pod所在的命名空间,像–all-namespaces参数是不能使用的
kubectl get pod -n kube-system kube-apiserver-k8s-01 -o wide
获取kube-system命名空间中指定的pod:kube-apiserver-k8s-01的信息,并且展示更多信息,包括pod ip,所在节点等信息
kubectl get pod -n kube-system kube-apiserver-k8s-01 -o yaml
获取kube-system命名空间中指定的pod:kube-apiserver-k8s-01的信息,并且以yaml格式展示pod详细信息
kubectl get pod -n kube-system kube-apiserver-k8s-01 -o json
获取kube-system命名空间中指定的pod:kube-apiserver-k8s-01的信息,并且以json格式展示pod详细信息
kubectl get pod --all-namespaces --watch
监控pod资源的变化
上述命令中的pod为kubernetes集群中的一种资源对象,其它资源对象,例如:deployment、deamonset、endpoint、ingress、services、secrets等等,都可以用get命令,全部的资源对象详见这里
kubectl describe
打印所选资源的详细描述信息,当pod启动异常的时候也可以用该命令排查问题
kubectl describe -n kube-system pod kube-apiserver-k8s-01
描述pod:kube-apiserver-k8s-01的详细信息
kubectl describe -n kube-system secrets kubernetes-dashboard-token-9mvxp
描述secrets详细信息,例如该命令可查询登录dashboard所需的token信息
kubectl exec
与docker exec命令一样,kubectl exec 也是用来进入容器内部的
kubectl exec -it -n kube-system kube-apiserver-k8s-01 sh
进入kube-system命名空间下的kube-apiserver-k8s-01容器内部
仅当pod内只有一个容器的时候适用
kubectl exec -it -n kube-system calico-node-rw4c2 -c install-cni sh
-it:开启虚拟终端tty,并将标准输入传入容器中
-i, --stdin=false: Pass stdin to the container
-t, --tty=false: Stdin is a TTY
当pod中有多个容器,需要进入指定的容器时适用,比上一条命令多了-c container_name
container_name可以通过kubectl describe命令获得
kubectl describe pod calico-node-rw4c2 -n kube-system | grep -B 1 “Container ID”
kubectl logs
kubectl logs用来查看容器的日志,在定位问题时非常有用
kubectl logs -n kube-system -f --tail 10 kube-apiserver-k8s-01
-f: 动态打印日志
–tail 10: 打印最后10行日志,不加该参数时默认会打印全部的日志,在日志非常多的时候非常有用
kubectl scale
kubectl scale用来对deployement、replicaset、statefulset等资源进行伸缩
kubectl scale deployment -n kube-system --replicas=2 kubernetes-dashboard
–replicas=2: 指定副本数量为2
先设置replicas=0,再设置replicas=1可实现pod重启操作
kubectl apply
通过传入文件名或者标准输入来创建资源或配置
kubectl apply -f .
创建或更新当前目录所有的yaml文件描述的配置或资源
kubectl apply -f /home/agms/
创建或更新指定目录所有的yaml文件描述的配置或资源
kubectl apply -f /home/agms/a.yaml
创建或更新指定yaml文件描述的配置或资源
kubectl delete
kubectl delete -f .
删除当前目录所有的yaml文件描述的配置或资源
kubectl delete -f /home/agms/
删除指定目录所有的yaml文件描述的配置或资源
kubectl delete -f /home/agms/a.yaml
删除指定yaml文件描述的配置或资源
kubectl delete nodes k8s-01
按照节点名删除集群中的节点(慎用)
kubectl explain*
列出受支持资源的字段、版本,各字段的描述、类型等,在编写yaml文件时非常有用
kubectl explain deployment.spec
描述deployment资源的spec字段
kubectl create
通过命令行创建kubernetes资源或配置信息
kubectl create namespace fpi-inc
创建一个fpi-inc的命名空间
一般建议通过kubectl apply的方式来进行资源或配置的创建
node host alias
Master 192.168.0.10 master
Node 192.168.0.11 Node
配置节点别名、配置免秘钥登陆
#node1写master、node2写worker1(以后扩展多个节点)
nodeName=master
echo $nodeName > /etc/hostname
echo “192.168.0.10 node1 master” >> /etc/hosts
echo “192.168.0.11 node2 worker1” >> /etc/hosts
#此处所有会话都直接回车
ssh-keygen -t rsa
cd ~/.ssh
touch authorized_keys
#拷贝node1和node2的id_rsa.pub到authorized_keys(node1和node2的都拷贝进去,两个节点有相同的authorized_keys)
reboot
从阿里云镜像安装
CentOS / RHEL / Fedora
cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet
关闭swap
swapoff -a
sed -i ‘s/^(.swap.$)/#\1/’ /etc/fstab
官网下载:https://github.com/etcd-io/etcd/releases
1.生成ssl安全证书(如果使用http协议,此步可略过)
curl -s -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -s -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssl cfssljson
cp cfssl cfssljson /usr/local/bin/
mkdir -p ~/ssl
cd ~/ssl
cat <ca-config.json
{
“signing”: {
“default”: {
“expiry”: “876000h”
},
“profiles”: {
“kubernetes”: {
“expiry”: “876000h”,
“usages”: [
“signing”,
“key encipherment”,
“server auth”,
“client auth”
]
}
}
}
}
EOF
cat <ca-csr.json
{
“CN”: “kubernetes”,
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “BeiJing”,
“L”: “BeiJing”,
“O”: “k8s”,
“OU”: “System”
}
],
“ca”: {
“expiry”: “87600h”
}
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
#生成ca-key.pem、ca.csr、ca.pem三个文件
cat <kubernetes-csr.json
{
“CN”: “kubernetes”,
“hosts”: [
“127.0.0.1”,
“192.168.0.10”,
“192.168.0.11”,
“10.244.0.1”,
“kubernetes”,
“kubernetes.default”,
“kubernetes.default.svc”,
“kubernetes.default.svc.cluster”,
“kubernetes.default.svc.cluster.local”
],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “BeiJing”,
“L”: “BeiJing”,
“O”: “k8s”,
“OU”: “System”
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
cp * /etc/kubernetes/ssl
2.安装etcd
tar xf etcd-v3.3.10-linux-amd64.tar.gz
cd etcd-v3.3.10-linux-amd64
cp etcd* /usr/local/bin/
mkdir -p /var/lib/etcd/
3.安装服务
vim /etc/systemd/system/ etcd.service
etcd.service如下所示,不同节点需要修改–name参数,以及监听本机ip:port,如果用http协议,可以不配置ssl安全证书
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd
–name etcd0
–cert-file=/etc/kubernetes/ssl/kubernetes.pem
–key-file=/etc/kubernetes/ssl/kubernetes-key.pem
–peer-cert-file=/etc/kubernetes/ssl/kubernetes.pem
–peer-key-file=/etc/kubernetes/ssl/kubernetes-key.pem
–trusted-ca-file=/etc/kubernetes/ssl/ca.pem
–peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem
–initial-advertise-peer-urls “https://192.168.0.10:2380”
–listen-peer-urls “https://192.168.0.10:2380”
–listen-client-urls “https://192.168.0.10:2379,https://127.0.0.1:2379”
–advertise-client-urls “https://192.168.0.10:2379”
–initial-cluster-token “etcd-cluster”
–initial-cluster etcd0=https://192.168.0.10:2380,etcd1=https://192.168.0.11:2380
–initial-cluster-state new
–data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动服务
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
查看健康状态
etcdctl --endpoints=https://192.168.0.10:2379 --ca-file=/etc/kubernetes/ssl/ca.pem cluster-health
kubeadm init --config k8s_init.yaml
一个k8s初始化的文件如下所示,kubernetesVersion指定了初始化的版本,需要预先在所有节点上下载下来镜像并打上tag,不然会初始化不动(如果没有预先下载,会从官网下载,要翻墙的,可以从国外服务器上下载之后使用docker save、docker load把镜像保存成文件再载入)
k8s.gcr.io/kube-proxy-amd64 v1.10.3 4261d315109d 5 months ago 97.1 MB
k8s.gcr.io/kube-scheduler-amd64 v1.10.3 353b8f1d102e 5 months ago 50.4 MB
k8s.gcr.io/kube-controller-manager-amd64 v1.10.3 40c8d10b2d11 5 months ago 148 MB
k8s.gcr.io/kube-apiserver-amd64 v1.10.3 e03746fe22c3 5 months ago 225 MB
api:
advertiseAddress: 192.168.0.10
bindPort: 6443
controlPlaneEndpoint: “”
auditPolicy:
logDir: /var/log/kubernetes/audit
logMaxAge: 2
path: “”
authorizationModes:
添加一个环境变量 export KUBECONFIG=/etc/kubernetes/admin.conf
初始化完毕后,根据提示执行以下命令:
root@k8s-master-01:/home/zcs# mkdir -p $HOME/.kube
root@k8s-master-01:/home/zcs# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@k8s-master-01:/home/zcs# sudo chown
(
i
d
−
u
)
:
(id -u):
(id−u):(id -g) $HOME/.kube/config
根据提示在worker节点执行kubeadm join xxx命令,将worker节点加入集群
root@worker-01:~# kubeadm join 192.168.0.10:6443 --token 7odzio.v63p658llil3cij9 --discovery-token-ca-cert-hash
sha256:3ea30427d276996f214adba1794af4e37262cdfaa4326dac0c33534fd45a843d
[preflight] Running pre-flight checks.
[WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[preflight] Starting the kubelet service
[discovery] Trying to connect to API Server “192.168.0.10:6443”
[discovery] Created cluster-info discovery client, requesting info from “https://192.168.0.180:6443”
[discovery] Requesting info from “https://192.168.0.10:6443” again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server “192.168.0.10:6443”
[discovery] Successfully established connection with API Server “192.168.1.10:6443”
This node has joined the cluster:
重新生成新的token
kubeadm token create
查看重新生成的token
kubeadm join --token aa78f6.8b4cafc8ed26c34f --discovery-token-ca-cert-hash sha256:0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538 172.16.6.79:6443 --skip-preflight-checks
kubectl apply -f mysql.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
custom.cnf: |
[mysqld]
default_storage_engine=innodb
lower_case_table_names=1
skip_name_resolve
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 1
selector:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7.20
name: mysql
resources:
limits:
memory: 4Gi ports: - containerPort: 3306 hostPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "abc2333" volumeMounts: - name: mysql-data-volume mountPath: /var/lib/mysql - name: mysql-conf mountPath: /etc/mysql/conf.d/ - name: mysql-date mountPath: /etc/localtime volumes: - name: mysql-data-volume hostPath: path: /home/docker/agms/mysql/data - name: mysql-conf configMap: name: mysql-config - name: mysql-date hostPath: path: /etc/localtime
第一次写博客,排版有问题,希望大家多多见谅.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。