同步时间
# ntpdate time.nist.gov
k8s集群组成 k8s部署环境 
https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#prerequisites
01 安装方式
关于安装方式,目前除去云服务商本身提供的K8S集群服务, 本地集群安装方式主要有3种: 基于二进制的安装方式
基于官方工具kubeadm的安装方式
基于第三方工具的安装 1、基于yum直接将相关组件部署为系统级守护进程,缺点:controller-manager故障,需要手动重启; 节点网络:192.168.0.0/16
Pod网络地址:10.244.0.0/16
Service网络地址:10.96.0.0/12   //掩码是12位的
etcd部署在master节点上,不独立;
2、使用kubeadm进行部署,将k8s的核心组件部署为pod,但需要在master和node上手动部署kubelet和docker(docker是运行容器的引擎,kubelet是运行pod化的容器的核心组件);
使用kubeadm进行部署,每一个节点都需要作为k8s底层的docker运行的节点,即包括master都需要安装docker,同时每一个节点都需要安装、运行kubelet、docker,并且确保这两者启动并运行。把第一个节点初始化为master,把其他节点初始化为node。将master上的组件API Server、etcd、controller-manager、scheduler都运行为pod(都是静态pod,不受k8s管理,只是运行为pod的形式),即都跑在kubelet之上,以容器化的形式运行(k8s自己的组件都运行为pod)。node上将kube-proxy运行为Pod。每一个节点包括master都需要以pod运行flannel(动态pod,由k8s自身管理),
k8s在github上的地址:https://github.com/kubernetes
 
kubeadm初始化并安装、生成k8s集群的过程  
https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md
kubeadm初始化、安装集群的步骤:
1、master、nodes:安装kubelet、kubeadm、docker
2、master:kubeadm init  //在master运行kubeadm init,初始化集群 3、nodes:kubeadm join   //在各nodes节点执行kubeadm join,将节点加入到集群中去

安装实践

部署环境

master:IP:192.168.184.141  主机名:master

node1: IP:192.168.184.142  主机名:node01

node2: IP:192.168.184.143  主机名:node02

链接地址:https://github.com/kubernetes/kubernetes/releases?after=v1.13.0-alpha.0

将master和node节点分开下载(注意这是第一种安装方式,即将k8s的组件以系统级守护进程来运行)

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#v1111

注意:无论是master还是node,用到的都是server端的安装包,由于在服务器本地也要执行一些客户端的命令,所以也需要将客户端的安装包下载下来。

下面以第二种安装方式,即kubeadm安装k8s,这里使用阿里云利用yum进行安装

注意:iptables和firewalld一定不能启用,因为在安装k8s时会大量操作iptables规则

阿里云镜像链接  https://mirrors.aliyun.com/kubernetes/

1、首先部署docker的yum仓库   https://mirrors.aliyun.com/docker-ce/linux/centos/

master ~]# cd /etc/yum.repos.d/

master yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

master yum.repos.d]# vim docker-ce.repo   //可以看出已经指向阿里云的仓库链接了

2、配置k8s的yum仓库

master ~]# cd /etc/yum.repos.d/

master yum.repos.d]# vim kubernets.repo

   [kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
enabled=

3、初始化k8s和docker的yum仓库

master yum.repos.d]# yum repolist

将k8s和docker的yum仓库发送至node01和node02节点

master yum.repos.d]# scp kubernets.repo docker-ce.repo node01:/etc/yum.repos.d/

master yum.repos.d]# scp kubernets.repo docker-ce.repo node02:/etc/yum.repos.d/

4、在master上安装docker和k8s

master yum.repos.d]# yum install docker-ce kubelet kubeadm kubectl   //kubectl是API Server的命令行客户端

在安装过程出现k8s无gpg-key的问题,就手动导入

master yum.repos.d]# vim kubernets.repo    //将gpgcheck=0

master ~]# wget https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg   //下载yum检查密钥,注意路径

master ~]# rpm --import yum-key.gpg   //导入密钥

master ~]# yum install docker-ce kubelet kubeadm kubectl   //在此进行安装

5、初始化docker和k8s并启动

docker需要到docker仓库中下载所依赖的每一个镜像文件,这些镜像文件有时可能是无法获取的,所以可以利用其他方法加载镜像文件再导入进来。由于kubeadm是支持直接使用本地当中已有的镜像文件或者使用本地私有仓库作为镜像的下载路径的。这里并不适用此方法,而是使用代理路径来获取并下载相关镜像文件。

master ~]# vim /usr/lib/systemd/system/docker.service   //修改此文件,定义一个环境变量

[Service]

Environment="HTTPS_PROXY=http://www.ik8s.io:10080" //在访问https服务时,通过访问代理来加载相关的镜像文件,加载完之后可以把此行注释掉

Environment="NO_PROXY=127.0.0.0/8,192.168.184.0/24"  //此行表示不做代理

master ~]# systemctl daemon-reload

master ~]# systemctl start docker

master ~]# docker info

由于docker会大量生成iptables规则,可能需要打开bridge-nf-call-ip6tables和bridge-nf-call-iptables的桥接功能

[root@master ~]# cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
                 1    //确定这两个参数都是1
[root@master ~]# cat /proc/sys/net/bridge/bridge-nf-call-iptables
                 1

以上docker就设定成功

下面开始设定kubelet

master ~]# rpm -ql kubelet
/etc/kubernetes/manifests     //清单目录
/etc/sysconfig/kubelet      //配置文件
/usr/bin/kubelet        //主程序
/usr/lib/systemd/system/kubelet.service   //unit file

master ~]# systemctl enable kubelet   //先不要启动kubelet,因为还没有初始化完成

master ~]# kubeadm init --help   //查看初始化选项

kubeadm初始化选项和命令:https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/

--apiserver-advertise-address string
API Server将要广播的监听地址。如指定为 `0.0.0.0` 将使用缺省的网卡地址。
--apiserver-bind-port int32 缺省值:
API Server绑定的端口
--apiserver-cert-extra-sans stringSlice
可选的额外提供的证书主题别名(SANs)用于指定API Server的服务器证书。可以是IP地址也可以是DNS名称。
--cert-dir string 缺省值: "/etc/kubernetes/pki"
证书的存储路径。
--config string
kubeadm配置文件的路径。警告:配置文件的功能是实验性的。
--cri-socket string 缺省值: "/var/run/dockershim.sock"
指明要连接的CRI socket文件
CoreDNS=true|false (缺省值=true)
DynamicKubeletConfig=true|false (当前为BETA状态 - 缺省值=false)
-h, --help
获取init命令的帮助信息
--ignore-preflight-errors stringSlice
忽视检查项错误列表,列表中的每一个检查项如发生错误将被展示输出为警告,而非错误。 例如: 'IsPrivilegedUser,Swap'. 如填写为 'all' 则将忽视所有的检查项错误。
--kubernetes-version string 缺省值: "stable-1"
为control plane选择一个特定的Kubernetes版本。
--node-name string
指定节点的名称。
--pod-network-cidr string
指明pod网络可以使用的IP地址段。 如果设置了这个参数,control plane将会为每一个节点自动分配CIDRs。
--service-cidr string 缺省值: "10.96.0.0/12"
为service的虚拟IP地址另外指定IP地址段
--service-dns-domain string 缺省值: "cluster.local"
为services另外指定域名, 例如: "myorg.internal".
--skip-token-print
不打印出由 `kubeadm init` 命令生成的默认令牌。
--token string
这个令牌用于建立主从节点间的双向受信链接。格式为 [a-z0-]{}\.[a-z0-]{} - 示例: abcdef.0123456789abcdef
--token-ttl duration 缺省值: 24h0m0s
令牌被自动删除前的可用时长 (示例: 1s, 2m, 3h). 如果设置为 '', 令牌将永不过期

获取镜像列表  https://www.cnblogs.com/peter1007/articles/9872491.html

master ~]# kubeadm config images list

k8s.gcr.io/kube-apiserver:v1.14.2
k8s.gcr.io/kube-controller-manager:v1.14.2
k8s.gcr.io/kube-scheduler:v1.14.2
k8s.gcr.io/kube-proxy:v1.14.2
k8s.gcr.io/pause:3.1  //pause的作用是比如一个容器可以不用启动,随后其他容器启动时可以加入复制这个容器的网络和存储卷,这个容器称为基础架构容器。
k8s.gcr.io/etcd:3.3.10
k8s.gcr.io/coredns:1.3.1

master ~]# kubeadm init --kubernetes-version=v1.14.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16

master ~]# vim /etc/sysconfig/kubelet

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

master ~]# kubeadm init --kubernetes-version=v1.14.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16 --ignore-preflight-errors=Swap

但是出现了拉取镜像失败的问题,原因可能是无法访问google的

cgroup驱动程序错误解决方法:https://kubernetes.io/docs/setup/cri/

cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF

关掉swap分区:https://blog.51cto.com/10950710/2373669

master ~]# swapoff -a

永久禁用swap分区:
注释掉/etc/fstab文件中"/dev/mapper/centos-swap"这一行:

Kubernetes:如何解决从k8s.gcr.io拉取镜像失败问题:

   https://www.cnblogs.com/climbsnail/p/12821799.html    //重点参考

https://blog.csdn.net/jinguangliu/article/details/82792617

https://www.cnblogs.com/nb-blog/p/10636733.html

此方式是docker.io仓库对google的容器做了镜像,可以通过下列命令下拉取相关镜像:

#docker pull mirrorgooglecontainers/kube-apiserver-amd64:v1.14.2   //先手动拉取镜像

master ~]# docker pull coredns/coredns:1.3.1

根据安装版本信息进行相应的修改。通过docker tag命令来修改镜像的标签:

#docker tag docker.io/mirrorgooglecontainers/kube-proxy-amd64:v1.14.2 k8s.gcr.io/kube-proxy-amd64:v1.14.2

上述拉取镜像自动化https://blog.51cto.com/nhylovezyh/2377982

重点参考:https://www.cnblogs.com/climbsnail/p/12821799.html

解决上述问题后再次执行master ~]# kubeadm init --kubernetes-version=v1.14.2...即可成功

此段代码是需要用到

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.184.141: --token c6iiam.88h3alqgl9pewtsw --discovery-token-ca-cert-hash sha256:68672b008c52eca6623e875401cc99cdd0942ce359c6345ddbc57ce1e59be4ea

master ~]# ss -tnl

问题:API Server没有启动,没有监听6443端口

The connection to the server 192.168.184.141:6443 was refused - did you specify the right host or port?

注意:如果服务器不小心重启,kubelet无法重新启动,解决方案:https://www.jianshu.com/p/39896f2e429d

[root@master ~]# mkdir -p $HOME/.kube
[root@master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config  //admin.conf是kubeadm自动初始化好的一个文件,它可以被kubectl拿来作为配置文件,指定连接至k8s的API Server并完成认证。
[root@master ~]# chown $(id -u):$(id -g) $HOME/.kube/config //如果管理员执行上述两个操作,此步就取消

[root@master ~]# kubectl get componentstatus   //这里能正常显示信息,说明API Server是正常的

[root@master ~]# kubectl get nodes  //查看节点
   NAME    STATUS    ROLES    AGE   VERSION
   master  NotReady  master  7h12m  v1.14.2

//NotReady此时master是未就绪状态,因为缺少flannel或者Calico这样的网络组件

下面在master服务器上部署flannel网络组件 https://github.com/coreos/flannel

# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml   //执行此命令,会自动在线获取部署清单,并基于此清单下载镜像,启动并部署flannel

[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

podsecuritypolicy.extensions/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created

[root@master ~]# kubectl get nodes
    NAME    STATUS   ROLES    AGE    VERSION
    master  Ready    master   7h30m  v1.14.2   //此时master已经ready状态

[root@master ~]# kubectl get pods -n kube-system   //kube-system是一个名称空间

列表中显示的是当前所有运行的pod,并且属于kube-system名称空间,如果不指明的名称空间的话,那就属于kubernetes集群默认的名称空间,即defaults。

[root@master ~]# kubectl get ns   //查看k8s集群的名称空间
   NAME              STATUS    AGE    //四个名称空间
   default           Active   7h41m
   kube-node-lease   Active   7h41m
   kube-public       Active   7h41m
   kube-system       Active   7h41m    //系统级别的pod都在kube-system名称空间中

以上master节点算是安装完成,只要node节点安装成功,更改docker文件(获取镜像文件),启动docker并开机启动docker和k8s,再设置kubelet swap文件,再初始化k8s集群(将node节点加入到集群中)就可以了。

master节点已经设置成功,下面就是指node01节点和node02节点

1、首先将master节点的yum仓库复制到node01和node02

master ~]# scp yum-key.gpg node01:/root node01:/root

master ~]# scp /etc/yum.repos.d/kubernets.repo node01:/etc/yum.repos.d/

master ~]# scp /etc/yum.repos.d/docker-ce.repo node01:/etc/yum.repos.d/

2、安装docker-ce和kubernetes

node1 ~]# rpm --import yum-key.gpg    //首先导入yum密钥文件

node1 ~]# yum install docker-ce kubelet kubeadm

node01(192.168.184.142)节点已经安装成功,下面对node01节点进行初始化

首先设置docker.service文件,可以下载镜像文件,但是这里不能访问Google的镜像文件,只能手动下载

master ~]# scp /usr/lib/systemd/system/docker.service node01:/usr/lib/systemd/system/docker.service

master ~]# scp /etc/sysconfig/kubelet node01:/etc/sysconfig/

KUBELET_EXTRA_ARGS="--fail-swap-on=false"   //文件中的内容

这里依然需要解决:cgroup驱动程序错误解决方法:https://kubernetes.io/docs/setup/cri/,前文已有叙述。

[root@node01 ~]# systemctl start docker
[root@node01 ~]# docker info

[root@node01 ~]# systemctl enable docker kubelet   //开机启动
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /usr/lib/systemd/system/kubelet.service.

node01 ~]# kubeadm join 192.168.184.141:6443 --token c6iiam.88h3alqgl9pewtsw --discovery-token-ca-cert-hash sha256:68672b008c52eca6623e875401cc99cdd0942ce359c6345ddbc57ce1e59be4ea --ignore-preflight-errors=Swap  //初始化集群

此时需要等待node01节点需要下载kube_proxy镜像和flannel镜像,并启动起来,node节点才算真正初始化完成。

在master节点可以查看到node01节点已经加进集群,但是没有初始化完成

node01 ~]# docker pull quay.io/coreos/flannel:v0.11.0

node01 ~]# docker pull mirrorgooglecontainers/kube-proxy:v1.14.2

node01 ~]# docker tag mirrorgooglecontainers/kube-proxy:v1.14.2 k8s.gcr.io/kube-proxy:v1.14.2

node01 ~]# docker rmi mirrorgooglecontainers/kube-proxy:v1.14.2

node01 ~]# docker pull mirrorgooglecontainers/pause:3.1

node01 ~]# docker tag mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1

node01 ~]# docker rmi mirrorgooglecontainers/pause:3.1

准备node02节点

1、首先复制masetr节点上配置好的docker和k8s的yum仓库文件

master ~]# scp yum-key.gpg node02:/root

master ~]# scp /etc/yum.repos.d/kubernets.repo node02:/etc/yum.repos.d/

master ~]# scp /etc/yum.repos.d/docker-ce.repo node02:/etc/yum.repos.d/

2、在node02节点安装docker和k8s

node02 ~]# yum install docker-ce kubeadm kubelet

node02 ~]# vim /usr/lib/systemd/system/docker.service

Environment="NO_PROXY=127.0.0.1/8,192.168.184.0/24"   //在文件中service段落中添加此行

node02 ~]# vim /etc/sysconfig/kubelet

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

cgroup驱动程序错误解决方法:https://kubernetes.io/docs/setup/cri/

node02 ~]# swapoff -a   //关闭swap分区

node02 ~]# systemctl daemon-reload

node02 ~]# systemctl enable docker

node02 ~]# systemctl start docker

node02 ~]# systemctl enable kubelet

3、拉取镜像

node02 ~]# docker pull quay.io/coreos/flannel:v0.11.0

node02 ~]# docker pull mirrorgooglecontainers/kube-proxy:v1.14.2

node02 ~]# docker tag mirrorgooglecontainers/kube-proxy:v1.14.2 k8s.gcr.io/kube-proxy:v1.14.2

node02 ~]# docker rmi mirrorgooglecontainers/kube-proxy:v1.14.2

node02 ~]# docker pull mirrorgooglecontainers/pause:3.1

node02 ~]# docker tag mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1

node02 ~]# docker rmi mirrorgooglecontainers/pause:3.1

4、初始化k8s集群

node02 ~]# kubeadm join 192.168.184.141:6443 --token c6iiam.88h3alqgl9pewtsw --discovery-token-ca-cert-hash sha256:68672b008c52eca6623e875401cc99cdd0942ce359c6345ddbc57ce1e59be4ea --ignore-preflight-errors=Swap   //注意口令是会过期的,要注意更新

kubeadm 生成的token过期后,集群增加节点 https://www.jianshu.com/p/a5e379638577

master ~]# kubectl get pods -n kube-system -o wide

3、kubeadm初始化Kubernetes集群的更多相关文章

  1. kubeadm初始化kubernetes集群

    有两种方式安装集群: 1.手动安装各个节点的各个组件,安装极其复杂困难. 2.使用工具:kubeadm kubeadm 是官方提供的专门部署集群的管理工具. 1. 在kubeadm下每个节点都需要安装 ...

  2. kubeadm搭建kubernetes集群之三:加入node节点

    在上一章<kubeadm搭建kubernetes集群之二:创建master节点>的实战中,我们把kubernetes的master节点搭建好了,本章我们将加入node节点,使得整个环境可以 ...

  3. kubeadm搭建kubernetes集群之二:创建master节点

    在上一章kubeadm搭建kubernetes集群之一:构建标准化镜像中我们用VMware安装了一个CentOS7虚拟机,并且打算用这个虚拟机的镜像文件作为后续整个kubernetes的标准化镜像,现 ...

  4. 02-kubeadm初始化Kubernetes集群

    目录 部署 组件分布 部署环境 kubeadm 步骤 基础环境 基础配置 安装基础组件 配置yum源 安装组件 初始化 master 导入镜像 执行命令: 查看组件状态 查看node状态 安装flan ...

  5. Kubernetes(K8s) 安装(使用kubeadm安装Kubernetes集群)

    背景: 由于工作发生了一些变动,很长时间没有写博客了. 概述: 这篇文章是为了介绍使用kubeadm安装Kubernetes集群(可以用于生产级别).使用了Centos 7系统. 一.Centos7 ...

  6. kubeadm 搭建kubernetes集群环境

    需求 kubeadm 搭建kubernetes集群环境 准备条件 三台VPS(本文使用阿里云香港 - centos7.7) 一台能SSH连接到VPS的本地电脑 (推荐连接工具xshell) 安装步骤 ...

  7. Kubernetes 学习3 kubeadm初始化k8s集群

    一.k8s集群 1.k8s整体架构图 2.k8s网络架构图 二.基于kubeadm安装k8s步骤 1.master,nodes:安装kubelet,kubeadm,docker 2.master: k ...

  8. 使用kubeadm部署Kubernetes集群

    一.环境架构与部署准备 1.集群节点架构与各节点所需安装的服务如下图: 2.安装环境与软件版本: Master: 所需软件:docker-ce 17.03.kubelet1.11.1.kubeadm1 ...

  9. kubeadm部署Kubernetes集群

    Preface 通过kubeadm管理工具部署Kubernetes集群,相对离线包的二进制部署集群方式而言,更为简单与便捷.以下为个人学习总结: 两者区别在于前者部署方式使得大部分集群组件(Kube- ...

随机推荐

  1. DA_04_解决Xshell中文乱码问题

    一:解决Xshell中文乱码问题      二:解决克隆后eth0不见的问题 2.1:虚拟机克隆步骤:          1.直接修改  /etc/sysconfig/network-script/i ...

  2. C++虚函数作用原理(一)——虚函数如何在C++语言逻辑中存在

    C++多态,接触其实也没太长的时间.上课的时候老师总是不停的讲,多态可以实现利用一个基类对象调用不同继承类的成员函数.我就会觉得很伤脑筋,这个的原理到底是什么?是什么呢? 开始的时候我觉得自己应该能够 ...

  3. less 分页显示文件内容

    1.命令功能 less 是more的增强版,可以分页显示文件内容,而且less打开文件的速度要比vi,more更快.less支持搜索功能,显示行号. 2.语法格式 less  option  file ...

  4. 磁盘阵列(RAID)

    RAID 0亦称为带区集.它将两个以上的磁盘并联起来,成为一个大容量的磁盘.在存放数据时,分段后分散存储在这些磁盘中,因为读写时都可以并行处理,所以在所有的级别中,RAID 0的速度是最快的.但是RA ...

  5. x86和x64下指针的大小

    根据测试 int main() { ; )); )); int n1 = sizeof(a); int n2 = sizeof(p); // int n3 = sizeof(*p); error in ...

  6. Python之文字转图片

    Pygame模块一览表: 引入pygame模块 ,若本机没有请自行pip install pygame #载入必要的模块 import pygame #pygame初始化 pygame.init() ...

  7. (转)rotatelogs - Piped logging program to rotate Apache logs

    原文:http://publib.boulder.ibm.com/httpserv/manual60/programs/rotatelogs.html rotatelogs is a simple p ...

  8. 51 Nod 1629 B君的圆锥

    1629 B君的圆锥  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 B君要用一个表面积为S的圆锥将白山云包起来. B君希望包住的白山云体积尽量大 ...

  9. np.max() 和 np.maximum()的区别

    1.np.max(a, axis=None, out=None, keepdims=False) 求序列的最值 最少接受一个参数 axis默认为axis=0即列向,如果axis=1即横向 ex: &g ...

  10. codeforces1C

    Ancient Berland Circus CodeForces - 1C 如今,Berland 的所有马戏表演都有一个圆形的竞技场,其直径为 13 米,但过去的情况有所不同. 在古代 Berlan ...