log 2021-07-30
project
epis
고민되는 점이.. k8s를 쓰면 그게 대부분 인프라를 관리하므로 마이크로서비스 아키텍쳐의 각 패턴들을 공부하는데는 조금 애매하지 않을까 싶다. consul와 k8s를 같이 찾아볼 때에도 보통 k8s 클러스터와 외부 통신을 연동시킬때 쓴다고 하는 것 같다.
클러스터 구성 자체는 간단한거 같다. 마스터 노드 즉 명령을 내릴 수 있는 노드는 한개로 제한되는건가?
https://rancher.com/docs/k3s/latest/en/quick-start/
위 설명대로, 다른 pc에서 토큰과 url 지정해서 구성하니 해당 pc에서는 sudo k3s kubectl get no
명령이 실행되지 않는다. worker node이기 때문에 그런 듯하다.
k8s 공부
구조
- control plane
- api server
- scheduler
- controller-manager
- cloud-controller-manager
- api server
- nodes
- proxy
- kubelet
- container runtime
api 서버가 scheduler, controller, nodes와 통신
강의에서는 kubeadm으로 셋업한다는데, 나는 k3s로 일단 구성은 되었다고 생각한다.
클러스터 셋업
우분투에서 대략적인 셋업 방법인데, 나는 k3s로 구성했으므로 일단 스킵, 좀 불안하긴하다. 모든 과정 상세히 적어봐야 큰 의미 없을듯하여 대략적으로 절차만 기술함.
네트워크 설정
클라우드에서는 보통 호스트 이름이 랜덤 해쉬값으로 지정되는데, 우분투에서는 다음 명령으로 호스트 이름을 지정할 수 있는 듯하다:
sudo hostnamectl set-hostname <name>
(적용되려면 다시 로그인해야한다.)
그리고, 모든 대상 호스트들에서 터미널을 열어서 서로 위치를 알 수 있도록 프라이빗 ip와 대상 호스트이름을 아래와 같이 지정해주는 작업을 한다. (터미널에 여러 탭 동시 입력 기능이 있으면 좋다. hyper.js 의 경우 hyper-broadcast를 사용하면 가능하다.)
운영체제 레벨 시스템 설정 (containerd 활성화)
우분투 기준 k8s를 설치하기 위해 상당히 복잡한 시스템 설정을 하는데, 정확히 뭘 하는지 잘 모르겠다.
다음 설정들을 모든 호스트에서 건드린다.
/etc/modules-load.d/containerd.conf
설정 수정후 modprobe로 재시작
/etc/sysctl.d/99-kubernetes-cri.conf
sysctl로 재부팅 없이 적용
그 다음, apt로 containerd 패키지 설치,
systemctl로 재시작 후 status 확인
다행히 sudo systemctl status containerd
로 확인한 결과 아래와 같이 실행중이므로 스킵해도 될 듯하다.
k8s 패키지 설치
sudo swapoff -a
로 스왑 비활성화etc/fstab
설정 수정하여 항상 스왑 비활성화하도록 적용apt-transport-https
패키지 설치- k8s 저장소의 gpg key 등록
- k8s 저장소를 apt 저장소리스트에 등록
- apt update, kubelet, kubeadm, kubectl 설치
apt mark hold <packages...>
명령으로 자동 업데이트 되지 않도록 버전 고정 설정
클러스터 초기화
- control 노드에서,
sudo kubeadm init --pod-network-cider <cidr>
명령으로 초기화,--kubernetes-version <v>
옵션으로 버전 지정 가능
- 사용자 설정 적용
- calico 네트워크 플러그인 적용
- https://kubernetes.io/docs/concepts/cluster-administration/networking/#the-kubernetes-network-model
- 위 문서처럼, k8s는 하위 네트워크 모델을 유연하게 적용 가능한 듯하다.
- worker node에서 쓸 join 명령 출력, 카피
- worker 노드에서
- 위에서 카피한 명령으로 클러스터에 참가
- 실행 노드 확인
k8s 네트워크는 아래 블로그에 굉장히 잘 정리되어 있다.
sport
cf 1555
A
15 6 -> 300 120 20 8 -> 300 120 25 10 -> 300 120
사실상 비율이 같으므로, 나머지를 최소로 하면 될 듯하다. 300을 넘어가는 값은 300으로 나눈것만 계산하면 된다.
300 이하의 값의 정답은 어떻게 계산하나? 0부터 올라가면서, 300까지가 시간이니, 각 시간 기준 이전 시간들 참조해서 업데이트하는 스위핑방식으로 업데이트하면 될 듯하다.
15 15 15 15 15 15 30 30 30 30 30 30 …
문제가.. lower_bound? 같은 느낌이라 조건을 어떻게 잡아야 하는지 헷갈린다. 120기준으로 나눠버리면 123 이런수는 제대로 고려가 안된다.. 즉 나누되, 남는 수가 일정 이상이 되어야 한다.
복잡하다. 그냥 대충 생각하면 120이상이면 2당 5가 증가하는데, 120 300 12 30 2 5 …
rust solution
fn solve<R: io::BufRead, W: io::Write>(scan: &mut UnsafeScanner<R>, out: &mut W) {
let cases = ri32(scan);
let mut arr= vec![15i64; 250];
use std::cmp::min;
for i in 0..245 {
let idx = i as i64;
let mut cur_min = i64::MAX;
if idx-6 >= 0 {
cur_min = min(cur_min, arr[i-6]+15);
}
if idx-8 >= 0 {
cur_min = min(cur_min, arr[i-8]+20);
}
if idx-10 >= 0 {
cur_min = min(cur_min, arr[i-10]+25);
}
if idx <= 6 {
cur_min = 15;
} else if idx <= 8 { // 이부분과 아래 케이스를 처리 안했어서 여러번 틀렸음..
cur_min = 20;
} else if idx <= 10 {
cur_min = 25;
}
arr[i] = cur_min;
}
arr[0] = 0;
// dbg!(&arr);
for case in 0..cases {
let n = ri64(scan);
let div = n / 2;
let left = n % 2;
if n < 120 {
writeln!(out, "{}", arr[n as usize]);
} else {
writeln!(out, "{}", div*5+left*5);
}
}
}
꼭 이런 마감 처리에서 시간을 많이 뺏긴다. 완벽하고 깔끔하게 맞는 조건으로 짜려면 어떻게 연습해야 하는 것일까? 완전 논리적 증명 후 풀이??..
B
이건 진짜 종이 없인 못풀듯. 그림 그려서 풀었다.
rust solution
fn solve<R: io::BufRead, W: io::Write>(scan: &mut UnsafeScanner<R>, out: &mut W) {
let cases = ri32(scan);
for _ in 0..cases {
let (W,H) = (rf64(scan), rf64(scan));
let (x1,y1,x2,y2) = (rf64(scan), rf64(scan), rf64(scan), rf64(scan));
let (w,h) = (rf64(scan), rf64(scan));
let large_x = f64::max(x1, W-x2);
let large_y = f64::max(y1, H-y2);
let mut overlap_w = f64::max(w-large_x, 0.0);
let mut overlap_h = f64::max(h-large_y, 0.0);
if w+(x2-x1) > W {
overlap_w = f64::MAX;
}
if h+(y2-y1) > H {
overlap_h = f64::MAX;
}
let min_dist = f64::min(overlap_w, overlap_h);
if min_dist >= 100000005.0 {
writeln!(out, "{}", -1);
} else {
writeln!(out, "{:.8}", min_dist);
}
}
}
C
A보다도 시간이 덜 걸린 것 같다. 아이디어 자체도 간단하고 구현도 간단하다. A에 시간을 너무 써서 대회 시간 내에 풀지 못했다.
rust solution
fn solve<R: io::BufRead, W: io::Write>(scan: &mut UnsafeScanner<R>, out: &mut W) {
let cases = ri32(scan);
for _ in 0..cases {
let mut arr1 = vec![];
let mut arr2 = vec![];
let mut sums1 = vec![];
let mut sums2 = vec![];
let mut maxv1 = 0;
let mut maxv2 = 0;
let m = ri32(scan);
for i in 0..m {
let val = ri32(scan);
arr1.push(val);
maxv1 += val;
}
for i in 0..m {
let val = ri32(scan);
arr2.push(val);
maxv2 += val;
}
let mut leftsums = maxv1;
for (i, item1) in arr1.iter().enumerate() {
let val = item1.clone();
sums1.push(leftsums);
leftsums -= val;
}
sums1.push(0);
let mut lastsums = 0;
for (i, item2) in arr2.iter().enumerate() {
let val = item2.clone();
sums2.push(lastsums);
lastsums += val;
}
let mut min_so_far = i32::MAX;
let mut cur_max = 0;
for idx in 0..m {
cur_max = i32::max(sums1[(idx + 1) as usize], sums2[(idx) as usize]);
if cur_max < min_so_far {
min_so_far = cur_max;
}
}
// dbg!(sums1);
// dbg!(sums2);
writeln!(out, "{}", min_so_far);
}
}
Comments